# 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/extra/director.py
# class Director(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         return cls.construct(client, cls.helpers.find(node, 'Director'), child=True)
# 
# Path: plex/objects/library/extra/writer.py
# class Writer(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         items = []
# 
#         for genre in cls.helpers.findall(node, 'Writer'):
#             _, obj = Writer.construct(client, genre, child=True)
# 
#             items.append(obj)
# 
#         return [], items
# 
# Path: plex/objects/library/media.py
# class Media(Descriptor):
#     parts = Property(resolver=lambda: Part.from_node)
# 
#     id = Property(type=int)
# 
#     video_codec = Property('videoCodec')
#     video_frame_rate = Property('videoFrameRate')
#     video_resolution = Property('videoResolution')
# 
#     audio_channels = Property('audioChannels', int)
#     audio_codec = Property('audioCodec')
# 
#     container = Property
# 
#     width = Property(type=int)
#     height = Property(type=int)
# 
#     aspect_ratio = Property('aspectRatio', float)
#     bitrate = Property(type=int)
#     duration = Property(type=int)
# 
#     @classmethod
#     def from_node(cls, client, node):
#         return cls.construct(client, cls.helpers.find(node, 'Media'), 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.extra.director import Director
from plex.objects.library.extra.writer import Writer
from plex.objects.library.media import Media
from plex.objects.mixins.session import SessionMixin


class Video(Directory, SessionMixin):
    director = Property(resolver=lambda: Director.from_node)
    media = Property(resolver=lambda: Media.from_node)
    writers = Property(resolver=lambda: Writer.from_node)

    view_count = Property('viewCount', int)
    view_offset = Property('viewOffset', int)

    chapter_images_stale = Property('chapterImagesStale', (int, bool))

# 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/extra/director.py
# class Director(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         return cls.construct(client, cls.helpers.find(node, 'Director'), child=True)
# 
# Path: plex/objects/library/extra/writer.py
# class Writer(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         items = []
# 
#         for genre in cls.helpers.findall(node, 'Writer'):
#             _, obj = Writer.construct(client, genre, child=True)
# 
#             items.append(obj)
# 
#         return [], items
# 
# Path: plex/objects/library/media.py
# class Media(Descriptor):
#     parts = Property(resolver=lambda: Part.from_node)
# 
#     id = Property(type=int)
# 
#     video_codec = Property('videoCodec')
#     video_frame_rate = Property('videoFrameRate')
#     video_resolution = Property('videoResolution')
# 
#     audio_channels = Property('audioChannels', int)
#     audio_codec = Property('audioCodec')
# 
#     container = Property
# 
#     width = Property(type=int)
#     height = Property(type=int)
# 
#     aspect_ratio = Property('aspectRatio', float)
#     bitrate = Property(type=int)
#     duration = Property(type=int)
# 
#     @classmethod
#     def from_node(cls, client, node):
#         return cls.construct(client, cls.helpers.find(node, 'Media'), 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/video.py
from plex.objects.core.base import Property
from plex.objects.directory import Directory
from plex.objects.library.extra.director import Director
from plex.objects.library.extra.writer import Writer
from plex.objects.library.media import Media
from plex.objects.mixins.session import SessionMixin



class Video(Directory, SessionMixin):
    director = Property(resolver=lambda: Director.from_node)
    media = Property(resolver=lambda: Media.from_node)
    writers = Property(resolver=lambda: Writer.from_node)

    view_count = Property('viewCount', int)
    view_offset = Property('viewOffset', int)

    chapter_images_stale = Property('chapterImagesStale', (int, bool))

    chapter_source = Property('chapterSource')