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)
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)