Support for downloading extra artwork from Fanart.tv (resolves #1023).
New image types include:
* clearart
* discart
* extrathumbs
* extrafanart
* logo
* banner
* landscape (16:9 Thumb)
There are a couple things that should be noted:
1. Only English images will be downloaded.
2. The fanart image is now downloaded from Fanart.tv if it can find one, otherwise it uses TMDB
like it used to. This is because the images on Fanart.tv tend to be higher resolutions &
quality.
3. Since multiple extrathumbs and extrafanarts are downloaded into a subdirectory, subdirectories
are now supported for metadata file names. The subdirectories will be automatically created if
they don't exist.
4. Bluray discart will always be preferred over DVD. Ideally, it would prefer DVD versions for
SD quality movies, but I couldn't find an easy way to determine the quality from within the
plugin. I suspect major changes would be needed to the plugin system in general in order to get
this to work. If a user cares about the distinction, the best work-around is to not download
these in Couchpotato and run the Artwork Downloader addon from within XBMC.
5. A maximum of 4 extrathumbs and 20 extrafanarts will be downloaded.
Squashed commit of the following:
commit b113a4def197a9ca8545bde9f5081c0591b93b36
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Thu Apr 24 14:24:12 2014 -0500
Bug-fix and code cleanup.
Fixed a bug where the movie.info event would crash if there aren't any pictures to scrape in
fanart.tv.
commit adf7a4675d472e9e95a316c6cccc681a52804f13
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 16:15:03 2014 -0500
Added support for extrafanart.
Also, the main fanart will be taken from fanart.tv unless one
does not exist.
commit 1791e46c8602f40bb56fe0cf7ecb0607f35b4b12
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 15:13:14 2014 -0500
Couchpotato now downloads extrathumbs from the extra tmdb backdrops if they exist.
This commit made some major changes to the core image creation functionality that
makes writing multiple images to folders possible.
commit c0858807873749dbc928c0260037138f51f894ca
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 12:18:53 2014 -0500
Bug Fix & Implemented functionality to select bluray or dvd disc images.
Currently, only blurays will be selected, unless there are no blurays.
However, if a mechanism for determining the quality of the release is
implemented, it would be simple to make this selection based on the
quality.
commit 786751371d243f53d0f5c6f2c38d92288d8608ba
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 10:59:25 2014 -0500
Fixed a bug where non-HD clearart and logos couldn't be downloaded.
commit feda8df483d13b5a5df3a869f25de8f2c7e6ffe3
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 10:12:31 2014 -0500
Fixed some problems that were missed with the previous merge.
commit 5ddab6c40e69a5accc6c0336cd7485920ff82d8f
Merge: 7273abf ff46aa0
Author: Dan Boehm <dboehm.dev@gmail.com>
Date: Wed Apr 23 10:02:11 2014 -0500
Merge branch 'develop' into fanarttv
Conflicts:
couchpotato/core/media/movie/providers/info/themoviedb.py
couchpotato/core/providers/metadata/xbmc/__init__.py
commit 7273abf827735cf245711c3d3199a6a173a964aa
Author: dan <dan@DBoehm-Arch.danboehm>
Date: Thu Feb 27 13:29:57 2014 -0600
Downloads extra artwork from fanart.tv
Downloads occur with correct filenaming when XBMC metadata is generated,
but the image URLs are selected when the movie.info event is called.
commit 9080d9d749c7e1ddbdc78f7b37a3c5f83195d580
Author: dan <dan@DBoehm-Arch.danboehm>
Date: Wed Feb 26 16:31:37 2014 -0600
Added basic functionality for fanarttv provider.
This should be mostly done and is based on the tvdb provider.
commit 1b39b246c2a9d65f9ef86c4e150a12d893e362c0
Author: dan <dan@DBoehm-Arch.danboehm>
Date: Wed Feb 26 14:50:17 2014 -0600
Updated fanarttv library with the correct package hierarchy
(libs.fanarttv).
commit 8abb7c8f8ad3347900debb9f6a6d5a7acb7df396
Author: dan <dan@DBoehm-Arch.danboehm>
Date: Wed Feb 26 13:12:48 2014 -0600
Added fanart.tv API python library (lib.fanarttv).
The upstream for this library is at
https://github.com/z4r/python-fanart.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
__author__ = 'Andrea De Marco <24erre@gmail.com>'
|
||||
__version__ = '1.4.0'
|
||||
__classifiers__ = [
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
]
|
||||
__copyright__ = "2012, %s " % __author__
|
||||
__license__ = """
|
||||
Copyright %s.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
""" % __copyright__
|
||||
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
__doc__ = """
|
||||
:abstract: Python interface to fanart.tv API
|
||||
:version: %s
|
||||
:author: %s
|
||||
:contact: http://z4r.github.com/
|
||||
:date: 2012-04-04
|
||||
:copyright: %s
|
||||
""" % (__version__, __author__, __license__)
|
||||
|
||||
|
||||
def values(obj):
|
||||
return [v for k, v in obj.__dict__.iteritems() if not k.startswith('_')]
|
||||
|
||||
BASEURL = 'http://api.fanart.tv/webservice'
|
||||
|
||||
|
||||
class FORMAT(object):
|
||||
JSON = 'JSON'
|
||||
XML = 'XML'
|
||||
PHP = 'PHP'
|
||||
|
||||
|
||||
class WS(object):
|
||||
MUSIC = 'artist'
|
||||
MOVIE = 'movie'
|
||||
TV = 'series'
|
||||
|
||||
|
||||
class TYPE(object):
|
||||
ALL = 'all'
|
||||
|
||||
class TV(object):
|
||||
ART = 'clearart'
|
||||
LOGO = 'clearlogo'
|
||||
CHARACTER = 'characterart'
|
||||
THUMB = 'tvthumb'
|
||||
SEASONTHUMB = 'seasonthumb'
|
||||
BACKGROUND = 'showbackground'
|
||||
HDLOGO = 'hdtvlogo'
|
||||
HDART = 'hdclearart'
|
||||
POSTER = 'tvposter'
|
||||
BANNER = 'tvbanner'
|
||||
|
||||
class MUSIC(object):
|
||||
DISC = 'cdart'
|
||||
LOGO = 'musiclogo'
|
||||
BACKGROUND = 'artistbackground'
|
||||
COVER = 'albumcover'
|
||||
THUMB = 'artistthumb'
|
||||
|
||||
class MOVIE(object):
|
||||
ART = 'movieart'
|
||||
LOGO = 'movielogo'
|
||||
DISC = 'moviedisc'
|
||||
POSTER = 'movieposter'
|
||||
BACKGROUND = 'moviebackground'
|
||||
HDLOGO = 'hdmovielogo'
|
||||
HDART = 'hdmovieclearart'
|
||||
BANNER = 'moviebanner'
|
||||
THUMB = 'moviethumb'
|
||||
|
||||
|
||||
class SORT(object):
|
||||
POPULAR = 1
|
||||
NEWEST = 2
|
||||
OLDEST = 3
|
||||
|
||||
|
||||
class LIMIT(object):
|
||||
ONE = 1
|
||||
ALL = 2
|
||||
|
||||
FORMAT_LIST = values(FORMAT)
|
||||
WS_LIST = values(WS)
|
||||
TYPE_LIST = values(TYPE.MUSIC) + values(TYPE.TV) + values(TYPE.MOVIE) + [TYPE.ALL]
|
||||
MUSIC_TYPE_LIST = values(TYPE.MUSIC) + [TYPE.ALL]
|
||||
TV_TYPE_LIST = values(TYPE.TV) + [TYPE.ALL]
|
||||
MOVIE_TYPE_LIST = values(TYPE.MOVIE) + [TYPE.ALL]
|
||||
SORT_LIST = values(SORT)
|
||||
LIMIT_LIST = values(LIMIT)
|
||||
@@ -0,0 +1,44 @@
|
||||
import libs.requests as requests
|
||||
import libs.fanarttv as fanart
|
||||
from libs.fanarttv.errors import RequestFanartError, ResponseFanartError
|
||||
|
||||
|
||||
class Request(object):
|
||||
def __init__(self, apikey, id, ws, type=None, sort=None, limit=None):
|
||||
self._apikey = apikey
|
||||
self._id = id
|
||||
self._ws = ws
|
||||
self._type = type or fanart.TYPE.ALL
|
||||
self._sort = sort or fanart.SORT.POPULAR
|
||||
self._limit = limit or fanart.LIMIT.ALL
|
||||
self.validate()
|
||||
self._response = None
|
||||
|
||||
def validate(self):
|
||||
for attribute_name in ('ws', 'type', 'sort', 'limit'):
|
||||
attribute = getattr(self, '_' + attribute_name)
|
||||
choices = getattr(fanart, attribute_name.upper() + '_LIST')
|
||||
if attribute not in choices:
|
||||
raise RequestFanartError('Not allowed {0}: {1} [{2}]'.format(attribute_name, attribute, ', '.join(choices)))
|
||||
|
||||
def __str__(self):
|
||||
return '/'.join(map(str, [
|
||||
fanart.BASEURL,
|
||||
self._ws,
|
||||
self._apikey,
|
||||
self._id,
|
||||
fanart.FORMAT.JSON,
|
||||
self._type,
|
||||
self._sort,
|
||||
self._limit,
|
||||
]))
|
||||
|
||||
def response(self):
|
||||
try:
|
||||
response = requests.get(str(self))
|
||||
rjson = response.json()
|
||||
if not isinstance(rjson, dict):
|
||||
raise Exception(response.text)
|
||||
return rjson
|
||||
except Exception as e:
|
||||
raise ResponseFanartError(str(e))
|
||||
@@ -0,0 +1,15 @@
|
||||
class FanartError(Exception):
|
||||
def __str__(self):
|
||||
return ', '.join(map(str, self.args))
|
||||
|
||||
def __repr__(self):
|
||||
name = self.__class__.__name__
|
||||
return '%s%r' % (name, self.args)
|
||||
|
||||
|
||||
class ResponseFanartError(FanartError):
|
||||
pass
|
||||
|
||||
|
||||
class RequestFanartError(FanartError):
|
||||
pass
|
||||
@@ -0,0 +1,46 @@
|
||||
class Immutable(object):
|
||||
_mutable = False
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if self._mutable or name == '_mutable':
|
||||
super(Immutable, self).__setattr__(name, value)
|
||||
else:
|
||||
raise TypeError("Can't modify immutable instance")
|
||||
|
||||
def __delattr__(self, name):
|
||||
if self._mutable:
|
||||
super(Immutable, self).__delattr__(name)
|
||||
else:
|
||||
raise TypeError("Can't modify immutable instance")
|
||||
|
||||
def __eq__(self, other):
|
||||
return hash(self) == hash(other)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(repr(self))
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (
|
||||
self.__class__.__name__,
|
||||
', '.join(['{0}={1}'.format(k, repr(v)) for k, v in self])
|
||||
)
|
||||
|
||||
def __iter__(self):
|
||||
l = self.__dict__.keys()
|
||||
l.sort()
|
||||
for k in l:
|
||||
if not k.startswith('_'):
|
||||
yield k, getattr(self, k)
|
||||
|
||||
@staticmethod
|
||||
def mutablemethod(f):
|
||||
def func(self, *args, **kwargs):
|
||||
if isinstance(self, Immutable):
|
||||
old_mutable = self._mutable
|
||||
self._mutable = True
|
||||
res = f(self, *args, **kwargs)
|
||||
self._mutable = old_mutable
|
||||
else:
|
||||
res = f(self, *args, **kwargs)
|
||||
return res
|
||||
return func
|
||||
@@ -0,0 +1,68 @@
|
||||
import json
|
||||
import os
|
||||
import libs.requests as requests
|
||||
from libs.fanarttv.core import Request
|
||||
from libs.fanarttv.immutable import Immutable
|
||||
|
||||
|
||||
class LeafItem(Immutable):
|
||||
KEY = NotImplemented
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes):
|
||||
self.id = int(id)
|
||||
self.url = url
|
||||
self.likes = int(likes)
|
||||
self._content = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, resource):
|
||||
return cls(**dict([(str(k), v) for k, v in resource.iteritems()]))
|
||||
|
||||
@classmethod
|
||||
def extract(cls, resource):
|
||||
return [cls.from_dict(i) for i in resource.get(cls.KEY, {})]
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def content(self):
|
||||
if not self._content:
|
||||
self._content = requests.get(self.url).content
|
||||
return self._content
|
||||
|
||||
def __str__(self):
|
||||
return self.url
|
||||
|
||||
|
||||
class ResourceItem(Immutable):
|
||||
WS = NotImplemented
|
||||
request_cls = Request
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, map):
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def get(cls, id):
|
||||
map = cls.request_cls(
|
||||
apikey=os.environ.get('FANART_APIKEY'),
|
||||
id=id,
|
||||
ws=cls.WS
|
||||
).response()
|
||||
return cls.from_dict(map)
|
||||
|
||||
def json(self, **kw):
|
||||
return json.dumps(
|
||||
self,
|
||||
default=lambda o: dict([(k, v) for k, v in o.__dict__.items() if not k.startswith('_')]),
|
||||
**kw
|
||||
)
|
||||
|
||||
|
||||
class CollectableItem(Immutable):
|
||||
@classmethod
|
||||
def from_dict(cls, key, map):
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def collection_from_dict(cls, map):
|
||||
return [cls.from_dict(k, v) for k, v in map.iteritems()]
|
||||
@@ -0,0 +1,103 @@
|
||||
import libs.fanarttv as fanart
|
||||
from libs.fanarttv.items import LeafItem, Immutable, ResourceItem
|
||||
__all__ = (
|
||||
'ArtItem',
|
||||
'DiscItem',
|
||||
'LogoItem',
|
||||
'PosterItem',
|
||||
'BackgroundItem',
|
||||
'HdLogoItem',
|
||||
'HdArtItem',
|
||||
'BannerItem',
|
||||
'ThumbItem',
|
||||
'Movie',
|
||||
)
|
||||
|
||||
|
||||
class MovieItem(LeafItem):
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes, lang):
|
||||
super(MovieItem, self).__init__(id, url, likes)
|
||||
self.lang = lang
|
||||
|
||||
|
||||
class DiscItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.DISC
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes, lang, disc, disc_type):
|
||||
super(DiscItem, self).__init__(id, url, likes, lang)
|
||||
self.disc = int(disc)
|
||||
self.disc_type = disc_type
|
||||
|
||||
|
||||
class ArtItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.ART
|
||||
|
||||
|
||||
class LogoItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.LOGO
|
||||
|
||||
|
||||
class PosterItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.POSTER
|
||||
|
||||
|
||||
class BackgroundItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.BACKGROUND
|
||||
|
||||
|
||||
class HdLogoItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.HDLOGO
|
||||
|
||||
|
||||
class HdArtItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.HDART
|
||||
|
||||
|
||||
class BannerItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.BANNER
|
||||
|
||||
|
||||
class ThumbItem(MovieItem):
|
||||
KEY = fanart.TYPE.MOVIE.THUMB
|
||||
|
||||
|
||||
class Movie(ResourceItem):
|
||||
WS = fanart.WS.MOVIE
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, name, imdbid, tmdbid, arts, logos, discs, posters, backgrounds, hdlogos, hdarts,
|
||||
banners, thumbs):
|
||||
self.name = name
|
||||
self.imdbid = imdbid
|
||||
self.tmdbid = tmdbid
|
||||
self.arts = arts
|
||||
self.posters = posters
|
||||
self.logos = logos
|
||||
self.discs = discs
|
||||
self.backgrounds = backgrounds
|
||||
self.hdlogos = hdlogos
|
||||
self.hdarts = hdarts
|
||||
self.banners = banners
|
||||
self.thumbs = thumbs
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, resource):
|
||||
assert len(resource) == 1, 'Bad Format Map'
|
||||
name, resource = resource.items()[0]
|
||||
return cls(
|
||||
name=name,
|
||||
imdbid=resource['imdb_id'],
|
||||
tmdbid=resource['tmdb_id'],
|
||||
arts=ArtItem.extract(resource),
|
||||
logos=LogoItem.extract(resource),
|
||||
discs=DiscItem.extract(resource),
|
||||
posters=PosterItem.extract(resource),
|
||||
backgrounds=BackgroundItem.extract(resource),
|
||||
hdlogos=HdLogoItem.extract(resource),
|
||||
hdarts=HdArtItem.extract(resource),
|
||||
banners=BannerItem.extract(resource),
|
||||
thumbs=ThumbItem.extract(resource),
|
||||
)
|
||||
@@ -0,0 +1,80 @@
|
||||
from libs.fanarttv.items import Immutable, LeafItem, ResourceItem, CollectableItem
|
||||
import libs.fanarttv as fanart
|
||||
__all__ = (
|
||||
'BackgroundItem',
|
||||
'CoverItem',
|
||||
'LogoItem',
|
||||
'ThumbItem',
|
||||
'DiscItem',
|
||||
'Artist',
|
||||
'Album',
|
||||
)
|
||||
|
||||
|
||||
class BackgroundItem(LeafItem):
|
||||
KEY = fanart.TYPE.MUSIC.BACKGROUND
|
||||
|
||||
|
||||
class CoverItem(LeafItem):
|
||||
KEY = fanart.TYPE.MUSIC.COVER
|
||||
|
||||
|
||||
class LogoItem(LeafItem):
|
||||
KEY = fanart.TYPE.MUSIC.LOGO
|
||||
|
||||
|
||||
class ThumbItem(LeafItem):
|
||||
KEY = fanart.TYPE.MUSIC.THUMB
|
||||
|
||||
|
||||
class DiscItem(LeafItem):
|
||||
KEY = fanart.TYPE.MUSIC.DISC
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes, disc, size):
|
||||
super(DiscItem, self).__init__(id, url, likes)
|
||||
self.disc = int(disc)
|
||||
self.size = int(size)
|
||||
|
||||
|
||||
class Artist(ResourceItem):
|
||||
WS = fanart.WS.MUSIC
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, name, mbid, albums, backgrounds, logos, thumbs):
|
||||
self.name = name
|
||||
self.mbid = mbid
|
||||
self.albums = albums
|
||||
self.backgrounds = backgrounds
|
||||
self.logos = logos
|
||||
self.thumbs = thumbs
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, resource):
|
||||
assert len(resource) == 1, 'Bad Format Map'
|
||||
name, resource = resource.items()[0]
|
||||
return cls(
|
||||
name=name,
|
||||
mbid=resource['mbid_id'],
|
||||
albums=Album.collection_from_dict(resource.get('albums', {})),
|
||||
backgrounds=BackgroundItem.extract(resource),
|
||||
thumbs=ThumbItem.extract(resource),
|
||||
logos=LogoItem.extract(resource),
|
||||
)
|
||||
|
||||
|
||||
class Album(CollectableItem):
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, mbid, covers, arts):
|
||||
self.mbid = mbid
|
||||
self.covers = covers
|
||||
self.arts = arts
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, key, resource):
|
||||
return cls(
|
||||
mbid=key,
|
||||
covers=CoverItem.extract(resource),
|
||||
arts=DiscItem.extract(resource),
|
||||
)
|
||||
@@ -0,0 +1,108 @@
|
||||
import libs.fanarttv as fanart
|
||||
from libs.fanarttv.items import LeafItem, Immutable, ResourceItem
|
||||
__all__ = (
|
||||
'CharacterItem',
|
||||
'ArtItem',
|
||||
'LogoItem',
|
||||
'BackgroundItem',
|
||||
'SeasonItem',
|
||||
'ThumbItem',
|
||||
'HdLogoItem',
|
||||
'HdArtItem',
|
||||
'PosterItem',
|
||||
'BannerItem',
|
||||
'TvShow',
|
||||
)
|
||||
|
||||
|
||||
class TvItem(LeafItem):
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes, lang):
|
||||
super(TvItem, self).__init__(id, url, likes)
|
||||
self.lang = lang
|
||||
|
||||
|
||||
class SeasonedTvItem(TvItem):
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, id, url, likes, lang, season):
|
||||
super(SeasonedTvItem, self).__init__(id, url, likes, lang)
|
||||
self.season = 0 if season == 'all' else int(season or 0)
|
||||
|
||||
|
||||
class CharacterItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.CHARACTER
|
||||
|
||||
|
||||
class ArtItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.ART
|
||||
|
||||
|
||||
class LogoItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.LOGO
|
||||
|
||||
|
||||
class BackgroundItem(SeasonedTvItem):
|
||||
KEY = fanart.TYPE.TV.BACKGROUND
|
||||
|
||||
|
||||
class SeasonItem(SeasonedTvItem):
|
||||
KEY = fanart.TYPE.TV.SEASONTHUMB
|
||||
|
||||
|
||||
class ThumbItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.THUMB
|
||||
|
||||
|
||||
class HdLogoItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.HDLOGO
|
||||
|
||||
|
||||
class HdArtItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.HDART
|
||||
|
||||
|
||||
class PosterItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.POSTER
|
||||
|
||||
|
||||
class BannerItem(TvItem):
|
||||
KEY = fanart.TYPE.TV.BANNER
|
||||
|
||||
|
||||
class TvShow(ResourceItem):
|
||||
WS = fanart.WS.TV
|
||||
|
||||
@Immutable.mutablemethod
|
||||
def __init__(self, name, tvdbid, backgrounds, characters, arts, logos, seasons, thumbs, hdlogos, hdarts, posters,
|
||||
banners):
|
||||
self.name = name
|
||||
self.tvdbid = tvdbid
|
||||
self.backgrounds = backgrounds
|
||||
self.characters = characters
|
||||
self.arts = arts
|
||||
self.logos = logos
|
||||
self.seasons = seasons
|
||||
self.thumbs = thumbs
|
||||
self.hdlogos = hdlogos
|
||||
self.hdarts = hdarts
|
||||
self.posters = posters
|
||||
self.banners = banners
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, resource):
|
||||
assert len(resource) == 1, 'Bad Format Map'
|
||||
name, resource = resource.items()[0]
|
||||
return cls(
|
||||
name=name,
|
||||
tvdbid=resource['thetvdb_id'],
|
||||
backgrounds=BackgroundItem.extract(resource),
|
||||
characters=CharacterItem.extract(resource),
|
||||
arts=ArtItem.extract(resource),
|
||||
logos=LogoItem.extract(resource),
|
||||
seasons=SeasonItem.extract(resource),
|
||||
thumbs=ThumbItem.extract(resource),
|
||||
hdlogos=HdLogoItem.extract(resource),
|
||||
hdarts=HdArtItem.extract(resource),
|
||||
posters=PosterItem.extract(resource),
|
||||
banners=BannerItem.extract(resource),
|
||||
)
|
||||
Reference in New Issue
Block a user