# Path: zenodo/modules/records/models.py
# class ObjectType(object):
#     """Class to load object types data."""
# 
#     index_id = None
#     index_internal_id = None
#     types = None
#     subtypes = None
# 
#     @classmethod
#     def _load_data(cls):
#         """Load object types for JSON data."""
#         if cls.index_id is None:
#             with open(join(dirname(__file__), "data", "objecttypes.json")) \
#                     as fp:
#                 data = json.load(fp)
# 
#             cls.index_internal_id = {}
#             cls.index_id = {}
#             cls.types = set()
#             cls.subtypes = {}
#             for objtype in data:
#                 cls.index_internal_id[objtype['internal_id']] = objtype
#                 cls.index_id[objtype['id'][:-1]] = objtype
#                 if '-' in objtype['internal_id']:
#                     type_, subtype = objtype['internal_id'].split('-')
#                     cls.types.add(type_)
#                     if type_ not in cls.subtypes:
#                         cls.subtypes[type_] = set()
#                     cls.subtypes[type_].add(subtype)
#                 else:
#                     cls.types.add(objtype['internal_id'])
# 
#     @classmethod
#     def validate_internal_id(cls, id):
#         """Check if the provided ID corresponds to the internal ones."""
#         cls._load_data()
#         return id in cls.index_internal_id
# 
#     @classmethod
#     def _jsonloader(cls, uri, **dummy_kwargs):
#         """Local JSON loader for JsonRef."""
#         cls._load_data()
#         return cls.index_id[uri]
# 
#     @classmethod
#     def get(cls, value):
#         """Get object type value."""
#         cls._load_data()
#         try:
#             return JsonRef.replace_refs(
#                 cls.index_internal_id[value],
#                 jsonschema=True,
#                 loader=cls._jsonloader)
#         except KeyError:
#             return None
# 
#     @classmethod
#     def get_types(cls):
#         """Get object type value."""
#         cls._load_data()
#         return cls.types
# 
#     @classmethod
#     def get_subtypes(cls, type_):
#         """Get object type value."""
#         cls._load_data()
#         return cls.subtypes[type_]
# 
#     @classmethod
#     def get_by_dict(cls, value):
#         """Get object type dict with type and subtype key."""
#         if not value:
#             return None
#         if 'subtype' in value:
#             if isinstance(value, AttrDict):
#                 value = value.to_dict()
#             internal_id = "{0}-{1}".format(
#                 value.get('type', ''),
#                 value.get('subtype', '')
#             )
#         else:
#             internal_id = value['type']
#         return cls.get(internal_id)
# 
#     @classmethod
#     def get_openaire_subtype(cls, value):
#         """Get the OpenAIRE community-specific subtype.
# 
#         OpenAIRE community-specific subtype requires that the record is
#         accepted to the relevant community.
# 
#         :param value: Full 'metadata' dictionary. Higher level metadata is
#                       required since we are fetching both 'resource_type' and
#                       'communities'.
#         :type value: dict
#         :returns: Subtype in the form "openaire:<OA-comm-ID>:<OA-subtype-ID>"
#                   or None.
#         :rtype: str
#         """
#         comms = value.get('communities', [])
#         oa_type = value['resource_type'].get('openaire_subtype')
#         if oa_type and is_valid_openaire_type(value['resource_type'], comms):
#             return 'openaire:' + oa_type
# 
# 
#     @classmethod
#     def get_cff_type(cls, value):
#         resource_type_obj = cls.index_internal_id
#         for key in resource_type_obj:
#             if value == resource_type_obj[key].get('cff'):
#                 return resource_type_obj[key]['internal_id']
#         return None
# 
# Path: zenodo/modules/records/serializers/schemas/common.py
# def api_link_for(tpl, **kwargs):
#     """Create an API link using specific template."""
#     is_api_app = 'invenio-deposit-rest' in current_app.extensions
# 
#     base = '{}/api'
#     if current_app.testing and is_api_app:
#         base = '{}'
# 
#     return link_for(
#         base.format(current_app.config['THEME_SITEURL']), tpl, **kwargs)
# 
# def ui_link_for(tpl, **kwargs):
#     """Create an UI link using specific template."""
#     return link_for(current_app.config['THEME_SITEURL'], tpl, **kwargs)


import idutils
import pycountry
from flask import current_app, request
from invenio_iiif.previewer import previewable_extensions as thumbnail_exts
from invenio_iiif.utils import ui_iiif_image_url
from marshmallow import Schema, fields, missing, pre_dump
from ...models import ObjectType
from ..fields import DateString, SanitizedHTML, SanitizedUnicode
from .common import api_link_for, ui_link_for

    # NOTE: Zenodo communities?
    # sourceOrganization

    def get_dates(self, obj):
        """Get dates of the record."""
        dates = []
        for interval in obj['metadata'].get('dates', []):
            start = interval.get('start') or '..'
            end = interval.get('end') or '..'
            if start != '..' and end != '..' and start == end:
                dates.append(start)
            else:
                dates.append(start + '/' + end)
        return dates or missing

    def get_context(self, obj):
        """Returns the value for '@context' value."""
        return self.CONTEXT

    def get_doi(self, obj):
        """Get DOI of the record."""
        data = obj['metadata']
        return idutils.to_url(data['doi'], 'doi', 'https') \
            if data.get('doi') \
            else missing

    def get_type(self, obj):
        """Get schema.org type of the record."""
        data = obj['metadata']

