Exemplo n.º 1
0
def create_abstract(event,
                    abstract_data,
                    custom_fields_data=None,
                    send_notifications=False):
    abstract = Abstract(event=event, submitter=session.user)
    tracks = abstract_data.pop('submitted_for_tracks', None)
    attachments = abstract_data.pop('attachments', None)
    abstract.populate_from_dict(abstract_data)
    if tracks is not None:
        _update_tracks(abstract, tracks)
    if custom_fields_data:
        set_custom_fields(abstract, custom_fields_data)
    db.session.flush()

    if attachments:
        add_abstract_files(abstract, attachments['added'], log_action=False)
    signals.event.abstract_created.send(abstract)

    if send_notifications:
        send_abstract_notifications(abstract)
    logger.info('Abstract %s created by %s', abstract, session.user)
    abstract.event.log(EventLogRealm.management, EventLogKind.positive,
                       'Abstracts',
                       'Abstract {} created'.format(abstract.verbose_title),
                       session.user)
    return abstract
Exemplo n.º 2
0
def add_abstract_files(abstract, files, log_action=True):
    if not files:
        return
    for f in files:
        filename = secure_filename(f.filename, 'attachment')
        content_type = mimetypes.guess_type(
            f.filename)[0] or f.mimetype or 'application/octet-stream'
        abstract_file = AbstractFile(filename=filename,
                                     content_type=content_type,
                                     abstract=abstract)
        abstract_file.save(f.stream)
        db.session.flush()
    if log_action:
        logger.info('%d abstract file(s) added to %s by %s', len(files),
                    abstract, session.user)
        num = len(files)
        if num == 1:
            msg = 'Added file to abstract {}'.format(abstract.verbose_title)
        else:
            msg = 'Added {} files to abstract {}'.format(
                num, abstract.verbose_title)
        abstract.event.log(
            EventLogRealm.management,
            EventLogKind.positive,
            'Abstracts',
            msg,
            session.user,
            data={'Files': ', '.join(f.filename for f in abstract.files)})
Exemplo n.º 3
0
def delete_abstract_comment(comment):
    comment.is_deleted = True
    db.session.flush()
    logger.info("Abstract comment %s deleted by %s", comment, session.user)
    comment.abstract.event.log(
        EventLogRealm.management, EventLogKind.negative, 'Abstracts',
        'Comment on abstract {} removed'.format(
            comment.abstract.verbose_title), session.user)
Exemplo n.º 4
0
def reset_abstract_state(abstract):
    abstract.reset_state()
    db.session.flush()
    logger.info('Abstract %s state reset by %s', abstract, session.user)
    abstract.event.log(
        EventLogRealm.management, EventLogKind.change, 'Abstracts',
        'State of abstract {} reset'.format(abstract.verbose_title),
        session.user)
Exemplo n.º 5
0
def update_reviewed_for_tracks(abstract, tracks):
    _update_tracks(abstract, tracks, only_reviewed_for=True)
    db.session.flush()
    logger.info('Reviewed tracks of abstract %s updated by %s', abstract,
                session.user)
    abstract.event.log(
        EventLogRealm.management, EventLogKind.change, 'Abstracts',
        'Reviewed tracks of abstract {} updated'.format(
            abstract.verbose_title), session.user)
Exemplo n.º 6
0
def create_abstract_comment(abstract, comment_data):
    comment = AbstractComment(user=session.user)
    comment.populate_from_dict(comment_data)
    comment.abstract = abstract
    db.session.flush()
    logger.info("Abstract %s received a comment from %s", abstract,
                session.user)
    abstract.event.log(
        EventLogRealm.management, EventLogKind.positive, 'Abstracts',
        'Abstract {} received a comment'.format(abstract.verbose_title),
        session.user)
Exemplo n.º 7
0
def delete_abstract(abstract, delete_contrib=False):
    abstract.is_deleted = True
    contrib = abstract.contribution
    abstract.contribution = None
    if delete_contrib and contrib:
        delete_contribution(contrib)
    db.session.flush()
    signals.event.abstract_deleted.send(abstract)
    logger.info('Abstract %s deleted by %s', abstract, session.user)
    abstract.event.log(EventLogRealm.management, EventLogKind.negative,
                       'Abstracts',
                       'Abstract {} deleted'.format(abstract.verbose_title),
                       session.user)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
