Beispiel #1
0
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 = OLEA_REPLACE_DEVS
    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=olea.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 assignee before setting first new assignee
            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)