- completato il supporto al futuro Kodi 19\n- ridisegnato infoplus\n- fix vari ed eventuali\n
This commit is contained in:
marco
2020-09-29 21:08:25 +02:00
parent d153ac5918
commit 8a8d1e4f5e
195 changed files with 20697 additions and 23038 deletions

View File

@@ -0,0 +1,568 @@
# -*- coding: utf-8 -*-
# --------------------------------------------------------------------------------
# autorenumber - Rinomina Automaticamente gli Episodi
# --------------------------------------------------------------------------------
'''
USO:
1) utilizzare autorenumber.renumber(itemlist) nelle le funzioni peliculas e similari per aggiungere il menu contestuale
2) utilizzare autorenumber.renumber(itemlist, item, typography) nella funzione episodios
3) Aggiungere le seguinti stringhe nel json del canale (per attivare la configurazione di autonumerazione del canale)
{
"id": "autorenumber",
"type": "bool",
"label": "@70712",
"default": false,
"enabled": true,
"visible": true
},
{
"id": "autorenumber_mode",
"type": "bool",
"label": "@70688",
"default": false,
"enabled": true,
"visible": "eq(-1,true)"
}
'''
try:
import xbmcgui
except:
xbmcgui = None
import re, base64, json, inspect
from core import jsontools, tvdb, scrapertools, filetools
from core.support import typo
from platformcode import config, platformtools, logger
TAG_TVSHOW_RENUMERATE = "TVSHOW_AUTORENUMBER"
TAG_ID = "ID"
TAG_SEASON = "Season"
TAG_EPISODE = "Episode"
TAG_SPECIAL = "Special"
TAG_MODE = "Mode"
TAG_EPLIST = "EpList"
TAG_CHECK = "ReCheck"
TAG_SPLIST = "SpList"
TAG_TYPE = "Type"
def renumber(itemlist, item='', typography=''):
logger.info()
dict_series = load(itemlist[0]) if len(itemlist) > 0 else {}
if item:
item.channel = item.from_channel if item.from_channel else item.channel
title = item.fulltitle.rstrip()
already_renumbered = scrapertools.find_single_match(itemlist[0].title, r'(\d+\D\d+)')
if already_renumbered :
return itemlist
elif item.channel in item.channel_prefs and TAG_TVSHOW_RENUMERATE in item.channel_prefs[item.channel] and title not in dict_series:
from core.videolibrarytools import check_renumber_options
from specials.videolibrary import update_videolibrary
check_renumber_options(item)
update_videolibrary(item)
elif inspect.stack()[2][3] == 'find_episodes':
return itemlist
elif title in dict_series and TAG_ID in dict_series[title]:
ID = dict_series[title][TAG_ID]
Episode = dict_series[title][TAG_EPISODE]
Season = dict_series[title][TAG_SEASON] if TAG_SEASON in dict_series[title] else ''
Mode = dict_series[title][TAG_MODE] if TAG_MODE in dict_series[title] else False
Type = dict_series[title][TAG_TYPE] if TAG_TYPE in dict_series[title] else 'auto'
renumeration(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title, Type)
else:
if config.get_setting('autorenumber', item.channel):
config_item(item, itemlist, typography, True)
else:
return itemlist
else:
for item in itemlist:
title = item.fulltitle.rstrip()
if title in dict_series and TAG_ID in dict_series[title]:
ID = dict_series[title][TAG_ID]
exist = True
else:
exist = False
if item.contentType != 'movie':
if item.context:
context2 = item.context
item.show = item.fulltitle = title
item.context = context(exist) + context2
else:
item.show = item.fulltitle = title
item.context = context(exist)
def config_item(item, itemlist=[], typography='', active=False):
logger.info()
# Configurazione Automatica, Tenta la numerazione Automatica degli episodi
title = item.fulltitle.rstrip()
dict_series = load(item)
ID = dict_series[title][TAG_ID] if title in dict_series and TAG_ID in dict_series[title] else ''
# Pulizia del Titolo
if any( word in title.lower() for word in ['specials', 'speciali']):
title = re.sub(r'\sspecials|\sspeciali', '', title.lower())
tvdb.find_and_set_infoLabels(item)
elif not item.infoLabels['tvdb_id']:
item.contentSerieName= title.rstrip('123456789 ')
tvdb.find_and_set_infoLabels(item)
if not ID and active:
if item.infoLabels['tvdb_id']:
ID = item.infoLabels['tvdb_id']
dict_renumerate = {TAG_ID: ID}
dict_series[title] = dict_renumerate
# Trova La Stagione
if any(word in title.lower() for word in ['specials', 'speciali']):
dict_renumerate[TAG_SEASON] = '0'
elif RepresentsInt(title.split()[-1]):
dict_renumerate[TAG_SEASON] = title.split()[-1]
else: dict_renumerate[TAG_SEASON] = '1'
dict_renumerate[TAG_EPISODE] = ''
write(item, dict_series)
return renumber(itemlist, item, typography)
else:
return itemlist
else:
return renumber(itemlist, item, typography)
def semiautomatic_config_item(item):
logger.info()
# Configurazione Semi Automatica, utile in caso la numerazione automatica fallisca
tvdb.find_and_set_infoLabels(item)
item.channel = item.from_channel if item.from_channel else item.channel
dict_series = load(item)
title = item.fulltitle.rstrip()
# Trova l'ID della serie
while not item.infoLabels['tvdb_id']:
try:
item.show = platformtools.dialog_input(default=item.show, heading=config.get_localized_string(30112)) # <- Enter title to search
tvdb.find_and_set_infoLabels(item)
except:
heading = config.get_localized_string(70704) # <- TMDB ID (0 to cancel)
info = platformtools.dialog_numeric(0, heading)
item.infoLabels['tvdb_id'] = '0' if info == '' else info
if item.infoLabels['tvdb_id']:
ID = item.infoLabels['tvdb_id']
dict_renumerate = {TAG_ID: ID}
dict_series[title] = dict_renumerate
# Trova la Stagione
if any( word in title.lower() for word in ['specials', 'speciali'] ):
heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for specials)
season = platformtools.dialog_numeric(0, heading, '0')
dict_renumerate[TAG_SEASON] = season
elif RepresentsInt(title.split()[-1]):
heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for season > 1)
season = platformtools.dialog_numeric(0, heading, title.split()[-1])
dict_renumerate[TAG_SEASON] = season
else:
heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for season 1)
season = platformtools.dialog_numeric(0, heading, '1')
dict_renumerate[TAG_SEASON] = season
mode = platformtools.dialog_yesno(config.get_localized_string(70687), config.get_localized_string(70688), nolabel=config.get_localized_string(30023), yeslabel=config.get_localized_string(30022))
if mode == True:
dict_renumerate[TAG_MODE] = False
if TAG_SPECIAL in dict_series[title]:
specials = dict_renumerate[TAG_SPECIAL]
else:
specials = []
write(item, dict_series)
_list = []
itemlist = find_episodes(item)
for item in itemlist:
Title = re.sub(r'\d+x\d+ - ', '', item.title)
if item.action == 'findvideos':
_list.append(Title)
selected = platformtools.dialog_multiselect(config.get_localized_string(70734), _list)
# if len(selected) > 0:
for select in selected:
specials.append(int(scrapertools.find_single_match(_list[select], r'(\d+)')))
dict_renumerate[TAG_SPECIAL] = specials
dict_renumerate[TAG_MODE] = False
dict_renumerate[TAG_TYPE] = 'auto'
dict_renumerate[TAG_EPISODE] = ''
write(item, dict_series)
# xbmc.executebuiltin("Container.Refresh")
else:
message = config.get_localized_string(60444)
heading = item.fulltitle.strip()
platformtools.dialog_notification(heading, message)
def renumeration (itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title, Type):
# Se ID è 0 salta la rinumerazione
if ID == '0':
return itemlist
# Numerazione per gli Speciali
elif Season == '0':
EpisodeDict = {}
for item in itemlist:
if config.get_localized_string(30992) not in item.title:
number = scrapertools.find_single_match(item.title, r'\d+')
item.title = typo('0x' + number + ' - ', typography) + item.title
# Usa la lista degli Episodi se esiste nel Json
elif Episode:
EpisodeDict = json.loads(base64.b64decode(Episode))
# Controlla che la lista egli Episodi sia della stessa lunghezza di Itemlist
if EpisodeDict == 'none':
return error(itemlist)
if Type == 'manual' and len(EpisodeDict) < len(itemlist):
EpisodeDict = manual_renumeration(item, True)
if len(EpisodeDict) >= len(itemlist) and scrapertools.find_single_match(itemlist[0].title, r'\d+') in EpisodeDict:
for item in itemlist:
if config.get_localized_string(30992) not in item.title:
number = scrapertools.find_single_match(item.title, r'\d+')
number = int(number) # if number !='0': number.lstrip('0')
item.title = typo(EpisodeDict[str(number)] + ' - ', typography) + item.title
else:
make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title)
else:
make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title)
def manual_renumeration(item, modify=False):
logger.info()
_list = []
if item.from_channel: item.channel = item.from_channel
title = item.fulltitle.rstrip()
dict_series = load(item)
if title not in dict_series: dict_series[title] = {}
if TAG_EPISODE in dict_series[title] and dict_series[title][TAG_EPISODE]:
EpisodeDict = json.loads(base64.b64decode(dict_series[title][TAG_EPISODE]))
del dict_series[title][TAG_EPISODE]
else: EpisodeDict = {}
if TAG_EPLIST in dict_series[title]: del dict_series[title][TAG_EPLIST]
if TAG_MODE in dict_series[title]: del dict_series[title][TAG_MODE]
if TAG_CHECK in dict_series[title]: del dict_series[title][TAG_CHECK]
if TAG_SEASON in dict_series[title]: del dict_series[title][TAG_SEASON]
if TAG_SPECIAL in dict_series[title]: del dict_series[title][TAG_SPECIAL]
dict_series[title][TAG_TYPE] = 'manual'
write(item, dict_series)
if TAG_ID not in dict_series[title] or (TAG_ID in dict_series[title] and not dict_series[title][TAG_ID]):
tvdb.find_and_set_infoLabels(item)
# Trova l'ID della serie
while not item.infoLabels['tvdb_id']:
try:
item.show = platformtools.dialog_input(default=item.show, heading=config.get_localized_string(30112)) # <- Enter title to search
tvdb.find_and_set_infoLabels(item)
except:
heading = config.get_localized_string(70704) # <- TMDB ID (0 to cancel)
info = platformtools.dialog_numeric(0, heading)
item.infoLabels['tvdb_id'] = '0' if info == '' else info
if item.infoLabels['tvdb_id']:
ID = item.infoLabels['tvdb_id']
dict_renumerate = {TAG_ID: ID}
dict_series[title] = dict_renumerate
itemlist = find_episodes(item)
for it in itemlist:
Title = re.sub(r'\d+x\d+ - ', '', it.title)
if modify == True:
ep = int(scrapertools.find_single_match(Title, r'(\d+)'))
if it.action == 'findvideos' and str(ep) not in EpisodeDict:
_list.append(Title)
else:
if it.action == 'findvideos':
_list.append(Title)
count = 1
preselect = platformtools.dialog_select(config.get_localized_string(70732),[typo(config.get_localized_string(70518),'bold'),typo(config.get_localized_string(70519),'bold')])
selection = []
if preselect == 0:
for i in _list:
selection.append(_list.index(i))
while len(_list) > 0:
selected = platformtools.dialog_multiselect(config.get_localized_string(70734), _list, preselect=selection)
if selected == None: break
season = ''
while not season:
season = platformtools.dialog_numeric(0, config.get_localized_string(70733))
count = int(platformtools.dialog_numeric(0, config.get_localized_string(70733)))
for select in selected:
ep = int(scrapertools.find_single_match(_list[select], r'(\d+)'))
if season == '0':
episode = ''
while not episode:
episode = platformtools.dialog_numeric(0, config.get_localized_string(70735) % _list[select] )
EpisodeDict[str(ep)] = '%sx%s' %(season, episode.zfill(2))
else:
EpisodeDict[str(ep)] = '%sx%s' %(season, str(count).zfill(2))
count += 1
for select in reversed(selected):
del _list[select]
dict_series[title][TAG_TYPE] = 'manual'
EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode())
dict_series[title][TAG_EPISODE] = EpisodeDict.decode()
write(item, dict_series)
# xbmc.executebuiltin("Container.Refresh")
if modify == True:
return json.loads(base64.b64decode(EpisodeDict))
def delete_renumeration(item):
logger.info()
if item.from_channel: item.channel = item.from_channel
title = item.fulltitle.rstrip()
dict_series = load(item)
if title in dict_series: del dict_series[title]
write(item, dict_series)
def make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title):
logger.info()
exist = True
item.infoLabels['tvdb_id'] = ID
tvdb.set_infoLabels_item(item)
FirstOfSeason= 0
EpisodeDict = json.loads(base64.b64decode(Episode)) if Episode else {}
Special = dict_series[title][TAG_SPECIAL] if TAG_SPECIAL in dict_series[title] else []
EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST])) if TAG_EPLIST in dict_series[title] else []
Pages = dict_series[title][TAG_CHECK] if TAG_CHECK in dict_series[title] else [1]
# Ricava Informazioni da TVDB
checkpages = []
check = True
Page = Pages[-1]
while exist:
if check:
for page in Pages:
data = tvdb.otvdb_global.get_list_episodes(ID,page)
logger.info('DATA',data)
for episodes in data['data']:
if episodes['firstAired'] and [episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']] not in EpList:
EpList.append([episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']])
else:
if page not in checkpages:
checkpages.append(page)
check = False
data = tvdb.otvdb_global.get_list_episodes(ID,Page)
if data:
Page = Page + 1
for episodes in data['data']:
if episodes['firstAired'] and [episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']] not in EpList:
EpList.append([episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']])
else:
if page not in checkpages:
checkpages.append(Page -1)
exist = False
EpList.sort()
dict_series[title][TAG_CHECK] = checkpages
EpList = base64.b64encode(json.dumps(EpList).encode())
dict_series[title][TAG_EPLIST] = EpList.decode()
write(item, dict_series)
# Crea Dizionari per la numerazione
if EpList:
EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST]))
specials = []
regular = {}
complete = {}
allep = 1
ep = 1
specialep = 0
for episode in EpList:
complete[allep] = [str(episode[1]) + 'x' + str(episode[2]), episode[0]]
if episode[1] == 0:
specials.append(allep)
specialep = specialep + 1
else:
regular[ep] = [str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1]
ep = ep + 1
allep = allep + 1
# seleziona l'Episodio di partenza
if int(Season) > 1:
for numbers, data in regular.items():
if data[0] == Season + 'x1':
FirstOfSeason = numbers - 1
if Mode == True: Special = specials
addiction = 0
for item in itemlist:
# Otiene Numerazione Episodi
scraped_ep = scrapertools.find_single_match(re.sub(r'\[[^\]]+\]','',item.title), r'\d+')
if scraped_ep:
episode = int(scraped_ep)
number = episode + FirstOfSeason - addiction
count = number + addiction
# Crea Dizionario Episodi
if episode == 0:
EpisodeDict[str(episode)] = str(complete[regular[FirstOfSeason+1][2]][0])
elif addiction < len(Special):
if episode in Special:
try:
season = complete[regular[count][2]][0]
EpisodeDict[str(episode)] = str(complete[regular[count][2]][0]) if season.startswith( '0' ) else '0x' + platformtools.dialog_numeric(0, item.title + '?', '')
except:
EpisodeDict[str(episode)] = '0x' + platformtools.dialog_numeric(0, item.title + '?', '')
addiction = addiction + 1
elif number <= len(regular):
EpisodeDict[str(episode)] = str(regular[number][0])
else:
try: EpisodeDict[str(episode)] = str(complete[regular[number+2][2]][0])
except: EpisodeDict[str(episode)] = '0x0'
elif number <= len(regular) and number in regular:
EpisodeDict[str(episode)] = str(regular[number][0])
else:
try: EpisodeDict[str(episode)] = str(complete[regular[number+2][2]][0])
except: EpisodeDict[str(episode)] = '0x0'
# Aggiunge numerazione agli Episodi
item.title = typo(EpisodeDict[str(episode)] + ' - ', typography) + item.title
# Scrive Dizionario Episodi sul json
EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode())
dict_series[title][TAG_EPISODE] = EpisodeDict.decode()
write(item, dict_series)
else:
heading = config.get_localized_string(70704)
ID = platformtools.dialog_numeric(0, heading)
dict_series[title][TAG_ID] = ID
write(item, dict_series)
if ID == '0':
return itemlist
else:
return make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title)
def check(item):
logger.info()
dict_series = load(item)
title = item.fulltitle.rstrip()
if title in dict_series: title = dict_series[title]
return True if TAG_ID in title and TAG_EPISODE in title else False
def error(itemlist):
message = config.get_localized_string(70713)
heading = itemlist[0].fulltitle.strip()
platformtools.dialog_notification(heading, message)
return itemlist
def find_episodes(item):
logger.info()
ch = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel])
itemlist = ch.episodios(item)
return itemlist
def RepresentsInt(s):
# Controllo Numro Stagione
logger.info()
try:
int(s)
return True
except ValueError:
return False
def access():
allow = False
if config.is_xbmc():
allow = True
return allow
def context(exist):
if access():
modify = config.get_localized_string(70714) if exist else ''
_context = [{"title": typo(modify + config.get_localized_string(70585), 'bold'),
"action": "select_type",
"channel": "autorenumber",}]
return _context
def select_type(item):
select = platformtools.dialog_select(config.get_localized_string(70730),[typo(config.get_localized_string(70731),'bold'), typo(config.get_localized_string(70732),'bold'), typo(config.get_localized_string(707433),'bold')])
if select == 0: semiautomatic_config_item(item)
elif select == 1: manual_renumeration(item)
elif select == 2: return delete_renumeration(item)
else: return
def filename(item):
logger.info()
name_file = item.channel + "_data.json"
path = filetools.join(config.get_data_path(), "settings_channels")
fname = filetools.join(path, name_file)
return fname
def load(item):
logger.info()
try:
json_file = open(filename(item), "r").read()
json = jsontools.load(json_file)[TAG_TVSHOW_RENUMERATE]
except:
json = {}
return json
def write(item, json):
logger.info()
json_file = open(filename(item), "r").read()
js = jsontools.load(json_file)
js[TAG_TVSHOW_RENUMERATE] = json
with open(filename(item), "w") as file:
file.write(jsontools.dump(js))
file.close()

