1
0
mirror of https://github.com/moparisthebest/SickRage synced 2024-08-13 16:53:54 -04:00

Added FanArt.TV API package to libs, we now try to get images from fanart.tv if we can't find them on theTVDB or TMDB.

This commit is contained in:
echel0n 2014-12-20 09:05:38 -08:00
parent 2d14eef522
commit de1c40db01
23 changed files with 2314 additions and 17 deletions

110
lib/fanart/__init__.py Normal file
View File

@ -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)

44
lib/fanart/core.py Normal file
View File

@ -0,0 +1,44 @@
import requests
import fanart
from fanart.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))

15
lib/fanart/errors.py Normal file
View File

@ -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

46
lib/fanart/immutable.py Normal file
View File

@ -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

68
lib/fanart/items.py Normal file
View File

@ -0,0 +1,68 @@
import json
import os
import requests
from fanart.core import Request
from fanart.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()]

103
lib/fanart/movie.py Normal file
View File

@ -0,0 +1,103 @@
import fanart
from fanart.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),
)

80
lib/fanart/music.py Normal file
View File

@ -0,0 +1,80 @@
from fanart.items import Immutable, LeafItem, ResourceItem, CollectableItem
import 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),
)

View File

@ -0,0 +1,3 @@
import os
LOCALDIR = os.path.dirname(__file__)

View File

@ -0,0 +1,196 @@
{
"logos": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-4e04b6495dfd3.png",
"likes": 2,
"id": 11977
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-517ac36e39f67.png",
"likes": 1,
"id": 28249
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-51f557082cfde.png",
"likes": 0,
"id": 31817
}
],
"arts": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/clearart/wilfred-us-4e05f10e87711.png",
"likes": 2,
"id": 11987
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/clearart/wilfred-us-4e2f151d5ed62.png",
"likes": 1,
"id": 12470
}
],
"name": "Wilfred (US)",
"hdarts": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdclearart/wilfred-us-505f94ed0ba13.png",
"likes": 1,
"id": 21112
},
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdclearart/wilfred-us-52403264aa3ec.png",
"likes": 1,
"id": 33751
}
],
"backgrounds": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-5034dbd49115e.jpg",
"id": 19965,
"season": 0,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92db6973.jpg",
"id": 23166,
"season": 0,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92dbb46b.jpg",
"id": 23167,
"season": 0,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92dbb9d1.jpg",
"id": 23168,
"season": 0,
"likes": 0
}
],
"thumbs": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/tvthumb/wilfred-us-501cf526174fe.jpg",
"likes": 1,
"id": 19596
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/tvthumb/wilfred-us-51bfb4a105904.jpg",
"likes": 0,
"id": 30060
}
],
"characters": [],
"posters": [
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/tvposter/wilfred-us-525d893230d7c.jpg",
"likes": 1,
"id": 34584
}
],
"seasons": [
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-52403782bab55.jpg",
"id": 33752,
"season": 1,
"likes": 1
},
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-5240379335232.jpg",
"id": 33753,
"season": 2,
"likes": 1
},
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-524037bc83c7d.jpg",
"id": 33754,
"season": 3,
"likes": 1
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb0a8e60f9.jpg",
"id": 19586,
"season": 1,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb0b4bf229.jpg",
"id": 19587,
"season": 2,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb144e6a46.jpg",
"id": 19588,
"season": 0,
"likes": 0
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-51c953105ef77.jpg",
"id": 30309,
"season": 3,
"likes": 0
}
],
"banners": [
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/tvbanner/wilfred-us-52403a7185070.jpg",
"likes": 1,
"id": 33755
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/tvbanner/wilfred-us-5265193db51f7.jpg",
"likes": 0,
"id": 34716
}
],
"hdlogos": [
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-505f373be58e6.png",
"likes": 1,
"id": 21101
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-517ac360def17.png",
"likes": 1,
"id": 28248
},
{
"lang": "he",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-52402df7ed945.png",
"likes": 1,
"id": 33750
},
{
"lang": "en",
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-51f556fb4abd3.png",
"likes": 0,
"id": 31816
}
],
"tvdbid": "239761"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

View File

