"Fossies" - the Fresh Open Source Software Archive

Member "indico-2.2.5/indico/modules/events/abstracts/controllers/abstract_list.py" (6 Dec 2019, 10124 Bytes) of package /linux/www/indico-2.2.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "abstract_list.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.1.8_vs_2.2.

    1 # This file is part of Indico.
    2 # Copyright (C) 2002 - 2019 CERN
    3 #
    4 # Indico is free software; you can redistribute it and/or
    5 # modify it under the terms of the MIT License; see the
    6 # LICENSE file for more details.
    7 
    8 from __future__ import unicode_literals
    9 
   10 from collections import defaultdict
   11 from operator import attrgetter
   12 
   13 from flask import flash, jsonify, request, session
   14 from sqlalchemy.orm import joinedload, subqueryload
   15 
   16 from indico.modules.events.abstracts.controllers.base import RHManageAbstractsBase
   17 from indico.modules.events.abstracts.controllers.common import (AbstractsDownloadAttachmentsMixin, AbstractsExportCSV,
   18                                                                 AbstractsExportExcel, AbstractsExportPDFMixin,
   19                                                                 CustomizeAbstractListMixin, DisplayAbstractListMixin)
   20 from indico.modules.events.abstracts.forms import BulkAbstractJudgmentForm
   21 from indico.modules.events.abstracts.lists import AbstractListGeneratorManagement
   22 from indico.modules.events.abstracts.models.abstracts import Abstract, AbstractState
   23 from indico.modules.events.abstracts.models.persons import AbstractPersonLink
   24 from indico.modules.events.abstracts.operations import create_abstract, delete_abstract, judge_abstract
   25 from indico.modules.events.abstracts.schemas import abstract_review_questions_schema, abstracts_schema
   26 from indico.modules.events.abstracts.util import make_abstract_form
   27 from indico.modules.events.abstracts.views import WPManageAbstracts
   28 from indico.modules.events.contributions.models.persons import AuthorType
   29 from indico.modules.events.util import get_field_values
   30 from indico.util.i18n import _, ngettext
   31 from indico.web.util import jsonify_data, jsonify_form, jsonify_template
   32 
   33 
   34 class RHAbstractListBase(RHManageAbstractsBase):
   35     """Base class for all RHs using the abstract list generator"""
   36 
   37     def _process_args(self):
   38         RHManageAbstractsBase._process_args(self)
   39         self.list_generator = AbstractListGeneratorManagement(event=self.event)
   40 
   41 
   42 class RHManageAbstractsActionsBase(RHAbstractListBase):
   43     """Base class for RHs performing actions on selected abstracts"""
   44 
   45     _abstract_query_options = ()
   46 
   47     @property
   48     def _abstract_query(self):
   49         query = Abstract.query.with_parent(self.event)
   50         if self._abstract_query_options:
   51             query = query.options(*self._abstract_query_options)
   52         return query
   53 
   54     def _process_args(self):
   55         RHAbstractListBase._process_args(self)
   56         ids = map(int, request.form.getlist('abstract_id'))
   57         self.abstracts = self._abstract_query.filter(Abstract.id.in_(ids)).all()
   58 
   59 
   60 class RHBulkAbstractJudgment(RHManageAbstractsActionsBase):
   61     """Perform bulk judgment operations on selected abstracts"""
   62 
   63     def _process(self):
   64         form = BulkAbstractJudgmentForm(event=self.event, abstract_id=[a.id for a in self.abstracts],
   65                                         judgment=request.form.get('judgment'))
   66         if form.validate_on_submit():
   67             judgment_data, abstract_data = form.split_data
   68             submitted_abstracts = {abstract for abstract in self.abstracts if abstract.state == AbstractState.submitted}
   69             for abstract in submitted_abstracts:
   70                 judge_abstract(abstract, abstract_data, judge=session.user, **judgment_data)
   71             num_judged_abstracts = len(submitted_abstracts)
   72             num_prejudged_abstracts = len(self.abstracts) - num_judged_abstracts
   73             if num_judged_abstracts:
   74                 flash(ngettext("One abstract has been judged.",
   75                                "{num} abstracts have been judged.",
   76                                num_judged_abstracts).format(num=num_judged_abstracts), 'success')
   77             if num_prejudged_abstracts:
   78                 flash(ngettext("One abstract has been skipped since it is already judged.",
   79                                "{num} abstracts have been skipped since they are already judged.",
   80                                num_prejudged_abstracts).format(num=num_prejudged_abstracts), 'warning')
   81             return jsonify_data(**self.list_generator.render_list())
   82         return jsonify_form(form=form, fields=form._order, submit=_('Judge'), disabled_until_change=False)
   83 
   84 
   85 class RHAbstractList(DisplayAbstractListMixin, RHAbstractListBase):
   86     template = 'management/abstract_list.html'
   87     view_class = WPManageAbstracts
   88 
   89     def _render_template(self, **kwargs):
   90         kwargs['track_session_map'] = {track.id: track.default_session_id for track in self.event.tracks}
   91         return super(RHAbstractList, self)._render_template(**kwargs)
   92 
   93 
   94 class RHAbstractListCustomize(CustomizeAbstractListMixin, RHAbstractListBase):
   95     view_class = WPManageAbstracts
   96     ALLOW_LOCKED = True
   97 
   98 
   99 class RHAbstractListStaticURL(RHAbstractListBase):
  100     """Generate a static URL for the configuration of the abstract list"""
  101 
  102     ALLOW_LOCKED = True
  103 
  104     def _process(self):
  105         return jsonify(url=self.list_generator.generate_static_url())
  106 
  107 
  108 class RHCreateAbstract(RHAbstractListBase):
  109     def _process(self):
  110         abstract_form_class = make_abstract_form(self.event, session.user, notification_option=True, management=self.management)
  111         form = abstract_form_class(event=self.event, management=self.management)
  112         if form.validate_on_submit():
  113             data = form.data
  114             send_notifications = data.pop('send_notifications')
  115             abstract = create_abstract(self.event, *get_field_values(data), send_notifications=send_notifications)
  116             flash(_("Abstract '{}' created successfully").format(abstract.title), 'success')
  117             tpl_components = self.list_generator.render_list(abstract)
  118             if tpl_components.get('hide_abstract'):
  119                 self.list_generator.flash_info_message(abstract)
  120             return jsonify_data(**tpl_components)
  121         return jsonify_form(form, back=_("Cancel"), form_header_kwargs={'action': request.relative_url})
  122 
  123 
  124 class RHDeleteAbstracts(RHManageAbstractsActionsBase):
  125     def _process(self):
  126         delete_contribs = request.values.get('delete_contribs') == '1'
  127         deleted_contrib_count = 0
  128         for abstract in self.abstracts:
  129             if delete_contribs and abstract.contribution:
  130                 deleted_contrib_count += 1
  131             delete_abstract(abstract, delete_contribs)
  132         deleted_abstract_count = len(self.abstracts)
  133         flash(ngettext("The abstract has been deleted.",
  134                        "{count} abstracts have been deleted.", deleted_abstract_count)
  135               .format(count=deleted_abstract_count), 'success')
  136         if deleted_contrib_count:
  137             flash(ngettext("The linked contribution has been deleted.",
  138                            "{count} linked contributions have been deleted.", deleted_contrib_count)
  139                   .format(count=deleted_contrib_count), 'success')
  140         return jsonify_data(**self.list_generator.render_list())
  141 
  142 
  143 class RHAbstractPersonList(RHManageAbstractsActionsBase):
  144     """List of persons somehow related to abstracts (co-authors, speakers...)"""
  145 
  146     ALLOW_LOCKED = True
  147 
  148     @property
  149     def _membership_filter(self):
  150         abstract_ids = {abstract.id for abstract in self.abstracts}
  151         return Abstract.id.in_(abstract_ids)
  152 
  153     def _process(self):
  154         submitters = {abstract.submitter for abstract in self.abstracts}
  155         abstract_persons = AbstractPersonLink.find_all(AbstractPersonLink.abstract.has(self._membership_filter))
  156         abstract_persons_dict = defaultdict(lambda: {'speaker': False, 'submitter': False, 'primary_author': False,
  157                                                      'secondary_author': False})
  158         for abstract_person in abstract_persons:
  159             dict_key = abstract_person.person.user if abstract_person.person.user else abstract_person.person
  160             person_roles = abstract_persons_dict[dict_key]
  161             person_roles['speaker'] |= abstract_person.is_speaker
  162             person_roles['primary_author'] |= abstract_person.author_type == AuthorType.primary
  163             person_roles['secondary_author'] |= abstract_person.author_type == AuthorType.secondary
  164         for submitter in submitters:
  165             abstract_persons_dict[submitter]['submitter'] |= True
  166         return jsonify_template('events/abstracts/management/abstract_person_list.html',
  167                                 event_persons=abstract_persons_dict, event=self.event)
  168 
  169 
  170 class RHManageAbstractsExportActionsBase(RHManageAbstractsActionsBase):
  171     ALLOW_LOCKED = True
  172 
  173 
  174 class RHAbstractsDownloadAttachments(AbstractsDownloadAttachmentsMixin, RHManageAbstractsExportActionsBase):
  175     pass
  176 
  177 
  178 class RHAbstractsExportPDF(AbstractsExportPDFMixin, RHManageAbstractsExportActionsBase):
  179     pass
  180 
  181 
  182 class RHAbstractsExportCSV(AbstractsExportCSV, RHManageAbstractsExportActionsBase):
  183     pass
  184 
  185 
  186 class RHAbstractsExportExcel(AbstractsExportExcel, RHManageAbstractsExportActionsBase):
  187     pass
  188 
  189 
  190 class RHAbstractsExportJSON(RHManageAbstractsExportActionsBase):
  191     _abstract_query_options = (joinedload('submitter'),
  192                                joinedload('accepted_track'),
  193                                joinedload('accepted_contrib_type'),
  194                                joinedload('submitted_contrib_type'),
  195                                subqueryload('comments'),
  196                                subqueryload('field_values'),
  197                                subqueryload('submitted_for_tracks'),
  198                                subqueryload('reviewed_for_tracks'),
  199                                subqueryload('person_links'),
  200                                subqueryload('reviews').joinedload('ratings').joinedload('question'))
  201 
  202     def _process(self):
  203         abstracts = abstracts_schema.dump(sorted(self.abstracts, key=attrgetter('friendly_id')))
  204         questions = abstract_review_questions_schema.dump(self.event.abstract_review_questions)
  205         response = jsonify(version=1, abstracts=abstracts, questions=questions)
  206         response.headers['Content-Disposition'] = 'attachment; filename="abstracts.json"'
  207         return response