# Path: plex/objects/core/base.py
# class Property(object):
#     helpers = Interface.helpers
# 
#     def __init__(self, name=None, type=None, resolver=None):
#         self.name = name
#         self.type = type
#         self.resolver = resolver
# 
#     def value(self, descriptor, client, key, node, keys_used):
#         if self.resolver is not None:
#             return self.value_func(descriptor, client, key, node, keys_used)
# 
#         return self.value_node(descriptor, key, node, keys_used)
# 
#     def value_node(self, descriptor, key, node, keys_used):
#         value = self.helpers.get(node, key)
# 
#         if value is None:
#             return None
# 
#         keys_used.append(key.lower())
# 
#         try:
#             return self.value_convert(value)
#         except Exception as ex:
#             log.warn('[%s] Unable to parse property %r - %%s' % (descriptor.__name__, key), ex, exc_info=True)
#             return None
# 
#     def value_convert(self, value):
#         if not self.type:
#             return value
# 
#         types = self.type if isinstance(self.type, collections.Iterable) else [self.type]
#         result = value
# 
#         for target_type in types:
#             try:
#                 result = target_type(result)
#             except Exception as ex:
#                 six.reraise(ex, None, sys.exc_info()[2])
# 
#         return result
# 
#     def value_func(self, descriptor, client, key, node, keys_used):
#         func = self.resolver()
# 
#         try:
#             keys, value = func(client, node)
# 
#             keys_used.extend([k.lower() for k in keys])
#             return value
#         except Exception as ex:
#             log.warn('[%s] Exception raised in value function for %r - %%s' % (descriptor.__name__, key), ex, exc_info=True)
#             return None
# 
# Path: plex/objects/directory.py
# class Directory(Descriptor):
#     key = Property
#     type = Property
# 
#     title = Property
# 
#     art = Property
#     thumb = Property
# 
#     allow_sync = Property('allowSync', bool)
#     updated_at = Property('updatedAt', int)
# 
# Path: plex/objects/library/metadata/base.py
# class Metadata(Descriptor):
#     section = Property(resolver=lambda: Metadata.construct_section)
# 
#     key = Property
#     guid = Property
#     rating_key = Property('ratingKey')
#     extra_key = Property('primaryExtraKey')
# 
#     title = Property
#     title_sort = Property('titleSort')
#     title_sort_saved = Property('titleSortSaved')
#     title_original = Property('originalTitle')
# 
#     audience_rating = Property('audienceRating', float)
#     audience_rating_image = Property('audienceRatingImage')
# 
#     content_rating = Property('contentRating')
#     content_rating_age = Property('contentRatingAge', int)
# 
#     rating = Property(type=float)
#     rating_count = Property('ratingCount')
#     rating_image = Property('ratingImage')
# 
#     studio = Property
#     summary = Property
#     tagline = Property
#     year = Property(type=int)
# 
#     thumb = Property
# 
#     source_icon = Property('sourceIcon')
#     source_title = Property('sourceTitle')
#     url = Property('url')
# 
#     deferred = Property(type=(int, bool))
# 
#     added_at = Property('addedAt', int)
#     created_at_accuracy = Property('createdAtAccuracy')
#     created_at_tzoffset = Property('createdAtTZOffset', int)
#     deleted_at = Property('deletedAt', int)
#     first_scan_added_at = Property('firstScanAddedAt', int)
#     last_viewed_at = Property('lastViewedAt', int)
#     originally_available_at = Property('originallyAvailableAt')
# 
#     @staticmethod
#     def construct_section(client, node):
#         attribute_map = {
#             'key': 'librarySectionID',
#             'uuid': 'librarySectionUUID',
#             'title': 'librarySectionTitle'
#         }
# 
#         return Section.construct(client, node, attribute_map, child=True)
# 
# Path: plex/objects/mixins/session.py
# class SessionMixin(DescriptorMixin):
#     session = Property(resolver=lambda: SessionMixin.construct_session)
# 
#     @staticmethod
#     def construct_session(client, node):
#         return Session.construct(client, node, child=True)


from plex.objects.core.base import Property
from plex.objects.directory import Directory
from plex.objects.library.metadata.base import Metadata
from plex.objects.mixins.session import SessionMixin


class PhotoAlbum(Directory, Metadata):
    index = Property(type=int)

    def __repr__(self):
        return '<PhotoAlbum %r>' % self.title


class Photo(Directory, Metadata, SessionMixin):
    grandparent = Property(resolver=lambda: Photo.construct_grandparent)

