Beispiel #1
0
    def _process(self):
        from indico.modules.events.contributions import contribution_settings

        show_booking_warning = False
        if (config.ENABLE_ROOMBOOKING and not self.event.has_ended and self.event.room
                and not self.event.room_reservation_links):
            # Check if any of the managers of the event already have a booking that overlaps with the event datetime
            manager_ids = [p.user.id for p in self.event.acl_entries if p.user]
            has_overlap = (ReservationOccurrence.query
                           .filter(ReservationOccurrence.is_valid,
                                   db.or_(Reservation.booked_for_id.in_(manager_ids),
                                          Reservation.created_by_id.in_(manager_ids)),
                                   db_dates_overlap(ReservationOccurrence,
                                                    'start_dt', self.event.start_dt_local,
                                                    'end_dt', self.event.end_dt_local),
                                   Reservation.room_id == self.event.room.id,
                                   ~Room.is_deleted)
                           .join(Reservation)
                           .join(Room)
                           .has_rows())
            show_booking_warning = not has_overlap
        has_reference_types = ReferenceType.query.has_rows()
        has_event_labels = EventLabel.query.has_rows()
        show_draft_warning = (self.event.type_ == EventType.conference and
                              not contribution_settings.get(self.event, 'published') and
                              (TimetableEntry.query.with_parent(self.event).has_rows() or
                               Contribution.query.with_parent(self.event).has_rows()))
        return WPEventSettings.render_template('settings.html', self.event, 'settings',
                                               show_booking_warning=show_booking_warning,
                                               show_draft_warning=show_draft_warning,
                                               has_reference_types=has_reference_types,
                                               has_event_labels=has_event_labels)
Beispiel #2
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    event = abstract.event
    contrib_person_links = set()
    person_link_attrs = {'_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone', 'author_type',
                         'is_speaker', 'display_order'}
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)

    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {'custom_{}'.format(field_value.contribution_field.id): field_value.data for
                          field_value in abstract.field_values}
    return create_contribution(event, {'friendly_id': abstract.friendly_id,
                                       'title': abstract.title,
                                       'duration': duration,
                                       'description': abstract.description,
                                       'type': abstract.accepted_contrib_type,
                                       'track': abstract.accepted_track,
                                       'session': contrib_session,
                                       'person_link_data': {link: True for link in contrib_person_links}},
                               custom_fields_data=custom_fields_data)
Beispiel #3
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    event = abstract.event
    contrib_person_links = set()
    person_link_attrs = {
        '_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone',
        'author_type', 'is_speaker', 'display_order'
    }
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)

    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {
        'custom_{}'.format(field_value.contribution_field.id): field_value.data
        for field_value in abstract.field_values
    }
    return create_contribution(event, {
        'friendly_id': abstract.friendly_id,
        'title': abstract.title,
        'duration': duration,
        'description': abstract.description,
        'type': abstract.accepted_contrib_type,
        'track': abstract.accepted_track,
        'session': contrib_session,
        'person_link_data': {link: True
                             for link in contrib_person_links}
    },
                               custom_fields_data=custom_fields_data)
Beispiel #4
0
 def _check_access(self):
     RHDisplayEventBase._check_access(self)
     published = contribution_settings.get(self.event, 'published')
     if not published and not self.event.can_manage(session.user):
         raise NotFound(
             _('The contributions of this event have not been published yet'
               ))
Beispiel #5
0
 def _render_template(self, selected_entry, **kwargs):
     published = contribution_settings.get(self.event, 'published')
     return self.view_class.render_template(self.template,
                                            self.event,
                                            selected_entry=selected_entry,
                                            published=published,
                                            **kwargs)
Beispiel #6
0
 def _process(self):
     return self.view_class.render_template(
         'display/contribution_list.html',
         self.event,
         timezone=self.event.display_tzinfo,
         published=contribution_settings.get(self.event, 'published'),
         **self.list_generator.get_list_kwargs())
Beispiel #7
0
 def _check_access(self):
     RHDisplayEventBase._check_access(self)
     published = contribution_settings.get(self.event, 'published')
     if not published:
         raise NotFound(
             _("The contributions of this event have not been published yet"
               ))