@ -0,0 +1,174 @@
{
"The Hunger Games": {
"tmdb_id": "70160",
"imdb_id": "tt1392170",
"movieart": [
{
"id": "1226",
"url": "http://assets.fanart.tv/fanart/movies/70160/movieart/the-hunger-games-4f6dc995edb8f.png",
"lang": "en",
"likes": "3"
},
{
"id": "1225",
"url": "http://assets.fanart.tv/fanart/movies/70160/movieart/the-hunger-games-4f6dc980b4514.png",
"lang": "en",
"likes": "1"
}
],
"movielogo": [
{
"id": "1230",
"url": "http://assets.fanart.tv/fanart/movies/70160/movielogo/the-hunger-games-4f6e0e63a9d29.png",
"lang": "en",
"likes": "2"
},
{
"id": "8020",
"url": "http://assets.fanart.tv/fanart/movies/70160/movielogo/the-hunger-games-5018f873b5188.png",
"lang": "en",
"likes": "1"
},
{
"id": "1224",
"url": "http://assets.fanart.tv/fanart/movies/70160/movielogo/the-hunger-games-4f6dc95a08de1.png",
"lang": "en",
"likes": "0"
}
],
"moviedisc": [
{
"id": "8431",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviedisc/the-hunger-games-501db4437623f.png",
"lang": "en",
"likes": "1",
"disc": "1",
"disc_type": "dvd"
},
{
"id": "9787",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviedisc/the-hunger-games-502fd6d695a60.png",
"lang": "en",
"likes": "1",
"disc": "1",
"disc_type": "bluray"
}
],
"moviethumb": [
{
"id": "10687",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviethumb/the-hunger-games-503c88b32cf66.jpg",
"lang": "en",
"likes": "0"
}
],
"hdmovielogo": [
{
"id": "13004",
"url": "http://assets.fanart.tv/fanart/movies/70160/hdmovielogo/the-hunger-games-50500118613e3.png",
"lang": "en",
"likes": "0"
}
],
"moviebackground": [
{
"id": "14043",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5057c79ad3c56.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "14044",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5057c79ad5526.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15911",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071de49311d1.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15914",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071df619b835.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15917",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e01fee856.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15918",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e0adcc57a.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15919",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e12006159.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15921",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e206aa2ac.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15922",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e2869d774.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15925",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e30069b72.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15927",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e3c4979b7.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15930",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e5b3f039b.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15931",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e6369e812.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15936",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e8749e73a.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "15937",
"url": "http://assets.fanart.tv/fanart/movies/70160/moviebackground/the-hunger-games-5071e9913bfeb.jpg",
"lang": "en",
"likes": "0"
}
],
"hdmovieclearart": [
{
"id": "14104",
"url": "http://assets.fanart.tv/fanart/movies/70160/hdmovieclearart/the-hunger-games-50582453b1375.png",
"lang": "en",
"likes": "0"
}
]
}
}

View File

@ -0,0 +1,171 @@
{
"Avenged Sevenfold": {
"mbid_id": "24e1b53c-3085-4581-8472-0b0088d2508c",
"artistbackground": [
{
"id": "3027",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/artistbackground/avenged-sevenfold-4ddd7889a0fcf.jpg",
"likes": "0"
},
{
"id": "64046",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/artistbackground/avenged-sevenfold-50c4db9a2c6e2.jpg",
"likes": "0"
},
{
"id": "64048",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/artistbackground/avenged-sevenfold-50c4dc653f004.jpg",
"likes": "0"
}
],
"albums": {
"180560ee-2d9d-33cf-8de7-cdaaba610739": {
"albumcover": [
{
"id": "3028",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/city-of-evil-4ddd79ca0beea.jpg",
"likes": "0"
}
],
"cdart": [
{
"id": "9921",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/cdart/city-of-evil-4e5f7b9f50d37.png",
"likes": "0",
"disc": "1",
"size": "1000"
}
]
},
"1c7120ae-32b6-3693-8974-599977b01601": {
"albumcover": [
{
"id": "3029",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/waking-the-fallen-4ddd79ca1b11e.jpg",
"likes": "0"
}
],
"cdart": [
{
"id": "9922",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/cdart/waking-the-fallen-4e5f7b9f5ebdf.png",
"likes": "0",
"disc": "1",
"size": "1000"
}
]
},
"94672194-7f42-3965-a489-f2f3cdc1c79e": {
"albumcover": [
{
"id": "3030",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/avenged-sevenfold-4ddd79ca1bcd6.jpg",
"likes": "0"
}
],
"cdart": [
{
"id": "9923",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/cdart/avenged-sevenfold-4e5f7b9f5fb7f.png",
"likes": "0",
"disc": "1",
"size": "1000"
}
]
},
"9d642393-0005-3e89-b3d4-35d89c2f6ad6": {
"albumcover": [
{
"id": "3031",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/sounding-the-seventh-trumpet-4ddd79ca1d05e.jpg",
"likes": "0"
}
],
"cdart": [
{
"id": "9924",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/cdart/sounding-the-seventh-trumpet-4e5f7b9f62e47.png",
"likes": "0",
"disc": "1",
"size": "1000"
}
]
},
"fe4373ed-5e89-46b3-b4c0-31433ce217df": {
"albumcover": [
{
"id": "3032",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/nightmare-4ddd79ca1dffe.jpg",
"likes": "0"
}
],
"cdart": [
{
"id": "11630",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/cdart/nightmare-4e8059a3c581c.png",
"likes": "0",
"disc": "1",
"size": "1000"
}
]
},
"41d1b72b-1eee-3319-937f-c85d6d2fcfbb": {
"albumcover": [
{
"id": "61014",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/albumcover/warmness-on-the-soul-509d2e9150bf4.jpg",
"likes": "0"
}
]
}
},
"musiclogo": [
{
"id": "5712",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/musiclogo/avenged-sevenfold-4dfc8aee78b49.png",
"likes": "0"
},
{
"id": "41835",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/musiclogo/avenged-sevenfold-4ffc75f3a7e54.png",
"likes": "0"
},
{
"id": "41836",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/musiclogo/avenged-sevenfold-4ffc75f3a8473.png",
"likes": "0"
}
],
"artistthumb": [
{
"id": "31109",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/artistthumb/avenged-sevenfold-4fb2b533bc73a.jpg",
"likes": "0"
},
{
"id": "64042",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/artistthumb/avenged-sevenfold-50c4d9279d6e9.jpg",
"likes": "0"
}
],
"hdmusiclogo": [
{
"id": "49644",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/hdmusiclogo/avenged-sevenfold-503fcebece042.png",
"likes": "0"
},
{
"id": "49645",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/hdmusiclogo/avenged-sevenfold-503fcebecf17e.png",
"likes": "0"
}
],
"musicbanner": [
{
"id": "52630",
"url": "http://assets.fanart.tv/fanart/music/24e1b53c-3085-4581-8472-0b0088d2508c/musicbanner/avenged-sevenfold-505b2346a559d.jpg",
"likes": "0"
}
]
}
}