# Path: plex/objects/core/base.py
# class Property(object):
#     helpers = Interface.helpers
# 
#     def __init__(self, name=None, type=None, resolver=None):
#         self.name = name
#         self.type = type
#         self.resolver = resolver
# 
#     def value(self, descriptor, client, key, node, keys_used):
#         if self.resolver is not None:
#             return self.value_func(descriptor, client, key, node, keys_used)
# 
#         return self.value_node(descriptor, key, node, keys_used)
# 
#     def value_node(self, descriptor, key, node, keys_used):
#         value = self.helpers.get(node, key)
# 
#         if value is None:
#             return None
# 
#         keys_used.append(key.lower())
# 
#         try:
#             return self.value_convert(value)
#         except Exception as ex:
#             log.warn('[%s] Unable to parse property %r - %%s' % (descriptor.__name__, key), ex, exc_info=True)
#             return None
# 
#     def value_convert(self, value):
#         if not self.type:
#             return value
# 
#         types = self.type if isinstance(self.type, collections.Iterable) else [self.type]
#         result = value
# 
#         for target_type in types:
#             try:
#                 result = target_type(result)
#             except Exception as ex:
#                 six.reraise(ex, None, sys.exc_info()[2])
# 
#         return result
# 
#     def value_func(self, descriptor, client, key, node, keys_used):
#         func = self.resolver()
# 
#         try:
#             keys, value = func(client, node)
# 
#             keys_used.extend([k.lower() for k in keys])
#             return value
#         except Exception as ex:
#             log.warn('[%s] Exception raised in value function for %r - %%s' % (descriptor.__name__, key), ex, exc_info=True)
#             return None
# 
# Path: plex/objects/directory.py
# class Directory(Descriptor):
#     key = Property
#     type = Property
# 
#     title = Property
# 
#     art = Property
#     thumb = Property
# 
#     allow_sync = Property('allowSync', bool)
#     updated_at = Property('updatedAt', int)
# 
# Path: plex/objects/library/metadata/base.py
# class Metadata(Descriptor):
#     section = Property(resolver=lambda: Metadata.construct_section)
# 
#     key = Property
#     guid = Property
#     rating_key = Property('ratingKey')
#     extra_key = Property('primaryExtraKey')
# 
#     title = Property
#     title_sort = Property('titleSort')
#     title_sort_saved = Property('titleSortSaved')
#     title_original = Property('originalTitle')
# 
#     audience_rating = Property('audienceRating', float)
#     audience_rating_image = Property('audienceRatingImage')
# 
#     content_rating = Property('contentRating')
#     content_rating_age = Property('contentRatingAge', int)
# 
#     rating = Property(type=float)
#     rating_count = Property('ratingCount')
#     rating_image = Property('ratingImage')
# 
#     studio = Property
#     summary = Property
#     tagline = Property
#     year = Property(type=int)
# 
#     thumb = Property
# 
#     source_icon = Property('sourceIcon')
#     source_title = Property('sourceTitle')
#     url = Property('url')
# 
#     deferred = Property(type=(int, bool))
# 
#     added_at = Property('addedAt', int)
#     created_at_accuracy = Property('createdAtAccuracy')
#     created_at_tzoffset = Property('createdAtTZOffset', int)
#     deleted_at = Property('deletedAt', int)
#     first_scan_added_at = Property('firstScanAddedAt', int)
#     last_viewed_at = Property('lastViewedAt', int)
#     originally_available_at = Property('originallyAvailableAt')
# 
#     @staticmethod
#     def construct_section(client, node):
#         attribute_map = {
#             'key': 'librarySectionID',
#             'uuid': 'librarySectionUUID',
#             'title': 'librarySectionTitle'
#         }
# 
#         return Section.construct(client, node, attribute_map, child=True)
# 
# Path: plex/objects/mixins/session.py
# class SessionMixin(DescriptorMixin):
#     session = Property(resolver=lambda: SessionMixin.construct_session)
# 
#     @staticmethod
#     def construct_session(client, node):
#         return Session.construct(client, node, child=True)


# Path: plex/objects/library/metadata/photo.py
from plex.objects.core.base import Property
from plex.objects.directory import Directory
from plex.objects.library.metadata.base import Metadata
from plex.objects.mixins.session import SessionMixin



class PhotoAlbum(Directory, Metadata):
    index = Property(type=int)

    def __repr__(self):
        return '<PhotoAlbum %r>' % self.title


class Photo(Directory, Metadata, SessionMixin):
    grandparent = Property(resolver=lambda: Photo.construct_grandparent)

    parent = Property(resolver=lambda: Photo.construct_parent)