Beispiel #1
0
    def migrate_event_notes(self):
        self.print_step('migrating event notes')

        janitor_user = User.get_one(self.janitor_user_id)
        self.print_msg('Using janitor user {}'.format(janitor_user), always=True)
        for event, obj, minutes, special_prot in committing_iterator(self._iter_minutes()):
            if special_prot:
                self.print_warning(
                    cformat('%{yellow!}{} minutes have special permissions; skipping them').format(obj),
                    event_id=event.id
                )
                continue
            path = get_archived_file(minutes, self.archive_dirs)[1]
            if path is None:
                self.print_error(cformat('%{red!}{} minutes not found on disk; skipping them').format(obj),
                                 event_id=event.id)
                continue
            with open(path, 'r') as f:
                data = convert_to_unicode(f.read()).strip()
            if not data:
                self.print_warning(cformat('%{yellow}{} minutes are empty; skipping them').format(obj),
                                   always=False, event_id=event.id)
                continue
            note = EventNote(linked_object=obj)
            note.create_revision(RenderMode.html, data, janitor_user)
            db.session.add(note)
            if not self.quiet:
                self.print_success(cformat('%{cyan}{}').format(obj), event_id=event.id)
Beispiel #2
0
def test_get_for_linked_object_preload(note, dummy_user, count_queries,
                                       preload):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    assert EventNote.get_for_linked_object(note.object, preload_event=preload)
    with count_queries() as cnt:
        EventNote.get_for_linked_object(note.object)
    assert (cnt() == 0) == preload
Beispiel #3
0
    def migrate_event_notes(self):
        self.print_step('migrating event notes')

        janitor_user = User.get_one(self.janitor_user_id)
        self.print_msg('Using janitor user {}'.format(janitor_user), always=True)
        for event, obj, minutes, special_prot in committing_iterator(self._iter_minutes()):
            if special_prot:
                self.print_warning(
                    cformat('%{yellow!}{} minutes have special permissions; skipping them').format(obj),
                    event_id=event.id
                )
                continue
            path = get_archived_file(minutes, self.archive_dirs)[1]
            if path is None:
                self.print_error(cformat('%{red!}{} minutes not found on disk; skipping them').format(obj),
                                 event_id=event.id)
                continue
            with open(path, 'r') as f:
                data = convert_to_unicode(f.read()).strip()
            if not data:
                self.print_warning(cformat('%{yellow}{} minutes are empty; skipping them').format(obj),
                                   always=False, event_id=event.id)
                continue
            note = EventNote(linked_object=obj)
            note.create_revision(RenderMode.html, data, janitor_user)
            db.session.add(note)
            if not self.quiet:
                self.print_success(cformat('%{cyan}{}').format(obj), event_id=event.id)
Beispiel #4
0
 def _getParams(self):
     super(NoteExportHook, self)._getParams()
     event = self._obj = Event.get(self._pathParams['event_id'], is_deleted=False)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         self._obj = Session.query.with_parent(event).filter_by(id=session_id).first()
         if self._obj is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = (Contribution.query.with_parent(event)
                                     .filter_by(id=contribution_id, is_deleted=False)
                                     .first())
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
         subcontribution_id = self._pathParams.get('subcontribution_id')
         if subcontribution_id:
             self._obj = SubContribution.query.with_parent(contribution).filter_by(id=subcontribution_id,
                                                                                   is_deleted=False).first()
             if self._obj is None:
                 raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj, preload_event=False)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Beispiel #5
0
 def _getParams(self):
     super()._getParams()
     event = self._obj = Event.get(self._pathParams['event_id'],
                                   is_deleted=False)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         self._obj = Session.query.with_parent(event).filter_by(
             id=session_id).first()
         if self._obj is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = (
             Contribution.query.with_parent(event).filter_by(
                 id=contribution_id, is_deleted=False).first())
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
         subcontribution_id = self._pathParams.get('subcontribution_id')
         if subcontribution_id:
             self._obj = SubContribution.query.with_parent(
                 contribution).filter_by(id=subcontribution_id,
                                         is_deleted=False).first()
             if self._obj is None:
                 raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj,
                                                  preload_event=False)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Beispiel #6
