def update_reviewing_roles(event, users, contributions, role, assign):
    role_map = {
        PaperReviewingRole.judge: attrgetter('paper_judges'),
        PaperReviewingRole.content_reviewer: attrgetter('paper_content_reviewers'),
        PaperReviewingRole.layout_reviewer: attrgetter('paper_layout_reviewers'),
    }

    for contrib in contributions:
        role_group = role_map[role](contrib)
        for user in users:
            if assign:
                role_group.add(user)
            else:
                role_group.discard(user)

    contrib_ids = ['#{}'.format(c.friendly_id) for c in sorted(contributions, key=attrgetter('friendly_id'))]
    log_data = {'Users': ', '.join(sorted(person.full_name for person in users)),
                'Contributions': ', '.join(contrib_ids)}
    roles_to_notify = paper_reviewing_settings.get(event, 'notify_on_assigned_contrib')
    if role in roles_to_notify:
        for user in users:
            notify_paper_assignment(user, role, contributions, event, assign)
    if assign:
        event.log(EventLogRealm.management, EventLogKind.positive, 'Papers',
                  'Papers assigned ({})'.format(orig_string(role.title)), session.user, data=log_data)
    else:
        event.log(EventLogRealm.management, EventLogKind.negative, 'Papers',
                  'Papers unassigned ({})'.format(orig_string(role.title)), session.user, data=log_data)
    db.session.flush()
    logger.info('Paper reviewing roles in event %r updated by %r', event, session.user)
 def _format_roles(roles):
     roles = set(roles)
     return ', '.join(
         sorted(
             orig_string(role.friendly_name)
             for role in available_roles.itervalues()
             if role.name in roles))
def set_reviewing_state(event, reviewing_type, enable):
    event.cfp.set_reviewing_state(reviewing_type, enable)
    action = 'enabled' if enable else 'disabled'
    logger.info("Reviewing type '%s' for event %r %s by %r", reviewing_type.name, event, action, session.user)
    event.log(EventLogRealm.management, EventLogKind.positive if enable else EventLogKind.negative, 'Papers',
              "{} {} reviewing".format("Enabled" if enable else "Disabled", orig_string(reviewing_type.title.lower())),
              session.user)
def judge_paper(paper, judgment, comment, judge):
    if judgment == PaperAction.accept:
        paper.state = PaperRevisionState.accepted
    elif judgment == PaperAction.reject:
        paper.state = PaperRevisionState.rejected
    elif judgment == PaperAction.to_be_corrected:
        paper.state = PaperRevisionState.to_be_corrected
    paper.last_revision.judgment_comment = comment
    paper.last_revision.judge = judge
    paper.last_revision.judgment_dt = now_utc()
    db.session.flush()
    log_data = {'New state': orig_string(judgment.title)}
    notify_paper_judgment(paper)
    logger.info('Paper %r was judged by %r to %s', paper, judge, orig_string(judgment.title))
    paper.event.log(EventLogRealm.management, EventLogKind.change, 'Papers',
                    'Paper "{}" was judged'.format(orig_string(paper.verbose_title)), judge,
                    data=log_data)
def create_review(paper, review_type, user, review_data, questions_data):
    review = PaperReview(revision=paper.last_revision, type=review_type.instance, user=user)
    review.populate_from_dict(review_data)
    log_data = {}
    for question in paper.event.cfp.get_questions_for_review_type(review_type.instance):
        value = int(questions_data['question_{}'.format(question.id)])
        review.ratings.append(PaperReviewRating(question=question, value=value))
        log_data[question.text] = value
    db.session.flush()
    notify_paper_review_submission(review)
    logger.info("Paper %r received a review of type %s by %r", paper, review_type.instance.name, user)
    log_data.update({
        'Type': orig_string(review_type.title),
        'Action': orig_string(review.proposed_action.title),
        'Comment': review.comment
    })
    paper.event.log(EventLogRealm.management, EventLogKind.positive, 'Papers',
                    'Paper for contribution {} reviewed'.format(paper.contribution.verbose_title),
                    user, data=log_data)
    return review