View File

@ -0,0 +1,196 @@
{
"Wilfred (US)": {
"hdclearart": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdclearart/wilfred-us-505f94ed0ba13.png",
"lang": "en",
"id": "21112",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdclearart/wilfred-us-52403264aa3ec.png",
"lang": "he",
"id": "33751",
"likes": "1"
}
],
"seasonthumb": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-52403782bab55.jpg",
"lang": "he",
"id": "33752",
"season": "1",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-5240379335232.jpg",
"lang": "he",
"id": "33753",
"season": "2",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-524037bc83c7d.jpg",
"lang": "he",
"id": "33754",
"season": "3",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb0a8e60f9.jpg",
"lang": "en",
"id": "19586",
"season": "1",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb0b4bf229.jpg",
"lang": "en",
"id": "19587",
"season": "2",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-501bb144e6a46.jpg",
"lang": "en",
"id": "19588",
"season": "0",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/seasonthumb/wilfred-us-51c953105ef77.jpg",
"lang": "en",
"id": "30309",
"season": "3",
"likes": "0"
}
],
"tvbanner": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/tvbanner/wilfred-us-52403a7185070.jpg",
"lang": "he",
"id": "33755",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/tvbanner/wilfred-us-5265193db51f7.jpg",
"lang": "en",
"id": "34716",
"likes": "0"
}
],
"thetvdb_id": "239761",
"clearlogo": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-4e04b6495dfd3.png",
"lang": "en",
"id": "11977",
"likes": "2"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-517ac36e39f67.png",
"lang": "en",
"id": "28249",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/clearlogo/wilfred-us-51f557082cfde.png",
"lang": "en",
"id": "31817",
"likes": "0"
}
],
"tvposter": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/tvposter/wilfred-us-525d893230d7c.jpg",
"lang": "he",
"id": "34584",
"likes": "1"
}
],
"showbackground": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-5034dbd49115e.jpg",
"lang": "en",
"id": "19965",
"season": "all",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92db6973.jpg",
"lang": "en",
"id": "23166",
"season": "all",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92dbb46b.jpg",
"lang": "en",
"id": "23167",
"season": "all",
"likes": "0"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/showbackground/wilfred-us-50b0c92dbb9d1.jpg",
"lang": "en",
"id": "23168",
"season": "all",
"likes": "0"
}
],
"tvthumb": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/tvthumb/wilfred-us-501cf526174fe.jpg",
"lang": "en",
"id": "19596",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/tvthumb/wilfred-us-51bfb4a105904.jpg",
"lang": "en",
"id": "30060",
"likes": "0"
}
],
"clearart": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/clearart/wilfred-us-4e05f10e87711.png",
"lang": "en",
"id": "11987",
"likes": "2"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/clearart/wilfred-us-4e2f151d5ed62.png",
"lang": "en",
"id": "12470",
"likes": "1"
}
],
"hdtvlogo": [
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-505f373be58e6.png",
"lang": "en",
"id": "21101",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-517ac360def17.png",
"lang": "en",
"id": "28248",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-52402df7ed945.png",
"lang": "he",
"id": "33750",
"likes": "1"
},
{
"url": "http://assets.fanart.tv/fanart/tv/239761/hdtvlogo/wilfred-us-51f556fb4abd3.png",
"lang": "en",
"id": "31816",
"likes": "0"
}
]
}
}