96
platformcode/backup.py Normal file
View File

@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# Backup and restore video library
# ------------------------------------------------------------
import datetime, xbmc
from core import ziptools, videolibrarytools, filetools
from platformcode import logger, config, platformtools, xbmc_videolibrary
from distutils.dir_util import copy_tree
from specials import videolibrary
temp_path = u'' + xbmc.translatePath("special://userdata/addon_data/plugin.video.kod/temp/")
movies_path = u'' + filetools.join(temp_path, "movies")
tvshows_path = u'' + filetools.join(temp_path, "tvshows")
videolibrary_movies_path = u'' + videolibrarytools.MOVIES_PATH
videolibrary_tvshows_path = u'' + videolibrarytools.TVSHOWS_PATH
def export_videolibrary(item):
logger.info()
zip_file_folder = platformtools.dialog_browse(3, config.get_localized_string(80002))
if zip_file_folder == "":
return
zip_file = u'' + xbmc.translatePath(zip_file_folder + "KoD_video_library-" + str(datetime.date.today()) + ".zip")
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80003))
p_dialog.update(0)
if filetools.exists(temp_path):
filetools.rmdirtree(temp_path)
filetools.mkdir(temp_path)
p_dialog.update(25)
filetools.mkdir(movies_path)
copy_tree(videolibrary_movies_path, movies_path)
p_dialog.update(50)
filetools.mkdir(tvshows_path)
copy_tree(videolibrary_tvshows_path, tvshows_path)
p_dialog.update(75)
zipper = ziptools.ziptools()
zipper.zip(temp_path, zip_file)
filetools.rmdirtree(temp_path)
p_dialog.update(100)
xbmc.sleep(1000)
p_dialog.close()
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80004), time=5000, sound=False)
def import_videolibrary(item):
logger.info()
zip_file = u'' + platformtools.dialog_browse(1, config.get_localized_string(80005), mask=".zip")
if zip_file == "":
return
if not platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(80006)):
return
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80007))
p_dialog.update(0)
if filetools.exists(temp_path):
filetools.rmdirtree(temp_path)
filetools.mkdir(temp_path)
unzipper = ziptools.ziptools()
unzipper.extract(zip_file, temp_path)
p_dialog.update(20)
if config.is_xbmc() and config.get_setting("videolibrary_kodi"):
xbmc_videolibrary.clean()
p_dialog.update(30)
filetools.rmdirtree(videolibrary_movies_path)
filetools.rmdirtree(videolibrary_tvshows_path)
p_dialog.update(50)
config.verify_directories_created()
if filetools.exists(movies_path):
copy_tree(movies_path, videolibrary_movies_path)
p_dialog.update(70)
if filetools.exists(tvshows_path):
copy_tree(tvshows_path, videolibrary_tvshows_path)
p_dialog.update(90)
filetools.rmdirtree(temp_path)
p_dialog.update(100)
xbmc.sleep(1000)
p_dialog.close()
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80008), time=5000, sound=False)
videolibrary.update_videolibrary()
if config.is_xbmc() and config.get_setting("videolibrary_kodi"):
xbmc_videolibrary.update()

297
platformcode/checkhost.py Normal file
View File

@@ -0,0 +1,297 @@
# -*- coding: utf-8 -*-
import xbmc, xbmcgui
import xbmcaddon
import json
from platformcode import config, logger
import requests
import sys
if sys.version_info[0] >= 3:
from lib.httplib2 import py3 as httplib2
else:
from lib.httplib2 import py2 as httplib2
import socket
addon = xbmcaddon.Addon()
addonname = addon.getAddonInfo('name')
addonid = addon.getAddonInfo('id')
LIST_SITE = ['http://www.ansa.it/', 'https://www.google.it']#, 'https://www.google.com']
# list of sites that will not be reached with the manager's DNS
LST_SITE_CHCK_DNS = ['https://www.casacinema.me/', 'https://cb01-nuovo-indirizzo.info/']
#'https://www.italia-film.pw', 'https://www.cb01.uno/',] # tolti
class Kdicc():
def __init__(self, is_exit = True, check_dns = True, view_msg = True,
lst_urls = [], lst_site_check_dns = [], in_addon = False):
self.ip_addr = xbmc.getIPAddress()
self.dns = [xbmc.getInfoLabel('Network.DNS1Address'),
xbmc.getInfoLabel('Network.DNS2Address')]
self.check_dns = check_dns
self.is_exit = is_exit
self.lst_urls = lst_urls
self.view_msg = view_msg
self.lst_site_check_dns = lst_site_check_dns
self.urls = []
#logger.info("check #### INIZIO INIT#### ")
def check_Ip(self):
"""
check the ip
if ip_addr = 127.0.0.1 or ip_addr = '' then the device does not is connected to the modem/router
return: bool
"""
if self.ip_addr == '127.0.0.1' or self.ip_addr == '':
return False
else:
return True
def check_Adsl(self):
"""
check if the device reaches the sites
"""
urls = LIST_SITE
r = self.rqst(urls)
http_errr = 0
for rslt in r:
logger.info("check_Adsl rslt: %s" % rslt['code'])
# Errno -2 could be lack of adsl connection or unreachable site ....
# even in cases where there is a change of manager.
if rslt['code'] == '111' or '[Errno -3]' in str(rslt['code']) or 'Errno -2' in str(rslt['code']):
http_errr +=1
if len(LIST_SITE) == http_errr:
return False
else:
return True
def check_Dns(self):
"""
Control if DNS reaches certain sites
"""
if self.lst_site_check_dns == []:
urls = LST_SITE_CHCK_DNS
else:
urls = self.lst_site_check_dns
r = self.rqst(urls)
logger.info("check_Dns result: %s" % r)
http_errr = 0
for rslt in r:
logger.info("check_Dns rslt: %s" % rslt['code'])
if rslt['code'] == '111':
http_errr +=1
if len(LST_SITE_CHCK_DNS) == http_errr:
return False
else:
return True
def rqst(self, lst_urls):
"""
url must start with http(s):'
return : (esito, sito, url, code, reurl)
"""
rslt_final = []
if lst_urls == []:
lst_urls = self.lst_urls
for sito in lst_urls:
rslt = {}
try:
r = requests.head(sito, allow_redirects = True) #, timeout=7) # from error after lib insertion of httplib2
if r.url.endswith('/'):
r.url = r.url[:-1]
if str(sito) != str(r.url):
is_redirect = True
else:
is_redirect = False
rslt['code'] = r.status_code
rslt['url'] = str(sito)
rslt['rdrcturl'] = str(r.url)
rslt['isRedirect'] = is_redirect
rslt['history'] = r.history
logger.info("Risultato nel try: %s" % (r,))
except requests.exceptions.ConnectionError as conn_errr:
# Errno 10061 for s.o. win
# will the Errno 10xxx and 11xxx be to be compacted in any way?
# the errors are incorporated in code = '111' since at that moment
# they are not reached for any reason
if '[Errno 111]' in str(conn_errr) or 'Errno 10060' in str(conn_errr) \
or 'Errno 10061' in str(conn_errr) \
or '[Errno 110]' in str(conn_errr) \
or 'ConnectTimeoutError' in str(conn_errr) \
or 'Errno 11002' in str(conn_errr) or 'ReadTimeout' in str(conn_errr) \
or 'Errno 11001' in str(conn_errr) \
or 'Errno -2' in str(conn_errr): # this error is also in the code: -2
rslt['code'] = '111'
rslt['url'] = str(sito)
rslt['http_err'] = 'Connection error'
else:
rslt['code'] = conn_errr
rslt['url'] = str(sito)
rslt['http_err'] = 'Connection refused'
rslt_final.append(rslt)
return rslt_final
def http_Resp(self):
rslt = {}
for sito in self.lst_urls:
try:
s = httplib2.Http()
code, resp = s.request(sito, body=None)
if code.previous:
logger.info("r1 http_Resp: %s %s %s %s" %
(code.status, code.reason, code.previous['status'],
code.previous['-x-permanent-redirect-url']))
rslt['code'] = code.previous['status']
rslt['redirect'] = code.previous['-x-permanent-redirect-url']
rslt['status'] = code.status
else:
rslt['code'] = code.status
except httplib2.ServerNotFoundError as msg:
# both for lack of ADSL and for non-existent sites
rslt['code'] = -2
except socket.error as msg:
# for unreachable sites without correct DNS
# [Errno 111] Connection refused
rslt['code'] = 111
except:
rslt['code'] = 'Connection error'
return rslt
def view_Advise(self, txt = '' ):
"""
Notice per user testConnected
"""
ip = self.check_Ip()
if ip:
txt += '\nIP: %s\n' % self.ip_addr
txt += '\nDNS: %s\n' % (self.dns)
else:
txt += '\nIP: %s' % self.ip_addr
dialog = xbmcgui.Dialog()
if config.get_setting('checkdns'):
risposta= dialog.yesno(addonname, txt, nolabel=config.get_localized_string(707403), yeslabel=config.get_localized_string(707404))
if risposta == False:
config.set_setting('checkdns', False)
dialog.textviewer(addonname+' '+config.get_localized_string(707405), config.get_localized_string(707406))
else:
txt = config.get_localized_string(707402)
dialog.notification(addonname, txt, xbmcgui.NOTIFICATION_INFO, 10000)
"""
def called in launcher.py
"""
def test_conn(is_exit, check_dns, view_msg,
lst_urls, lst_site_check_dns, in_addon):
ktest = Kdicc(is_exit, check_dns, view_msg, lst_urls, lst_site_check_dns, in_addon)
# if it does not have the IP, I will communicate it to the user
if not ktest.check_Ip():
# I don't let you get into the addon
# enter language code
if view_msg == True:
ktest.view_Advise(config.get_localized_string(70720))
if ktest.is_exit == True:
exit()
# if it has no ADSL connection, I will communicate it to the user
if not ktest.check_Adsl():
if view_msg == True:
ktest.view_Advise(config.get_localized_string(70721))
if ktest.is_exit == True:
exit()
# if it has DNS filtered, I will communicate it to the user
if check_dns == True:
if not ktest.check_Dns():
if view_msg == True:
ktest.view_Advise(config.get_localized_string(70722))
logger.info("############ Start Check DNS ############")
logger.info("## IP: %s" % (ktest.ip_addr))
logger.info("## DNS: %s" % (ktest.dns))
logger.info("############# End Check DNS #############")
# if check_dns == True:
# if ktest.check_Ip() == True and ktest.check_Adsl() == True and ktest.check_Dns() == True:
# return True
# else:
# return False
# else:
# if ktest.check_Ip() == True and ktest.check_Adsl() == True:
# return True
# else:
# return False
# def for creating the channels.json file
def check_channels(inutile=''):
"""
I read the channel hosts from the channels.json file, I check them,
I write the channels-test.json file with the error code and the new url in case of redirect
urls MUST have http (s)
During the urls check the ip, asdl and dns checks are carried out.
This is because it can happen that at any time the connection may have problems. If it does, check it
relative writing of the file is interrupted with a warning message
"""
logger.info()
folderJson = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('path')).decode('utf-8')
fileJson = 'channels.json'
with open(folderJson+'/'+fileJson) as f:
data = json.load(f)
risultato = {}
for chann, host in sorted(data.items()):
ris = []
# 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))
rslt = Kdicc(lst_urls = [host]).http_Resp()
# all right
if rslt['code'] == 200:
risultato[chann] = host
# redirect
elif str(rslt['code']).startswith('3'):
# risultato[chann] = str(rslt['code']) +' - '+ rslt['redirect'][:-1]
if rslt['redirect'].endswith('/'):
rslt['redirect'] = rslt['redirect'][:-1]
risultato[chann] = rslt['redirect']
# non-existent site
elif rslt['code'] == -2:
risultato[chann] = 'Host Sconosciuto - '+ str(rslt['code']) +' - '+ host
# site not reachable - probable dns not set
elif rslt['code'] == 111:
risultato[chann] = ['Host non raggiungibile - '+ str(rslt['code']) +' - '+ host]
else:
# other types of errors
# risultato[chann] = 'Errore Sconosciuto - '+str(rslt['code']) +' - '+ host
risultato[chann] = host
logger.info("check #### FINE #### rslt :%s " % (rslt))
fileJson_test = 'channels-test.json'
# I write the updated file
with open(folderJson+'/'+fileJson_test, 'w') as f:
data = json.dump(risultato, f, sort_keys=True, indent=4)
logger.info(data)