0
 def _process_form(self, form, **kwargs):
     saved = False
     if form.validate_on_submit():
         note = EventNote.get_or_create(self.object)
         is_new = note.id is None or note.is_deleted
         is_restored = is_new and note.is_deleted
         # TODO: get render mode from form data once it can be selected
         note.create_revision(RenderMode.html, form.source.data, session.user)
         is_changed = attrs_changed(note, 'current_revision')
         db.session.add(note)
         db.session.flush()
         if is_new:
             if is_restored:
                 signals.event.notes.note_restored.send(note)
             else:
                 signals.event.notes.note_added.send(note)
             logger.info('Note %s created by %s', note, session.user)
             self.event.log(EventLogRealm.participants, LogKind.positive, 'Minutes', 'Added minutes',
                            session.user, data=note.link_event_log_data)
         elif is_changed:
             signals.event.notes.note_modified.send(note)
             logger.info('Note %s modified by %s', note, session.user)
             self.event.log(EventLogRealm.participants, LogKind.change, 'Minutes', 'Updated minutes',
                            session.user, data=note.link_event_log_data)
         saved = is_new or is_changed
     return jsonify_template('events/notes/edit_note.html', form=form, object_type=self.object_type,
                             object=self.object, saved=saved, **kwargs)
Beispiel #7
0
 def _getParams(self):
     super(NoteExportHook, self)._getParams()
     event = self._obj = ConferenceHolder().getById(
         self._pathParams['event_id'], True)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         session = self._obj = event.getSessionById(session_id)
         if session is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = event.getContributionById(
             contribution_id)
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
     subcontribution_id = self._pathParams.get('subcontribution_id')
     if subcontribution_id:
         subcontribution = self._obj = contribution.getSubContributionById(
             subcontribution_id)
         if subcontribution is None:
             raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Beispiel #8
0
 def _clone_note(self, old_note, new_object):
     revision = old_note.current_revision
     self._note_map[old_note] = note = EventNote.get_or_create(new_object)
     if note.is_deleted:
         self._restored_notes.add(note)
     note.create_revision(render_mode=revision.render_mode,
                          source=revision.source,
                          user=revision.user)
Beispiel #9
0
 def clone(self, new_event, options):
     from indico.modules.events.notes.models.notes import EventNote
     if 'notes' not in options:
         return
     for old_note in self.find_notes():
         revision = old_note.current_revision
         new_note = EventNote(link_type=old_note.link_type,
                              event_id=new_event.id,
                              session_id=old_note.session_id,
                              contribution_id=old_note.contribution_id,
                              subcontribution_id=old_note.subcontribution_id)
         new_note.create_revision(render_mode=revision.render_mode,
                                  source=revision.source,
                                  user=revision.user)
         db.session.add(new_note)
         db.session.flush()
         logger.info('Added note during event cloning: {}'.format(new_note))
Beispiel #10
0
 def clone(self, new_event, options):
     from indico.modules.events.notes.models.notes import EventNote
     if 'notes' not in options:
         return
     for old_note in self.find_notes():
         revision = old_note.current_revision
         new_note = EventNote(link_type=old_note.link_type,
                              event_id=new_event.id,
                              session_id=old_note.session_id,
                              contribution_id=old_note.contribution_id,
                              subcontribution_id=old_note.subcontribution_id)
         new_note.create_revision(render_mode=revision.render_mode,
                                  source=revision.source,
                                  user=revision.user)
         db.session.add(new_note)
         db.session.flush()
         logger.info('Added note during event cloning: {}'.format(new_note))
Beispiel #11
0
 def _process(self):
     note = EventNote.get_for_linked_object(self.object, preload_event=False)
     if note is not None:
         note.delete(session.user)
         signals.event.notes.note_deleted.send(note)
         logger.info('Note {} deleted by {}'.format(note, session.user))
         self.event.log(EventLogRealm.participants, EventLogKind.negative, 'Minutes',
                        'Removed minutes from {} {}'.format(self.object_type, self.object.getTitle()), session.user)
     return redirect(url_for('event.conferenceDisplay', self.event))
Beispiel #12
0
 def _process(self):
     note = EventNote.get_for_linked_object(self.object, preload_event=False)
     if note is not None:
         note.delete(session.user)
         signals.event.notes.note_deleted.send(note)
         logger.info('Note %s deleted by %s', note, session.user)
         self.event.log(EventLogRealm.participants, EventLogKind.negative, 'Minutes', 'Removed minutes',
                        session.user, data=note.link_event_log_data)
     return redirect(self.event.url)