View File

@ -0,0 +1,756 @@
{
"Dexter": {
"thetvdb_id": "79349",
"hdtvlogo": [
{
"id": "20959",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdtvlogo/dexter-50575994eb118.png",
"lang": "en",
"likes": "10"
},
{
"id": "20378",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdtvlogo/dexter-503fc2f24d9b3.png",
"lang": "en",
"likes": "5"
}
],
"hdclearart": [
{
"id": "23059",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-50af98e73b0a5.png",
"lang": "en",
"likes": "8"
},
{
"id": "24313",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-50eb4363da522.png",
"lang": "en",
"likes": "5"
},
{
"id": "20560",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-504775fd50557.png",
"lang": "en",
"likes": "4"
},
{
"id": "29495",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51aa63100548b.png",
"lang": "en",
"likes": "3"
},
{
"id": "26712",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51400b1672938.png",
"lang": "en",
"likes": "1"
},
{
"id": "29496",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51aa724f0a2ab.png",
"lang": "en",
"likes": "1"
},
{
"id": "29505",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51aab23851368.png",
"lang": "en",
"likes": "1"
},
{
"id": "29594",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51afbcdf38d5e.png",
"lang": "en",
"likes": "1"
},
{
"id": "29595",
"url": "http://assets.fanart.tv/fanart/tv/79349/hdclearart/dexter-51afbcdf3ea8e.png",
"lang": "en",
"likes": "1"
}
],
"clearlogo": [
{
"id": "20958",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearlogo/dexter-5057573260826.png",
"lang": "en",
"likes": "6"
},
{
"id": "2114",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearlogo/Dexter-79349-2.png",
"lang": "en",
"likes": "4"
},
{
"id": "14577",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearlogo/dexter-4ecdf0c030189.png",
"lang": "en",
"likes": "3"
},
{
"id": "16685",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearlogo/dexter-4f6879db58edf.png",
"lang": "ru",
"likes": "1"
}
],
"characterart": [
{
"id": "16825",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-4f76318ae4410.png",
"lang": "en",
"likes": "5"
},
{
"id": "29497",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-51aa726346bcf.png",
"lang": "en",
"likes": "3"
},
{
"id": "14981",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-4eface5cee809.png",
"lang": "en",
"likes": "1"
},
{
"id": "16996",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-4f8189d220d4b.png",
"lang": "en",
"likes": "1"
},
{
"id": "26713",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-51400b26c65de.png",
"lang": "en",
"likes": "1"
},
{
"id": "29597",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-51afbcf6002a7.png",
"lang": "en",
"likes": "1"
},
{
"id": "29598",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-51afbcf6006e6.png",
"lang": "en",
"likes": "1"
},
{
"id": "29646",
"url": "http://assets.fanart.tv/fanart/tv/79349/characterart/dexter-51b0fc45e0dc0.png",
"lang": "en",
"likes": "1"
}
],
"clearart": [
{
"id": "4980",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/D_79349 (3).png",
"lang": "en",
"likes": "4"
},
{
"id": "14579",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/dexter-4ecdf0db2adf1.png",
"lang": "en",
"likes": "3"
},
{
"id": "16682",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/dexter-4f68753540f2d.png",
"lang": "ru",
"likes": "1"
},
{
"id": "4982",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/D_79349.png",
"lang": "en",
"likes": "0"
},
{
"id": "4983",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/D_79349 (1).png",
"lang": "en",
"likes": "0"
},
{
"id": "4984",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/D_79349 (0).png",
"lang": "en",
"likes": "0"
},
{
"id": "14578",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/dexter-4ecdf0cf3fb38.png",
"lang": "en",
"likes": "0"
},
{
"id": "17196",
"url": "http://assets.fanart.tv/fanart/tv/79349/clearart/dexter-4f8af83f3bde7.png",
"lang": "en",
"likes": "0"
}
],
"showbackground": [
{
"id": "18467",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fc683691dea7.jpg",
"lang": "en",
"likes": "4",
"season": "1"
},
{
"id": "18950",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fdf608e2df53.jpg",
"lang": "en",
"likes": "2",
"season": "3"
},
{
"id": "18466",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fc6830dc2ccc.jpg",
"lang": "en",
"likes": "1",
"season": "4"
},
{
"id": "18468",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fc683a5ab451.jpg",
"lang": "en",
"likes": "1",
"season": "6"
},
{
"id": "21524",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bdd9c35771.jpg",
"lang": "en",
"likes": "1",
"season": "all"
},
{
"id": "21526",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bddc9f04cb.jpg",
"lang": "en",
"likes": "1",
"season": ""
},
{
"id": "21530",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bde2654668.jpg",
"lang": "en",
"likes": "1",
"season": "all"
},
{
"id": "24058",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50def777ea9c8.jpg",
"lang": "en",
"likes": "1",
"season": "all"
},
{
"id": "18515",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fc8eab16803c.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "18947",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fdf5e107be0d.jpg",
"lang": "en",
"likes": "0",
"season": "5"
},
{
"id": "18949",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fdf601385517.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "18952",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-4fdf6386ce1c1.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "21525",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bddb3bd3f4.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "21527",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bdddc3f476.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "21529",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-506bde113406e.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24046",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50de1f84e736f.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24048",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50de1f84e7d57.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24049",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50de21ac3ae25.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24054",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50def777e84d0.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24055",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50def777e8dbc.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24056",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-50def777e9762.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "24986",
"url": "http://assets.fanart.tv/fanart/tv/79349/showbackground/dexter-5101fa187c857.jpg",
"lang": "en",
"likes": "0",
"season": "all"
}
],
"seasonthumb": [
{
"id": "18986",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21b7708ebe.jpg",
"lang": "en",
"likes": "3",
"season": "6"
},
{
"id": "5002",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (6).jpg",
"lang": "en",
"likes": "1",
"season": "3"
},
{
"id": "5003",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (5).jpg",
"lang": "en",
"likes": "1",
"season": "1"
},
{
"id": "17802",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa981a7251d7.jpg",
"lang": "en",
"likes": "1",
"season": "5"
},
{
"id": "17823",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4faab0bccbfb6.jpg",
"lang": "en",
"likes": "1",
"season": "6"
},
{
"id": "18980",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21a6955116.jpg",
"lang": "en",
"likes": "1",
"season": "1"
},
{
"id": "18982",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21b0767edb.jpg",
"lang": "en",
"likes": "1",
"season": "2"
},
{
"id": "18983",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21b292d661.jpg",
"lang": "en",
"likes": "1",
"season": "3"
},
{
"id": "18984",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21b42d983d.jpg",
"lang": "en",
"likes": "1",
"season": "4"
},
{
"id": "18985",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fe21b5847d7b.jpg",
"lang": "en",
"likes": "1",
"season": "5"
},
{
"id": "21883",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-5071800d37e80.jpg",
"lang": "en",
"likes": "1",
"season": "7"
},
{
"id": "4989",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (9).jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "4990",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (19).jpg",
"lang": "en",
"likes": "0",
"season": "4"
},
{
"id": "4991",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (18).jpg",
"lang": "en",
"likes": "0",
"season": "4"
},
{
"id": "4992",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (17).jpg",
"lang": "en",
"likes": "0",
"season": "3"
},
{
"id": "4993",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (16).jpg",
"lang": "en",
"likes": "0",
"season": "2"
},
{
"id": "4994",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (15).jpg",
"lang": "en",
"likes": "0",
"season": "1"
},
{
"id": "4995",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (14).jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "4996",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (13).jpg",
"lang": "en",
"likes": "0",
"season": "4"
},
{
"id": "4997",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (12).jpg",
"lang": "en",
"likes": "0",
"season": "3"
},
{
"id": "4998",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (11).jpg",
"lang": "en",
"likes": "0",
"season": "2"
},
{
"id": "4999",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (10).jpg",
"lang": "en",
"likes": "0",
"season": "1"
},
{
"id": "5000",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (8).jpg",
"lang": "en",
"likes": "0",
"season": "2"
},
{
"id": "5001",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (7).jpg",
"lang": "en",
"likes": "0",
"season": "4"
},
{
"id": "5004",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter.jpg",
"lang": "en",
"likes": "0",
"season": "all"
},
{
"id": "5005",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (4).jpg",
"lang": "en",
"likes": "0",
"season": "5"
},
{
"id": "5006",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (3).jpg",
"lang": "en",
"likes": "0",
"season": "4"
},
{
"id": "5007",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (2).jpg",
"lang": "en",
"likes": "0",
"season": "3"
},
{
"id": "5008",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (1).jpg",
"lang": "en",
"likes": "0",
"season": "2"
},
{
"id": "5009",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/Dexter (0).jpg",
"lang": "en",
"likes": "0",
"season": "1"
},
{
"id": "17803",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa981a7258fb.jpg",
"lang": "en",
"likes": "0",
"season": "5"
},
{
"id": "17804",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa981a725c14.jpg",
"lang": "en",
"likes": "0",
"season": "5"
},
{
"id": "17805",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa981c6607e4.jpg",
"lang": "en",
"likes": "0",
"season": "0"
},
{
"id": "17807",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa98ac2b811d.jpg",
"lang": "en",
"likes": "0",
"season": "6"
},
{
"id": "17808",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa98ac2b87ab.jpg",
"lang": "en",
"likes": "0",
"season": "6"
},
{
"id": "17810",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fa994697afa3.jpg",
"lang": "en",
"likes": "0",
"season": "6"
},
{
"id": "18514",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-4fc8e9fa79bf8.jpg",
"lang": "en",
"likes": "0",
"season": "7"
},
{
"id": "31022",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-51dc720661cb7.jpg",
"lang": "en",
"likes": "0",
"season": "8"
},
{
"id": "31023",
"url": "http://assets.fanart.tv/fanart/tv/79349/seasonthumb/dexter-51dc72a19a0bb.jpg",
"lang": "en",
"likes": "0",
"season": "8"
}
],
"tvthumb": [
{
"id": "5012",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (10).jpg",
"lang": "en",
"likes": "2"
},
{
"id": "5023",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (0).jpg",
"lang": "en",
"likes": "2"
},
{
"id": "14580",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/dexter-4ecdf5027a53c.jpg",
"lang": "en",
"likes": "2"
},
{
"id": "5013",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (9).jpg",
"lang": "en",
"likes": "1"
},
{
"id": "5016",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (6).jpg",
"lang": "en",
"likes": "1"
},
{
"id": "5020",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (2).jpg",
"lang": "en",
"likes": "1"
},
{
"id": "29341",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/dexter-51a338d376b4a.jpg",
"lang": "de",
"likes": "1"
},
{
"id": "31722",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/dexter-51f27112a2a89.jpg",
"lang": "en",
"likes": "1"
},
{
"id": "5010",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (12).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5011",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (11).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5014",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (8).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5015",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (7).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5017",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (5).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5018",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (4).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5019",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (3).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5021",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349.jpg",
"lang": "en",
"likes": "0"
},
{
"id": "5022",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/D_79349 (1).jpg",
"lang": "en",
"likes": "0"
},
{
"id": "14277",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvthumb/dexter-4ead4375923fd.jpg",
"lang": "en",
"likes": "0"
}
],
"tvbanner": [
{
"id": "30062",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvbanner/dexter-51bfc857c84fd.jpg",
"lang": "en",
"likes": "1"
},
{
"id": "30063",
"url": "http://assets.fanart.tv/fanart/tv/79349/tvbanner/dexter-51bfc89667267.jpg",
"lang": "en",
"likes": "1"
}
]
}
}