def withdraw_abstract(abstract):
    abstract.reset_state()
    abstract.state = AbstractState.withdrawn
    contrib = abstract.contribution
    abstract.contribution = None
    if contrib:
        delete_contribution(contrib)
    db.session.flush()
    signals.event.abstract_state_changed.send(abstract)
    logger.info('Abstract %s withdrawn by %s', abstract, session.user)
    abstract.event.log(EventLogRealm.management, EventLogKind.negative,
                       'Abstracts',
                       'Abstract {} withdrawn'.format(abstract.verbose_title),
                       session.user)
Exemplo n.º 10
0
def update_abstract_review(review, review_data, questions_data):
    event = review.abstract.event
    changes = review.populate_from_dict(review_data)
    review.modified_dt = now_utc()
    log_fields = {}
    for question in event.abstract_review_questions:
        field_name = 'question_{}'.format(question.id)
        rating = question.get_review_rating(review, allow_create=True)
        old_value = rating.value
        rating.value = int(questions_data[field_name])
        if old_value != rating.value:
            changes[field_name] = (old_value, rating.value)
            log_fields[field_name] = {'title': question.text, 'type': 'number'}
    db.session.flush()
    logger.info("Abstract review %s modified", review)
    log_fields.update({'proposed_action': 'Action', 'comment': 'Comment'})
    if review.proposed_action in {
            AbstractAction.mark_as_duplicate, AbstractAction.merge
    }:
        log_fields['proposed_related_abstract'] = {
            'title':
            'Other abstract',
            'type':
            'string',
            'convert':
            lambda change: [x.verbose_title if x else None for x in change]
        }
    elif review.proposed_action == AbstractAction.accept:
        log_fields['proposed_contribution_type'] = {
            'title': 'Contribution type',
            'type': 'string',
            'convert': lambda change: [x.name if x else None for x in change]
        }
    elif review.proposed_action == AbstractAction.change_tracks:
        log_fields['proposed_tracks'] = {
            'title': 'Other tracks',
            'convert':
            lambda change: [sorted(t.title for t in x) for x in change]
        }
    event.log(EventLogRealm.management,
              EventLogKind.change,
              'Abstracts',
              'Review for abstract {} modified'.format(
                  review.abstract.verbose_title),
              session.user,
              data={
                  'Track': review.track.title,
                  'Changes': make_diff_log(changes, log_fields)
              })
Exemplo n.º 11
0
def schedule_cfa(event, start_dt, end_dt, modification_end_dt):
    event.cfa.schedule(start_dt, end_dt, modification_end_dt)
    logger.info("Call for abstracts for %s scheduled by %s", event,
                session.user)
    log_data = {}
    if start_dt:
        log_data['Start'] = start_dt.isoformat()
    if end_dt:
        log_data['End'] = end_dt.isoformat()
    if modification_end_dt:
        log_data['Modification deadline'] = modification_end_dt.isoformat()
    event.log(EventLogRealm.management,
              EventLogKind.change,
              'Abstracts',
              'Call for abstracts scheduled',
              session.user,
              data=log_data)
Exemplo n.º 12
0
def update_abstract_comment(comment, comment_data):
    changes = comment.populate_from_dict(comment_data)
    comment.modified_by = session.user
    comment.modified_dt = now_utc()
    db.session.flush()
    logger.info("Abstract comment %s modified by %s", comment, session.user)
    comment.abstract.event.log(EventLogRealm.management,
                               EventLogKind.change,
                               'Abstracts',
                               'Comment on abstract {} modified'.format(
                                   comment.abstract.verbose_title),
                               session.user,
                               data={
                                   'Changes':
                                   make_diff_log(changes, {
                                       'text': 'Text',
                                       'visibility': 'Visibility'
                                   })
                               })
