riorganizzazione cartelle

This commit is contained in:
marco
2020-09-21 18:49:09 +02:00
parent 0b605cf215
commit d489fb443b
38 changed files with 38 additions and 49 deletions
-285
View File
@@ -1,285 +0,0 @@
# -*- coding: utf-8 -*-
from core import filetools, jsontools
from core.item import Item
from platformcode import config, logger, platformtools
from time import sleep
__channel__ = "autoplay"
PLAYED = False
quality_list = ['4k', '2160p', '2160', '4k2160p', '4k2160', '4k 2160p', '4k 2160', '2k',
'fullhd', 'fullhd 1080', 'fullhd 1080p', 'full hd', 'full hd 1080', 'full hd 1080p', 'hd1080', 'hd1080p', 'hd 1080', 'hd 1080p', '1080', '1080p',
'hd', 'hd720', 'hd720p', 'hd 720', 'hd 720p', '720', '720p', 'hdtv',
'sd', '480p', '480', '360p', '360', '240p', '240',
'default']
def start(itemlist, item):
'''
Main method from which the links are automatically reproduced
- In case the option to activate it will use the options defined by the user.
- Otherwise it will try to reproduce any link that has the preferred language.
:param itemlist: list (list of items ready to play, ie with action = 'play')
:param item: item (the main item of the channel)
:return: try to auto-reproduce, in case of failure it returns the itemlist that it received in the beginning
'''
if item.global_search:
return itemlist
logger.info()
global PLAYED
PLAYED = False
base_item = item
if not config.is_xbmc():
return itemlist
if config.get_setting('autoplay'):
url_list_valid = []
autoplay_list = []
autoplay_b = []
favorite_quality = []
favorite_servers = []
blacklisted_servers = config.get_setting("black_list", server='servers')
if not blacklisted_servers: blacklisted_servers = []
from core import servertools
servers_list = list(servertools.get_servers_list().items())
for server, server_parameters in servers_list:
if config.get_setting('favorites_servers_list', server=server):
favorite_servers.append(server.lower())
if not favorite_servers:
config.set_setting('favorites_servers_list', [], server='servers')
favorite_servers = []
else:
favorite_servers = list(set(favorite_servers) - set(blacklisted_servers))
# Save the current value of "Action and Player Mode" in preferences
user_config_setting_action = config.get_setting("default_action")
user_config_setting_player = config.get_setting("player_mode")
# Enable the "View in high quality" action (if the server returns more than one quality, eg gdrive)
if not user_config_setting_action: config.set_setting("default_action", 2)
if user_config_setting_player != 0: config.set_setting("player_mode", 0)
# Priorities when ordering itemlist:
# 0: Servers and qualities
# 1: Qualities and servers
# 2: Servers only
# 3: Only qualities
# 4: Do not order
if config.get_setting('favorites_servers') and favorite_servers and config.get_setting('default_action'):
priority = 0 # 0: Servers and qualities or 1: Qualities and servers
elif config.get_setting('favorites_servers') and favorite_servers:
priority = 2 # Servers only
elif config.get_setting('default_action'):
priority = 3 # Only qualities
else:
priority = 4 # Do not order
if config.get_setting('default_action') == 1:
quality_list.reverse()
favorite_quality = quality_list
for item in itemlist:
autoplay_elem = dict()
b_dict = dict()
# We check that it is a video item
if 'server' not in item:
continue
if item.server.lower() in blacklisted_servers:
continue
# If it does not have a defined quality, it assigns a 'default' quality.
if item.quality.lower() not in quality_list:
item.quality = 'default'
# The list for custom settings is created
if priority < 2: # 0: Servers and qualities or 1: Qualities and servers
# if the server and the quality are not in the favorites lists or the url is repeated, we discard the item
if item.server.lower() not in favorite_servers or item.quality.lower() not in favorite_quality or item.url in url_list_valid:
item.type_b = True
item.play_from = base_item.play_from
b_dict['videoitem']= item
autoplay_b.append(b_dict)
continue
autoplay_elem["indice_server"] = favorite_servers.index(item.server.lower())
autoplay_elem["indice_quality"] = favorite_quality.index(item.quality.lower())
elif priority == 2: # Servers only
# if the server is not in the favorites list or the url is repeated, we discard the item
if item.server.lower() not in favorite_servers or item.url in url_list_valid:
item.type_b = True
item.play_from = base_item.play_from
b_dict['videoitem'] = item
autoplay_b.append(b_dict)
continue
autoplay_elem["indice_server"] = favorite_servers.index(item.server.lower())
elif priority == 3: # Only qualities
# if the quality is not in the favorites list or the url is repeated, we discard the item
if item.quality.lower() not in favorite_quality or item.url in url_list_valid:
item.type_b = True
item.play_from = base_item.play_from
b_dict['videoitem'] = item
autoplay_b.append(b_dict)
continue
autoplay_elem["indice_quality"] = favorite_quality.index(item.quality.lower())
else: # Do not order
# if the url is repeated, we discard the item
item.play_from = base_item.play_from
if item.url in url_list_valid:
continue
# If the item reaches here we add it to the list of valid urls and to autoplay_list
url_list_valid.append(item.url)
item.plan_b=True
item.play_from = base_item.play_from
autoplay_elem['videoitem'] = item
autoplay_list.append(autoplay_elem)
# We order according to priority
if priority == 0: autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server'])) # Servers and qualities
elif priority == 1: autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server'])) # Qualities and servers
elif priority == 2: autoplay_list.sort(key=lambda orden: (orden['indice_server'])) # Servers only
elif priority == 3: autoplay_list.sort(key=lambda orden: (orden['indice_quality'])) # Only qualities
# if quality priority is active
if priority == 0 and config.get_setting('quality_priority'):
max_quality = autoplay_list[0]["indice_quality"] if autoplay_list and "indice_quality" in autoplay_list[0] else 0
for n, item in enumerate(itemlist):
if 'server' not in item:
continue
if item.server.lower() in blacklisted_servers:
continue
# If it does not have a defined quality, it assigns a 'default' quality.
if item.quality == '':
item.quality = 'default'
if favorite_quality.index(item.quality.lower()) < max_quality:
item.type_b = False
autoplay_elem["indice_server"] = n
autoplay_elem["indice_quality"] = favorite_quality.index(item.quality.lower())
autoplay_elem['videoitem'] = item
autoplay_list.append(autoplay_elem)
autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server']))
# Plan b is prepared, in case it is active the non-favorite elements are added at the end
# try: plan_b = settings_node['plan_b']
# except:
plan_b = True
text_b = ''
if plan_b: autoplay_list.extend(autoplay_b)
# If there are elements in the autoplay list, an attempt is made to reproduce each element, until one is found or all fail.
if autoplay_list or (plan_b and autoplay_b):
max_intentos = 5
max_intentos_servers = {}
# If something is playing it stops playing
if platformtools.is_playing():
platformtools.stop_video()
for autoplay_elem in autoplay_list:
play_item = Item
channel_id = autoplay_elem['videoitem'].channel
if autoplay_elem['videoitem'].channel == 'videolibrary':
channel_id = autoplay_elem['videoitem'].contentChannel
# If it is not a favorite element if you add the text plan b
if autoplay_elem['videoitem'].type_b:
text_b = '(Plan B)'
if not platformtools.is_playing() and not PLAYED:
videoitem = autoplay_elem['videoitem']
if videoitem.server.lower() not in max_intentos_servers:
max_intentos_servers[videoitem.server.lower()] = max_intentos
# If the maximum number of attempts of this server have been reached, we jump to the next
if max_intentos_servers[videoitem.server.lower()] == 0:
continue
lang = " "
if hasattr(videoitem, 'language') and videoitem.language != "":
lang = " '%s' " % videoitem.language
name = servername(videoitem.server)
platformtools.dialog_notification("AutoPlay %s" %text_b, "%s%s%s" % (name, lang, videoitem.quality.upper()), sound=False)
# Try to play the links If the channel has its own play method, use it
try: channel = __import__('channels.%s' % channel_id, None, None, ["channels.%s" % channel_id])
except: channel = __import__('specials.%s' % channel_id, None, None, ["specials.%s" % channel_id])
if hasattr(channel, 'play'):
resolved_item = getattr(channel, 'play')(videoitem)
if len(resolved_item) > 0:
if isinstance(resolved_item[0], list): videoitem.video_urls = resolved_item
else: videoitem = resolved_item[0]
# If not directly reproduce and mark as seen
# Check if the item comes from the video library
try:
if base_item.contentChannel == 'videolibrary' or base_item.nfo:
# Fill the video with the data of the main item and play
play_item = base_item.clone(**videoitem.__dict__)
platformtools.play_video(play_item, autoplay=True)
else:
# If it doesn't come from the video library, just play
platformtools.play_video(videoitem, autoplay=True)
except:
pass
sleep(3)
try:
if platformtools.is_playing():
PLAYED = True
break
except:
logger.debug(str(len(autoplay_list)))
# If we have come this far, it is because it could not be reproduced
max_intentos_servers[videoitem.server.lower()] -= 1
# If the maximum number of attempts of this server has been reached, ask if we want to continue testing or ignore it.
if max_intentos_servers[videoitem.server.lower()] == 0:
text = config.get_localized_string(60072) % name
if not platformtools.dialog_yesno("AutoPlay", text, config.get_localized_string(60073)):
max_intentos_servers[videoitem.server.lower()] = max_intentos
# If there are no items in the list, it is reported
if autoplay_elem == autoplay_list[-1]:
platformtools.dialog_notification('AutoPlay', config.get_localized_string(60072) % name)
else:
platformtools.dialog_notification(config.get_localized_string(60074), config.get_localized_string(60075))
# Restore if necessary the previous value of "Action and Player Mode" in preferences
if not user_config_setting_action: config.set_setting("default_action", user_config_setting_action)
if user_config_setting_player != 0: config.set_setting("player_mode", user_config_setting_player)
return itemlist
def play_multi_channel(item, itemlist):
logger.info()
start(itemlist, item)
def servername(server):
from core.servertools import translate_server_name
path = filetools.join(config.get_runtime_path(), 'servers', server.lower() + '.json')
name = jsontools.load(open(path, "r").read())['name'].upper()
return translate_server_name(name)
-567
View File
@@ -1,567 +0,0 @@
# -*- 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, info
from platformcode import config, platformtools
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=''):
info()
dict_series = load(itemlist[0]) if len(itemlist) > 0 else {}
if item:
# from core.support import dbg;dbg()
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):
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):
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):
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 item in itemlist:
Title = re.sub(r'\d+x\d+ - ', '', item.title)
if modify == True:
ep = int(scrapertools.find_single_match(Title, r'(\d+)'))
if item.action == 'findvideos' and str(ep) not in EpisodeDict:
_list.append(Title)
else:
if item.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))
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):
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):
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)
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):
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):
info()
ch = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel])
itemlist = ch.episodios(item)
return itemlist
def RepresentsInt(s):
# Controllo Numro Stagione
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):
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):
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):
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
View File
@@ -1,96 +0,0 @@
# -*- 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
View File
@@ -1,297 +0,0 @@
# -*- 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:
xbmc.log("check_Adsl rslt: %s" % rslt['code'], level=xbmc.LOGNOTICE)
# 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)
xbmc.log("check_Dns result: %s" % r, level=xbmc.LOGNOTICE)
http_errr = 0
for rslt in r:
xbmc.log("check_Dns rslt: %s" % rslt['code'], level=xbmc.LOGNOTICE)
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
xbmc.log("Risultato nel try: %s" % (r,), level=xbmc.LOGNOTICE)
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:
xbmc.log("r1 http_Resp: %s %s %s %s" %
(code.status, code.reason, code.previous['status'],
code.previous['-x-permanent-redirect-url']), level=xbmc.LOGNOTICE)
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))
xbmc.log("############ Start Check DNS ############", level=xbmc.LOGNOTICE)
xbmc.log("## IP: %s" % (ktest.ip_addr), level=xbmc.LOGNOTICE)
xbmc.log("## DNS: %s" % (ktest.dns), level=xbmc.LOGNOTICE)
xbmc.log("############# End Check DNS #############", level=xbmc.LOGNOTICE)
# 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)
-2
View File
@@ -7,7 +7,6 @@ import re, inspect, xbmcgui
from core import httptools, jsontools, tmdb, support, filetools
from core.item import Item
from platformcode import config, platformtools
from specials import autoplay
from channelselector import get_thumb
from collections import OrderedDict
@@ -735,7 +734,6 @@ def relative(key, json, path):
def pagination(item, itemlist = []):
support.info()
import json
itlist = []
if not itemlist:
+2 -3
View File
@@ -8,7 +8,6 @@ from __future__ import division
import sys, os
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
from future.builtins import filter
from past.utils import old_div
import re, time, unicodedata, xbmc
@@ -18,7 +17,7 @@ from core import filetools, jsontools, scraper, scrapertools, servertools, video
from core.downloader import Downloader
from core.item import Item
from platformcode import config, logger, platformtools
from core.support import info, dbg, typo
from core.support import info, typo
from servers import torrent
kb = '0xFF65B3DA'
@@ -865,7 +864,7 @@ def get_episodes(item):
itemlist = []
if episodes and not scrapertools.find_single_match(episodes[0].title, r'(\d+.\d+)') and item.channel not in ['videolibrary'] and item.action != 'season':
from specials.autorenumber import select_type, renumber, check
from core.autorenumber import select_type, renumber, check
# support.dbg()
if not check(item):
select_type(item)
-135
View File
@@ -1,135 +0,0 @@
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.infoger.error(e)
import traceback
support.infoger.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']
-658
View File
@@ -1,658 +0,0 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# filtertools - is responsible for filtering results
# ------------------------------------------------------------
from builtins import object
from core import jsontools
from core.item import Item
from platformcode import config, logger
from platformcode import platformtools
from core import channeltools
TAG_TVSHOW_FILTER = "TVSHOW_FILTER"
TAG_NAME = "name"
TAG_ACTIVE = "active"
TAG_LANGUAGE = "language"
TAG_QUALITY_ALLOWED = "quality_allowed"
COLOR = {"parent_item": "yellow", "error": "red", "striped_even_active": "blue",
"striped_even_inactive": "0xff00bfff", "striped_odd_active": "0xff008000",
"striped_odd_inactive": "0xff00fa9a", "selected": "blue"
}
filter_global = None
__channel__ = "filtertools"
# TODO take a look at https://pyformat.info/, you can format the style and make references directly to elements
class ResultFilter(object):
def __init__(self, dict_filter):
self.active = dict_filter[TAG_ACTIVE]
self.language = dict_filter[TAG_LANGUAGE]
self.quality_allowed = dict_filter[TAG_QUALITY_ALLOWED]
def __str__(self):
return "{active: '%s', language: '%s', quality_allowed: '%s'}" % (self.active, self.language, self.quality_allowed)
class Filter(object):
def __init__(self, item, global_filter_lang_id):
self.result = None
self.__get_data(item, global_filter_lang_id)
def __get_data(self, item, global_filter_lang_id):
dict_filtered_shows = jsontools.get_node_from_file(item.channel, TAG_TVSHOW_FILTER)
tvshow = item.show.lower().strip()
global_filter_language = config.get_setting(global_filter_lang_id, item.channel)
if tvshow in list(dict_filtered_shows.keys()):
self.result = ResultFilter({TAG_ACTIVE: dict_filtered_shows[tvshow][TAG_ACTIVE],
TAG_LANGUAGE: dict_filtered_shows[tvshow][TAG_LANGUAGE],
TAG_QUALITY_ALLOWED: dict_filtered_shows[tvshow][TAG_QUALITY_ALLOWED]})
# general option "do not filter"
elif global_filter_language != 0:
from core import channeltools
list_controls, dict_settings = channeltools.get_channel_controls_settings(item.channel)
for control in list_controls:
if control["id"] == global_filter_lang_id:
try:
language = control["lvalues"][global_filter_language]
# logger.debug("language %s" % language)
except:
logger.error("The value associated with the code was not found '%s': %s" % (global_filter_lang_id, global_filter_language))
break
self.result = ResultFilter({TAG_ACTIVE: True, TAG_LANGUAGE: language, TAG_QUALITY_ALLOWED: []})
break
def __str__(self):
return "{'%s'}" % self.result
def access():
"""
Returns whether or not filtertools can be used
"""
allow = False
if config.is_xbmc() or config.get_platform() == "mediaserver":
allow = True
return allow
def context(item, list_language=None, list_quality=None, exist=False):
"""
For xbmc / kodi and mediaserver since they can show the contextual menu, a filter option is added to the configuration menu, only if it is for series.
Depending on the place and if there is a filter, more options will be added to show.
The context -is shown only for series-.
@param item: eelement to get the information and see what context to add
@type item: item
param list_language: list of possible languages
@type list_language: list[str]
@param list_quality: list of possible qualities
@type list_quality: list[str]
@param exist: if the filter exists
@type exist: bool
@return: list of options to display in the context menu
@rtype: list
"""
# Depending on how the context is, we save it and add the filtertools options.
if isinstance(item.context, str):
_context = item.context.split("|")
elif isinstance(item.context, list):
_context = item.context
else:
_context = []
if access():
dict_data = {"title": config.get_localized_string(60426), "action": "config_item", "channel": "filtertools"}
if list_language:
dict_data["list_language"] = list_language
if list_quality:
dict_data["list_quality"] = list_quality
added = False
if isinstance(_context, list):
for x in _context:
if x and isinstance(x, dict):
if x["channel"] == "filtertools":
added = True
break
if not added:
_context.append(dict_data)
if item.action == "play":
if not exist:
_context.append({"title": config.get_localized_string(60427) % item.language, "action": "save_from_context",
"channel": "filtertools", "from_channel": item.channel})
else:
_context.append({"title": config.get_localized_string(60428) % item.language, "action": "delete_from_context",
"channel": "filtertools", "from_channel": item.channel})
return _context
def show_option(itemlist, channel, list_language, list_quality):
if access():
itemlist.append(Item(channel=__channel__, title=config.get_localized_string(60429) % COLOR.get("parent_item", "auto"), action="load",
list_language=list_language, list_quality=list_quality, from_channel=channel))
return itemlist
def load(item):
return mainlist(channel=item.from_channel, list_language=item.list_language, list_quality=item.list_quality)
def check_conditions(_filter, list_item, item, list_language, list_quality, quality_count=0, language_count=0):
is_language_valid = True
if _filter.language:
# logger.debug("title es %s" % item.title)
# 2nd lang
from platformcode import unify
_filter.language = unify.set_lang(_filter.language).upper()
# comes from episodes
if isinstance(item.language, list):
# 2nd lang
for n, lang in enumerate(item.language):
item.language[n] = unify.set_lang(lang).upper()
if _filter.language in item.language:
language_count += 1
else:
is_language_valid = False
# comes from findvideos
else:
# 2nd lang
item.language = unify.set_lang(item.language).upper()
if item.language.lower() == _filter.language.lower():
language_count += 1
else:
is_language_valid = False
is_quality_valid = True
quality = ""
if _filter.quality_allowed and item.quality != "":
# if hasattr (item, 'quality'): # this validation is not necessary because the empty attribute is ALWAYS returned
if item.quality.lower() in _filter.quality_allowed:
quality = item.quality.lower()
quality_count += 1
else:
is_quality_valid = False
if is_language_valid and is_quality_valid:
#TODO 2nd lang: we should see if it is convenient to unify the language here or not
item.list_language = list_language
if list_quality:
item.list_quality = list_quality
item.context = context(item, exist=True)
list_item.append(item)
# logger.debug("{0} | context: {1}".format(item.title, item.context))
# logger.debug(" -Enlace añadido")
elif not item.language:
list_item.append(item)
logger.debug(" idioma valido?: %s, item.language: %s, filter.language: %s" % (is_language_valid, item.language, _filter.language))
logger.debug(" calidad valida?: %s, item.quality: %s, filter.quality_allowed: %s" % (is_quality_valid, quality, _filter.quality_allowed))
return list_item, quality_count, language_count, _filter.language
def get_link(list_item, item, list_language, list_quality=None, global_filter_lang_id="filter_languages"):
"""
Returns a list of links, if the item is correctly filtered it is added to the received list.
@param list_item: list of links
@type list_item: list[Item]
@param item: element to filter
@type item: Item
@param list_language: list of possible languages
@type list_language: list[str]
@param list_quality: list of possible qualities
@type list_quality: list[str]
@param global_filter_lang_id: id of the filtering variable by language that is in settings
@type global_filter_lang_id: str
@return: Item list
@rtype: list[Item]
"""
logger.info()
# if the required fields are None we leave
if list_item is None or item is None:
return []
logger.debug("total de items : %s" % len(list_item))
global filter_global
if not filter_global:
filter_global = Filter(item, global_filter_lang_id).result
logger.debug("filter: '%s' datos: '%s'" % (item.show, filter_global))
if filter_global and filter_global.active:
list_item, quality_count, language_count = check_conditions(filter_global, list_item, item, list_language, list_quality)[:3]
else:
item.context = context(item)
list_item.append(item)
return list_item
def get_links(list_item, item, list_language, list_quality=None, global_filter_lang_id="filter_languages"):
"""
Returns a list of filtered links.
@param list_item: list of links
@type list_item: list[Item]
@param item: element to filter
@type item: item
@param list_language: list of possible languages
@type list_language: list[str]
@param list_quality: list of possible qualities
@type list_quality: list[str]
@param global_filter_lang_id: id of the filtering variable by language that is in settings
@type global_filter_lang_id: str
@return: lista de Item
@rtype: list[Item]
"""
logger.info()
# if the required fields are None we leave
if list_item is None or item is None:
return []
# if list_item is empty we go back, no platform validation is added so Plex can do global filter
if len(list_item) == 0:
return list_item
second_lang = config.get_setting('second_language')
logger.debug("total de items : %s" % len(list_item))
new_itemlist = []
quality_count = 0
language_count = 0
_filter = Filter(item, global_filter_lang_id).result
logger.debug("filter: '%s' datos: '%s'" % (item.show, _filter))
if _filter and _filter.active:
for item in list_item:
new_itemlist, quality_count, language_count, first_lang = check_conditions(_filter, new_itemlist, item, list_language, list_quality, quality_count, language_count)
#2nd lang
if second_lang and second_lang != 'No' and first_lang.lower() != second_lang.lower() :
second_list= []
_filter2 = _filter
_filter2.language = second_lang
for it in new_itemlist:
if isinstance(it.language, list):
if not second_lang in it.language:
second_list.append(it)
else:
second_list = new_itemlist
break
for item in list_item:
new_itemlist, quality_count, language_count, second_lang = check_conditions(_filter2, second_list, item, list_language, list_quality, quality_count, language_count)
logger.debug("FILTERED ITEMS: %s/%s, language [%s]: %s, allowed quality %s: %s" % (len(new_itemlist), len(list_item), _filter.language, language_count, _filter.quality_allowed, quality_count))
if len(new_itemlist) == 0:
list_item_all = []
for i in list_item:
list_item_all.append(i.tourl())
_context = [{"title": config.get_localized_string(60430) % _filter.language, "action": "delete_from_context", "channel": "filtertools", "to_channel": item.channel}]
if _filter.quality_allowed:
msg_quality_allowed = " y calidad %s" % _filter.quality_allowed
else:
msg_quality_allowed = ""
msg_lang = ' %s' % first_lang.upper()
if second_lang and second_lang != 'No':
msg_lang = 's %s ni %s' % (first_lang.upper(), second_lang.upper())
new_itemlist.append(Item(channel=__channel__, action="no_filter", list_item_all=list_item_all,
show=item.show,
title=config.get_localized_string(60432) % (_filter.language, msg_quality_allowed),
context=_context))
else:
for item in list_item:
item.list_language = list_language
if list_quality:
item.list_quality = list_quality
item.context = context(item)
new_itemlist = list_item
return new_itemlist
def no_filter(item):
"""
Muestra los enlaces sin filtrar
@param item: item
@type item: Item
@return: lista de enlaces
@rtype: list[Item]
"""
logger.info()
itemlist = []
for i in item.list_item_all:
itemlist.append(Item().fromurl(i))
return itemlist
def mainlist(channel, list_language, list_quality):
"""
Shows a list of the leaked series
@param channel: channel name to get filtered series
@type channel: str
@param list_language: channel language list
@type list_language: list[str]
@param list_quality: channel quality list
@type list_quality: list[str]
@return: Item list
@rtype: list[Item]
"""
logger.info()
itemlist = []
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_FILTER)
idx = 0
for tvshow in sorted(dict_series):
if idx % 2 == 0:
if dict_series[tvshow][TAG_ACTIVE]:
tag_color = COLOR.get("striped_even_active", "auto")
else:
tag_color = COLOR.get("striped_even_inactive", "auto")
else:
if dict_series[tvshow][TAG_ACTIVE]:
tag_color = COLOR.get("striped_odd_active", "auto")
else:
tag_color = COLOR.get("striped_odd_inactive", "auto")
idx += 1
name = dict_series.get(tvshow, {}).get(TAG_NAME, tvshow)
activo = config.get_localized_string(60433)
if dict_series[tvshow][TAG_ACTIVE]:
activo = ""
title = config.get_localized_string(60434) % (tag_color, name, activo)
itemlist.append(Item(channel=__channel__, action="config_item", title=title, show=name,
list_language=list_language, list_quality=list_quality, from_channel=channel))
if len(itemlist) == 0:
itemlist.append(Item(channel=channel, action="mainlist", title=config.get_localized_string(60435)))
return itemlist
def config_item(item):
"""
displays a filtered series for your setup
@param item: item
@type item: Item
"""
logger.info()
logger.info("item %s" % item.tostring())
# WE GET THE JSON DATA
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.lower().strip()
default_lang = ''
channel_parameters = channeltools.get_channel_parameters(item.from_channel)
list_language = channel_parameters["filter_languages"]
try:
if channel_parameters["filter_languages"] != '' and len(list_language) > 0:
default_lang = list_language[1]
except:
pass
if default_lang == '':
platformtools.dialog_notification("FilterTools", "There are no defined languages")
return
else:
lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, default_lang)
list_quality = dict_series.get(tvshow, {}).get(TAG_QUALITY_ALLOWED, [x.lower() for x in item.list_quality])
# logger.info("lang selected {}".format(lang_selected))
# logger.info("list quality {}".format(list_quality))
active = True
custom_button = {'visible': False}
allow_option = False
if item.show.lower().strip() in dict_series:
allow_option = True
active = dict_series.get(item.show.lower().strip(), {}).get(TAG_ACTIVE, False)
custom_button = {'label': config.get_localized_string(60437), 'function': 'delete', 'visible': True, 'close': True}
list_controls = []
if allow_option:
active_control = {
"id": "active",
"type": "bool",
"label": config.get_localized_string(60438),
"color": "",
"default": active,
"enabled": allow_option,
"visible": allow_option,
}
list_controls.append(active_control)
language_option = {
"id": "language",
"type": "list",
"label": config.get_localized_string(60439),
# "color": "0xFFee66CC",
"default": item.list_language.index(lang_selected),
"enabled": True,
"visible": True,
"lvalues": item.list_language
}
list_controls.append(language_option)
if item.list_quality:
list_controls_calidad = [
{
"id": "textoCalidad",
"type": "label",
"label": "Calidad permitida",
"color": "0xffC6C384",
"enabled": True,
"visible": True,
},
]
for element in sorted(item.list_quality, key=str.lower):
list_controls_calidad.append({
"id": element,
"type": "bool",
"label": element,
"default": (False, True)[element.lower() in list_quality],
"enabled": True,
"visible": True,
})
# we concatenate list_controls with list_controls_quality
list_controls.extend(list_controls_calidad)
title = config.get_localized_string(60441) % (COLOR.get("selected", "auto"), item.show)
platformtools.show_channel_settings(list_controls=list_controls, callback='save', item=item,
caption=title, custom_button=custom_button)
def delete(item, dict_values):
logger.info()
if item:
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
heading = config.get_localized_string(60442)
line1 = config.get_localized_string(60443) % (COLOR.get("selected", "auto"), item.show.strip())
if platformtools.dialog_yesno(heading, line1) == 1:
lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "")
dict_series.pop(tvshow, None)
result, json_data = jsontools.update_node(dict_series, item.from_channel, TAG_TVSHOW_FILTER)
sound = False
if result:
message = config.get_localized_string(60444)
else:
message = config.get_localized_string(60445)
sound = True
heading = "%s [%s]" % (item.show.strip(), lang_selected)
platformtools.dialog_notification(heading, message, sound=sound)
if item.action in ["findvideos", "play"]:
platformtools.itemlist_refresh()
def save(item, dict_data_saved):
"""
Save the configured values in the window
@param item: item
@type item: Item
@param dict_data_saved: dictionary with saved data
@type dict_data_saved: dict
"""
logger.info()
if item and dict_data_saved:
logger.debug('item: %s\ndatos: %s' % (item.tostring(), dict_data_saved))
if item.from_channel == "videolibrary":
item.from_channel = item.contentChannel
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
logger.info("Data is updated")
list_quality = []
for _id, value in list(dict_data_saved.items()):
if _id in item.list_quality and value:
list_quality.append(_id.lower())
lang_selected = item.list_language[dict_data_saved[TAG_LANGUAGE]]
dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True),
TAG_LANGUAGE: lang_selected, TAG_QUALITY_ALLOWED: list_quality}
dict_series[tvshow] = dict_filter
result, json_data = jsontools.update_node(dict_series, item.from_channel, TAG_TVSHOW_FILTER)
sound = False
if result:
message = config.get_localized_string(60446)
else:
message = config.get_localized_string(70593)
sound = True
heading = "%s [%s]" % (item.show.strip(), lang_selected)
platformtools.dialog_notification(heading, message, sound=sound)
if item.from_action in ["findvideos", "play"]:
platformtools.itemlist_refresh()
def save_from_context(item):
"""
Save the filter through the context menu
@param item: item
@type item: item
"""
logger.info()
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: True, TAG_LANGUAGE: item.language, TAG_QUALITY_ALLOWED: []}
dict_series[tvshow] = dict_filter
result, json_data = jsontools.update_node(dict_series, item.from_channel, TAG_TVSHOW_FILTER)
sound = False
if result:
message = "SAVED FILTER"
else:
message = "Error saving to disk"
sound = True
heading = "%s [%s]" % (item.show.strip(), item.language)
platformtools.dialog_notification(heading, message, sound=sound)
if item.from_action in ["findvideos", "play"]:
platformtools.itemlist_refresh()
def delete_from_context(item):
"""
Delete the filter through the context menu
@param item: item
@type item: item
"""
logger.info()
# We come from get_links and no result has been obtained, in context menu and we delete
if item.to_channel != "":
item.from_channel = item.to_channel
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "")
dict_series.pop(tvshow, None)
result, json_data = jsontools.update_node(dict_series, item.from_channel, TAG_TVSHOW_FILTER)
sound = False
if result:
message = "FILTER REMOVED"
else:
message = "Error saving to disk"
sound = True
heading = "%s [%s]" % (item.show.strip(), lang_selected)
platformtools.dialog_notification(heading, message, sound=sound)
if item.from_action in ["findvideos", "play", "no_filter"]: # 'no_filter' es el mismo caso que L#601
platformtools.itemlist_refresh()
-1093
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -247,7 +247,7 @@ def novedades(item):
list_canales, any_active = get_channels_list()
if config.is_xbmc():
from specials import side_menu
from platformcode import side_menu
if mode=='silent' and any_active and len(list_canales[item.extra]) > 0:
side_menu.set_menu_settings(item)
aux_list=[]
-151
View File
@@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
import os, sys, ssl
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
if PY3:
import urllib.parse as urlparse
import _ssl
DEFAULT_CIPHERS = _ssl._DEFAULT_CIPHERS
else:
import urlparse
DEFAULT_CIPHERS = ssl._DEFAULT_CIPHERS
from lib.requests_toolbelt.adapters import host_header_ssl
from lib import doh
from platformcode import logger, config
import requests
from core import scrapertools
try:
import _sqlite3 as sql
except:
import sqlite3 as sql
db = os.path.join(config.get_data_path(), 'kod_db.sqlite')
if 'PROTOCOL_TLS' in ssl.__dict__:
protocol = ssl.PROTOCOL_TLS
elif 'PROTOCOL_SSLv23' in ssl.__dict__:
protocol = ssl.PROTOCOL_SSLv23
else:
protocol = ssl.PROTOCOL_SSLv3
class CustomContext(ssl.SSLContext):
def __init__(self, protocol, hostname, *args, **kwargs):
self.hostname = hostname
if PY3:
super(CustomContext, self).__init__()
else:
super(CustomContext, self).__init__(protocol)
self.verify_mode = ssl.CERT_NONE
def wrap_socket(self, *args, **kwargs):
kwargs['server_hostname'] = self.hostname
self.verify_mode = ssl.CERT_NONE
return super(CustomContext, self).wrap_socket(*args, **kwargs)
class CipherSuiteAdapter(host_header_ssl.HostHeaderSSLAdapter):
def __init__(self, domain, CF=False, *args, **kwargs):
self.conn = sql.connect(db)
self.cur = self.conn.cursor()
self.ssl_context = CustomContext(protocol, domain)
self.CF = CF # if cloudscrape is in action
self.cipherSuite = kwargs.pop('cipherSuite', DEFAULT_CIPHERS)
super(CipherSuiteAdapter, self).__init__(**kwargs)
def flushDns(self, request, domain, **kwargs):
self.cur.execute('delete from dnscache where domain=?', (domain,))
self.conn.commit()
return self.send(request, flushedDns=True, **kwargs)
def getIp(self, domain):
ip = None
try:
self.cur.execute('select ip from dnscache where domain=?', (domain,))
ip = self.cur.fetchall()[0][0]
logger.info('Cache DNS: ' + domain + ' = ' + str(ip))
except:
pass
if not ip: # not cached
try:
ip = doh.query(domain)[0]
logger.info('Query DoH: ' + domain + ' = ' + str(ip))
self.writeToCache(domain, ip)
except Exception:
logger.error('Failed to resolve hostname, fallback to normal dns')
import traceback
logger.error(traceback.print_exc())
return ip
def writeToCache(self, domain, ip):
try:
self.cur.execute('insert into dnscache values(?,?)', (domain, ip))
except:
self.cur.execute("""CREATE TABLE IF NOT EXISTS dnscache(
"domain" TEXT NOT NULL UNIQUE,
"ip" TEXT NOT NULL,
PRIMARY KEY("domain")
);""")
self.conn.commit()
def init_poolmanager(self, *args, **kwargs):
kwargs['ssl_context'] = self.ssl_context
return super(CipherSuiteAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
kwargs['ssl_context'] = self.ssl_context
return super(CipherSuiteAdapter, self).proxy_manager_for(*args, **kwargs)
def send(self, request, flushedDns=False, **kwargs):
try:
parse = urlparse.urlparse(request.url)
except:
raise requests.exceptions.InvalidURL
if parse.netloc:
domain = parse.netloc
else:
raise requests.exceptions.URLRequired
if not scrapertools.find_single_match(domain, '\d+\.\d+\.\d+\.\d+'):
ip = self.getIp(domain)
else:
ip = None
if ip:
self.ssl_context = CustomContext(protocol, domain)
if self.CF:
self.ssl_context.options |= (ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
self.ssl_context.set_ciphers(self.cipherSuite)
self.init_poolmanager(self._pool_connections, self._pool_maxsize, block=self._pool_block)
realUrl = request.url
if request.headers:
request.headers["Host"] = domain
else:
request.headers = {"Host": domain}
ret = None
tryFlush = False
parse = list(parse)
parse[1] = ip
request.url = urlparse.urlunparse(parse)
try:
ret = super(CipherSuiteAdapter, self).send(request, **kwargs)
except Exception as e:
logger.info('Request for ' + domain + ' with ip ' + ip + ' failed')
logger.info(e)
# if 'SSLError' in str(e):
# # disabilito
# config.set_setting("resolver_dns", False)
# request.url = realUrl
# ret = super(CipherSuiteAdapter, self).send(request, **kwargs)
# else:
tryFlush = True
if tryFlush and not flushedDns: # re-request ips and update cache
logger.info('Flushing dns cache for ' + domain)
return self.flushDns(request, domain, **kwargs)
ret.url = realUrl
else:
ret = super(host_header_ssl.HostHeaderSSLAdapter, self).send(request, **kwargs)
return ret
+2 -1
View File
@@ -558,7 +558,8 @@ def genres_menu(item):
itemlist.append(Item(channel=item.channel, title=typo(value, 'bold'), page=1,
action='discover_list', discovery=discovery,
mode=item.mode))
channelselector.thumb(itemlist)
from core import support
support.thumb(itemlist)
return sorted(itemlist, key=lambda it: it.title)
-151
View File
@@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
from core.item import Item
from platformcode import logger
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/?ewogICAgImFjdGlvbiI6ICJzaWRlX21lbnUiLCAKICAgICJjaGFubmVsIjogInNob3J0Y3V0cyIsIAogICAgImluZm9MYWJlbHMiOiB7fQp9)'))
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):
from specials import side_menu
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])
-365
View File
@@ -1,365 +0,0 @@
# -*- 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, xbmcplugin, xbmcaddon
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:
from specials import side_menu
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))
+1 -1
View File
@@ -1763,7 +1763,7 @@ def imagenes(item):
return itemlist
if item.images:
from specials import infoplus
from platformcode import infoplus
for key, value in item.images.iteritems():
if key == "tmdb" and "Tmdb" in item.title:
if item.folder:
+2 -3
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#from builtins import str
import sys, xbmc, os, traceback
import sys
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
@@ -12,7 +12,6 @@ from core import filetools, scrapertools, videolibrarytools
from core.support import typo, thumb
from core.item import Item
from platformcode import config, logger, platformtools
from lib import generictools
from distutils import dir_util
if PY3:
from concurrent import futures
@@ -383,7 +382,7 @@ def get_episodes(item):
def findvideos(item):
from specials import autoplay
from core import autoplay
logger.info()
# logger.debug("item:\n" + item.tostring('\n'))
videolibrarytools.check_renumber_options(item)