View File

@ -0,0 +1,23 @@
from unittest import TestCase
from fanart.core import Request
from fanart.errors import RequestFanartError, ResponseFanartError
from httpretty import httprettified, HTTPretty
class RequestTestCase(TestCase):
def test_valitate_error(self):
self.assertRaises(RequestFanartError, Request, 'key', 'id', 'sport')
@httprettified
def test_response_error(self):
request = Request('apikey', 'objid', 'series')
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/series/apikey/objid/JSON/all/1/2',
body='Please specify a valid API key',
)
try:
request.response()
except ResponseFanartError as e:
self.assertEqual(repr(e), "ResponseFanartError('No JSON object could be decoded',)")
self.assertEqual(str(e), 'No JSON object could be decoded')

View File

@ -0,0 +1,49 @@
from unittest import TestCase
from fanart.immutable import Immutable
class TestMutable(object):
def __init__(self, spam, ham, eggs):
self.spam = spam
self.ham = ham
self.eggs = eggs
@Immutable.mutablemethod
def anyway(self):
self.spam = self.ham + self.eggs
class TestImmutable(TestMutable, Immutable):
@Immutable.mutablemethod
def __init__(self, *args, **kwargs):
super(TestImmutable, self).__init__(*args, **kwargs)
class ImmutableTestCase(TestCase):
def setUp(self):
self.instance = TestImmutable('spam', 'ham', 'eggs')
def test_set_raises(self):
self.assertRaises(TypeError, self.instance.__setattr__, 'spam', 'ham')
def test_set(self):
self.instance._mutable = True
self.instance.spam = 'ham'
self.assertEqual(self.instance.spam, 'ham')
def test_del_raises(self):
self.assertRaises(TypeError, self.instance.__delattr__, 'spam')
def test_del(self):
self.instance._mutable = True
del self.instance.spam
self.assertRaises(AttributeError, self.instance.__getattribute__, 'spam')
def test_equal(self):
new_instance = TestImmutable('spam', 'ham', 'eggs')
self.assertEqual(self.instance, new_instance)
def test_mutable_dec(self):
instance = TestMutable('spam', 'ham', 'eggs')
instance.anyway()
self.assertEqual(instance.spam, 'hameggs')

