def form_valid(self, form): if form.has_changed(): old = Issue.objects.get(pk=self.object.pk) changed_data = signals.fields_to_changed_data(old, form.changed_data) ret = super(IssueEditView, self).form_valid(form) signals.modify.send(sender=self.model, instance=form.instance, changed_data=changed_data, user=self.request.user, ) return ret return super(IssueEditView, self).form_valid(form)
def compile(expression, project, user): global attrs_to_set global issue_to_change global glob_project global glob_user global issue_created global cleanup global cleanup_asignee global timelogs global issue_changed issue_created = False issue_changed = False cleanup_asignee = True attrs_to_set = [] timelogs = [] issue_to_change = "" glob_project = project glob_user = user # check that user has write access to project if not project.developer_allowed(user): raise Exception( u"No user permissions to modify issues in this project") # parse expression lexer = lex.lex(module=issue.lexer) # writes to parsetab.py (this is closed internally) and parser.out (which seems to stay open) # I don't know why debuglog (parser.out) is still open if we provide our own PlyLogger with it's # own file descriptor in that case yacc should not open any files. parser = yacc.yacc() parser.parse(expression, lexer=lexer) # TODO BUG cleanup yacc - close and parser.out, Y TFH is there no destructor doing this for us? # NOTE ^this doesn't seem to be possible - s. comment above # create issue if necessary if issue_created: issue_to_change = Issue(title=issue_to_change, project=glob_project, kanbancol=glob_project.kanbancol.first(), creator=glob_user) issue_to_change.save() if issue_changed: changed_data = signals.fields_to_changed_data( issue_to_change, [tup[0] for tup in attrs_to_set]) # handle timelogging separately for tdiff in timelogs: timelog = Timelog(user=glob_user, issue=issue_to_change, time=tdiff) timelog.save() for attr in attrs_to_set: # process all parsed attributes to change field = issue_to_change.__getattribute__(attr[0]) if str(type(field)).startswith("<class 'django.db.models"): # cleanup asignee before setting first new asignee if attr[0] == "assignee" and cleanup_asignee: cleanup_asignee = False field.clear() # we have a related field -> call add field.add(attr[1]) else: # no db model field, simply assign value issue_to_change.__setattr__(attr[0], attr[1]) issue_to_change.save() if issue_created: signals.create.send(sender=Issue, instance=issue_to_change, user=user) if not issue_created and issue_changed: signals.modify.send(sender=Issue, instance=issue_to_change, user=user, changed_data=changed_data)