Beispiel #13
0
 def migrate(self):
     for obj, minutes, special_prot in self._iter_minutes():
         if special_prot:
             self.print_warning('%[yellow!]{} minutes have special permissions; skipping them'.format(obj))
             continue
         path = get_archived_file(minutes, self.archive_dirs)[1]
         if path is None:
             self.print_error('%[red!]{} minutes not found on disk; skipping them'.format(obj))
             continue
         with open(path, 'r') as f:
             data = convert_to_unicode(f.read()).strip()
         if not data:
             self.print_warning('%[yellow]{} minutes are empty; skipping them'.format(obj), always=False)
             continue
         note = EventNote(object=obj)
         note.create_revision(RenderMode.html, data, self.system_user)
         if not self.quiet:
             self.print_success('%[cyan]{}'.format(obj))
Beispiel #14
0
def test_acls(dummy_event, dummy_contribution, dummy_user, create_user,
              obj_type):
    from .schemas import ACLSchema

    class TestSchema(ACLSchema, mm.Schema):
        pass

    if obj_type == 'event':
        obj = dummy_event
    elif obj_type == 'contrib':
        obj = dummy_contribution
    elif obj_type == 'subcontrib':
        obj = SubContribution(contribution=dummy_contribution,
                              title='Test',
                              duration=timedelta(minutes=10))
    elif obj_type == 'attachment':
        folder = AttachmentFolder(title='Dummy Folder',
                                  description='a dummy folder')
        obj = Attachment(folder=folder,
                         user=dummy_user,
                         title='Dummy Attachment',
                         type=AttachmentType.link,
                         link_url='https://example.com')
        obj.folder.object = dummy_event
    elif obj_type == 'note':
        obj = EventNote(object=dummy_event)
        obj.create_revision(RenderMode.html, 'this is a dummy note',
                            dummy_user)

    def assert_acl(expected_read_acl):
        __tracebackhide__ = True
        data = schema.dump(obj)
        read_acl = data['_access'].pop('read', None)
        assert data == {
            '_access': {
                'delete': ['IndicoAdmin'],
                'owner': ['IndicoAdmin'],
                'update': ['IndicoAdmin']
            }
        }
        if read_acl is not None:
            read_acl = set(read_acl)
        assert read_acl == expected_read_acl

    schema = TestSchema()
    user = create_user(1, email='*****@*****.**')

    # everything is public
    assert_acl(None)

    # event is protected and the acl is empty (nobody has regular access)
    dummy_event.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin'})

    # user on the acl has access
    dummy_event.update_principal(user, read_access=True)
    assert_acl({'IndicoAdmin', 'User:1'})
Beispiel #15
0
def test_get_or_create(db, dummy_user, dummy_event, create_event):
    note = EventNote.get_or_create(dummy_event)
    assert note is not None
    assert not inspect(note).persistent  # new object
    note.create_revision(RenderMode.html, 'test', dummy_user)
    note.is_deleted = True
    db.session.flush()
    # get deleted one
    assert EventNote.get_or_create(dummy_event) == note
    assert inspect(note).persistent
    note.is_deleted = False
    db.session.flush()
    # same if it's not deleted
    assert EventNote.get_or_create(dummy_event) == note
    assert inspect(note).persistent
    # other event should create a new one
    other = EventNote.get_or_create(create_event(123))
    other.create_revision(RenderMode.html, 'test', dummy_user)
    assert other != note
    assert not inspect(other).persistent
Beispiel #16
0
def test_get_or_create(db, dummy_user, dummy_event, create_event):
    note = EventNote.get_or_create(dummy_event)
    assert note is not None
    assert not inspect(note).persistent  # new object
    note.create_revision(RenderMode.html, 'test', dummy_user)
    note.is_deleted = True
    db.session.flush()
    # get deleted one
    assert EventNote.get_or_create(dummy_event) == note
    assert inspect(note).persistent
    note.is_deleted = False
    db.session.flush()
    # same if it's not deleted
    assert EventNote.get_or_create(dummy_event) == note
    assert inspect(note).persistent
    # other event should create a new one
    other = EventNote.get_or_create(create_event(123))
    other.create_revision(RenderMode.html, 'test', dummy_user)
    assert other != note
    assert not inspect(other).persistent
Beispiel #17
0
 def _process(self):
     note = EventNote.get_for_linked_object(self.object, preload_event=False)
     if note is not None:
         note.delete(session.user)
         signals.event.notes.note_deleted.send(note)
         logger.info("Note {} deleted by {}".format(note, session.user))
         self.event.log(
             EventLogRealm.participants,
             EventLogKind.negative,
             "Minutes",
             "Removed minutes",
             session.user,
             data=note.link_event_log_data,
         )
     return redirect(url_for("event.conferenceDisplay", self.event))
