# 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/container.py
# class ChildrenContainer(MediaContainer):
#     pass
# 
# Path: plex/objects/library/extra/genre.py
# class Genre(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         items = []
# 
#         for genre in cls.helpers.findall(node, 'Genre'):
#             _, obj = Genre.construct(client, genre, child=True)
# 
#             items.append(obj)
# 
#         return [], items
# 
# 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/library/metadata/artist.py
# class Artist(Directory, Metadata, RateMixin):
#     index = Property(type=int)
# 
#     def all_leaves(self):
#         return self.client['library/metadata'].all_leaves(self.rating_key)
# 
#     def children(self):
#         return self.client['library/metadata'].children(self.rating_key)
# 
#     def __repr__(self):
#         return '<Artist %r>' % self.title
# 
# Path: plex/objects/mixins/rate.py
# class RateMixin(DescriptorMixin):
#     user_rating = Property('userRating', float)
# 
#     def rate(self, value):
#         return Plex['library'].rate(self.rating_key, value)


from plex.objects.core.base import Property
from plex.objects.directory import Directory
from plex.objects.library.container import ChildrenContainer
from plex.objects.library.extra.genre import Genre
from plex.objects.library.metadata.base import Metadata
from plex.objects.library.metadata.artist import Artist
from plex.objects.mixins.rate import RateMixin


class Album(Directory, Metadata, RateMixin):
    artist = Property(resolver=lambda: Album.construct_artist)
    genres = Property(resolver=lambda: Genre.from_node)


# 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/container.py
# class ChildrenContainer(MediaContainer):
#     pass
# 
# Path: plex/objects/library/extra/genre.py
# class Genre(Descriptor):
#     id = Property(type=int)
#     tag = Property
# 
#     @classmethod
#     def from_node(cls, client, node):
#         items = []
# 
#         for genre in cls.helpers.findall(node, 'Genre'):
#             _, obj = Genre.construct(client, genre, child=True)
# 
#             items.append(obj)
# 
#         return [], items
# 
# 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/library/metadata/artist.py
# class Artist(Directory, Metadata, RateMixin):
#     index = Property(type=int)
# 
#     def all_leaves(self):
#         return self.client['library/metadata'].all_leaves(self.rating_key)
# 
#     def children(self):
#         return self.client['library/metadata'].children(self.rating_key)
# 
#     def __repr__(self):
#         return '<Artist %r>' % self.title
# 
# Path: plex/objects/mixins/rate.py
# class RateMixin(DescriptorMixin):
#     user_rating = Property('userRating', float)
# 
#     def rate(self, value):
#         return Plex['library'].rate(self.rating_key, value)


# Path: plex/objects/library/metadata/album.py
from plex.objects.core.base import Property
from plex.objects.directory import Directory
from plex.objects.library.container import ChildrenContainer
from plex.objects.library.extra.genre import Genre
from plex.objects.library.metadata.base import Metadata
from plex.objects.library.metadata.artist import Artist
from plex.objects.mixins.rate import RateMixin



class Album(Directory, Metadata, RateMixin):
    artist = Property(resolver=lambda: Album.construct_artist)
    genres = Property(resolver=lambda: Genre.from_node)


    index = Property(type=int)