View File

@ -0,0 +1,27 @@
from unittest import TestCase
import os
from fanart.items import LeafItem
from httpretty import httprettified, HTTPretty
from fanart.tests import LOCALDIR
class LeafItemTestCase(TestCase):
def setUp(self):
self.leaf = LeafItem(id=11977, likes=2, url='http://test.tv/50x50.txt')
def test_str(self):
self.assertEqual(str(self.leaf), 'http://test.tv/50x50.txt')
@httprettified
def test_content(self):
with open(os.path.join(LOCALDIR, 'response/50x50.png')) as fp:
body = fp.read()
HTTPretty.register_uri(
HTTPretty.GET,
'http://test.tv/50x50.txt',
body=body
)
self.assertEqual(self.leaf.content(), body)
self.assertEqual(len(HTTPretty.latest_requests), 1)
self.assertEqual(self.leaf.content(), body) # Cached
self.assertEqual(len(HTTPretty.latest_requests), 1)

View File

@ -0,0 +1,21 @@
import os
import unittest
from httpretty import HTTPretty, httprettified
from fanart.movie import *
from fanart.tests import LOCALDIR
os.environ['FANART_APIKEY'] = 'e3c7f0d0beeaf45b3a0dd3b9dd8a3338'
class TvItemTestCase(unittest.TestCase):
@httprettified
def test_get(self):
with open(os.path.join(LOCALDIR, 'response/movie_thg.json')) as fp:
body = fp.read()
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/movie/e3c7f0d0beeaf45b3a0dd3b9dd8a3338/70160/JSON/all/1/2',
body=body
)
hunger_games = Movie.get(id=70160)
self.assertEqual(hunger_games.tmdbid, '70160')
self.assertEqual(hunger_games, eval(repr(hunger_games)))