# Path: zenodo/modules/records/models.py
# class ObjectType(object):
#     """Class to load object types data."""
# 
#     index_id = None
#     index_internal_id = None
#     types = None
#     subtypes = None
# 
#     @classmethod
#     def _load_data(cls):
#         """Load object types for JSON data."""
#         if cls.index_id is None:
#             with open(join(dirname(__file__), "data", "objecttypes.json")) \
#                     as fp:
#                 data = json.load(fp)
# 
#             cls.index_internal_id = {}
#             cls.index_id = {}
#             cls.types = set()
#             cls.subtypes = {}
#             for objtype in data:
#                 cls.index_internal_id[objtype['internal_id']] = objtype
#                 cls.index_id[objtype['id'][:-1]] = objtype
#                 if '-' in objtype['internal_id']:
#                     type_, subtype = objtype['internal_id'].split('-')
#                     cls.types.add(type_)
#                     if type_ not in cls.subtypes:
#                         cls.subtypes[type_] = set()
#                     cls.subtypes[type_].add(subtype)
#                 else:
#                     cls.types.add(objtype['internal_id'])
# 
#     @classmethod
#     def validate_internal_id(cls, id):
#         """Check if the provided ID corresponds to the internal ones."""
#         cls._load_data()
#         return id in cls.index_internal_id
# 
#     @classmethod
#     def _jsonloader(cls, uri, **dummy_kwargs):
#         """Local JSON loader for JsonRef."""
#         cls._load_data()
#         return cls.index_id[uri]
# 
#     @classmethod
#     def get(cls, value):
#         """Get object type value."""
#         cls._load_data()
#         try:
#             return JsonRef.replace_refs(
#                 cls.index_internal_id[value],
#                 jsonschema=True,
#                 loader=cls._jsonloader)
#         except KeyError:
#             return None
# 
#     @classmethod
#     def get_types(cls):
#         """Get object type value."""
#         cls._load_data()
#         return cls.types
# 
#     @classmethod
#     def get_subtypes(cls, type_):
#         """Get object type value."""
#         cls._load_data()
#         return cls.subtypes[type_]
# 
#     @classmethod
#     def get_by_dict(cls, value):
#         """Get object type dict with type and subtype key."""
#         if not value:
#             return None
#         if 'subtype' in value:
#             if isinstance(value, AttrDict):
#                 value = value.to_dict()
#             internal_id = "{0}-{1}".format(
#                 value.get('type', ''),
#                 value.get('subtype', '')
#             )
#         else:
#             internal_id = value['type']
#         return cls.get(internal_id)
# 
#     @classmethod
#     def get_openaire_subtype(cls, value):
#         """Get the OpenAIRE community-specific subtype.
# 
#         OpenAIRE community-specific subtype requires that the record is
#         accepted to the relevant community.
# 
#         :param value: Full 'metadata' dictionary. Higher level metadata is
#                       required since we are fetching both 'resource_type' and
#                       'communities'.
#         :type value: dict
#         :returns: Subtype in the form "openaire:<OA-comm-ID>:<OA-subtype-ID>"
#                   or None.
#         :rtype: str
#         """
#         comms = value.get('communities', [])
#         oa_type = value['resource_type'].get('openaire_subtype')
#         if oa_type and is_valid_openaire_type(value['resource_type'], comms):
#             return 'openaire:' + oa_type
# 
# 
#     @classmethod
#     def get_cff_type(cls, value):
#         resource_type_obj = cls.index_internal_id
#         for key in resource_type_obj:
#             if value == resource_type_obj[key].get('cff'):
#                 return resource_type_obj[key]['internal_id']
#         return None
# 
# Path: zenodo/modules/records/serializers/schemas/common.py
# def api_link_for(tpl, **kwargs):
#     """Create an API link using specific template."""
#     is_api_app = 'invenio-deposit-rest' in current_app.extensions
# 
#     base = '{}/api'
#     if current_app.testing and is_api_app:
#         base = '{}'
# 
#     return link_for(
#         base.format(current_app.config['THEME_SITEURL']), tpl, **kwargs)
# 
# def ui_link_for(tpl, **kwargs):
#     """Create an UI link using specific template."""
#     return link_for(current_app.config['THEME_SITEURL'], tpl, **kwargs)


# Path: zenodo/modules/records/serializers/schemas/schemaorg.py
import idutils
import pycountry
from flask import current_app, request
from invenio_iiif.previewer import previewable_extensions as thumbnail_exts
from invenio_iiif.utils import ui_iiif_image_url
from marshmallow import Schema, fields, missing, pre_dump
from ...models import ObjectType
from ..fields import DateString, SanitizedHTML, SanitizedUnicode
from .common import api_link_for, ui_link_for


    # NOTE: Zenodo communities?
    # sourceOrganization

    def get_dates(self, obj):
        """Get dates of the record."""
        dates = []
        for interval in obj['metadata'].get('dates', []):
            start = interval.get('start') or '..'
            end = interval.get('end') or '..'
            if start != '..' and end != '..' and start == end:
                dates.append(start)
            else:
                dates.append(start + '/' + end)
        return dates or missing

    def get_context(self, obj):
        """Returns the value for '@context' value."""
        return self.CONTEXT

    def get_doi(self, obj):
        """Get DOI of the record."""
        data = obj['metadata']
        return idutils.to_url(data['doi'], 'doi', 'https') \
            if data.get('doi') \
            else missing

    def get_type(self, obj):
        """Get schema.org type of the record."""
        data = obj['metadata']

        obj_type = ObjectType.get_by_dict(data['resource_type'])