Beispiel #8
0
 def _process(self):
     inherited_location = self.event.location_data
     inherited_location['inheriting'] = True
     default_duration = contribution_settings.get(self.event,
                                                  'default_duration')
     contrib_form_class = make_contribution_form(self.event)
     form = contrib_form_class(obj=FormDefaults(
         location_data=inherited_location, duration=default_duration),
                               event=self.event)
     if form.validate_on_submit():
         # Create empty contribution so it can be compared to the new one in flash_if_unregistered
         contrib = Contribution()
         with flash_if_unregistered(self.event,
                                    lambda: contrib.person_links):
             contrib = create_contribution(self.event,
                                           *get_field_values(form.data))
         flash(
             _("Contribution '{}' created successfully").format(
                 contrib.title), 'success')
         tpl_components = self.list_generator.render_list(contrib)
         if tpl_components['hide_contrib']:
             self.list_generator.flash_info_message(contrib)
         return jsonify_data(**tpl_components)
     return jsonify_template('events/contributions/forms/contribution.html',
                             form=form)
Beispiel #9
0
 def _check_access(self):
     RHAbstractsBase._check_access(self)
     published = contribution_settings.get(self.event, 'published')
     if not published:
         raise NotFound(
             _('The contributions of this event have not been published yet'
               ))
Beispiel #10
0
 def _has_access(self, user):
     event = Event.get(self._eventId, is_deleted=False)
     if event:
         can_manage = user is not None and event.can_manage(user)
         if not can_manage and not contribution_settings.get(event, 'published'):
             return False
     return True
Beispiel #11
0
 def can_edit(self, user):
     # Submitters can edit their own contributions if configured
     from indico.modules.events.contributions import contribution_settings
     submitters_can_edit = contribution_settings.get(
         self.event, 'submitters_can_edit')
     return self.can_manage(
         user, permission=('submit' if submitters_can_edit else None))
Beispiel #12
0
 def _check_access(self):
     RHDisplayEventBase._check_access(self)
     published = contribution_settings.get(self.event, 'published')
     if not self.contrib.can_access(session.user):
         raise Forbidden
     if not published:
         raise NotFound(_("The contributions of this event have not been published yet."))
Beispiel #13
0
 def _process(self):
     form = ContributionDefaultDurationForm(duration=contribution_settings.get(self.event, 'default_duration'))
     if form.validate_on_submit():
         contribution_settings.set(self.event, 'default_duration', form.duration.data)
         flash(_("Default contribution duration was changed successfully"))
         return jsonify_data()
     return jsonify_form(form)
Beispiel #14
0
    def _check_access(self):
        RHDisplayEventBase._check_access(self)
        published = contribution_settings.get(self.event, 'published')
        if not published:
            raise NotFound(_("The contributions of this event have not been published yet."))

        if not is_menu_entry_enabled(self.MENU_ENTRY_NAME, self.event):
            self._forbidden_if_not_admin()
Beispiel #15
0
 def _process(self):
     form = AllowSubmitterEditsForm(
         allow=contribution_settings.get(self.event, 'submitters_can_edit'))
     if form.validate_on_submit():
         contribution_settings.set(self.event, 'submitters_can_edit',
                                   form.allow.data)
         flash(_('Submitter edit settings changed successfully'), 'success')
         return jsonify_data()
     return jsonify_form(form)
Beispiel #16
0
 def _check_access(self):
     if not self.contrib.can_access(session.user):
         # perform event access check since it may send the user to the access key or registration page
         RHDisplayEventBase._check_access(self)
         raise Forbidden
     published = contribution_settings.get(self.event, 'published')
     if not published and not self._can_view_unpublished():
         raise NotFound(
             _('The contributions of this event have not been published yet.'
               ))
Beispiel #17
0
 def _check_access(self):
     RHDisplayEventBase._check_access(self)
     if not self.subcontrib.can_access(session.user):
         raise Forbidden
     published = contribution_settings.get(self.event, 'published')
     if (not published and not self.event.can_manage(session.user)
             and not self.contrib.is_user_associated(session.user)):
         raise NotFound(
             _("The contributions of this event have not been published yet."
               ))