View File

@ -0,0 +1,22 @@
import os
import unittest
from httpretty import HTTPretty, httprettified
from fanart.music import *
from fanart.tests import LOCALDIR
os.environ['FANART_APIKEY'] = 'e3c7f0d0beeaf45b3a0dd3b9dd8a3338'
class ArtistItemTestCase(unittest.TestCase):
@httprettified
def test_get(self):
with open(os.path.join(LOCALDIR, 'response/music_a7f.json')) as fp:
body = fp.read()
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/artist/e3c7f0d0beeaf45b3a0dd3b9dd8a3338/24e1b53c-3085-4581-8472-0b0088d2508c/JSON/all/1/2',
body=body
)
a7f = Artist.get(id='24e1b53c-3085-4581-8472-0b0088d2508c')
self.assertEqual(a7f.mbid, '24e1b53c-3085-4581-8472-0b0088d2508c')
self.assertEqual(a7f, eval(repr(a7f)))
self.assertEqual(len(a7f.thumbs), 2)

View File

@ -0,0 +1,46 @@
import json
from fanart.errors import ResponseFanartError
import os
import unittest
from httpretty import HTTPretty, httprettified
from fanart.tv import *
from fanart.tests import LOCALDIR
os.environ['FANART_APIKEY'] = 'e3c7f0d0beeaf45b3a0dd3b9dd8a3338'
class TvItemTestCase(unittest.TestCase):
@httprettified
def test_get_wilfred(self):
with open(os.path.join(LOCALDIR, 'response/tv_239761.json')) as fp:
body = fp.read()
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/series/e3c7f0d0beeaf45b3a0dd3b9dd8a3338/239761/JSON/all/1/2',
body=body
)
wilfred = TvShow.get(id=239761)
self.assertEqual(wilfred.tvdbid, '239761')
with open(os.path.join(LOCALDIR, 'json/wilfred.json')) as fp:
self.assertEqual(json.loads(wilfred.json()), json.load(fp))
@httprettified
def test_get_dexter(self):
with open(os.path.join(LOCALDIR, 'response/tv_79349.json')) as fp:
body = fp.read()
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/series/e3c7f0d0beeaf45b3a0dd3b9dd8a3338/79349/JSON/all/1/2',
body=body
)
dexter = TvShow.get(id=79349)
self.assertEqual(dexter.tvdbid, '79349')
self.assertEqual(dexter, eval(repr(dexter)))
@httprettified
def test_get_null(self):
HTTPretty.register_uri(
HTTPretty.GET,
'http://api.fanart.tv/webservice/series/e3c7f0d0beeaf45b3a0dd3b9dd8a3338/79349/JSON/all/1/2',
body='null'
)
self.assertRaises(ResponseFanartError, TvShow.get, id=79349)

