-
-
Save ThiefMaster/bd78f52909ec963023ce2e368874dac6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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