Files
DevOps/Kodi/Lenovo/addons/script.embuary.info/resources/lib/main.py

563 lines
18 KiB
Python

#!/usr/bin/python
# coding: utf-8
########################
import sys
import xbmc
import xbmcgui
from resources.lib.helper import *
from resources.lib.tmdb import *
from resources.lib.person import *
from resources.lib.video import *
from resources.lib.season import *
from resources.lib.localdb import *
########################
class TheMovieDB(object):
def __init__(self,call,params):
self.monitor = xbmc.Monitor()
self.window_stack = []
self.dialog_cache = {}
self.call = call
self.tmdb_id = params.get('tmdb_id')
self.season = params.get('season')
self.query = remove_quotes(params.get('query'))
self.query_year = params.get('year')
self.exact_search = True if params.get('exact') == 'true' else False
self.external_id = params.get('external_id')
self.dbid = params.get('dbid')
if self.call == 'tv':
self.dbtype = 'tvshow'
elif self.call == 'movie':
self.dbtype = 'movie'
winprop('script.embuary.info-language_code', DEFAULT_LANGUAGE)
winprop('script.embuary.info-country_code', COUNTRY_CODE)
busydialog()
if self.dbid and self.dbtype:
self.tmdb_id = self.find_id(method='dbid')
elif self.external_id:
self.tmdb_id = self.find_id(method='external_id')
elif self.query:
self.tmdb_id = self.find_id(method='query')
if self.tmdb_id:
self.call_params = {}
local_media = get_local_media()
self.call_params['local_shows'] = local_media['shows']
self.call_params['local_movies'] = local_media['movies']
self.entry_point()
busydialog(close=True)
''' Search for tmdb_id based one a query string or external ID (IMDb or TVDb)
'''
def find_id(self,method):
if method == 'dbid':
method_details = 'VideoLibrary.Get%sDetails' % self.dbtype
param = '%sid' % self.dbtype
key_details = '%sdetails' % self.dbtype
dbinfo = json_call(method_details,
properties=['uniqueid', 'year', 'title'],
params={param: int(self.dbid)}
)
try:
dbinfo = dbinfo['result'][key_details]
except KeyError:
return
uniqueid = dbinfo.get('uniqueid', {})
result = None
for item in uniqueid:
if uniqueid[item].startswith('tt'):
result = tmdb_find(self.call, uniqueid[item])
break
elif self.dbtype == 'tvshow' and item.lower() == 'tvdb' and uniqueid[item]:
result = tmdb_find(self.call, uniqueid[item])
break
if not result:
self.query = dbinfo.get('title')
self.query_year = dbinfo.get('year', '')
tmdb_id = self.find_id(method='query')
return tmdb_id
elif method == 'external_id':
result = tmdb_find(self.call, self.external_id)
if not result and self.query:
self.find_id(method='query')
elif method == 'query':
if ' / ' in self.query:
query_values = self.query.split(' / ')
position = tmdb_select_dialog_small(query_values)
if position < 0:
return ''
else:
self.query = query_values[position]
result = tmdb_search(self.call, self.query, self.query_year)
if self.exact_search:
exact_results = []
for item in result:
title = item.get('title') or item.get('name') or ''
original_title = item.get('original_title') or item.get('original_name') or ''
if title.lower() == self.query.lower() or original_title.lower() == self.query.lower():
if self.query_year:
premiered = item.get('first_air_date', '') if self.call == 'tv' else item.get('release_date', '')
if self.query_year == premiered[:-6]:
exact_results.append(item)
else:
exact_results.append(item)
if exact_results:
result = exact_results
else:
return ''
try:
if len(result) > 1:
position = tmdb_select_dialog(result, self.call)
if position < 0:
raise Exception
else:
position = 0
tmdb_id = result[position]['id']
except Exception:
return ''
return tmdb_id
''' Collect all data by the tmdb_id and build the dialogs.
'''
def entry_point(self):
self.call_params['call'] = self.call
self.call_params['tmdb_id'] = self.tmdb_id
self.call_params['season'] = self.season
self.request = self.call + str(self.tmdb_id)
busydialog()
if self.call == 'person':
dialog = self.fetch_person()
elif self.call == 'tv' and self.season:
dialog = self.fetch_season()
elif self.call == 'movie' or self.call == 'tv':
dialog = self.fetch_video()
busydialog(close=True)
''' Open next dialog if information has been found. If not open the previous dialog again.
'''
if dialog:
self.dialog_cache[self.request] = dialog
self.dialog_manager(dialog)
elif self.window_stack:
self.dialog_history()
else:
self.quit()
def fetch_person(self):
data = TMDBPersons(self.call_params)
if not data['person']:
return
dialog = DialogPerson('script-embuary-person.xml', ADDON_PATH, 'default', '1080i',
person=data['person'],
movies=data['movies'],
tvshows=data['tvshows'],
combined=data['combined'],
images=data['images'],
tmdb_id=self.tmdb_id
)
return dialog
def fetch_video(self):
data = TMDBVideos(self.call_params)
if not data['details']:
return
dialog = DialogVideo('script-embuary-video.xml', ADDON_PATH, 'default', '1080i',
details=data['details'],
cast=data['cast'],
crew=data['crew'],
similar=data['similar'],
youtube=data['youtube'],
backdrops=data['backdrops'],
posters=data['posters'],
collection=data['collection'],
seasons=data['seasons'],
tmdb_id=self.tmdb_id
)
return dialog
def fetch_season(self):
data = TMDBSeasons(self.call_params)
if not data['details']:
return
dialog = DialogSeason('script-embuary-video.xml', ADDON_PATH, 'default', '1080i',
details=data['details'],
cast=data['cast'],
gueststars=data['gueststars'],
posters=data['posters'],
tmdb_id=self.tmdb_id
)
return dialog
''' Dialog handler. Creates the window history, reopens dialogs from a stack
or cache and is responsible for keeping the script alive.
'''
def dialog_manager(self,dialog):
dialog.doModal()
try:
next_id = dialog['id']
next_call = dialog['call']
next_season = dialog['season']
if next_call == 'youtube':
while condition('Player.HasMedia | Window.IsVisible(busydialog) | Window.IsVisible(busydialognocancel) | Window.IsVisible(okdialog)') and not self.monitor.abortRequested():
self.monitor.waitForAbort(1)
# reopen dialog after playback ended
self.dialog_manager(dialog)
if next_call == 'back':
self.dialog_history()
if next_call == 'close':
raise Exception
if not next_id or not next_call:
raise Exception
self.window_stack.append(dialog)
self.tmdb_id = next_id
self.call = next_call
self.season = next_season
self.request = next_call + str(next_id) + str(next_season)
if self.dialog_cache.get(self.request):
dialog = self.dialog_cache[self.request]
self.dialog_manager(dialog)
else:
self.entry_point()
except Exception:
self.quit()
def dialog_history(self):
if self.window_stack:
dialog = self.window_stack.pop()
self.dialog_manager(dialog)
else:
self.quit()
def quit(self):
del self.call_params
del self.window_stack
del self.dialog_cache
quit()
''' Person dialog
'''
class DialogPerson(xbmcgui.WindowXMLDialog):
def __init__(self,*args,**kwargs):
self.first_load = True
self.action = {}
self.tmdb_id = kwargs['tmdb_id']
self.person = kwargs['person']
self.movies = kwargs['movies']
self.tvshows = kwargs['tvshows']
self.combined = kwargs['combined']
self.images = kwargs['images']
def __getitem__(self,key):
return self.action[key]
def __setitem__(self,key,value):
self.action[key] = value
def onInit(self):
execute('ClearProperty(script.embuary.info-nextcall,home)')
if self.first_load:
self.add_items()
def add_items(self):
self.first_load = False
index = 10051
li = [self.person, self.movies, self.tvshows, self.images, self.combined]
for items in li:
try:
clist = self.getControl(index)
clist.addItems(items)
except RuntimeError as error:
log('Control with id %s cannot be filled. Error --> %s' % (str(index), error), DEBUG)
pass
index += 1
def onAction(self,action):
if action.getId() in [92,10]:
self.action['id'] = ''
self.action['season'] = ''
self.action['call'] = 'back' if action.getId() == 92 else 'close'
self.quit()
def onClick(self,controlId):
next_id = xbmc.getInfoLabel('Container(%s).ListItem.Property(id)' % controlId)
next_call = xbmc.getInfoLabel('Container(%s).ListItem.Property(call)' % controlId)
if next_call in ['person','movie','tv'] and next_id:
self.action['id'] = next_id
self.action['call'] = next_call
self.action['season'] = ''
self.quit()
elif next_call == 'image':
FullScreenImage(controlId)
def quit(self):
close_action = self.getProperty('onclose')
onnext_action = self.getProperty('onnext')
onback_action = self.getProperty('onback_%s' % self.getFocusId())
if self.action.get('call') and self.action.get('id'):
execute('SetProperty(tmdb_next_call,true,home)')
if onnext_action:
execute(onnext_action)
if self.action.get('call') == 'back' and onback_action:
execute(onback_action)
else:
if close_action:
execute(close_action)
self.close()
''' Show & movie dialog
'''
class DialogVideo(xbmcgui.WindowXMLDialog):
def __init__(self,*args,**kwargs):
self.first_load = True
self.action = {}
self.tmdb_id = kwargs['tmdb_id']
self.details = kwargs['details']
self.cast = kwargs['cast']
self.crew = kwargs['crew']
self.similar = kwargs['similar']
self.youtube = kwargs['youtube']
self.backdrops = kwargs['backdrops']
self.posters = kwargs['posters']
self.seasons = kwargs['seasons']
self.collection = kwargs['collection']
def __getitem__(self,key):
return self.action[key]
def __setitem__(self,key,value):
self.action[key] = value
def onInit(self):
execute('ClearProperty(script.embuary.info-nextcall,home)')
if self.first_load:
self.add_items()
def add_items(self):
self.first_load = False
index = 10051
li = [self.details, self.cast, self.similar, self.youtube, self.backdrops, self.crew, self.collection, self.seasons, self.posters]
for items in li:
try:
clist = self.getControl(index)
clist.addItems(items)
except RuntimeError as error:
log('Control with id %s cannot be filled. Error --> %s' % (str(index), error), DEBUG)
pass
index += 1
def onAction(self,action):
if action.getId() in [92,10]:
self.action['id'] = ''
self.action['season'] = ''
self.action['call'] = 'back' if action.getId() == 92 else 'close'
self.quit()
def onClick(self,controlId):
next_id = xbmc.getInfoLabel('Container(%s).ListItem.Property(id)' % controlId)
next_call = xbmc.getInfoLabel('Container(%s).ListItem.Property(call)' % controlId)
next_season = xbmc.getInfoLabel('Container(%s).ListItem.Property(call_season)' % controlId)
if next_call in ['person','movie','tv'] and next_id:
if next_id != str(self.tmdb_id) or next_season:
self.action['id'] = next_id
self.action['call'] = next_call
self.action['season'] = next_season
self.quit()
elif next_call == 'image':
FullScreenImage(controlId)
elif next_call == 'youtube':
self.action['id'] = ''
self.action['season'] = ''
self.action['call'] = 'youtube'
xbmc.Player().play('plugin://plugin.video.youtube/play/?video_id=%s' % xbmc.getInfoLabel('Container(%s).ListItem.Property(ytid)' % controlId))
self.quit()
def quit(self):
close_action = self.getProperty('onclose')
onnext_action = self.getProperty('onnext')
onback_action = self.getProperty('onback_%s' % self.getFocusId())
if self.action.get('call') and self.action.get('id'):
execute('SetProperty(script.embuary.info-nextcall,true,home)')
if onnext_action:
execute(onnext_action)
if self.action.get('call') == 'back' and onback_action:
execute(onback_action)
else:
if close_action:
execute(close_action)
self.close()
''' Season dialog
'''
class DialogSeason(xbmcgui.WindowXMLDialog):
def __init__(self,*args,**kwargs):
self.first_load = True
self.action = {}
self.tmdb_id = kwargs['tmdb_id']
self.details = kwargs['details']
self.cast = kwargs['cast']
self.gueststars = kwargs['gueststars']
self.posters = kwargs['posters']
def __getitem__(self,key):
return self.action[key]
def __setitem__(self,key,value):
self.action[key] = value
def onInit(self):
execute('ClearProperty(script.embuary.info-nextcall,home)')
if self.first_load:
self.add_items()
def add_items(self):
self.first_load = False
index = [10051, 10052, 10056, 10059]
li = [self.details, self.cast, self.gueststars, self.posters]
for items in li:
try:
clist = self.getControl(index[li.index(items)])
clist.addItems(items)
except RuntimeError as error:
log('Control with id %s cannot be filled. Error --> %s' % (str(index[li.index(items)]), error), DEBUG)
pass
def onAction(self,action):
if action.getId() in [92,10]:
self.action['id'] = ''
self.action['season'] = ''
self.action['call'] = 'back' if action.getId() == 92 else 'close'
self.quit()
def onClick(self,controlId):
next_id = xbmc.getInfoLabel('Container(%s).ListItem.Property(id)' % controlId)
next_call = xbmc.getInfoLabel('Container(%s).ListItem.Property(call)' % controlId)
if next_call in ['person'] and next_id:
self.action['id'] = next_id
self.action['call'] = next_call
self.action['season'] = ''
self.quit()
elif next_call == 'image':
FullScreenImage(controlId)
def quit(self):
close_action = self.getProperty('onclose')
onnext_action = self.getProperty('onnext')
onback_action = self.getProperty('onback_%s' % self.getFocusId())
if self.action.get('call') and self.action.get('id'):
execute('SetProperty(script.embuary.info-nextcall,true,home)')
if onnext_action:
execute(onnext_action)
if self.action.get('call') == 'back' and onback_action:
execute(onback_action)
else:
if close_action:
execute(close_action)
self.close()
''' Slideshow dialog
'''
class FullScreenImage(object):
def __init__(self,controlId):
slideshow = []
for i in range(int(xbmc.getInfoLabel('Container(%s).NumItems' % controlId))):
slideshow.append(xbmc.getInfoLabel('Container(%s).ListItemAbsolute(%s).Art(thumb)' % (controlId,i)))
dialog = self.ShowImage('script-embuary-image.xml', ADDON_PATH, 'default', '1080i', slideshow=slideshow, position=xbmc.getInfoLabel('Container(%s).CurrentItem' % controlId))
dialog.doModal()
del dialog
class ShowImage(xbmcgui.WindowXMLDialog):
def __init__(self,*args,**kwargs):
self.position = int(kwargs['position']) - 1
self.slideshow = list()
for item in kwargs['slideshow']:
list_item = xbmcgui.ListItem(label='')
list_item.setArt({'icon': item})
self.slideshow.append(list_item)
def onInit(self):
self.cont = self.getControl(1)
self.cont.addItems(self.slideshow)
self.cont.selectItem(self.position)
self.setFocusId(2)