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:
mac12m99
2021-04-28 21:52:53 +02:00
parent 73cb2b9d6a
commit b70aeb5191
25 changed files with 363 additions and 242 deletions
@@ -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.
+7 -5
View File
@@ -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 &quot;cerca trailer&quot;
- 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
View File
@@ -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",
+3
View File
@@ -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 -1
View File
@@ -1,7 +1,7 @@
{
"id": "animeleggendari",
"name": "AnimePerTutti",
"active": true,
"active": false,
"language": ["ita", "sub-ita"],
"thumbnail": "animepertutti.png",
"bannermenu": "animepertutti.png",
+2 -2
View File
@@ -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()
+2 -2
View File
@@ -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()
+10 -1
View File
@@ -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
+1 -1
View File
@@ -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 .
+2
View File
@@ -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>'
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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):
+24
View File
@@ -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
View File
@@ -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('&amp;', '&')
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
View File
@@ -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"]
+80
View File
@@ -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()
+5 -5
View File
@@ -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=(.*?)&amp;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('&amp;', '&').replace('https://translate.google.com/website?sl=' + SL + '&tl=' + TL + '&u=', '')
data = data.replace('&amp;', '&').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:
+8 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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()