def calculate(cls, comaster_pk=None, now=None): ''' Calculates and updates EGs based on the formula table. ''' if not now: now = datetime.now() filters = dict(ied__co_master__pk=comaster_pk) filters = {} ai = generate_tag_context(AI.objects.filter(**filters).values(*cls.AI_ATTRS) ) di = generate_tag_context(DI.objects.filter(**filters).values(*cls.DI_ATTRS) ) eg = generate_tag_context(SVGElement.objects.values(*cls.EG_ATTRS)) # Generate context for formula evaluation ctx = dict(ai=ai, di=di, eg=eg,) ctx.update(cls.DSL_FUNCTIONS) context = bunchify(ctx) success, fail = 0, 0 for formula in cls.objects.all(): # Fila donde se guarda el cálculo element = formula.target texto_formula = formula.formula # Fix single equal sign #texto_formula = re.sub(r'(?:[\b\s])=(:?[\s\b])', '==', texto_formula) texto_formula = texto_formula.replace('=', '==') try: #import pdb; pdb.set_trace() value = eval(texto_formula, {}, context) except Exception as e: fail += 1 # Record error formula.last_error = '%s: %s' % (type(e).__name__, e.message) print e, formula.target.tag, formula.attribute, texto_formula import traceback; traceback.print_exc(); formula.save() else: success += 1 if formula.last_error: formula.last_error = '' formula.save() # print "Setenado", element.tag, formula.attribute, value attribute = formula.attribute prev_value = getattr(element, attribute) if prev_value != value: # Update setattr(element, attribute, value) element.save() # TODO: Check profile never_updated = SVGElement.objects.filter(last_update__isnull=True) never_updated.update(last_update=now) return success, fail
def build_context(cls, **kwargs): '''Takes a dict with typically ai, di and eg queryset and generate a iterable, item accesible dict and then adds DSL functions. returns an object that supports attribute and item access for eval's locals use (values and functions)''' context = {t: generate_tag_context(vs) for t, vs in kwargs.iteritems()} context.update(cls.DSL_FUNCTIONS) return bunchify(context)