def judge_abstract(abstract,
                   abstract_data,
                   judgment,
                   judge,
                   contrib_session=None,
                   merge_persons=False,
                   send_notifications=False):
    abstract.judge = judge
    abstract.judgment_dt = now_utc()
    abstract.judgment_comment = abstract_data['judgment_comment']
    log_data = {'Judgment': orig_string(judgment.title)}
    if judgment == AbstractAction.accept:
        abstract.state = AbstractState.accepted
        abstract.accepted_track = abstract_data.get('accepted_track')
        if abstract_data.get('override_contrib_type') or abstract_data.get(
                'accepted_contrib_type'):
            abstract.accepted_contrib_type = abstract_data.get(
                'accepted_contrib_type')
        else:
            abstract.accepted_contrib_type = abstract.submitted_contrib_type
        if not abstract.contribution:
            abstract.contribution = create_contribution_from_abstract(
                abstract, contrib_session)
        if abstract.accepted_track:
            log_data['Track'] = abstract.accepted_track.title
        if abstract.accepted_contrib_type:
            log_data['Type'] = abstract.accepted_contrib_type.name
    elif judgment == AbstractAction.reject:
        abstract.state = AbstractState.rejected
    elif judgment == AbstractAction.mark_as_duplicate:
        abstract.state = AbstractState.duplicate
        abstract.duplicate_of = abstract_data['duplicate_of']
        log_data['Duplicate of'] = abstract.duplicate_of.verbose_title
    elif judgment == AbstractAction.merge:
        abstract.state = AbstractState.merged
        abstract.merged_into = abstract_data['merged_into']
        log_data['Merged into'] = abstract.merged_into.verbose_title
        log_data['Merge authors'] = merge_persons
        if merge_persons:
            _merge_person_links(abstract.merged_into, abstract)
    db.session.flush()
    if send_notifications:
        log_data['Notifications sent'] = send_abstract_notifications(abstract)
    logger.info('Abstract %s judged by %s', abstract, judge)
    abstract.event.log(EventLogRealm.management,
                       EventLogKind.change,
                       'Abstracts',
                       'Abstract {} judged'.format(abstract.verbose_title),
                       judge,
                       data=log_data)
Exemple #7
0
def make_diff_log(changes, fields):
    """Create a value for log data containing change information.

    :param changes: a dict mapping attributes to ``(old, new)`` tuples
    :param fields: a dict mapping attributes to field metadata.  for
            simple cases this may be a string with the human-friendly
            title, for more advanced fields it should be a dict
            containing ``title``, a ``type`` string and a ``convert``
            callback which will be invoked with a tuple containing the
            old and new value
    """
    data = {'_diff': True}
    for key, field_data in fields.iteritems():
        try:
            change = changes[key]
        except KeyError:
            continue
        if isinstance(field_data, basestring):
            field_data = {'title': field_data}
        title = field_data['title']
        convert = field_data.get('convert')
        type_ = field_data.get('type')
        if convert:
            change = convert(change)
        if type_ is not None:
            # when we have an explicit type specified don't do any
            # guessing/conversions
            pass
        elif all(isinstance(x, Enum) for x in change):
            type_ = 'enum'
            change = [orig_string(getattr(x, 'title', x.name)) for x in change]
        elif all(isinstance(x, (int, long, float)) for x in change):
            type_ = 'number'
        elif all(isinstance(x, (list, tuple)) for x in change):
            type_ = 'list'
        elif all(isinstance(x, set) for x in change):
            type_ = 'list'
            change = map(sorted, change)
        elif all(isinstance(x, bool) for x in change):
            type_ = 'bool'
        elif all(isinstance(x, datetime) for x in change):
            type_ = 'datetime'
            change = [x.isoformat() for x in change]
        else:
            type_ = 'text'
            change = map(unicode, map(orig_string, change))
        data[title] = list(change) + [type_]
    return data
