KoD 1.4
- completato il supporto al futuro Kodi 19\n- ridisegnato infoplus\n- fix vari ed eventuali\n
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
# -*- 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)
|
||||
+1
-1
@@ -113,7 +113,7 @@ class Downloader(object):
|
||||
line2 = config.get_localized_string(59983) % ( self.downloaded[1], self.downloaded[2], self.size[1], self.size[2], self.speed[1], self.speed[2], self.connections[0], self.connections[1])
|
||||
line3 = config.get_localized_string(60202) % (self.remaining_time)
|
||||
|
||||
progreso.update(int(self.progress), line1, line2 + " " + line3)
|
||||
progreso.update(int(self.progress), line1 + '\n' + line2 + " " + line3)
|
||||
self.__update_json()
|
||||
finally:
|
||||
progreso.close()
|
||||
|
||||
@@ -271,7 +271,7 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
|
||||
# Create the progress dialog
|
||||
if not silent:
|
||||
progreso = platformtools.dialog_progress(header, "Downloading...", url, nombrefichero)
|
||||
progreso = platformtools.dialog_progress(header, "Downloading..." + '\n' + url + '\n' + nombrefichero)
|
||||
|
||||
# If the platform does not return a valid dialog box, it assumes silent mode
|
||||
if progreso is None:
|
||||
@@ -408,7 +408,7 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
error = downloadfileRTMP(url, nombrefichero, silent)
|
||||
if error and not silent:
|
||||
from platformcode import platformtools
|
||||
platformtools.dialog_ok("You cannot download that video "," RTMP downloads not yet "," are supported")
|
||||
platformtools.dialog_ok("You cannot download that video "," RTMP downloads not yet supported")
|
||||
else:
|
||||
import traceback
|
||||
from pprint import pprint
|
||||
@@ -480,7 +480,7 @@ def downloadfileRTMP(url, nombrefichero, silent):
|
||||
rtmpdump_exit = spawnv(P_NOWAIT, rtmpdump_cmd, rtmpdump_args)
|
||||
if not silent:
|
||||
from platformcode import platformtools
|
||||
advertencia = platformtools.dialog_ok("RTMP download option is experimental", "and the video will download in the background.", "No progress bar will be displayed.")
|
||||
advertencia = platformtools.dialog_ok("RTMP download option is experimental", "and the video will download in the background. \n No progress bar will be displayed.")
|
||||
except:
|
||||
return True
|
||||
|
||||
@@ -520,7 +520,7 @@ def downloadfileGzipped(url, pathfichero):
|
||||
|
||||
# Create the progress dialog
|
||||
from platformcode import platformtools
|
||||
progreso = platformtools.dialog_progress("addon", config.get_localized_string(60200), url.split("|")[0], nombrefichero)
|
||||
progreso = platformtools.dialog_progress("addon", config.get_localized_string(60200) + '\n' + url.split("|")[0] + '\n' + nombrefichero)
|
||||
|
||||
# Socket timeout at 60 seconds
|
||||
socket.setdefaulttimeout(10)
|
||||
|
||||
@@ -0,0 +1,658 @@
|
||||
# -*- 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()
|
||||
+19
-16
@@ -137,7 +137,7 @@ load_cookies()
|
||||
|
||||
def save_cookies(alfa_s=False):
|
||||
cookies_lock.acquire()
|
||||
if not alfa_s: logger.info("Saving cookies...")
|
||||
if not alfa_s: logger.debug("Saving cookies...")
|
||||
cj.save(cookies_file, ignore_discard=True)
|
||||
cookies_lock.release()
|
||||
|
||||
@@ -161,7 +161,7 @@ def random_useragent():
|
||||
|
||||
|
||||
def show_infobox(info_dict):
|
||||
logger.info()
|
||||
logger.debug()
|
||||
from textwrap import wrap
|
||||
|
||||
box_items_kodi = {'r_up_corner': u'\u250c',
|
||||
@@ -186,16 +186,16 @@ def show_infobox(info_dict):
|
||||
|
||||
|
||||
|
||||
width = 60
|
||||
width = 100
|
||||
version = '%s: %s' % (config.get_localized_string(20000), __version)
|
||||
if config.is_xbmc():
|
||||
box = box_items_kodi
|
||||
else:
|
||||
box = box_items
|
||||
|
||||
logger.info('%s%s%s' % (box['r_up_corner'], box['fill'] * width, box['l_up_corner']))
|
||||
logger.info('%s%s%s' % (box['center'], version.center(width), box['center']))
|
||||
logger.info('%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center']))
|
||||
logger.debug('%s%s%s' % (box['r_up_corner'], box['fill'] * width, box['l_up_corner']))
|
||||
logger.debug('%s%s%s' % (box['center'], version.center(width), box['center']))
|
||||
logger.debug('%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center']))
|
||||
|
||||
count = 0
|
||||
for key, value in info_dict:
|
||||
@@ -210,13 +210,13 @@ def show_infobox(info_dict):
|
||||
for line in text:
|
||||
if len(line) < width:
|
||||
line = line.ljust(width, ' ')
|
||||
logger.info('%s%s%s' % (box['center'], line, box['center']))
|
||||
logger.debug('%s%s%s' % (box['center'], line, box['center']))
|
||||
else:
|
||||
logger.info('%s%s%s' % (box['center'], text, box['center']))
|
||||
logger.debug('%s%s%s' % (box['center'], text, box['center']))
|
||||
if count < len(info_dict):
|
||||
logger.info('%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center']))
|
||||
logger.debug('%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center']))
|
||||
else:
|
||||
logger.info('%s%s%s' % (box['r_dn_corner'], box['fill'] * width, box['l_dn_corner']))
|
||||
logger.debug('%s%s%s' % (box['r_dn_corner'], box['fill'] * width, box['l_dn_corner']))
|
||||
return
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ def downloadpage(url, **opt):
|
||||
CF = True
|
||||
|
||||
if config.get_setting('resolver_dns') and not opt.get('use_requests', False):
|
||||
from specials import resolverdns
|
||||
from core import resolverdns
|
||||
session.mount('https://', resolverdns.CipherSuiteAdapter(domain, CF))
|
||||
|
||||
req_headers = default_headers.copy()
|
||||
@@ -402,6 +402,13 @@ def downloadpage(url, **opt):
|
||||
response['data'] = req.content if req.content else ''
|
||||
response['url'] = req.url
|
||||
|
||||
if type(response['data']) != str:
|
||||
try: response['data'] = response['data'].decode('utf-8')
|
||||
except: response['data'] = response['data'].decode('ISO-8859-1')
|
||||
|
||||
if not response['data']:
|
||||
response['data'] = ''
|
||||
|
||||
if req.headers.get('Server', '').startswith('cloudflare') and response_code in [429, 503, 403]\
|
||||
and not opt.get('CF', False) and 'Please turn JavaScript on and reload the page' in response['data']:
|
||||
# if domain not in CF_LIST:
|
||||
@@ -416,15 +423,11 @@ def downloadpage(url, **opt):
|
||||
response['data'] = re.sub('["|\']/save/[^"]*(https?://[^"]+)', '"\\1', response['data'])
|
||||
response['url'] = response['url'].replace('https://web.archive.org/save/', '')
|
||||
|
||||
if type(response['data']) != str:
|
||||
response['data'] = response['data'].decode('UTF-8')
|
||||
|
||||
if not response['data']:
|
||||
response['data'] = ''
|
||||
try:
|
||||
response['json'] = to_utf8(req.json())
|
||||
except:
|
||||
response['json'] = dict()
|
||||
|
||||
response['code'] = response_code
|
||||
response['headers'] = req.headers
|
||||
response['cookies'] = req.cookies
|
||||
|
||||
+2
-2
@@ -90,7 +90,7 @@ def get_node_from_file(name_file, node, path=None):
|
||||
@return: dict with the node to return
|
||||
@rtype: dict
|
||||
"""
|
||||
logger.info()
|
||||
logger.debug()
|
||||
from platformcode import config
|
||||
from core import filetools
|
||||
|
||||
@@ -129,7 +129,7 @@ def check_to_backup(data, fname, dict_data):
|
||||
@param dict_data: dictionary name
|
||||
@type dict_data: dict
|
||||
"""
|
||||
logger.info()
|
||||
logger.debug()
|
||||
|
||||
if not dict_data:
|
||||
logger.error("Error loading json from file %s" % fname)
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# -*- 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
|
||||
@@ -85,11 +85,12 @@ def decodeHtmlentities(data):
|
||||
|
||||
if match.group(1) == "#" and ent.replace(";", "").isdigit():
|
||||
ent = unichr(int(ent.replace(";", "")))
|
||||
return ent.encode('utf-8')
|
||||
return ent if PY3 else ent.encode('utf-8')
|
||||
else:
|
||||
cp = html5.get(ent)
|
||||
if cp:
|
||||
return cp.decode("unicode-escape").encode('utf-8') + res
|
||||
if PY3: return cp + res
|
||||
else: return cp.decode("unicode-escape").encode('utf-8') + res
|
||||
else:
|
||||
return match.group()
|
||||
|
||||
@@ -112,9 +113,11 @@ def unescape(text):
|
||||
# character reference
|
||||
try:
|
||||
if text[:3] == "&#x":
|
||||
return unichr(int(text[3:-1], 16)).encode("utf-8")
|
||||
ret = unichr(int(text[3:-1], 16))
|
||||
return ret if PY3 else ret.encode("utf-8")
|
||||
else:
|
||||
return unichr(int(text[2:-1])).encode("utf-8")
|
||||
ret = unichr(int(text[2:-1]))
|
||||
return ret if PY3 else ret.encode("utf-8")
|
||||
|
||||
except ValueError:
|
||||
logger.error("error de valor")
|
||||
|
||||
+7
-20
@@ -148,26 +148,13 @@ def findvideos(data, skip=False):
|
||||
devuelve = []
|
||||
skip = int(skip)
|
||||
servers_list = list(get_servers_list().keys())
|
||||
|
||||
|
||||
# is_filter_servers = False
|
||||
|
||||
# Run findvideos on each active server
|
||||
for serverid in servers_list:
|
||||
'''if not is_server_enabled(serverid):
|
||||
continue'''
|
||||
if config.get_setting('servers_blacklist') and serverid not in config.get_setting("black_list", server='servers'):
|
||||
# if config.get_setting("filter_servers") == True and config.get_setting("black_list", server=serverid):
|
||||
# is_filter_servers = True
|
||||
continue
|
||||
devuelve.extend(findvideosbyserver(data, serverid))
|
||||
if skip and len(devuelve) >= skip:
|
||||
devuelve = devuelve[:skip]
|
||||
break
|
||||
# if config.get_setting("filter_servers") == False: is_filter_servers = False
|
||||
# logger.info('DEVUELVE: ' + str(devuelve))
|
||||
# if not devuelve and is_filter_servers:
|
||||
# platformtools.dialog_ok(config.get_localized_string(60000), config.get_localized_string(60001))
|
||||
if is_server_enabled(serverid) :
|
||||
devuelve.extend(findvideosbyserver(data, serverid))
|
||||
if skip and len(devuelve) >= skip:
|
||||
devuelve = devuelve[:skip]
|
||||
break
|
||||
return devuelve
|
||||
|
||||
|
||||
@@ -710,9 +697,9 @@ def sort_servers(servers_list):
|
||||
"""
|
||||
if servers_list and config.get_setting('favorites_servers'):
|
||||
if isinstance(servers_list[0], Item):
|
||||
servers_list = sorted(servers_list, key=lambda x: config.get_setting("favorites_servers_list", server=x.server) or 100)
|
||||
servers_list = sorted(servers_list, key=lambda x: config.get_setting("favorites_servers_list", server=x.server))
|
||||
else:
|
||||
servers_list = sorted(servers_list, key=lambda x: config.get_setting("favorites_servers_list", server=x) or 100)
|
||||
servers_list = sorted(servers_list, key=lambda x: config.get_setting("favorites_servers_list", server=x))
|
||||
|
||||
return servers_list
|
||||
|
||||
|
||||
+193
-116
@@ -1,34 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -----------------------------------------------------------
|
||||
# support functions that are needed by many channels, to no repeat the same code
|
||||
import base64
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from time import time
|
||||
import base64, inspect, os, re, sys
|
||||
|
||||
PY3 = False
|
||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||||
if PY3:
|
||||
from concurrent import futures
|
||||
else:
|
||||
from concurrent_py2 import futures
|
||||
|
||||
try:
|
||||
import urllib.request as urllib
|
||||
from urllib.request import Request, urlopen
|
||||
import urllib.parse as urlparse
|
||||
from urllib.parse import urlencode
|
||||
except ImportError:
|
||||
import urllib, urlparse
|
||||
else:
|
||||
from concurrent_py2 import futures
|
||||
import urlparse
|
||||
from urllib2 import Request, urlopen
|
||||
from urllib import urlencode
|
||||
|
||||
from channelselector import thumb
|
||||
from core import httptools, scrapertools, servertools, tmdb, channeltools
|
||||
from time import time
|
||||
from core import httptools, scrapertools, servertools, tmdb, channeltools, autoplay
|
||||
from core.item import Item
|
||||
from lib import unshortenit
|
||||
from platformcode import logger, config
|
||||
from specials import autoplay
|
||||
from platformcode import config
|
||||
from platformcode.logger import info
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def hdpass_get_servers(item):
|
||||
def get_hosts(url, quality):
|
||||
@@ -38,29 +33,21 @@ def hdpass_get_servers(item):
|
||||
|
||||
for mir_url, srv in scrapertools.find_multiple_matches(mir, patron_option):
|
||||
mir_url = scrapertools.decodeHtmlentities(mir_url)
|
||||
log(mir_url)
|
||||
it = item.clone(action="play",
|
||||
quality=quality,
|
||||
title=srv,
|
||||
server=srv,
|
||||
url= mir_url)
|
||||
if not servertools.get_server_parameters(srv.lower()): # do not exists or it's empty
|
||||
it = hdpass_get_url(it)[0]
|
||||
info(mir_url)
|
||||
it = item.clone(action="play", quality=quality, title=srv, server=srv, url= mir_url)
|
||||
if not servertools.get_server_parameters(srv.lower()): it = hdpass_get_url(it)[0] # do not exists or it's empty
|
||||
ret.append(it)
|
||||
return ret
|
||||
# Carica la pagina
|
||||
itemlist = []
|
||||
if 'hdpass' in item.url or 'hdplayer' in item.url:
|
||||
url = item.url
|
||||
if 'hdpass' in item.url or 'hdplayer' in item.url: url = item.url
|
||||
else:
|
||||
data = httptools.downloadpage(item.url, CF=False).data.replace('\n', '')
|
||||
patron = r'<iframe(?: id="[^"]+")? width="[^"]+" height="[^"]+" src="([^"]+)"[^>]+><\/iframe>'
|
||||
url = scrapertools.find_single_match(data, patron)
|
||||
url = url.replace("&download=1", "")
|
||||
if 'hdpass' not in url and 'hdplayer' not in url:
|
||||
return itemlist
|
||||
if not url.startswith('http'):
|
||||
url = 'https:' + url
|
||||
if 'hdpass' not in url and 'hdplayer' not in url: return itemlist
|
||||
if not url.startswith('http'): url = 'https:' + url
|
||||
|
||||
data = httptools.downloadpage(url, CF=False).data
|
||||
patron_res = '<div class="buttons-bar resolutions-bar">(.*?)<div class="buttons-bar'
|
||||
@@ -68,7 +55,6 @@ def hdpass_get_servers(item):
|
||||
patron_option = r'<a href="([^"]+?)"[^>]+>([^<]+?)</a'
|
||||
|
||||
res = scrapertools.find_single_match(data, patron_res)
|
||||
# dbg()
|
||||
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
thL = []
|
||||
@@ -78,15 +64,14 @@ def hdpass_get_servers(item):
|
||||
for res in futures.as_completed(thL):
|
||||
if res.result():
|
||||
itemlist.extend(res.result())
|
||||
return server(item, itemlist=itemlist)
|
||||
|
||||
return server(item, itemlist=itemlist)
|
||||
|
||||
def hdpass_get_url(item):
|
||||
data = httptools.downloadpage(item.url, CF=False).data
|
||||
src = scrapertools.find_single_match(data, r'<iframe allowfullscreen custom-src="([^"]+)')
|
||||
if src:
|
||||
item.url = base64.b64decode(src)
|
||||
else:
|
||||
item.url = scrapertools.find_single_match(data, r'<iframe allowfullscreen src="([^"]+)')
|
||||
if src: item.url = base64.b64decode(src)
|
||||
else: item.url = scrapertools.find_single_match(data, r'<iframe allowfullscreen src="([^"]+)')
|
||||
item.url, c = unshortenit.unshorten_only(item.url)
|
||||
|
||||
return [item]
|
||||
@@ -96,9 +81,8 @@ def color(text, color):
|
||||
|
||||
|
||||
def search(channel, item, texto):
|
||||
log(item.url + " search " + texto)
|
||||
if 'findhost' in dir(channel):
|
||||
channel.findhost()
|
||||
info(item.url + " search " + texto)
|
||||
if 'findhost' in dir(channel): channel.findhost()
|
||||
item.url = channel.host + "/?s=" + texto
|
||||
try:
|
||||
return channel.peliculas(item)
|
||||
@@ -121,7 +105,7 @@ def dbg():
|
||||
|
||||
def regexDbg(item, patron, headers, data=''):
|
||||
if config.dev_mode():
|
||||
import json, urllib2, webbrowser
|
||||
import json, webbrowser
|
||||
url = 'https://regex101.com'
|
||||
|
||||
if not data:
|
||||
@@ -132,14 +116,15 @@ def regexDbg(item, patron, headers, data=''):
|
||||
html = data
|
||||
headers = {'content-type': 'application/json'}
|
||||
data = {
|
||||
'regex': patron.decode('utf-8'),
|
||||
'regex': patron if PY3 else patron.decode('utf-8'),
|
||||
'flags': 'gm',
|
||||
'testString': html.decode('utf-8'),
|
||||
'testString': html if PY3 else html.decode('utf-8'),
|
||||
'delimiter': '"""',
|
||||
'flavor': 'python'
|
||||
}
|
||||
r = urllib2.Request(url + '/api/regex', json.dumps(data, encoding='latin1'), headers=headers)
|
||||
r = urllib2.urlopen(r).read()
|
||||
data = json.dumps(data).encode() if PY3 else json.dumps(data, encoding='latin1')
|
||||
r = Request(url + '/api/regex', data, headers=headers)
|
||||
r = urlopen(r).read()
|
||||
permaLink = json.loads(r)['permalinkFragment']
|
||||
webbrowser.open(url + "/r/" + permaLink)
|
||||
|
||||
@@ -152,10 +137,8 @@ def scrapeLang(scraped, lang, longtitle):
|
||||
language = ''
|
||||
|
||||
if scraped['lang']:
|
||||
if 'ita' in scraped['lang'].lower():
|
||||
language = 'ITA'
|
||||
if 'sub' in scraped['lang'].lower():
|
||||
language = 'Sub-' + language
|
||||
if 'ita' in scraped['lang'].lower(): language = 'ITA'
|
||||
if 'sub' in scraped['lang'].lower(): language = 'Sub-' + language
|
||||
|
||||
if not language: language = lang
|
||||
if language: longtitle += typo(language, '_ [] color kod')
|
||||
@@ -177,11 +160,10 @@ def unifyEp(ep):
|
||||
|
||||
def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, typeContentDict, typeActionDict, blacklist, search, pag, function, lang, sceneTitle):
|
||||
itemlist = []
|
||||
log("scrapeBlock qui")
|
||||
if debug:
|
||||
regexDbg(item, patron, headers, block)
|
||||
matches = scrapertools.find_multiple_matches_groups(block, patron)
|
||||
log('MATCHES =', matches)
|
||||
logger.debug('MATCHES =', matches)
|
||||
|
||||
known_keys = ['url', 'title', 'title2', 'season', 'episode', 'thumb', 'quality', 'year', 'plot', 'duration', 'genere', 'rating', 'type', 'lang', 'other', 'size', 'seed']
|
||||
# Legenda known_keys per i groups nei patron
|
||||
@@ -298,7 +280,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
try:
|
||||
parsedTitle = guessit(title)
|
||||
title = longtitle = parsedTitle.get('title', '')
|
||||
log('TITOLO',title)
|
||||
logger.debug('TITOLO',title)
|
||||
if parsedTitle.get('source'):
|
||||
quality = str(parsedTitle.get('source'))
|
||||
if parsedTitle.get('screen_size'):
|
||||
@@ -332,7 +314,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
longtitle += s + parsedTitle.get('episode_title')
|
||||
item.contentEpisodeTitle = parsedTitle.get('episode_title')
|
||||
except:
|
||||
log('Error')
|
||||
logger.debug('Error')
|
||||
|
||||
longtitle = typo(longtitle, 'bold')
|
||||
lang1, longtitle = scrapeLang(scraped, lang, longtitle)
|
||||
@@ -419,7 +401,7 @@ def scrape(func):
|
||||
|
||||
args = func(*args)
|
||||
function = func.__name__ if not 'actLike' in args else args['actLike']
|
||||
# log('STACK= ',inspect.stack()[1][3])
|
||||
# info('STACK= ',inspect.stack()[1][3])
|
||||
|
||||
item = args['item']
|
||||
|
||||
@@ -451,12 +433,13 @@ def scrape(func):
|
||||
matches = []
|
||||
|
||||
for n in range(2):
|
||||
log('PATRON= ', patron)
|
||||
logger.debug('PATRON= ', patron)
|
||||
if not data:
|
||||
page = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True)
|
||||
data = re.sub("='([^']+)'", '="\\1"', page.data)
|
||||
data = data.replace('\n', ' ')
|
||||
data = data.replace('\t', ' ')
|
||||
data = data.replace(' ', ' ')
|
||||
data = re.sub(r'>\s+<', '> <', data)
|
||||
# replace all ' with " and eliminate newline, so we don't need to worry about
|
||||
scrapingTime = time()
|
||||
@@ -466,7 +449,7 @@ def scrape(func):
|
||||
blocks = scrapertools.find_multiple_matches_groups(data, patronBlock)
|
||||
block = ""
|
||||
for bl in blocks:
|
||||
# log(len(blocks),bl)
|
||||
# info(len(blocks),bl)
|
||||
if 'season' in bl and bl['season']:
|
||||
item.season = bl['season']
|
||||
blockItemlist, blockMatches = scrapeBlock(item, args, bl['block'], patron, headers, action, pagination, debug,
|
||||
@@ -491,7 +474,7 @@ def scrape(func):
|
||||
|
||||
# if url may be changed and channel has findhost to update
|
||||
if 'findhost' in func.__globals__ and not itemlist:
|
||||
logger.info('running findhost ' + func.__module__)
|
||||
info('running findhost ' + func.__module__)
|
||||
host = func.__globals__['findhost']()
|
||||
parse = list(urlparse.urlparse(item.url))
|
||||
from core import jsontools
|
||||
@@ -505,7 +488,7 @@ def scrape(func):
|
||||
break
|
||||
|
||||
if (pagination and len(matches) <= pag * pagination) or not pagination: # next page with pagination
|
||||
if patronNext and inspect.stack()[1][3] not in ['newest', 'search']:
|
||||
if patronNext and inspect.stack()[1][3] not in ['newest']:
|
||||
nextPage(itemlist, item, data, patronNext, function)
|
||||
|
||||
# next page for pagination
|
||||
@@ -526,7 +509,7 @@ def scrape(func):
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
if anime:
|
||||
from specials import autorenumber
|
||||
from platformcode import autorenumber
|
||||
if function == 'episodios' or item.action == 'episodios': autorenumber.renumber(itemlist, item, 'bold')
|
||||
else: autorenumber.renumber(itemlist)
|
||||
# if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
|
||||
@@ -548,7 +531,7 @@ def scrape(func):
|
||||
if config.get_setting('trakt_sync'):
|
||||
from core import trakt_tools
|
||||
trakt_tools.trakt_check(itemlist)
|
||||
log('scraping time: ', time()-scrapingTime)
|
||||
logger.debug('scraping time: ', time()-scrapingTime)
|
||||
return itemlist
|
||||
|
||||
return wrapper
|
||||
@@ -726,15 +709,11 @@ def menuItem(itemlist, filename, title='', action='', url='', contentType='undef
|
||||
|
||||
def menu(func):
|
||||
def wrapper(*args):
|
||||
log()
|
||||
args = func(*args)
|
||||
|
||||
item = args['item']
|
||||
log(item.channel + ' start')
|
||||
logger.debug(item.channel + ' menu start')
|
||||
host = func.__globals__['host']
|
||||
list_servers = func.__globals__['list_servers'] if 'list_servers' in func.__globals__ else ['directo']
|
||||
list_quality = func.__globals__['list_quality'] if 'list_quality' in func.__globals__ else ['default']
|
||||
log('LIST QUALITY', list_quality)
|
||||
filename = func.__module__.split('.')[1]
|
||||
single_search = False
|
||||
# listUrls = ['film', 'filmSub', 'tvshow', 'tvshowSub', 'anime', 'animeSub', 'search', 'top', 'topSub']
|
||||
@@ -749,7 +728,7 @@ def menu(func):
|
||||
|
||||
for name in listUrls:
|
||||
dictUrl[name] = args[name] if name in args else None
|
||||
log(dictUrl[name])
|
||||
logger.debug(dictUrl[name])
|
||||
if name == 'film': title = 'Film'
|
||||
if name == 'tvshow': title = 'Serie TV'
|
||||
if name == 'anime': title = 'Anime'
|
||||
@@ -816,9 +795,8 @@ def menu(func):
|
||||
channel_config(item, itemlist)
|
||||
|
||||
# Apply auto Thumbnails at the menus
|
||||
from channelselector import thumb
|
||||
thumb(itemlist)
|
||||
log(item.channel + ' end')
|
||||
logger.debug(item.channel + ' menu end')
|
||||
return itemlist
|
||||
|
||||
return wrapper
|
||||
@@ -944,6 +922,7 @@ def match(item_url_string, **args):
|
||||
data = re.sub("='([^']+)'", '="\\1"', data)
|
||||
data = data.replace('\n', ' ')
|
||||
data = data.replace('\t', ' ')
|
||||
data = data.replace(' ', ' ')
|
||||
data = re.sub(r'>\s+<', '><', data)
|
||||
data = re.sub(r'([a-zA-Z])"([a-zA-Z])', "\1'\2", data)
|
||||
|
||||
@@ -984,7 +963,7 @@ def match(item_url_string, **args):
|
||||
|
||||
|
||||
def match_dbg(data, patron):
|
||||
import json, urllib2, webbrowser
|
||||
import json, webbrowser
|
||||
url = 'https://regex101.com'
|
||||
headers = {'content-type': 'application/json'}
|
||||
data = {
|
||||
@@ -994,8 +973,9 @@ def match_dbg(data, patron):
|
||||
'delimiter': '"""',
|
||||
'flavor': 'python'
|
||||
}
|
||||
r = urllib2.Request(url + '/api/regex', json.dumps(data, encoding='latin1'), headers=headers)
|
||||
r = urllib2.urlopen(r).read()
|
||||
js = json.dumps(data).encode() if PY3 else json.dumps(data, encoding='latin1')
|
||||
r = Request(url + '/api/regex', js, headers=headers)
|
||||
r = urlopen(r).read()
|
||||
permaLink = json.loads(r)['permalinkFragment']
|
||||
webbrowser.open(url + "/r/" + permaLink)
|
||||
|
||||
@@ -1051,7 +1031,7 @@ def download(itemlist, item, typography='', function_level=1, function=''):
|
||||
from_action=from_action,
|
||||
contentTitle=contentTitle,
|
||||
path=item.path,
|
||||
thumbnail=thumb(thumb='downloads.png'),
|
||||
thumbnail=thumb('downloads'),
|
||||
downloadItemlist=downloadItemlist
|
||||
))
|
||||
if from_action == 'episodios':
|
||||
@@ -1068,7 +1048,7 @@ def download(itemlist, item, typography='', function_level=1, function=''):
|
||||
from_action=from_action,
|
||||
contentTitle=contentTitle,
|
||||
download='season',
|
||||
thumbnail=thumb(thumb='downloads.png'),
|
||||
thumbnail=thumb('downloads'),
|
||||
downloadItemlist=downloadItemlist
|
||||
))
|
||||
|
||||
@@ -1079,7 +1059,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
|
||||
# Simply add this function to add video library support
|
||||
# Function_level is useful if the function is called by another function.
|
||||
# If the call is direct, leave it blank
|
||||
log()
|
||||
info()
|
||||
|
||||
if item.contentType == 'movie':
|
||||
action = 'add_pelicula_to_library'
|
||||
@@ -1108,7 +1088,6 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
|
||||
if (function == 'findvideos' and contentType == 'movie') \
|
||||
or (function == 'episodios' and contentType != 'movie'):
|
||||
if config.get_videolibrary_support() and len(itemlist) > 0:
|
||||
from channelselector import get_thumb
|
||||
itemlist.append(
|
||||
Item(channel=item.channel,
|
||||
title=title,
|
||||
@@ -1122,7 +1101,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
|
||||
from_action=item.action,
|
||||
extra=extra,
|
||||
path=item.path,
|
||||
thumbnail=get_thumb('add_to_videolibrary.png')
|
||||
thumbnail=thumb('add_to_videolibrary')
|
||||
))
|
||||
|
||||
return itemlist
|
||||
@@ -1130,7 +1109,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
|
||||
def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page='', resub=[]):
|
||||
# Function_level is useful if the function is called by another function.
|
||||
# If the call is direct, leave it blank
|
||||
log()
|
||||
info()
|
||||
action = inspect.stack()[function_or_level][3] if type(function_or_level) == int else function_or_level
|
||||
if next_page == '':
|
||||
next_page = scrapertools.find_single_match(data, patron)
|
||||
@@ -1140,7 +1119,7 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
|
||||
if 'http' not in next_page:
|
||||
next_page = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + (next_page if next_page.startswith('/') else '/' + next_page)
|
||||
next_page = next_page.replace('&', '&')
|
||||
log('NEXT= ', next_page)
|
||||
info('NEXT= ', next_page)
|
||||
itemlist.append(
|
||||
Item(channel=item.channel,
|
||||
action = action,
|
||||
@@ -1168,7 +1147,9 @@ def pagination(itemlist, item, page, perpage, function_level=1):
|
||||
|
||||
|
||||
def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=True, Download=True, patronTag=None, Videolibrary=True):
|
||||
log()
|
||||
info()
|
||||
blacklisted_servers = config.get_setting("black_list", server='servers')
|
||||
if not blacklisted_servers: blacklisted_servers = []
|
||||
if not data and not itemlist:
|
||||
data = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True).data
|
||||
if data:
|
||||
@@ -1179,7 +1160,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
|
||||
def getItem(videoitem):
|
||||
if not servertools.get_server_parameters(videoitem.server.lower()): # do not exists or it's empty
|
||||
findS = servertools.get_server_from_url(videoitem.url)
|
||||
log(findS)
|
||||
info(findS)
|
||||
if not findS:
|
||||
if item.channel == 'community':
|
||||
findS= (config.get_localized_string(30137), videoitem.url, 'directo')
|
||||
@@ -1187,7 +1168,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
|
||||
videoitem.url = unshortenit.unshorten_only(videoitem.url)[0]
|
||||
findS = servertools.get_server_from_url(videoitem.url)
|
||||
if not findS:
|
||||
log(videoitem, 'Non supportato')
|
||||
info(videoitem, 'Non supportato')
|
||||
return
|
||||
videoitem.server = findS[2]
|
||||
videoitem.title = findS[0]
|
||||
@@ -1213,7 +1194,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
thL = [executor.submit(getItem, videoitem) for videoitem in itemlist if videoitem.url]
|
||||
for it in futures.as_completed(thL):
|
||||
if it.result():
|
||||
if it.result() and it.result().server.lower() not in blacklisted_servers:
|
||||
verifiedItemlist.append(it.result())
|
||||
try:
|
||||
verifiedItemlist.sort(key=lambda it: int(re.sub(r'\D','',it.quality)))
|
||||
@@ -1247,39 +1228,19 @@ def filterLang(item, itemlist):
|
||||
# import channeltools
|
||||
list_language = channeltools.get_lang(item.channel)
|
||||
if len(list_language) > 1:
|
||||
from specials import filtertools
|
||||
from core import filtertools
|
||||
itemlist = filtertools.get_links(itemlist, item, list_language)
|
||||
return itemlist
|
||||
|
||||
# def aplay(item, itemlist, list_servers='', list_quality=''):
|
||||
# if inspect.stack()[1][3] == 'mainlist':
|
||||
# autoplay.init(item.channel, list_servers, list_quality)
|
||||
# autoplay.show_option(item.channel, itemlist)
|
||||
# else:
|
||||
# autoplay.start(itemlist, item)
|
||||
|
||||
|
||||
def log(*args):
|
||||
# Function to simplify the log
|
||||
# Automatically returns File Name and Function Name
|
||||
string = ''
|
||||
for arg in args:
|
||||
string += ' '+str(arg)
|
||||
frame = inspect.stack()[1]
|
||||
filename = frame[0].f_code.co_filename
|
||||
filename = os.path.basename(filename)
|
||||
logger.info("[" + filename + "] - [" + inspect.stack()[1][3] + "] " + string)
|
||||
|
||||
|
||||
def channel_config(item, itemlist):
|
||||
from channelselector import get_thumb
|
||||
itemlist.append(
|
||||
Item(channel='setting',
|
||||
action="channel_config",
|
||||
title=typo(config.get_localized_string(60587), 'color kod bold'),
|
||||
config=item.channel,
|
||||
folder=False,
|
||||
thumbnail=get_thumb('setting_0.png'))
|
||||
thumbnail=thumb('setting_0'))
|
||||
)
|
||||
|
||||
|
||||
@@ -1288,6 +1249,7 @@ def extract_wrapped(decorated):
|
||||
closure = (c.cell_contents for c in decorated.__closure__)
|
||||
return next((c for c in closure if isinstance(c, FunctionType)), None)
|
||||
|
||||
|
||||
def addQualityTag(item, itemlist, data, patron):
|
||||
if itemlist:
|
||||
defQualVideo = {
|
||||
@@ -1332,10 +1294,8 @@ def addQualityTag(item, itemlist, data, patron):
|
||||
"RESYNC": "il film è stato lavorato e re sincronizzato con una traccia audio. A volte potresti riscontrare una mancata sincronizzazione tra audio e video.",
|
||||
}
|
||||
qualityStr = scrapertools.find_single_match(data, patron).strip().upper()
|
||||
if PY3:
|
||||
qualityStr = qualityStr.encode('ascii', 'ignore')
|
||||
else:
|
||||
qualityStr = qualityStr.decode('unicode_escape').encode('ascii', 'ignore')
|
||||
# if PY3: qualityStr = qualityStr.encode('ascii', 'ignore')
|
||||
if not PY3: qualityStr = qualityStr.decode('unicode_escape').encode('ascii', 'ignore')
|
||||
|
||||
if qualityStr:
|
||||
try:
|
||||
@@ -1354,14 +1314,14 @@ def addQualityTag(item, itemlist, data, patron):
|
||||
descr += typo(audio + ': ', 'color kod') + defQualAudio.get(audio, '') + '\n'
|
||||
except:
|
||||
descr = ''
|
||||
itemlist.insert(0,
|
||||
Item(channel=item.channel,
|
||||
action="",
|
||||
title=typo(qualityStr, '[] color kod bold'),
|
||||
plot=descr,
|
||||
folder=False))
|
||||
itemlist.insert(0,Item(channel=item.channel,
|
||||
action="",
|
||||
title=typo(qualityStr, '[] color kod bold'),
|
||||
plot=descr,
|
||||
folder=False,
|
||||
thumbnail=thumb('info')))
|
||||
else:
|
||||
log('nessun tag qualità trovato')
|
||||
info('nessun tag qualità trovato')
|
||||
|
||||
def get_jwplayer_mediaurl(data, srvName, onlyHttp=False):
|
||||
video_urls = []
|
||||
@@ -1378,4 +1338,121 @@ def get_jwplayer_mediaurl(data, srvName, onlyHttp=False):
|
||||
video_urls.append(['.' + url.split('.')[-1] + ' [' + quality + '] [' + srvName + ']', url if not onlyHttp else url.replace('https://', 'http://')])
|
||||
|
||||
video_urls.sort(key=lambda x: x[0].split()[1])
|
||||
return video_urls
|
||||
return video_urls
|
||||
|
||||
|
||||
def thumb(item_itemlist_string=None, genre=False, live=False):
|
||||
from channelselector import get_thumb
|
||||
if live:
|
||||
if type(item_itemlist_string) == list:
|
||||
for item in item_itemlist_string:
|
||||
item.thumbnail = "https://raw.githubusercontent.com/kodiondemand/media/master/live/" + item.fulltitle.lower().replace(' ','_') + '.png'
|
||||
else:
|
||||
item_itemlist_string.thumbnail = "https://raw.githubusercontent.com/kodiondemand/media/master/live/" + item.fulltitle.lower().replace(' ','_') + '.png'
|
||||
return item_itemlist_string
|
||||
|
||||
icon_dict = {'movie':['film', 'movie'],
|
||||
'tvshow':['serie','tv','episodi','episodio','fiction', 'show'],
|
||||
'documentary':['documentari','documentario', 'documentary', 'documentaristico'],
|
||||
'teenager':['ragazzi','teenager', 'teen'],
|
||||
'learning':['learning', 'school', 'scuola'],
|
||||
'all':['tutti', 'all'],
|
||||
'news':['novità', "novita'", 'aggiornamenti', 'nuovi', 'nuove', 'new', 'newest', 'news', 'ultimi', 'notizie'],
|
||||
'now_playing':['cinema', 'in sala'],
|
||||
'anime':['anime'],
|
||||
'genres':['genere', 'generi', 'categorie', 'categoria', 'category'],
|
||||
'animation': ['animazione', 'cartoni', 'cartoon', 'animation'],
|
||||
'action':['azione', 'marziali', 'action', 'martial'],
|
||||
'adventure': ['avventura', 'adventure'],
|
||||
'biographical':['biografico', 'biographical', 'biografia'],
|
||||
'comedy':['comico', 'commedia', 'demenziale', 'comedy', 'brillante', 'demential', 'parody'],
|
||||
'adult':['erotico', 'hentai', 'harem', 'ecchi', 'adult'],
|
||||
'drama':['drammatico', 'drama', 'dramma'],
|
||||
'syfy':['fantascienza', 'science fiction', 'syfy', 'sci-fi'],
|
||||
'fantasy':['fantasy', 'magia', 'magic', 'fantastico'],
|
||||
'crime':['gangster','poliziesco', 'crime', 'crimine', 'police'],
|
||||
'grotesque':['grottesco', 'grotesque'],
|
||||
'war':['guerra', 'war', 'military'],
|
||||
'children':['bambini', 'kids'],
|
||||
'horror':['horror', 'orrore'],
|
||||
'music':['musical', 'musica', 'music', 'musicale'],
|
||||
'mistery':['mistero', 'giallo', 'mystery'],
|
||||
'noir':['noir'],
|
||||
'popular':['popolari','popolare', 'più visti', 'raccomandati', 'raccomandazioni' 'recommendations'],
|
||||
'thriller':['thriller'],
|
||||
'top_rated' : ['fortunato', 'votati', 'lucky', 'top'],
|
||||
'on_the_air' : ['corso', 'onda', 'diretta', 'dirette'],
|
||||
'western':['western'],
|
||||
'vos':['sub','sub-ita'],
|
||||
'romance':['romantico','sentimentale', 'romance', 'soap'],
|
||||
'family':['famiglia','famiglie', 'family'],
|
||||
'historical':['storico', 'history', 'storia', 'historical'],
|
||||
'az':['lettera','lista','alfabetico','a-z', 'alphabetical'],
|
||||
'year':['anno', 'anni', 'year'],
|
||||
'update':['replay', 'update'],
|
||||
'videolibrary':['teche'],
|
||||
'info':['info','information','informazioni'],
|
||||
'star':['star', 'personaggi', 'interpreti', 'stars', 'characters', 'performers', 'staff', 'actors', 'attori'],
|
||||
'winter':['inverno', 'winter'],
|
||||
'spring':['primavera', 'spring'],
|
||||
'summer':['estate', 'summer'],
|
||||
'autumn':['autunno', 'autumn'],
|
||||
'autoplay':[config.get_localized_string(60071)]
|
||||
}
|
||||
|
||||
suffix_dict = {'_hd':['hd','altadefinizione','alta definizione'],
|
||||
'_4k':['4K'],
|
||||
'_az':['lettera','lista','alfabetico','a-z', 'alphabetical'],
|
||||
'_year':['anno', 'anni', 'year'],
|
||||
'_genre':['genere', 'generi', 'categorie', 'categoria']}
|
||||
|
||||
search = ['cerca', 'search']
|
||||
|
||||
search_suffix ={'_movie':['film', 'movie'],
|
||||
'_tvshow':['serie','tv', 'fiction']}
|
||||
|
||||
def autoselect_thumb(item, genre):
|
||||
info('SPLIT',re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()))
|
||||
if genre == False:
|
||||
for thumb, titles in icon_dict.items():
|
||||
if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in search):
|
||||
thumb = 'search'
|
||||
for suffix, titles in search_suffix.items():
|
||||
if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ):
|
||||
thumb = thumb + suffix
|
||||
item.thumbnail = get_thumb(thumb + '.png')
|
||||
elif any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)| ',item.title.lower()) for word in titles ):
|
||||
if thumb == 'movie' or thumb == 'tvshow':
|
||||
for suffix, titles in suffix_dict.items():
|
||||
if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ):
|
||||
thumb = thumb + suffix
|
||||
item.thumbnail = get_thumb(thumb + '.png')
|
||||
else: item.thumbnail = get_thumb(thumb + '.png')
|
||||
else:
|
||||
thumb = item.thumbnail
|
||||
|
||||
else:
|
||||
for thumb, titles in icon_dict.items():
|
||||
if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ):
|
||||
item.thumbnail = get_thumb(thumb + '.png')
|
||||
else:
|
||||
thumb = item.thumbnail
|
||||
|
||||
item.title = re.sub(r'\s*\{[^\}]+\}','',item.title)
|
||||
return item
|
||||
|
||||
if item_itemlist_string:
|
||||
if type(item_itemlist_string) == list:
|
||||
for item in item_itemlist_string:
|
||||
autoselect_thumb(item, genre)
|
||||
return item_itemlist_string
|
||||
|
||||
elif type(item_itemlist_string) == str:
|
||||
filename, file_extension = os.path.splitext(item_itemlist_string)
|
||||
if not file_extension: item_itemlist_string += '.png'
|
||||
return get_thumb(item_itemlist_string)
|
||||
else:
|
||||
return autoselect_thumb(item_itemlist_string, genre)
|
||||
|
||||
else:
|
||||
return get_thumb('next.png')
|
||||
+4
-1
@@ -950,7 +950,10 @@ class Tmdb(object):
|
||||
if self.busqueda_tipo == "movie":
|
||||
resultado = resultado["movie_results"][0]
|
||||
else:
|
||||
resultado = resultado["tv_results"][0]
|
||||
if resultado["tv_results"]:
|
||||
resultado = resultado["tv_results"][0]
|
||||
else:
|
||||
resultado = resultado['tv_episode_results'][0]
|
||||
|
||||
self.results = [resultado]
|
||||
self.total_results = 1
|
||||
|
||||
+4
-3
@@ -71,9 +71,8 @@ def token_trakt(item):
|
||||
else:
|
||||
import time
|
||||
dialog_auth = platformtools.dialog_progress(config.get_localized_string(60251),
|
||||
config.get_localized_string(60252) % item.verify_url,
|
||||
config.get_localized_string(60253)
|
||||
% item.user_code,
|
||||
config.get_localized_string(60252) % item.verify_url + '\n' +
|
||||
config.get_localized_string(60253) % item.user_code + '\n' +
|
||||
config.get_localized_string(60254))
|
||||
|
||||
# Generalmente cada 5 segundos se intenta comprobar si el usuario ha introducido el código
|
||||
@@ -199,6 +198,8 @@ def get_trakt_watched(id_type, mediatype, update=False):
|
||||
|
||||
|
||||
def trakt_check(itemlist):
|
||||
if type(itemlist) != list:
|
||||
return
|
||||
def sync(item, id_result):
|
||||
info = item.infoLabels
|
||||
try:
|
||||
|
||||
+51
-100
@@ -6,13 +6,17 @@
|
||||
# Used to obtain series data for the video library
|
||||
# ------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] >= 3: PY3 = True
|
||||
else: PY3 = False
|
||||
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from future.builtins import object
|
||||
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
|
||||
import re
|
||||
import re, requests
|
||||
|
||||
from core import jsontools
|
||||
from core import scrapertools
|
||||
@@ -100,12 +104,12 @@ def find_and_set_infoLabels(item):
|
||||
otvdb_global = Tvdb(tvdb_id=item.infoLabels['tvdb_id'])
|
||||
|
||||
if not item.contentSeason:
|
||||
p_dialog.update(50, config.get_localized_string(60296), config.get_localized_string(60295))
|
||||
p_dialog.update(50, config.get_localized_string(60296) + '\n' + config.get_localized_string(60295))
|
||||
results, info_load = otvdb_global.get_list_results()
|
||||
logger.debug("results: %s" % results)
|
||||
|
||||
if not item.contentSeason:
|
||||
p_dialog.update(100, config.get_localized_string(60296), config.get_localized_string(60297) % len(results))
|
||||
p_dialog.update(100, config.get_localized_string(60296) + '\n' + config.get_localized_string(60297) % len(results))
|
||||
p_dialog.close()
|
||||
|
||||
if len(results) > 1:
|
||||
@@ -335,7 +339,7 @@ class Tvdb(object):
|
||||
self.list_results = []
|
||||
self.lang = ""
|
||||
self.search_name = kwargs['search'] = \
|
||||
re.sub('\[\\\?(B|I|COLOR)\s?[^\]]*\]', '', kwargs.get('search', ''))
|
||||
re.sub(r'\[\\\?(B|I|COLOR)\s?[^\]]*\]', '', kwargs.get('search', ''))
|
||||
self.list_episodes = {}
|
||||
self.episodes = {}
|
||||
|
||||
@@ -390,9 +394,11 @@ class Tvdb(object):
|
||||
|
||||
url = HOST + "/login"
|
||||
params = {"apikey": apikey}
|
||||
if PY3: params = jsontools.dump(params).encode()
|
||||
else: params = jsontools.dump(params)
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(url, data=jsontools.dump(params), headers=DEFAULT_HEADERS)
|
||||
req = urllib.request.Request(url, data=params, headers=DEFAULT_HEADERS)
|
||||
response = urllib.request.urlopen(req)
|
||||
html = response.read()
|
||||
response.close()
|
||||
@@ -743,6 +749,7 @@ class Tvdb(object):
|
||||
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
|
||||
response = urllib.request.urlopen(req)
|
||||
html = response.read()
|
||||
logger.info(html)
|
||||
response.close()
|
||||
|
||||
except Exception as ex:
|
||||
@@ -836,7 +843,7 @@ class Tvdb(object):
|
||||
|
||||
except Exception as ex:
|
||||
# if isinstance(ex, urllib).HTTPError:
|
||||
logger.debug("code %s " % ex.code)
|
||||
logger.debug("code %s " % ex)
|
||||
|
||||
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
|
||||
logger.error("error: %s" % message)
|
||||
@@ -1021,102 +1028,46 @@ class Tvdb(object):
|
||||
if not origen:
|
||||
origen = self.result
|
||||
|
||||
# todo revisar
|
||||
# if 'credits' in origen.keys():
|
||||
# dic_origen_credits = origen['credits']
|
||||
# origen['credits_cast'] = dic_origen_credits.get('cast', [])
|
||||
# origen['credits_crew'] = dic_origen_credits.get('crew', [])
|
||||
# del origen['credits']
|
||||
|
||||
items = list(origen.items())
|
||||
|
||||
for k, v in items:
|
||||
if not v:
|
||||
continue
|
||||
|
||||
if k == 'overview':
|
||||
ret_infoLabels['plot'] = v
|
||||
|
||||
elif k == 'runtime':
|
||||
ret_infoLabels['duration'] = int(v) * 60
|
||||
|
||||
elif k == 'firstAired':
|
||||
ret_infoLabels['year'] = int(v[:4])
|
||||
ret_infoLabels['premiered'] = v.split("-")[2] + "/" + v.split("-")[1] + "/" + v.split("-")[0]
|
||||
|
||||
# todo revisar
|
||||
# elif k == 'original_title' or k == 'original_name':
|
||||
# ret_infoLabels['originaltitle'] = v
|
||||
|
||||
elif k == 'siteRating':
|
||||
ret_infoLabels['rating'] = float(v)
|
||||
|
||||
elif k == 'siteRatingCount':
|
||||
ret_infoLabels['votes'] = v
|
||||
|
||||
elif k == 'status':
|
||||
# se traduce los estados de una serie
|
||||
ret_infoLabels['status'] = v
|
||||
|
||||
# I am not in favor of putting the chain as a studio but it is how the scraper does it in a generic way
|
||||
elif k == 'network':
|
||||
ret_infoLabels['studio'] = v
|
||||
|
||||
elif k == 'image_poster':
|
||||
# obtenemos la primera imagen de la lista
|
||||
ret_infoLabels['thumbnail'] = HOST_IMAGE + v[0]['fileName']
|
||||
|
||||
elif k == 'image_fanart':
|
||||
# obtenemos la primera imagen de la lista
|
||||
ret_infoLabels['fanart'] = HOST_IMAGE + v[0]['fileName']
|
||||
|
||||
# # no disponemos de la imagen de fondo
|
||||
# elif k == 'banner':
|
||||
# ret_infoLabels['fanart'] = HOST_IMAGE + v
|
||||
|
||||
elif k == 'id':
|
||||
ret_infoLabels['tvdb_id'] = v
|
||||
|
||||
elif k == 'imdbId':
|
||||
ret_infoLabels['imdb_id'] = v
|
||||
# no se muestra
|
||||
# ret_infoLabels['code'] = v
|
||||
|
||||
elif k in "rating":
|
||||
# we translate the age rating (content rating system)
|
||||
ret_infoLabels['mpaa'] = v
|
||||
|
||||
elif k in "genre":
|
||||
ret_infoLabels['title'] = origen['seriesName']
|
||||
ret_infoLabels['tvdb_id'] = origen['id']
|
||||
thumbs = requests.get(HOST + '/series/' + str(origen['id']) + '/images/query?keyType=poster').json()
|
||||
if 'data' in thumbs:
|
||||
ret_infoLabels['thumbnail'] = HOST_IMAGE + thumbs['data'][0]['fileName']
|
||||
elif 'poster' in origen and origen['poster']:
|
||||
ret_infoLabels['thumbnail'] = origen['poster']
|
||||
fanarts = requests.get(HOST + '/series/' + str(origen['id']) + '/images/query?keyType=fanart').json()
|
||||
if 'data' in fanarts:
|
||||
ret_infoLabels['fanart'] = HOST_IMAGE + fanarts['data'][0]['fileName']
|
||||
elif 'fanart' in origen and origen['fanart']:
|
||||
ret_infoLabels['thumbnail'] = origen['fanart']
|
||||
if 'overview' in origen and origen['overview']:
|
||||
ret_infoLabels['plot'] = origen['overview']
|
||||
if 'duration' in origen and origen['duration']:
|
||||
ret_infoLabels['duration'] = int(origen['duration']) * 60
|
||||
if 'firstAired' in origen and origen['firstAired']:
|
||||
ret_infoLabels['year'] = int(origen['firstAired'][:4])
|
||||
ret_infoLabels['premiered'] = origen['firstAired'].split("-")[2] + "/" + origen['firstAired'].split("-")[1] + "/" + origen['firstAired'].split("-")[0]
|
||||
if 'siteRating' in origen and origen['siteRating']:
|
||||
ret_infoLabels['rating'] = float(origen['siteRating'])
|
||||
if 'siteRatingCount' in origen and origen['siteRatingCount']:
|
||||
ret_infoLabels['votes'] = origen['siteRatingCount']
|
||||
if 'status' in origen and origen['status']:
|
||||
ret_infoLabels['status'] = origen['status']
|
||||
if 'network' in origen and origen['network']:
|
||||
ret_infoLabels['studio'] = origen['network']
|
||||
if 'imdbId' in origen and origen['rating']:
|
||||
ret_infoLabels['imdb_id'] = origen['imdbId']
|
||||
if 'rating' in origen and origen['rating']:
|
||||
ret_infoLabels['mpaa'] = origen['rating']
|
||||
if 'genre' in origen and origen['genre']:
|
||||
for genre in origen['genre']:
|
||||
genre_list = ""
|
||||
for index, i in enumerate(v):
|
||||
if index > 0:
|
||||
genre_list += ", "
|
||||
|
||||
# traducimos los generos
|
||||
genre_list += i
|
||||
|
||||
ret_infoLabels['genre'] = genre_list
|
||||
|
||||
elif k == 'seriesName': # or k == 'name' or k == 'title':
|
||||
# if len(origen.get('aliases', [])) > 0:
|
||||
# ret_infoLabels['title'] = v + " " + origen.get('aliases', [''])[0]
|
||||
# else:
|
||||
# ret_infoLabels['title'] = v
|
||||
# logger.info("el titulo es %s " % ret_infoLabels['title'])
|
||||
ret_infoLabels['title'] = v
|
||||
|
||||
elif k == 'cast':
|
||||
dic_aux = dict((name, character) for (name, character) in l_castandrole)
|
||||
l_castandrole.extend([(p['name'], p['role']) for p in v if p['name'] not in list(dic_aux.keys())])
|
||||
|
||||
else:
|
||||
logger.debug("Attributes not added: %s=%s" % (k, v))
|
||||
pass
|
||||
|
||||
# Sort the lists and convert them to str if necessary
|
||||
if l_castandrole:
|
||||
genre_list += genre + ', '
|
||||
ret_infoLabels['genre'] = genre_list.rstrip(', ')
|
||||
if 'cast' in origen and origen['cast']:
|
||||
dic_aux = dict((name, character) for (name, character) in l_castandrole)
|
||||
l_castandrole.extend([(p['name'], p['role']) for p in origen['cast'] if p['name'] not in list(dic_aux.keys())])
|
||||
ret_infoLabels['castandrole'] = l_castandrole
|
||||
|
||||
logger.debug("ret_infoLabels %s" % ret_infoLabels)
|
||||
|
||||
return ret_infoLabels
|
||||
|
||||
+10
-10
@@ -205,7 +205,7 @@ def save_movie(item, silent=False):
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
if filetools.write(json_path, item.tojson()):
|
||||
if not silent: p_dialog.update(100, config.get_localized_string(60062), item.contentTitle)
|
||||
if not silent: p_dialog.update(100, item.contentTitle)
|
||||
item_nfo.library_urls[item.channel] = item.url
|
||||
|
||||
if filetools.write(nfo_path, head_nfo + item_nfo.tojson()):
|
||||
@@ -221,7 +221,7 @@ def save_movie(item, silent=False):
|
||||
# If we get to this point it is because something has gone wrong
|
||||
logger.error("Could not save %s in the video library" % item.contentTitle)
|
||||
if not silent:
|
||||
p_dialog.update(100, config.get_localized_string(60063), item.contentTitle)
|
||||
p_dialog.update(100, item.contentTitle)
|
||||
p_dialog.close()
|
||||
return 0, 0, -1, path
|
||||
|
||||
@@ -254,7 +254,7 @@ def add_renumber_options(item, head_nfo, path):
|
||||
return ret
|
||||
|
||||
def check_renumber_options(item):
|
||||
from specials.autorenumber import load, write
|
||||
from platformcode.autorenumber import load, write
|
||||
for key in item.channel_prefs:
|
||||
if 'TVSHOW_AUTORENUMBER' in item.channel_prefs[key]:
|
||||
item.channel = key
|
||||
@@ -645,10 +645,10 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
# Silent is to show no progress (for service)
|
||||
if not silent:
|
||||
# progress dialog
|
||||
p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60064))
|
||||
p_dialog.update(0, config.get_localized_string(60065))
|
||||
p_dialog = platformtools.dialog_progress(config.get_localized_string(60064) ,'')
|
||||
# p_dialog.update(0, config.get_localized_string(60065))
|
||||
|
||||
channel_alt = serie.channels # We prepare to add the emergency urls
|
||||
channel_alt = serie.channel # We prepare to add the emergency urls
|
||||
emergency_urls_stat = config.get_setting("emergency_urls", channel_alt) # Does the channel want emergency urls?
|
||||
emergency_urls_succ = False
|
||||
try: channel = __import__('specials.%s' % channel_alt, fromlist=["specials.%s" % channel_alt])
|
||||
@@ -673,7 +673,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) # Path of the episode .json
|
||||
if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode': # Do we keep emergency urls?
|
||||
if not silent:
|
||||
p_dialog.update(0, 'Caching links and .torren filest...', e.title) # progress dialog
|
||||
p_dialog.update(0, 'Caching links and .torren filest...\n' + e.title) # progress dialog
|
||||
if json_path in ficheros: # If there is the .json we get the urls from there
|
||||
if overwrite: # but only if .json are overwritten
|
||||
json_epi = Item().fromjson(filetools.read(json_path)) #We read the .json
|
||||
@@ -690,7 +690,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
emergency_urls_succ = True # ... is a success and we are going to mark the .nfo
|
||||
elif emergency_urls_stat == 3 and e.contentType == 'episode': # Do we update emergency urls?
|
||||
if not silent:
|
||||
p_dialog.update(0, 'Caching links and .torrent files...', e.title) # progress dialog
|
||||
p_dialog.update(0, 'Caching links and .torrent files...\n' + e.title) # progress dialog
|
||||
e = emergency_urls(e, channel, json_path, headers=headers) # we generate the urls
|
||||
if e.emergency_urls: # If we already have urls...
|
||||
emergency_urls_succ = True # ... is a success and we are going to mark the .nfo
|
||||
@@ -722,7 +722,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
t = 0
|
||||
for i, e in enumerate(scraper.sort_episode_list(new_episodelist)):
|
||||
if not silent:
|
||||
p_dialog.update(int(math.ceil((i + 1) * t)), config.get_localized_string(60064), e.title)
|
||||
p_dialog.update(int(math.ceil((i + 1) * t)), e.title)
|
||||
|
||||
high_sea = e.contentSeason
|
||||
high_epi = e.contentEpisodeNumber
|
||||
@@ -1073,7 +1073,7 @@ def add_tvshow(item, channel=None):
|
||||
# Get the episode list
|
||||
itemlist = getattr(channel, item.action)(item)
|
||||
if itemlist and not scrapertools.find_single_match(itemlist[0].title, r'(\d+x\d+)'):
|
||||
from specials.autorenumber import select_type, renumber, check
|
||||
from platformcode.autorenumber import select_type, renumber, check
|
||||
if not check(item):
|
||||
action = item.action
|
||||
select_type(item)
|
||||
|
||||
Reference in New Issue
Block a user