Exemplo n.º 13
0
def delete_abstract_files(abstract, files):
    if not files:
        return
    num = len(files)
    for file_ in files:
        db.session.delete(file_)
    logger.info('%d abstract files deleted from %s by %s', num, abstract,
                session.user)
    if num == 1:
        msg = 'Deleted file from abstract {}'.format(abstract.verbose_title)
    else:
        msg = 'Deleted {} files from abstract {}'.format(
            num, abstract.verbose_title)
    abstract.event.log(EventLogRealm.management,
                       EventLogKind.negative,
                       'Abstracts',
                       msg,
                       session.user,
                       data={'Files': ', '.join(f.filename for f in files)})
Exemplo n.º 14
0
    def _process(self):
        roles = get_roles_for_event(self.event)
        form = AbstractReviewingRolesForm(event=self.event, obj=FormDefaults(roles=roles))

        if form.validate_on_submit():
            role_data = form.roles.role_data
            self.event.global_conveners = set(role_data['global_conveners'])
            self.event.global_abstract_reviewers = set(role_data['global_reviewers'])

            for track, user_roles in role_data['track_roles'].viewitems():
                track.conveners = set(user_roles['convener'])
                track.abstract_reviewers = set(user_roles['reviewer'])

            # Update actual ACLs
            update_object_principals(self.event, role_data['all_conveners'], role='track_convener')
            update_object_principals(self.event, role_data['all_reviewers'], role='abstract_reviewer')

            flash(_("Abstract reviewing roles have been updated."), 'success')
            logger.info("Abstract reviewing roles of %s have been updated by %s", self.event, session.user)
            return jsonify_data()
        return jsonify_form(form, skip_labels=True, form_header_kwargs={'id': 'reviewing-role-form'},
                            disabled_until_change=True)
Exemplo n.º 15
0
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
Exemplo n.º 16
0
def update_abstract(abstract, abstract_data, custom_fields_data=None):
    tracks = abstract_data.pop('submitted_for_tracks', None)
    attachments = abstract_data.pop('attachments', None)
    changes = {}

    if tracks is not None and abstract.edit_track_mode == EditTrackMode.both:
        changes.update(_update_tracks(abstract, tracks))

    if attachments:
        deleted_files = {
            f
            for f in abstract.files if f.id in attachments['deleted']
        }
        abstract.files = list(set(abstract.files) - deleted_files)
        delete_abstract_files(abstract, deleted_files)
        add_abstract_files(abstract, attachments['added'])

    changes.update(abstract.populate_from_dict(abstract_data))
    if custom_fields_data:
        changes.update(set_custom_fields(abstract, custom_fields_data))
    db.session.flush()
    logger.info('Abstract %s modified by %s', abstract, session.user)
    log_fields = {
        'title': 'Title',
        'description': 'Content',
        'submission_comment': 'Comment',
        'submitted_for_tracks': {
            'title': 'Tracks',
            'convert':
            lambda change: [sorted(t.title for t in x) for x in change]
        },
        'submitted_contrib_type': {
            'title': 'Contribution type',
            'type': 'string',
            'convert': lambda change: [t.name if t else None for t in change]
        }
    }
    for field_name, change in changes.iteritems():
        # we skip skip None -> '' changes (editing an abstract that
        # did not have a value for a new field yet without filling
        # it out)
        if not field_name.startswith('custom_') or not any(changes):
            continue
        field_id = int(field_name[7:])
        field = abstract.event.get_contribution_field(field_id)
        field_impl = field.field
        log_fields[field_name] = {
            'title':
            field.title,
            'type':
            field_impl.log_type,
            'convert':
            lambda change, field_impl=field_impl: map(
                field_impl.get_friendly_value, change)
        }
    abstract.event.log(EventLogRealm.management,
                       EventLogKind.change,
                       'Abstracts',
                       'Abstract {} modified'.format(abstract.verbose_title),
                       session.user,
                       data={'Changes': make_diff_log(changes, log_fields)})
Exemplo n.º 17
0
def close_cfa(event):
    event.cfa.close()
    logger.info("Call for abstracts for %s closed by %s", event, session.user)
    event.log(EventLogRealm.management, EventLogKind.negative, 'Abstracts',
              'Call for abstracts closed', session.user)
Exemplo n.º 18
0
def open_cfa(event):
    event.cfa.open()
    logger.info("Call for abstracts for %s opened by %s", event, session.user)
    event.log(EventLogRealm.management, EventLogKind.positive, 'Abstracts',
              'Call for abstracts opened', session.user)