def _process_cascaded_event_contents(records, additional_events=None): """ Flatten a series of records into its most basic elements (subcontribution level). Yields results. :param records: queue records to process :param additional_events: events whose content will be included in addition to those found in records """ changed_events = additional_events or set() changed_contributions = set() changed_subcontributions = set() session_records = {rec.session_id for rec in records if rec.type == EntryType.session} contribution_records = {rec.contrib_id for rec in records if rec.type == EntryType.contribution} subcontribution_records = {rec.subcontrib_id for rec in records if rec.type == EntryType.subcontribution} event_records = {rec.event_id for rec in records if rec.type == EntryType.event} if event_records: changed_events.update(Event.find(Event.id.in_(event_records))) for event in changed_events: yield event # Sessions are added (explicitly changed only, since they don't need to be sent anywhere) if session_records: changed_contributions.update(Contribution .find(Contribution.session_id.in_(session_records), ~Contribution.is_deleted)) # Contributions are added (implictly + explicitly changed) changed_event_ids = {ev.id for ev in changed_events} condition = Contribution.event_id.in_(changed_event_ids) & ~Contribution.is_deleted if contribution_records: condition = db.or_(condition, Contribution.id.in_(contribution_records)) contrib_query = Contribution.find(condition).options(joinedload('subcontributions')) for contribution in contrib_query: yield contribution changed_subcontributions.update(contribution.subcontributions) # Same for subcontributions if subcontribution_records: changed_subcontributions.update(SubContribution.find(SubContribution.id.in_(subcontribution_records))) for subcontrib in changed_subcontributions: yield subcontrib
def _handleGet(self): contributions = (Contribution.find( event_new=self._conf.as_event, is_deleted=False).options(joinedload('timetable_entry'), joinedload('paper_reviewing_roles'))) filter = {} #filtering if the active user is a referee: he can only see his own contribs isOnlyReferee = RCReferee.hasRights(self) \ and not RCPaperReviewManager.hasRights(self) \ and not self._conf.canModify(self.getAW()) # We want to make an 'or', not an 'and' of the reviewing assign status filter["reviewing"] = {} if isOnlyReferee: filter["reviewing"]["referee"] = self._getUser() elif self._showWithReferee: filter["reviewing"]["referee"] = "any" if self._showWithEditor: filter["reviewing"]["editor"] = "any" if self._showWithReviewer: filter["reviewing"]["reviewer"] = "any" filter["type"] = self._selTypes filter["track"] = self._selTracks filter["session"] = self._selSessions filter["materialsubmitted"] = self._showWithMaterial filterCrit = ContributionsReviewingFilterCrit(self._conf, filter) sortingCrit = contribFilters.SortingCriteria(["number"]) filterCrit.getField("type").setShowNoValue(self._typeShowNoValue) filterCrit.getField("track").setShowNoValue(self._trackShowNoValue) filterCrit.getField("session").setShowNoValue(self._sessionShowNoValue) filterCrit.getField("reviewing").setShowNoValue(self._showWithoutTeam) filterCrit.getField("materialsubmitted").setShowNoValue( self._showWithoutMaterial) f = filters.SimpleFilter(filterCrit, sortingCrit) contributions = f.apply(contributions) return [_serialize_contribution(contrib) for contrib in contributions]
def _handleGet(self): contributions = Contribution.find(event_new=self._conf.as_event, is_deleted=False).options( joinedload("timetable_entry"), joinedload("paper_reviewing_roles") ) filter = {} # filtering if the active user is a referee: he can only see his own contribs isOnlyReferee = ( RCReferee.hasRights(self) and not RCPaperReviewManager.hasRights(self) and not self._conf.canModify(self.getAW()) ) # We want to make an 'or', not an 'and' of the reviewing assign status filter["reviewing"] = {} if isOnlyReferee: filter["reviewing"]["referee"] = self._getUser() elif self._showWithReferee: filter["reviewing"]["referee"] = "any" if self._showWithEditor: filter["reviewing"]["editor"] = "any" if self._showWithReviewer: filter["reviewing"]["reviewer"] = "any" filter["type"] = self._selTypes filter["track"] = self._selTracks filter["session"] = self._selSessions filter["materialsubmitted"] = self._showWithMaterial filterCrit = ContributionsReviewingFilterCrit(self._conf, filter) sortingCrit = contribFilters.SortingCriteria(["number"]) filterCrit.getField("type").setShowNoValue(self._typeShowNoValue) filterCrit.getField("track").setShowNoValue(self._trackShowNoValue) filterCrit.getField("session").setShowNoValue(self._sessionShowNoValue) filterCrit.getField("reviewing").setShowNoValue(self._showWithoutTeam) filterCrit.getField("materialsubmitted").setShowNoValue(self._showWithoutMaterial) f = filters.SimpleFilter(filterCrit, sortingCrit) contributions = f.apply(contributions) return [_serialize_contribution(contrib) for contrib in contributions]
def _migrate_papers(self): contributions = { c.id: c for c in (Contribution.find(event_new=self.event).options( joinedload('legacy_paper_reviewing_roles'))) } if not hasattr(self.pr, '_contribution_index'): self.importer.print_warning( cformat('%{yellow!}Event has no contribution index!'), event_id=self.event.id) return for contrib_id, rm in self.pr._contribution_index.iteritems(): if contrib_id not in contributions: self.importer.print_warning( cformat('%{yellow!}Contribution {} not found in event' ).format(contrib_id), event_id=self.event.id) continue contribution = contributions[contrib_id] self._migrate_paper_roles(contribution) self._migrate_revisions(contribution, rm)
def get_category_timetable(categ_ids, start_dt, end_dt, detail_level='event', tz=utc, from_categ=None, grouped=True): """Retrieve time blocks that fall within a specific time interval for a given set of categories. :param categ_ids: iterable containing list of category IDs :param start_dt: start of search interval (``datetime``, expected to be in display timezone) :param end_dt: end of search interval (``datetime`` in expected to be in display timezone) :param detail_level: the level of detail of information (``event|session|contribution``) :param tz: the ``timezone`` information should be displayed in :param from_categ: ``Category`` that will be taken into account to calculate visibility :param grouped: Whether to group results by start date :returns: a dictionary containing timetable information in a structured way. See source code for examples. """ day_start = start_dt.astimezone(utc) day_end = end_dt.astimezone(utc) dates_overlap = lambda t: (t.start_dt >= day_start) & (t.start_dt <= day_end) items = defaultdict(lambda: defaultdict(list)) # first of all, query TimetableEntries/events that fall within # specified range of dates (and category set) events = _query_events(categ_ids, day_start, day_end) if from_categ: events = events.filter(Event.is_visible_in(from_categ)) for eid, tt_start_dt in events: if tt_start_dt: items[eid][tt_start_dt.astimezone(tz).date()].append(tt_start_dt) else: items[eid] = None # then, retrieve detailed information about the events event_ids = set(items) query = (Event.find(Event.id.in_(event_ids)) .options(subqueryload(Event.person_links).joinedload(EventPersonLink.person), joinedload(Event.own_room).noload('owner'), joinedload(Event.own_venue), joinedload(Event.category).undefer('effective_icon_data'), undefer('effective_protection_mode'))) scheduled_events = defaultdict(list) ongoing_events = [] events = [] for e in query: if grouped: local_start_dt = e.start_dt.astimezone(tz).date() local_end_dt = e.end_dt.astimezone(tz).date() if items[e.id] is None: # if there is no TimetableEntry, this means the event has not timetable on that interval for day in iterdays(max(start_dt.date(), local_start_dt), min(end_dt.date(), local_end_dt)): # if the event starts on this date, we've got a time slot if day.date() == local_start_dt: scheduled_events[day.date()].append((e.start_dt, e)) else: ongoing_events.append(e) else: for start_d, start_dts in items[e.id].viewitems(): scheduled_events[start_d].append((start_dts[0], e)) else: events.append(e) # result['events'][date(...)] -> [(datetime(....), Event(...))] # result[event_id]['contribs'][date(...)] -> [(TimetableEntry(...), Contribution(...))] # result['ongoing_events'] = [Event(...)] if grouped: result = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) else: result = defaultdict(lambda: defaultdict(list)) result.update({ 'events': scheduled_events if grouped else events, 'ongoing_events': ongoing_events }) # according to detail level, ask for extra information from the DB if detail_level != 'event': query = _query_blocks(event_ids, dates_overlap, detail_level) if grouped: for b in query: start_date = b.timetable_entry.start_dt.astimezone(tz).date() result[b.session.event_id]['blocks'][start_date].append((b.timetable_entry, b)) else: for b in query: result[b.session.event_id]['blocks'].append(b) if detail_level == 'contribution': query = (Contribution.find(Contribution.event_id.in_(event_ids), dates_overlap(TimetableEntry), ~Contribution.is_deleted) .options(contains_eager(Contribution.timetable_entry), joinedload(Contribution.person_links)) .join(TimetableEntry)) if grouped: for c in query: start_date = c.timetable_entry.start_dt.astimezone(tz).date() result[c.event_id]['contribs'][start_date].append((c.timetable_entry, c)) else: for c in query: result[c.event_id]['contributions'].append(c) query = (Break.find(TimetableEntry.event_id.in_(event_ids), dates_overlap(TimetableEntry)) .options(contains_eager(Break.timetable_entry)) .join(TimetableEntry)) if grouped: for b in query: start_date = b.timetable_entry.start_dt.astimezone(tz).date() result[b.timetable_entry.event_id]['breaks'][start_date].append((b.timetable_entry, b)) else: for b in query: result[b.timetable_entry.event_id]['breaks'].append(b) return result
def _process_cascaded_event_contents(records, additional_events=None): """ Flatten a series of records into its most basic elements (subcontribution level). Yields results. :param records: queue records to process :param additional_events: events whose content will be included in addition to those found in records """ changed_events = additional_events or set() changed_contributions = set() changed_subcontributions = set() session_records = { rec.session_id for rec in records if rec.type == EntryType.session } contribution_records = { rec.contrib_id for rec in records if rec.type == EntryType.contribution } subcontribution_records = { rec.subcontrib_id for rec in records if rec.type == EntryType.subcontribution } event_records = { rec.event_id for rec in records if rec.type == EntryType.event } if event_records: changed_events.update(Event.find(Event.id.in_(event_records))) for event in changed_events: yield event # Sessions are added (explicitly changed only, since they don't need to be sent anywhere) if session_records: changed_contributions.update( Contribution.find(Contribution.session_id.in_(session_records), ~Contribution.is_deleted)) # Contributions are added (implictly + explicitly changed) changed_event_ids = {ev.id for ev in changed_events} condition = Contribution.event_id.in_( changed_event_ids) & ~Contribution.is_deleted if contribution_records: condition = db.or_(condition, Contribution.id.in_(contribution_records)) contrib_query = Contribution.find(condition).options( joinedload('subcontributions')) for contribution in contrib_query: yield contribution changed_subcontributions.update(contribution.subcontributions) # Same for subcontributions if subcontribution_records: changed_subcontributions.update( SubContribution.find( SubContribution.id.in_(subcontribution_records))) for subcontrib in changed_subcontributions: yield subcontrib