View File

@@ -76,7 +76,7 @@ def get_platform(full_version=False):
code_db = {'10': 'MyVideos37.db', '11': 'MyVideos60.db', '12': 'MyVideos75.db',
'13': 'MyVideos78.db', '14': 'MyVideos90.db', '15': 'MyVideos93.db',
'16': 'MyVideos99.db', '17': 'MyVideos107.db', '18': 'MyVideos116.db',
'19': 'MyVideos116.db'}
'19': 'MyVideos119.db'}
num_version = xbmc.getInfoLabel('System.BuildVersion')
num_version = re.match("\d+\.\d+", num_version).group(0)
@@ -134,9 +134,10 @@ def get_system_platform():
platform = "osx"
return platform
def is_autorun_enabled():
try:
if "xbmc.executebuiltin('XBMC.RunAddon(plugin.video.kod)')" in open(os.path.join(xbmc.translatePath('special://userdata'),'autoexec.py')).read():
if "xbmc.executebuiltin('RunAddon(plugin.video.kod)')" in open(os.path.join(xbmc.translatePath('special://userdata'),'autoexec.py')).read():
return True
else:
return False
@@ -153,12 +154,12 @@ def enable_disable_autorun(is_enabled):
if is_enabled is False:
with open(path, append_write) as file:
file.write("import xbmc\nxbmc.executebuiltin('XBMC.RunAddon(plugin.video.kod)')")
file.write("import xbmc\nxbmc.executebuiltin('RunAddon(plugin.video.kod)')")
set_setting('autostart', 'On')
else:
file = open(path, "r")
old_content = file.read()
new_content = old_content.replace("xbmc.executebuiltin('XBMC.RunAddon(plugin.video.kod)')", "")
new_content = old_content.replace("xbmc.executebuiltin('RunAddon(plugin.video.kod)')", "")
file.close()
with open(path, "w") as file:
file.write(new_content)

View File

@@ -41,7 +41,7 @@ def download_and_play(url, file_name, download_path):
dialog.update(0)
while not cancelled and download_thread.isAlive():
dialog.update(download_thread.get_progress(), config.get_localized_string(60313),
dialog.update(download_thread.get_progress(), config.get_localized_string(60313) + '\n' +
config.get_localized_string(60314) + str(int(old_div(download_thread.get_speed(), 1024))) + " KB/s " + str(
download_thread.get_actual_size()) + config.get_localized_string(60316) + str( download_thread.get_total_size()) + "MB",
config.get_localized_string(60202) % (str(downloadtools.sec_to_hms(download_thread.get_remaining_time()))))
@@ -286,7 +286,7 @@ class DownloadThread(threading.Thread):
logger.info("Force_stop file detected, download is interrupted")
f.close()
xbmc.executebuiltin("XBMC.Notification(%s,%s,300)" % (config.get_localized_string(60319),config.get_localized_string(60320)))
xbmc.executebuiltin("Notification(%s,%s,300)" % (config.get_localized_string(60319),config.get_localized_string(60320)))
return

View File

@@ -0,0 +1,135 @@
from core import filetools, downloadtools, support
from platformcode import config, platformtools, updater
import xbmc, xbmcaddon, sys, platform
host = 'https://github.com'
elementum_url = host + '/elgatito/plugin.video.elementum/releases'
filename = filetools.join(config.get_data_path(),'elementum.zip')
addon_path = xbmc.translatePath('special://home/addons/')
setting_path = xbmc.translatePath('special://profile/addon_data/')
elementum_path = filetools.join(addon_path,'plugin.video.elementum')
elementum_setting = filetools.join(setting_path,'plugin.video.elementum')
elementum_setting_file = filetools.join(elementum_setting,'settings.xml')
kod_setting_file = filetools.join(addon_path,'plugin.video.kod', 'resources', 'settings', 'elementum', 'settings.xml')
def download(item=None):
if filetools.exists(elementum_path):
if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70783)):
setting()
platformtools.dialog_ok('Elementum', config.get_localized_string(70783))
else:
if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70782)):
pform = get_platform()
url = support.match(elementum_url, patronBlock=r'<div class="release-entry">(.*?)<!-- /.release-body -->', patron=r'<a href="([a-zA-Z0-9/\.-]+%s.zip)' % pform).match
support.info('OS:', pform)
support.info('Extract IN:', elementum_path)
support.info('URL:', url)
if url:
downloadtools.downloadfile(host + url, filename)
extract()
xbmc.sleep(1000)
setting()
def extract():
import zipfile
from platformcode.updater import fixZipGetHash
support.info('Estraggo Elementum in:', elementum_path)
try:
hash = fixZipGetHash(filename)
support.info(hash)
with zipfile.ZipFile(filetools.file_open(filename, 'rb', vfs=False)) as zip_ref:
zip_ref.extractall(xbmc.translatePath(addon_path))
except Exception as e:
support.info('Non sono riuscito ad estrarre il file zip')
support.logger.error(e)
import traceback
support.logger.error(traceback.print_exc())
def setting():
# support.dbg()
xbmc.executebuiltin('UpdateLocalAddons')
xbmc.sleep(1000)
if filetools.isfile(elementum_setting_file):
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "plugin.video.elementum", "enabled": true }}')
Continue = True
while Continue:
try:
__settings__ = xbmcaddon.Addon(id="plugin.video.elementum")
__settings__.setSetting('skip_burst_search', 'true')
__settings__.setSetting('greeting_enabled', 'false')
__settings__.setSetting('do_not_disturb', 'true')
Continue = False
except:
support.info('RIPROVO')
xbmc.sleep(100)
else:
if not filetools.exists(elementum_path):
filetools.mkdir(elementum_path)
filetools.copy(kod_setting_file, elementum_setting_file)
xbmc.sleep(1000)
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "plugin.video.elementum", "enabled": true }}')
updater.refreshLang()
if filetools.exists(filename):
filetools.remove(filename)
def get_platform():
build = xbmc.getInfoLabel("System.BuildVersion")
kodi_version = int(build.split()[0][:2])
ret = {
"auto_arch": sys.maxsize > 2 ** 32 and "64-bit" or "32-bit",
"arch": sys.maxsize > 2 ** 32 and "x64" or "x86",
"os": "",
"version": platform.release(),
"kodi": kodi_version,
"build": build
}
if xbmc.getCondVisibility("system.platform.android"):
ret["os"] = "android"
if "arm" in platform.machine() or "aarch" in platform.machine():
ret["arch"] = "arm"
if "64" in platform.machine() and ret["auto_arch"] == "64-bit":
ret["arch"] = "arm64"
elif xbmc.getCondVisibility("system.platform.linux"):
ret["os"] = "linux"
if "aarch" in platform.machine() or "arm64" in platform.machine():
if xbmc.getCondVisibility("system.platform.linux.raspberrypi"):
ret["arch"] = "armv7"
elif ret["auto_arch"] == "32-bit":
ret["arch"] = "armv7"
elif ret["auto_arch"] == "64-bit":
ret["arch"] = "arm64"
elif platform.architecture()[0].startswith("32"):
ret["arch"] = "arm"
else:
ret["arch"] = "arm64"
elif "armv7" in platform.machine():
ret["arch"] = "armv7"
elif "arm" in platform.machine():
ret["arch"] = "arm"
elif xbmc.getCondVisibility("system.platform.xbox"):
ret["os"] = "windows"
ret["arch"] = "x64"
elif xbmc.getCondVisibility("system.platform.windows"):
ret["os"] = "windows"
if platform.machine().endswith('64'):
ret["arch"] = "x64"
elif xbmc.getCondVisibility("system.platform.osx"):
ret["os"] = "darwin"
ret["arch"] = "x64"
elif xbmc.getCondVisibility("system.platform.ios"):
ret["os"] = "ios"
ret["arch"] = "arm"
return ret['os'] + '_' + ret['arch']

View File

@@ -25,7 +25,7 @@ from platformcode import logger, config, platformtools
def get_environment():
"""
Returns the most common OS, Kodi and Alpha environment variables,
    necessary for fault diagnosis
necessary for fault diagnosis
"""
try:
@@ -341,9 +341,6 @@ def list_env(environment={}):
if not environment:
environment = get_environment()
if environment['debug'] == 'False':
logger.log_enable(True)
logger.info(sep)
logger.info('KoD environment variables: ' + environment['addon_version'] + ' Debug: ' + environment['debug'])
logger.info(sep)
@@ -399,9 +396,6 @@ def list_env(environment={}):
logger.info('LOG Size: ' + environment['log_size'].replace('.', ',') + ' MB')
logger.info(sep)
if environment['debug'] == 'False':
logger.log_enable(False)
return environment

549
platformcode/infoplus.py Normal file
View File

