Skip to content

Instantly share code, notes, and snippets.

@ThiefMaster
Created May 17, 2019 14:09
Show Gist options
  • Save ThiefMaster/bd78f52909ec963023ce2e368874dac6 to your computer and use it in GitHub Desktop.
Save ThiefMaster/bd78f52909ec963023ce2e368874dac6 to your computer and use it in GitHub Desktop.
from __future__ import unicode_literals
import itertools
from marshmallow_enum import EnumField
from indico.core.db.sqlalchemy.principals import PrincipalType
from indico.core.db.sqlalchemy.protection import ProtectionMode
from indico.core.marshmallow import mm
from indico.modules.attachments import Attachment
from indico.modules.events import Event
from indico.modules.events.models.events import EventType
from indico.modules.events.models.persons import EventPersonLink
def _get_location(obj):
if obj.venue_name and obj.room_name:
return '{}: {}'.format(obj.venue_name, obj.room_name)
elif obj.venue_name or obj.room_name:
return obj.venue_name or obj.room_name
else:
return None
def _get_identifiers(principal):
if principal.principal_type == PrincipalType.user:
# Instead of using the email this uses `User:ID`.
# Since the user can change the email this is better as
# it will ensure that only this given Indico user has access.
# If you want to stick with email, simply replace it with
# 'User:{}'.format(principal.email)
yield principal.identifier
elif principal.principal_type == PrincipalType.event_role:
for user in principal.members:
# same thing here
yield user.identifier
elif principal.is_group:
yield principal.identifier
def _get_event_acl(event):
acl = set(itertools.chain.from_iterable(_get_identifiers(x.principal) for x in event.acl_entries))
if event.effective_protection_mode == ProtectionMode.public:
# Probably we could skip sending any other ACL entries in this case...
acl.add('ANONYMOUS')
return {'read': sorted(acl), 'owner': [], 'update': [], 'delete': []}
def _get_attachment_acl(attachment):
linked_object = attachment.folder.object
if attachment.is_self_protected:
principals = {p for p in attachment.acl} | set(linked_object.get_manager_list(recursive=True))
elif attachment.is_inheriting and attachment.folder.is_self_protected:
principals = {p for p in attachment.folder.acl} | set(linked_object.get_manager_list(recursive=True))
else:
principals = linked_object.get_access_list()
acl = set(itertools.chain.from_iterable(_get_identifiers(x) for x in principals))
return {'read': sorted(acl), 'owner': [], 'update': [], 'delete': []}
class PersonLinkSchema(mm.Schema):
# Not using a ModelSchema here so this can be used for contribution person links etc. as well!
name = mm.String(attribute='full_name')
affiliation = mm.String()
class Meta:
model = EventPersonLink
fields = ('name', 'affiliation')
class EventSchema(mm.ModelSchema):
url = mm.String(attribute='external_url')
category_path = mm.Function(lambda event: event.category.chain_titles[1:])
event_type = EnumField(EventType, attribute='type_')
creation_date = mm.DateTime(attribute='created_dt')
start_date = mm.DateTime(attribute='start_dt')
end_date = mm.DateTime(attribute='end_dt')
location = mm.Function(_get_location)
speakers_chairs = mm.Nested(PersonLinkSchema, attribute='person_links', many=True)
_access = mm.Function(_get_event_acl)
class Meta:
model = Event
fields = ('_access', 'category_path', 'creation_date', 'description', 'end_date', 'event_type', 'id',
'location', 'speakers_chairs', 'start_date', 'title', 'url')
class AttachmentSchema(mm.ModelSchema):
_access = mm.Function(_get_attachment_acl)
url = mm.String(attribute='absolute_download_url')
name = mm.String(attribute='title')
class Meta:
model = Event
fields = ('_access', 'id', 'url', 'name')
# If you want to test this quickly, keep the code below and the file as indico/web/blueprint.py
# and go to https://yourinstance/schema-test/event/EVENTID
from indico.web.flask.wrappers import IndicoBlueprint
bp = IndicoBlueprint('test', __name__)
@bp.route('/schema-test/event/<int:event_id>')
def event_test(event_id):
event = Event.get_one(event_id)
return EventSchema().jsonify(event)
@bp.route('/schema-test/attachment/<int:attachment_id>')
def attachment_test(attachment_id):
attachment = Attachment.get_one(attachment_id)
return AttachmentSchema().jsonify(attachment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment