261 lines
9.2 KiB
Python
261 lines
9.2 KiB
Python
import os
|
|
import sys
|
|
import socket
|
|
import urllib2
|
|
import urlparse
|
|
import xbmc
|
|
import xbmcgui
|
|
import xbmcplugin
|
|
from quasar.logger import log
|
|
from quasar.config import QUASARD_HOST
|
|
from quasar.addon import ADDON, ADDON_ID, ADDON_PATH
|
|
from quasar.util import notify, getLocalizedString, getLocalizedLabel, system_information
|
|
|
|
try:
|
|
import simplejson as json
|
|
except ImportError:
|
|
import json
|
|
|
|
|
|
HANDLE = int(sys.argv[1])
|
|
|
|
|
|
class InfoLabels(dict):
|
|
def __init__(self, *args, **kwargs):
|
|
self.update(*args, **kwargs)
|
|
|
|
def __getitem__(self, key):
|
|
return dict.get(self, key.lower(), "")
|
|
|
|
def __setitem__(self, key, val):
|
|
dict.__setitem__(self, key.lower(), val)
|
|
|
|
def update(self, *args, **kwargs):
|
|
for k, v in dict(*args, **kwargs).iteritems():
|
|
self[k] = v
|
|
|
|
|
|
class closing(object):
|
|
def __init__(self, thing):
|
|
self.thing = thing
|
|
|
|
def __enter__(self):
|
|
return self.thing
|
|
|
|
def __exit__(self, *exc_info):
|
|
self.thing.close()
|
|
|
|
|
|
class NoRedirectHandler(urllib2.HTTPRedirectHandler):
|
|
def http_error_302(self, req, fp, code, msg, headers):
|
|
import urllib
|
|
infourl = urllib.addinfourl(fp, headers, headers["Location"])
|
|
infourl.status = code
|
|
infourl.code = code
|
|
return infourl
|
|
http_error_300 = http_error_302
|
|
http_error_301 = http_error_302
|
|
http_error_303 = http_error_302
|
|
http_error_307 = http_error_302
|
|
|
|
|
|
def getInfoLabels():
|
|
id_list = [int(s) for s in sys.argv[0].split("/") if s.isdigit()]
|
|
tmdb_id = id_list[0] if id_list else None
|
|
|
|
if not tmdb_id:
|
|
parsed_url = urlparse.urlparse(sys.argv[0] + sys.argv[2])
|
|
query = urlparse.parse_qs(parsed_url.query)
|
|
log.debug("Parsed URL: %s, Query: %s", repr(parsed_url), repr(query))
|
|
if 'tmdb' in query and 'show' not in query:
|
|
tmdb_id = query['tmdb'][0]
|
|
url = "%s/movie/%s/infolabels" % (QUASARD_HOST, tmdb_id)
|
|
elif 'show' in query:
|
|
tmdb_id = query['show'][0]
|
|
if 'season' in query and 'episode' in query:
|
|
url = "%s/show/%s/season/%s/episode/%s/infolabels" % (QUASARD_HOST, tmdb_id, query['season'][0], query['episode'][0])
|
|
else:
|
|
url = "%s/show/%s/infolabels" % (QUASARD_HOST, tmdb_id)
|
|
else:
|
|
url = "%s/infolabels" % (QUASARD_HOST)
|
|
elif 'movie' in sys.argv[0]:
|
|
url = "%s/movie/%s/infolabels" % (QUASARD_HOST, tmdb_id)
|
|
elif ('episode' in sys.argv[0] or 'show' in sys.argv[0]) and len(id_list) > 2:
|
|
url = "%s/show/%s/season/%s/episode/%s/infolabels" % (QUASARD_HOST, tmdb_id, id_list[1], id_list[2])
|
|
elif 'show' in sys.argv[0] and len(id_list) == 2:
|
|
url = "%s/show/%s/season/%s/episode/%s/infolabels" % (QUASARD_HOST, tmdb_id, id_list[1], 1)
|
|
else:
|
|
url = "%s/infolabels" % (QUASARD_HOST)
|
|
|
|
log.debug("Resolving TMDB item by calling %s for %s" % (url, repr(sys.argv)))
|
|
|
|
try:
|
|
with closing(urllib2.urlopen(url)) as response:
|
|
resolved = json.loads(response.read())
|
|
if not resolved:
|
|
return {}
|
|
|
|
if 'info' in resolved and resolved['info']:
|
|
resolved.update(resolved['info'])
|
|
|
|
if 'art' in resolved and resolved['art']:
|
|
resolved['artbanner'] = ''
|
|
for k, v in resolved['art'].items():
|
|
resolved['art' + k] = v
|
|
|
|
if 'info' in resolved:
|
|
del resolved['info']
|
|
if 'art' in resolved:
|
|
del resolved['art']
|
|
if 'stream_info' in resolved:
|
|
del resolved['stream_info']
|
|
|
|
if 'dbtype' not in resolved:
|
|
resolved['dbtype'] = 'video'
|
|
if 'mediatype' not in resolved or resolved['mediatype'] == '':
|
|
resolved['Mediatype'] = resolved['dbtype']
|
|
|
|
return resolved
|
|
except:
|
|
log.debug("Could not resolve TMDB item: %s" % tmdb_id)
|
|
return {}
|
|
|
|
|
|
def _json(url):
|
|
with closing(urllib2.urlopen(url)) as response:
|
|
if response.code >= 300 and response.code <= 307:
|
|
# Pause currently playing Quasar file to avoid doubling requests
|
|
if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player().getPlayingFile():
|
|
xbmc.Player().pause()
|
|
_infoLabels = InfoLabels(getInfoLabels())
|
|
|
|
item = xbmcgui.ListItem(
|
|
path=response.geturl(),
|
|
label=_infoLabels["label"],
|
|
label2=_infoLabels["label2"],
|
|
thumbnailImage=_infoLabels["thumbnail"])
|
|
|
|
item.setArt({
|
|
"poster": _infoLabels["artposter"],
|
|
"banner": _infoLabels["artbanner"],
|
|
"fanart": _infoLabels["artfanart"]
|
|
})
|
|
|
|
item.setInfo(type='Video', infoLabels=_infoLabels)
|
|
xbmcplugin.setResolvedUrl(HANDLE, True, item)
|
|
return
|
|
|
|
payload = response.read()
|
|
|
|
try:
|
|
if payload:
|
|
return json.loads(payload)
|
|
except:
|
|
raise Exception(payload)
|
|
|
|
|
|
def run(url_suffix=""):
|
|
if not os.path.exists(os.path.join(ADDON_PATH, ".firstrun")):
|
|
notify(getLocalizedString(30101))
|
|
system_information()
|
|
return
|
|
|
|
donatePath = os.path.join(ADDON_PATH, ".donate")
|
|
if not os.path.exists(donatePath):
|
|
with open(donatePath, "w"):
|
|
os.utime(donatePath, None)
|
|
dialog = xbmcgui.Dialog()
|
|
dialog.ok("Quasar", getLocalizedString(30141))
|
|
|
|
socket.setdefaulttimeout(int(ADDON.getSetting("buffer_timeout")))
|
|
urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))
|
|
|
|
# Pause currently playing Quasar file to avoid doubling requests
|
|
if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player().getPlayingFile():
|
|
xbmc.Player().pause()
|
|
|
|
url = sys.argv[0].replace("plugin://%s" % ADDON_ID, QUASARD_HOST + url_suffix) + sys.argv[2]
|
|
log.debug("Requesting %s from %s" % (url, repr(sys.argv)))
|
|
|
|
try:
|
|
data = _json(url)
|
|
except urllib2.URLError as e:
|
|
if 'Connection refused' in e.reason:
|
|
notify(getLocalizedString(30116), time=7000)
|
|
else:
|
|
import traceback
|
|
map(log.error, traceback.format_exc().split("\n"))
|
|
notify(e.reason, time=7000)
|
|
return
|
|
except Exception as e:
|
|
import traceback
|
|
map(log.error, traceback.format_exc().split("\n"))
|
|
try:
|
|
msg = unicode(e)
|
|
except:
|
|
try:
|
|
msg = str(e)
|
|
except:
|
|
msg = repr(e)
|
|
notify(getLocalizedLabel(msg), time=7000)
|
|
return
|
|
|
|
if not data:
|
|
return
|
|
|
|
if data["content_type"]:
|
|
content_type = data["content_type"]
|
|
if data["content_type"].startswith("menus"):
|
|
content_type = data["content_type"].split("_")[1]
|
|
|
|
xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
|
|
if content_type != "tvshows":
|
|
xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
|
|
xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
|
|
xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
|
|
xbmcplugin.setContent(HANDLE, content_type)
|
|
|
|
listitems = range(len(data["items"]))
|
|
for i, item in enumerate(data["items"]):
|
|
# Translate labels
|
|
if item["label"][0:8] == "LOCALIZE":
|
|
item["label"] = unicode(getLocalizedLabel(item["label"]), 'utf-8')
|
|
if item["label2"][0:8] == "LOCALIZE":
|
|
item["label2"] = getLocalizedLabel(item["label2"])
|
|
|
|
listItem = xbmcgui.ListItem(label=item["label"], label2=item["label2"], iconImage=item["icon"], thumbnailImage=item["thumbnail"])
|
|
if item.get("info"):
|
|
listItem.setInfo("video", item["info"])
|
|
if item.get("stream_info"):
|
|
for type_, values in item["stream_info"].items():
|
|
listItem.addStreamInfo(type_, values)
|
|
if item.get("art"):
|
|
listItem.setArt(item["art"])
|
|
elif ADDON.getSetting('default_fanart') == 'true' and item["label"] != unicode(getLocalizedString(30218), 'utf-8'):
|
|
fanart = os.path.join(ADDON_PATH, "fanart.jpg")
|
|
listItem.setArt({'fanart': fanart})
|
|
if item.get("context_menu"):
|
|
# Translate context menus
|
|
for m, menu in enumerate(item["context_menu"]):
|
|
if menu[0][0:8] == "LOCALIZE":
|
|
menu[0] = getLocalizedLabel(menu[0])
|
|
listItem.addContextMenuItems(item["context_menu"])
|
|
listItem.setProperty("isPlayable", item["is_playable"] and "true" or "false")
|
|
if item.get("properties"):
|
|
for k, v in item["properties"].items():
|
|
listItem.setProperty(k, v)
|
|
listitems[i] = (item["path"], listItem, not item["is_playable"])
|
|
|
|
xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems))
|
|
|
|
# Set ViewMode
|
|
if data["content_type"]:
|
|
viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"])
|
|
if viewMode:
|
|
try:
|
|
xbmc.executebuiltin('Container.SetViewMode(%s)' % viewMode)
|
|
except Exception as e:
|
|
log.warning("Unable to SetViewMode(%s): %s" % (viewMode, repr(e)))
|
|
|
|
xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)
|