Beispiel #18
0
 def _process(self):
     inherited_location = self.event.location_data
     inherited_location['inheriting'] = True
     default_duration = contribution_settings.get(self.event, 'default_duration')
     form = SessionForm(obj=FormDefaults(colors=get_random_color(self.event), location_data=inherited_location,
                                         default_contribution_duration=default_duration),
                        event=self.event)
     if form.validate_on_submit():
         new_session = create_session(self.event, form.data)
         return self._get_response(new_session)
     return jsonify_form(form)
Beispiel #19
0
    def _check_access(self):
        RHDisplayEventBase._check_access(self)
        published = contribution_settings.get(self.event, 'published')
        if not published and not has_contributions_with_user_as_submitter(
                self.event, session.user):
            raise NotFound(
                _('The contributions of this event have not been published yet.'
                  ))

        if not is_menu_entry_enabled(self.MENU_ENTRY_NAME, self.event):
            self._forbidden_if_not_admin()
Beispiel #20
0
 def _check_access(self):
     if not self.subcontrib.can_access(session.user):
         # perform event access check since it may send the user to the access key or registration page
         RHDisplayEventBase._check_access(self)
         raise Forbidden
     published = contribution_settings.get(self.event, 'published')
     if (not published and not self.event.can_manage(session.user)
             and not self.subcontrib.is_user_associated(session.user)):
         raise NotFound(
             _("The contributions of this event have not been published yet."
               ))
Beispiel #21
0
 def _process(self):
     inherited_location = self.event.location_data
     inherited_location['inheriting'] = True
     default_duration = contribution_settings.get(self.event, 'default_duration')
     form = SessionForm(obj=FormDefaults(colors=get_random_color(self.event), location_data=inherited_location,
                                         default_contribution_duration=default_duration),
                        event=self.event)
     if form.validate_on_submit():
         new_session = create_session(self.event, form.data)
         return self._get_response(new_session)
     return jsonify_form(form)
Beispiel #22
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    from indico.modules.events.abstracts.settings import abstracts_settings

    event = abstract.event
    contrib_person_links = set()
    author_submission_rights = (
        event.cfa.contribution_submitters == SubmissionRightsType.all)
    person_link_attrs = {
        '_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone',
        'author_type', 'is_speaker', 'display_order'
    }
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)
    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {
        f'custom_{field_value.contribution_field.id}': field_value.data
        for field_value in abstract.field_values
    }
    contrib = create_contribution(event, {
        'friendly_id': abstract.friendly_id,
        'title': abstract.title,
        'duration': duration,
        'description': abstract.description,
        'type': abstract.accepted_contrib_type,
        'track': abstract.accepted_track,
        'session': contrib_session,
        'person_link_data': {
            link: (author_submission_rights or link.is_speaker)
            for link in contrib_person_links
        }
    },
                                  custom_fields_data=custom_fields_data)
    if abstracts_settings.get(event, 'copy_attachments') and abstract.files:
        folder = AttachmentFolder.get_or_create_default(contrib)
        for abstract_file in abstract.files:
            attachment = Attachment(user=abstract.submitter,
                                    type=AttachmentType.file,
                                    folder=folder,
                                    title=abstract_file.filename)
            attachment.file = AttachmentFile(
                user=abstract.submitter,
                filename=abstract_file.filename,
                content_type=abstract_file.content_type)
            with abstract_file.open() as fd:
                attachment.file.save(fd)
    db.session.flush()
    return contrib
Beispiel #23
0
 def _process(self):
     contrib = (Contribution.query.filter_by(id=self.contrib.id).options(
         joinedload('type'), joinedload('session'),
         joinedload('subcontributions'),
         joinedload('timetable_entry').lazyload('*')).one())
     can_manage = self.event.can_manage(session.user)
     owns_abstract = contrib.abstract.user_owns(
         session.user) if contrib.abstract else None
     field_values = filter_field_values(contrib.field_values, can_manage,
                                        owns_abstract)
     return self.view_class.render_template(
         'display/contribution_display.html',
         self.event,
         contribution=contrib,
         show_author_link=_author_page_active(self.event),
         field_values=field_values,
         page_title=contrib.title,
         published=contribution_settings.get(self.event, 'published'))