@@ -0,0 +1,549 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# infoplus window with item information
# ------------------------------------------------------------
import xbmc, xbmcgui, sys, requests, re
from core import support, tmdb, filetools, channeltools, servertools
from core.item import Item
from platformcode import config, platformtools
from platformcode.logger import log
from core.scrapertools import decodeHtmlentities, htmlclean
PY3 = False
if sys.version_info[0] >= 3: PY3 = True
if PY3: from concurrent import futures
else: from concurrent_py2 import futures
info_list = []
SearchWindows = []
api = 'k_0tdb8a8y'
# Control ID
FANART = 30000
NUMBER = 30001
TITLE = 30002
TAGLINE = 30003
PLOT = 30004
RATING_ICON = 30005
RATING = 30006
TRAILER = 30007
SEARCH = 30008
NEXT = 30009
PREVIOUS = 30010
LOADING = 30011
COMMANDS = 30012
RECOMANDED = TRAILERS = 30500
ACTORS = 30501
CAST = 30502
# Actions
LEFT = 1
RIGHT = 2
UP = 3
DOWN = 4
EXIT = 10
BACKSPACE = 92
def Main(item):
if type(item) == Item:
item.channel = item.from_channel
global ITEM
ITEM = item
Info = xbmcgui.ListItem(item.infoLabels['title'])
for key, value in item.infoLabels.items():
Info.setProperty(key, str(value))
else:
Info = item
main = MainWindow('InfoPlus.xml', config.get_runtime_path())
add({'class':main, 'info':Info, 'id':RECOMANDED, RECOMANDED:0, ACTORS:0})
modal()
class MainWindow(xbmcgui.WindowXMLDialog):
def __init__(self, *args, **kwargs):
self.items = []
self.cast = []
self.actors = []
self.ids = {}
def onInit(self):
#### Compatibility with Kodi 18 ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
if Info.getProperty('id'):self.items = get_movies(Info)
else: self.items = get_recomendations(Info)
self.cast, self.actors = get_cast(Info)
self.getControl(LOADING).setVisible(False)
self.getControl(RECOMANDED).addItems(self.items)
self.getControl(FANART).setImage(Info.getProperty('fanart'))
self.getControl(ACTORS).addItems(self.actors)
if self.cast:
self.getControl(CAST).setVisible(True)
self.getControl(CAST).addItems(self.cast)
else:
self.getControl(CAST).setVisible(False)
if Info.getProperty('rating'): rating = str(Info.getProperty('rating'))
else: rating = 'N/A'
self.getControl(RATING).setText(rating)
getFocus(self)
def onClick(self, control_id):
setFocus(self)
if control_id in [SEARCH]:
title = self.getControl(RECOMANDED).getSelectedItem().getProperty('title')
mode = self.getControl(RECOMANDED).getSelectedItem().getProperty('mediatype')
self.close()
if self.getControl(RECOMANDED).getSelectedPosition() > 0:
Search(ITEM.clone(action='search', search_text=title))
else:
Search(ITEM.clone(channel='search', action='new_search', search_text=title, mode=mode))
elif control_id in [TRAILER]:
info = self.getControl(RECOMANDED).getSelectedItem()
self.close()
Trailer(info)
elif control_id in [ACTORS, CAST]:
self.close()
Main(self.getControl(self.getFocusId()).getSelectedItem())
elif control_id in [RECOMANDED] and self.getControl(RECOMANDED).getSelectedPosition() > 0:
self.close()
Main(self.getControl(RECOMANDED).getSelectedItem())
def onAction(self, action):
if self.getFocusId() in [ACTORS, RECOMANDED]:
self.ids[self.getFocusId()] = self.getControl(self.getFocusId()).getSelectedPosition()
if self.getFocusId() in [ACTORS, CAST] and action not in [BACKSPACE, EXIT]:
actors_more_info(self.getControl(self.getFocusId()).getSelectedItem())
if self.getFocusId() in [RECOMANDED]:
fanart = self.getControl(self.getFocusId()).getSelectedItem().getProperty('fanart')
rating = self.getControl(self.getFocusId()).getSelectedItem().getProperty('rating')
if not rating: rating = 'N/A'
self.getControl(FANART).setImage(fanart)
self.getControl(RATING).setText(rating)
cast, actors = get_cast(self.getControl(self.getFocusId()).getSelectedItem())
self.getControl(ACTORS).reset()
self.getControl(ACTORS).addItems(actors)
self.getControl(CAST).reset()
self.getControl(CAST).addItems(cast)
action = action.getId()
if action in [BACKSPACE]:
self.close()
remove()
modal()
elif action in [EXIT]:
self.close()
def Search(item):
if item.action == 'findvideos': XML = 'ServersWindow.xml'
else: XML = 'SearchWindow.xml'
global Info
Info = item
main = SearchWindow(XML, config.get_runtime_path())
add({'class':main, 'info':item, 'id':RECOMANDED})
modal()
class SearchWindow(xbmcgui.WindowXMLDialog):
def __init__(self, *args, **kwargs):
self.items = []
self.itemlist = []
self.commands = []
self.ids = {}
self.channel = None
def onInit(self):
#### Compatibility with Kodi 18 ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
if len(self.items) == 0:
if Info.action == 'new_search' and Info.mode:
from specials.search import new_search
itemlist = new_search(Info)
elif Info.action == 'channel_search':
from specials.search import channel_search
itemlist = channel_search(Info)
else:
self.channel = __import__('channels.%s' % Info.channel, fromlist=["channels.%s" % Info.channel])
if Info.action == 'search': itemlist = getattr(self.channel, 'search')(Info, Info.search_text)
else: itemlist = getattr(self.channel, Info.action)(Info)
if not itemlist:
if platformtools.dialog_yesno(config.get_localized_string(60473), config.get_localized_string(70820) % Info.channel):
remove()
self.close()
return Search(Info.clone(mode=Info.infoLabels['mediatype']))
else:
remove()
self.close()
modal()
for item in itemlist:
if item.action not in ['save_download', 'add_pelicula_to_library', 'add_serie_to_library', ''] and item.infoLabels['title']:
if item.action == 'findvideos' and item.contentType in ['episode', 'tvshow']:
it = xbmcgui.ListItem(re.sub(r'\[[^\]]+\]', '', item.title))
self.getControl(NUMBER).setText(support.typo(config.get_localized_string(70362),'uppercase bold'))
else:
it = xbmcgui.ListItem(item.infoLabels['title'])
it.setProperty('channel', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('action', item.action)
it.setProperty('server', servertools.get_server_parameters(item.server.lower()).get('name',item.server))
it.setProperty('url', item.url)
for key, value in item.infoLabels.items():
it.setProperty(key, str(value))
if item.action == 'play':
it.setProperty('thumbnail', "https://raw.githubusercontent.com/kodiondemand/media/master/resources/servers/%s.png" % item.server.lower())
self.items.append(it)
self.itemlist.append(item)
if itemlist[0].contentType == 'movie':
if not itemlist[0].server:
self.commands.append(itemlist[0].clone(action='add_pelicula_to_library', thumbnail=support.thumb('add_to_videolibrary')))
self.commands.append(itemlist[0].clone(channel='downloads', action='save_download', from_channel=itemlist[0].channel, from_action=itemlist[0].action, thumbnail=support.thumb('downloads')))
else:
self.commands.append(Info.clone(channel='downloads', action='save_download', from_channel=Info.channel, from_action=Info.action, thumbnail=support.thumb('downloads')))
if itemlist[0].contentType in ['tvshow', 'episode']:
if not itemlist[0].server:
self.commands.append(itemlist[0].clone(action='add_serie_to_library', thumbnail=support.thumb('add_to_videolibrary')))
self.commands.append(itemlist[0].clone(channel='downloads', action='save_download', from_channel=itemlist[0].channel, from_action=itemlist[0].action, thumbnail=support.thumb('downloads')))
else:
self.commands.append(Info.clone(channel='downloads', action='save_download', from_channel=Info.channel, from_action=Info.action, thumbnail=support.thumb('downloads')))
if self.commands:
commands = []
for command in self.commands:
it = xbmcgui.ListItem(command.title)
path = filetools.join(config.get_runtime_path(),'resources','skins','Default','media','Infoplus',command.thumbnail.split('/')[-1].replace('thumb_',''))
it.setProperty('thumbnail',path)
commands.append(it)
self.getControl(COMMANDS).addItems(commands)
if self.items:
self.getControl(FANART).setImage(self.items[0].getProperty('fanart'))
self.getControl(RECOMANDED).addItems(self.items)
self.getControl(LOADING).setVisible(False)
getFocus(self)
def onClick(self, control_id):
setFocus(self)
if control_id == COMMANDS:
from platformcode.launcher import run
pos = self.getControl(COMMANDS).getSelectedPosition()
if self.commands[pos].action =='save_download' and self.commands[pos].contentType == 'tvshow':
actions = [self.commands[-1].clone(), self.commands[-1].clone(download='season')]
options = [config.get_localized_string(60355),config.get_localized_string(60357)]
run(actions[platformtools.dialog_select(config.get_localized_string(60498),options)])
else:
run(self.commands[pos])
else:
action = self.getControl(RECOMANDED).getSelectedItem().getProperty('action')
channel = self.getControl(RECOMANDED).getSelectedItem().getProperty('channel')
url = self.getControl(RECOMANDED).getSelectedItem().getProperty('url')
item = Item(channel=channel, action=action, url=url)
if action == 'play':
item.server = self.getControl(RECOMANDED).getSelectedItem().getProperty('server')
self.close()
platformtools.play_video(item)
xbmc.sleep(500)
while xbmc.Player().isPlaying():
xbmc.sleep(500)
modal()
elif config.get_setting('autoplay'):
item.quality = self.getControl(RECOMANDED).getSelectedItem().getProperty('quality')
getattr(self.channel, item.action)(item)
self.close()
xbmc.sleep(500)
while xbmc.Player().isPlaying():
xbmc.sleep(500)
modal()
else:
pos = self.getControl(RECOMANDED).getSelectedPosition()
self.close()
if self.itemlist[pos].mode: remove()
Search(self.itemlist[pos])
def onAction(self, action):
if self.getFocusId() in [RECOMANDED]:
fanart = self.getControl(self.getFocusId()).getSelectedItem().getProperty('fanart')
self.getControl(FANART).setImage(fanart)
action = action.getId()
if action in [BACKSPACE]:
self.close()
remove()
modal()
elif action in [EXIT]:
self.close()
def Trailer(info):
global info_list, trailers
trailers = []
trailers_list = []
Type = info.getProperty('mediatype')
if Type != "movie": Type = "tv"
trailers_list = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), tipo=Type).get_videos()
if trailers_list:
for i, trailer in enumerate(trailers_list):
item = xbmcgui.ListItem(trailer['name'])
item.setProperties({'tile':trailer['name'],
'url': trailer['url'],
'thumbnail': 'http://img.youtube.com/vi/' + trailer['url'].split('=')[-1] + '/0.jpg',
'fanart':info.getProperty('fanart'),
'position':'%s/%s' % (i + 1, len(trailers_list))})
trailers.append(item)
else: # TRY youtube search
patron = r'thumbnails":\[\{"url":"(https://i.ytimg.com/vi[^"]+).*?'
patron += r'text":"([^"]+).*?'
patron += r'simpleText":"[^"]+.*?simpleText":"([^"]+).*?'
patron += r'url":"([^"]+)'
matches = support.match('https://www.youtube.com/results?search_query=' + info.getProperty('title').replace(' ','+') + '+trailer+ita', patron = patron).matches
i = 0
for thumb, title, text, url in matches:
i += 1
item = xbmcgui.ListItem(title + ' - '+ text)
item.setProperties({'tile':title + ' - '+ text, 'url': url, 'thumbnail': thumb, 'fanart':info.getProperty('fanart'), 'position':'%s/%s' % (i, len(matches))})
trailers.append(item)
main = TrailerWindow('TrailerWindow.xml', config.get_runtime_path())
add({'class':main, 'info':trailers, 'id':RECOMANDED, TRAILERS:0})
modal()
class TrailerWindow(xbmcgui.WindowXMLDialog):
def __init__(self, *args, **kwargs):
self.ids = {}
def onInit(self):
#### Compatibility with Kodi 18 ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
self.getControl(FANART).setImage(trailers[0].getProperty('fanart'))
self.getControl(NUMBER).setText(trailers[0].getProperty('position'))
self.getControl(TRAILERS).addItems(trailers)
self.setFocusId(TRAILERS)
getFocus(self)
def onClick(self, control_id):
setFocus(self)
if control_id in [TRAILERS]:
selected = self.getControl(TRAILERS).getSelectedItem()
platformtools.play_video(Item(title=selected.getProperty('title'), action='play', url=selected.getProperty('url'), server='youtube'))
while not xbmc.Player().isPlaying():
xbmc.sleep(100)
self.close()
while xbmc.Player().isPlaying():
xbmc.sleep(100)
modal()
def onAction(self, action):
if self.getFocusId() in [TRAILERS]:
self.ids[self.getFocusId()] = self.getControl(self.getFocusId()).getSelectedPosition()
fanart = self.getControl(TRAILERS).getSelectedItem().getProperty('fanart')
position = self.getControl(TRAILERS).getSelectedItem().getProperty('position')
self.getControl(FANART).setImage(fanart)
self.getControl(NUMBER).setText(position)
action = action.getId()
global info_list
if action in [BACKSPACE]:
self.close()
remove()
modal()
elif action in [EXIT]:
self.close()
class images(xbmcgui.WindowDialog):
def __init__(self, *args, **kwargs):
self.tmdb = kwargs.get("tmdb", {})
self.imdb = kwargs.get("imdb", {})
self.mal = kwargs.get("mal", {})
self.fanartv = kwargs.get("fanartv", {})
self.image_list = []
for key, value in self.tmdb.items():
for detail in value: self.image_list.append('http://image.tmdb.org/t/p/original' + detail["file_path"])
for image in self.imdb: self.image_list.append(image["src"])
for image, title in self.mal: self.image_list.append(image)
for key, value in self.fanartv.items():
for image in value: self.image_list.append(image["url"])
#### Kodi 18 Compatibility ####
if config.get_platform(True)['num_version'] < 18: self.setCoordinateResolution(2)
log
self.background = xbmcgui.ControlImage(0, 0, 1280, 720, imagepath('white'), colorDiffuse='FF232323')
self.addControl(self.background)
main_image = self.image_list[0] if self.image_list else ''
self.main_image = xbmcgui.ControlImage(0, 0, 1280, 720, main_image, 2)
self.addControl(self.main_image)
self.close_btn = xbmcgui.ControlButton(0, 0, 1280, 720, '' ,'', '')
self.addControl(self.close_btn)
# BUTTON LEFT
self.btn_left = xbmcgui.ControlButton(0, 330, 60, 60, '', imagepath('previous_focus'), imagepath('previous_nofocus'))
self.addControl(self.btn_left)
self.btn_left.setAnimations([('WindowOpen', 'effect=slide start=-60,0 end=0,0 delay=100 time=200'),('WindowClose', 'effect=slide start=0,0 end=-60,0 delay=100 time=200')])
# BUTTON RIGHT
self.btn_right = xbmcgui.ControlButton(1220, 330, 60, 60, '', imagepath('next_focus'), imagepath('next_nofocus'))
self.addControl(self.btn_right)
self.btn_right.setAnimations([('WindowOpen', 'effect=slide start=60,0 end=0,0 delay=100 time=200'),('WindowClose', 'effect=slide start=0,0 end=60,0 delay=100 time=200')])
self.count = 0
def onAction(self, action):
if action in [BACKSPACE, EXIT]:
self.close()
if action in [RIGHT, DOWN]:
self.count += 1
if self.count > len(self.image_list) -1: self.count = 0
self.main_image.setImage(self.image_list[self.count])
if action in [LEFT, UP]:
self.count -= 1
if self.count < 0: self.count = len(self.image_list) -1
self.main_image.setImage(self.image_list[self.count])
def onControl(self, control):
if control.getId() == self.btn_right.getId():
self.count += 1
if self.count > len(self.image_list) -1: self.count = 0
self.main_image.setImage(self.image_list[self.count])
elif control.getId() == self.btn_left.getId():
self.count -= 1
if self.count < 0: self.count = len(self.image_list) -1
self.main_image.setImage(self.image_list[self.count])
else:
self.close()
def get_recomendations(info):
recommendations = [info]
Type = info.getProperty('mediatype')
if Type != "movie": Type = "tv"
search = {'url': '%s/%s/recommendations' % (Type, info.getProperty('tmdb_id')), 'language': 'it', 'page': 1}
tmdb_res = tmdb.Tmdb(discover=search, tipo=Type, idioma_Search='it').results
for result in tmdb_res:
if Type == 'movie':
title = result.get("title", '')
original_title = result.get("original_title", "")
else:
title = result.get("name", '')
original_title = result.get("original_name", '')
thumbnail ='http://image.tmdb.org/t/p/w342' + result.get("poster_path", "") if result.get("poster_path", "") else ''
fanart = 'http://image.tmdb.org/t/p/original' + result.get("backdrop_path", "") if result.get("backdrop_path", "") else ''
item = xbmcgui.ListItem(title)
item.setProperties({'title': title,
'original_title': original_title,
'mediatype': info.getProperty('mediatype'),
'tmdb_id': result.get('id', 0),
'imdb_id': info.getProperty('imdb_id'),
'rating': result.get('vote_average', 0),
'plot': result.get('overview', ''),
'year': result.get('release_date', '').split('-')[0],
'thumbnail': thumbnail,
'fanart': fanart})
recommendations.append(item)
return recommendations
def get_cast(info):
cast_list = []
actors_list = []
Type = "movie" if info.getProperty('mediatype') == 'movie' else 'tv'
otmdb = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), tipo=Type)
actors = otmdb.result.get("credits", {}).get("cast", [])
cast = otmdb.result.get("credits", {}).get("crew", []) if Type == 'movie' else otmdb.result.get("created_by", [])
for i, crew in enumerate(cast):
if crew.get('job', '') == 'Director' or Type!= "movie":
actors.insert(0, crew)
else:
res = xbmcgui.ListItem(crew.get('name', ''))
res.setProperties({'title': crew.get('name', ''),
'job': crew.get('job', '') if crew.get('job', '') else crew.get('character',''),
'thumbnail': "https://image.tmdb.org/t/p/w342" + crew.get('profile_path', '') if crew.get('profile_path', '') else '',
'department': crew.get('department', ''),
'type': Type,
'id': crew.get('id', ''),
'mediatype': info.getProperty('mediatype')})
cast_list.append(res)
for actor in actors:
res = xbmcgui.ListItem(actor.get('name', ''))
res.setProperties({'title': actor.get('name', ''),
'job': actor.get('job', '') if actor.get('job', '') else actor.get('character',''),
'thumbnail': "https://image.tmdb.org/t/p/w342" + actor.get('profile_path', '') if actor.get('profile_path', '') else imagepath('no_photo'),
'type': Type,
'id': actor.get('id', ''),
'mediatype': info.getProperty('mediatype')})
actors_list.append(res)
return cast_list, actors_list
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
def actors_more_info(ListItem):
Type = ListItem.getProperty('type')
actor_id = ListItem.getProperty('id')
more = tmdb.Tmdb(discover={'url': 'person/' + str(actor_id), 'language': 'en'}).results
if more['biography']: ListItem.setProperty('bio', more['biography'])
def get_movies(info):
Type = info.getProperty('mediatype') if info.getProperty('mediatype') == 'movie' else 'tv'
more = tmdb.Tmdb(discover={'url': 'person/' + str(info.getProperty('id')), 'language': 'it', 'append_to_response': Type + '_credits'}).results
movies = []
for movie in more.get(Type + '_credits', {}).get('cast',[]) + more.get(Type + '_credits', {}).get('crew',[]):
ret = {}
ret['mediatype'] = info.getProperty('mediatype')
thumbnail = movie.get('poster_path','')
ret['thumbnail'] = "https://image.tmdb.org/t/p/w342" + thumbnail if thumbnail else imagepath(Type)
ret['title'] = movie.get('title','') if Type == 'movie' else movie.get('name','')
ret['original_title'] = movie.get('original_title','') if Type == 'movie' else movie.get("original_name", '')
ret['tmdb_id'] = movie.get('id',0)
if ret not in movies: movies.append(ret)
itemlist = []
with futures.ThreadPoolExecutor() as executor:
List = [executor.submit(add_infoLabels, movie) for movie in movies]
for res in futures.as_completed(List):
if res.result():
itemlist.append(res.result())
itemlist = sorted(itemlist, key=lambda it: (it.getProperty('year'),it.getProperty('title')))
return itemlist
def add_infoLabels(movie):
it = Item(title=movie['title'], infoLabels=movie, contentType=movie['mediatype'])
tmdb.set_infoLabels_item(it, True)
movie=it.infoLabels
item = xbmcgui.ListItem(movie['title'])
for key, value in movie.items():
item.setProperty(key, str(value))
return item
def add(Dict):
global info_list
info_list.append(Dict)
def remove():
global info_list
info_list = info_list[:-1]
def modal():
global Info
global info_list
if info_list:
Info = info_list[-1]['info']
info_list[-1]['class'].doModal()
def getFocus(self):
global info_list
for key, value in info_list[-1].items():
if key not in ['class', 'info', 'id']:
self.getControl(int(key)).selectItem(value)
self.setFocusId(info_list[-1]['id'])
def setFocus(self):
global info_list
info_list[-1]['id'] = self.getFocusId()
for key, values in self.ids.items():
info_list[-1][key] = values

