KoD 1.4
- completato il supporto al futuro Kodi 19\n- ridisegnato infoplus\n- fix vari ed eventuali\n
This commit is contained in:
568
platformcode/autorenumber.py
Normal file
568
platformcode/autorenumber.py
Normal 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
96
platformcode/backup.py
Normal 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
297
platformcode/checkhost.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
135
platformcode/elementum_download.py
Normal file
135
platformcode/elementum_download.py
Normal 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']
|
||||
@@ -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
549
platformcode/infoplus.py
Normal 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
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
150
platformcode/shortcuts.py
Normal 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
364
platformcode/side_menu.py
Normal 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))
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
111
platformcode/updatetvshow.py
Normal file
111
platformcode/updatetvshow.py
Normal 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()) + ")")
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user