KoD 1.4.1
- ridisegnata la finestra della scelta film/serietv quando si aggiunge in videoteca\n- modifiche minori, qualche fix ai canali/server ed alla ricerca alternativa\n
This commit is contained in:
@@ -72,7 +72,6 @@ def import_videolibrary(item):
|
||||
if config.is_xbmc() and config.get_setting("videolibrary_kodi"):
|
||||
xbmc_videolibrary.clean()
|
||||
p_dialog.update(30)
|
||||
xbmc.sleep(1000)
|
||||
shutil.rmtree(videolibrary_movies_path)
|
||||
shutil.rmtree(videolibrary_tvshows_path)
|
||||
p_dialog.update(50)
|
||||
@@ -102,7 +101,7 @@ def zip(dir, file):
|
||||
temp = file
|
||||
file = filetools.join(temp_path, os.path.split(file)[-1])
|
||||
smb = True
|
||||
with ZipFile(file, "w") as zf:
|
||||
with ZipFile(filetools.file_open(file, 'wb', vfs=False), "w") as zf:
|
||||
abs_src = os.path.abspath(dir)
|
||||
for dirname, subdirs, files in os.walk(dir):
|
||||
for filename in files:
|
||||
@@ -119,5 +118,5 @@ def unzip(dir, file):
|
||||
filetools.copy(file, temp)
|
||||
file = temp
|
||||
|
||||
with ZipFile(file, 'r') as zf:
|
||||
zf.extractall(dir)
|
||||
with ZipFile(filetools.file_open(file, 'rb', vfs=False), 'r') as zf:
|
||||
zf.extractall(dir)
|
||||
|
||||
@@ -258,10 +258,10 @@ def check_channels(inutile=''):
|
||||
|
||||
risultato = {}
|
||||
|
||||
for chann, host in sorted(data.items()):
|
||||
for chann, host in sorted(data['direct'].items()):
|
||||
|
||||
ris = []
|
||||
# to get an idea of the timing
|
||||
# to get an idea of the timing
|
||||
# useful only if you control all channels
|
||||
# for channels with error 522 about 40 seconds are lost ...
|
||||
logger.info("check #### INIZIO #### channel - host :%s - %s " % (chann, host))
|
||||
@@ -290,6 +290,7 @@ def check_channels(inutile=''):
|
||||
|
||||
logger.info("check #### FINE #### rslt :%s " % (rslt))
|
||||
|
||||
risultato = {'findhost': data['findhost'], 'direct': risultato}
|
||||
fileJson_test = 'channels-test.json'
|
||||
# I write the updated file
|
||||
with open(folderJson+'/'+fileJson_test, 'w') as f:
|
||||
|
||||
@@ -15,7 +15,7 @@ __language__ = __settings__.getLocalizedString
|
||||
__version_fix = None
|
||||
__dev_mode = None
|
||||
|
||||
channels_data = list()
|
||||
channels_data = dict()
|
||||
|
||||
def get_addon_core():
|
||||
return __settings__
|
||||
@@ -101,27 +101,29 @@ def is_xbmc():
|
||||
def get_videolibrary_support():
|
||||
return True
|
||||
|
||||
def get_channel_url(findhostMethod=None, name=None):
|
||||
|
||||
def get_channel_url(findhostMethod=None, name=None, forceFindhost=False):
|
||||
from core import jsontools
|
||||
import inspect
|
||||
|
||||
LOCAL_FILE = os.path.join(get_runtime_path(), "channels.json")
|
||||
global channels_data
|
||||
if not channels_data:
|
||||
with open(LOCAL_FILE) as f:
|
||||
channels_data = jsontools.load(f.read())
|
||||
|
||||
frame = inspect.stack()[1]
|
||||
if not name:
|
||||
name = os.path.basename(frame[0].f_code.co_filename).replace('.py', '')
|
||||
if findhostMethod:
|
||||
url = jsontools.get_node_from_file(name, 'url')
|
||||
if not url or 'web.archive.org' in url: # per eliminare tutti i webarchive salvati causa bug httptools CF, eliminare in futuro
|
||||
url = findhostMethod()
|
||||
if not url or 'web.archive.org' in url or forceFindhost: # per eliminare tutti i webarchive salvati causa bug httptools CF, eliminare in futuro
|
||||
url = findhostMethod(channels_data['findhost'][name])
|
||||
jsontools.update_node(url, name, 'url')
|
||||
return url
|
||||
else:
|
||||
ROOT_DIR = xbmc.translatePath(__settings__.getAddonInfo('Path'))
|
||||
LOCAL_FILE = os.path.join(ROOT_DIR, "channels.json")
|
||||
global channels_data
|
||||
if not channels_data:
|
||||
with open(LOCAL_FILE) as f:
|
||||
channels_data = jsontools.load(f.read())
|
||||
return channels_data[name]
|
||||
return channels_data['direct'][name]
|
||||
|
||||
|
||||
def get_system_platform():
|
||||
""" function: to recover the platform that xbmc is running """
|
||||
@@ -147,7 +149,7 @@ def is_autorun_enabled():
|
||||
|
||||
|
||||
def enable_disable_autorun(is_enabled):
|
||||
# using autoexec.py and not service.py to force autorun
|
||||
# old method, now using service.py
|
||||
|
||||
path = os.path.join(xbmc.translatePath('special://userdata'),'autoexec.py')
|
||||
append_write = 'a' if os.path.exists(path) else 'w'
|
||||
@@ -163,7 +165,7 @@ def enable_disable_autorun(is_enabled):
|
||||
file.close()
|
||||
with open(path, "w") as file:
|
||||
file.write(new_content)
|
||||
set_setting('autostart', 'Off')
|
||||
set_setting('autostart', True)
|
||||
return True
|
||||
|
||||
def get_all_settings_addon():
|
||||
|
||||
@@ -6,6 +6,15 @@ from __future__ import unicode_literals
|
||||
import inspect, os, xbmc, sys
|
||||
from platformcode import config
|
||||
|
||||
# for test suite
|
||||
try:
|
||||
xbmc.KodiStub()
|
||||
testMode = True
|
||||
record = False
|
||||
recordedLog = ''
|
||||
import html
|
||||
except:
|
||||
testMode = False
|
||||
LOG_FORMAT = '{addname}[{filename}.{function}:{line}]{sep} {message}'
|
||||
DEBUG_ENABLED = config.get_setting("debug")
|
||||
DEF_LEVEL = xbmc.LOGINFO if sys.version_info[0] >= 3 else xbmc.LOGNOTICE
|
||||
@@ -28,6 +37,10 @@ def error(*args):
|
||||
def log(*args, **kwargs):
|
||||
msg = ''
|
||||
for arg in args: msg += ' ' + str(arg)
|
||||
if testMode and record:
|
||||
global recordedLog
|
||||
recordedLog += msg + '\n'
|
||||
return
|
||||
frame = inspect.currentframe().f_back.f_back
|
||||
filename = frame.f_code.co_filename
|
||||
filename = os.path.basename(filename).split('.')[0]
|
||||
|
||||
@@ -111,6 +111,70 @@ def dialog_browse(_type, heading, shares="files", mask="", useThumbs=False, trea
|
||||
|
||||
|
||||
def dialog_register(heading, user=False, email=False, password=False, user_default='', email_default='', password_default='', captcha_img=''):
|
||||
class Register(xbmcgui.WindowXMLDialog):
|
||||
def Start(self, heading, user, email, password, user_default, email_default, password_default, captcha_img):
|
||||
self.result = {}
|
||||
self.heading = heading
|
||||
self.user = user
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.user_default = user_default
|
||||
self.email_default = email_default
|
||||
self.password_default = password_default
|
||||
self.captcha_img = captcha_img
|
||||
self.doModal()
|
||||
|
||||
return self.result
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.mensaje = kwargs.get("mensaje")
|
||||
self.imagen = kwargs.get("imagen")
|
||||
|
||||
def onInit(self):
|
||||
#### Kodi 18 compatibility ####
|
||||
if config.get_platform(True)['num_version'] < 18:
|
||||
self.setCoordinateResolution(2)
|
||||
height = 90
|
||||
self.getControl(10002).setText(self.heading)
|
||||
if self.user:
|
||||
self.getControl(10003).setText(self.user_default)
|
||||
height += 70
|
||||
else:
|
||||
self.getControl(10003).setVisible(False)
|
||||
if self.email:
|
||||
self.getControl(10004).setText(self.email_default)
|
||||
height += 70
|
||||
else:
|
||||
self.getControl(10004).setVisible(False)
|
||||
if self.password:
|
||||
self.getControl(10005).setText(self.password_default)
|
||||
height += 70
|
||||
else:
|
||||
self.getControl(10005).setVisible(False)
|
||||
if self.captcha_img:
|
||||
|
||||
self.getControl(10007).setImage(self.captcha_img)
|
||||
height += 240
|
||||
else:
|
||||
self.getControl(10005).setVisible(False)
|
||||
height += 40
|
||||
if height < 250: height = 250
|
||||
self.getControl(10000).setHeight(height)
|
||||
self.getControl(10001).setHeight(height)
|
||||
self.getControl(10000).setPosition(255, (720 - height) / 2)
|
||||
self.setFocusId(30000)
|
||||
|
||||
def onClick(self, control):
|
||||
if control in [10010]:
|
||||
self.close()
|
||||
|
||||
elif control in [10009]:
|
||||
if self.user: self.result['user'] = self.getControl(10003).getText()
|
||||
if self.email: self.result['email'] = self.getControl(10004).getText()
|
||||
if self.password: self.result['password'] = self.getControl(10005).getText()
|
||||
if self.captcha_img: self.result['captcha'] = self.getControl(10006).getText()
|
||||
self.close()
|
||||
|
||||
dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img)
|
||||
return dialog
|
||||
|
||||
@@ -1274,68 +1338,3 @@ def get_platform():
|
||||
ret["arch"] = "arm"
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
class Register(xbmcgui.WindowXMLDialog):
|
||||
def Start(self, heading, user, email, password, user_default, email_default, password_default, captcha_img):
|
||||
self.result = {}
|
||||
self.heading = heading
|
||||
self.user = user
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.user_default = user_default
|
||||
self.email_default = email_default
|
||||
self.password_default = password_default
|
||||
self.captcha_img = captcha_img
|
||||
self.doModal()
|
||||
|
||||
return self.result
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.mensaje = kwargs.get("mensaje")
|
||||
self.imagen = kwargs.get("imagen")
|
||||
|
||||
def onInit(self):
|
||||
#### Kodi 18 compatibility ####
|
||||
if config.get_platform(True)['num_version'] < 18:
|
||||
self.setCoordinateResolution(2)
|
||||
height = 90
|
||||
self.getControl(10002).setText(self.heading)
|
||||
if self.user:
|
||||
self.getControl(10003).setText(self.user_default)
|
||||
height+=70
|
||||
else:
|
||||
self.getControl(10003).setVisible(False)
|
||||
if self.email:
|
||||
self.getControl(10004).setText(self.email_default)
|
||||
height+=70
|
||||
else:
|
||||
self.getControl(10004).setVisible(False)
|
||||
if self.password:
|
||||
self.getControl(10005).setText(self.password_default)
|
||||
height+=70
|
||||
else:
|
||||
self.getControl(10005).setVisible(False)
|
||||
if self.captcha_img:
|
||||
|
||||
self.getControl(10007).setImage(self.captcha_img)
|
||||
height+=240
|
||||
else:
|
||||
self.getControl(10005).setVisible(False)
|
||||
height +=40
|
||||
if height < 250: height = 250
|
||||
self.getControl(10000).setHeight(height)
|
||||
self.getControl(10001).setHeight(height)
|
||||
self.getControl(10000).setPosition(255, (720-height)/2)
|
||||
self.setFocusId(30000)
|
||||
|
||||
def onClick(self, control):
|
||||
if control in [10010]:
|
||||
self.close()
|
||||
|
||||
elif control in [10009]:
|
||||
if self.user: self.result['user'] = self.getControl(10003).getText()
|
||||
if self.email: self.result['email'] = self.getControl(10004).getText()
|
||||
if self.password: self.result['password'] = self.getControl(10005).getText()
|
||||
if self.captcha_img: self.result['captcha'] = self.getControl(10006).getText()
|
||||
self.close()
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from platformcode import logger, side_menu
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def context():
|
||||
@@ -18,6 +18,7 @@ def context():
|
||||
return context
|
||||
|
||||
def Side_menu(item):
|
||||
from platformcode import side_menu
|
||||
side_menu.open_menu(item)
|
||||
|
||||
def shortcut_menu(item):
|
||||
|
||||
@@ -161,8 +161,12 @@ def check(background=False):
|
||||
if addon.getSetting("addon_update_message"):
|
||||
if background:
|
||||
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80040) % commits[0]['sha'][:7], time=3000, sound=False)
|
||||
with open(xbmc.translatePath(changelogFile), 'a+') as fileC:
|
||||
fileC.write(changelog)
|
||||
try:
|
||||
with open(xbmc.translatePath(changelogFile), 'a+') as fileC:
|
||||
fileC.write(changelog)
|
||||
except:
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
elif changelog:
|
||||
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80041) + changelog)
|
||||
else:
|
||||
@@ -175,7 +179,8 @@ def showSavedChangelog():
|
||||
try:
|
||||
with open(xbmc.translatePath(changelogFile), 'r') as fileC:
|
||||
changelog = fileC.read()
|
||||
platformtools.dialog_ok('Kodi on Demand', 'Aggiornamenti applicati:\n' + changelog)
|
||||
if changelog.strip():
|
||||
platformtools.dialog_ok('Kodi on Demand', 'Aggiornamenti applicati:\n' + changelog)
|
||||
os.remove(xbmc.translatePath(changelogFile))
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -4,332 +4,52 @@ import xbmcgui
|
||||
|
||||
from core.tmdb import Tmdb
|
||||
from platformcode import config, logger
|
||||
from core import filetools
|
||||
|
||||
ID_BUTTON_CLOSE = 10003
|
||||
ID_BUTTON_PREVIOUS = 10025
|
||||
ID_BUTTON_NEXT = 10026
|
||||
ID_BUTTON_CANCEL = 10027
|
||||
ID_BUTTON_OK = 10028
|
||||
BACKGROUND = 30000
|
||||
LOADING = 30001
|
||||
SELECT = 30002
|
||||
|
||||
def imagepath(image):
|
||||
if len(image.split('.')) == 1: image += '.png'
|
||||
path = filetools.join(config.get_runtime_path(), 'resources', 'skins' , 'Default', 'media', 'Infoplus', image)
|
||||
return path
|
||||
|
||||
class InfoWindow(xbmcgui.WindowXMLDialog):
|
||||
otmdb = None
|
||||
|
||||
item_title = ""
|
||||
item_serie = ""
|
||||
item_temporada = 0
|
||||
item_episodio = 0
|
||||
result = {}
|
||||
|
||||
# PARA TMDB
|
||||
@staticmethod
|
||||
def get_language(lng):
|
||||
# Cambiamos el formato del Idioma
|
||||
languages = {
|
||||
'aa': 'Afar', 'ab': 'Abkhazian', 'af': 'Afrikaans', 'ak': 'Akan', 'sq': 'Albanian', 'am': 'Amharic',
|
||||
'ar': 'Arabic', 'an': 'Aragonese', 'as': 'Assamese', 'av': 'Avaric', 'ae': 'Avestan', 'ay': 'Aymara',
|
||||
'az': 'Azerbaijani', 'ba': 'Bashkir', 'bm': 'Bambara', 'eu': 'Basque', 'be': 'Belarusian', 'bn': 'Bengali',
|
||||
'bh': 'Bihari languages', 'bi': 'Bislama', 'bo': 'Tibetan', 'bs': 'Bosnian', 'br': 'Breton',
|
||||
'bg': 'Bulgarian', 'my': 'Burmese', 'ca': 'Catalan; Valencian', 'cs': 'Czech', 'ch': 'Chamorro',
|
||||
'ce': 'Chechen', 'zh': 'Chinese',
|
||||
'cu': 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic', 'cv': 'Chuvash',
|
||||
'kw': 'Cornish', 'co': 'Corsican', 'cr': 'Cree', 'cy': 'Welsh', 'da': 'Danish', 'de': 'German',
|
||||
'dv': 'Divehi; Dhivehi; Maldivian', 'nl': 'Dutch; Flemish', 'dz': 'Dzongkha', 'en': 'English',
|
||||
'eo': 'Esperanto', 'et': 'Estonian', 'ee': 'Ewe', 'fo': 'Faroese', 'fa': 'Persian', 'fj': 'Fijian',
|
||||
'fi': 'Finnish', 'fr': 'French', 'fy': 'Western Frisian', 'ff': 'Fulah', 'Ga': 'Georgian',
|
||||
'gd': 'Gaelic; Scottish Gaelic', 'ga': 'Irish', 'gl': 'Galician', 'gv': 'Manx',
|
||||
'el': 'Greek, Modern (1453-)', 'gn': 'Guarani', 'gu': 'Gujarati', 'ht': 'Haitian; Haitian Creole',
|
||||
'ha': 'Hausa', 'he': 'Hebrew', 'hz': 'Herero', 'hi': 'Hindi', 'ho': 'Hiri Motu', 'hr': 'Croatian',
|
||||
'hu': 'Hungarian', 'hy': 'Armenian', 'ig': 'Igbo', 'is': 'Icelandic', 'io': 'Ido',
|
||||
'ii': 'Sichuan Yi; Nuosu', 'iu': 'Inuktitut', 'ie': 'Interlingue; Occidental',
|
||||
'ia': 'Interlingua (International Auxiliary Language Association)', 'id': 'Indonesian', 'ik': 'Inupiaq',
|
||||
'it': 'Italian', 'jv': 'Javanese', 'ja': 'Japanese', 'kl': 'Kalaallisut; Greenlandic', 'kn': 'Kannada',
|
||||
'ks': 'Kashmiri', 'ka': 'Georgian', 'kr': 'Kanuri', 'kk': 'Kazakh', 'km': 'Central Khmer',
|
||||
'ki': 'Kikuyu; Gikuyu', 'rw': 'Kinyarwanda', 'ky': 'Kirghiz; Kyrgyz', 'kv': 'Komi', 'kg': 'Kongo',
|
||||
'ko': 'Korean', 'kj': 'Kuanyama; Kwanyama', 'ku': 'Kurdish', 'lo': 'Lao', 'la': 'Latin', 'lv': 'Latvian',
|
||||
'li': 'Limburgan; Limburger; Limburgish', 'ln': 'Lingala', 'lt': 'Lithuanian',
|
||||
'lb': 'Luxembourgish; Letzeburgesch', 'lu': 'Luba-Katanga', 'lg': 'Ganda', 'mk': 'Macedonian',
|
||||
'mh': 'Marshallese', 'ml': 'Malayalam', 'mi': 'Maori', 'mr': 'Marathi', 'ms': 'Malay', 'Mi': 'Micmac',
|
||||
'mg': 'Malagasy', 'mt': 'Maltese', 'mn': 'Mongolian', 'na': 'Nauru', 'nv': 'Navajo; Navaho',
|
||||
'nr': 'Ndebele, South; South Ndebele', 'nd': 'Ndebele, North; North Ndebele', 'ng': 'Ndonga',
|
||||
'ne': 'Nepali', 'nn': 'Norwegian Nynorsk; Nynorsk, Norwegian', 'nb': 'Bokmål, Norwegian; Norwegian Bokmål',
|
||||
'no': 'Norwegian', 'oc': 'Occitan (post 1500)', 'oj': 'Ojibwa', 'or': 'Oriya', 'om': 'Oromo',
|
||||
'os': 'Ossetian; Ossetic', 'pa': 'Panjabi; Punjabi', 'pi': 'Pali', 'pl': 'Polish', 'pt': 'Portuguese',
|
||||
'ps': 'Pushto; Pashto', 'qu': 'Quechua', 'ro': 'Romanian; Moldavian; Moldovan', 'rn': 'Rundi',
|
||||
'ru': 'Russian', 'sg': 'Sango', 'rm': 'Romansh', 'sa': 'Sanskrit', 'si': 'Sinhala; Sinhalese',
|
||||
'sk': 'Slovak', 'sl': 'Slovenian', 'se': 'Northern Sami', 'sm': 'Samoan', 'sn': 'Shona', 'sd': 'Sindhi',
|
||||
'so': 'Somali', 'st': 'Sotho, Southern', 'es': 'Spanish', 'sc': 'Sardinian', 'sr': 'Serbian', 'ss': 'Swati',
|
||||
'su': 'Sundanese', 'sw': 'Swahili', 'sv': 'Swedish', 'ty': 'Tahitian', 'ta': 'Tamil', 'tt': 'Tatar',
|
||||
'te': 'Telugu', 'tg': 'Tajik', 'tl': 'Tagalog', 'th': 'Thai', 'ti': 'Tigrinya',
|
||||
'to': 'Tonga (Tonga Islands)', 'tn': 'Tswana', 'ts': 'Tsonga', 'tk': 'Turkmen', 'tr': 'Turkish',
|
||||
'tw': 'Twi', 'ug': 'Uighur; Uyghur', 'uk': 'Ukrainian', 'ur': 'Urdu', 'uz': 'Uzbek', 've': 'Venda',
|
||||
'vi': 'Vietnamese', 'vo': 'Volapük', 'wa': 'Walloon', 'wo': 'Wolof', 'xh': 'Xhosa', 'yi': 'Yiddish',
|
||||
'yo': 'Yoruba', 'za': 'Zhuang; Chuang', 'zu': 'Zulu'}
|
||||
|
||||
return languages.get(lng, lng)
|
||||
|
||||
def get_scraper_data(self, data_in):
|
||||
self.otmdb = None
|
||||
# logger.debug(str(data_in))
|
||||
|
||||
if self.listData:
|
||||
# Data common to all listings
|
||||
infoLabels = self.scraper().get_infoLabels(origen=data_in)
|
||||
|
||||
if "original_language" in infoLabels:
|
||||
infoLabels["language"] = self.get_language(infoLabels["original_language"])
|
||||
infoLabels["puntuacion"] = "%s/10 (%s)" % (infoLabels.get("rating", "?"), infoLabels.get("votes", "N/A"))
|
||||
|
||||
self.result = infoLabels
|
||||
|
||||
def start(self, data, caption="Información del vídeo", item=None, scraper=Tmdb):
|
||||
"""
|
||||
It shows a window with the info of the video. Optionally, the title of the window can be indicated by means of the argument 'caption'.
|
||||
|
||||
If an item is passed as the 'data' argument use the Tmdb scrapper to find the video info
|
||||
In case of movies:
|
||||
Take the title from the following fields (in this order)
|
||||
1. contentTitle (this has priority 1)
|
||||
2. title (this has priority 2)
|
||||
The first one containing "something" interprets it as the title (it is important to make sure that the title is in
|
||||
your site)
|
||||
|
||||
In case of series:
|
||||
1. Find the season and episode in the contentSeason and contentEpisodeNumber fields
|
||||
2. Try to remove it from the video title (format: 1x01)
|
||||
|
||||
Here are two possible options:
|
||||
1. We have Season and episode
|
||||
Shows the information of the specific chapter
|
||||
2. We DO NOT have Season and episode
|
||||
In this case it shows the generic information of the series
|
||||
|
||||
If an InfoLabels object (see item.py) is passed as an argument 'data' it shows in the window directly
|
||||
the past information (without using the scrapper)
|
||||
Format:
|
||||
In case of movies:
|
||||
infoLabels ({
|
||||
"type" : "movie",
|
||||
"title": "Title of the movie",
|
||||
"original_title": "Original movie title",
|
||||
"date": "Release date",
|
||||
"language": "Original language of the movie",
|
||||
"rating": "Rating of the movie",
|
||||
"votes": "Number of votes",
|
||||
"genres": "Genres of the movie",
|
||||
"thumbnail": "Path for the thumbnail",
|
||||
"fanart": "Route for the fanart",
|
||||
"plot": "Synopsis of the movie"
|
||||
}
|
||||
In case of series:
|
||||
infoLabels ({
|
||||
"type" : "tv",
|
||||
"title": "Title of the series",
|
||||
"episode_title": "Episode title",
|
||||
"date": "Date of issue",
|
||||
"language": "Original language of the series",
|
||||
"rating": "Punctuation of the series",
|
||||
"votes": "Number of votes",
|
||||
"genres": "Genres of the series",
|
||||
"thumbnail": "Path for the thumbnail",
|
||||
"fanart": "Route for the fanart",
|
||||
"plot": "Synopsis of the episode or series",
|
||||
"seasons": "Number of Seasons",
|
||||
"season": "Season",
|
||||
"episodes": "Number of episodes of the season",
|
||||
"episode": "Episode"
|
||||
}
|
||||
If a list of InfoLabels () with the previous structure is passed as the 'data' argument, it shows the buttons
|
||||
'Previous' and 'Next' to scroll through the list. It also shows the 'Accept' and 'Cancel' buttons that
|
||||
call the function 'callback' of the channel from where the call is made, passing the element as parameters
|
||||
current (InfoLabels ()) or None respectively.
|
||||
|
||||
@param data: information to get scraper data.
|
||||
@type data: item, InfoLabels, list(InfoLabels)
|
||||
@param caption: window title.
|
||||
@type caption: str
|
||||
@param item: item for which the information window is to be displayed
|
||||
@type item: Item
|
||||
@param scraper: scraper that has the data of the movies or series to show in the window.
|
||||
@type scraper: Scraper
|
||||
"""
|
||||
|
||||
# We capture the parameters
|
||||
self.caption = caption
|
||||
def start(self, results, caption="", item=None, scraper=Tmdb):
|
||||
self.items = []
|
||||
self.response = None
|
||||
self.results = results
|
||||
self.item = item
|
||||
self.indexList = -1
|
||||
self.listData = None
|
||||
self.return_value = None
|
||||
self.scraper = scraper
|
||||
|
||||
logger.debug(data)
|
||||
if type(data) == list:
|
||||
self.listData = data
|
||||
self.indexList = 0
|
||||
data = self.listData[self.indexList]
|
||||
|
||||
self.get_scraper_data(data)
|
||||
|
||||
# Show window
|
||||
self.doModal()
|
||||
return self.return_value
|
||||
|
||||
def __init__(self, *args):
|
||||
self.caption = ""
|
||||
self.item = None
|
||||
self.listData = None
|
||||
self.indexList = 0
|
||||
self.return_value = None
|
||||
self.scraper = Tmdb
|
||||
logger.info('RESPONSE',self.response)
|
||||
return self.response
|
||||
|
||||
def onInit(self):
|
||||
#### Kodi 18 compatibility ####
|
||||
if config.get_platform(True)['num_version'] < 18:
|
||||
if xbmcgui.__version__ == "1.2":
|
||||
self.setCoordinateResolution(1)
|
||||
else:
|
||||
self.setCoordinateResolution(5)
|
||||
self.setCoordinateResolution(2)
|
||||
|
||||
# We put the title and the images
|
||||
self.getControl(10002).setLabel(self.caption)
|
||||
self.getControl(10004).setImage(self.result.get("fanart", ""))
|
||||
self.getControl(10005).setImage(self.result.get("thumbnail", "images/img_no_disponible.png"))
|
||||
for result in self.results:
|
||||
infoLabels = self.scraper().get_infoLabels(origen=result)
|
||||
it = xbmcgui.ListItem(infoLabels['title'])
|
||||
it.setProperty('fanart', infoLabels.get('fanart', ''))
|
||||
it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv')))
|
||||
it.setProperty('genre', infoLabels.get('genre', 'N/A'))
|
||||
it.setProperty('rating', str(infoLabels.get('rating', 'N/A')))
|
||||
it.setProperty('plot', str(infoLabels.get('plot', '')))
|
||||
it.setProperty('year', str(infoLabels.get('year', '')))
|
||||
self.items.append(it)
|
||||
|
||||
# We load the data for the movie format
|
||||
if self.result.get("mediatype", "movie") == "movie":
|
||||
self.getControl(10006).setLabel(config.get_localized_string(60377))
|
||||
self.getControl(10007).setLabel(self.result.get("title", "N/A"))
|
||||
self.getControl(10008).setLabel(config.get_localized_string(60378))
|
||||
self.getControl(10009).setLabel(self.result.get("originaltitle", "N/A"))
|
||||
self.getControl(100010).setLabel(config.get_localized_string(60379))
|
||||
self.getControl(100011).setLabel(self.result.get("language", "N/A"))
|
||||
self.getControl(100012).setLabel(config.get_localized_string(60380))
|
||||
self.getControl(100013).setLabel(self.result.get("puntuacion", "N/A"))
|
||||
self.getControl(100014).setLabel(config.get_localized_string(60381))
|
||||
self.getControl(100015).setLabel(self.result.get("release_date", "N/A"))
|
||||
self.getControl(100016).setLabel(config.get_localized_string(60382))
|
||||
self.getControl(100017).setLabel(self.result.get("genre", "N/A"))
|
||||
self.getControl(SELECT).addItems(self.items)
|
||||
self.getControl(BACKGROUND).setImage(self.items[0].getProperty('fanart'))
|
||||
self.getControl(LOADING).setVisible(False)
|
||||
self.setFocusId(SELECT)
|
||||
|
||||
# We load the data for the serial format
|
||||
else:
|
||||
self.getControl(10006).setLabel(config.get_localized_string(60383))
|
||||
self.getControl(10007).setLabel(self.result.get("title", "N/A"))
|
||||
self.getControl(10008).setLabel(config.get_localized_string(60379))
|
||||
self.getControl(10009).setLabel(self.result.get("language", "N/A"))
|
||||
self.getControl(100010).setLabel(config.get_localized_string(60380))
|
||||
self.getControl(100011).setLabel(self.result.get("puntuacion", "N/A"))
|
||||
self.getControl(100012).setLabel(config.get_localized_string(60382))
|
||||
self.getControl(100013).setLabel(self.result.get("genre", "N/A"))
|
||||
def onClick(self, control_id):
|
||||
if control_id == SELECT:
|
||||
self.response = self.results[self.getControl(SELECT).getSelectedPosition()]
|
||||
self.close()
|
||||
|
||||
if self.result.get("season"):
|
||||
self.getControl(100014).setLabel(config.get_localized_string(60384))
|
||||
self.getControl(100015).setLabel(self.result.get("temporada_nombre", "N/A"))
|
||||
self.getControl(100016).setLabel(config.get_localized_string(60385))
|
||||
self.getControl(100017).setLabel(self.result.get("season", "N/A") + " de " + self.result.get("seasons", "N/A"))
|
||||
if self.result.get("episode"):
|
||||
self.getControl(100014).setLabel(config.get_localized_string(60377))
|
||||
self.getControl(100015).setLabel(self.result.get("episode_title", "N/A"))
|
||||
self.getControl(100018).setLabel(config.get_localized_string(60386))
|
||||
self.getControl(100019).setLabel(self.result.get("episode", "N/A") + " de " + self.result.get("episodes", "N/A"))
|
||||
self.getControl(100020).setLabel(config.get_localized_string(60387))
|
||||
self.getControl(100021).setLabel(self.result.get("date", "N/A"))
|
||||
|
||||
# Synopsis
|
||||
if self.result['plot']:
|
||||
self.getControl(100022).setLabel(config.get_localized_string(60388))
|
||||
self.getControl(100023).setText(self.result.get("plot", "N/A"))
|
||||
else:
|
||||
self.getControl(100022).setLabel("")
|
||||
self.getControl(100023).setText("")
|
||||
|
||||
# We load the buttons if necessary
|
||||
self.getControl(10024).setVisible(self.indexList > -1) # Button group
|
||||
self.getControl(ID_BUTTON_PREVIOUS).setEnabled(self.indexList > 0) # Previous
|
||||
|
||||
if self.listData:
|
||||
m = len(self.listData)
|
||||
else:
|
||||
m = 1
|
||||
|
||||
self.getControl(ID_BUTTON_NEXT).setEnabled(self.indexList + 1 != m) # Following
|
||||
self.getControl(100029).setLabel("(%s/%s)" % (self.indexList + 1, m)) # x/m
|
||||
|
||||
# We put the focus in the Group of buttons, if "Previous" was deactivated the focus would go to the "Next" button
|
||||
# if "Next" tb is deactivated it will pass the focus to the "Cancel" button
|
||||
self.setFocus(self.getControl(10024))
|
||||
|
||||
return self.return_value
|
||||
|
||||
def onClick(self, _id):
|
||||
logger.info("onClick id=" + repr(_id))
|
||||
if _id == ID_BUTTON_PREVIOUS and self.indexList > 0:
|
||||
self.indexList -= 1
|
||||
self.get_scraper_data(self.listData[self.indexList])
|
||||
self.onInit()
|
||||
|
||||
elif _id == ID_BUTTON_NEXT and self.indexList < len(self.listData) - 1:
|
||||
self.indexList += 1
|
||||
self.get_scraper_data(self.listData[self.indexList])
|
||||
self.onInit()
|
||||
|
||||
elif _id == ID_BUTTON_OK or _id == ID_BUTTON_CLOSE or _id == ID_BUTTON_CANCEL:
|
||||
self.close()
|
||||
|
||||
if _id == ID_BUTTON_OK:
|
||||
self.return_value = self.listData[self.indexList]
|
||||
else:
|
||||
self.return_value = None
|
||||
|
||||
def onAction(self, action):
|
||||
logger.info("action=" + repr(action.getId()))
|
||||
action = action.getId()
|
||||
|
||||
# Find Focus
|
||||
focus = self.getFocusId()
|
||||
|
||||
# Left
|
||||
if action == 1:
|
||||
|
||||
if focus == ID_BUTTON_OK:
|
||||
self.setFocus(self.getControl(ID_BUTTON_CANCEL))
|
||||
|
||||
elif focus == ID_BUTTON_CANCEL:
|
||||
if self.indexList + 1 != len(self.listData):
|
||||
# Next
|
||||
self.setFocus(self.getControl(ID_BUTTON_NEXT))
|
||||
elif self.indexList > 0:
|
||||
# Previous
|
||||
self.setFocus(self.getControl(ID_BUTTON_PREVIOUS))
|
||||
|
||||
elif focus == ID_BUTTON_NEXT:
|
||||
if self.indexList > 0:
|
||||
# Next
|
||||
self.setFocus(self.getControl(ID_BUTTON_PREVIOUS))
|
||||
|
||||
# Right
|
||||
elif action == 2:
|
||||
|
||||
if focus == ID_BUTTON_PREVIOUS:
|
||||
if self.indexList + 1 != len(self.listData):
|
||||
# Next
|
||||
self.setFocus(self.getControl(ID_BUTTON_NEXT))
|
||||
else:
|
||||
# Cancel
|
||||
self.setFocus(self.getControl(ID_BUTTON_CANCEL))
|
||||
|
||||
elif focus == ID_BUTTON_NEXT:
|
||||
self.setFocus(self.getControl(ID_BUTTON_CANCEL))
|
||||
|
||||
elif focus == ID_BUTTON_CANCEL:
|
||||
self.setFocus(self.getControl(ID_BUTTON_OK))
|
||||
|
||||
# Up
|
||||
elif action == 3:
|
||||
self.setFocus(self.getControl(ID_BUTTON_CLOSE))
|
||||
|
||||
# Down
|
||||
elif action == 4:
|
||||
self.setFocus(self.getControl(ID_BUTTON_OK))
|
||||
# Press ESC or Back, simulate click on cancel button
|
||||
if action in [10, 92]:
|
||||
self.onClick(ID_BUTTON_CANCEL)
|
||||
|
||||
Reference in New Issue
Block a user