View File

@@ -28,7 +28,7 @@ def start():
# if it has DNS problems start but let in
# if everything is ok: enter the addon
from specials.checkhost import test_conn
from platformcode.checkhost import test_conn
import threading
threading.Thread(target=test_conn, args=(True, not config.get_setting('resolver_dns'), True, [], [], True)).start()
@@ -65,7 +65,7 @@ def run(item=None):
category = dictCategory[config.get_setting("category")]
item = Item(channel="news", action="novedades", extra=category, mode = 'silent')
else:
from specials import side_menu
from platformcode import side_menu
item= Item()
item = side_menu.check_user_home(item)
item.start = True
@@ -121,6 +121,18 @@ def run(item=None):
else:
return keymaptools.set_key()
elif item.channel == "infoplus":
from platformcode import infoplus
return infoplus.Main(item)
elif item.channel == "shortcuts":
from platformcode import shortcuts
return getattr(shortcuts, item.action)(item)
elif item.channel == "autorenumber":
from platformcode import autorenumber
return getattr(autorenumber, item.action)(item)
elif item.action == "delete_key":
from platformcode import keymaptools
return keymaptools.delete_key()
@@ -145,6 +157,9 @@ def run(item=None):
short = urllib.urlopen('https://u.nu/api.php?action=shorturl&format=simple&url=' + item.url).read().decode('utf-8')
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(70740) % short)
# Action in certain channel specified in "action" and "channel" parameters
elif item.action == "check_channels":
from platformcode import checkhost
checkhost.check_channels()
else:
# Checks if channel exists
if os.path.isfile(os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py")):
@@ -330,15 +345,14 @@ def run(item=None):
if Channel:
if item.url:
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014), log_message, nolabel='ok', yeslabel=config.get_localized_string(70739)):
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message, nolabel='ok', yeslabel=config.get_localized_string(70739)):
run(Item(action="open_browser", url=item.url))
else:
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014), log_message)
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message)
else:
platformtools.dialog_ok(
config.get_localized_string(60038),
config.get_localized_string(60015),
log_message)
config.get_localized_string(60015) + '\n' + log_message)
def new_search(item, channel=None):

View File

@@ -2,112 +2,41 @@
# --------------------------------------------------------------------------------
# Logger (kodi)
# --------------------------------------------------------------------------------
import inspect
import xbmc
from __future__ import unicode_literals
import inspect, os, xbmc, sys
from platformcode import config
import sys
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
loggeractive = (config.get_setting("debug") == True)
try:
xbmc.KodiStub()
testMode = True
import cgi
except:
testMode = False
def log_enable(active):
global loggeractive
loggeractive = active
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
def encode_log(message=""):
# Unicode to utf8
if isinstance(message, unicode):
message = message.encode("utf8")
if PY3: message = message.decode("utf8")
# All encodings to utf8
elif not PY3 and isinstance(message, str):
message = unicode(message, "utf8", errors="replace").encode("utf8")
# Bytes encodings to utf8
elif PY3 and isinstance(message, bytes):
message = message.decode("utf8")
# Objects to string
else:
message = str(message)
if testMode:
message = cgi.escape(message).replace('\n', '<br>')
return message
def info(*args):
log(*args)
def get_caller(message=None):
if message and isinstance(message, unicode):
message = message.encode("utf8")
if PY3: message = message.decode("utf8")
elif message and PY3 and isinstance(message, bytes):
message = message.decode("utf8")
elif message and not PY3:
message = unicode(message, "utf8", errors="replace").encode("utf8")
elif message:
message = str(message)
module = inspect.getmodule(inspect.currentframe().f_back.f_back)
if module == None:
module = "None"
else:
module = module.__name__
function = inspect.currentframe().f_back.f_back.f_code.co_name
if module == "__main__":
module = "kod"
else:
module = "kod." + module
if message:
if module not in message:
if function == "<module>":
return module + " " + message
else:
return module + " [" + function + "] " + message
else:
return message
else:
if function == "<module>":
return module
else:
return module + "." + function
def debug(*args):
if DEBUG_ENABLED:
log(*args)
def info(texto=""):
if loggeractive:
xbmc.log(get_caller(encode_log(texto)), xbmc.LOGNOTICE)
def error(*args):
log("######## ERROR #########", level=xbmc.LOGERROR)
log(*args, level=xbmc.LOGERROR)
def debug(texto=""):
if loggeractive:
texto = " [" + get_caller() + "] " + encode_log(texto)
xbmc.log("######## DEBUG #########", xbmc.LOGNOTICE)
xbmc.log(texto, xbmc.LOGNOTICE)
def error(texto=""):
texto = " [" + get_caller() + "] " + encode_log(texto)
xbmc.log("######## ERROR #########", xbmc.LOGERROR)
xbmc.log(texto, xbmc.LOGERROR)
def log(*args, **kwargs):
msg = ''
for arg in args: msg += ' ' + str(arg)
frame = inspect.currentframe().f_back.f_back
filename = frame.f_code.co_filename
filename = os.path.basename(filename).split('.')[0]
xbmc.log(LOG_FORMAT.format(addname=config.PLUGIN_NAME,
filename=filename,
line=frame.f_lineno,
sep=':' if msg else '',
function=frame.f_code.co_name,
message=msg), kwargs.get('level', DEF_LEVEL))
class WebErrorException(Exception):

View File