Beispiel #24
0
 def _process(self):
     inherited_location = self.event.location_data
     inherited_location['inheriting'] = True
     default_duration = contribution_settings.get(self.event, 'default_duration')
     contrib_form_class = make_contribution_form(self.event)
     form = contrib_form_class(obj=FormDefaults(location_data=inherited_location, duration=default_duration),
                               event=self.event)
     if form.validate_on_submit():
         # Create empty contribution so it can be compared to the new one in flash_if_unregistered
         contrib = Contribution()
         with flash_if_unregistered(self.event, lambda: contrib.person_links):
             contrib = create_contribution(self.event, *get_field_values(form.data))
         flash(_("Contribution '{}' created successfully").format(contrib.title), 'success')
         tpl_components = self.list_generator.render_list(contrib)
         if tpl_components['hide_contrib']:
             self.list_generator.flash_info_message(contrib)
         return jsonify_data(**tpl_components)
     return jsonify_template('events/contributions/forms/contribution.html', form=form)
Beispiel #25
0
 def _process(self):
     self.event.preload_all_acl_entries()
     if self.theme is None:
         event_info = serialize_event_info(self.event)
         timetable_data = TimetableSerializer(
             self.event).serialize_timetable(strip_empty_days=True)
         timetable_settings = layout_settings.get(
             self.event, 'timetable_theme_settings')
         return self.view_class.render_template(
             'display.html',
             self.event,
             event_info=event_info,
             timetable_data=timetable_data,
             timetable_settings=timetable_settings,
             timetable_layout=self.timetable_layout,
             published=contribution_settings.get(self.event, 'published'))
     else:
         return self.view_class_simple(self, self.event, self.theme,
                                       self.theme_override).display()
Beispiel #26
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    from indico.modules.events.abstracts.settings import abstracts_settings

    event = abstract.event
    contrib_person_links = set()
    person_link_attrs = {'_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone', 'author_type',
                         'is_speaker', 'display_order'}
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)

    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {'custom_{}'.format(field_value.contribution_field.id): field_value.data for
                          field_value in abstract.field_values}
    contrib = create_contribution(event, {'friendly_id': abstract.friendly_id,
                                          'title': abstract.title,
                                          'duration': duration,
                                          'description': abstract.description,
                                          'type': abstract.accepted_contrib_type,
                                          'track': abstract.accepted_track,
                                          'session': contrib_session,
                                          'person_link_data': {link: True for link in contrib_person_links}},
                                  custom_fields_data=custom_fields_data)
    if abstracts_settings.get(event, 'copy_attachments') and abstract.files:
        folder = AttachmentFolder.get_or_create_default(contrib)
        for abstract_file in abstract.files:
            attachment = Attachment(user=abstract.submitter, type=AttachmentType.file, folder=folder,
                                    title=abstract_file.filename)
            attachment.file = AttachmentFile(user=abstract.submitter, filename=abstract_file.filename,
                                             content_type=abstract_file.content_type)
            with abstract_file.open() as fd:
                attachment.file.save(fd)
    db.session.flush()
    return contrib
Beispiel #27
0
 def _process_GET(self):
     return jsonify(contribution_settings.get(self.event, 'published'))
Beispiel #28
0
 def _visible_timetable(event):
     return contribution_settings.get(event, 'published')
Beispiel #29
0
 def _default_duration(self):
     return contribution_settings.get(self.event, 'default_duration')
Beispiel #30
0
 def _serialize_timetable(self, event, user):
     if not contribution_settings.get(
             event, 'published') and not event.can_manage(user):
         return {}
     return TimetableSerializer(event, management=False,
                                user=user).serialize_timetable()
