Exemple #1
0
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
Exemple #2
0
 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
Exemple #3
0
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
Exemple #4
0
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']))
Exemple #5
0
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']))
Exemple #6
0
 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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
 def _process_args(self):
     RHDisplayEventBase._process_args(self)
     self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)
Exemple #12
0
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
Exemple #13
0
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
    }
Exemple #14
0
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
    }
Exemple #15
0
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
    }
Exemple #16
0
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
    }
Exemple #17
0
 def _process_args(self):
     RHManageContributionBase._process_args(self)
     self.subcontrib = SubContribution.get_or_404(
         request.view_args['subcontrib_id'], is_deleted=False)
Exemple #18
0
 def _checkParams(self, params):
     RHManageContributionBase._checkParams(self, params)
     self.subcontrib = SubContribution.get_one(
         request.view_args['subcontrib_id'], is_deleted=False)
Exemple #19
0
 def _checkParams(self, params):
     RHConferenceBaseDisplay._checkParams(self, params)
     self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)
Exemple #20
0
 def _checkParams(self, params):
     RHConferenceBaseDisplay._checkParams(self, params)
     self.subcontrib = SubContribution.get_one(
         request.view_args['subcontrib_id'], is_deleted=False)
Exemple #21
0
 def _process_args(self):
     RHDisplayEventBase._process_args(self)
     self.subcontrib = SubContribution.get_one(
         request.view_args['subcontrib_id'], is_deleted=False)
Exemple #22
0
 def _checkParams(self, params):
     RHManageContributionBase._checkParams(self, params)
     self.subcontrib = SubContribution.get_one(request.view_args['subcontrib_id'], is_deleted=False)