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)
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
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)
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)
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)
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)
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)
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))
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))
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)
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))
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'})
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
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))
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']))
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 )
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)
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)
def find_notes(self): from indico.modules.events.notes.models.notes import EventNote return EventNote.find(event_id=self.event.id, is_deleted=False)
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
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
def has_note(self): return EventNote.get_for_linked_object(self, preload_event=self.PRELOAD_EVENT_NOTES) is not None
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
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)
def _get_event_path(self, data): if not (note := EventNote.get(data['note_id'])): return []
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
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 _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)
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()
def _process(self): note = EventNote.get_for_linked_object(self.object, preload_event=False) if not note: raise NotFound return sanitize_html(note.html)
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)
def has_data(self): return EventNote.has_rows()
def has_note(self): return EventNote.get_for_linked_object( self, preload_event=self.PRELOAD_EVENT_NOTES) is not None
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
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)
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 _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))