def test_deleted_relationships(db, dummy_event_new): event = dummy_event_new assert not event.contributions assert not event.sessions s = Session(event_new=event, title='s') sd = Session(event_new=event, title='sd', is_deleted=True) c = Contribution(event_new=event, title='c', session=sd, duration=timedelta(minutes=30)) cd = Contribution(event_new=event, title='cd', session=sd, duration=timedelta(minutes=30), is_deleted=True) sc = SubContribution(contribution=c, title='sc', duration=timedelta(minutes=10)) scd = SubContribution(contribution=c, title='scd', duration=timedelta(minutes=10), is_deleted=True) db.session.flush() db.session.expire_all() # reload all the objects from the db event = Event.get(event.id) s = Session.get(s.id) sd = Session.get(sd.id) c = Contribution.get(c.id) cd = Contribution.get(cd.id) sc = SubContribution.get(sc.id) scd = SubContribution.get(scd.id) # deleted items should not be in the lists assert event.sessions == [s] assert event.contributions == [c] assert sd.contributions == [c] assert c.subcontributions == [sc] # the other direction should work fine even in case of deletion assert s.event_new == event assert sd.event_new == event assert c.event_new == event assert cd.event_new == event assert sc.contribution == c assert scd.contribution == c
def _clone_subcontribs(self, subcontribs): attrs = get_simple_column_attrs(SubContribution) for old_subcontrib in subcontribs: subcontrib = SubContribution() subcontrib.populate_from_attrs(old_subcontrib, attrs) subcontrib.references = list(self._clone_references(SubContributionReference, old_subcontrib.references)) subcontrib.person_links = list(self._clone_person_links(SubContributionPersonLink, old_subcontrib.person_links)) self._subcontrib_map[old_subcontrib] = subcontrib yield subcontrib
def create_subcontribution(contrib, data): subcontrib = SubContribution() subcontrib.populate_from_dict(data) contrib.subcontributions.append(subcontrib) db.session.flush() signals.event.subcontribution_created.send(subcontrib) logger.info('Subcontribution %s created by %s', subcontrib, session.user) subcontrib.event_new.log(EventLogRealm.management, EventLogKind.positive, 'Subcontributions', 'Subcontribution "{}" has been created'.format(subcontrib.title), session.user) return subcontrib
def obj_deref(ref): """Returns the object identified by `ref`""" from indico_livesync.models.queue import EntryType if ref['type'] == EntryType.category: return CategoryManager().getById(ref['category_id'], True) elif ref['type'] == EntryType.event: return Event.get(ref['event_id']) elif ref['type'] == EntryType.contribution: return Contribution.get(ref['contrib_id']) elif ref['type'] == EntryType.subcontribution: return SubContribution.get(ref['subcontrib_id']) else: raise ValueError('Unexpected object type: {}'.format(ref['type']))
def obj_deref(ref): """Returns the object identified by `ref`""" from indico_livesync.models.queue import EntryType if ref['type'] == EntryType.category: return Category.get_or_404(ref['category_id']) elif ref['type'] == EntryType.event: return Event.get_or_404(ref['event_id']) elif ref['type'] == EntryType.session: return Session.get_or_404(ref['session_id']) elif ref['type'] == EntryType.contribution: return Contribution.get_or_404(ref['contrib_id']) elif ref['type'] == EntryType.subcontribution: return SubContribution.get_or_404(ref['subcontrib_id']) else: raise ValueError('Unexpected object type: {}'.format(ref['type']))
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 get_object_from_args(args=None): """Retrieves an event object from request arguments. This utility is meant to be used in cases where the same controller can deal with objects attached to various parts of an event which use different URLs to indicate which object to use. :param args: The request arguments. If unspecified, ``request.view_args`` is used. :return: An ``(object_type, event, object)`` tuple. The event is always the :class:`Event` associated with the object. The object may be an `Event`, `Session`, `Contribution` or `SubContribution`. If the object does not exist, ``(object_type, None, None)`` is returned. """ if args is None: args = request.view_args object_type = args['object_type'] event = Event.find_first(id=args['confId'], is_deleted=False) if event is None: obj = None elif object_type == 'event': obj = event elif object_type == 'session': obj = Session.query.with_parent(event).filter_by( id=args['session_id']).first() elif object_type == 'contribution': obj = Contribution.query.with_parent(event).filter_by( id=args['contrib_id']).first() elif object_type == 'subcontribution': obj = SubContribution.find( SubContribution.id == args['subcontrib_id'], ~SubContribution.is_deleted, SubContribution.contribution.has(event=event, id=args['contrib_id'], is_deleted=False)).first() else: raise ValueError('Unexpected object type: {}'.format(object_type)) if obj is not None: return object_type, event, obj else: return object_type, None, None
def parse_indico_id(indico_id): event_match = re.match('(\d+)$', indico_id) session_match = re.match('(\d+)s(\d+)$', indico_id) contrib_match = re.match('(\d+)c(\d+)$', indico_id) subcontrib_match = re.match('(\d+)c(\d+)sc(\d+)$', indico_id) if subcontrib_match: event = Event.get(subcontrib_match.group(1), is_deleted=False) if not event: return None return SubContribution.find(SubContribution.id == subcontrib_match.group(3), ~SubContribution.is_deleted, SubContribution.contribution.has(event=event, id=subcontrib_match.group(2), is_deleted=False)).first() elif session_match: event = Event.get(session_match.group(1), is_deleted=False) return Session.query.with_parent(event).filter_by(id=session_match.group(2)).first() elif contrib_match: event = Event.get(contrib_match.group(1), is_deleted=False) return Contribution.query.with_parent(event).filter_by(id=contrib_match.group(2)).first() elif event_match: return Event.get(event_match.group(1), is_deleted=False) else: return None
def get_object_from_args(args=None): """Retrieves an event object from request arguments. This utility is meant to be used in cases where the same controller can deal with objects attached to various parts of an event which use different URLs to indicate which object to use. :param args: The request arguments. If unspecified, ``request.view_args`` is used. :return: An ``(object_type, event, object)`` tuple. The event is always the :class:`Event` associated with the object. The object may be an `Event`, `Session`, `Contribution` or `SubContribution`. If the object does not exist, ``(object_type, None, None)`` is returned. """ if args is None: args = request.view_args object_type = args['object_type'] event = Event.find_first(id=args['confId'], is_deleted=False) if event is None: obj = None elif object_type == 'event': obj = event elif object_type == 'session': obj = Session.query.with_parent(event).filter_by(id=args['session_id']).first() elif object_type == 'contribution': obj = Contribution.query.with_parent(event).filter_by(id=args['contrib_id']).first() elif object_type == 'subcontribution': obj = SubContribution.find(SubContribution.id == args['subcontrib_id'], ~SubContribution.is_deleted, SubContribution.contribution.has(event=event, id=args['contrib_id'], is_deleted=False)).first() else: raise ValueError('Unexpected object type: {}'.format(object_type)) if obj is not None: return object_type, event, obj else: return object_type, None, None
def _process_args(self): RHDisplayEventBase._process_args(self) self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)
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 test_dump_event_note(db, dummy_user, dummy_event, dummy_contribution, link_type): from .schemas import EventNoteRecordSchema if link_type == 'event': ids = {} note = EventNote(object=dummy_event) url = '/event/0/note/' elif link_type == 'contrib': ids = {'contribution_id': dummy_contribution.id} note = EventNote(object=dummy_contribution) url = f'/event/0/contributions/{dummy_contribution.id}/note/' elif link_type == 'subcontrib': subcontribution = SubContribution(contribution=dummy_contribution, title='Dummy Subcontribution', duration=timedelta(minutes=10)) db.session.flush() ids = { 'contribution_id': subcontribution.contribution_id, 'subcontribution_id': subcontribution.id, } note = EventNote(object=subcontribution) url = f'/event/0/contributions/{dummy_contribution.id}/subcontributions/{subcontribution.id}/note/' note.create_revision(RenderMode.html, 'this is a dummy <strong>note</strong>', dummy_user) db.session.flush() category_id = dummy_event.category_id schema = EventNoteRecordSchema(context={'schema': 'test-notes'}) assert schema.dump(note) == { '$schema': 'test-notes', '_access': { 'delete': ['IndicoAdmin'], 'owner': ['IndicoAdmin'], 'update': ['IndicoAdmin'], }, '_data': { 'content': 'this is a dummy note', 'site': 'http://localhost', 'title': note.object.title, 'persons': { 'name': 'Guinea Pig' } }, 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'modified_dt': note.current_revision.created_dt.isoformat(), 'event_id': 0, 'note_id': note.id, 'type': 'event_note', 'url': f'http://localhost{url}', **ids }
def test_dump_subcontribution(db, dummy_user, dummy_event, dummy_contribution, create_entry, scheduled): from .schemas import SubContributionRecordSchema extra = {} if scheduled: create_entry(dummy_contribution, utc.localize(datetime(2020, 4, 20, 4, 20))) extra = { 'start_dt': dummy_contribution.start_dt.isoformat(), 'end_dt': dummy_contribution.end_dt.isoformat(), } subcontribution = SubContribution( contribution=dummy_contribution, title='Dummy Subcontribution', description='A dummy <strong>subcontribution</strong>', duration=timedelta(minutes=10)) person = EventPerson.create_from_user(dummy_user, dummy_event) subcontribution.person_links.append( SubContributionPersonLink(person=person)) db.session.flush() category_id = dummy_contribution.event.category_id schema = SubContributionRecordSchema( context={'schema': 'test-subcontribs'}) assert schema.dump(subcontribution) == { '$schema': 'test-subcontribs', '_access': { 'delete': ['IndicoAdmin'], 'owner': ['IndicoAdmin'], 'update': ['IndicoAdmin'], }, '_data': { 'description': 'A dummy subcontribution', 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'name': 'Guinea Pig' }], 'site': 'http://localhost', 'title': 'Dummy Subcontribution', }, 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'contribution_id': dummy_contribution.id, 'duration': 10, 'event_id': 0, 'subcontribution_id': subcontribution.id, 'type': 'subcontribution', 'url': f'http://localhost/event/0/contributions/{dummy_contribution.id}/subcontributions/{subcontribution.id}', **extra }
def test_dump_event_note(db, dummy_user, dummy_event, dummy_contribution, link_type): from indico.modules.search.schemas import EventNoteSchema if link_type == 'event': ids = {'contribution_id': None, 'subcontribution_id': None} note = EventNote(object=dummy_event) url = '/event/0/note/' elif link_type == 'contrib': ids = { 'contribution_id': dummy_contribution.id, 'subcontribution_id': None } note = EventNote(object=dummy_contribution) url = f'/event/0/contributions/{dummy_contribution.id}/note/' elif link_type == 'subcontrib': subcontribution = SubContribution(contribution=dummy_contribution, title='Dummy Subcontribution', duration=timedelta(minutes=10)) db.session.flush() ids = { 'contribution_id': subcontribution.contribution_id, 'subcontribution_id': subcontribution.id, } note = EventNote(object=subcontribution) url = f'/event/0/contributions/{dummy_contribution.id}/subcontributions/{subcontribution.id}/note/' note.create_revision(RenderMode.html, 'this is a dummy note', dummy_user) db.session.flush() category_id = dummy_event.category_id schema = EventNoteSchema() assert schema.dump(note) == { 'content': 'this is a dummy note', 'user': { 'affiliation': None, 'name': 'Guinea Pig' }, 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'modified_dt': note.current_revision.created_dt.isoformat(), 'event_id': 0, 'note_id': note.id, 'title': note.object.title, 'type': 'event_note', 'url': url, **ids }
def test_dump_subcontribution(db, dummy_user, dummy_event, dummy_contribution, create_entry, scheduled): from indico.modules.search.schemas import SubContributionSchema extra = {'start_dt': None, 'end_dt': None} if scheduled: create_entry(dummy_contribution, utc.localize(datetime(2020, 4, 20, 4, 20))) extra = { 'start_dt': dummy_contribution.start_dt.isoformat(), 'end_dt': dummy_contribution.end_dt.isoformat(), } subcontribution = SubContribution(contribution=dummy_contribution, title='Dummy Subcontribution', description='A dummy subcontribution', duration=timedelta(minutes=10)) person = EventPerson.create_from_user(dummy_user, dummy_event) subcontribution.person_links.append( SubContributionPersonLink(person=person)) db.session.flush() category_id = dummy_contribution.event.category_id schema = SubContributionSchema() assert schema.dump(subcontribution) == { 'description': 'A dummy subcontribution', 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'affiliation': None, 'name': 'Guinea Pig' }], 'title': 'Dummy Subcontribution', 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'contribution_id': dummy_contribution.id, 'duration': 10, 'event_id': 0, 'subcontribution_id': subcontribution.id, 'type': 'subcontribution', 'url': f'/event/0/contributions/{dummy_contribution.id}/subcontributions/{subcontribution.id}', **extra }
def _process_args(self): RHManageContributionBase._process_args(self) self.subcontrib = SubContribution.get_or_404( request.view_args['subcontrib_id'], is_deleted=False)
def _checkParams(self, params): RHManageContributionBase._checkParams(self, params) self.subcontrib = SubContribution.get_one( request.view_args['subcontrib_id'], is_deleted=False)
def _checkParams(self, params): RHConferenceBaseDisplay._checkParams(self, params) self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)
def _checkParams(self, params): RHConferenceBaseDisplay._checkParams(self, params) self.subcontrib = SubContribution.get_one( request.view_args['subcontrib_id'], is_deleted=False)
def _process_args(self): RHDisplayEventBase._process_args(self) self.subcontrib = SubContribution.get_one( request.view_args['subcontrib_id'], is_deleted=False)
def _checkParams(self, params): RHManageContributionBase._checkParams(self, params) self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)