def update_session_coordinator_privs(event, data):
    changes = {}
    for priv, enabled in data.iteritems():
        setting = COORDINATOR_PRIV_SETTINGS[priv]
        if session_settings.get(event, setting) == enabled:
            continue
        session_settings.set(event, setting, enabled)
        changes[priv] = (not enabled, enabled)
    db.session.flush()
    logger.info('Session coordinator privs of event %r updated with %r by %r',
                event, data, session.user)
    if changes:
        log_fields = {
            priv: orig_string(title)
            for priv, title in COORDINATOR_PRIV_TITLES.iteritems()
        }
        event.log(EventLogRealm.management,
                  EventLogKind.change,
                  'Sessions',
                  'Coordinator privileges updated',
                  session.user,
                  data={'Changes': make_diff_log(changes, log_fields)})
def create_abstract_review(abstract, track, user, review_data, questions_data):
    review = AbstractReview(abstract=abstract, track=track, user=user)
    review.populate_from_dict(review_data)
    log_data = {}
    for question in abstract.event.abstract_review_questions:
        value = int(questions_data['question_{}'.format(question.id)])
        review.ratings.append(
            AbstractReviewRating(question=question, value=value))
        log_data[question.text] = value
    db.session.flush()
    logger.info("Abstract %s received a review by %s for track %s", abstract,
                user, track)
    log_data.update({
        'Track': track.title,
        'Action': orig_string(review.proposed_action.title),
        'Comment': review.comment
    })
    if review.proposed_action == AbstractAction.accept:
        log_data['Contribution type'] = (review.proposed_contribution_type.name
                                         if review.proposed_contribution_type
                                         else None)
    elif review.proposed_action == AbstractAction.change_tracks:
        log_data['Other tracks'] = sorted(t.title
                                          for t in review.proposed_tracks)
    elif review.proposed_action in {
            AbstractAction.mark_as_duplicate, AbstractAction.merge
    }:
        log_data[
            'Other abstract'] = review.proposed_related_abstract.verbose_title
    abstract.event.log(EventLogRealm.management,
                       EventLogKind.positive,
                       'Abstracts',
                       'Abstract {} reviewed'.format(abstract.verbose_title),
                       user,
                       data=log_data)
    return review
 def FIELD_DATA(cls):
     title_item = {
         'price': 0,
         'is_billable': False,
         'places_limit': 0,
         'is_enabled': True
     }
     return [
         (cls.title, {
             'title': cls.title.get_title(),
             'input_type': 'single_choice',
             'data': {
                 'item_type':
                 'dropdown',
                 'with_extra_slots':
                 False,
                 'choices': [
                     dict(title_item,
                          id=unicode(uuid4()),
                          caption=orig_string(t.title)) for t in UserTitle
                     if t
                 ]
             }
         }),
         (cls.first_name, {
             'title': cls.first_name.get_title(),
             'input_type': 'text'
         }),
         (cls.last_name, {
             'title': cls.last_name.get_title(),
             'input_type': 'text'
         }),
         (cls.email, {
             'title': cls.email.get_title(),
             'input_type': 'email'
         }),
         (cls.affiliation, {
             'title': cls.affiliation.get_title(),
             'input_type': 'text'
         }),
         # Fields disabled by default start in position 1000 to avoid problems reordering
         (cls.address, {
             'title': cls.address.get_title(),
             'input_type': 'textarea',
             'is_enabled': False,
             'position': 1000
         }),
         (cls.country, {
             'title': cls.country.get_title(),
             'input_type': 'country',
             'is_enabled': False,
             'position': 1001
         }),
         (cls.phone, {
             'title': cls.phone.get_title(),
             'input_type': 'phone',
             'is_enabled': False,
             'position': 1002
         }),
         (cls.position, {
             'title': cls.position.get_title(),
             'input_type': 'text',
             'is_enabled': False,
             'position': 1003
         }),
     ]
 def render(cls, abstract):
     return orig_string(abstract.submitter.title)