Beispiel #31
0
    def _build_event_api_data(self, event):
        can_manage = self.user is not None and event.can_manage(self.user)
        data = self._build_event_api_data_base(event)
        data.update({
            '_fossil':
            self.fossils_mapping['event'].get(self._detail_level),
            'categoryId':
            event.category_id,
            'category':
            event.category.title,
            'note':
            build_note_api_data(event.note),
            'roomFullname':
            event.room_name,
            'url':
            event.external_url,
            'creationDate':
            self._serialize_date(event.created_dt),
            'creator':
            self._serialize_person(event.creator,
                                   person_type='Avatar',
                                   can_manage=can_manage),
            'hasAnyProtection':
            event.effective_protection_mode != ProtectionMode.public,
            'roomMapURL':
            event.room.map_url if event.room else None,
            'folders':
            build_folders_api_data(event),
            'chairs':
            self._serialize_persons(event.person_links,
                                    person_type='ConferenceChair',
                                    can_manage=can_manage),
            'material':
            build_material_legacy_api_data(event) +
            filter(None, [build_note_legacy_api_data(event.note)]),
            'keywords':
            event.keywords,
        })

        event_category_path = event.category.chain
        visibility = {'id': '', 'name': 'Everywhere'}
        if event.visibility is None:
            pass  # keep default
        elif event.visibility == 0:
            visibility['name'] = 'Nowhere'
        elif event.visibility:
            try:
                path_segment = event_category_path[-event.visibility]
            except IndexError:
                pass
            else:
                visibility['id'] = path_segment['id']
                visibility['name'] = path_segment['title']
        data['visibility'] = visibility

        if can_manage:
            data['allowed'] = self._serialize_access_list(event)

        allow_details = contribution_settings.get(event,
                                                  'published') or can_manage
        if self._detail_level in {'contributions', 'subcontributions'
                                  } and allow_details:
            data['contributions'] = []
            for contribution in event.contributions:
                include_subcontribs = self._detail_level == 'subcontributions'
                serialized_contrib = self._serialize_contribution(
                    contribution, include_subcontribs)
                data['contributions'].append(serialized_contrib)
        elif self._detail_level == 'sessions' and allow_details:
            # Contributions without a session
            data['contributions'] = []
            for contribution in event.contributions:
                if not contribution.session:
                    serialized_contrib = self._serialize_contribution(
                        contribution)
                    data['contributions'].append(serialized_contrib)

            data['sessions'] = []
            for session_ in event.sessions:
                data['sessions'].extend(self._build_session_api_data(session_))
        if self._occurrences:
            data['occurrences'] = fossilize(self._calculate_occurrences(
                event, self._fromDT, self._toDT,
                pytz.timezone(config.DEFAULT_TIMEZONE)),
                                            {Period: IPeriodFossil},
                                            tz=self._tz,
                                            naiveTZ=config.DEFAULT_TIMEZONE)
        # check whether the plugins want to add/override any data
        for update in values_from_signal(
                signals.event.metadata_postprocess.send('http-api',
                                                        event=event,
                                                        data=data),
                as_list=True):
            data.update(update)
        return data