Beispiel #18
0
def obj_deref(ref):
    """Return 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'])
    elif ref['type'] == EntryType.note:
        return EventNote.get_or_404(ref['note_id'])
    elif ref['type'] == EntryType.attachment:
        return Attachment.get_or_404(ref['attachment_id'])
    else:
        raise ValueError('Unexpected object type: {}'.format(ref['type']))
Beispiel #19
0
 def _process_form(self, form, **kwargs):
     saved = False
     if form.validate_on_submit():
         note = EventNote.get_or_create(self.object)
         is_new = note.id is None or note.is_deleted
         # TODO: get render mode from form data once it can be selected
         note.create_revision(RenderMode.html, form.source.data, session.user)
         is_changed = attrs_changed(note, "current_revision")
         db.session.add(note)
         db.session.flush()
         if is_new:
             signals.event.notes.note_added.send(note)
             logger.info("Note {} created by {}".format(note, session.user))
             self.event.log(
                 EventLogRealm.participants,
                 EventLogKind.positive,
                 "Minutes",
                 "Added minutes",
                 session.user,
                 data=note.link_event_log_data,
             )
         elif is_changed:
             signals.event.notes.note_modified.send(note)
             logger.info("Note {} modified by {}".format(note, session.user))
             self.event.log(
                 EventLogRealm.participants,
                 EventLogKind.change,
                 "Minutes",
                 "Updated minutes",
                 session.user,
                 data=note.link_event_log_data,
             )
         saved = is_new or is_changed
     return jsonify_template(
         "events/notes/edit_note.html",
         form=form,
         object_type=self.object_type,
         object=self.object,
         saved=saved,
         **kwargs
     )
Beispiel #20
0
 def _getParams(self):
     super(NoteExportHook, self)._getParams()
     event = self._obj = ConferenceHolder().getById(self._pathParams['event_id'], True)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         session = self._obj = event.getSessionById(session_id)
         if session is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = session.getContributionById(contribution_id)
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
     subcontribution_id = self._pathParams.get('subcontribution_id')
     if subcontribution_id:
         subcontribution = self._obj = contribution.getSubContributionById(subcontribution_id)
         if subcontribution is None:
             raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Beispiel #21
0
 def _process_form(self, form, **kwargs):
     if form.validate_on_submit():
         note = EventNote.get_or_create(self.object)
         is_new = note.id is None or note.is_deleted
         # TODO: get render mode from form data once it can be selected
         note.create_revision(RenderMode.html, form.source.data, session.user)
         is_changed = attrs_changed(note, 'current_revision')
         db.session.add(note)
         db.session.flush()
         if is_new:
             signals.event.notes.note_added.send(note)
             logger.info('Note {} created by {}'.format(note, session.user))
             self.event.log(EventLogRealm.participants, EventLogKind.positive, 'Minutes',
                            'Added minutes to {} {}'.format(self.object_type, self.object.getTitle()), session.user)
         elif is_changed:
             signals.event.notes.note_modified.send(note)
             logger.info('Note {} modified by {}'.format(note, session.user))
             self.event.log(EventLogRealm.participants, EventLogKind.change, 'Minutes',
                            'Updated minutes for {} {}'.format(self.object_type, self.object.getTitle()),
                            session.user)
         return jsonify_data(flash=False)
     return jsonify_template('events/notes/edit_note.html', form=form, object_type=self.object_type,
                             object=self.object, **kwargs)
Beispiel #22
0
 def find_notes(self):
     from indico.modules.events.notes.models.notes import EventNote
     return EventNote.find(event_id=self.event.id, is_deleted=False)
Beispiel #23
0
def test_get_for_linked_object(note, dummy_user, create_event):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    assert EventNote.get_for_linked_object(note.object) == note
    assert EventNote.get_for_linked_object(create_event(123)) is None
Beispiel #24
0
def test_get_for_linked_object_deleted(note, dummy_user):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    note.is_deleted = True
    assert EventNote.get_for_linked_object(note.linked_object) is None
Beispiel #25
0
 def has_note(self):
     return EventNote.get_for_linked_object(self, preload_event=self.PRELOAD_EVENT_NOTES) is not None
Beispiel #26
0
def test_get_for_linked_object(note, dummy_user, create_event):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    assert EventNote.get_for_linked_object(note.linked_object) == note
    assert EventNote.get_for_linked_object(create_event('123')) is None
Beispiel #27
0
def test_get_for_linked_object_preload(note, dummy_user, mocker, preload):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    assert EventNote.get_for_linked_object(note.linked_object, preload_event=preload)
    query = mocker.patch.object(EventNote, 'query', new=PropertyMock())
    EventNote.get_for_linked_object(note.linked_object)
    assert query.called == (not preload)
Beispiel #28
0
 def _get_event_path(self, data):
     if not (note := EventNote.get(data['note_id'])):
         return []
Beispiel #29
0
def note(db, dummy_event):
    note = EventNote(object=dummy_event)
    db.session.expunge(
        note
    )  # keep it out of the SA session (linking it to the event adds it)
    return note
Beispiel #30
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
    }
Beispiel #31
0
 def _clone_note(self, old_note, new_object):
     revision = old_note.current_revision
     new_object.note = EventNote()
     new_object.note.create_revision(render_mode=revision.render_mode,
                                     source=revision.source,
                                     user=revision.user)
Beispiel #32
0
def _delete_event_notes(event, **kwargs):
    from indico.modules.events.notes.models.notes import EventNote
    EventNote.find(event_id=event.id).update({EventNote.is_deleted: True})
    db.session.expire_all()
Beispiel #33
0
 def _process(self):
     note = EventNote.get_for_linked_object(self.object, preload_event=False)
     if not note:
         raise NotFound
     return sanitize_html(note.html)
Beispiel #34
0
 def _process(self):
     note = EventNote.get_or_404(request.view_args['note_id'])
     if embed_url := self._get_embed_url(note):
         return redirect(embed_url)
Beispiel #35
0
 def has_data(self):
     return EventNote.has_rows()
Beispiel #36
0
 def has_note(self):
     return EventNote.get_for_linked_object(
         self, preload_event=self.PRELOAD_EVENT_NOTES) is not None
Beispiel #37
0
 def has_data(self):
     return EventNote.has_rows()
Beispiel #38
0
def test_get_for_linked_object_deleted(note, dummy_user):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    note.is_deleted = True
    assert EventNote.get_for_linked_object(note.object) is None
Beispiel #39
0
    def search_notes(self, q, user, page, category_id, event_id,
                     admin_override_enabled):
        contrib_event = db.aliased(Event)
        contrib_session = db.aliased(Session)
        subcontrib_contrib = db.aliased(Contribution)
        subcontrib_session = db.aliased(Session)
        subcontrib_event = db.aliased(Event)
        session_event = db.aliased(Event)

        note_strategy = load_only('id', 'link_type', 'event_id',
                                  'linked_event_id', 'contribution_id',
                                  'subcontribution_id', 'session_id', 'html')
        # event
        event_strategy = note_strategy.contains_eager(EventNote.linked_event)
        event_strategy.undefer(Event.effective_protection_mode)
        _apply_event_access_strategy(event_strategy)
        _apply_acl_entry_strategy(
            event_strategy.selectinload(Event.acl_entries), EventPrincipal)
        # contribution
        contrib_strategy = note_strategy.contains_eager(EventNote.contribution)
        _apply_contrib_access_strategy(contrib_strategy)
        _apply_acl_entry_strategy(
            contrib_strategy.selectinload(Contribution.acl_entries),
            ContributionPrincipal)
        contrib_event_strategy = contrib_strategy.contains_eager(
            Contribution.event.of_type(contrib_event))
        _apply_event_access_strategy(contrib_event_strategy)
        _apply_acl_entry_strategy(
            contrib_event_strategy.selectinload(contrib_event.acl_entries),
            EventPrincipal)
        contrib_session_strategy = contrib_strategy.contains_eager(
            Contribution.session.of_type(contrib_session))
        contrib_session_strategy.load_only('id', 'event_id', 'protection_mode')
        _apply_acl_entry_strategy(
            contrib_session_strategy.selectinload(contrib_session.acl_entries),
            SessionPrincipal)
        # subcontribution
        subcontrib_strategy = note_strategy.contains_eager(
            EventNote.subcontribution)
        subcontrib_contrib_strategy = subcontrib_strategy.contains_eager(
            SubContribution.contribution.of_type(subcontrib_contrib))
        _apply_contrib_access_strategy(subcontrib_contrib_strategy)
        _apply_acl_entry_strategy(
            subcontrib_contrib_strategy.selectinload(
                subcontrib_contrib.acl_entries), ContributionPrincipal)
        subcontrib_event_strategy = subcontrib_contrib_strategy.contains_eager(
            subcontrib_contrib.event.of_type(subcontrib_event))
        _apply_event_access_strategy(subcontrib_event_strategy)
        _apply_acl_entry_strategy(
            subcontrib_event_strategy.selectinload(
                subcontrib_event.acl_entries), EventPrincipal)
        subcontrib_session_strategy = subcontrib_contrib_strategy.contains_eager(
            subcontrib_contrib.session.of_type(subcontrib_session))
        subcontrib_session_strategy.load_only('id', 'event_id',
                                              'protection_mode')
        _apply_acl_entry_strategy(
            subcontrib_session_strategy.selectinload(
                subcontrib_session.acl_entries), SessionPrincipal)
        # session
        session_strategy = note_strategy.contains_eager(EventNote.session)
        session_strategy.load_only('id', 'event_id', 'protection_mode')
        session_event_strategy = session_strategy.contains_eager(
            Session.event.of_type(session_event))
        _apply_event_access_strategy(session_event_strategy)
        session_event_strategy.selectinload(session_event.acl_entries)
        _apply_acl_entry_strategy(
            session_strategy.selectinload(Session.acl_entries),
            SessionPrincipal)

        note_filters = [
            EventNote.html_matches(q), ~EventNote.is_deleted,
            db.or_(EventNote.link_type != LinkType.event, ~Event.is_deleted),
            db.or_(EventNote.link_type != LinkType.contribution,
                   ~Contribution.is_deleted & ~contrib_event.is_deleted),
            db.or_(
                EventNote.link_type != LinkType.subcontribution,
                db.and_(~SubContribution.is_deleted,
                        ~subcontrib_contrib.is_deleted,
                        ~subcontrib_event.is_deleted)),
            db.or_(EventNote.link_type != LinkType.session,
                   ~Session.is_deleted & ~session_event.is_deleted)
        ]

        if category_id is not None:
            note_filters.append(
                EventNote.event.has(
                    Event.category_chain_overlaps(category_id)))
        if event_id is not None:
            note_filters.append(EventNote.event_id == event_id)

        query = (
            EventNote.query.filter(
                *note_filters).options(note_strategy).outerjoin(
                    EventNote.linked_event).outerjoin(
                        EventNote.contribution).outerjoin(
                            Contribution.event.of_type(contrib_event)).
            outerjoin(Contribution.session.of_type(contrib_session)).outerjoin(
                EventNote.subcontribution).outerjoin(
                    SubContribution.contribution.of_type(subcontrib_contrib)).
            outerjoin(
                subcontrib_contrib.event.of_type(subcontrib_event)).outerjoin(
                    subcontrib_contrib.session.of_type(
                        subcontrib_session)).outerjoin(
                            EventNote.session).outerjoin(
                                Session.event.of_type(session_event)))

        objs, pagenav = self._paginate(query, page, EventNote.id, user,
                                       admin_override_enabled)

        query = (EventNote.query.filter(EventNote.id.in_(
            n.id for n in objs)).options(
                joinedload(EventNote.contribution),
                joinedload(EventNote.subcontribution).joinedload(
                    SubContribution.contribution),
                joinedload(EventNote.event).options(
                    undefer(Event.detailed_category_chain)),
                joinedload(EventNote.current_revision).joinedload(
                    EventNoteRevision.user).joinedload('_affiliation'),
            ))
        notes_by_id = {n.id: n for n in query}
        notes = [notes_by_id[n.id] for n in objs]

        res = HTMLStrippingEventNoteSchema(many=True).dump(notes)
        return pagenav, EventNoteResultSchema(many=True).load(res)
Beispiel #40
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
    }
Beispiel #41
0
 def _make_form(self, source=None):
     note = None
     if not source:
         note = EventNote.get_for_linked_object(self.object, preload_event=False)
     return NoteForm(obj=self._get_defaults(note=note, source=source))
Beispiel #42
0
def test_get_for_linked_object_preload(note, dummy_user, count_queries, preload):
    note.create_revision(RenderMode.html, 'test', dummy_user)
    assert EventNote.get_for_linked_object(note.object, preload_event=preload)
    with count_queries() as cnt:
        EventNote.get_for_linked_object(note.object)
    assert (cnt() == 0) == preload