@@ -8,8 +8,10 @@
import sys
if sys.version_info[0] >= 3:
PY3 = True
import urllib.parse as urllib
else:
PY3 = False
import urllib
import os, xbmc, xbmcgui, xbmcplugin
@@ -30,17 +32,10 @@ class XBMCPlayer(xbmc.Player):
xbmc_player = XBMCPlayer()
def makeMessage(line1, line2, line3):
message = line1
if line2:
message += '\n' + line2
if line3:
message += '\n' + line3
return message
def dialog_ok(heading, line1, line2="", line3=""):
def dialog_ok(heading, message):
dialog = xbmcgui.Dialog()
return dialog.ok(heading, makeMessage(line1, line2, line3))
return dialog.ok(heading, message)
def dialog_notification(heading, message, icon=3, time=5000, sound=True):
@@ -52,19 +47,19 @@ def dialog_notification(heading, message, icon=3, time=5000, sound=True):
dialog_ok(heading, message)
def dialog_yesno(heading, line1, line2="", line3="", nolabel=config.get_localized_string(70170), yeslabel=config.get_localized_string(30022), autoclose=0, customlabel=None):
def dialog_yesno(heading, message, nolabel=config.get_localized_string(70170), yeslabel=config.get_localized_string(30022), autoclose=0, customlabel=None):
# customlabel only on kodi 19
dialog = xbmcgui.Dialog()
if config.get_platform() == 'kodi-matrix':
if PY3:
if autoclose:
return dialog.yesno(heading, makeMessage(line1, line2, line3), nolabel=nolabel, yeslabel=yeslabel, customlabel=customlabel, autoclose=autoclose)
return dialog.yesno(heading, message, nolabel=nolabel, yeslabel=yeslabel, customlabel=customlabel, autoclose=autoclose)
else:
return dialog.yesno(heading, makeMessage(line1, line2, line3), nolabel=nolabel, yeslabel=yeslabel, customlabel=customlabel)
return dialog.yesno(heading, message, nolabel=nolabel, yeslabel=yeslabel, customlabel=customlabel)
else:
if autoclose:
return dialog.yesno(heading, makeMessage(line1, line2, line3), nolabel=nolabel, yeslabel=yeslabel, autoclose=autoclose)
return dialog.yesno(heading, message, nolabel=nolabel, yeslabel=yeslabel, autoclose=autoclose)
else:
return dialog.yesno(heading, makeMessage(line1, line2, line3), nolabel=nolabel, yeslabel=yeslabel)
return dialog.yesno(heading, message, nolabel=nolabel, yeslabel=yeslabel)
def dialog_select(heading, _list, preselect=0, useDetails=False):
@@ -75,9 +70,9 @@ def dialog_multiselect(heading, _list, autoclose=0, preselect=[], useDetails=Fal
return xbmcgui.Dialog().multiselect(heading, _list, autoclose=autoclose, preselect=preselect, useDetails=useDetails)
def dialog_progress(heading, line1, line2=" ", line3=" "):
def dialog_progress(heading, message):
dialog = xbmcgui.DialogProgress()
dialog.create(heading, makeMessage(line1, line2, line3))
dialog.create(heading, message)
return dialog
@@ -140,7 +135,7 @@ def render_items(itemlist, parent_item):
"""
logger.info('START render_items')
thumb_type = config.get_setting('video_thumbnail_type')
from specials import shortcuts
from platformcode import shortcuts
from core import httptools
_handle = int(sys.argv[1])
default_fanart = config.get_fanart()
@@ -390,9 +385,9 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
continue
if "goto" in command:
context_commands.append((command["title"], "XBMC.Container.Refresh (%s?%s)" % (sys.argv[0], item.clone(**command).tourl())))
context_commands.append((command["title"], "Container.Refresh (%s?%s)" % (sys.argv[0], item.clone(**command).tourl())))
else:
context_commands.append((command["title"], "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(**command).tourl())))
context_commands.append((command["title"], "RunPlugin(%s?%s)" % (sys.argv[0], item.clone(**command).tourl())))
# Do not add more predefined options if you are inside kodfavoritos
if parent_item.channel == 'kodfavorites':
return context_commands
@@ -400,43 +395,43 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
if item.action and item.action not in ["add_pelicula_to_library", "add_serie_to_library", "buscartrailer", "actualizar_titulos"]:
# Show information: if the item has a plot, we assume that it is a series, season, chapter or movie
# if item.infoLabels['plot'] and (num_version_xbmc < 17.0 or item.contentType == 'season'):
# context_commands.append((config.get_localized_string(60348), "XBMC.Action(Info)"))
# context_commands.append((config.get_localized_string(60348), "Action(Info)"))
# ExtendedInfo: If the addon is installed and a series of conditions are met
if kwargs.get('has_extendedinfo') \
and config.get_setting("extended_info") == True:
if item.contentType == "episode" and item.contentEpisodeNumber and item.contentSeason and (item.infoLabels['tmdb_id'] or item.contentSerieName):
param = "tvshow_id =%s, tvshow=%s, season=%s, episode=%s" % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason, item.contentEpisodeNumber)
context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedepisodeinfo,%s)" % param))
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedepisodeinfo,%s)" % param))
elif item.contentType == "season" and item.contentSeason and (item.infoLabels['tmdb_id'] or item.contentSerieName):
param = "tvshow_id =%s,tvshow=%s, season=%s" % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason)
context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=seasoninfo,%s)" % param))
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=seasoninfo,%s)" % param))
elif item.contentType == "tvshow" and (item.infoLabels['tmdb_id'] or item.infoLabels['tvdb_id'] or item.infoLabels['imdb_id'] or item.contentSerieName):
param = "id =%s,tvdb_id=%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['tvdb_id'], item.infoLabels['imdb_id'], item.contentSerieName)
context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedtvinfo,%s)" % param))
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedtvinfo,%s)" % param))
elif item.contentType == "movie" and (item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.contentTitle):
param = "id =%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['imdb_id'], item.contentTitle)
context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedinfo,%s)" % param))
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedinfo,%s)" % param))
# InfoPlus
if config.get_setting("infoplus"):
#if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id'] or \
# (item.contentTitle and item.infoLabels["year"]) or item.contentSerieName:
if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id']:
context_commands.append(("InfoPlus", "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=start&from_channel=' + item.channel)))
context_commands.append(("InfoPlus", "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=Main&from_channel=' + item.channel)))
# Go to the Main Menu (channel.mainlist)
if parent_item.channel not in ["news", "channelselector", "downloads"] and item.action != "mainlist":
if parent_item.action != "mainlist":
context_commands.insert(0, (config.get_localized_string(60349), "XBMC.Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl())))
context_commands.insert(1, (config.get_localized_string(70739), "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())))
context_commands.insert(0, (config.get_localized_string(60349), "Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl())))
context_commands.insert(1, (config.get_localized_string(70739), "Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())))
# Add to kodfavoritos (My links)
if item.channel not in ["favorites", "videolibrary", "help", ""] and parent_item.channel != "favorites":
context_commands.append( (config.get_localized_string(70557), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
context_commands.append( (config.get_localized_string(70557), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
# Search in other channels
if item.contentType in ['movie', 'tvshow'] and item.channel != 'search' and item.action not in ['play'] and parent_item.action != 'mainlist':
@@ -451,51 +446,51 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
else:
mediatype = item.contentType
context_commands.append((config.get_localized_string(60350), "XBMC.Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted}))))
context_commands.append((config.get_localized_string(60350), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted}))))
context_commands.append( (config.get_localized_string(70561), "XBMC.Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id']))))
context_commands.append( (config.get_localized_string(70561), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id']))))
# Set as Home Page
if config.get_setting('start_page'):
if item.action not in ['episodios', 'seasons', 'findvideos', 'play']:
context_commands.insert(0, (config.get_localized_string(60351), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], Item(channel='side_menu', action="set_custom_start", parent=item.tourl()).tourl())))
context_commands.insert(0, (config.get_localized_string(60351), "RunPlugin(%s?%s)" % (sys.argv[0], Item(channel='side_menu', action="set_custom_start", parent=item.tourl()).tourl())))
if item.channel != "videolibrary":
# Add Series to the video library
if item.action in ["episodios", "get_episodios", "get_seasons"] and item.contentSerieName:
context_commands.append((config.get_localized_string(60352), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60352), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action)))
# Add Movie to Video Library
elif item.action in ["detail", "findvideos"] and item.contentType == 'movie' and item.contentTitle:
context_commands.append((config.get_localized_string(60353), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60353), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action)))
if not item.local and item.channel not in ["downloads", "filmontv"] and item.server != 'torrent' and parent_item.action != 'mainlist' and config.get_setting('downloadenabled'):
# Download movie
if item.contentType == "movie":
context_commands.append((config.get_localized_string(60354), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60354), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
elif item.contentSerieName:
# Descargar series
if item.contentType == "tvshow" and item.action not in ['findvideos']:
if item.channel == 'videolibrary':
context_commands.append((config.get_localized_string(60003), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60355), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60003), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60355), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60357), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action)))
# Download episode
elif item.contentType == "episode" or item.action in ['findvideos']:
context_commands.append((config.get_localized_string(60356), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60356), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
# Download season
elif item.contentType == "season":
context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60357), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action)))
# Open settings...
if item.action in ["findvideos", 'episodios', 'check', 'new_search'] or "buscar_trailer" in context:
context_commands.append((config.get_localized_string(60359), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s)" % (sys.argv[0], urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
if kwargs.get('superfavourites'):
context_commands.append((config.get_localized_string(60361), "XBMC.RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)"))
context_commands.append((config.get_localized_string(60361), "RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)"))
if config.dev_mode():
context_commands.insert(0, ("item info", "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl())))
context_commands.insert(0, ("item info", "Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl())))
return context_commands
@@ -678,7 +673,7 @@ def show_recaptcha(key, referer):
def alert_no_disponible_server(server):
# 'The video is no longer in %s', 'Try another server or another channel'
dialog_ok(config.get_localized_string(30055), (config.get_localized_string(30057) % server), config.get_localized_string(30058))
dialog_ok(config.get_localized_string(30055), (config.get_localized_string(30057) % server) + '\n' + config.get_localized_string(30058))
def alert_unsopported_server():
@@ -780,13 +775,13 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
if not autoplay:
if item.server != "":
if "<br/>" in motivo:
ret = dialog_yesno(config.get_localized_string(60362), motivo.split("<br/>")[0], motivo.split("<br/>")[1], item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362), motivo.split("<br/>")[0] + '\n' + motivo.split("<br/>")[1] + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), motivo, item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362), motivo + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363), config.get_localized_string(60364), item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363) + '\n' + config.get_localized_string(60364) + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
if ret:
xbmc.executebuiltin("XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
xbmc.executebuiltin("Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
if item.channel == "favorites":
# "Remove from favorites"
opciones.append(config.get_localized_string(30154))
@@ -841,7 +836,7 @@ def set_opcion(item, seleccion, opciones, video_urls):
# "Search Trailer":
elif opciones[seleccion] == config.get_localized_string(30162):
config.set_setting("subtitulo", False)
xbmc.executebuiltin("XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(channel="trailertools", action="buscartrailer", contextual=True).tourl()))
xbmc.executebuiltin("RunPlugin(%s?%s)" % (sys.argv[0], item.clone(channel="trailertools", action="buscartrailer", contextual=True).tourl()))
salir = True
return salir
@@ -973,7 +968,7 @@ def play_torrent(item, xlistitem, mediaurl):
torrent_options = torrent_client_installed(show_tuple=True)
if len(torrent_options) == 0:
from specials import elementum_download
from platformcode import elementum_download
elementum_download.download()
return play_torrent(item, xlistitem, mediaurl)
elif len(torrent_options) > 1:
@@ -1007,9 +1002,6 @@ def play_torrent(item, xlistitem, mediaurl):
time.sleep(3)
def log(texto):
xbmc.log(texto, xbmc.LOGNOTICE)
def resume_playback(item, return_played_time=False):
class ResumePlayback(xbmcgui.WindowXMLDialog):
Close = False
@@ -1058,7 +1050,7 @@ def resume_playback(item, return_played_time=False):
if return_played_time:
return item_nfo.played_time
# Show Window
elif (config.get_setting("player_mode") not in [3] or item.play_from == 'window') and item_nfo.played_time:
elif (config.get_setting("player_mode") not in [3] or item.play_from == 'window') and item_nfo.played_time and item_nfo.played_time >= 120:
Dialog = ResumePlayback('ResumePlayback.xml', config.get_runtime_path(), item=item_nfo)
Dialog.show()
t = 0
@@ -1144,7 +1136,6 @@ def install_widevine():
def download_widevine(version, platform, path):
# for x86 architectures
from zipfile import ZipFile
from xbmcaddon import Addon
from core import downloadtools
archiveName = 'https://dl.google.com/widevine-cdm/' + version + '-' + platform['os'] + '-' + platform['arch'] + '.zip'
fileName = config.get_temp_file('widevine.zip')
@@ -1161,7 +1152,6 @@ def download_widevine(version, platform, path):
def download_chromeos_image(devices, platform, path):
# for arm architectures
from core import downloadtools
from zipfile import ZipFile
from core import jsontools
best = best_chromeos_image(devices)
archiveName = best['url']

150
platformcode/shortcuts.py Normal file
View File

@@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
from platformcode import logger, side_menu
def context():
from platformcode import config
context = []
# original
# if config.get_setting('quick_menu'): context.append((config.get_localized_string(60360).upper(), "RunPlugin(plugin://plugin.video.kod/?%s)" % Item(channel='shortcuts', action="shortcut_menu").tourl()))
# if config.get_setting('side_menu'): context.append((config.get_localized_string(70737).upper(), "RunPlugin(plugin://plugin.video.kod/?%s)" % Item(channel='shortcuts',action="Side_menu").tourl()))
# if config.get_setting('kod_menu'): context.append((config.get_localized_string(60026), "RunPlugin(plugin://plugin.video.kod/?%s)" % Item(channel='shortcuts', action="settings_menu").tourl()))
# pre-serialised
if config.get_setting('quick_menu'): context.append((config.get_localized_string(60360), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJzaG9ydGN1dF9tZW51IiwgCiAgICAiY2hhbm5lbCI6ICJzaG9ydGN1dHMiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D)'))
if config.get_setting('Side_menu'): context.append((config.get_localized_string(70737), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJTaWRlX21lbnUiLCAKICAgICJjaGFubmVsIjogInNob3J0Y3V0cyIsIAogICAgImluZm9MYWJlbHMiOiB7fQp9)'))
if config.get_setting('kod_menu'): context.append((config.get_localized_string(60026), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJzZXR0aW5nc19tZW51IiwgCiAgICAiY2hhbm5lbCI6ICJzaG9ydGN1dHMiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D)'))
return context
def Side_menu(item):
side_menu.open_menu(item)
def shortcut_menu(item):
from platformcode import keymaptools
keymaptools.open_shortcut_menu()
def settings_menu(item):
from platformcode import config
config.open_settings()
def servers_menu(item):
# from core.support import dbg; dbg()
from core import servertools
from core.item import Item
from platformcode import config, platformtools
from specials import setting
names = []
ids = []
if item.type == 'debriders':
action = 'server_debrid_config'
server_list = list(servertools.get_debriders_list().keys())
for server in server_list:
server_parameters = servertools.get_server_parameters(server)
if server_parameters['has_settings']:
names.append(server_parameters['name'])
ids.append(server)
select = platformtools.dialog_select(config.get_localized_string(60552), names)
ID = ids[select]
it = Item(channel = 'settings',
action = action,
config = ID)
return setting.server_debrid_config(it)
else:
action = 'server_config'
server_list = list(servertools.get_servers_list().keys())
for server in sorted(server_list):
server_parameters = servertools.get_server_parameters(server)
if server_parameters["has_settings"] and [x for x in server_parameters["settings"] if x["id"] not in ["black_list", "white_list"]]:
names.append(server_parameters['name'])
ids.append(server)
select = platformtools.dialog_select(config.get_localized_string(60538), names)
ID = ids[select]
it = Item(channel = 'settings',
action = action,
config = ID)
return setting.server_config(it)
def channels_menu(item):
import channelselector
from core import channeltools
from core.item import Item
from platformcode import config, platformtools
from specials import setting
names = []
ids = []
channel_list = channelselector.filterchannels("all")
for channel in channel_list:
if not channel.channel:
continue
channel_parameters = channeltools.get_channel_parameters(channel.channel)
if channel_parameters["has_settings"]:
names.append(channel.title)
ids.append(channel.channel)
select = platformtools.dialog_select(config.get_localized_string(60537), names)
ID = ids[select]
it = Item(channel='settings',
action="channel_config",
config=ID)
return setting.channel_config(it)
def check_channels(item):
from specials import setting
from platformcode import config, platformtools
# from core.support import dbg; dbg()
item.channel = 'setting'
item.extra = 'lib_check_datajson'
itemlist = setting.conf_tools(item)
text = ''
for item in itemlist:
text += item.title + '\n'
platformtools.dialog_textviewer(config.get_localized_string(60537), text)
def SettingOnPosition(item):
# addonId is the Addon ID
# item.category is the Category (Tab) offset (0=first, 1=second, 2...etc)
# item.setting is the Setting (Control) offse (0=first, 1=second, 2...etc)
# This will open settings dialog focusing on fourth setting (control) inside the third category (tab)
import xbmc
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.kod)')
category = item.category if item.category else 0
setting = item.setting if item.setting else 0
logger.info('SETTING= ' + str(setting))
xbmc.executebuiltin('SetFocus(%i)' % (category - 100))
xbmc.executebuiltin('SetFocus(%i)' % (setting - 80))
def select(item):
from platformcode import config, platformtools
# item.id = setting ID
# item.type = labels or values
# item.values = values separeted by |
# item.label = string or string id
label = config.get_localized_string(int(item.label)) if item.label.isdigit() else item.label
values = []
if item.type == 'labels':
for val in item.values.split('|'):
values.append(config.get_localized_string(int(val)))
else:
values = item.values.split('|')
select = platformtools.dialog_select(label, values, config.get_setting(item.id))
config.set_setting(item.id, values[select])

364
platformcode/side_menu.py Normal file
View File

@@ -0,0 +1,364 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# from builtins import str
import sys
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
import os
from core.item import Item
from core import jsontools
from platformcode import config, logger, launcher
import xbmc, xbmcgui
media_path = os.path.join(config.get_runtime_path(), "resources/skins/Default/media/side_menu/")
menu_settings_path = os.path.join(config.get_data_path(), "settings_channels", 'menu_settings_data.json')
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_setting_data.json', 'menu')
else:
menu_node = {'categoria actual':config.get_setting('category')}
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
ACTION_SHOW_FULLSCREEN = 36
ACTION_GESTURE_SWIPE_LEFT = 511
ACTION_SELECT_ITEM = 7
ACTION_PREVIOUS_MENU = 10
ACTION_MOVE_LEFT = 1
ACTION_MOVE_RIGHT = 2
ACTION_MOVE_DOWN = 4
ACTION_MOVE_UP = 3
def set_menu_settings(item):
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
else:
menu_node = {}
menu_node['categoria actual'] = item.extra
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def check_user_home(item):
logger.info()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
if 'user_home' in menu_node:
item = Item().fromurl(menu_node['user_home'])
else:
item = Item(channel="channelselector", action="getmainlist", viewmode="movie")
from platformcode import platformtools
undefined_start = platformtools.dialog_ok(config.get_localized_string(70664), config.get_localized_string(70665) + '\n' + config.get_localized_string(70666))
return item
def set_custom_start(item):
logger.info()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
else:
menu_node={}
parent_item= Item().fromurl(item.parent)
parent_item.start=True
config.set_setting("custom_start",True)
if config.get_setting("news_start"):
config.set_setting("news_start", False)
menu_node['user_home']=parent_item.tourl()
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def get_start_page():
logger.info()
dictCategory = {
config.get_localized_string(70137): 'peliculas',
config.get_localized_string(30123): 'series',
config.get_localized_string(30124): 'anime',
config.get_localized_string(70018): 'infantiles',
config.get_localized_string(60513): 'documentales',
config.get_localized_string(70013): 'terror',
config.get_localized_string(30124): 'castellano',
config.get_localized_string(59976): 'latino',
config.get_localized_string(70171): 'torrent',
}
category = dictCategory[config.get_setting("category")]
custom_start= config.get_setting("custom_start")
#if category != 'definido':
if custom_start == False:
item = Item(channel="news", action="novedades", extra=category, mode='silent')
else:
item = Item()
item = side_menu.check_user_home(item)
return item
def open_menu(item):
main = Main('side_menu.xml', config.get_runtime_path())
main.doModal()
del main
def open_shortcut_menu(item):
from platformcode import keymaptools
keymaptools.open_shortcut_menu()
class Main(xbmcgui.WindowXMLDialog):
def __init__(self, *args, **kwargs):
self.items = []
def onInit(self):
#### Kodi 18 compatibility ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
self.focus = -1
self.buttons = []
posx= 0
posy= 145
space = 30
selected = 'selected0.png'
width = 260
height = 30
textcolor = "0xFFCCCCCC"
conditional_textcolor = "0xFF0081C2"
shadow = "0x00000000"
offsetx = 30
offsety = 5
font = 'font25_title'
if config.get_setting('start_page'):
label = config.get_localized_string(70663)
self.button_start = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path + selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_start)
self.buttons.append(self.button_start)
posy += space * 2
label = config.get_localized_string(70009)
self.button_alfa = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path+selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_alfa)
self.buttons.append(self.button_alfa)
posy += space
label = config.get_localized_string(30100)
self.button_config = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path + selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_config)
self.buttons.append(self.button_config)
posy += space*2
label = config.get_localized_string(30122)
self.button_peliculas = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
alignment=0x00000000, noFocusTexture='',
focusTexture=media_path+selected, textColor=textcolor,
shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
self.addControl(self.button_peliculas)
self.buttons.append(self.button_peliculas)
posy += space
label = config.get_localized_string(70017)
self.button_series = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
alignment=0x00000000, noFocusTexture='',
focusTexture=media_path+selected, textColor=textcolor,
shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
self.addControl(self.button_series)
self.buttons.append(self.button_series)
posy += space
label = config.get_localized_string(30124)
self.button_anime = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path+selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_anime)
self.buttons.append(self.button_anime)
# posy += space
# label = config.get_localized_string(70018)
# self.button_infantil = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
# alignment=0x00000000, noFocusTexture='',
# focusTexture=media_path+selected, textColor=textcolor,
# shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
# self.addControl(self.button_infantil)
# self.buttons.append(self.button_infantil)
posy += space
label = config.get_localized_string(70019)
self.button_docu = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
alignment=0x00000000, noFocusTexture='',
focusTexture=media_path + selected, textColor=textcolor,
shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
self.addControl(self.button_docu)
self.buttons.append(self.button_docu)
posy += space
# label = config.get_localized_string(70013)
# self.button_terror = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
# alignment=0x00000000, noFocusTexture='',
# focusTexture=media_path+selected, textColor=textcolor,
# shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
# self.addControl(self.button_terror)
# self.buttons.append(self.button_terror)
# if channelselector.auto_filter() == 'esp':
# posy += space
# label = config.get_localized_string(59981)
# self.button_lat = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
# noFocusTexture='', focusTexture=media_path+selected,
# textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
# textOffsetY=offsety)
# self.addControl(self.button_lat)
# self.buttons.append(self.button_lat)
# posy += space
# label = config.get_localized_string(70014)
# self.button_cast = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
# noFocusTexture='', focusTexture=media_path + selected,
# textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
# textOffsetY=offsety)
# self.addControl(self.button_cast)
# self.buttons.append(self.button_cast)
# posy += space
# label = config.get_localized_string(70015)
# self.button_torrent = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
# alignment=0x00000000, noFocusTexture='',
# focusTexture=media_path+selected, textColor=textcolor,
# shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
# self.addControl(self.button_torrent)
# self.buttons.append(self.button_torrent)
start_page_item = get_start_page()
if config.get_setting('start_page') and start_page_item.channel == 'news':
posy += space
label = config.get_localized_string(70016)
self.button_config = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
alignment=0x00000000, noFocusTexture='',
focusTexture=media_path+selected, textColor=conditional_textcolor,
shadowColor=shadow, textOffsetX=offsetx, textOffsetY=offsety)
self.addControl(self.button_config)
self.buttons.append(self.button_config)
posy += space*2
label = config.get_localized_string(60423)
self.button_buscar = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path + selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_buscar)
self.buttons.append(self.button_buscar)
posy += space
label = config.get_localized_string(70036)
self.button_actor = xbmcgui.ControlButton(posx, posy, width, height, label, font=font, alignment=0x00000000,
noFocusTexture='', focusTexture=media_path + selected,
textColor=textcolor, shadowColor=shadow, textOffsetX=offsetx,
textOffsetY=offsety)
self.addControl(self.button_actor)
self.buttons.append(self.button_actor)
posy += space
label = config.get_localized_string(70010)
self.button_config_search = xbmcgui.ControlButton(posx, posy, width, height, label, font=font,
alignment=0x00000000,
noFocusTexture='', focusTexture=media_path + selected,
textColor=conditional_textcolor, shadowColor=shadow,
textOffsetX=offsetx, textOffsetY=offsety)
self.addControl(self.button_config_search)
self.buttons.append(self.button_config_search)
label=''
self.button_close = xbmcgui.ControlButton(260, 0, 1020, 725, label, noFocusTexture='', focusTexture='')
self.addControl(self.button_close)
def onClick(self, control):
new_item=''
control = self.getControl(control).getLabel()
if control == config.get_localized_string(70663):
new_item = get_start_page()
elif control == config.get_localized_string(70009):
new_item = Item(channel='', action='getmainlist', title='Menú Alfa')
elif control == config.get_localized_string(30100):
new_item = Item(channel='setting', action="settings")
elif control == config.get_localized_string(30122):
new_item = Item(channel='news', action="novedades", extra="peliculas", mode='silent')
elif control == config.get_localized_string(70017):
new_item = Item(channel='news', action="novedades", extra="series", mode='silent')
elif control == config.get_localized_string(30124):
new_item = Item(channel='news', action="novedades", extra="anime", mode='silent')
elif control == config.get_localized_string(70018):
new_item = Item(channel='news', action="novedades", extra="infantiles", mode='silent')
elif control == config.get_localized_string(70019):
new_item = Item(channel='news', action="novedades", extra="documentales", mode='silent')
elif control == config.get_localized_string(70013):
new_item = Item(channel='news', action="novedades", extra="terror", mode='silent')
elif control == config.get_localized_string(59981):
new_item = Item(channel='news', action="novedades", extra="castellano", mode='silent')
elif control == config.get_localized_string(70014):
new_item = Item(channel='news', action="novedades", extra="latino", mode='silent')
elif control == config.get_localized_string(70015):
new_item = Item(channel='news', action="novedades", extra="torrent", mode='silent')
elif control == config.get_localized_string(70016):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
if 'categoria actual' in menu_node:
category = menu_node['categoria actual']
new_item = Item(channel='news', action="setting_channel", extra=category, menu=True)
elif control == config.get_localized_string(60423):
new_item = Item(channel='search', action="search")
elif control == config.get_localized_string(70036):
new_item = Item(channel='tvmoviedb', title="Buscar actor/actriz", action="search_",
search={'url': 'search/person', 'language': def_lang, 'page': 1}, star=True)
elif control == config.get_localized_string(70010):
new_item = Item(channel='search', action="setting_channel")
elif control == '':
self.close()
if new_item !='':
self.run_action(new_item)
def onAction(self, action):
if action == ACTION_PREVIOUS_MENU or action == ACTION_GESTURE_SWIPE_LEFT or action == 110 or action == 92:
self.close()
if action == ACTION_MOVE_RIGHT or action == ACTION_MOVE_DOWN:
self.focus += 1
if self.focus > len(self.buttons)-1:
self.focus = 0
while True:
id_focus = str(self.buttons[self.focus].getId())
if xbmc.getCondVisibility('[Control.IsVisible(' + id_focus + ')]'):
self.setFocus(self.buttons[self.focus])
break
self.focus += 1
if action == ACTION_MOVE_LEFT or action == ACTION_MOVE_UP:
self.focus -= 1
if self.focus < 0:
self.focus = len(self.buttons) - 1
while True:
id_focus = str(self.buttons[self.focus].getId())
if xbmc.getCondVisibility('[Control.IsVisible(' + id_focus + ')]'):
self.setFocus(self.buttons[self.focus])
break
self.focus -= 1
def run_action(self, item):
logger.info()
if item.menu != True:
self.close()
xbmc.executebuiltin("Container.update(%s)"%launcher.run(item))

View File

@@ -92,7 +92,6 @@ def check(background=False):
if 'Merge' in commitJson['commit']['message']:
continue
logger.info('aggiornando a ' + commitJson['sha'])
alreadyApplied = True
# major update
if len(commitJson['files']) > 50:
@@ -104,6 +103,11 @@ def check(background=False):
serviceChanged = True
break
patch_url = commitJson['html_url'] + '.patch'
logger.info('applicando ' + patch_url)
from lib import patch
patch.fromurl(patch_url).apply(root=addonDir)
for file in commitJson['files']:
if file["filename"] == trackingFile: # il file di tracking non si modifica
continue
@@ -113,46 +117,18 @@ def check(background=False):
poFilesChanged = True
if 'service.py' in file["filename"]:
serviceChanged = True
if file['status'] == 'modified' or file['status'] == 'added':
if 'patch' in file:
text = ""
try:
localFile = io.open(os.path.join(addonDir, file["filename"]), 'r+', encoding="utf8")
text = localFile.read()
if not PY3:
text = text.decode('utf-8')
except IOError: # nuovo file
# crea le cartelle se non esistono
dirname = os.path.dirname(os.path.join(addonDir, file["filename"]))
if not os.path.exists(dirname):
os.makedirs(dirname)
localFile = io.open(os.path.join(addonDir, file["filename"]), 'w', encoding="utf8")
patched = apply_patch(text, (file['patch']+'\n').encode('utf-8'))
if patched != text: # non eseguo se già applicata (es. scaricato zip da github)
alreadyApplied = False
if getShaStr(patched) == file['sha']:
localFile.seek(0)
localFile.truncate()
localFile.writelines(patched)
localFile.close()
else: # nel caso ci siano stati problemi
logger.info('lo sha non corrisponde, scarico il file')
localFile.close()
urllib.urlretrieve(file['raw_url'], os.path.join(addonDir, file['filename']))
else: # è un file NON testuale, lo devo scaricare
# se non è già applicato
filename = os.path.join(addonDir, file['filename'])
dirname = os.path.dirname(filename)
if not (filetools.isfile(os.path.join(addonDir, file['filename'])) and getSha(filename) == file['sha']):
if not os.path.exists(dirname):
os.makedirs(dirname)
urllib.urlretrieve(file['raw_url'], filename)
alreadyApplied = False
if (file['status'] == 'modified' and 'patch' not in file) or file['status'] == 'added':
# è un file NON testuale che è stato modificato, oppure è un file nuovo (la libreria non supporta la creazione di un nuovo file)
# lo devo scaricare
filename = os.path.join(addonDir, file['filename'])
dirname = os.path.dirname(filename)
if not (filetools.isfile(os.path.join(addonDir, file['filename'])) and getSha(filename) == file['sha']):
logger.info('scaricando ' + file['raw_url'])
if not os.path.exists(dirname):
os.makedirs(dirname)
urllib.urlretrieve(file['raw_url'], filename)
elif file['status'] == 'removed':
remove(os.path.join(addonDir, file["filename"]))
alreadyApplied = False
elif file['status'] == 'renamed':
# se non è già applicato
if not (filetools.isfile(os.path.join(addonDir, file['filename'])) and getSha(os.path.join(addonDir, file['filename'])) == file['sha']):
@@ -161,9 +137,7 @@ def check(background=False):
if not filetools.isdir(os.path.join(addonDir, d)):
filetools.mkdir(os.path.join(addonDir, d))
filetools.move(os.path.join(addonDir, file['previous_filename']), os.path.join(addonDir, file['filename']))
alreadyApplied = False
if not alreadyApplied: # non mando notifica se già applicata (es. scaricato zip da github)
changelog += commitJson['commit']['message'] + "\n"
changelog += commitJson['commit']['message'] + "\n"
except:
import traceback
logger.error(traceback.format_exc())
@@ -181,6 +155,7 @@ def check(background=False):
xbmc.executebuiltin("UpdateLocalAddons")
if poFilesChanged:
refreshLang()
xbmc.sleep(1000)
updated = True
if addon.getSetting("addon_update_message"):
@@ -205,6 +180,7 @@ def showSavedChangelog():
except:
pass
def calcCurrHash():
treeHash = githash.tree_hash(addonDir).hexdigest()
logger.info('tree hash: ' + treeHash)
@@ -235,38 +211,6 @@ def calcCurrHash():
localCommitFile.close()
# https://gist.github.com/noporpoise/16e731849eb1231e86d78f9dfeca3abc Grazie!
def apply_patch(s,patch,revert=False):
"""
Apply unified diff patch to string s to recover newer string.
If revert is True, treat s as the newer string, recover older string.
"""
s = s.splitlines(True)
p = patch.splitlines(True)
t = ''
i = sl = 0
(midx,sign) = (1,'+') if not revert else (3,'-')
while i < len(p) and p[i].startswith(("---","+++")): i += 1 # skip header lines
while i < len(p):
m = _hdr_pat.match(p[i])
if not m: raise Exception("Cannot process diff")
i += 1
l = int(m.group(midx))-1 + (m.group(midx+1) == '0')
t += ''.join(s[sl:l])
sl = l
while i < len(p) and p[i][0] != '@':
if i+1 < len(p) and p[i+1][0] == '\\': line = p[i][:-1]; i += 2
else: line = p[i]; i += 1
if len(line) > 0:
if line[0] == sign or line[0] == ' ': t += line[1:]
sl += (line[0] != sign)
t += ''.join(s[sl:])
if not PY3:
t = t.decode('utf-8')
return t
def getSha(path):
try:
f = io.open(path, 'rb', encoding="utf8")
@@ -319,7 +263,7 @@ def updateFromZip(message=config.get_localized_string(80050)):
if os.path.isfile(localfilename):
logger.info('il file esiste')
dp.update(80, config.get_localized_string(20000), config.get_localized_string(80032))
dp.update(80, config.get_localized_string(20000) + '\n' + config.get_localized_string(80032))
import zipfile
try:
@@ -436,7 +380,7 @@ def fixZipGetHash(zipFile):
f.write(
b'\x00\x00') # Zip file comment length: 0 byte length; tell zip applications to stop reading.
return str(hash)
return hash.decode('utf-8')
def _pbhook(numblocks, blocksize, filesize, url, dp):

View File

@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
import xbmc, sys, base64, json, xbmcgui, os, xbmcvfs, traceback
from platformcode import config, logger
from lib.sambatools import libsmb as samba
from core import scrapertools
def exists(path, silent=False, vfs=True):
path = xbmc.translatePath(path)
try:
if vfs:
result = bool(xbmcvfs.exists(path))
if not result and not path.endswith('/') and not path.endswith('\\'):
result = bool(xbmcvfs.exists(join(path, ' ').rstrip()))
return result
elif path.lower().startswith("smb://"):
return samba.exists(path)
else:
return os.path.exists(path)
except:
logger.error("ERROR when checking the path: %s" % path)
if not silent:
logger.error(traceback.format_exc())
return False
def join(*paths):
list_path = []
if paths[0].startswith("/"):
list_path.append("")
for path in paths:
if path:
list_path += path.replace("\\", "/").strip("/").split("/")
if scrapertools.find_single_match(paths[0], r'(^\w+:\/\/)'):
return str("/".join(list_path))
else:
return str(os.sep.join(list_path))
def search_paths(Id):
records = execute_sql('SELECT idPath FROM tvshowlinkpath WHERE idShow LIKE "%s"' % Id)
if len(records) >= 1:
for record in records:
path_records = execute_sql('SELECT strPath FROM path WHERE idPath LIKE "%s"' % record[0])
for path in path_records:
if config.get_setting('videolibrarypath') in path[0] and exists(join(path[0], 'tvshow.nfo')):
return path[0]
return ''
def execute_sql(sql):
logger.info()
file_db = ""
records = None
# We look for the archive of the video database according to the version of kodi
video_db = config.get_platform(True)['video_db']
if video_db:
file_db = os.path.join(xbmc.translatePath("special://userdata/Database"), video_db)
# alternative method to locate the database
if not file_db or not os.path.exists(file_db):
file_db = ""
for f in os.path.listdir(xbmc.translatePath("special://userdata/Database")):
path_f = os.path.join(xbmc.translatePath("special://userdata/Database"), f)
if os.path.pathoos.pathols.isfile(path_f) and f.lower().startswith('myvideos') and f.lower().endswith('.db'):
file_db = path_f
break
if file_db:
logger.info("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.info("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
records = cursor.fetchall()
if sql.lower().startswith("select"):
if len(records) == 1 and records[0][0] is None:
records = []
conn.close()
logger.info("Query executed. Records: %s" % nun_records)
except:
logger.error("Error executing sql query")
if conn:
conn.close()
else:
logger.debug("Database not found")
return records
if __name__ == '__main__':
path = search_paths(sys.listitem.getVideoInfoTag().getDbId())
if path:
item = {"action": "update_tvshow", "channel": "videolibrary", 'path':path}
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + base64.b64encode(json.dumps(item).encode()) + ")")
else:
dialog = xbmcgui.Dialog()
title = sys.listitem.getVideoInfoTag().getTitle()
if dialog.yesno(title, config.get_localized_string(70817) % title, nolabel=config.get_localized_string(70170), yeslabel=config.get_localized_string(30022)):
item = {"action": "new_search", "channel": "search", "mode":"tvshow", "search_text": sys.listitem.getVideoInfoTag().getTitle()}
xbmc.executebuiltin("ActivateWindow(10025,plugin://plugin.video.kod/?" + base64.b64encode(json.dumps(item).encode()) + ")")

View File

@@ -12,7 +12,7 @@ from past.utils import old_div
from core import channeltools, servertools, scrapertools
from platformcode import config, logger, platformtools
from core.support import log, dbg, match
from core.support import info, dbg, match
class SettingsWindow(xbmcgui.WindowXMLDialog):
@@ -141,7 +141,7 @@ class SettingsWindow(xbmcgui.WindowXMLDialog):
"""
def start(self, list_controls=None, dict_values=None, caption="", callback=None, item=None, custom_button=None, channelpath=None):
log()
info()
# Media Path
self.mediapath = os.path.join(config.get_runtime_path(), 'resources', 'skins', 'Default', 'media')
@@ -371,32 +371,30 @@ class SettingsWindow(xbmcgui.WindowXMLDialog):
def add_control_text(self, c):
if xbmcgui.ControlEdit == ControlEdit:
control = xbmcgui.ControlEdit(0, -100, self.controls_width, self.height_control, c["label"],
os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'), 0,
textColor=c["color"], font=self.font, isPassword=c["hidden"], window=self)
control = xbmcgui.ControlEdit(0, -100, self.controls_width, self.height_control,
c["label"], self.font, c["color"], '', 1 | 4,
focusTexture='',
noFocusTexture='')
else:
control = xbmcgui.ControlEdit(0, -100, self.controls_width, self.height_control,
c["label"], self.font, c["color"], '', 1 | 4, isPassword=c["hidden"],
focusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
noFocusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'))
image = xbmcgui.ControlImage(0, -100, self.controls_width + 10, self.height_control, os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'))
self.addControl(image)
self.addControl(control)
image.setVisibleCondition('Control.HasFocus(%s)' % control.getId(), True)
control.setVisible(False)
control.setLabel(c["label"])
if c['hidden']: control.setType(xbmcgui.INPUT_TYPE_PASSWORD, c["label"])
# frodo fix
s = self.values[c["id"]]
if s is None:
s = ''
if s is None: s = c['default'] if 'default' in c else ''
control.setText(s)
# control.setText(self.values[c["id"]])
control.setWidth(self.controls_width + 10)
control.setWidth(self.controls_width-10)
control.setHeight(self.height_control)
c["control"] = control
c['image'] = image
def add_control_bool(self, c):
# Old versions do not support some textures
@@ -405,24 +403,34 @@ class SettingsWindow(xbmcgui.WindowXMLDialog):
label=c["label"], font=self.font, textColor=c["color"],
focusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
noFocusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'))
else:
elif xbmcgui.__version__ in ["3.0", "3.0.0"]:
control = xbmcgui.ControlRadioButton(0, -100, self.controls_width + 20,
self.height_control, label=c["label"], font=self.font,
textColor=c["color"],
focusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
noFocusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'),
focusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
noFocusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
focusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'),
noFocusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'))
else:
control = xbmcgui.ControlRadioButton(0, -100, self.controls_width + 20,
self.height_control, label=c["label"], font=self.font,
textColor=c["color"],
focusTexture='',
noFocusTexture='',
focusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
noFocusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
focusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'),
noFocusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'))
image = xbmcgui.ControlImage(0, -100, self.controls_width + 10, self.height_control, os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'))
self.addControl(image)
self.addControl(control)
image.setVisibleCondition('Control.HasFocus(%s)' % control.getId(), True)
control.setVisible(False)
control.setRadioDimension(x=self.controls_width - (self.height_control - 5), y=0, width=self.height_control - 5, height=self.height_control - 5)
control.setSelected(self.values[c["id"]])
c["control"] = control
c['image'] = image
def onInit(self):
self.getControl(10004).setEnabled(False)
@@ -446,8 +454,6 @@ class SettingsWindow(xbmcgui.WindowXMLDialog):
self.getControl(10006).setLabel(self.custom_button['label'])
else:
self.getControl(10006).setVisible(False)
# self.getControl(10004).setPosition(self.getControl(10004).getPosition()[0], self.getControl(10004).getPosition()[1])
# self.getControl(10005).setPosition(self.getControl(10005).getPosition()[0], self.getControl(10005).getPosition()[1])
# Control Area Dimensions
self.controls_width = self.getControl(10007).getWidth() - 30
@@ -543,15 +549,17 @@ class SettingsWindow(xbmcgui.WindowXMLDialog):
c["y"] = self.controls_pos_y + visible_count * self.height_control
visible_count += 1
if c["type"] != "list":
if c["type"] == "bool": c["control"].setPosition(self.controls_pos_x, c["y"])
else: c["control"].setPosition(self.controls_pos_x, c["y"])
else:
if c["type"] == "list":
c["control"].setPosition(self.controls_pos_x, c["y"])
if xbmcgui.__version__ == "1.2": c["label"].setPosition(self.controls_pos_x + self.controls_width - 30, c["y"])
else: c["label"].setPosition(self.controls_pos_x, c["y"])
else:
if c["type"] == "bool": c["control"].setPosition(self.controls_pos_x, c["y"])
elif c['type'] == 'text': c["control"].setPosition(self.controls_pos_x +10, c["y"])
else: c["control"].setPosition(self.controls_pos_x, c["y"])
if c['type'] in ['bool', 'text']:c['image'].setPosition(self.controls_pos_x, c["y"])
self.set_visible(c, True)
# Calculate the position and size of the ScrollBar

View File

@@ -2,13 +2,18 @@
# ------------------------------------------------------------
# XBMC Library Tools
# ------------------------------------------------------------
from future import standard_library
standard_library.install_aliases()
# from future import standard_library
# standard_library.install_aliases()
#from builtins import str
import sys, os, threading, time, re, math, xbmc, xbmcgui
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
if PY3:
import urllib.request as urllib2 # Es muy lento en PY2. En PY3 es nativo
else:
import urllib2 # Usamos el nativo de PY2 que es más rápido
from core import filetools, jsontools
from platformcode import config, logger, platformtools
from core import scrapertools
@@ -71,7 +76,7 @@ def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
xbmc.sleep(1000)
# Set played time
item_nfo.played_time = int(actual_time) if not marked and actual_time > 120 else 0
item_nfo.played_time = int(actual_time) if not marked else 0
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
# Silent sync with Trakt
@@ -84,8 +89,8 @@ def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
xbmc.executebuiltin('Action(Back)')
xbmc.sleep(500)
if next_episode and next_episode.next_ep:
from platformcode.launcher import play_from_library
return play_from_library(next_episode)
from platformcode.launcher import play_from_library
return play_from_library(next_episode)
# If it is configured to mark as seen
if config.get_setting("mark_as_watched", "videolibrary"):
@@ -434,7 +439,10 @@ def get_data(payload):
@param payload: data
:return:
"""
import urllib.request, urllib.error
try:
import urllib.request as urllib
except ImportError:
import urllib
logger.info("payload: %s" % payload)
# Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type
headers = {'content-type': 'application/json'}
@@ -447,8 +455,8 @@ def get_data(payload):
xbmc_port = 0
xbmc_json_rpc_url = "http://" + config.get_setting("xbmc_host", "videolibrary") + ":" + str(xbmc_port) + "/jsonrpc"
req = urllib.request.Request(xbmc_json_rpc_url, data=jsontools.dump(payload), headers=headers)
f = urllib.request.urlopen(req)
req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump(payload), headers=headers)
f = urllib.urlopen(req)
response = f.read()
f.close()
@@ -571,7 +579,7 @@ def set_content(content_type, silent=False, custom=False):
if install:
try:
# Install metadata.themoviedb.org
xbmc.executebuiltin('xbmc.installaddon(metadata.themoviedb.org)', True)
xbmc.executebuiltin('InstallAddon(metadata.themoviedb.org)', True)
logger.info("Instalado el Scraper de películas de TheMovieDB")
except:
pass
@@ -594,7 +602,7 @@ def set_content(content_type, silent=False, custom=False):
if install:
try:
xbmc.executebuiltin('xbmc.installaddon(metadata.universal)', True)
xbmc.executebuiltin('InstallAddon(metadata.universal)', True)
if xbmc.getCondVisibility('System.HasAddon(metadata.universal)'):
continuar = True
except:
@@ -625,7 +633,7 @@ def set_content(content_type, silent=False, custom=False):
if install:
try:
# Install metadata.tvdb.com
xbmc.executebuiltin('xbmc.installaddon(metadata.tvdb.com)', True)
xbmc.executebuiltin('InstallAddon(metadata.tvdb.com)', True)
logger.info("The TVDB series Scraper installed ")
except:
pass
@@ -649,7 +657,7 @@ def set_content(content_type, silent=False, custom=False):
if install:
try:
# Install metadata.tvshows.themoviedb.org
xbmc.executebuiltin('xbmc.installaddon(metadata.tvshows.themoviedb.org)', True)
xbmc.executebuiltin('InstallAddon(metadata.tvshows.themoviedb.org)', True)
if xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'):
continuar = True
except:
@@ -843,7 +851,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
return
p = 80
progress.update(p, config.get_localized_string(20000), config.get_localized_string(80013))
progress.update(p, config.get_localized_string(20000) + '\n' + config.get_localized_string(80013))
for OldFolder, NewFolder in [[old_movies_folder, new_movies_folder], [old_tvshows_folder, new_tvshows_folder]]:
sql_old_folder = sql_old_path + OldFolder
@@ -906,12 +914,12 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
logger.info('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
p += 5
progress.update(p, config.get_localized_string(20000), config.get_localized_string(80013))
progress.update(p, config.get_localized_string(20000) + '\n' + config.get_localized_string(80013))
progress.update(100)
xbmc.sleep(1000)
progress.close()
xbmc.executebuiltin('XBMC.ReloadSkin()')
xbmc.executebuiltin('ReloadSkin()')
def clean(path_list=[]):
@@ -1234,7 +1242,7 @@ def ask_set_content(silent=False):
# ask to configure Kodi video library
if platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(80015)):
# ask for custom or default settings
if not platformtools.dialog_yesno(config.get_localized_string(80026), config.get_localized_string(80016), "", "", config.get_localized_string(80017), config.get_localized_string(80018)):
if not platformtools.dialog_yesno(config.get_localized_string(80026), config.get_localized_string(80016), config.get_localized_string(80017), config.get_localized_string(80018)):
# input path and folders
path = platformtools.dialog_browse(3, config.get_localized_string(80019), config.get_setting("videolibrarypath"))
movies_folder = platformtools.dialog_input(config.get_setting("folder_movies"), config.get_localized_string(80020))