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 _process(self): defaults = FormDefaults( content_review_questions=self.event.cfp.content_review_questions, layout_review_questions=self.event.cfp.layout_review_questions, **paper_reviewing_settings.get_all(self.event)) form = PaperReviewingSettingsForm(event=self.event, obj=defaults) if form.validate_on_submit(): data = form.data content_review_questions = data.pop('content_review_questions', None) layout_review_questions = data.pop('layout_review_questions', None) if content_review_questions is None: content_review_questions = self.event.cfp.content_review_questions if layout_review_questions is None: layout_review_questions = self.event.cfp.layout_review_questions self.event.paper_review_questions = content_review_questions + layout_review_questions email_settings = data.pop('email_settings') data.update(email_settings) paper_reviewing_settings.set_multi(self.event, data) flash(_("The reviewing settings were saved successfully"), 'success') logger.info("Paper reviewing settings of %r updated by %r", self.event, session.user) return jsonify_data() self.commit = False return jsonify_form(form)
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 update_review(review, review_data, questions_data): paper = review.revision.paper event = paper.event changes = review.populate_from_dict(review_data) review.modified_dt = now_utc() log_fields = {} for question in event.cfp.get_questions_for_review_type(review.type): 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() notify_paper_review_submission(review) logger.info("Paper review %r modified", review) log_fields.update({ 'proposed_action': 'Action', 'comment': 'Comment' }) event.log(EventLogRealm.management, EventLogKind.change, 'Papers', 'Review for paper {} modified'.format(paper.verbose_title), session.user, data={'Changes': make_diff_log(changes, log_fields)})
def reset_paper_state(paper): paper.reset_state() db.session.flush() notify_paper_judgment(paper, reset=True) logger.info('Paper %r state reset by %r', paper, session.user) paper.event.log(EventLogRealm.management, EventLogKind.change, 'Papers', 'Judgment {} reset'.format(paper.verbose_title), session.user)
def update_team_members(event, managers, judges, content_reviewers=None, layout_reviewers=None): updated = {} update_object_principals(event, managers, role='paper_manager') updated[PaperReviewingRole.judge] = update_object_principals(event, judges, role='paper_judge') if content_reviewers is not None: updated[PaperReviewingRole.content_reviewer] = update_object_principals(event, content_reviewers, role='paper_content_reviewer') if layout_reviewers is not None: updated[PaperReviewingRole.layout_reviewer] = update_object_principals(event, layout_reviewers, role='paper_layout_reviewer') unassigned_contribs = _unassign_removed(event, updated) roles_to_notify = paper_reviewing_settings.get(event, 'notify_on_added_to_event') if PaperReviewingRole.judge in roles_to_notify: for judge in updated[PaperReviewingRole.judge]['added']: notify_added_to_reviewing_team(judge, PaperReviewingRole.judge, event) for judge in updated[PaperReviewingRole.judge]['removed']: notify_removed_from_reviewing_team(judge, PaperReviewingRole.judge, event) if PaperReviewingRole.content_reviewer in roles_to_notify: for reviewer in updated[PaperReviewingRole.content_reviewer]['added']: notify_added_to_reviewing_team(reviewer, PaperReviewingRole.content_reviewer, event) for reviewer in updated[PaperReviewingRole.content_reviewer]['removed']: notify_removed_from_reviewing_team(reviewer, PaperReviewingRole.content_reviewer, event) if PaperReviewingRole.layout_reviewer in roles_to_notify: for reviewer in updated[PaperReviewingRole.layout_reviewer]['added']: notify_added_to_reviewing_team(reviewer, PaperReviewingRole.layout_reviewer, event) for reviewer in updated[PaperReviewingRole.layout_reviewer]['removed']: notify_removed_from_reviewing_team(reviewer, PaperReviewingRole.layout_reviewer, event) logger.info("Paper teams of %r updated by %r", event, session.user) return unassigned_contribs
def delete_comment(comment): comment.is_deleted = True db.session.flush() logger.info("Paper comment %r deleted by %r", comment, session.user) paper = comment.paper_revision.paper paper.event.log(EventLogRealm.management, EventLogKind.negative, 'Papers', 'Comment on paper {} removed'.format(paper.verbose_title), session.user)
def update_competences(user_competences, competences): event = user_competences.event user_competences.competences = competences logger.info("Competences for user %r in event %r updated by %r", user_competences.user, event, session.user) event.log(EventLogRealm.management, EventLogKind.positive, 'Papers', "Updated competences for user {}".format(user_competences.user.full_name), session.user, data={'Competences': ', '.join(competences)})
def create_paper_template(event, data): file = data.pop('template') template = PaperTemplate(event=event) template.populate_from_dict(data) _store_paper_template_file(template, file) db.session.flush() logger.info('Paper template %r uploaded by %r', template, session.user) return template
def set_deadline(event, role, deadline, enforce=True): paper_reviewing_settings.set_multi(event, { '{}_deadline'.format(role.name): deadline, 'enforce_{}_deadline'.format(role.name): enforce }) log_data = {'Enforced': enforce, 'Deadline': deadline.isoformat() if deadline else 'None'} logger.info('Paper reviewing deadline (%s) set in %r by %r', role.name, event, session.user) event.log(EventLogRealm.management, EventLogKind.change, 'Papers', "Paper reviewing deadline ({}) set".format(role.title), session.user, data=log_data)
def update_comment(comment, text, visibility): changes = comment.populate_from_dict({'text': text, 'visibility': visibility}) comment.modified_by = session.user comment.modified_dt = now_utc() db.session.flush() logger.info("Paper comment %r modified by %r", comment, session.user) paper = comment.paper_revision.paper paper.event.log(EventLogRealm.management, EventLogKind.change, 'Papers', 'Comment on paper {} modified'.format(paper.verbose_title), session.user, data={'Changes': make_diff_log(changes, {'text': 'Text', 'visibility': 'Visibility'})})
def schedule_cfp(event, start_dt, end_dt): event.cfp.schedule(start_dt, end_dt) log_data = {} if start_dt: log_data['Start'] = start_dt.isoformat() if end_dt: log_data['End'] = end_dt.isoformat() logger.info("Call for papers for %r scheduled by %r", event, session.user) event.log(EventLogRealm.management, EventLogKind.change, 'Papers', 'Call for papers scheduled', session.user, data=log_data)
def create_paper_revision(paper, submitter, files): revision = PaperRevision(paper=paper, submitter=submitter) for f in files: filename = secure_filename(f.filename, 'paper') content_type = mimetypes.guess_type(f.filename)[0] or f.mimetype or 'application/octet-stream' pf = PaperFile(filename=filename, content_type=content_type, paper_revision=revision, _contribution=paper.contribution) pf.save(f.stream) db.session.flush() db.session.expire(revision._contribution, ['_paper_last_revision']) notify_paper_revision_submission(revision) logger.info('Paper revision %r submitted by %r', revision, session.user) paper.event.log(EventLogRealm.management, EventLogKind.positive, 'Papers', "Paper revision {} submitted for contribution {} ({})" .format(revision.id, paper.contribution.title, paper.contribution.friendly_id), session.user) return revision
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_comment(paper, text, visibility, user): comment = PaperReviewComment(user=user, text=text, visibility=visibility) paper.last_revision.comments.append(comment) db.session.flush() recipients = {x for x in paper.contribution.paper_judges} if visibility == PaperCommentVisibility.contributors or visibility == PaperCommentVisibility.reviewers: recipients |= paper.contribution.paper_layout_reviewers if paper.cfp.layout_reviewing_enabled else set() recipients |= paper.contribution.paper_content_reviewers if paper.cfp.content_reviewing_enabled else set() if visibility == PaperCommentVisibility.contributors: recipients |= {x.person for x in paper.contribution.person_links if x.person.email and x.person.email != user.email} recipients.discard(user) for receiver in recipients: notify_comment(receiver, paper, text, user) logger.info("Paper %r received a comment from %r", paper, session.user) paper.event.log(EventLogRealm.management, EventLogKind.positive, 'Papers', 'Paper {} received a comment'.format(paper.verbose_title), session.user)
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 open_cfp(event): event.cfp.open() logger.info("Call for papers for %r opened by %r", event, session.user) event.log(EventLogRealm.management, EventLogKind.positive, 'Papers', 'Call for papers opened', session.user)
def create_competences(event, user, competences): PaperCompetence(event=event, user=user, competences=competences) logger.info("Competences for user %r for event %r created by %r", user, event, session.user) event.log(EventLogRealm.management, EventLogKind.positive, 'Papers', "Added competences of {}".format(user.full_name), session.user, data={'Competences': ', '.join(competences)})
def delete_paper_template(template): db.session.delete(template) db.session.flush() logger.info('Paper template %r deleted by %r', template, session.user)
def update_paper_template(template, data): file = data.pop('template', None) template.populate_from_dict(data) if file is not None: _store_paper_template_file(template, file) logger.info('Paper template %r updated by %r', template, session.user)
def close_cfp(event): event.cfp.close() logger.info("Call for papers for %r closed by %r", event, session.user) event.log(EventLogRealm.management, EventLogKind.negative, 'Papers', 'Call for papers closed', session.user)