108
lib/fanart/tv.py Normal file
View File

@ -0,0 +1,108 @@
import fanart
from fanart.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),
)

View File

@ -472,6 +472,7 @@ CALENDAR_UNPROTECTED = False
TMDB_API_KEY = 'edc5f123313769de83a71e157758030b'
TRAKT_API_KEY = 'abd806c54516240c76e4ebc9c5ccf394'
FANART_API_KEY = '9b3afaf26f6241bdb57d6cc6bd798da7'
__INITIALIZED__ = False

View File

@ -35,7 +35,6 @@ from sickbeard.show_name_helpers import allPossibleShowNames
from lib.tmdb_api.tmdb_api import TMDB
class GenericMetadata():
"""
Base class for all metadata providers. Default behavior is meant to mostly
@ -774,19 +773,27 @@ class GenericMetadata():
if image_type == 'poster_thumb':
if getattr(indexer_show_obj, 'poster', None) is not None:
image_url = re.sub('posters', '_cache/posters', indexer_show_obj['poster'])
if not image_url:
# Try and get images from Fanart.TV
image_url = self._retrieve_show_images_from_fanart(show_obj, image_type)
if not image_url:
# Try and get images from TMDB
image_url = self._retrieve_show_images_from_tmdb(show_obj, image_type)
elif image_type == 'banner_thumb':
if getattr(indexer_show_obj, 'banner', None) is not None:
image_url = re.sub('graphical', '_cache/graphical', indexer_show_obj['banner'])
if not image_url:
# Try and get images from Fanart.TV
image_url = self._retrieve_show_images_from_fanart(show_obj, image_type)
else:
if getattr(indexer_show_obj, image_type, None) is not None:
image_url = indexer_show_obj[image_type]
# Try and get posters and fanart from TMDB
if image_url is None:
if image_type in ('poster', 'poster_thumb'):
image_url = self._retrieve_show_images_from_tmdb(show_obj, poster=True)
elif image_type == 'fanart':
image_url = self._retrieve_show_images_from_tmdb(show_obj, backdrop=True)
if not image_url:
# Try and get images from Fanart.TV
image_url = self._retrieve_show_images_from_fanart(show_obj, image_type)
if not image_url:
# Try and get images from TMDB
image_url = self._retrieve_show_images_from_tmdb(show_obj, image_type)
if image_url:
image_data = metadata_helpers.getShowImage(image_url, which)
@ -961,7 +968,13 @@ class GenericMetadata():
return (indexer_id, name, indexer)
def _retrieve_show_images_from_tmdb(self, show, backdrop=False, poster=False):
def _retrieve_show_images_from_tmdb(self, show, type):
types = {'poster': 'poster_path',
'banner': None,
'fanart': 'backdrop_path',
'poster_thumb': 'poster_path',
'banner_thumb': None}
# get TMDB configuration info
tmdb = TMDB(sickbeard.TMDB_API_KEY)
config = tmdb.Configuration()
@ -977,14 +990,39 @@ class GenericMetadata():
try:
search = tmdb.Search()
for show_name in set(allPossibleShowNames(show)):
for result in search.collection({'query': show_name})['results'] + search.tv({'query': show_name})[
'results']:
if backdrop and result['backdrop_path']:
return "{0}{1}{2}".format(base_url, max_size, result['backdrop_path'])
elif poster and result['poster_path']:
return "{0}{1}{2}".format(base_url, max_size, result['poster_path'])
for result in search.collection({'query': show_name})['results'] + search.tv({'query': show_name})['results']:
if result[types[type]]:
return "{0}{1}{2}".format(base_url, max_size, result[types[type]])
except Exception, e:
except Exception as e:
pass
logger.log(u"Could not find any posters or background for " + show.name, logger.DEBUG)
logger.log(u"Could not find any images on TMDB for " + show.name, logger.DEBUG)
def _retrieve_show_images_from_fanart(self, show, type):
from fanart.core import Request
import fanart
types = {'poster': fanart.TYPE.TV.POSTER,
'banner': fanart.TYPE.TV.BANNER,
'fanart': fanart.TYPE.TV.ART,
'poster_thumb': fanart.TYPE.TV.THUMB,
'banner_thumb': fanart.TYPE.TV.BANNER}
try:
indexerid = helpers.mapIndexersToShow(show)[1]
request = Request(
apikey=sickbeard.FANART_API_KEY,
id=indexerid,
ws=fanart.WS.TV,
type=types[type],
sort=fanart.SORT.POPULAR,
limit=fanart.LIMIT.ONE,
)
resp = request.response()
return resp.values()[-1].values()[-2][-1]['url']
except Exception as e:
pass
logger.log(u"Could not find any images on Fanart.tv for " + show.name, logger.DEBUG)