KoD 1.6.3
- Corretto blocco nella ricerca globale\n- migliorie e fix vari ai canali e al core\n
This commit is contained in:
@@ -15,12 +15,7 @@ assignees: ''
|
||||
Inserisci il nome del canale
|
||||
|
||||
|
||||
- Il tipo di problema riscontrato, sii il più esauriente possibile. Che azione ha portato all'errore
|
||||
- Indica il tipo di problema riscontrato, sii il più esauriente possibile. Che azione ha portato all'errore (Es. non riesco ad aggiungere film nella videoteca, ne dal menu contestuale, ne dalla voce in fondo alla lista dei server)
|
||||
|
||||
Es. non riesco ad aggiungere film nella videoteca, ne dal menu contestuale, ne dalla voce in fondo alla lista dei server.
|
||||
|
||||
Se faccio ricerca globale, non riesco ad aggiungere film/serie/anime nella videoteca o a scaricare il video.
|
||||
|
||||
|
||||
- Allega il file di log nella sua completezza. Non cancellarne delle parti.
|
||||
- Ottieni il log seguendo le istruzioni: https://telegra.ph/LOG-11-20 e invialo qui.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.6.2" provider-name="KoD Team">
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.6.3" provider-name="KoD Team">
|
||||
<requires>
|
||||
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
|
||||
<import addon="metadata.themoviedb.org"/>
|
||||
@@ -15,6 +15,10 @@
|
||||
<label>70269</label>
|
||||
<visible>String.IsEqual(ListItem.dbtype,tvshow)</visible>
|
||||
</item>
|
||||
<!-- <item library="externalsearch.py">-->
|
||||
<!-- <label>90001</label>-->
|
||||
<!-- <visible>!String.StartsWith(ListItem.FileNameAndPath, plugin://plugin.video.kod/) + [String.IsEqual(ListItem.dbtype,tvshow) | String.IsEqual(ListItem.dbtype,movie)]</visible>-->
|
||||
<!-- </item>-->
|
||||
</menu>
|
||||
</extension>
|
||||
<extension point="xbmc.addon.metadata">
|
||||
@@ -27,10 +31,8 @@
|
||||
<screenshot>resources/media/screenshot-2.png</screenshot>
|
||||
<screenshot>resources/media/screenshot-3.png</screenshot>
|
||||
</assets>
|
||||
<news>- Migliorata funzione "cerca trailer"
|
||||
- Episodio successivo: è ora disponibile la modalità playlist (puoi usare il tasto riproduci successivo di kodi)
|
||||
- aggiunto www.accuradio.com
|
||||
- migliorie varie</news>
|
||||
<news>- Corretto blocco nella ricerca globale
|
||||
- migliorie e fix vari ai canali e al core</news>
|
||||
<description lang="it">Naviga velocemente sul web e guarda i contenuti presenti</description>
|
||||
<disclaimer>[COLOR red]The owners and submitters to this addon do not host or distribute any of the content displayed by these addons nor do they have any affiliation with the content providers.[/COLOR]
|
||||
[COLOR yellow]Kodi © is a registered trademark of the XBMC Foundation. We are not connected to or in any other way affiliated with Kodi, Team Kodi, or the XBMC Foundation. Furthermore, any software, addons, or products offered by us will receive no support in official Kodi channels, including the Kodi forums and various social networks.[/COLOR]</disclaimer>
|
||||
|
||||
+11
-11
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"direct": {
|
||||
"altadefinizione01": "https://www.altadefinizione01.games",
|
||||
"altadefinizione01_link": "https://altadefinizione01.house",
|
||||
"altadefinizione01_link": "https://altadefinizione01.travel",
|
||||
"animealtadefinizione": "https://www.animealtadefinizione.it",
|
||||
"animeforce": "https://www.animeforce.it",
|
||||
"animeleggendari": "https://animezeus.com",
|
||||
@@ -12,28 +12,28 @@
|
||||
"casacinema": "https://www.casacinema.page",
|
||||
"cb01anime": "https://www.cineblog01.red",
|
||||
"cineblog01": "https://cb01.uno",
|
||||
"cinemalibero": "https://cinemalibero.work",
|
||||
"cinemalibero": "https://cinemalibero.shop",
|
||||
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
|
||||
"discoveryplus": "https://www.discoveryplus.com",
|
||||
"dreamsub": "https://dreamsub.stream",
|
||||
"dsda": "https://www.dsda.press",
|
||||
"eurostreaming": "https://eurostreaming.center",
|
||||
"eurostreaming": "https://eurostreaming.shop",
|
||||
"filmigratis": "https://filmigratis.org",
|
||||
"guardaseriecam": "https://guardaserie.cam",
|
||||
"guardaserieclick": "https://www.guardaserie.vision",
|
||||
"guardaserieicu": "https://guardaserie.world",
|
||||
"guardaserieclick": "https://www.guardaserie.support",
|
||||
"guardaserieicu": "https://guardaserie.win",
|
||||
"hd4me": "https://hd4me.net",
|
||||
"ilcorsaronero": "https://ilcorsaronero.link",
|
||||
"ilgeniodellostreaming": "https://ilgeniodellostreaming.moe",
|
||||
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.photo",
|
||||
"italiaserie": "https://italiaserie.club",
|
||||
"ilgeniodellostreaming": "https://ilgeniodellostreaming.vet",
|
||||
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.bond",
|
||||
"italiaserie": "https://italiaserie.pw",
|
||||
"mediasetplay": "https://www.mediasetplay.mediaset.it",
|
||||
"mondoserietv": "https://mondoserietv.fun",
|
||||
"mondoserietv": "https://mondoserietv.club",
|
||||
"paramount": "https://www.paramountnetwork.it",
|
||||
"piratestreaming": "https://www.piratestreaming.codes",
|
||||
"piratestreaming": "https://www.piratestreaming.bar",
|
||||
"polpotv": "https://roma.polpo.tv",
|
||||
"raiplay": "https://www.raiplay.it",
|
||||
"serietvonline": "https://serietvonline.guru",
|
||||
"serietvonline": "https://serietvonline.solar",
|
||||
"serietvsubita": "http://serietvsubita.xyz",
|
||||
"serietvu": "https://www.serietvu.link",
|
||||
"streamingcommunity": "https://streamingcommunity.co",
|
||||
|
||||
@@ -116,6 +116,9 @@ def findvideos(item):
|
||||
|
||||
|
||||
def get_video_list(item, url, title, itemlist):
|
||||
if 'vvvvid' in url:
|
||||
itemlist.append(item.clone(title='VVVVID', url=url, server='vvvvid', action='play'))
|
||||
else:
|
||||
from requests import get
|
||||
if not url.startswith('http'): url = host + url
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "animeleggendari",
|
||||
"name": "AnimePerTutti",
|
||||
"active": true,
|
||||
"active": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "animepertutti.png",
|
||||
"bannermenu": "animepertutti.png",
|
||||
|
||||
@@ -120,8 +120,8 @@ def peliculas(item):
|
||||
item.title += support.typo(item.lang2, '_ [] color kod')
|
||||
if item.args == 'novita':
|
||||
item.title = item.title
|
||||
if 'wp-content' in item.thumbnail and not item.infoLabels['year']:
|
||||
item.infoLabels['year'] = item.thumbnail.split('/')[5]
|
||||
# if 'wp-content' in item.thumbnail and not item.infoLabels['year']:
|
||||
# item.infoLabels['year'] = item.thumbnail.split('/')[5]
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def menu(item):
|
||||
|
||||
def search(item, texto):
|
||||
support.info(texto)
|
||||
item.url = host + "/?s=" + texto
|
||||
item.url = host + "/search/" + texto
|
||||
try:
|
||||
return peliculas(item)
|
||||
except:
|
||||
@@ -72,7 +72,7 @@ def peliculas(item):
|
||||
if item.args == 'newest':
|
||||
patron = r'<div id="blockvids">\s*<ul>\s*<li>\s*<a href="(?P<url>[^"]+)"[^>]+><img[^>]+src="(?P<thumb>[^"]+)"[^>]*>(?:[^>]+>){4}(?P<title>[^\[]+)\[(?P<lang>[^\]]+)\]'
|
||||
else:
|
||||
patron = r'<div class="span4">\s*<a href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+><\/a>(?:[^>]+>){7}\s*<h1>(?P<title>[^<\[]+)(?:\[(?P<lang>[^\]]+)\])?</h1></a>.*?-->(?:.*?<br />)?\s*(?P<plot>[^<]+)'
|
||||
patron = r'<div class="span4">\s*<a href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+><\/a>(?:[^>]+>){7}\s*<h1>(?P<title>[^<\[]+)(?:\[(?P<lang>[^\]]+)\])?</h1></a>.*?-->(?:.*?<br(?: /)?>)?\s*(?P<plot>[^<]+)'
|
||||
patronNext = r'<link rel="next" href="([^"]+)"'
|
||||
action = 'check'
|
||||
return locals()
|
||||
|
||||
@@ -13,6 +13,8 @@ if sys.version_info[0] >= 3: from concurrent import futures
|
||||
else: from concurrent_py2 import futures
|
||||
from collections import OrderedDict
|
||||
|
||||
PAGINATION = 4
|
||||
|
||||
host = ''
|
||||
post_url = '?assetTypes=HD,browser,widevine,geoIT|geoNo:HD,browser,geoIT|geoNo:HD,geoIT|geoNo:SD,browser,widevine,geoIT|geoNo:SD,browser,geoIT|geoNo:SD,geoIT|geoNo&auto=true&balance=true&format=smil&formats=MPEG-DASH,MPEG4,M3U&tracking=true'
|
||||
deviceid = '61d27df7-5cbf-4419-ba06-cfd27ecd4588'
|
||||
@@ -233,7 +235,10 @@ def epmenu(item):
|
||||
def episodios(item):
|
||||
logger.debug()
|
||||
itemlist = []
|
||||
json = current_session.get('https://feed.entertainment.tv.theplatform.eu/f/PR1GhC/mediaset-prod-all-programs?byCustomValue={subBrandId}{'+ item.url + '}&range=0-1000').json()['entries']
|
||||
if not item.nextIndex: item.nextIndex = 1
|
||||
|
||||
url = 'https://feed.entertainment.tv.theplatform.eu/f/PR1GhC/mediaset-prod-all-programs?byCustomValue={subBrandId}{'+ item.url + '}&range=' + str(item.nextIndex) + '-' + str(item.nextIndex + PAGINATION)
|
||||
json = current_session.get(url).json()['entries']
|
||||
|
||||
for it in json:
|
||||
urls = []
|
||||
@@ -258,6 +263,10 @@ def episodios(item):
|
||||
|
||||
if len(itemlist) == 1: return findvideos(itemlist[0])
|
||||
|
||||
if (len(json) >= PAGINATION):
|
||||
item.nextIndex += PAGINATION + 1
|
||||
support.nextPage(itemlist, item)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def search(item, text):
|
||||
else:
|
||||
action = 'episodios'
|
||||
item.args = 'search'
|
||||
item.url = host + "/?s=" + text
|
||||
item.url = host + "?a=b&s=" + text
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore .
|
||||
|
||||
@@ -57,6 +57,7 @@ def mainlist(item):
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.info()
|
||||
anime = True
|
||||
|
||||
blacklist = ['DMCA', 'Contatti', 'Attenzione NON FARTI OSCURARE', 'Lista Cartoni Animati e Anime']
|
||||
patronBlock = r'<h1>.+?</h1>(?P<block>.*?)<div class="footer_c">'
|
||||
@@ -106,6 +107,7 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
support.info()
|
||||
anime = True
|
||||
action = 'findvideos'
|
||||
patronBlock = r'<table>(?P<block>.*)<\/table>'
|
||||
patron = r'<tr><td>(?P<title>.*?)?[ ](?:Parte)?(?P<episode>\d+x\d+|\d+)(?:|[ ]?(?P<title2>.+?)?(?:avi)?)<(?P<data>.*?)<\/td><tr>'
|
||||
|
||||
@@ -27,7 +27,7 @@ def search(item, text):
|
||||
support.info(text)
|
||||
# item.args='search'
|
||||
item.text = text
|
||||
item.url = item.url + '/?%73=' + text.replace(' ', '+')
|
||||
item.url = item.url + '/?a=b&s=' + text.replace(' ', '+')
|
||||
|
||||
try:
|
||||
return peliculas(item)
|
||||
@@ -69,7 +69,7 @@ def peliculas(item):
|
||||
#patronBlock = '"lcp_catlist"[^>]+>(?P<block>.*)</ul>'
|
||||
patronBlock = '<main[^>]+>(?P<block>.*?)</ma'
|
||||
#patron = r'href="(?P<url>[^"]+)" title="(?P<title>[^"]+)"'
|
||||
patron = r'<a href="(?P<url>[^"]+)"[^>]*>(?P<title>[^<]+)<[^>]+>[^>]+><div'
|
||||
patron = r'<a href="(?P<url>[^"]+)"[^>]*>(?P<title>[^<]+)<[^>]+>[^>]+>\s*<div'
|
||||
elif item.args == 'last':
|
||||
patronBlock = 'Aggiornamenti</h2>(?P<block>.*)</ul>'
|
||||
patron = r'<a href="(?P<url>[^"]+)">\s*<img[^>]+src[set]{0,3}="(?P<thumbnail>[^ ]+)[^>]+>\s*<span[^>]+>(?P<title>[^<]+)'
|
||||
|
||||
+3
-3
@@ -24,12 +24,12 @@ except:
|
||||
|
||||
|
||||
main_host = host + '/vvvvid/ondemand/'
|
||||
host = main_host
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
if conn_id:
|
||||
host = main_host
|
||||
anime = ['anime/',
|
||||
('Popolari',['anime/', 'peliculas', 'channel/10002/last/']),
|
||||
('Nuove Uscite',['anime/', 'peliculas', 'channel/10007/last/']),
|
||||
@@ -220,8 +220,8 @@ def make_itemlist(itemlist, item, data):
|
||||
if item.contentType != 'movie': infoLabels['tvshowtitle'] = fulltitle
|
||||
itemlist.append(
|
||||
item.clone(title = support.typo(title, 'bold'),
|
||||
fulltitle= fulltitle,
|
||||
show= fulltitle,
|
||||
fulltitle= title,
|
||||
show= title,
|
||||
url= main_host + str(key['show_id']) + '/seasons/',
|
||||
action= 'findvideos' if item.contentType == 'movie' else 'episodios',
|
||||
contentType = item.contentType,
|
||||
|
||||
+3
-3
@@ -86,14 +86,14 @@ def encode(path, _samba=False):
|
||||
@rtype: str
|
||||
@return path encoded in system character set or utf-8 if samba
|
||||
"""
|
||||
# from core.support import dbg;dbg()
|
||||
if not isinstance(path, unicode):
|
||||
path = unicode(path, "utf-8", "ignore")
|
||||
|
||||
if scrapertools.find_single_match(path, r'(^\w+:\/\/)') or _samba and not PY3:
|
||||
if not PY3:
|
||||
if scrapertools.find_single_match(path, r'(^\w+:\/\/)') or _samba:
|
||||
path = path.encode("utf-8", "ignore")
|
||||
else:
|
||||
if fs_encoding and not PY3:
|
||||
if fs_encoding:
|
||||
path = path.encode(fs_encoding, "ignore")
|
||||
|
||||
# if PY3 and isinstance(path, bytes):
|
||||
|
||||
@@ -478,3 +478,27 @@ def get_md5(cadena):
|
||||
devuelve = binascii.hexlify(md5.new(cadena).digest())
|
||||
|
||||
return devuelve
|
||||
|
||||
|
||||
def title_unify(title):
|
||||
import unicodedata
|
||||
|
||||
u_title = ''
|
||||
if type(title) == str: title = u'' + title
|
||||
for c in unicodedata.normalize('NFD', title):
|
||||
cat = unicodedata.category(c)
|
||||
if cat != 'Mn':
|
||||
if cat == 'Pd':
|
||||
c_new = '-'
|
||||
elif cat in ['Ll', 'Lu'] or c == ':':
|
||||
c_new = c
|
||||
else:
|
||||
c_new = ' '
|
||||
u_title += c_new
|
||||
|
||||
if (u_title.count(':') + u_title.count('-')) == 1:
|
||||
# subtitle, split but only if there's one, it might be part of title
|
||||
spl = u_title.replace(':', '-').split('-')
|
||||
u_title = spl[0] if len(spl[0]) > 5 else spl[1]
|
||||
|
||||
return u_title.strip()
|
||||
|
||||
+17
-7
@@ -558,7 +558,7 @@ def scrape(func):
|
||||
|
||||
if anime and inspect.stack()[1][3] not in ['find_episodes']:
|
||||
from platformcode import autorenumber
|
||||
if (function == 'episodios' or item.action == 'episodios'): autorenumber.start(itemlist, item)
|
||||
if function == 'episodios': autorenumber.start(itemlist, item)
|
||||
else: autorenumber.start(itemlist)
|
||||
# if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
|
||||
# pass
|
||||
@@ -1123,6 +1123,15 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
|
||||
# If the call is direct, leave it blank
|
||||
logger.debug()
|
||||
action = inspect.stack()[function_or_level][3] if type(function_or_level) == int else function_or_level
|
||||
|
||||
if not data and not patron and not next_page:
|
||||
itemlist.append(
|
||||
item.clone(action = action,
|
||||
title=typo(config.get_localized_string(30992), 'color kod bold'),
|
||||
nextPage=True,
|
||||
thumbnail=thumb()))
|
||||
return itemlist[-1]
|
||||
|
||||
if next_page == '':
|
||||
next_page = scrapertools.find_single_match(data, patron)
|
||||
|
||||
@@ -1133,12 +1142,9 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
|
||||
next_page = next_page.replace('&', '&')
|
||||
logger.debug('NEXT= ', next_page)
|
||||
itemlist.append(
|
||||
item.clone(channel=item.channel,
|
||||
action = action,
|
||||
contentType=item.contentType,
|
||||
item.clone(action = action,
|
||||
title=typo(config.get_localized_string(30992), 'color kod bold'),
|
||||
url=next_page,
|
||||
args=item.args,
|
||||
nextPage=True,
|
||||
thumbnail=thumb()))
|
||||
return itemlist[-1]
|
||||
@@ -1190,12 +1196,16 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
|
||||
videoitem.title = findS[0]
|
||||
videoitem.url = findS[1]
|
||||
srv_param = servertools.get_server_parameters(videoitem.server.lower())
|
||||
|
||||
logger.debug(videoitem)
|
||||
if videoitem.video_urls or srv_param.get('active', False):
|
||||
item.title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' or (config.get_localized_string(30161) in item.title) else item.title
|
||||
|
||||
quality = videoitem.quality if videoitem.quality else item.quality if item.quality else ''
|
||||
videoitem.title = (item.title if item.channel not in ['url'] else '') + (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "") + (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")
|
||||
videoitem.title = (item.title if item.channel not in ['url'] else '')\
|
||||
+ (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "")\
|
||||
+ (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")\
|
||||
+ (typo(videoitem.contentLanguage, '_ color kod []') if videoitem.contentLanguage else "")\
|
||||
+ (typo(videoitem.extraInfo, '_ color kod []') if videoitem.extraInfo else "")
|
||||
videoitem.plot = typo(videoitem.title, 'bold') + (typo(quality, '_ [] bold') if quality else '')
|
||||
videoitem.channel = item.channel
|
||||
videoitem.fulltitle = item.fulltitle
|
||||
|
||||
+33
-54
@@ -21,9 +21,11 @@ import ast, copy, re, time
|
||||
from core import filetools, httptools, jsontools, scrapertools
|
||||
from core.item import InfoLabels
|
||||
from platformcode import config, logger, platformtools
|
||||
import threading
|
||||
|
||||
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
|
||||
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
|
||||
lock = threading.Lock()
|
||||
|
||||
# ------------------------------------------------- -------------------------------------------------- --------
|
||||
# Set of functions related to infoLabels.
|
||||
@@ -200,18 +202,22 @@ def set_infoLabels_itemlist(item_list, seekTmdb=False, idioma_busqueda=def_lang,
|
||||
|
||||
if not config.get_setting('tmdb_active') and not forced:
|
||||
return
|
||||
import threading
|
||||
|
||||
# threads_num = config.get_setting("tmdb_threads", default=20)
|
||||
# semaforo = threading.Semaphore(threads_num)
|
||||
lock = threading.Lock()
|
||||
r_list = list()
|
||||
i = 0
|
||||
l_hilo = list()
|
||||
|
||||
def sub_thread(_item, _i, _seekTmdb):
|
||||
# semaforo.acquire()
|
||||
ret = 0
|
||||
try:
|
||||
ret = set_infoLabels_item(_item, _seekTmdb, idioma_busqueda, lock)
|
||||
except:
|
||||
import traceback
|
||||
logger.error(traceback.format_exc(1))
|
||||
if lock and lock.locked():
|
||||
lock.release()
|
||||
# logger.debug(str(ret) + "item: " + _item.tostring())
|
||||
# semaforo.release()
|
||||
r_list.append((_i, _item, ret))
|
||||
@@ -298,16 +304,18 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda=def_lang, lock=None
|
||||
if episodio:
|
||||
# Update data
|
||||
__leer_datos(otmdb_global)
|
||||
if episodio.get('episodio_titulo'):
|
||||
item.infoLabels['title'] = episodio['episodio_titulo']
|
||||
if episodio['episodio_sinopsis']:
|
||||
if episodio.get('episodio_sinopsis'):
|
||||
item.infoLabels['plot'] = episodio['episodio_sinopsis']
|
||||
if episodio['episodio_imagen']:
|
||||
if episodio.get('episodio_imagen'):
|
||||
item.infoLabels['poster_path'] = episodio['episodio_imagen']
|
||||
item.thumbnail = item.infoLabels['poster_path']
|
||||
if episodio['episodio_air_date']:
|
||||
if episodio.get('episodio_air_date'):
|
||||
item.infoLabels['aired'] = episodio['episodio_air_date']
|
||||
if episodio['episodio_vote_average']:
|
||||
if episodio.get('episodio_vote_average'):
|
||||
item.infoLabels['rating'] = episodio['episodio_vote_average']
|
||||
if episodio.get('episodio_vote_count'):
|
||||
item.infoLabels['votes'] = episodio['episodio_vote_count']
|
||||
|
||||
# 4l3x87 - fix for overlap infoLabels if there is episode or season
|
||||
@@ -411,51 +419,24 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda=def_lang, lock=None
|
||||
__leer_datos(otmdb)
|
||||
return len(item.infoLabels)
|
||||
|
||||
# title might contain - or : --> try to search only second title
|
||||
def splitTitle():
|
||||
if '-' in item.fulltitle:
|
||||
item.infoLabels['tvshowtitle'] = item.fulltitle.split('-')[1]
|
||||
item.infoLabels['title'] = item.infoLabels['tvshowtitle']
|
||||
elif ':' in item.fulltitle:
|
||||
item.infoLabels['tvshowtitle'] = item.fulltitle.split(':')[1]
|
||||
item.infoLabels['title'] = item.infoLabels['tvshowtitle']
|
||||
else:
|
||||
return False
|
||||
def unify():
|
||||
new_title = scrapertools.title_unify(item.fulltitle)
|
||||
if new_title != item.fulltitle:
|
||||
item.infoLabels['tvshowtitle'] = scrapertools.title_unify(item.infoLabels['tvshowtitle'])
|
||||
item.infoLabels['title'] = scrapertools.title_unify(item.infoLabels['title'])
|
||||
item.fulltitle = new_title
|
||||
return True
|
||||
# We check what type of content it is...
|
||||
if item.contentType == 'movie':
|
||||
tipo_busqueda = 'movie'
|
||||
elif item.contentType == 'undefined': # don't know
|
||||
def detect():
|
||||
# try movie first
|
||||
results = search(otmdb_global, 'movie')
|
||||
if results:
|
||||
item.contentType = 'movie'
|
||||
infoMovie = item.infoLabels
|
||||
if infoMovie['title'] == item.fulltitle: # exact match -> it's probably correct
|
||||
return results
|
||||
|
||||
# try tvshow then
|
||||
item.infoLabels = {'tvshowtitle': item.infoLabels['tvshowtitle']} # reset infolabels
|
||||
results = search(otmdb_global, 'tv')
|
||||
if results:
|
||||
item.contentType = 'tvshow'
|
||||
else:
|
||||
item.infoLabels = infoMovie
|
||||
|
||||
return results
|
||||
|
||||
results = detect()
|
||||
if not results:
|
||||
if splitTitle():
|
||||
results = detect()
|
||||
return results
|
||||
tipo_busqueda = 'multi'
|
||||
else:
|
||||
tipo_busqueda = 'tv'
|
||||
|
||||
ret = search(otmdb_global, tipo_busqueda)
|
||||
if not ret:
|
||||
if splitTitle():
|
||||
if not ret: # try with unified title
|
||||
if unify():
|
||||
ret = search(otmdb_global, tipo_busqueda)
|
||||
return ret
|
||||
# Search in tmdb is deactivated or has not given result
|
||||
@@ -1050,7 +1031,7 @@ class Tmdb(object):
|
||||
# We sort result based on fuzzy match to detect most similar
|
||||
if len(results) > 1:
|
||||
from lib.fuzzy_match import algorithims
|
||||
results.sort(key=lambda r: algorithims.trigram(text_simple, r['title'] if self.busqueda_tipo == 'movie' else r['name']), reverse=True)
|
||||
results.sort(key=lambda r: algorithims.trigram(text_simple, r.get('name', '') if self.busqueda_tipo == 'tv' else r.get('title', '')), reverse=True)
|
||||
|
||||
# We return the number of results of this page
|
||||
self.results = results
|
||||
@@ -1065,7 +1046,6 @@ class Tmdb(object):
|
||||
logger.error(msg)
|
||||
return 0
|
||||
|
||||
|
||||
def __discover(self, index_results=0):
|
||||
self.result = ResultDictDefault()
|
||||
results = []
|
||||
@@ -1425,27 +1405,27 @@ class Tmdb(object):
|
||||
if not temporada:
|
||||
# An error has occurred
|
||||
return {}
|
||||
# if capitulo == 9: from core.support import dbg;dbg()
|
||||
|
||||
if len(temporada["episodes"]) == 0:
|
||||
# An error has occurred
|
||||
logger.error("Episode %d of the season %d not found." % (capitulo, numtemporada))
|
||||
return {}
|
||||
|
||||
|
||||
elif len(temporada["episodes"]) < capitulo and temporada["episodes"][-1]['episode_number'] >= capitulo:
|
||||
n = None
|
||||
for i, chapters in enumerate(temporada["episodes"]):
|
||||
if chapters['episode_number'] == capitulo:
|
||||
n = i
|
||||
n = i + 1
|
||||
break
|
||||
if n != None:
|
||||
capitulo = n
|
||||
else:
|
||||
logger.error("Episode %d of the season %d not found." % (capitulo, numtemporada))
|
||||
return {}
|
||||
# else:
|
||||
# logger.error("Episode %d of the season %d not found." % (capitulo, numtemporada))
|
||||
# return {}
|
||||
|
||||
elif len(temporada["episodes"]) < capitulo:
|
||||
logger.error("Episode %d of the season %d not found." % (capitulo, numtemporada))
|
||||
return {}
|
||||
|
||||
ret_dic = dict()
|
||||
# Get data for this season
|
||||
@@ -1465,7 +1445,7 @@ class Tmdb(object):
|
||||
dic_aux = temporada.get('credits', {})
|
||||
ret_dic["temporada_cast"] = dic_aux.get('cast', [])
|
||||
ret_dic["temporada_crew"] = dic_aux.get('crew', [])
|
||||
if capitulo == -1:
|
||||
if capitulo == 0:
|
||||
# If we only look for season data, include the technical team that has intervened in any chapter
|
||||
dic_aux = dict((i['id'], i) for i in ret_dic["temporada_crew"])
|
||||
for e in temporada["episodes"]:
|
||||
@@ -1475,8 +1455,7 @@ class Tmdb(object):
|
||||
ret_dic["temporada_crew"] = list(dic_aux.values())
|
||||
|
||||
# Obtain chapter data if applicable
|
||||
|
||||
if capitulo != -1:
|
||||
if capitulo > 0:
|
||||
episodio = temporada["episodes"][capitulo - 1]
|
||||
ret_dic["episodio_titulo"] = episodio.get("name", )
|
||||
ret_dic["episodio_sinopsis"] = episodio["overview"]
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import xbmc, sys, xbmcgui, os
|
||||
from platformcode import config, logger
|
||||
|
||||
# incliuding folder libraries
|
||||
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
|
||||
sys.path.insert(0, librerias)
|
||||
|
||||
|
||||
from core import tmdb
|
||||
from core.item import Item
|
||||
|
||||
def execute_search():
|
||||
"""
|
||||
Gather the selected ListItem's attributes in order to compute the `Item` parameters
|
||||
and perform the KOD's globalsearch.
|
||||
Globalsearch will be executed specifing the content-type of the selected ListItem
|
||||
|
||||
NOTE: this method needs the DBTYPE and TMDB_ID specified as ListItem's properties
|
||||
"""
|
||||
|
||||
# These following lines are commented and keep in the code just as reminder.
|
||||
# In future, they could be used to filter the search outcome
|
||||
|
||||
# ADDON: maybe can we know if the current windows is related to a specific addon?
|
||||
# we could skip the ContextMenu if we already are in KOD's window
|
||||
|
||||
tmdbid = xbmc.getInfoLabel('ListItem.Property(tmdb_id)')
|
||||
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
|
||||
title = xbmc.getInfoLabel('ListItem.Title')
|
||||
year = xbmc.getInfoLabel('ListItem.Year')
|
||||
imdb = xbmc.getInfoLabel('ListItem.IMDBNumber')
|
||||
# folderPath = xbmc.getInfoLabel('Container.FolderPath')
|
||||
# filePath = xbmc.getInfoLabel('ListItem.FileNameAndPath')
|
||||
# logger.info("****")
|
||||
# logger.info( xbmc.getCondVisibility("String.Contains(Container.FolderPath, 'plugin.video.kod')") )
|
||||
# logger.info( xbmc.getCondVisibility("String.Contains(ListItem.FileNameAndPath, 'plugin.video.kod')") )
|
||||
# logger.info( xbmc.getCondVisibility("String.IsEqual(ListItem.dbtype,tvshow)") )
|
||||
# logger.info( xbmc.getCondVisibility("String.IsEqual(ListItem.dbtype,movie)") )
|
||||
# logger.info("****")
|
||||
|
||||
# visible = xbmc.getCondVisibility("!String.StartsWith(ListItem.FileNameAndPath, 'plugin://plugin.video.kod/') + [String.IsEqual(ListItem.dbtype,tvshow) | String.IsEqual(ListItem.dbtype,movie)]")
|
||||
|
||||
logstr = "Selected ListItem is: 'IMDB: {}' - TMDB: {}' - 'Title: {}' - 'Year: {}'' - 'Type: {}'".format(imdb, tmdbid, title, year, mediatype)
|
||||
logger.info(logstr)
|
||||
|
||||
if not tmdbid and imdb:
|
||||
logger.info('No TMDBid found. Try to get by IMDB')
|
||||
it = Item(contentType= mediatype, infoLabels={'imdb_id' : imdb})
|
||||
tmdb.set_infoLabels(it)
|
||||
tmdbid = it.infoLabels.get('tmdb_id', '')
|
||||
|
||||
if not tmdbid:
|
||||
logger.info('No TMDBid found. Try to get by Title/Year')
|
||||
it = Item(contentTitle= title, contentType= mediatype, infoLabels={'year' : year})
|
||||
tmdb.set_infoLabels(it)
|
||||
tmdbid = it.infoLabels.get('tmdb_id', '')
|
||||
|
||||
|
||||
item = Item(
|
||||
action="Search",
|
||||
channel="globalsearch",
|
||||
contentType= mediatype,
|
||||
mode="search",
|
||||
text= title,
|
||||
type= mediatype,
|
||||
infoLabels= {
|
||||
'tmdb_id': tmdbid,
|
||||
'year': year
|
||||
},
|
||||
folder= False
|
||||
)
|
||||
|
||||
logger.info("Invoking Item: {}".format(item.tostring()))
|
||||
|
||||
itemurl = item.tourl()
|
||||
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + itemurl + ")")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
execute_search()
|
||||
@@ -88,20 +88,20 @@ def process_request_proxy(url):
|
||||
time.sleep(0.5)
|
||||
result = requests.get(
|
||||
url_request_proxy,
|
||||
timeout=20,
|
||||
headers={'User-Agent': 'android'}
|
||||
timeout=20
|
||||
# headers={'User-Agent': 'android'}
|
||||
)
|
||||
data = result.content.decode('utf-8', 'ignore')
|
||||
if not PY3:
|
||||
data = data.encode('utf-8')
|
||||
if logger:
|
||||
logger.debug()
|
||||
logger.debug(url_request_proxy)
|
||||
|
||||
data = re.sub('\s(\w+)=(?!")([^<>\s]+)', r' \1="\2"', data)
|
||||
data = re.sub('https://translate\.googleusercontent\.com/.*?u=(.*?)&usg=[A-Za-z0-9_-]+', '\\1', data)
|
||||
data = re.sub('https?://[a-zA-Z0-9]+--' + domain.replace('.', '-') + '\.translate\.goog(/[a-zA-Z0-9#/-]+)', 'https://' + domain + '\\1', data)
|
||||
data = re.sub('https?://[a-zA-Z0-9-]+' + domain.replace('.', '-') + '\.translate\.goog(/[a-zA-Z0-9#/-]+)', 'https://' + domain + '\\1', data)
|
||||
data = re.sub('\s+<', '<', data)
|
||||
data = data.replace('&', '&').replace('https://translate.google.com/website?sl=' + SL + '&tl=' + TL + '&u=', '')
|
||||
data = data.replace('&', '&').replace('https://translate.google.com/website?sl=' + SL + '&tl=' + TL + '&ajax=1&u=', '')
|
||||
|
||||
return {'url': url.strip(), 'result': result, 'data': data}
|
||||
except Exception as e:
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
|
||||
from core import support
|
||||
import xbmc, xbmcgui, re, base64, inspect, sys
|
||||
from core import jsontools, tmdb, scrapertools, filetools
|
||||
from core.item import Item
|
||||
@@ -99,11 +100,11 @@ class autorenumber():
|
||||
def __init__(self, itemlist, item=None):
|
||||
self.item = item
|
||||
self.itemlist = itemlist
|
||||
self.renumberdict = load(self.itemlist[0]) if self.itemlist else load(item) if item else {}
|
||||
self.selectspecials = False
|
||||
self.manual = False
|
||||
self.auto = False
|
||||
if self.item:
|
||||
self.renumberdict = load(item)
|
||||
self.auto = config.get_setting('autorenumber', item.channel)
|
||||
self.title = self.item.fulltitle.strip()
|
||||
if match(self.itemlist[0].title, patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
|
||||
@@ -129,6 +130,7 @@ class autorenumber():
|
||||
self.episodes = {}
|
||||
self.config()
|
||||
else:
|
||||
self.renumberdict = {}
|
||||
for item in self.itemlist:
|
||||
item.context = [{"title": typo(config.get_localized_string(70585), 'bold'),
|
||||
"action": "start",
|
||||
@@ -140,13 +142,16 @@ class autorenumber():
|
||||
# Pulizia del Titolo
|
||||
if any( word in self.title.lower() for word in ['specials', 'speciali']):
|
||||
self.title = re.sub(r'\s*specials|\s*speciali', '', self.title.lower())
|
||||
elif not self.item.infoLabels['tvdb_id']:
|
||||
elif not self.item.infoLabels['tmdb_id']:
|
||||
self.item.contentSerieName = self.title.rstrip('123456789 ')
|
||||
|
||||
while not self.item.exit:
|
||||
self.item.infoLabels['imdb_id'] = ''
|
||||
self.item.infoLabels['tvdb_id'] = ''
|
||||
self.item.infoLabels['tmdb_id'] = ''
|
||||
self.item.infoLabels['year'] = '-'
|
||||
self.item.contentType = 'tvshow'
|
||||
|
||||
while not self.item.exit:
|
||||
tmdb.find_and_set_infoLabels(self.item)
|
||||
if self.item.infoLabels['tmdb_id']: self.item.exit = True
|
||||
else:self.item = platformtools.dialog_info(self.item, 'tmdb')
|
||||
|
||||
@@ -6479,3 +6479,7 @@ msgstr ""
|
||||
msgctxt "#80050"
|
||||
msgid "Downloading..."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#90001"
|
||||
msgid "Search on KOD"
|
||||
msgstr "Search on KOD..."
|
||||
|
||||
@@ -6480,3 +6480,8 @@ msgstr "Rimuovi episodi in locale"
|
||||
msgctxt "#80050"
|
||||
msgid "Downloading..."
|
||||
msgstr "Download in corso..."
|
||||
|
||||
|
||||
msgctxt "#90001"
|
||||
msgid "Search on KOD"
|
||||
msgstr "Cerca con KOD..."
|
||||
|
||||
+15
-11
@@ -19,9 +19,6 @@ defp = defpage[config.get_setting('pagination','community')]
|
||||
disable_pagination = False
|
||||
show_seasons = config.get_setting('show_seasons','community')
|
||||
|
||||
list_servers = ['directo', 'akstream', 'wstream', 'backin', 'cloudvideo', 'clipwatching', 'fembed', 'gounlimited', 'mega', 'mixdrop']
|
||||
list_quality = ['SD', '720', '1080', '4k']
|
||||
|
||||
tmdb_api = 'a1ab8b8669da03637a4b98fa39c39228'
|
||||
|
||||
def mainlist(item):
|
||||
@@ -401,14 +398,16 @@ def findvideos(item):
|
||||
json = item.url['links']
|
||||
else:
|
||||
json = item.url
|
||||
|
||||
# support.dbg()
|
||||
for option in json:
|
||||
extra = set_extra_values(item, option, item.path)
|
||||
title = item.fulltitle + (' - '+option['title'] if 'title' in option else '')
|
||||
title = set_title(title, extra.language, extra.quality)
|
||||
|
||||
itemlist.append(item.clone(channel=item.channel, title=title, url=option['url'], action='play', quality=extra.quality,
|
||||
language=extra.language, infoLabels=item.infoLabels))
|
||||
itemlist.append(
|
||||
item.clone(url=option['url'],
|
||||
action='play',
|
||||
quality=extra.quality,
|
||||
contentLanguage=extra.language,
|
||||
extraInfo=extra.info))
|
||||
|
||||
item.url = '' # do not pass referer
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -673,7 +672,8 @@ def set_extra_values(item, json, path):
|
||||
ret = Item()
|
||||
for key in json:
|
||||
if key == 'quality':
|
||||
ret.quality = json[key].upper()
|
||||
ret.quality = json[key]
|
||||
if ret.quality and not ret.quality[0].isdigit(): ret.quality = ret.quality.upper()
|
||||
elif key == 'language':
|
||||
ret.language = json[key].upper()
|
||||
elif key == 'plot':
|
||||
@@ -699,6 +699,8 @@ def set_extra_values(item, json, path):
|
||||
ret.filterkey = filterkey
|
||||
elif key == 'description':
|
||||
ret.description = json[key]
|
||||
elif key == 'info':
|
||||
ret.info = json[key]
|
||||
|
||||
if not ret.thumb:
|
||||
if 'get_search_menu' in inspect.stack()[1][3]:
|
||||
@@ -714,7 +716,7 @@ def set_extra_values(item, json, path):
|
||||
|
||||
|
||||
# format titles
|
||||
def set_title(title, language='', quality=''):
|
||||
def set_title(title, language='', quality='', info=''):
|
||||
logger.debug()
|
||||
|
||||
t = support.match(title, patron=r'\{([^\}]+)\}').match
|
||||
@@ -729,7 +731,9 @@ def set_title(title, language='', quality=''):
|
||||
title += support.typo(language.upper(), '_ [] color kod bold')
|
||||
else:
|
||||
for lang in language:
|
||||
title += support.typo(lang.upper(), '_ [] color kod bold')
|
||||
title += support.typo(language.upper(), '_ [] color kod bold')
|
||||
if info:
|
||||
title += support.typo(info.upper(), '_ [] color kod bold')
|
||||
|
||||
return title
|
||||
|
||||
|
||||
+52
-58
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import xbmc, xbmcgui, sys, channelselector, time, os
|
||||
from core import support
|
||||
from core.support import dbg, tmdb
|
||||
from core.item import Item
|
||||
from core import channeltools, servertools, scrapertools
|
||||
@@ -72,7 +71,7 @@ EPISODESLIST = 200
|
||||
SERVERLIST = 300
|
||||
|
||||
class SearchWindow(xbmcgui.WindowXML):
|
||||
def start(self, item, moduleDict={}, searchActions=[]):
|
||||
def start(self, item, moduleDict={}, searchActions=[], thActions=None):
|
||||
logger.debug()
|
||||
self.exit = False
|
||||
self.item = item
|
||||
@@ -89,12 +88,13 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.selected = False
|
||||
self.pos = 0
|
||||
self.items = []
|
||||
self.search_threads = []
|
||||
|
||||
if not searchActions:
|
||||
self.thActions = Thread(target=self.getActions)
|
||||
self.thActions.start()
|
||||
else:
|
||||
self.thActions = None
|
||||
self.thActions = thActions
|
||||
|
||||
self.lastSearch()
|
||||
if not self.item.text: return
|
||||
@@ -292,7 +292,24 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
|
||||
def timer(self):
|
||||
while self.searchActions:
|
||||
if self.exit: return
|
||||
percent = (float(self.count) / len(self.searchActions)) * 100
|
||||
self.LOADING.setVisible(False)
|
||||
self.PROGRESS.setPercent(percent)
|
||||
self.COUNT.setText('%s/%s [%s"]' % (self.count, len(self.searchActions), int(time.time() - self.time)))
|
||||
if percent == 100:
|
||||
self.channels = []
|
||||
self.moduleDict = {}
|
||||
self.searchActions = []
|
||||
|
||||
# if no results
|
||||
total = 0
|
||||
for num in self.results.values():
|
||||
total += num
|
||||
if not total:
|
||||
self.PROGRESS.setVisible(False)
|
||||
self.NORESULTS.setVisible(True)
|
||||
self.setFocusId(CLOSE)
|
||||
time.sleep(1)
|
||||
|
||||
def search(self):
|
||||
@@ -303,11 +320,21 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.thActions.join()
|
||||
Thread(target=self.timer).start()
|
||||
|
||||
try:
|
||||
with futures.ThreadPoolExecutor(max_workers=set_workers()) as executor:
|
||||
for searchAction in self.searchActions:
|
||||
if self.exit: return
|
||||
executor.submit(self.get_channel_results, searchAction)
|
||||
logger.debug('end search for:', searchAction.channel)
|
||||
self.search_threads.append(executor.submit(self.get_channel_results, searchAction))
|
||||
for ch in futures.as_completed(self.search_threads):
|
||||
self.count += 1
|
||||
if self.exit: return
|
||||
if ch.result():
|
||||
channel, valid, other = ch.result()
|
||||
self.update(channel, valid, other)
|
||||
except:
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
self.count = len(self.searchActions)
|
||||
|
||||
def get_channel_results(self, searchAction):
|
||||
def search(text):
|
||||
@@ -320,7 +347,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
|
||||
if self.item.mode != 'all':
|
||||
for elem in results:
|
||||
if elem.infoLabels['tmdb_id'] == self.item.infoLabels['tmdb_id']:
|
||||
if elem.infoLabels.get('tmdb_id') == self.item.infoLabels.get('tmdb_id'):
|
||||
elem.from_channel = channel
|
||||
elem.verified = 1
|
||||
valid.append(elem)
|
||||
@@ -349,10 +376,10 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
logger.debug('retring with original title on channel ' + channel)
|
||||
dummy, valid, dummy = search(self.item.infoLabels.get('originaltitle'))
|
||||
except:
|
||||
pass
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
self.count += 1
|
||||
return self.update(channel, valid, other if other else results)
|
||||
return channel, valid, other if other else results
|
||||
|
||||
def makeItem(self, url):
|
||||
item = Item().fromurl(url)
|
||||
@@ -388,21 +415,27 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
pos = self.CHANNELS.getSelectedPosition()
|
||||
self.CHANNELS.addItems(self.channels)
|
||||
self.CHANNELS.selectItem(pos)
|
||||
self.setFocusId(CHANNELS)
|
||||
if valid:
|
||||
self.setFocusId(RESULTS)
|
||||
|
||||
if valid and self.CHANNELS.size():
|
||||
item = self.CHANNELS.getListItem(0)
|
||||
resultsList = item.getProperty('items')
|
||||
for result in valid:
|
||||
resultsList += result.tourl() + '|'
|
||||
item.setProperty('items', resultsList)
|
||||
self.channels[0].setProperty('results', str(len(resultsList.split('|'))))
|
||||
self.channels[0].setProperty('results', str(len(resultsList.split('|')) - 1 ))
|
||||
|
||||
if self.CHANNELS.getSelectedPosition() == 0:
|
||||
items = []
|
||||
for result in valid:
|
||||
if result: items.append(self.makeItem(result.tourl()))
|
||||
pos = self.RESULTS.getSelectedPosition()
|
||||
self.RESULTS.addItems(items)
|
||||
if pos < 0:
|
||||
self.setFocusId(RESULTS)
|
||||
pos = 0
|
||||
self.RESULTS.selectItem(pos)
|
||||
|
||||
if results:
|
||||
resultsList = ''
|
||||
channelParams = channeltools.get_channel_parameters(channel)
|
||||
@@ -440,24 +473,6 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.RESULTS.reset()
|
||||
self.RESULTS.addItems(items)
|
||||
|
||||
percent = (float(self.count) / len(self.searchActions)) * 100
|
||||
self.LOADING.setVisible(False)
|
||||
self.PROGRESS.setPercent(percent)
|
||||
self.COUNT.setText('%s/%s [%s"]' % (self.count, len(self.searchActions), int(time.time() - self.time) ))
|
||||
if percent == 100:
|
||||
self.channels = []
|
||||
self.moduleDict = {}
|
||||
self.searchActions = []
|
||||
|
||||
# if no results
|
||||
total = 0
|
||||
for num in self.results.values():
|
||||
total += num
|
||||
if not total:
|
||||
self.PROGRESS.setVisible(False)
|
||||
self.NORESULTS.setVisible(True)
|
||||
self.setFocusId(CLOSE)
|
||||
|
||||
def onInit(self):
|
||||
self.time = time.time()
|
||||
|
||||
@@ -485,7 +500,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
if self.item.mode in ['all', 'search']:
|
||||
if self.item.type:
|
||||
self.item.mode = self.item.type
|
||||
self.item.text = title_unify(self.item.text)
|
||||
self.item.text = scrapertools.title_unify(self.item.text)
|
||||
self.thread = Thread(target=self.search)
|
||||
self.thread.start()
|
||||
elif self.item.mode in ['movie', 'tvshow', 'person_']:
|
||||
@@ -537,7 +552,8 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
elif (action in [DOWN] and focus in [BACK, CLOSE, MENU]) or focus not in [BACK, CLOSE, MENU, SERVERLIST, EPISODESLIST, RESULTS, CHANNELS]:
|
||||
if self.SERVERS.isVisible(): self.setFocusId(SERVERLIST)
|
||||
elif self.EPISODES.isVisible(): self.setFocusId(EPISODESLIST)
|
||||
elif self.RESULTS.isVisible(): self.setFocusId(RESULTS)
|
||||
elif self.RESULTS.isVisible() and self.RESULTS.size() > 0: self.setFocusId(RESULTS)
|
||||
elif self.CHANNELS.isVisible(): self.setFocusId(CHANNELS)
|
||||
|
||||
elif focus in [RESULTS]:
|
||||
pos = self.RESULTS.getSelectedPosition()
|
||||
@@ -594,7 +610,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.actors()
|
||||
elif search == 'persons':
|
||||
item = self.item.clone(mode='person_', discovery=self.persons[pos])
|
||||
Search(item, self.moduleDict, self.searchActions)
|
||||
Search(item, self.moduleDict, self.searchActions, self.thActions)
|
||||
if close_action:
|
||||
self.close()
|
||||
else:
|
||||
@@ -602,7 +618,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
if self.item.mode == 'movie': item.contentTitle = self.RESULTS.getSelectedItem().getLabel()
|
||||
else: item.contentSerieName = self.RESULTS.getSelectedItem().getLabel()
|
||||
|
||||
Search(item, self.moduleDict, self.searchActions)
|
||||
Search(item, self.moduleDict, self.searchActions, self.thActions)
|
||||
if close_action:
|
||||
self.close()
|
||||
|
||||
@@ -736,6 +752,8 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.exit = True
|
||||
if self.thread:
|
||||
busy(True)
|
||||
for th in self.search_threads:
|
||||
th.cancel()
|
||||
self.thread.join()
|
||||
busy(False)
|
||||
self.close()
|
||||
@@ -766,27 +784,3 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
server.window = True
|
||||
server.globalsearch = True
|
||||
return run(server)
|
||||
|
||||
|
||||
def title_unify(title):
|
||||
import unicodedata
|
||||
|
||||
u_title = ''
|
||||
if type(title) == str: title = u'' + title
|
||||
for c in unicodedata.normalize('NFD', title):
|
||||
cat = unicodedata.category(c)
|
||||
if cat != 'Mn':
|
||||
if cat == 'Pd':
|
||||
c_new = '-'
|
||||
elif cat in ['Ll', 'Lu'] or c == ':':
|
||||
c_new = c
|
||||
else:
|
||||
c_new = ' '
|
||||
u_title += c_new
|
||||
|
||||
if (u_title.count(':') + u_title.count('-')) == 1:
|
||||
# subtitle, split but only if there's one, it might be part of title
|
||||
spl = u_title.replace(':', '-').split('-')
|
||||
u_title = spl[0] if len(spl[0]) > 5 else spl[1]
|
||||
|
||||
return u_title.strip()
|
||||
|
||||
+14
-10
@@ -42,9 +42,14 @@ if __name__ == '__main__':
|
||||
with open(fileJson) as f:
|
||||
data = json.load(f)
|
||||
|
||||
result = data['direct']
|
||||
chList = os.listdir('channels')
|
||||
|
||||
for chann, host in sorted(data['direct'].items()):
|
||||
for k in data.keys():
|
||||
for chann, host in sorted(data[k].items()):
|
||||
if chann + '.json' not in chList:
|
||||
print(chann + ' not exists anymore')
|
||||
del data[k][chann]
|
||||
continue
|
||||
# to get an idea of the timing
|
||||
# useful only if you control all channels
|
||||
# for channels with error 522 about 40 seconds are lost ...
|
||||
@@ -54,11 +59,11 @@ if __name__ == '__main__':
|
||||
|
||||
# all right
|
||||
if rslt['code'] == 200:
|
||||
result[chann] = host
|
||||
data[k][chann] = host
|
||||
# redirect
|
||||
elif str(rslt['code']).startswith('3'):
|
||||
# result[chann] = str(rslt['code']) +' - '+ rslt['redirect'][:-1]
|
||||
result[chann] = rslt['redirect']
|
||||
# data[k][chann] = str(rslt['code']) +' - '+ rslt['redirect'][:-1]
|
||||
data[k][chann] = rslt['redirect']
|
||||
# cloudflare...
|
||||
elif rslt['code'] in [429, 503, 403]:
|
||||
from lib import proxytranslate
|
||||
@@ -67,7 +72,7 @@ if __name__ == '__main__':
|
||||
print('Cloudflare riconosciuto')
|
||||
try:
|
||||
page_data = proxytranslate.process_request_proxy(host).get('data', '')
|
||||
result[chann] = re.search('<base href="([^"]+)', page_data).group(1)
|
||||
data[k][chann] = re.search('<base href="([^"]+)', page_data).group(1)
|
||||
rslt['code_new'] = 200
|
||||
except Exception as e:
|
||||
import traceback
|
||||
@@ -83,10 +88,9 @@ if __name__ == '__main__':
|
||||
print('Errore Sconosciuto - '+str(rslt['code']) +' - '+ host)
|
||||
|
||||
print("check #### FINE #### rslt :%s " % (rslt))
|
||||
if result[chann].endswith('/'):
|
||||
result[chann] = result[chann][:-1]
|
||||
if data[k][chann].endswith('/'):
|
||||
data[k][chann] = data[k][chann][:-1]
|
||||
|
||||
result = {'findhost': data['findhost'], 'direct': result}
|
||||
# I write the updated file
|
||||
with open(fileJson, 'w') as f:
|
||||
json.dump(result, f, sort_keys=True, indent=4)
|
||||
json.dump(data, f, sort_keys=True, indent=4)
|
||||
|
||||
+2
-1
@@ -107,7 +107,8 @@ if __name__ == '__main__':
|
||||
path = search_paths(sys.listitem.getVideoInfoTag().getDbId())
|
||||
if path:
|
||||
item = Item(action="update_tvshow", channel="videolibrary", path=path)
|
||||
item.tourl()
|
||||
# Why? I think it is not necessary, just commented
|
||||
# item.tourl()
|
||||
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")")
|
||||
else:
|
||||
dialog = xbmcgui.Dialog()
|
||||
|
||||
Reference in New Issue
Block a user