def aggregate_history(self, dataset): prev = None prev_object_id = None datas = [] sink = AttrDict(object_id=-1, value=-1, content_object_repr='', created_at=AttrDict(year=-1, month=-1)) for mdata in itertools.chain(dataset.order_by('object_id', 'created_at'), [sink]): object_id = mdata.object_id ymonth = (mdata.created_at.year, mdata.created_at.month) if object_id != prev_object_id or ymonth != prev.ymonth: if prev_object_id is not None: data = AttrDict( date=datetime.date( year=prev.ymonth[0], month=prev.ymonth[1], day=1 ), value=current, content_object_repr=prev.content_object_repr ) datas.append(data) current = mdata.value else: current += mdata.value if object_id != prev_object_id: if prev_object_id is not None: yield (prev.content_object_repr, datas) datas = [] prev = mdata prev.ymonth = ymonth prev_object_id = object_id
def get_records(self): types = set() records = utils.RecordStorage() for record in self.get_declared_records(): types.add(record.type) if record.type == record.SOA: # Update serial and insert at 0 value = record.value.split() value[2] = str(self.serial) records.insert( 0, AttrDict(type=record.SOA, ttl=record.get_ttl(), value=' '.join(value))) else: records.append( AttrDict(type=record.type, ttl=record.get_ttl(), value=record.value)) for record in self.get_default_records(): if self.record_is_implicit(record, types): if record.type is Record.SOA: records.insert(0, record) else: records.append(record) return records
def __init__(self, *args, **kwargs): super(MailboxForm, self).__init__(*args, **kwargs) # Hack the widget in order to display add button remote_field_mock = AttrDict( **{ 'model': Address, 'get_related_field': lambda: AttrDict(name='id'), }) widget = self.fields['addresses'].widget self.fields['addresses'].widget = widgets.RelatedFieldWidgetWrapper( widget, remote_field_mock, self.modeladmin.admin_site, can_add_related=True) account = self.modeladmin.account # Filter related addresses by account old_render = self.fields['addresses'].widget.render def render(*args, **kwargs): output = old_render(*args, **kwargs) args = 'account=%i&mailboxes=%s' % (account.pk, self.instance.pk) output = output.replace('/add/?', '/add/?%s&' % args) return mark_safe(output) self.fields['addresses'].widget.render = render queryset = self.fields['addresses'].queryset realted_addresses = queryset.filter( account_id=account.pk).order_by('name') self.fields['addresses'].queryset = realted_addresses if self.instance and self.instance.pk: self.fields['addresses'].initial = self.instance.addresses.all()
def best_price(rates, metric): if rates.query.order_by != ['plan', 'quantity']: raise ValueError( "rates queryset should be ordered by 'plan' and 'quantity'") candidates = [] for plan, rates in rates.group_by('plan').items(): rates = _standardize(rates) plan_candidates = [] for rate in rates: if rate.quantity > metric: break if plan_candidates: ant = plan_candidates[-1] if ant.price == rate.price: # Multiple plans support ant.fold += 1 else: ant.quantity = rate.quantity - 1 plan_candidates.append( AttrDict( price=rate.price, quantity=metric, fold=1, )) else: plan_candidates.append( AttrDict( price=rate.price, quantity=metric, fold=1, )) candidates.extend(plan_candidates) results = [] accumulated = 0 for candidate in sorted(candidates, key=lambda c: c.price): if candidate.quantity < accumulated: # Out of barrier continue candidate.quantity *= candidate.fold if accumulated + candidate.quantity > metric: quantity = metric - accumulated else: quantity = candidate.quantity accumulated += quantity if quantity: if results and results[-1].price == candidate.price: results[-1].quantity += quantity else: results.append( AttrDict(**{ 'quantity': quantity, 'price': candidate.price })) return results
def match_price(rates, metric): if rates.query.order_by != ['plan', 'quantity']: raise ValueError( "rates queryset should be ordered by 'plan' and 'quantity'") candidates = [] selected = False prev = None rates = _standardize(rates.distinct()) for rate in rates: if prev: if prev.plan != rate.plan: if not selected and prev.quantity <= metric: candidates.append(prev) selected = False if not selected and rate.quantity > metric: if prev.quantity <= metric: candidates.append(prev) selected = True prev = rate if not selected and prev.quantity <= metric: candidates.append(prev) candidates.sort(key=lambda r: r.price) if candidates: return [ AttrDict(**{ 'quantity': metric, 'price': candidates[0].price, }) ] return None
def load(cls, operation, log=None): routes = None if log: routes = { (operation.backend, operation.action): AttrDict(host=log.server) } return cls(operation.backend_class, operation.instance, operation.action, routes=routes)
def get_default_records(self): defaults = [] if self.is_top: for ns in settings.DOMAINS_DEFAULT_NS: defaults.append(AttrDict(type=Record.NS, value=ns)) soa = self.get_default_soa() defaults.insert(0, AttrDict(type=Record.SOA, value=soa)) for mx in settings.DOMAINS_DEFAULT_MX: defaults.append(AttrDict(type=Record.MX, value=mx)) default_a = settings.DOMAINS_DEFAULT_A if default_a: defaults.append(AttrDict(type=Record.A, value=default_a)) default_aaaa = settings.DOMAINS_DEFAULT_AAAA if default_aaaa: defaults.append(AttrDict(type=Record.AAAA, value=default_aaaa)) return defaults
def step_price(rates, metric): if rates.query.order_by != ['plan', 'quantity']: raise ValueError( "rates queryset should be ordered by 'plan' and 'quantity'") # Step price group = [] minimal = (sys.maxsize, []) for plan, rates in rates.group_by('plan').items(): rates = _standardize(rates) value, steps = _compute_steps(rates, metric) if plan.is_combinable: group.append(steps) else: minimal = min(minimal, (value, steps), key=lambda v: v[0]) if len(group) == 1: value, steps = _compute_steps(rates, metric) minimal = min(minimal, (value, steps), key=lambda v: v[0]) elif len(group) > 1: # Merge steps = [] for rates in group: steps += rates steps.sort(key=lambda s: s.price) result = [] counter = 0 value = 0 ix = 0 targets = [] while counter < metric: barrier = steps[ix].barrier if barrier <= counter + 1: price = steps[ix].price quantity = steps[ix].quantity if quantity + counter > metric: quantity = metric - counter else: for target in targets: if counter + quantity >= target: quantity = (counter + quantity + 1) - target steps[ix].quantity -= quantity if not steps[ix].quantity: steps.pop(ix) break else: steps.pop(ix) counter += quantity value += quantity * price if result and result[-1].price == price: result[-1].quantity += quantity else: result.append(AttrDict(quantity=quantity, price=price)) ix = 0 targets = [] else: targets.append(barrier) ix += 1 minimal = min(minimal, (value, result), key=lambda v: v[0]) return minimal[1]
def inner(fn, name, method, *args, **kwargs): task_id = get_id() kwargs.update({ '_name': name, '_task_id': task_id, }) thread = method(target=fn, args=args, kwargs=kwargs) thread.start() # Celery API compat thread.request = AttrDict(id=task_id) return thread
def generate_line(self, order, price, *dates, metric=1, discounts=None, computed=False): """ discounts: extra discounts to apply computed: price = price*size already performed """ if len(dates) == 2: ini, end = dates elif len(dates) == 1: ini, end = dates[0], dates[0] else: raise AttributeError("WTF is '%s'?" % dates) discounts = discounts or () size = self.get_price_size(ini, end) if not computed: price = price * size subtotal = self.nominal_price * size * metric line = AttrDict( **{ 'order': order, 'subtotal': subtotal, 'ini': ini, 'end': end, 'size': size, 'metric': metric, 'discounts': [], }) if subtotal > price: plan_discount = price - subtotal self.generate_discount(line, self._PLAN, plan_discount) subtotal += plan_discount for dtype, dprice in discounts: subtotal += dprice # Prevent compensations/prepays to refund money if dtype in (self._COMPENSATION, self._PREPAY) and subtotal < 0: dprice -= subtotal if dprice: self.generate_discount(line, dtype, dprice) return line
def _compute_steps(rates, metric): value = 0 num = len(rates) accumulated = 0 barrier = 1 next_barrier = None end = False ix = 0 steps = [] while ix < num and not end: fold = 1 # Multiple contractions while ix < num - 1 and rates[ix] == rates[ix + 1]: ix += 1 fold += 1 if ix + 1 == num: quantity = metric - accumulated next_barrier = quantity else: quantity = rates[ix + 1].quantity - max(rates[ix].quantity, 1) next_barrier = quantity if rates[ix + 1].price > rates[ix].price: quantity *= fold if accumulated + quantity > metric: quantity = metric - accumulated end = True price = rates[ix].price steps.append( AttrDict(**{ 'quantity': quantity, 'price': price, 'barrier': barrier, })) accumulated += quantity barrier += next_barrier value += quantity * price ix += 1 return value, steps
def generate_discount(self, line, dtype, price): line.discounts.append(AttrDict(**{ 'type': dtype, 'total': price, }))
def edit_records(modeladmin, request, queryset): selected_ids = queryset.values_list('id', flat=True) # Include subodmains queryset = queryset.model.objects.filter( Q(top__id__in=selected_ids) | Q(id__in=selected_ids)).annotate( structured_id=Coalesce('top__id', 'id'), structured_name=Concat('top__name', 'name')).order_by('-structured_id', 'structured_name') formsets = [] for domain in queryset.prefetch_related('records'): modeladmin_copy = copy.copy(modeladmin) modeladmin_copy.model = Record prefix = '' if domain.is_top else ' ' * 8 context = { 'url': change_url(domain), 'name': prefix + domain.name, 'title': '', } if domain.id not in selected_ids: context['name'] += '*' context['title'] = _( "This subdomain was not explicitly selected " "but has been automatically added to this list.") link = '<a href="%(url)s" title="%(title)s">%(name)s</a>' % context modeladmin_copy.verbose_name_plural = mark_safe(link) RecordFormSet = modelformset_factory(Record, form=RecordForm, formset=RecordEditFormSet, extra=1, can_delete=True) formset = RecordFormSet(queryset=domain.records.all(), prefix=domain.id) formset.instance = domain formset.cls = RecordFormSet formsets.append(formset) if request.POST.get('post') == 'generic_confirmation': posted_formsets = [] all_valid = True for formset in formsets: instance = formset.instance formset = formset.cls(request.POST, request.FILES, queryset=formset.queryset, prefix=instance.id) formset.instance = instance if not formset.is_valid(): all_valid = False posted_formsets.append(formset) formsets = posted_formsets if all_valid: for formset in formsets: for form in formset.forms: form.instance.domain_id = formset.instance.id formset.save() fake_form = AttrDict({'changed_data': False}) change_message = modeladmin.construct_change_message( request, fake_form, [formset]) modeladmin.log_change(request, formset.instance, change_message) num = len(formsets) message = ungettext( _("Records for one selected domain have been updated."), _("Records for %i selected domains have been updated.") % num, num) modeladmin.message_user(request, message) return opts = modeladmin.model._meta context = { 'title': _("Edit records"), 'action_name': _("Edit records"), 'action_value': 'edit_records', 'display_objects': [], 'queryset': queryset, 'opts': opts, 'app_label': opts.app_label, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'formsets': formsets, 'obj': get_object_from_url(modeladmin, request), } return render(request, 'admin/domains/domain/edit_records.html', context)
def clean_custom_url(saas): instance = saas.instance instance.custom_url = instance.custom_url.strip() url = urlparse(instance.custom_url) if not url.path: instance.custom_url += '/' url = urlparse(instance.custom_url) try: protocol, valid_protocols = saas.PROTOCOL_MAP[url.scheme] except KeyError: raise ValidationError({ 'custom_url': _("%s scheme not supported (http/https)") % url.scheme, }) account = instance.account # get or create website try: website = Website.objects.get( protocol__in=valid_protocols, domains__name=url.netloc, account=account, ) except Website.DoesNotExist: # get or create domain Domain = Website.domains.field.related_model try: domain = Domain.objects.get(name=url.netloc) except Domain.DoesNotExist: raise ValidationError({ 'custom_url': _("Domain %s does not exist.") % url.netloc, }) if domain.account != account: raise ValidationError({ 'custom_url': _("Domain %s does not belong to account %s, it's from %s.") % (url.netloc, account, domain.account), }) # Create new website for custom_url # Changed by daniel: hardcode target_server to web.pangea.lan, consider putting it into settings.py tgt_server = Server.objects.get(name='web.pangea.lan') website = Website(name=url.netloc, protocol=protocol, account=account, target_server=tgt_server) full_clean(website) try: validate_domain_protocol(website, domain, protocol) except ValidationError as e: raise ValidationError({ 'custom_url': _("Error validating related %s: %s") % (type(website).__name__, e), }) # get or create directive try: directive = website.directives.get(name=saas.get_directive_name()) except WebsiteDirective.DoesNotExist: directive = WebsiteDirective(name=saas.get_directive_name(), value=url.path) if not directive.pk or directive.value != url.path: directive.value = url.path if website.pk: directive.website = website full_clean(directive) # Adaptation of orchestra.websites.forms.WebsiteDirectiveInlineFormSet.clean() locations = set( Content.objects.filter(website=website).values_list('path', flat=True)) values = defaultdict(list) directives = WebsiteDirective.objects.filter(website=website) for wdirective in directives.exclude(pk=directive.pk): fdirective = AttrDict({ 'name': wdirective.name, 'value': wdirective.value }) try: wdirective.directive_instance.validate_uniqueness( fdirective, values, locations) except ValidationError as err: raise ValidationError({ 'custom_url': _("Another directive with this URL path exists (%s)." % err) }) else: full_clean(directive, exclude=('website', )) return directive