KoD 1.6.2
- Migliorata funzione cerca trailer\n- Episodio successivo: è ora disponibile la modalità playlist (puoi usare il tasto riproduci successivo di kodi)\n- aggiunto www.accuradio.com\n- migliorie varie\n
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.6.1" provider-name="KoD Team">
|
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.6.2" provider-name="KoD Team">
|
||||||
<requires>
|
<requires>
|
||||||
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
|
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
|
||||||
<import addon="metadata.themoviedb.org"/>
|
<import addon="metadata.themoviedb.org"/>
|
||||||
@@ -23,12 +23,14 @@
|
|||||||
<assets>
|
<assets>
|
||||||
<icon>resources/media/logo.png</icon>
|
<icon>resources/media/logo.png</icon>
|
||||||
<fanart>resources/media/fanart.jpg</fanart>
|
<fanart>resources/media/fanart.jpg</fanart>
|
||||||
<screenshot>resources/media/themes/ss/1.png</screenshot>
|
<screenshot>resources/media/screenshot-1.png</screenshot>
|
||||||
<screenshot>resources/media/themes/ss/2.png</screenshot>
|
<screenshot>resources/media/screenshot-2.png</screenshot>
|
||||||
<screenshot>resources/media/themes/ss/3.png</screenshot>
|
<screenshot>resources/media/screenshot-3.png</screenshot>
|
||||||
</assets>
|
</assets>
|
||||||
<news>-Migliorata l'efficacia del riconoscimento dei contenuti in ricerca film/serie
|
<news>- Migliorata funzione "cerca trailer"
|
||||||
- corretti alcuni bug e fatti alcuni fix per i soliti cambi di struttura</news>
|
- Episodio successivo: è ora disponibile la modalità playlist (puoi usare il tasto riproduci successivo di kodi)
|
||||||
|
- aggiunto www.accuradio.com
|
||||||
|
- migliorie varie</news>
|
||||||
<description lang="it">Naviga velocemente sul web e guarda i contenuti presenti</description>
|
<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]
|
<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>
|
[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>
|
||||||
|
|||||||
+9
-9
@@ -14,7 +14,7 @@
|
|||||||
"casacinema": "https://www.casacinema.page",
|
"casacinema": "https://www.casacinema.page",
|
||||||
"cb01anime": "https://www.cineblog01.red",
|
"cb01anime": "https://www.cineblog01.red",
|
||||||
"cineblog01": "https://cb01.uno",
|
"cineblog01": "https://cb01.uno",
|
||||||
"cinemalibero": "https://cinemalibero.website",
|
"cinemalibero": "https://cinemalibero.pink",
|
||||||
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
|
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
|
||||||
"discoveryplus": "https://www.discoveryplus.com",
|
"discoveryplus": "https://www.discoveryplus.com",
|
||||||
"dreamsub": "https://dreamsub.stream",
|
"dreamsub": "https://dreamsub.stream",
|
||||||
@@ -22,24 +22,24 @@
|
|||||||
"eurostreaming": "https://eurostreaming.team",
|
"eurostreaming": "https://eurostreaming.team",
|
||||||
"filmgratis": "https://www.filmaltadefinizione.me",
|
"filmgratis": "https://www.filmaltadefinizione.me",
|
||||||
"filmigratis": "https://filmigratis.org",
|
"filmigratis": "https://filmigratis.org",
|
||||||
"filmsenzalimiticc": "https://www.filmsenzalimiti01.xyz",
|
"filmsenzalimiticc": "https://www.filmsenzalimiti01.website",
|
||||||
"filmstreaming01": "https://filmstreaming01.com",
|
"filmstreaming01": "https://filmstreaming01.com",
|
||||||
"guardaserie_stream": "https://guardaserie.yoga",
|
"guardaserie_stream": "https://guardaserie.yoga",
|
||||||
"guardaseriecam": "https://guardaserie.cam",
|
"guardaseriecam": "https://guardaserie.cam",
|
||||||
"guardaserieclick": "https://www.guardaserie.plus",
|
"guardaserieclick": "https://www.guardaserie.vision",
|
||||||
"guardaserieicu": "https://guardaserie.cloud",
|
"guardaserieicu": "https://guardaserie.world",
|
||||||
"hd4me": "https://hd4me.net",
|
"hd4me": "https://hd4me.net",
|
||||||
"ilcorsaronero": "https://ilcorsaronero.link",
|
"ilcorsaronero": "https://ilcorsaronero.link",
|
||||||
"ilgeniodellostreaming": "https://ilgeniodellostreaming.soy",
|
"ilgeniodellostreaming": "https://ilgeniodellostreaming.moe",
|
||||||
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.gold",
|
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.photo",
|
||||||
"italiaserie": "https://italiaserie.fit",
|
"italiaserie": "https://italiaserie.casa",
|
||||||
"mediasetplay": "https://www.mediasetplay.mediaset.it",
|
"mediasetplay": "https://www.mediasetplay.mediaset.it",
|
||||||
"mondoserietv": "https://mondoserietv.fun",
|
"mondoserietv": "https://mondoserietv.fun",
|
||||||
"paramount": "https://www.paramountnetwork.it",
|
"paramount": "https://www.paramountnetwork.it",
|
||||||
"piratestreaming": "https://www.piratestreaming.guru",
|
"piratestreaming": "https://www.piratestreaming.codes",
|
||||||
"polpotv": "https://roma.polpo.tv",
|
"polpotv": "https://roma.polpo.tv",
|
||||||
"raiplay": "https://www.raiplay.it",
|
"raiplay": "https://www.raiplay.it",
|
||||||
"serietvonline": "https://serietvonline.pink",
|
"serietvonline": "https://serietvonline.blue",
|
||||||
"serietvsubita": "http://serietvsubita.xyz",
|
"serietvsubita": "http://serietvsubita.xyz",
|
||||||
"serietvu": "https://www.serietvu.link",
|
"serietvu": "https://www.serietvu.link",
|
||||||
"streamingcommunity": "https://streamingcommunity.co",
|
"streamingcommunity": "https://streamingcommunity.co",
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"id": "accuradio",
|
||||||
|
"name": "AccuRadio",
|
||||||
|
"active": true,
|
||||||
|
"language": ["*"],
|
||||||
|
"thumbnail": "accuradio.png",
|
||||||
|
"banner": "accuradio.png",
|
||||||
|
"categories": ["music"],
|
||||||
|
"not_active":["include_in_global_search"],
|
||||||
|
"settings" :[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Canale per accuradio
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
import random
|
||||||
|
from core import httptools, support
|
||||||
|
from platformcode import logger
|
||||||
|
|
||||||
|
host = 'https://www.accuradio.com'
|
||||||
|
api_url = host + '/c/m/json/{}/'
|
||||||
|
headers = [['Referer', host]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def mainlist(item):
|
||||||
|
itemlist = []
|
||||||
|
item.action = 'peliculas'
|
||||||
|
js = httptools.downloadpage(api_url.format('brands')).json
|
||||||
|
for it in js.get('features',[]):
|
||||||
|
itemlist.append(
|
||||||
|
item.clone(url= '{}/{}'.format(host,it.get('canonical_url','')),
|
||||||
|
title=support.typo(it['name'],'italic') + support.typo(it.get('channels',''),'_ [] color kod')
|
||||||
|
))
|
||||||
|
for it in js.get('brands',[]):
|
||||||
|
itemlist.append(
|
||||||
|
item.clone(url= '{}/{}'.format(host,it.get('canonical_url','')),
|
||||||
|
title=support.typo(it['name'],'bullet bold') + support.typo(it.get('channels',''),'_ [] color kod')
|
||||||
|
))
|
||||||
|
|
||||||
|
itemlist.append(item.clone(title=support.typo('Cerca...', 'bold color kod'), action='search', thumbnail=support.thumb('search')))
|
||||||
|
support.channel_config(item, itemlist)
|
||||||
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
|
@support.scrape
|
||||||
|
def peliculas(item):
|
||||||
|
action = 'playradio'
|
||||||
|
patron = r'data-id="(?P<id>[^"]+)"\s*data-oldid="(?P<oldid>[^"]+)".*?data-name="(?P<title>[^"]+)(?:[^>]+>){5}<img class="[^"]+"\s*src="(?P<thumb>[^"]+)(?:[^>]+>){6}\s*(?P<plot>[^<]+)'
|
||||||
|
return locals()
|
||||||
|
|
||||||
|
|
||||||
|
def playradio(item):
|
||||||
|
import xbmcgui, xbmc
|
||||||
|
items = httptools.downloadpage('{}/playlist/json/{}/?ando={}&rand={}'.format(host, item.id, item.oldid, random.random())).json
|
||||||
|
playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
|
||||||
|
playlist.clear()
|
||||||
|
for i in items:
|
||||||
|
if 'id' in i:
|
||||||
|
url = i['primary'] + i['fn'] + '.m4a'
|
||||||
|
title = i['title']
|
||||||
|
artist = i['track_artist']
|
||||||
|
album = i['album']['title']
|
||||||
|
year = i['album']['year']
|
||||||
|
thumb = 'https://www.accuradio.com/static/images/covers300' + i['album']['cdcover']
|
||||||
|
duration = i.get('duration',0)
|
||||||
|
info = {'duration':duration,
|
||||||
|
'album':album,
|
||||||
|
'artist':artist,
|
||||||
|
'title':title,
|
||||||
|
'year':year,
|
||||||
|
'mediatype':'music'}
|
||||||
|
item = xbmcgui.ListItem(title, path=url)
|
||||||
|
item.setArt({'thumb':thumb, 'poster':thumb, 'icon':thumb})
|
||||||
|
item.setInfo('music',info)
|
||||||
|
playlist.add(url, item)
|
||||||
|
xbmc.Player().play(playlist)
|
||||||
|
|
||||||
|
|
||||||
|
def search(item, text):
|
||||||
|
support.info(text)
|
||||||
|
item.url = host + '/search/' + text
|
||||||
|
itemlist = []
|
||||||
|
try:
|
||||||
|
data = support.match(item.url).data
|
||||||
|
artists = support.match(data, patronBlock=r'artistResults(.*?)</ul', patron=r'href="(?P<url>[^"]+)"\s*>(?P<title>[^<]+)').matches
|
||||||
|
if artists:
|
||||||
|
for url, artist in artists:
|
||||||
|
itemlist.append(item.clone(title=support.typo(artist,'bullet bold'), thumbnail=support.thumb('music'), url=host+url, action='peliculas'))
|
||||||
|
item.data = data
|
||||||
|
itemlist += peliculas(item)
|
||||||
|
# Continua la ricerca in caso di errore
|
||||||
|
except:
|
||||||
|
import sys
|
||||||
|
for line in sys.exc_info():
|
||||||
|
logger.error("%s" % line)
|
||||||
|
return itemlist
|
||||||
@@ -77,8 +77,8 @@ def peliculas(item):
|
|||||||
item.title += support.typo(item.lang2, '_ [] color kod')
|
item.title += support.typo(item.lang2, '_ [] color kod')
|
||||||
if item.args == 'update':
|
if item.args == 'update':
|
||||||
item.title = item.title.replace('-', ' ')
|
item.title = item.title.replace('-', ' ')
|
||||||
if item.args == 'search':
|
# if item.args == 'search':
|
||||||
item.contentType = 'tvshow' if 'serie-' in item.url else 'movie'
|
# item.contentType = 'tvshow' if 'serie-' in item.url else 'movie'
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
|||||||
@@ -186,9 +186,10 @@ def play(item):
|
|||||||
if item.contentType == 'episode': data = session.get('{}/playback/v2/videoPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
if item.contentType == 'episode': data = session.get('{}/playback/v2/videoPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
||||||
else: data = session.get('{}/playback/v2/channelPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
else: data = session.get('{}/playback/v2/channelPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
||||||
if data.get('protection', {}).get('drm_enabled',True):
|
if data.get('protection', {}).get('drm_enabled',True):
|
||||||
url = data['streaming']['dash']['url']
|
item.url = data['streaming']['dash']['url']
|
||||||
item.drm = 'com.widevine.alpha'
|
item.drm = 'com.widevine.alpha'
|
||||||
item.license = data['protection']['schemes']['widevine']['licenseUrl'] + '|PreAuthorization=' + data['protection']['drmToken'] + '|R{SSM}|'
|
item.license = data['protection']['schemes']['widevine']['licenseUrl'] + '|PreAuthorization=' + data['protection']['drmToken'] + '|R{SSM}|'
|
||||||
else:
|
else:
|
||||||
url = data['streaming']['hls']['url']
|
item.url = data['streaming']['hls']['url']
|
||||||
return support.servertools.find_video_items(item, data=url)
|
item.manifest = 'hls'
|
||||||
|
return [item]
|
||||||
@@ -115,7 +115,6 @@ def select(item):
|
|||||||
def search(item, texto):
|
def search(item, texto):
|
||||||
support.info()
|
support.info()
|
||||||
item.url = host + "/?s=" + texto
|
item.url = host + "/?s=" + texto
|
||||||
item.contentType = 'episode'
|
|
||||||
item.args = 'search'
|
item.args = 'search'
|
||||||
try:
|
try:
|
||||||
return peliculas(item)
|
return peliculas(item)
|
||||||
|
|||||||
@@ -157,12 +157,17 @@ def episodios(item):
|
|||||||
|
|
||||||
def findvideos(item):
|
def findvideos(item):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
return support.server(item, item.url, Download=False)
|
return support.server(item, itemlist=[item.clone(title='Paramount', server='directo', action='play')], Download=False)
|
||||||
|
|
||||||
|
|
||||||
def play(item):
|
def play(item):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
item.server = 'paramount_server'
|
item.manifest = 'hls'
|
||||||
|
mgid = support.match(item.url, patron=r'uri":"([^"]+)"').match
|
||||||
|
url = 'https://media.mtvnservices.com/pmt/e1/access/index.html?uri=' + mgid + '&configtype=edge&ref=' + item.url
|
||||||
|
ID, rootUrl = support.match(url, patron=[r'"id":"([^"]+)",',r'brightcove_mediagenRootURL":"([^"]+)"']).matches
|
||||||
|
item.url = jsontools.load(support.match(rootUrl.replace('&device={device}','').format(uri = ID)).data)['package']['video']['item'][0]['rendition'][0]['src']
|
||||||
|
|
||||||
if item.livefilter:
|
if item.livefilter:
|
||||||
d = liveDict()[item.livefilter]
|
d = liveDict()[item.livefilter]
|
||||||
item = item.clone(title=support.typo(item.livefilter, 'bold'), fulltitle=item.livefilter, url=d['url'], plot=d['plot'], action='play', forcethumb=True, no_return=True)
|
item = item.clone(title=support.typo(item.livefilter, 'bold'), fulltitle=item.livefilter, url=d['url'], plot=d['plot'], action='play', forcethumb=True, no_return=True)
|
||||||
|
|||||||
+8
-3
@@ -1,9 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Canale per altadefinizione01
|
# Canale per tunein
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
from core import support
|
from core import scrapertools, support
|
||||||
|
from platformcode import logger
|
||||||
|
|
||||||
host = 'http://api.radiotime.com'
|
host = 'http://api.radiotime.com'
|
||||||
headers = [['Referer', host]]
|
headers = [['Referer', host]]
|
||||||
@@ -32,6 +33,7 @@ def radio(item):
|
|||||||
data = support.match(item, patron= r'text="(?P<title>[^\("]+)(?:\((?P<location>[^\)]+)\))?" URL="(?P<url>[^"]+)" bitrate="(?P<quality>[^"]+)" reliability="[^"]+" guide_id="[^"]+" subtext="(?P<song>[^"]+)" genre_id="[^"]+" formats="(?P<type>[^"]+)" (?:playing="[^"]+" )?(?:playing_image="[^"]+" )?(?:show_id="[^"]+" )?(?:item="[^"]+" )?image="(?P<thumb>[^"]+)"')
|
data = support.match(item, patron= r'text="(?P<title>[^\("]+)(?:\((?P<location>[^\)]+)\))?" URL="(?P<url>[^"]+)" bitrate="(?P<quality>[^"]+)" reliability="[^"]+" guide_id="[^"]+" subtext="(?P<song>[^"]+)" genre_id="[^"]+" formats="(?P<type>[^"]+)" (?:playing="[^"]+" )?(?:playing_image="[^"]+" )?(?:show_id="[^"]+" )?(?:item="[^"]+" )?image="(?P<thumb>[^"]+)"')
|
||||||
if data.matches:
|
if data.matches:
|
||||||
for title, location, url, quality, song, type, thumbnail in data.matches:
|
for title, location, url, quality, song, type, thumbnail in data.matches:
|
||||||
|
title = scrapertools.unescape(title)
|
||||||
itemlist.append(
|
itemlist.append(
|
||||||
item.clone(title = support.typo(title, 'bold') + support.typo(quality + ' kbps','_ [] bold color kod'),
|
item.clone(title = support.typo(title, 'bold') + support.typo(quality + ' kbps','_ [] bold color kod'),
|
||||||
thumbnail = thumbnail,
|
thumbnail = thumbnail,
|
||||||
@@ -43,6 +45,7 @@ def radio(item):
|
|||||||
matches = support.match(data.data, patron= r'text="(?P<title>[^\("]+)(?:\([^\)]+\))?" URL="(?P<url>[^"]+)" (?:guide_id="[^"]+" )?(?:stream_type="[^"]+" )?topic_duration="(?P<duration>[^"]+)" subtext="(?P<plot>[^"]+)" item="[^"]+" image="(?P<thumb>[^"]+)"').matches
|
matches = support.match(data.data, patron= r'text="(?P<title>[^\("]+)(?:\([^\)]+\))?" URL="(?P<url>[^"]+)" (?:guide_id="[^"]+" )?(?:stream_type="[^"]+" )?topic_duration="(?P<duration>[^"]+)" subtext="(?P<plot>[^"]+)" item="[^"]+" image="(?P<thumb>[^"]+)"').matches
|
||||||
if matches:
|
if matches:
|
||||||
for title, url, duration, plot, thumbnail in matches:
|
for title, url, duration, plot, thumbnail in matches:
|
||||||
|
title = scrapertools.unescape(title)
|
||||||
infoLabels={}
|
infoLabels={}
|
||||||
infoLabels['duration'] = duration
|
infoLabels['duration'] = duration
|
||||||
itemlist.append(
|
itemlist.append(
|
||||||
@@ -56,12 +59,14 @@ def radio(item):
|
|||||||
else:
|
else:
|
||||||
matches = support.match(data.data, patron= r'text="(?P<title>[^"]+)" URL="(?P<url>[^"]+)"').matches
|
matches = support.match(data.data, patron= r'text="(?P<title>[^"]+)" URL="(?P<url>[^"]+)"').matches
|
||||||
for title, url in matches:
|
for title, url in matches:
|
||||||
|
title = scrapertools.unescape(title)
|
||||||
itemlist.append(
|
itemlist.append(
|
||||||
item.clone(channel = item.channel,
|
item.clone(channel = item.channel,
|
||||||
title = support.typo(title, 'bold'),
|
title = support.typo(title, 'bold'),
|
||||||
thumbnail = item.thumbnail,
|
thumbnail = item.thumbnail,
|
||||||
url = url,
|
url = url,
|
||||||
action = 'radio'))
|
action = 'radio'))
|
||||||
|
support.nextPage(itemlist, item, data.data, r'(?P<url>[^"]+)" key="nextStations')
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
@@ -86,5 +91,5 @@ def search(item, text):
|
|||||||
except:
|
except:
|
||||||
import sys
|
import sys
|
||||||
for line in sys.exc_info():
|
for line in sys.exc_info():
|
||||||
support.logger.error("%s" % line)
|
logger.error("%s" % line)
|
||||||
return []
|
return []
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ except:
|
|||||||
conn_id = ''
|
conn_id = ''
|
||||||
|
|
||||||
|
|
||||||
main_host = host + '/vvvvid/ondemand/'
|
main_host = host + '/vvvvid/ondemand/'
|
||||||
|
|
||||||
|
|
||||||
@support.menu
|
@support.menu
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ def unescape(text):
|
|||||||
from Fredrik Lundh
|
from Fredrik Lundh
|
||||||
http://effbot.org/zone/re-sub.htm#unescape-html
|
http://effbot.org/zone/re-sub.htm#unescape-html
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not ('&' in text and ';' in text):
|
if not ('&' in text and ';' in text):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@@ -129,13 +130,16 @@ def unescape(text):
|
|||||||
import html.entities as htmlentitydefs
|
import html.entities as htmlentitydefs
|
||||||
else:
|
else:
|
||||||
import htmlentitydefs
|
import htmlentitydefs
|
||||||
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]).encode("utf-8")
|
ret = unichr(htmlentitydefs.name2codepoint[text[1:-1]]).encode("utf-8")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error("keyerror")
|
logger.error("keyerror")
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return text # leave as is
|
# from core.support import dbg;dbg()
|
||||||
|
if type(ret) != str:
|
||||||
|
ret = ret.decode()
|
||||||
|
return ret # leave as is
|
||||||
|
|
||||||
return re.sub("&#?\w+;", fixup, str(text))
|
return re.sub("&#?\w+;", fixup, str(text))
|
||||||
|
|
||||||
|
|||||||
@@ -327,8 +327,8 @@ def filter_list(episodelist, action=None, path=None):
|
|||||||
|
|
||||||
# Make Language List
|
# Make Language List
|
||||||
for episode in episodelist:
|
for episode in episodelist:
|
||||||
|
if not episode.contentLanguage: episode.contentLanguage = 'ITA'
|
||||||
if type(episode.contentLanguage) == list and episode.contentLanguage not in lang_list:
|
if type(episode.contentLanguage) == list and episode.contentLanguage not in lang_list:
|
||||||
#lang_list = episode.contentLanguage
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if episode.contentLanguage and episode.contentLanguage not in lang_list:
|
if episode.contentLanguage and episode.contentLanguage not in lang_list:
|
||||||
@@ -338,6 +338,7 @@ def filter_list(episodelist, action=None, path=None):
|
|||||||
if sub not in sub_list: sub_list.append(sub)
|
if sub not in sub_list: sub_list.append(sub)
|
||||||
else:
|
else:
|
||||||
lang_list.append(episode.contentLanguage)
|
lang_list.append(episode.contentLanguage)
|
||||||
|
|
||||||
# add to Language List subtitled languages
|
# add to Language List subtitled languages
|
||||||
if sub_list:
|
if sub_list:
|
||||||
for sub in sub_list:
|
for sub in sub_list:
|
||||||
|
|||||||
+1
-33
@@ -119,7 +119,7 @@ def get_channel_url(findhostMethod=None, name=None, forceFindhost=False):
|
|||||||
name = os.path.basename(frame[0].f_code.co_filename).replace('.py', '')
|
name = os.path.basename(frame[0].f_code.co_filename).replace('.py', '')
|
||||||
if findhostMethod:
|
if findhostMethod:
|
||||||
url = jsontools.get_node_from_file(name, 'url')
|
url = jsontools.get_node_from_file(name, 'url')
|
||||||
if not url or 'web.archive.org' in url or forceFindhost: # per eliminare tutti i webarchive salvati causa bug httptools CF, eliminare in futuro
|
if not url or forceFindhost:
|
||||||
url = findhostMethod(channels_data['findhost'][name])
|
url = findhostMethod(channels_data['findhost'][name])
|
||||||
jsontools.update_node(url, name, 'url')
|
jsontools.update_node(url, name, 'url')
|
||||||
return url
|
return url
|
||||||
@@ -139,38 +139,6 @@ def get_system_platform():
|
|||||||
return platform
|
return platform
|
||||||
|
|
||||||
|
|
||||||
def is_autorun_enabled():
|
|
||||||
try:
|
|
||||||
if "xbmc.executebuiltin('RunAddon(plugin.video.kod)')" in open(os.path.join(xbmc.translatePath('special://userdata'),'autoexec.py')).read():
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
except:
|
|
||||||
# if error in reading from file autoexec doesnt exists
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def enable_disable_autorun(is_enabled):
|
|
||||||
# old method, now using service.py
|
|
||||||
|
|
||||||
path = os.path.join(xbmc.translatePath('special://userdata'),'autoexec.py')
|
|
||||||
append_write = 'a' if os.path.exists(path) else 'w'
|
|
||||||
|
|
||||||
if is_enabled is False:
|
|
||||||
with open(path, append_write) as file:
|
|
||||||
file.write("import xbmc\nxbmc.executebuiltin('RunAddon(plugin.video.kod)')")
|
|
||||||
set_setting('autostart', 'On')
|
|
||||||
else:
|
|
||||||
file = open(path, "r")
|
|
||||||
old_content = file.read()
|
|
||||||
new_content = old_content.replace("xbmc.executebuiltin('RunAddon(plugin.video.kod)')", "")
|
|
||||||
file.close()
|
|
||||||
with open(path, "w") as file:
|
|
||||||
file.write(new_content)
|
|
||||||
set_setting('autostart', True)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_settings_addon():
|
def get_all_settings_addon():
|
||||||
# Read the settings.xml file and return a dictionary with {id: value}
|
# Read the settings.xml file and return a dictionary with {id: value}
|
||||||
from core import scrapertools
|
from core import scrapertools
|
||||||
|
|||||||
@@ -151,10 +151,6 @@ def run(item=None):
|
|||||||
import urllib
|
import urllib
|
||||||
short = urllib.urlopen('https://u.nu/api.php?action=shorturl&format=simple&url=' + item.url).read().decode('utf-8')
|
short = urllib.urlopen('https://u.nu/api.php?action=shorturl&format=simple&url=' + item.url).read().decode('utf-8')
|
||||||
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(70740) % short)
|
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(70740) % short)
|
||||||
# Action in certain channel specified in "action" and "channel" parameters
|
|
||||||
elif item.action == "check_channels":
|
|
||||||
from platformcode import checkhost
|
|
||||||
checkhost.check_channels()
|
|
||||||
else:
|
else:
|
||||||
# Checks if channel exists
|
# Checks if channel exists
|
||||||
if os.path.isfile(os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py")):
|
if os.path.isfile(os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py")):
|
||||||
@@ -461,7 +457,8 @@ def play_from_library(item):
|
|||||||
# Modify the action (currently the video library needs "findvideos" since this is where the sources are searched
|
# Modify the action (currently the video library needs "findvideos" since this is where the sources are searched
|
||||||
item.action = "findvideos"
|
item.action = "findvideos"
|
||||||
|
|
||||||
window_type = config.get_setting("window_type", "videolibrary")
|
window_type = config.get_setting("window_type", "videolibrary") if config.get_setting('next_ep') < 3 and item.contentType != 'movie' else 1
|
||||||
|
|
||||||
# and launch kodi again
|
# and launch kodi again
|
||||||
if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1:
|
if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1:
|
||||||
xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")")
|
xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")")
|
||||||
|
|||||||
@@ -294,6 +294,10 @@ def render_items(itemlist, parent_item):
|
|||||||
"""
|
"""
|
||||||
Function used to render itemlist on kodi
|
Function used to render itemlist on kodi
|
||||||
"""
|
"""
|
||||||
|
# if it's not a list, do nothing
|
||||||
|
if not isinstance(itemlist, list):
|
||||||
|
return
|
||||||
|
|
||||||
logger.debug('START render_items')
|
logger.debug('START render_items')
|
||||||
thumb_type = config.get_setting('video_thumbnail_type')
|
thumb_type = config.get_setting('video_thumbnail_type')
|
||||||
from platformcode import shortcuts
|
from platformcode import shortcuts
|
||||||
@@ -309,9 +313,6 @@ def render_items(itemlist, parent_item):
|
|||||||
check_sf = os.path.exists(sf_file_path)
|
check_sf = os.path.exists(sf_file_path)
|
||||||
superfavourites = check_sf and xbmc.getCondVisibility('System.HasAddon("plugin.program.super.favourites")')
|
superfavourites = check_sf and xbmc.getCondVisibility('System.HasAddon("plugin.program.super.favourites")')
|
||||||
|
|
||||||
# if it's not a list, do nothing
|
|
||||||
if not isinstance(itemlist, list):
|
|
||||||
return
|
|
||||||
# if there's no item, add "no elements" item
|
# if there's no item, add "no elements" item
|
||||||
if not len(itemlist):
|
if not len(itemlist):
|
||||||
itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png')))
|
itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png')))
|
||||||
@@ -583,7 +584,7 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
|||||||
if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id']:
|
if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id']:
|
||||||
context_commands.append(("InfoPlus", "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=Main&from_channel=' + item.channel)))
|
context_commands.append(("InfoPlus", "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=Main&from_channel=' + item.channel)))
|
||||||
|
|
||||||
# Go to the Main Menu (channel.mainlist)
|
# Open in browser and previous menu
|
||||||
if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist" and not parent_item.noMainMenu:
|
if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist" and not parent_item.noMainMenu:
|
||||||
if parent_item.action != "mainlist":
|
if parent_item.action != "mainlist":
|
||||||
context_commands.insert(0, (config.get_localized_string(60349), "Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl())))
|
context_commands.insert(0, (config.get_localized_string(60349), "Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl())))
|
||||||
@@ -609,8 +610,10 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
|||||||
else:
|
else:
|
||||||
mediatype = item.contentType
|
mediatype = item.contentType
|
||||||
|
|
||||||
context_commands.append((config.get_localized_string(60350), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted}))))
|
if config.get_setting('new_search'):
|
||||||
|
context_commands.append((config.get_localized_string(60350), "RunPlugin (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True}))))
|
||||||
|
else:
|
||||||
|
context_commands.append((config.get_localized_string(60350), "Container.Refresh (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted}))))
|
||||||
context_commands.append( (config.get_localized_string(70561), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id']))))
|
context_commands.append( (config.get_localized_string(70561), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id']))))
|
||||||
|
|
||||||
if item.channel != "videolibrary" and item.videolibrary != False:
|
if item.channel != "videolibrary" and item.videolibrary != False:
|
||||||
@@ -642,7 +645,7 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
|||||||
|
|
||||||
# Search trailer...
|
# Search trailer...
|
||||||
if (item.contentTitle and item.contentType in ['movie', 'tvshow']) or "buscar_trailer" in context:
|
if (item.contentTitle and item.contentType in ['movie', 'tvshow']) or "buscar_trailer" in context:
|
||||||
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s)" % (sys.argv[0], urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
|
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
|
||||||
|
|
||||||
if kwargs.get('superfavourites'):
|
if kwargs.get('superfavourites'):
|
||||||
context_commands.append((config.get_localized_string(60361), "RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)"))
|
context_commands.append((config.get_localized_string(60361), "RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)"))
|
||||||
@@ -936,8 +939,8 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
|
|||||||
if default_action == 3:
|
if default_action == 3:
|
||||||
seleccion = len(opciones) - 1
|
seleccion = len(opciones) - 1
|
||||||
|
|
||||||
# Search for trailers on youtube
|
# Search for trailers
|
||||||
if item.channel not in ["Trailer", "ecarteleratrailers"]:
|
if item.channel not in ["trailertools"]:
|
||||||
# "Search Trailer"
|
# "Search Trailer"
|
||||||
opciones.append(config.get_localized_string(30162))
|
opciones.append(config.get_localized_string(30162))
|
||||||
|
|
||||||
@@ -1094,6 +1097,7 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
|||||||
playlist.add(mediaurl, xlistitem)
|
playlist.add(mediaurl, xlistitem)
|
||||||
# Reproduce
|
# Reproduce
|
||||||
xbmc_player.play(playlist, xlistitem)
|
xbmc_player.play(playlist, xlistitem)
|
||||||
|
add_next_to_playlist(item)
|
||||||
|
|
||||||
if config.get_setting('trakt_sync'):
|
if config.get_setting('trakt_sync'):
|
||||||
from core import trakt_tools
|
from core import trakt_tools
|
||||||
@@ -1129,6 +1133,29 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
|||||||
xbmcgui.Window(12005).show()
|
xbmcgui.Window(12005).show()
|
||||||
|
|
||||||
|
|
||||||
|
def add_next_to_playlist(item):
|
||||||
|
import threading
|
||||||
|
from core import filetools, videolibrarytools
|
||||||
|
from platformcode import xbmc_videolibrary
|
||||||
|
def add_to_playlist(item):
|
||||||
|
if item.contentType != 'movie' and item.strm_path:
|
||||||
|
next= xbmc_videolibrary.next_ep(item)
|
||||||
|
if next:
|
||||||
|
next.back = True
|
||||||
|
nfo_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"), next.strm_path.replace('strm','nfo'))
|
||||||
|
if nfo_path and filetools.isfile(nfo_path):
|
||||||
|
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
|
||||||
|
nextItem = xbmcgui.ListItem(path=item_nfo.url)
|
||||||
|
nextItem.setArt({"thumb": item_nfo.contentThumbnail if item_nfo.contentThumbnail else item_nfo.thumbnail})
|
||||||
|
set_infolabels(nextItem, item_nfo, True)
|
||||||
|
nexturl = "plugin://plugin.video.kod/?" + next.tourl()
|
||||||
|
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||||
|
playlist.add(nexturl, nextItem)
|
||||||
|
add_to_playlist(next)
|
||||||
|
if item.contentType != 'movie' and config.get_setting('next_ep') == 3:
|
||||||
|
threading.Thread(target=add_to_playlist, args=[item]).start()
|
||||||
|
|
||||||
|
|
||||||
def torrent_client_installed(show_tuple=False):
|
def torrent_client_installed(show_tuple=False):
|
||||||
# External plugins found in servers / torrent.json node clients
|
# External plugins found in servers / torrent.json node clients
|
||||||
from core import filetools
|
from core import filetools
|
||||||
@@ -1216,7 +1243,8 @@ def resume_playback(played_time):
|
|||||||
if action in self.action_exitkeys_id:
|
if action in self.action_exitkeys_id:
|
||||||
self.set_values(False)
|
self.set_values(False)
|
||||||
self.close()
|
self.close()
|
||||||
if played_time:
|
|
||||||
|
if played_time and played_time > 30:
|
||||||
Dialog = ResumePlayback('ResumePlayback.xml', config.get_runtime_path(), played_time=played_time)
|
Dialog = ResumePlayback('ResumePlayback.xml', config.get_runtime_path(), played_time=played_time)
|
||||||
Dialog.show()
|
Dialog.show()
|
||||||
t = 0
|
t = 0
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ def mark_auto_as_watched(item):
|
|||||||
logger.debug()
|
logger.debug()
|
||||||
actual_time = 0
|
actual_time = 0
|
||||||
total_time = 0
|
total_time = 0
|
||||||
# logger.debug("item:\n" + item.tostring('\n'))
|
|
||||||
# if item.options['continue']: item.played_time = platformtools.resume_playback(platformtools.get_played_time(item))
|
|
||||||
|
|
||||||
time_limit = time.time() + 30
|
time_limit = time.time() + 30
|
||||||
while not platformtools.is_playing() and time.time() < time_limit:
|
while not platformtools.is_playing() and time.time() < time_limit:
|
||||||
@@ -40,7 +38,7 @@ def mark_auto_as_watched(item):
|
|||||||
|
|
||||||
percentage = float(config.get_setting("watched_setting")) / 100
|
percentage = float(config.get_setting("watched_setting")) / 100
|
||||||
time_from_end = config.get_setting('next_ep_seconds')
|
time_from_end = config.get_setting('next_ep_seconds')
|
||||||
if item.contentType != 'movie' and config.get_setting('next_ep'):
|
if item.contentType != 'movie' and config.get_setting('next_ep') < 3:
|
||||||
next_dialogs = ['NextDialog.xml', 'NextDialogExtended.xml', 'NextDialogCompact.xml']
|
next_dialogs = ['NextDialog.xml', 'NextDialogExtended.xml', 'NextDialogCompact.xml']
|
||||||
next_ep_type = config.get_setting('next_ep_type')
|
next_ep_type = config.get_setting('next_ep_type')
|
||||||
ND = next_dialogs[next_ep_type]
|
ND = next_dialogs[next_ep_type]
|
||||||
@@ -49,8 +47,10 @@ def mark_auto_as_watched(item):
|
|||||||
logger.debug(next_episode)
|
logger.debug(next_episode)
|
||||||
|
|
||||||
while platformtools.is_playing():
|
while platformtools.is_playing():
|
||||||
actual_time = xbmc.Player().getTime()
|
try: actual_time = xbmc.Player().getTime()
|
||||||
total_time = xbmc.Player().getTotalTime()
|
except: pass
|
||||||
|
try: total_time = xbmc.Player().getTotalTime()
|
||||||
|
except: pass
|
||||||
if item.played_time and xbmcgui.getCurrentWindowId() == 12005:
|
if item.played_time and xbmcgui.getCurrentWindowId() == 12005:
|
||||||
xbmc.Player().seekTime(item.played_time)
|
xbmc.Player().seekTime(item.played_time)
|
||||||
item.played_time = 0 # Fix for Slow Devices
|
item.played_time = 0 # Fix for Slow Devices
|
||||||
@@ -75,7 +75,6 @@ def mark_auto_as_watched(item):
|
|||||||
# check for next Episode
|
# check for next Episode
|
||||||
if next_episode and sync and time_from_end >= difference:
|
if next_episode and sync and time_from_end >= difference:
|
||||||
nextdialog = NextDialog(ND, config.get_runtime_path())
|
nextdialog = NextDialog(ND, config.get_runtime_path())
|
||||||
nextdialog.show()
|
|
||||||
while platformtools.is_playing() and not nextdialog.is_exit():
|
while platformtools.is_playing() and not nextdialog.is_exit():
|
||||||
xbmc.sleep(100)
|
xbmc.sleep(100)
|
||||||
if nextdialog.continuewatching:
|
if nextdialog.continuewatching:
|
||||||
@@ -83,10 +82,9 @@ def mark_auto_as_watched(item):
|
|||||||
xbmc.Player().stop()
|
xbmc.Player().stop()
|
||||||
nextdialog.close()
|
nextdialog.close()
|
||||||
break
|
break
|
||||||
xbmc.sleep(1000)
|
|
||||||
|
|
||||||
# if item.options['continue']:
|
# if item.options['continue']:
|
||||||
if 10 < actual_time < mark_time:
|
if actual_time < mark_time:
|
||||||
item.played_time = actual_time
|
item.played_time = actual_time
|
||||||
else: item.played_time = 0
|
else: item.played_time = 0
|
||||||
platformtools.set_played_time(item)
|
platformtools.set_played_time(item)
|
||||||
@@ -96,13 +94,16 @@ def mark_auto_as_watched(item):
|
|||||||
|
|
||||||
while platformtools.is_playing():
|
while platformtools.is_playing():
|
||||||
xbmc.sleep(100)
|
xbmc.sleep(100)
|
||||||
|
|
||||||
if not show_server and item.play_from != 'window' and not item.no_return:
|
if not show_server and item.play_from != 'window' and not item.no_return:
|
||||||
xbmc.sleep(700)
|
xbmc.sleep(700)
|
||||||
xbmc.executebuiltin('Action(ParentDir)')
|
xbmc.executebuiltin('Action(ParentDir)')
|
||||||
xbmc.sleep(500)
|
xbmc.sleep(500)
|
||||||
|
|
||||||
if next_episode and next_episode.next_ep and config.get_setting('next_ep') == 1:
|
if next_episode and next_episode.next_ep and config.get_setting('next_ep') == 1:
|
||||||
from platformcode.launcher import play_from_library
|
from platformcode.launcher import play_from_library
|
||||||
play_from_library(next_episode)
|
play_from_library(next_episode)
|
||||||
|
|
||||||
# db need to be closed when not used, it will cause freezes
|
# db need to be closed when not used, it will cause freezes
|
||||||
from core import db
|
from core import db
|
||||||
db.close()
|
db.close()
|
||||||
@@ -1368,7 +1369,6 @@ def next_ep(item):
|
|||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
|
||||||
class NextDialog(xbmcgui.WindowXMLDialog):
|
class NextDialog(xbmcgui.WindowXMLDialog):
|
||||||
item = None
|
item = None
|
||||||
cancel = False
|
cancel = False
|
||||||
@@ -1393,6 +1393,7 @@ class NextDialog(xbmcgui.WindowXMLDialog):
|
|||||||
self.setProperty("next_img", img)
|
self.setProperty("next_img", img)
|
||||||
self.setProperty("title", info["tvshowtitle"])
|
self.setProperty("title", info["tvshowtitle"])
|
||||||
self.setProperty("ep_title", "%dx%02d - %s" % (info["season"], info["episode"], info["title"]))
|
self.setProperty("ep_title", "%dx%02d - %s" % (info["season"], info["episode"], info["title"]))
|
||||||
|
self.doModal()
|
||||||
|
|
||||||
def set_exit(self, EXIT):
|
def set_exit(self, EXIT):
|
||||||
self.EXIT = EXIT
|
self.EXIT = EXIT
|
||||||
|
|||||||
@@ -1425,7 +1425,7 @@ msgid "The unzipped %s file already exists, or you want to overwrite it.?"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60305"
|
msgctxt "#60305"
|
||||||
msgid ""
|
msgid "[COLOR red]Do not open this link[/COLOR]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60306"
|
msgctxt "#60306"
|
||||||
@@ -1437,7 +1437,7 @@ msgid "Use 'Preferences' to change your password"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60308"
|
msgctxt "#60308"
|
||||||
msgid ""
|
msgid "[COLOR red]It's one use, so write it[/COLOR]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60309"
|
msgctxt "#60309"
|
||||||
@@ -1541,7 +1541,7 @@ msgid "Configuration"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60334"
|
msgctxt "#60334"
|
||||||
msgid ""
|
msgid "Log file too large. Restart Kodi and retry"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#60335"
|
msgctxt "#60335"
|
||||||
@@ -4809,7 +4809,7 @@ msgid "Notification(Update Kodi to its latest version, for best info,8000, 'http
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70501"
|
msgctxt "#70501"
|
||||||
msgid "Search did not match (%s)"
|
msgid "Search did not match"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70502"
|
msgctxt "#70502"
|
||||||
@@ -4841,11 +4841,11 @@ msgid "Search in Mymovies"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70510"
|
msgctxt "#70510"
|
||||||
msgid "Manual Search in Youtube"
|
msgid "Manual Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70511"
|
msgctxt "#70511"
|
||||||
msgid "Manual Search in Mymovies"
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70512"
|
msgctxt "#70512"
|
||||||
@@ -4853,11 +4853,11 @@ msgid "Searching in Mymovies"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70513"
|
msgctxt "#70513"
|
||||||
msgid "Manual Searching in Filmaffinity"
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70514"
|
msgctxt "#70514"
|
||||||
msgid "Manual Search in Jayhap"
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70515"
|
msgctxt "#70515"
|
||||||
@@ -6129,11 +6129,15 @@ msgstr ""
|
|||||||
|
|
||||||
msgctxt "#70832"
|
msgctxt "#70832"
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Disabilitato"
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70833"
|
msgctxt "#70833"
|
||||||
msgid "Automatic"
|
msgid "Automatic"
|
||||||
msgstr "Automatico"
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#70834"
|
||||||
|
msgid "Playlist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# DNS start [ settings and declaration ]
|
# DNS start [ settings and declaration ]
|
||||||
msgctxt "#707401"
|
msgctxt "#707401"
|
||||||
|
|||||||
@@ -1424,8 +1424,8 @@ msgid "The unzipped %s file already exists, or you want to overwrite it.?"
|
|||||||
msgstr "il file %s da decomprimere esiste già, vuoi sovrascriverlo?"
|
msgstr "il file %s da decomprimere esiste già, vuoi sovrascriverlo?"
|
||||||
|
|
||||||
msgctxt "#60305"
|
msgctxt "#60305"
|
||||||
msgid ""
|
msgid "[COLOR red]Do not open this link[/COLOR]"
|
||||||
msgstr ""
|
msgstr "[COLOR red]NON aprire questo link[/COLOR]"
|
||||||
|
|
||||||
msgctxt "#60306"
|
msgctxt "#60306"
|
||||||
msgid "The fields 'New password' and 'Confirm new password' do not match"
|
msgid "The fields 'New password' and 'Confirm new password' do not match"
|
||||||
@@ -1436,8 +1436,8 @@ msgid "Use 'Preferences' to change your password"
|
|||||||
msgstr "Entra in 'Preferenze' per cambiare la password"
|
msgstr "Entra in 'Preferenze' per cambiare la password"
|
||||||
|
|
||||||
msgctxt "#60308"
|
msgctxt "#60308"
|
||||||
msgid ""
|
msgid "[COLOR red]It's one use, so write it[/COLOR]"
|
||||||
msgstr ""
|
msgstr "[COLOR red]Funziona una volta sola, quindi scrivilo[/COLOR]"
|
||||||
|
|
||||||
msgctxt "#60309"
|
msgctxt "#60309"
|
||||||
msgid "The password is not correct."
|
msgid "The password is not correct."
|
||||||
@@ -1540,8 +1540,8 @@ msgid "Configuration"
|
|||||||
msgstr "Configurazione"
|
msgstr "Configurazione"
|
||||||
|
|
||||||
msgctxt "#60334"
|
msgctxt "#60334"
|
||||||
msgid ""
|
msgid "Log file too large. Restart Kodi and retry"
|
||||||
msgstr ""
|
msgstr "File di log troppo pesante. Riapri kodi e riprova"
|
||||||
|
|
||||||
msgctxt "#60335"
|
msgctxt "#60335"
|
||||||
msgid "Watch in..."
|
msgid "Watch in..."
|
||||||
@@ -4808,8 +4808,8 @@ msgid "Notification(Update Kodi to its latest version, for best info,8000, 'http
|
|||||||
msgstr "Notification(Aggiorna Kodi alla sua ultima versione, per migliori info,8000, 'http://i.imgur.com/mHgwcn3.png')"
|
msgstr "Notification(Aggiorna Kodi alla sua ultima versione, per migliori info,8000, 'http://i.imgur.com/mHgwcn3.png')"
|
||||||
|
|
||||||
msgctxt "#70501"
|
msgctxt "#70501"
|
||||||
msgid "Search did not match (%s)"
|
msgid "Search did not match"
|
||||||
msgstr "La ricerca non ha dato risultati (%s)"
|
msgstr "La ricerca non ha dato risultati"
|
||||||
|
|
||||||
msgctxt "#70502"
|
msgctxt "#70502"
|
||||||
msgid ">> Next"
|
msgid ">> Next"
|
||||||
@@ -4840,24 +4840,24 @@ msgid "Search in Mymovies"
|
|||||||
msgstr "Ricerca in Mymovies"
|
msgstr "Ricerca in Mymovies"
|
||||||
|
|
||||||
msgctxt "#70510"
|
msgctxt "#70510"
|
||||||
msgid "Manual Search in Youtube"
|
msgid "Manual Search"
|
||||||
msgstr "Ricerca Manuale in Youtube"
|
msgstr "Ricerca Manuale"
|
||||||
|
|
||||||
msgctxt "#70511"
|
msgctxt "#70511"
|
||||||
msgid "Manual Search in Mymovies"
|
msgid ""
|
||||||
msgstr "Ricerca Manuale in Mymovies"
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70512"
|
msgctxt "#70512"
|
||||||
msgid "Searching in Mymovies"
|
msgid "Searching in Mymovies"
|
||||||
msgstr "Ricerca in Mymovies"
|
msgstr "Ricerca in Mymovies"
|
||||||
|
|
||||||
msgctxt "#70513"
|
msgctxt "#70513"
|
||||||
msgid "Manual Searching in Filmaffinity"
|
msgid ""
|
||||||
msgstr "Ricerca Manuale in Filmaffinity"
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70514"
|
msgctxt "#70514"
|
||||||
msgid "Manual Search in Jayhap"
|
msgid ""
|
||||||
msgstr "Ricerca Manuale in Jayhap"
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#70515"
|
msgctxt "#70515"
|
||||||
msgid "Completed %s"
|
msgid "Completed %s"
|
||||||
@@ -6136,6 +6136,10 @@ msgctxt "#70833"
|
|||||||
msgid "Automatic"
|
msgid "Automatic"
|
||||||
msgstr "Automatico"
|
msgstr "Automatico"
|
||||||
|
|
||||||
|
msgctxt "#70834"
|
||||||
|
msgid "Playlist"
|
||||||
|
msgstr "Playlist"
|
||||||
|
|
||||||
# DNS start [ settings and declaration ]
|
# DNS start [ settings and declaration ]
|
||||||
msgctxt "#707401"
|
msgctxt "#707401"
|
||||||
msgid "Enable DNS check alert"
|
msgid "Enable DNS check alert"
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<setting id="videolibrary_kodi" type="bool" label="70120" default="false"/>
|
<setting id="videolibrary_kodi" type="bool" label="70120" default="false"/>
|
||||||
<setting label="59997" type="lsep"/>
|
<setting label="59997" type="lsep"/>
|
||||||
<setting id="videolibrary_max_quality" type="bool" label="70729" default="false" visible="true"/>
|
<setting id="videolibrary_max_quality" type="bool" label="70729" default="false" visible="true"/>
|
||||||
<setting id="next_ep" type="select" label="70748" lvalues="70832|70833|70732" default="1"/>
|
<setting id="next_ep" type="select" label="70748" lvalues="70832|70833|70732|70834" default="1"/>
|
||||||
<setting id="next_ep_type" type="select" label="70754" lvalues="70755|70756|70757" default="0" visible="!eq(-1,0)" subsetting="true"/>
|
<setting id="next_ep_type" type="select" label="70754" lvalues="70755|70756|70757" default="0" visible="!eq(-1,0)" subsetting="true"/>
|
||||||
<setting id="next_ep_seconds" type="slider" option="int" range="20,10,240" label="70749" default="40" visible="!eq(-2,0)" subsetting="true"/>
|
<setting id="next_ep_seconds" type="slider" option="int" range="20,10,240" label="70749" default="40" visible="!eq(-2,0)" subsetting="true"/>
|
||||||
<setting id="watched_setting" type="slider" option="int" range="20,5,90" label="60634" default="80"/>
|
<setting id="watched_setting" type="slider" option="int" range="20,5,90" label="60634" default="80"/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"active": true,
|
"active": false,
|
||||||
"find_videos": {
|
"find_videos": {
|
||||||
"ignore_urls": [],
|
"ignore_urls": [],
|
||||||
"patterns": [
|
"patterns": [
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ def test_video_exists(page_url):
|
|||||||
logger.debug("(page_url='%s')" % page_url)
|
logger.debug("(page_url='%s')" % page_url)
|
||||||
global data
|
global data
|
||||||
data = httptools.downloadpage(page_url).data
|
data = httptools.downloadpage(page_url).data
|
||||||
if "<h2>WE ARE SORRY</h2>" in data or '<title>404 Not Found</title>' in data:
|
if "as it expired or has been deleted" in data:
|
||||||
return False, config.get_localized_string(70449) % "UPstream"
|
return False, config.get_localized_string(70449) % "UPstream"
|
||||||
return True, ""
|
return True, ""
|
||||||
|
|
||||||
|
|||||||
+9
-19
@@ -16,24 +16,14 @@ def test_video_exists(page_url):
|
|||||||
|
|
||||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||||
logger.debug("url=" + page_url)
|
logger.debug("url=" + page_url)
|
||||||
video_urls = []
|
|
||||||
global data
|
global data
|
||||||
|
|
||||||
return support.get_jwplayer_mediaurl(data, 'VUP')
|
matches = support.get_jwplayer_mediaurl(data, 'VUP')
|
||||||
# patron = r'sources:\s*\[\{src:\s*"([^"]+)"'
|
if not matches:
|
||||||
# matches = scrapertools.find_multiple_matches(data, patron)
|
data = scrapertools.find_single_match(data, r"<script type='text/javascript'>(eval.function.p,a,c,k,e,.*?)\s*</script>")
|
||||||
# if not matches:
|
if data:
|
||||||
# data = scrapertools.find_single_match(data, r"<script type='text/javascript'>(eval.function.p,a,c,k,e,.*?)\s*</script>")
|
from lib import jsunpack
|
||||||
# if data:
|
data = jsunpack.unpack(data)
|
||||||
# from lib import jsunpack
|
matches = support.get_jwplayer_mediaurl(data, 'VUP')
|
||||||
# data = jsunpack.unpack(data)
|
|
||||||
# matches = scrapertools.find_multiple_matches(data, patron)
|
return matches
|
||||||
# for url in matches:
|
|
||||||
# quality = 'm3u8'
|
|
||||||
# video_url = url
|
|
||||||
# if 'label' in url:
|
|
||||||
# url = url.split(',')
|
|
||||||
# video_url = url[0]
|
|
||||||
# quality = url[1].replace('label:','')
|
|
||||||
# video_urls.append(['VUP Player [%s]' % quality, video_url.replace(',','')])
|
|
||||||
# return video_urls
|
|
||||||
|
|||||||
@@ -458,9 +458,6 @@ if __name__ == "__main__":
|
|||||||
if config.get_setting('autostart'):
|
if config.get_setting('autostart'):
|
||||||
xbmc.executebuiltin('RunAddon(plugin.video.' + config.PLUGIN_NAME + ')')
|
xbmc.executebuiltin('RunAddon(plugin.video.' + config.PLUGIN_NAME + ')')
|
||||||
|
|
||||||
# handling old autoexec method
|
|
||||||
if config.is_autorun_enabled():
|
|
||||||
config.enable_disable_autorun(True)
|
|
||||||
# port old db to new
|
# port old db to new
|
||||||
old_db_name = filetools.join(config.get_data_path(), "kod_db.sqlite")
|
old_db_name = filetools.join(config.get_data_path(), "kod_db.sqlite")
|
||||||
if filetools.isfile(old_db_name):
|
if filetools.isfile(old_db_name):
|
||||||
|
|||||||
@@ -343,6 +343,11 @@ class SearchWindow(xbmcgui.WindowXML):
|
|||||||
and self.item.infoLabels['year']:
|
and self.item.infoLabels['year']:
|
||||||
logger.debug('retring adding year on channel ' + channel)
|
logger.debug('retring adding year on channel ' + channel)
|
||||||
dummy, valid, dummy = search(self.item.text + " " + str(self.item.infoLabels['year']))
|
dummy, valid, dummy = search(self.item.text + " " + str(self.item.infoLabels['year']))
|
||||||
|
|
||||||
|
# some channels may use original title
|
||||||
|
if self.item.mode != 'all' and not valid and self.item.infoLabels.get('originaltitle'):
|
||||||
|
logger.debug('retring with original title on channel ' + channel)
|
||||||
|
dummy, valid, dummy = search(self.item.infoLabels.get('originaltitle'))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -749,6 +749,10 @@ def from_context(item):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if config.get_setting('new_search'):
|
||||||
|
from specials import globalsearch
|
||||||
|
return globalsearch.Search(item)
|
||||||
|
|
||||||
if 'list_type' not in item:
|
if 'list_type' not in item:
|
||||||
if 'wanted' in item:
|
if 'wanted' in item:
|
||||||
item.title = item.wanted
|
item.title = item.wanted
|
||||||
|
|||||||
+93
-51
@@ -836,9 +836,15 @@ def report_menu(item):
|
|||||||
action = 'call_browser'
|
action = 'call_browser'
|
||||||
url = item.url
|
url = item.url
|
||||||
itemlist.append(Item(channel=item.channel, action=action,
|
itemlist.append(Item(channel=item.channel, action=action,
|
||||||
title="**- LOG: [COLOR gold]%s[/COLOR] -**" % item.url, url=url,
|
title="LOG: [COLOR gold]%s[/COLOR]" % item.url, url=url,
|
||||||
thumbnail=thumb_next, unify=False, folder=False))
|
thumbnail=thumb_next, unify=False, folder=False))
|
||||||
|
if item.one_use:
|
||||||
|
itemlist.append(Item(channel=item.channel, action="",
|
||||||
|
title=config.get_localized_string(60305),
|
||||||
|
thumbnail=thumb_next, folder=False))
|
||||||
|
itemlist.append(Item(channel=item.channel, action="",
|
||||||
|
title=config.get_localized_string(60308),
|
||||||
|
thumbnail=thumb_next, folder=False))
|
||||||
itemlist.append(Item(channel=item.channel, action="call_browser",
|
itemlist.append(Item(channel=item.channel, action="call_browser",
|
||||||
title="su Github (raccomandato)", url='https://github.com/kodiondemand/addon/issues',
|
title="su Github (raccomandato)", url='https://github.com/kodiondemand/addon/issues',
|
||||||
thumbnail=thumb_next,
|
thumbnail=thumb_next,
|
||||||
@@ -847,14 +853,6 @@ def report_menu(item):
|
|||||||
url='https://t.me/kodiondemand', title="Su telegram",
|
url='https://t.me/kodiondemand', title="Su telegram",
|
||||||
thumbnail=thumb_next, unify=False, folder=False))
|
thumbnail=thumb_next, unify=False, folder=False))
|
||||||
|
|
||||||
if item.one_use:
|
|
||||||
itemlist.append(Item(channel=item.channel, action="",
|
|
||||||
title="[COLOR orange]NO ACCEDA al INFORME: se BORRARÁ[/COLOR]",
|
|
||||||
thumbnail=thumb_next, folder=False))
|
|
||||||
itemlist.append(Item(channel=item.channel, action="",
|
|
||||||
title="[COLOR orange]ya que es de un solo uso[/COLOR]",
|
|
||||||
thumbnail=thumb_next, folder=False))
|
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
@@ -917,33 +915,34 @@ def report_send(item, description='', fatal=False):
|
|||||||
# directly on the forum. If it is a size problem, you are asked to reset Kodi and redo the fault, to
|
# directly on the forum. If it is a size problem, you are asked to reset Kodi and redo the fault, to
|
||||||
# that the LOG is smaller.
|
# that the LOG is smaller.
|
||||||
|
|
||||||
|
|
||||||
pastebin_list = {
|
pastebin_list = {
|
||||||
'hastebin': ('1', 'https://hastebin.com/', 'documents', 'random', '', '',
|
'hastebin': ('1', 'https://hastebin.com/', 'documents', 'random', '', '',
|
||||||
'data', 'json', 'key', '', '0.29', '10', True, 'raw/', '', ''),
|
'data', 'json', 'key', '', '0.29', '10', True, 'raw/', '', ''),
|
||||||
'dpaste': ('1', 'http://dpaste.com/', 'api/v2/', 'random', 'content=',
|
'dpaste': ('1', 'http://dpaste.com/', 'api/v2/', 'random', 'content=',
|
||||||
'&syntax=text&title=%s&poster=alfa&expiry_days=7',
|
'&syntax=text&title=%s&poster=alfa&expiry_days=7',
|
||||||
'headers', '', '', 'location', '0.23', '15', True, '', '.txt', ''),
|
'headers', '', '', 'location', '0.23', '15', True, '', '.txt', ''),
|
||||||
'ghostbin': ('1', 'https://ghostbin.com/', 'paste/new', 'random', 'lang=text&text=',
|
'ghostbin': ('1', 'https://ghostbin.com/', 'paste/new', 'random', 'lang=text&text=',
|
||||||
'&expire=2d&password=&title=%s',
|
'&expire=2d&password=&title=%s',
|
||||||
'data', 'regex', '<title>(.*?)\s*-\s*Ghostbin<\/title>', '',
|
'data', 'regex', '<title>(.*?)\s*-\s*Ghostbin<\/title>', '',
|
||||||
'0.49', '15', False, 'paste/', '', ''),
|
'0.49', '15', False, 'paste/', '', ''),
|
||||||
'write.as': ('1', 'https://write.as/', 'api/posts', 'random', 'body=', '&title=%s',
|
'write.as': ('1', 'https://write.as/', 'api/posts', 'random', 'body=', '&title=%s',
|
||||||
'data', 'json', 'data', 'id', '0.018', '15', True, '', '', ''),
|
'data', 'json', 'data', 'id', '0.018', '15', True, '', '', ''),
|
||||||
'oneclickpaste': ('1', 'http://oneclickpaste.com/', 'index.php', 'random', 'paste_data=',
|
'oneclickpaste': ('1', 'http://oneclickpaste.com/', 'index.php', 'random', 'paste_data=',
|
||||||
'&title=%s&format=text&paste_expire_date=1W&visibility=0&pass=&submit=Submit',
|
'&title=%s&format=text&paste_expire_date=1W&visibility=0&pass=&submit=Submit',
|
||||||
'data', 'regex', '<a class="btn btn-primary" href="[^"]+\/(\d+\/)">\s*View\s*Paste\s*<\/a>',
|
'data', 'regex', '<a class="btn btn-primary" href="[^"]+\/(\d+\/)">\s*View\s*Paste\s*<\/a>',
|
||||||
'', '0.060', '5', True, '', '', ''),
|
'', '0.060', '5', True, '', '', ''),
|
||||||
'bpaste': ('1', 'https://bpaste.net/', '', 'random', 'code=', '&lexer=text&expiry=1week',
|
'bpaste': ('1', 'https://bpaste.net/', '', 'random', 'code=', '&lexer=text&expiry=1week',
|
||||||
'data', 'regex', 'View\s*<a\s*href="[^*]+/(.*?)">raw<\/a>', '',
|
'data', 'regex', 'View\s*<a\s*href="[^*]+/(.*?)">raw<\/a>', '',
|
||||||
'0.79', '15', True, 'raw/', '', ''),
|
'0.79', '15', True, 'raw/', '', ''),
|
||||||
'dumpz': ('0', 'http://dumpz.org/', 'api/dump', 'random', 'code=', '&lexer=text&comment=%s&password=',
|
'dumpz': ('0', 'http://dumpz.org/', 'api/dump', 'random', 'code=', '&lexer=text&comment=%s&password=',
|
||||||
'headers', '', '', 'location', '0.99', '15', False, '', '', ''),
|
'headers', '', '', 'location', '0.99', '15', False, '', '', ''),
|
||||||
'file.io': ('1', 'https://file.io/', '', 'random', '', 'expires=1w',
|
'file.io': ('1', 'https://file.io/', '', 'random', '', 'expires=1w',
|
||||||
'requests', 'json', 'key', '', '99.0', '30', False, '', '.log', ''),
|
'requests', 'json', 'key', '', '99.0', '30', False, '', '', ''),
|
||||||
'uploadfiles': ('1', 'https://up.uploadfiles.io/upload', '', 'random', '', '',
|
'uploadfiles': ('0', 'https://up.ufile.io/v1/upload', '', 'random', '', '',
|
||||||
'requests', 'json', 'url', '', '99.0', '30', False, None, '', '')
|
'curl', 'json', 'url', '', '99.0', '30', False, None, '', {'Referer': 'https://ufile.io/'}),
|
||||||
}
|
'anonfiles': ('1', 'https://api.anonfiles.com/upload', 'upload', 'random', '', '',
|
||||||
|
'requests', 'json', 'data', 'file,url,short', '99.0', '30', False, None, '', '')
|
||||||
|
}
|
||||||
pastebin_list_last = ['hastebin', 'ghostbin', 'file.io'] # We leave these services the last
|
pastebin_list_last = ['hastebin', 'ghostbin', 'file.io'] # We leave these services the last
|
||||||
pastebin_one_use = ['file.io'] # Single-use servers and deletes
|
pastebin_one_use = ['file.io'] # Single-use servers and deletes
|
||||||
pastebin_dir = []
|
pastebin_dir = []
|
||||||
@@ -994,7 +993,7 @@ def report_send(item, description='', fatal=False):
|
|||||||
random.shuffle(pastebin_dir)
|
random.shuffle(pastebin_dir)
|
||||||
pastebin_dir.extend(pastebin_list_last) # We leave these services the last
|
pastebin_dir.extend(pastebin_list_last) # We leave these services the last
|
||||||
|
|
||||||
#pastebin_dir = ['uploadfiles'] # For testing a service
|
# pastebin_dir = ['file.io'] # For testing a service
|
||||||
#log_data = 'TEST FOR SERVICE TESTS'
|
#log_data = 'TEST FOR SERVICE TESTS'
|
||||||
|
|
||||||
# The list of "pastebin" servers is scrolled to locate an active one, with capacity and availability
|
# The list of "pastebin" servers is scrolled to locate an active one, with capacity and availability
|
||||||
@@ -1018,7 +1017,7 @@ def report_send(item, description='', fatal=False):
|
|||||||
paste_file_size = float(pastebin_list[paste_name][10]) # Server capacity in MB
|
paste_file_size = float(pastebin_list[paste_name][10]) # Server capacity in MB
|
||||||
if paste_file_size > 0: # If it is 0, the capacity is unlimited
|
if paste_file_size > 0: # If it is 0, the capacity is unlimited
|
||||||
if log_size > paste_file_size: # Capacity and size verification
|
if log_size > paste_file_size: # Capacity and size verification
|
||||||
msg = 'Log file too large. Restart Kodi and retry'
|
msg = config.get_localized_string(60334)
|
||||||
continue
|
continue
|
||||||
paste_timeout = int(pastebin_list[paste_name][11]) # Timeout for the server
|
paste_timeout = int(pastebin_list[paste_name][11]) # Timeout for the server
|
||||||
paste_random_headers = pastebin_list[paste_name][12] # Do you use RAMDOM headers to mislead the serv?
|
paste_random_headers = pastebin_list[paste_name][12] # Do you use RAMDOM headers to mislead the serv?
|
||||||
@@ -1029,15 +1028,12 @@ def report_send(item, description='', fatal=False):
|
|||||||
paste_headers.update(jsontools.load((pastebin_list[paste_name][15])))
|
paste_headers.update(jsontools.load((pastebin_list[paste_name][15])))
|
||||||
|
|
||||||
if paste_name in pastebin_one_use:
|
if paste_name in pastebin_one_use:
|
||||||
pastebin_one_use_msg = 'DO NOT ACCESS THE REPORT: it will be DELETED'
|
|
||||||
item.one_use = True
|
item.one_use = True
|
||||||
else:
|
|
||||||
pastebin_one_use_msg = ''
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# POST is created with server options "pastebin"
|
# POST is created with server options "pastebin"
|
||||||
# This is the "requests" format
|
# This is the "requests" format
|
||||||
if paste_type == 'requests':
|
if paste_type in ['requests', 'curl']:
|
||||||
paste_file = {'file': (paste_title+'.log', log_data)}
|
paste_file = {'file': (paste_title+'.log', log_data)}
|
||||||
if paste_post1:
|
if paste_post1:
|
||||||
paste_file.update(paste_post1)
|
paste_file.update(paste_post1)
|
||||||
@@ -1079,8 +1075,50 @@ def report_send(item, description='', fatal=False):
|
|||||||
data = httptools.downloadpage(paste_host, params=paste_params, file=log_data,
|
data = httptools.downloadpage(paste_host, params=paste_params, file=log_data,
|
||||||
file_name=paste_title+'.log', timeout=paste_timeout,
|
file_name=paste_title+'.log', timeout=paste_timeout,
|
||||||
random_headers=paste_random_headers, headers=paste_headers)
|
random_headers=paste_random_headers, headers=paste_headers)
|
||||||
|
|
||||||
|
elif paste_type == 'curl':
|
||||||
|
paste_sufix = '/create_session'
|
||||||
|
data_post = {'file_size': len(log_data)}
|
||||||
|
logger.error(data_post)
|
||||||
|
data = httptools.downloadpage(paste_host+paste_sufix, params=paste_params,
|
||||||
|
ignore_response_code=True, post=data_post, timeout=paste_timeout, alfa_s=True,
|
||||||
|
random_headers=paste_random_headers, headers=paste_headers).data
|
||||||
|
data = jsontools.load(data)
|
||||||
|
if not data.get("fuid", ""):
|
||||||
|
logger.error("fuid: %s" % str(data))
|
||||||
|
raise
|
||||||
|
fuid = data["fuid"]
|
||||||
|
|
||||||
|
paste_sufix = '/chunk'
|
||||||
|
log_data_chunks = log_data
|
||||||
|
i = 0
|
||||||
|
chunk_len = 1024
|
||||||
|
while len(log_data_chunks) > 0:
|
||||||
|
i += 1
|
||||||
|
chunk = log_data_chunks[:chunk_len]
|
||||||
|
log_data_chunks = log_data_chunks[chunk_len:]
|
||||||
|
data_post = {'fuid': fuid, 'chunk_index': i}
|
||||||
|
data = httptools.downloadpage(paste_host+paste_sufix, params=paste_params, file=chunk, alfa_s=True,
|
||||||
|
ignore_response_code=True, post=data_post, timeout=paste_timeout, CF_test=False,
|
||||||
|
random_headers=paste_random_headers, headers=paste_headers).data
|
||||||
|
if not 'successful' in data:
|
||||||
|
logger.error("successful: %s" % str(data))
|
||||||
|
raise
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
paste_sufix = '/finalise'
|
||||||
|
data_post = {'fuid': fuid, 'total_chunks': i, 'file_name': paste_title+'.log', 'file_type': 'doc'}
|
||||||
|
resp = httptools.downloadpage(paste_host+paste_sufix, params=paste_params,
|
||||||
|
ignore_response_code=True, post=data_post, timeout=paste_timeout,
|
||||||
|
random_headers=paste_random_headers, headers=paste_headers)
|
||||||
|
if not resp.data:
|
||||||
|
logger.error("resp.content: %s" % str(resp.data))
|
||||||
|
raise
|
||||||
|
data['data'] = resp.data
|
||||||
|
data = type('HTTPResponse', (), data)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
msg = 'Inténtelo más tarde'
|
msg = 'Try later'
|
||||||
logger.error('Failed to save report. ' + msg)
|
logger.error('Failed to save report. ' + msg)
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
continue
|
continue
|
||||||
@@ -1093,16 +1131,20 @@ def report_send(item, description='', fatal=False):
|
|||||||
paste_host_return = ''
|
paste_host_return = ''
|
||||||
|
|
||||||
# Responses to REQUESTS requests
|
# Responses to REQUESTS requests
|
||||||
if paste_type == 'requests': # Response of request type "requests"?
|
if paste_type in ['requests', 'curl']: # Response of request type "requests"?
|
||||||
if paste_resp == 'json': # Answer in JSON format?
|
if paste_resp == 'json': # Answer in JSON format?
|
||||||
if paste_resp_key in data.data:
|
if paste_resp_key in data.data:
|
||||||
if not paste_url:
|
key = jsontools.load(data.data)[paste_resp_key]
|
||||||
key = jsontools.load(data.data)[paste_resp_key] # with a label
|
if paste_url and key: # hay etiquetas adicionales?
|
||||||
else:
|
try:
|
||||||
key = jsontools.load(data.data)[paste_resp_key][paste_url] # with two nested tags
|
for key_part in paste_url.split(','):
|
||||||
item.url = "%s%s%s" % (paste_host_resp+paste_host_return, key,
|
key = key[key_part] # por cada etiqueta adicional
|
||||||
paste_host_return_tail)
|
except:
|
||||||
else:
|
key = ''
|
||||||
|
if key:
|
||||||
|
item.url = "%s%s%s" % (paste_host_resp+paste_host_return, key,
|
||||||
|
paste_host_return_tail)
|
||||||
|
if not key:
|
||||||
logger.error('ERROR in data return format. data.data=' + str(data.data))
|
logger.error('ERROR in data return format. data.data=' + str(data.data))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
+100
-188
@@ -1,36 +1,40 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Search trailers from youtube, filmaffinity, mymovies, vimeo, etc...
|
# Search trailers from tmdb, youtube and mymovies...
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
#from builtins import str
|
|
||||||
|
# from builtins import str
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import xbmcaddon
|
from channelselector import get_thumb
|
||||||
|
|
||||||
PY3 = False
|
PY3 = False
|
||||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||||||
from past.utils import old_div
|
|
||||||
|
|
||||||
if PY3:
|
if PY3:
|
||||||
#from future import standard_library
|
# from future import standard_library
|
||||||
#standard_library.install_aliases()
|
# standard_library.install_aliases()
|
||||||
import urllib.parse as urllib # It is very slow in PY2. In PY3 it is native
|
import urllib.parse as urllib # It is very slow in PY2. In PY3 it is native
|
||||||
import urllib.parse as urlparse
|
import urllib.parse as urlparse
|
||||||
|
from concurrent import futures
|
||||||
else:
|
else:
|
||||||
import urllib # We use the native of PY2 which is faster
|
import urllib # We use the native of PY2 which is faster
|
||||||
import urlparse
|
import urlparse
|
||||||
|
from concurrent_py2 import futures
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from core import httptools, jsontools, scrapertools, servertools
|
from core import httptools, scrapertools, servertools
|
||||||
from core.support import match, thumb
|
from core.support import match, thumb
|
||||||
from core.item import Item
|
from core.item import Item
|
||||||
from platformcode import config, logger
|
from platformcode import config, logger, launcher
|
||||||
from platformcode import platformtools
|
from platformcode import platformtools
|
||||||
|
|
||||||
info_language = ["it", "en", "es", "fr", "de", "pt"] # from videolibrary.json
|
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
|
||||||
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
|
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
@@ -44,10 +48,14 @@ else:
|
|||||||
|
|
||||||
def buscartrailer(item, trailers=[]):
|
def buscartrailer(item, trailers=[]):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
|
if item.contentType != "movie":
|
||||||
|
tipo = "tv"
|
||||||
|
else:
|
||||||
|
tipo = "movie"
|
||||||
|
|
||||||
# List of actions if run from context menu
|
# List of actions if run from context menu
|
||||||
if item.action == "manual_search" and item.contextual:
|
if item.action == "manual_search" and item.contextual:
|
||||||
itemlist = manual_search(item)
|
itemlist = manual_search(item, tipo)
|
||||||
item.contentTitle = itemlist[0].contentTitle
|
item.contentTitle = itemlist[0].contentTitle
|
||||||
elif 'search' in item.action and item.contextual:
|
elif 'search' in item.action and item.contextual:
|
||||||
itemlist = globals()[item.action](item)
|
itemlist = globals()[item.action](item)
|
||||||
@@ -67,7 +75,8 @@ def buscartrailer(item, trailers=[]):
|
|||||||
item.contentTitle = item.contentTitle.strip()
|
item.contentTitle = item.contentTitle.strip()
|
||||||
elif keyboard:
|
elif keyboard:
|
||||||
contentTitle = re.sub(r'\[\/*(B|I|COLOR)\s*[^\]]*\]', '', item.contentTitle.strip())
|
contentTitle = re.sub(r'\[\/*(B|I|COLOR)\s*[^\]]*\]', '', item.contentTitle.strip())
|
||||||
item.contentTitle = platformtools.dialog_input(default=contentTitle, heading=config.get_localized_string(70505))
|
item.contentTitle = platformtools.dialog_input(default=contentTitle,
|
||||||
|
heading=config.get_localized_string(70505))
|
||||||
if item.contentTitle is None:
|
if item.contentTitle is None:
|
||||||
item.contentTitle = contentTitle
|
item.contentTitle = contentTitle
|
||||||
else:
|
else:
|
||||||
@@ -87,32 +96,28 @@ def buscartrailer(item, trailers=[]):
|
|||||||
title, url, server = servertools.findvideos(url)[0]
|
title, url, server = servertools.findvideos(url)[0]
|
||||||
title = "Trailer [" + server + "]"
|
title = "Trailer [" + server + "]"
|
||||||
itemlist.append(item.clone(title=title, url=url, server=server, action="play"))
|
itemlist.append(item.clone(title=title, url=url, server=server, action="play"))
|
||||||
if item.show or item.infoLabels['tvshowtitle'] or item.contentType != "movie":
|
|
||||||
tipo = "tv"
|
|
||||||
else:
|
|
||||||
tipo = "movie"
|
|
||||||
try:
|
try:
|
||||||
if not trailers:
|
for trailer in trailers:
|
||||||
itemlist.extend(tmdb_trailers(item, tipo))
|
title = trailer['name'] + " [" + trailer['size'] + "p] (" + trailer['language'].replace("en",
|
||||||
else:
|
"ING").replace(
|
||||||
for trailer in trailers:
|
"it", "ITA") + ") [tmdb/youtube]"
|
||||||
title = trailer['name'] + " [" + trailer['size'] + "p] (" + trailer['language'].replace("en", "ING").replace("it", "ITA") + ") [tmdb/youtube]"
|
itemlist.append(item.clone(action="play", title=title, url=trailer['url'], server="youtube"))
|
||||||
itemlist.append(item.clone(action="play", title=title, url=trailer['url'], server="youtube"))
|
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
if item.contextual: title = "%s"
|
multi_search(item, itemlist, tipo)
|
||||||
else: title = "%s"
|
if not itemlist:
|
||||||
|
itemlist.append(item.clone(title=config.get_localized_string(70501), title2=item.contentTitle,
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70507), action="youtube_search", thumbnail=thumb('search')))
|
action="", thumbnail=get_thumb('nofolder.png'), text_color=""))
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70508), action="mymovies_search", thumbnail=thumb('search')))
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70024), action="filmaffinity_search", thumbnail=thumb('search')))
|
|
||||||
|
|
||||||
|
from lib.fuzzy_match import algorithims
|
||||||
|
itemlist.sort(key=lambda r: algorithims.trigram(item.contentTitle + ' trailer', r.title), reverse=True)
|
||||||
|
|
||||||
if item.contextual:
|
if item.contextual:
|
||||||
global window_select, result
|
global window_select, result
|
||||||
select = Select("DialogSelect.xml", config.get_runtime_path(), item=item, itemlist=itemlist, caption=config.get_localized_string(70506) + item.contentTitle)
|
select = Select("DialogSelect.xml", config.get_runtime_path(), item=item, itemlist=itemlist,
|
||||||
|
caption=config.get_localized_string(70506) + item.contentTitle)
|
||||||
window_select.append(select)
|
window_select.append(select)
|
||||||
select.doModal()
|
select.doModal()
|
||||||
|
|
||||||
@@ -121,16 +126,24 @@ def buscartrailer(item, trailers=[]):
|
|||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def manual_search(item):
|
def multi_search(item, itemlist, tipo):
|
||||||
|
ris = []
|
||||||
|
with futures.ThreadPoolExecutor() as executor:
|
||||||
|
ris.append(executor.submit(mymovies_search, item))
|
||||||
|
ris.append(executor.submit(youtube_search, item))
|
||||||
|
ris.append(executor.submit(tmdb_trailers, item, tipo))
|
||||||
|
|
||||||
|
for r in futures.as_completed(ris):
|
||||||
|
itemlist.extend(r.result())
|
||||||
|
|
||||||
|
|
||||||
|
def manual_search(item, tipo):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
|
itemlist = []
|
||||||
texto = platformtools.dialog_input(default=item.contentTitle, heading=config.get_localized_string(30112))
|
texto = platformtools.dialog_input(default=item.contentTitle, heading=config.get_localized_string(30112))
|
||||||
if texto is not None:
|
if texto is not None:
|
||||||
if item.extra == "mymovies":
|
multi_search(item.clone(contentTitle=texto), itemlist, tipo)
|
||||||
return mymovies_search(item.clone(contentTitle=texto))
|
return itemlist
|
||||||
elif item.extra == "youtube":
|
|
||||||
return youtube_search(item.clone(contentTitle=texto, page=""))
|
|
||||||
elif item.extra == "filmaffinity":
|
|
||||||
return filmaffinity_search(item.clone(contentTitle=texto, page="", year=""))
|
|
||||||
|
|
||||||
|
|
||||||
def tmdb_trailers(item, tipo="movie"):
|
def tmdb_trailers(item, tipo="movie"):
|
||||||
@@ -145,9 +158,18 @@ def tmdb_trailers(item, tipo="movie"):
|
|||||||
tmdb_search = Tmdb(texto_buscado=item.contentTitle, tipo=tipo, year=item.infoLabels['year'])
|
tmdb_search = Tmdb(texto_buscado=item.contentTitle, tipo=tipo, year=item.infoLabels['year'])
|
||||||
|
|
||||||
if tmdb_search:
|
if tmdb_search:
|
||||||
for result in tmdb_search.get_videos():
|
for vid in tmdb_search.get_videos():
|
||||||
title = result['name'] + " [" + result['size'] + "p] (" + result['language'].replace("en", "ING").replace("it", "ITA") + ") [tmdb/youtube]"
|
found = False
|
||||||
itemlist.append(item.clone(action="play", title=title, url=result['url'], server="youtube"))
|
if vid['type'].lower() == 'trailer':
|
||||||
|
title = vid['name']
|
||||||
|
it = item.clone(action="play", title=title, title2="TMDB(youtube) - " + vid['language'].replace("en", "ING").replace("it", "ITA") + " [" + vid['size'] + "p]", url=vid['url'], server="youtube")
|
||||||
|
itemlist.append(it)
|
||||||
|
|
||||||
|
if vid['language'] == def_lang and not found: # play now because lang is correct and TMDB is trusted
|
||||||
|
found = True
|
||||||
|
launcher.run(it)
|
||||||
|
while platformtools.is_playing():
|
||||||
|
xbmc.sleep(100)
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
@@ -164,30 +186,25 @@ def youtube_search(item):
|
|||||||
else:
|
else:
|
||||||
title = urllib.quote(title)
|
title = urllib.quote(title)
|
||||||
title = title.replace("%20", "+")
|
title = title.replace("%20", "+")
|
||||||
data = httptools.downloadpage("https://www.youtube.com/results?sp=EgIQAQ%253D%253D&q=" + title).data
|
data = httptools.downloadpage("https://www.youtube.com/results?sp=EgIQAQ%253D%253D&search_query=" + title).data
|
||||||
patron = r'thumbnails":\[\{"url":"(https://i.ytimg.com/vi[^"]+).*?'
|
patron = r'thumbnails":\[\{"url":"(https://i.ytimg.com/vi[^"]+).*?'
|
||||||
patron += r'text":"([^"]+).*?'
|
patron += r'text":"([^"]+).*?'
|
||||||
patron += r'simpleText":"[^"]+.*?simpleText":"([^"]+).*?'
|
patron += r'simpleText":"[^"]+.*?simpleText":"([^"]+).*?'
|
||||||
patron += r'url":"([^"]+)'
|
patron += r'url":"([^"]+)'
|
||||||
matches = scrapertools.find_multiple_matches(data, patron)
|
matches = scrapertools.find_multiple_matches(data, patron)
|
||||||
for scrapedthumbnail, scrapedtitle, scrapedduration, scrapedurl in matches:
|
for scrapedthumbnail, scrapedtitle, scrapedduration, scrapedurl in matches:
|
||||||
scrapedtitle = scrapedtitle if PY3 else scrapedtitle.decode('utf8').encode('utf8') + " (" + scrapedduration + ")"
|
scrapedtitle = scrapedtitle if PY3 else scrapedtitle.decode('utf8').encode('utf8')
|
||||||
if item.contextual:
|
if item.contextual:
|
||||||
scrapedtitle = "%s" % scrapedtitle
|
scrapedtitle = "%s" % scrapedtitle
|
||||||
url = urlparse.urljoin('https://www.youtube.com/', scrapedurl)
|
url = urlparse.urljoin('https://www.youtube.com/', scrapedurl)
|
||||||
itemlist.append(item.clone(title=scrapedtitle, action="play", server="youtube", url=url, thumbnail=scrapedthumbnail))
|
itemlist.append(item.clone(title=scrapedtitle, title2='Youtube - ' + scrapedduration, action="play", server="youtube",
|
||||||
next_page = scrapertools.find_single_match(data, '<a href="([^"]+)"[^>]+><span class="yt-uix-button-content">')
|
url=url, thumbnail=scrapedthumbnail))
|
||||||
if next_page != "":
|
# next_page = scrapertools.find_single_match(data, '<a href="([^"]+)"[^>]+><span class="yt-uix-button-content">')
|
||||||
next_page = urlparse.urljoin("https://www.youtube.com", next_page)
|
# if next_page != "":
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(30992), action="youtube_search", extra="youtube", page=next_page, thumbnail=thumb('search'), text_color=""))
|
# next_page = urlparse.urljoin("https://www.youtube.com", next_page)
|
||||||
if not itemlist:
|
# itemlist.append(item.clone(title=config.get_localized_string(30992), action="youtube_search", extra="youtube",
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(70501) % title, action="", thumbnail="", text_color=""))
|
# page=next_page, thumbnail=thumb('search'), text_color=""))
|
||||||
if keyboard:
|
|
||||||
if item.contextual:
|
|
||||||
title = "%s"
|
|
||||||
else:
|
|
||||||
title = "%s"
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70510), action="manual_search", thumbnail=thumb('search'), extra="youtube"))
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
@@ -197,146 +214,48 @@ def mymovies_search(item):
|
|||||||
|
|
||||||
title = item.contentTitle
|
title = item.contentTitle
|
||||||
url = 'https://www.mymovies.it/ricerca/ricerca.php?limit=true&q=' + title
|
url = 'https://www.mymovies.it/ricerca/ricerca.php?limit=true&q=' + title
|
||||||
js = json.loads(httptools.downloadpage(url).data)['risultati']['film']['elenco']
|
try:
|
||||||
|
js = json.loads(httptools.downloadpage(url).data)['risultati']['film']['elenco']
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
itemlist = []
|
itemlist = []
|
||||||
for it in js:
|
with futures.ThreadPoolExecutor() as executor:
|
||||||
itemlist.append(item.clone(title=it['titolo'], thumbnail=it['immagine'].replace('\\',''), url=it['url'].replace('\\',''), action ='search_links_mymovies'))
|
ris = [executor.submit(search_links_mymovies, item.clone(title=it['titolo'], title2='MYmovies', thumbnail=it['immagine'].replace('\\', ''), url=it['url'].replace('\\', ''))) for it in js]
|
||||||
|
for r in futures.as_completed(ris):
|
||||||
if not itemlist:
|
if r.result():
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(70501), action="", thumbnail="", text_color=""))
|
itemlist.append(r.result())
|
||||||
|
|
||||||
if keyboard:
|
|
||||||
if item.contextual: title = "%s"
|
|
||||||
else: title = "%s"
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70511), action="manual_search", thumbnail=thumb('search'), extra="mymovies"))
|
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def search_links_mymovies(item):
|
def search_links_mymovies(item):
|
||||||
|
global result
|
||||||
logger.debug()
|
logger.debug()
|
||||||
trailer_url = match(item, patron=r'<li class="bottone_playlist"[^>]+><a href="([^"]+)"').match
|
trailer_url = match(item, patron=r'<source src="([^"]+)').match
|
||||||
itemlist = []
|
|
||||||
data = httptools.downloadpage(item.url).data
|
|
||||||
if trailer_url:
|
if trailer_url:
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(60221) + ' ' + item.title, url=trailer_url, server='directo', action="play"))
|
it = item.clone(url=trailer_url, server='directo', action="play")
|
||||||
itemlist = servertools.get_servers_itemlist(itemlist)
|
if 'tmdb_id' in it.infoLabels:
|
||||||
|
del it.infoLabels['tmdb_id'] # for not saving watch time
|
||||||
else:
|
return it
|
||||||
if keyboard:
|
|
||||||
if item.contextual:
|
|
||||||
title = "%s"
|
|
||||||
else:
|
|
||||||
title = "%s"
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70513), action="manual_search", thumbnail=thumb('search'), extra="filmaffinity"))
|
|
||||||
|
|
||||||
return itemlist
|
|
||||||
|
|
||||||
|
|
||||||
def filmaffinity_search(item):
|
|
||||||
logger.debug()
|
|
||||||
|
|
||||||
if item.filmaffinity:
|
|
||||||
item.url = item.filmaffinity
|
|
||||||
return search_links_filmaff(item)
|
|
||||||
|
|
||||||
# Check if it is a zero search or comes from the Next option
|
|
||||||
if item.page != "":
|
|
||||||
data = httptools.downloadpage(item.page).data
|
|
||||||
else:
|
|
||||||
params = urllib.urlencode([('stext', item.contentTitle), ('stype%5B%5D', 'title'), ('country', ''), ('genre', ''), ('fromyear', item.year), ('toyear', item.year)])
|
|
||||||
url = "http://www.filmaffinity.com/es/advsearch.php?%s" % params
|
|
||||||
data = httptools.downloadpage(url).data
|
|
||||||
|
|
||||||
itemlist = []
|
|
||||||
patron = '<div class="mc-poster">.*?<img.*?src="([^"]+)".*?' \
|
|
||||||
'<div class="mc-title"><a href="/es/film(\d+).html"[^>]+>(.*?)<img'
|
|
||||||
matches = scrapertools.find_multiple_matches(data, patron)
|
|
||||||
# If there is only one result, search directly for the trailers, but list all the results
|
|
||||||
if len(matches) == 1:
|
|
||||||
item.url = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % matches[0][1]
|
|
||||||
item.thumbnail = matches[0][0]
|
|
||||||
if not item.thumbnail.startswith("http"): item.thumbnail = "http://www.filmaffinity.com" + item.thumbnail
|
|
||||||
itemlist = search_links_filmaff(item)
|
|
||||||
elif len(matches) > 1:
|
|
||||||
for scrapedthumbnail, id, scrapedtitle in matches:
|
|
||||||
if not scrapedthumbnail.startswith("http"): scrapedthumbnail = "http://www.filmaffinity.com" + scrapedthumbnail
|
|
||||||
scrapedurl = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % id
|
|
||||||
if PY3: scrapedtitle = unicode(scrapedtitle, encoding="utf-8", errors="ignore")
|
|
||||||
scrapedtitle = scrapertools.htmlclean(scrapedtitle)
|
|
||||||
itemlist.append(item.clone(title=scrapedtitle, url=scrapedurl, action="search_links_filmaff", thumbnail=scrapedthumbnail))
|
|
||||||
|
|
||||||
next_page = scrapertools.find_single_match(data, '<a href="([^"]+)">>></a>')
|
|
||||||
if next_page != "":
|
|
||||||
next_page = urlparse.urljoin("http://www.filmaffinity.com/es/", next_page)
|
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(30992), page=next_page, action="filmaffinity_search", thumbnail=thumb('search'), text_color=""))
|
|
||||||
|
|
||||||
if not itemlist: itemlist.append(item.clone(title=config.get_localized_string(70501) % item.contentTitle, action="", thumbnail="", text_color=""))
|
|
||||||
|
|
||||||
if keyboard:
|
|
||||||
if item.contextual: title = "%s"
|
|
||||||
else: title = "%s"
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70513), action="manual_search", thumbnail=thumb('search'), extra="filmaffinity"))
|
|
||||||
|
|
||||||
return itemlist
|
|
||||||
|
|
||||||
|
|
||||||
def search_links_filmaff(item):
|
|
||||||
logger.debug()
|
|
||||||
|
|
||||||
itemlist = []
|
|
||||||
data = httptools.downloadpage(item.url).data
|
|
||||||
if not '<a class="lnkvvid"' in data:
|
|
||||||
itemlist.append(item.clone(title=config.get_localized_string(70503), action="", text_color=""))
|
|
||||||
else:
|
|
||||||
patron = '<a class="lnkvvid".*?<b>(.*?)</b>.*?iframe.*?src="([^"]+)"'
|
|
||||||
matches = scrapertools.find_multiple_matches(data, patron)
|
|
||||||
for scrapedtitle, scrapedurl in matches:
|
|
||||||
if not scrapedurl.startswith("http:"):
|
|
||||||
scrapedurl = urlparse.urljoin("http:", scrapedurl)
|
|
||||||
trailer_url = scrapedurl.replace("-nocookie.com/embed/", ".com/watch?v=")
|
|
||||||
if "youtube" in trailer_url:
|
|
||||||
server = "youtube"
|
|
||||||
code = scrapertools.find_single_match(trailer_url, 'v=([A-z0-9\-_]+)')
|
|
||||||
thumbnail = "https://img.youtube.com/vi/%s/0.jpg" % code
|
|
||||||
else:
|
|
||||||
server = ""
|
|
||||||
thumbnail = item.thumbnail
|
|
||||||
if PY3:
|
|
||||||
scrapedtitle = unicode(scrapedtitle, encoding="utf-8", errors="ignore")
|
|
||||||
scrapedtitle = scrapertools.htmlclean(scrapedtitle)
|
|
||||||
scrapedtitle += " [" + server + "]"
|
|
||||||
if item.contextual:
|
|
||||||
scrapedtitle = "%s" % scrapedtitle
|
|
||||||
itemlist.append(item.clone(title=scrapedtitle, url=trailer_url, server=server, action="play", thumbnail=thumbnail))
|
|
||||||
|
|
||||||
itemlist = servertools.get_servers_itemlist(itemlist)
|
|
||||||
if keyboard:
|
|
||||||
if item.contextual:
|
|
||||||
title = "%s"
|
|
||||||
else:
|
|
||||||
title = "%s"
|
|
||||||
itemlist.append(item.clone(title=title % config.get_localized_string(70513), action="manual_search", thumbnail="", extra="filmaffinity"))
|
|
||||||
|
|
||||||
return itemlist
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmc
|
import xbmc
|
||||||
|
|
||||||
|
|
||||||
class Select(xbmcgui.WindowXMLDialog):
|
class Select(xbmcgui.WindowXMLDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.item = kwargs.get('item')
|
self.item = kwargs.get('item')
|
||||||
self.itemlist = kwargs.get('itemlist')
|
self.itemlist = kwargs.get('itemlist')
|
||||||
self.caption = kwargs.get('caption')
|
self.caption = kwargs.get('caption')
|
||||||
self.result = None
|
|
||||||
def onInit(self):
|
def onInit(self):
|
||||||
try:
|
try:
|
||||||
self.control_list = self.getControl(6)
|
self.control_list = self.getControl(6)
|
||||||
self.getControl(5).setNavigation(self.control_list, self.control_list, self.control_list, self.control_list)
|
self.getControl(5).setNavigation(self.control_list, self.control_list, self.control_list,
|
||||||
|
self.control_list)
|
||||||
self.getControl(3).setEnabled(0)
|
self.getControl(3).setEnabled(0)
|
||||||
self.getControl(3).setVisible(0)
|
self.getControl(3).setVisible(0)
|
||||||
except:
|
except:
|
||||||
@@ -347,35 +266,30 @@ try:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.getControl(1).setLabel("" + self.caption + "")
|
self.getControl(1).setLabel("" + self.caption + "")
|
||||||
self.getControl(5).setLabel(config.get_localized_string(60495))
|
if keyboard:
|
||||||
|
self.getControl(5).setLabel(config.get_localized_string(70510))
|
||||||
self.items = []
|
self.items = []
|
||||||
for item in self.itemlist:
|
for item in self.itemlist:
|
||||||
item_l = xbmcgui.ListItem(item.title)
|
item_l = xbmcgui.ListItem(item.title, item.title2)
|
||||||
item_l.setArt({'thumb': item.thumbnail})
|
item_l.setArt({'thumb': item.thumbnail})
|
||||||
item_l.setProperty('item_copy', item.tourl())
|
item_l.setProperty('item_copy', item.tourl())
|
||||||
self.items.append(item_l)
|
self.items.append(item_l)
|
||||||
self.control_list.reset()
|
self.control_list.reset()
|
||||||
self.control_list.addItems(self.items)
|
self.control_list.addItems(self.items)
|
||||||
self.setFocus(self.control_list)
|
self.setFocus(self.control_list)
|
||||||
|
|
||||||
def onClick(self, id):
|
def onClick(self, id):
|
||||||
global window_select, result
|
global window_select, result
|
||||||
# Cancel button y [X]
|
# Cancel button y [X]
|
||||||
if id == 7:
|
if id == 7:
|
||||||
window_select[-1].close()
|
window_select[-1].close()
|
||||||
if id == 5:
|
if id == 5 and keyboard:
|
||||||
self.result = "_no_video"
|
|
||||||
result = "no_video"
|
|
||||||
self.close()
|
self.close()
|
||||||
window_select.pop()
|
buscartrailer(self.item.clone(action="manual_search", extra="youtube"))
|
||||||
if not window_select:
|
|
||||||
if not self.item.windowed:
|
|
||||||
del window_select
|
|
||||||
else:
|
|
||||||
window_select[-1].doModal()
|
|
||||||
def onAction(self, action):
|
def onAction(self, action):
|
||||||
global window_select, result
|
global window_select, result
|
||||||
if action == 92 or action == 110:
|
if action == 92 or action == 110:
|
||||||
self.result = "no_video"
|
|
||||||
result = "no_video"
|
result = "no_video"
|
||||||
self.close()
|
self.close()
|
||||||
window_select.pop()
|
window_select.pop()
|
||||||
@@ -394,10 +308,8 @@ try:
|
|||||||
xbmc.sleep(200)
|
xbmc.sleep(200)
|
||||||
if puede:
|
if puede:
|
||||||
result = video_urls[-1][1]
|
result = video_urls[-1][1]
|
||||||
self.result = video_urls[-1][1]
|
|
||||||
else:
|
else:
|
||||||
result = None
|
result = None
|
||||||
self.result = None
|
|
||||||
elif item.action == "play" and not self.item.windowed:
|
elif item.action == "play" and not self.item.windowed:
|
||||||
for window in window_select:
|
for window in window_select:
|
||||||
window.close()
|
window.close()
|
||||||
|
|||||||
@@ -417,6 +417,8 @@ def findvideos(item):
|
|||||||
|
|
||||||
all_videolibrary = []
|
all_videolibrary = []
|
||||||
ch_results = []
|
ch_results = []
|
||||||
|
list_servers = []
|
||||||
|
|
||||||
with futures.ThreadPoolExecutor() as executor:
|
with futures.ThreadPoolExecutor() as executor:
|
||||||
for nom_canal, json_path in list(list_canales.items()):
|
for nom_canal, json_path in list(list_canales.items()):
|
||||||
if filtro_canal and filtro_canal != nom_canal.capitalize():
|
if filtro_canal and filtro_canal != nom_canal.capitalize():
|
||||||
@@ -476,7 +478,6 @@ def findvideos(item):
|
|||||||
del item.library_urls[nom_canal]
|
del item.library_urls[nom_canal]
|
||||||
|
|
||||||
item_json = Item().fromjson(filetools.read(json_path))
|
item_json = Item().fromjson(filetools.read(json_path))
|
||||||
list_servers = []
|
|
||||||
# support.dbg()
|
# support.dbg()
|
||||||
try: from urllib.parse import urlsplit
|
try: from urllib.parse import urlsplit
|
||||||
except ImportError: from urlparse import urlsplit
|
except ImportError: from urlparse import urlsplit
|
||||||
|
|||||||
+3
-3
@@ -3,9 +3,9 @@ rm tests/home/userdata/addon_data/plugin.video.kod/settings_servers/*.json
|
|||||||
rm tests/home/userdata/addon_data/plugin.video.kod/cookies.dat
|
rm tests/home/userdata/addon_data/plugin.video.kod/cookies.dat
|
||||||
rm tests/home/userdata/addon_data/plugin.video.kod/kod_db.sqlite
|
rm tests/home/userdata/addon_data/plugin.video.kod/kod_db.sqlite
|
||||||
python3 -m pip install --upgrade pip
|
python3 -m pip install --upgrade pip
|
||||||
pip install sakee
|
pip install -U sakee
|
||||||
pip install html-testRunner
|
pip install -U html-testRunner
|
||||||
pip install parameterized
|
pip install -U parameterized
|
||||||
export PYTHONPATH=$PWD
|
export PYTHONPATH=$PWD
|
||||||
export KODI_INTERACTIVE=0
|
export KODI_INTERACTIVE=0
|
||||||
export KODI_HOME=$PWD/tests/home
|
export KODI_HOME=$PWD/tests/home
|
||||||
|
|||||||
+8
-10
@@ -315,6 +315,7 @@ class GenericServerTest(unittest.TestCase):
|
|||||||
def test_get_video_url(self):
|
def test_get_video_url(self):
|
||||||
module = __import__('servers.%s' % self.name, fromlist=["servers.%s" % self.name])
|
module = __import__('servers.%s' % self.name, fromlist=["servers.%s" % self.name])
|
||||||
page_url = self.server.url
|
page_url = self.server.url
|
||||||
|
httptools.default_headers['Referer'] = self.server.referer
|
||||||
print('testing ' + page_url)
|
print('testing ' + page_url)
|
||||||
print('Found on ' + self.server.foundOn)
|
print('Found on ' + self.server.foundOn)
|
||||||
print()
|
print()
|
||||||
@@ -342,10 +343,10 @@ class GenericServerTest(unittest.TestCase):
|
|||||||
print(headers)
|
print(headers)
|
||||||
if 'magnet:?' in directUrl: # check of magnet links not supported
|
if 'magnet:?' in directUrl: # check of magnet links not supported
|
||||||
continue
|
continue
|
||||||
if directUrl.split('.')[-1] == 'm3u8': # m3u8 is a text file and HEAD may be forbidden
|
page = downloadpage(directUrl, headers=headers, only_headers=True, use_requests=True, verify=False)
|
||||||
|
if not page.success and directUrl.split('.')[-1] == 'm3u8': # m3u8 is a text file and HEAD may be forbidden
|
||||||
page = downloadpage(directUrl, headers=headers, use_requests=True, verify=False)
|
page = downloadpage(directUrl, headers=headers, use_requests=True, verify=False)
|
||||||
else:
|
|
||||||
page = downloadpage(directUrl, headers=headers, only_headers=True, use_requests=True, verify=False)
|
|
||||||
self.assertTrue(page.success, self.name + ' scraper returned an invalid link')
|
self.assertTrue(page.success, self.name + ' scraper returned an invalid link')
|
||||||
self.assertLess(page.code, 400, self.name + ' scraper returned a ' + str(page.code) + ' link')
|
self.assertLess(page.code, 400, self.name + ' scraper returned a ' + str(page.code) + ' link')
|
||||||
contentType = page.headers['Content-Type']
|
contentType = page.headers['Content-Type']
|
||||||
@@ -356,10 +357,7 @@ class GenericServerTest(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if 'KOD_TST_CH' not in os.environ:
|
unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(report_name='report', add_timestamp=False, combine_reports=True,
|
||||||
unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(report_name='report', add_timestamp=False, combine_reports=True,
|
report_title='KoD Test Suite', template=os.path.join(config.get_runtime_path(), 'tests', 'template.html')), exit=False)
|
||||||
report_title='KoD Test Suite', template=os.path.join(config.get_runtime_path(), 'tests', 'template.html')), exit=False)
|
import webbrowser
|
||||||
import webbrowser
|
webbrowser.open(os.path.join(outDir, 'report.html'))
|
||||||
webbrowser.open(os.path.join(outDir, 'report.html'))
|
|
||||||
else:
|
|
||||||
unittest.main()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user