Beispiel #32
0
class CategoryEventFetcher(IteratedDataFetcher, SerializerBase):
    def __init__(self, user, hook):
        super().__init__(user, hook)
        self._eventType = hook._eventType
        self._occurrences = hook._occurrences
        self._location = hook._location
        self._room = hook._room
        self.user = user
        self._detail_level = get_query_parameter(request.args.to_dict(), ['d', 'detail'], 'events')
        if self._detail_level not in ('events', 'contributions', 'subcontributions', 'sessions'):
            raise HTTPAPIError(f'Invalid detail level: {self._detail_level}', 400)

    def _calculate_occurrences(self, event, from_dt, to_dt, tz):
        start_dt = max(from_dt, event.start_dt) if from_dt else event.start_dt
        end_dt = min(to_dt, event.end_dt) if to_dt else event.end_dt
        for day in iterdays(start_dt, end_dt):
            first_start, last_end = find_event_day_bounds(event, day.date())
            if first_start is not None:
                yield Period(first_start, last_end)

    def _get_query_options(self, detail_level):
        acl_user_strategy = joinedload('acl_entries').joinedload('user')
        # remote group membership checks will trigger a load on _all_emails
        # but not all events use this so there's no need to eager-load them
        # acl_user_strategy.noload('_primary_email')
        # acl_user_strategy.noload('_affiliation')
        creator_strategy = joinedload('creator')
        contributions_strategy = subqueryload('contributions')
        contributions_strategy.subqueryload('references')
        if detail_level in {'subcontributions', 'sessions'}:
            contributions_strategy.subqueryload('subcontributions').subqueryload('references')
        sessions_strategy = subqueryload('sessions')
        options = [acl_user_strategy, creator_strategy]
        if detail_level in {'contributions', 'subcontributions', 'sessions'}:
            options.append(contributions_strategy)
        if detail_level == 'sessions':
            options.append(sessions_strategy)
        options.append(undefer('effective_protection_mode'))
        return options

    def category(self, idlist, format):
        try:
            idlist = list(map(int, idlist))
        except ValueError:
            raise HTTPAPIError('Category IDs must be numeric', 400)
        if format == 'ics':
            buf = serialize_categories_ical(idlist, self.user,
                                            event_filter=Event.happens_between(self._fromDT, self._toDT),
                                            event_filter_fn=self._filter_event,
                                            update_query=self._update_query)
            return send_file('events.ics', buf, 'text/calendar')
        else:
            query = (Event.query
                     .filter(~Event.is_deleted,
                             Event.category_chain_overlaps(idlist),
                             Event.happens_between(self._fromDT, self._toDT))
                     .options(*self._get_query_options(self._detail_level)))
        query = self._update_query(query)
        return self.serialize_events(x for x in query if self._filter_event(x) and x.can_access(self.user))

    def category_extra(self, ids):
        if self._toDT is None:
            has_future_events = False
        else:
            query = Event.find(Event.category_id.in_(ids), ~Event.is_deleted, Event.start_dt > self._toDT)
            has_future_events = query.has_rows()
        return {
            'eventCategories': self._build_category_path_data(ids),
            'moreFutureEvents': has_future_events
        }

    def event(self, idlist):
        query = (Event.find(Event.id.in_(idlist),
                            ~Event.is_deleted,
                            Event.happens_between(self._fromDT, self._toDT))
                 .options(*self._get_query_options(self._detail_level)))
        query = self._update_query(query)
        return self.serialize_events(x for x in query if self._filter_event(x) and x.can_access(self.user))

    def _filter_event(self, event):
        if self._room or self._location or self._eventType:
            if self._eventType and event.type_.name != self._eventType:
                return False
            if self._location:
                name = event.venue_name
                if not name or not fnmatch.fnmatch(name.lower(), self._location.lower()):
                    return False
            if self._room:
                name = event.room_name
                if not name or not fnmatch.fnmatch(name.lower(), self._room.lower()):
                    return False
        return True

    def _update_query(self, query):
        order = get_query_parameter(request.args.to_dict(), ['o', 'order'])
        desc = get_query_parameter(request.args.to_dict(), ['c', 'descending']) == 'yes'
        limit = get_query_parameter(request.args.to_dict(), ['n', 'limit'])
        offset = get_query_parameter(request.args.to_dict(), ['O', 'offset'])

        col = {
            'start': Event.start_dt,
            'end': Event.end_dt,
            'id': Event.id,
            'title': Event.title
        }.get(order)
        if col:
            query = query.order_by(col.desc() if desc else col)
        if limit:
            query = query.limit(limit)
        if offset:
            query = query.offset(offset)

        return query

    def serialize_events(self, events):
        return list(map(self._build_event_api_data, events))

    def _serialize_category_path(self, category):
        visibility = {'id': None, 'name': 'Everywhere'}
        path = [self._serialize_path_entry(category_data) for category_data in category.chain]
        if category.visibility is not None:
            try:
                path_segment = path[-category.visibility]
            except IndexError:
                pass
            else:
                visibility['id'] = path_segment['id']
                visibility['name'] = path_segment['name']
        path.append({'visibility': visibility})
        return path

    def _serialize_path_entry(self, category_data):
        return {
            '_fossil': 'categoryMetadata',
            'type': 'Category',
            'name': category_data['title'],
            'id': category_data['id'],
            'url': url_for('categories.display', category_id=category_data['id'], _external=True)
        }

    def _build_category_path_data(self, ids):
        return [{'_type': 'CategoryPath', 'categoryId': category.id, 'path': self._serialize_category_path(category)}
                for category in Category.query.filter(Category.id.in_(ids)).options(undefer('chain'))]

    def _build_event_api_data(self, event):
        can_manage = self.user is not None and event.can_manage(self.user)
        data = self._build_event_api_data_base(event)
        material_data = build_material_legacy_api_data(event)
        if legacy_note_material := build_note_legacy_api_data(event.note):
            material_data.append(legacy_note_material)
        data.update({
            '_fossil': self.fossils_mapping['event'].get(self._detail_level),
            'categoryId': event.category_id,
            'category': event.category.title,
            'note': build_note_api_data(event.note),
            'roomFullname': event.room_name,
            'url': event.external_url,
            'creationDate': self._serialize_date(event.created_dt),
            'creator': self._serialize_person(event.creator, person_type='Avatar', can_manage=can_manage),
            'hasAnyProtection': event.effective_protection_mode != ProtectionMode.public,
            'roomMapURL': event.room.map_url if event.room else None,
            'folders': build_folders_api_data(event),
            'chairs': self._serialize_persons(event.person_links, person_type='ConferenceChair', can_manage=can_manage),
            'material': material_data,
            'keywords': event.keywords,
        })

        event_category_path = event.category.chain
        visibility = {'id': '', 'name': 'Everywhere'}
        if event.visibility is None:
            pass  # keep default
        elif event.visibility == 0:
            visibility['name'] = 'Nowhere'
        elif event.visibility:
            try:
                path_segment = event_category_path[-event.visibility]
            except IndexError:
                pass
            else:
                visibility['id'] = path_segment['id']
                visibility['name'] = path_segment['title']
        data['visibility'] = visibility

        if can_manage:
            data['allowed'] = self._serialize_access_list(event)

        allow_details = contribution_settings.get(event, 'published') or can_manage
        if self._detail_level in {'contributions', 'subcontributions'}:
            data['contributions'] = []
            if allow_details:
                for contribution in event.contributions:
                    include_subcontribs = self._detail_level == 'subcontributions'
                    serialized_contrib = self._serialize_contribution(contribution, include_subcontribs)
                    data['contributions'].append(serialized_contrib)
        elif self._detail_level == 'sessions':
            data['contributions'] = []
            data['sessions'] = []
            if allow_details:
                # Contributions without a session
                for contribution in event.contributions:
                    if not contribution.session:
                        serialized_contrib = self._serialize_contribution(contribution)
                        data['contributions'].append(serialized_contrib)

                for session_ in event.sessions:
                    data['sessions'].extend(self._build_session_api_data(session_))
        if self._occurrences:
            data['occurrences'] = fossilize(self._calculate_occurrences(event, self._fromDT, self._toDT,
                                            pytz.timezone(config.DEFAULT_TIMEZONE)),
                                            {Period: IPeriodFossil}, tz=self._tz, naiveTZ=config.DEFAULT_TIMEZONE)
        # check whether the plugins want to add/override any data
        for update in values_from_signal(
                signals.event.metadata_postprocess.send('http-api', event=event, data=data), as_list=True):
            data.update(update)
        return data
Beispiel #33
0
 def _boa_visible(event):
     return (config.LATEX_ENABLED and event.has_feature('abstracts')
             and contribution_settings.get(event, 'published'))
Beispiel #34
0
def should_show_draft_warning(event):
    return (event.type_ == EventType.conference and
            not contribution_settings.get(event, 'published') and
            (TimetableEntry.query.with_parent(event).has_rows() or
             Contribution.query.with_parent(event).has_rows()))
Beispiel #35
0
 def _default_duration(self):
     return contribution_settings.get(self.event, 'default_duration')