-Nuova Ricerca Globale\n-Nuova Rinumerazione\n-Messaggi di Errore più chiari\n-Fix var\n
This commit is contained in:
marco
2020-12-01 20:19:07 +01:00
parent 97e06a8b84
commit 94eac40955
233 changed files with 4568 additions and 2245 deletions

28
.github/workflows/updateDomains.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Update channel domains
on:
workflow_dispatch:
schedule:
- cron: '30 17 * * *'
jobs:
update:
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: 2.7
- name: Update domains
run: |
python tools/updateDomains.py
- name: Commit & Push changes
uses: actions-js/push@master
with:
message: "Aggiornamento domini"
branch: "master"
github_token: ${{ secrets.API_TOKEN_GITHUB }}

View File

@@ -1,4 +1,4 @@
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.4.1" provider-name="KoD Team">
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.5" provider-name="KoD Team">
<requires>
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
<import addon="metadata.themoviedb.org"/>
@@ -26,8 +26,10 @@
<screenshot>resources/media/themes/ss/2.png</screenshot>
<screenshot>resources/media/themes/ss/3.png</screenshot>
</assets>
<news>- ridisegnata la finestra della scelta film/serietv quando si aggiunge in videoteca
- modifiche minori, qualche fix ai canali/server ed alla ricerca alternativa</news>
<news>-Nuova Ricerca Globale
-Nuova Rinumerazione
-Messaggi di Errore più chiari
-Fix var</news>
<description lang="it">Naviga velocemente sul web e guarda i contenuti presenti</description>
<disclaimer>[COLOR red]The owners and submitters to this addon do not host or distribute any of the content displayed by these addons nor do they have any affiliation with the content providers.[/COLOR]
[COLOR yellow]Kodi © is a registered trademark of the XBMC Foundation. We are not connected to or in any other way affiliated with Kodi, Team Kodi, or the XBMC Foundation. Furthermore, any software, addons, or products offered by us will receive no support in official Kodi channels, including the Kodi forums and various social networks.[/COLOR]</disclaimer>

View File

@@ -1,57 +1,57 @@
{
"findhost": {
"altadefinizione01": "https://altadefinizione01-nuovo.info",
"altadefinizioneclick": "https://altadefinizione-nuovo.me",
"animealtadefinizione": "https://www.animealtadefinizione.it",
"cineblog01": "https://cb01.uno",
"eurostreaming": "https://eurostreaming.link",
"film4k": "https://film4k-nuovo.link",
"filmpertutti": "https://filmpertutti.nuovo.live",
"ilcorsaronero": "https://lagazzettadelcorsaro.com",
"seriehd": "https://nuovoindirizzo.info/seriehd/",
"serietvonline": "https://serietvonline.online",
"tantifilm": "https://www.tantifilm.wiki"
},
"direct": {
"altadefinizione01_link": "https://altadefinizione01.energy",
"animealtadefinizione": "https://www.animealtadefinizione.it",
"animeforce": "https://ww1.animeforce.org",
"animeleggendari": "https://animeora.com",
"animesaturn": "https://www.animesaturn.it",
"animestream": "https://www.animeworld.tv",
"animesubita": "http://www.animesubita.org",
"animetubeita": "http://www.animetubeita.com",
"animeunity": "https://www.animeunity.it",
"animeuniverse": "https://www.animeuniverse.it/",
"animeworld": "https://www.animeworld.tv",
"casacinema": "https://www.casacinema.page",
"cb01anime": "https://www.cineblog01.red",
"cinemalibero": "https://cinemalibero.xyz",
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
"dreamsub": "https://dreamsub.stream",
"dsda": "https://www.dsda.press",
"fastsubita": "https://fastsubita.uno",
"filmgratis": "https://www.filmaltadefinizione.co",
"filmigratis": "https://filmigratis.org",
"filmsenzalimiticc": "https://www.filmsenzalimiti01.online",
"filmstreaming01": "https://filmstreaming01.com",
"guardaserie_stream": "https://guardaserie.host",
"guardaseriecam": "https://guardaserie.cam",
"guardaserieclick": "https://www.guardaserie.clinic",
"guardaserieicu": "https://guardaserie.us",
"hd4me": "https://hd4me.net",
"ilgeniodellostreaming": "https://ilgeniodellostreaming.pet",
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.gold",
"italiaserie": "https://italiaserie.eu",
"mondoserietv": "https://mondoserietv.fun",
"piratestreaming": "https://www.piratestreaming.deals",
"polpotv": "https://polpotv.life",
"raiplay": "https://www.raiplay.it",
"serietvsubita": "http://serietvsubita.xyz",
"serietvu": "https://www.serietvu.link",
"streamingcommunity": "https://streamingcommunity.net",
"streamtime": "https://t.me/s/StreamTime",
"toonitalia": "https://toonitalia.org",
"altadefinizione01_link": "https://altadefinizione01.tips",
"animealtadefinizione": "https://www.animealtadefinizione.it",
"animeforce": "https://ww1.animeforce.org",
"animeleggendari": "https://animeora.com",
"animesaturn": "https://www.animesaturn.it",
"animestream": "https://www.animeworld.tv",
"animesubita": "http://www.animesubita.org",
"animetubeita": "http://www.animetubeita.com",
"animeunity": "https://www.animeunity.it",
"animeuniverse": "https://www.animeuniverse.it/",
"animeworld": "https://www.animeworld.tv",
"casacinema": "https://www.casacinema.page",
"cb01anime": "https://www.cineblog01.red",
"cinemalibero": "https://cinemalibero.life",
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
"dreamsub": "https://dreamsub.stream",
"dsda": "https://www.dsda.press",
"eurostreaming": "https://eurostreaming.bid",
"fastsubita": "https://fastsubita.xyz",
"filmgratis": "https://www.filmaltadefinizione.me",
"filmigratis": "https://filmigratis.org",
"filmsenzalimiticc": "https://www.filmsenzalimiti01.online",
"filmstreaming01": "https://filmstreaming01.com",
"guardaserie_stream": "https://guardaserie.host",
"guardaseriecam": "https://guardaserie.cam",
"guardaserieclick": "https://www.guardaserie.deals",
"guardaserieicu": "https://guardaserie.rocks",
"hd4me": "https://hd4me.net",
"ilgeniodellostreaming": "https://ilgeniodellostreaming.pet",
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.gold",
"italiaserie": "https://italiaserie.run",
"mondoserietv": "https://mondoserietv.fun",
"piratestreaming": "https://www.piratestreaming.date",
"polpotv": "https://roma.polpo.tv",
"raiplay": "https://www.raiplay.it",
"serietvonline": "https://serietvonline.cam",
"serietvsubita": "http://serietvsubita.xyz",
"serietvu": "https://www.serietvu.link",
"streamingcommunity": "https://streamingcommunity.net",
"streamtime": "https://t.me/s/StreamTime",
"toonitalia": "https://toonitalia.org",
"vvvvid": "https://www.vvvvid.it"
},
"findhost": {
"altadefinizione01": "https://altadefinizione01-nuovo.info",
"altadefinizioneclick": "https://altadefinizione-nuovo.me",
"animealtadefinizione": "https://www.animealtadefinizione.it",
"cineblog01": "https://cb01.uno",
"film4k": "https://film4k-nuovo.link",
"filmpertutti": "https://filmpertutti.nuovo.live",
"ilcorsaronero": "https://lagazzettadelcorsaro.com",
"seriehd": "https://nuovoindirizzo.info/seriehd/",
"tantifilm": "https://www.tantifilm.wiki"
}
}

View File

@@ -51,7 +51,7 @@ def peliculas(item):
## deflang = 'ITA'
action="findvideos"
patron = r'<div class="cover boxcaption"> <h2>\s*<a href="(?P<url>[^"]+)">(?P<title>[^<]+).*?src="(?P<thumb>[^"]+).*?<div class="trdublaj">(?P<quality>[^<]+).*?<span class="ml-label">(?P<year>[0-9]+).*?<span class="ml-label">(?P<duration>[^<]+).*?<p>(?P<plot>[^<]+)'
patron = r'<div class="cover boxcaption"> +<h2>\s*<a href="(?P<url>[^"]+)">(?P<title>[^<]+).*?src="(?P<thumb>[^"]+).*?<div class="trdublaj">(?P<quality>[^<]+).*?<span class="ml-label">(?P<year>[0-9]+).*?<span class="ml-label">(?P<duration>[^<]+).*?<p>(?P<plot>[^<]+)'
if item.args == "search":
patronBlock = r'</script> <div class="boxgrid caption">(?P<block>.*)<div id="right_bar">'

View File

@@ -73,7 +73,7 @@ def search(item, text):
except:
import sys
for line in sys.exc_info():
logger.info("%s mainlist search log: %s" % (__channel__, line))
logger.error("%s" % line)
return []
# =========== def per le novità nel menu principale =============

View File

@@ -46,9 +46,8 @@ def mainlist(item):
@support.scrape
def peliculas(item):
# debug = True
patron = r'<div class="wrapperImage">[ ]?(?:<span class="hd">(?P<quality>[^<>]+))?.+?href="(?P<url>[^"]+)".+?src="(?P<thumb>[^"]+)".+?<h2 class="titleFilm">[^>]+>'\
r'(?P<title>.+?)[ ]?(?:|\[(?P<lang>[^\]]+)\])?(?:\((?P<year>\d{4})\))?</a>.*?(?:IMDB\:</strong>[ ](?P<rating>.+?)<|</h2> )'
# debug=True
patron = r'<div class="wrapperImage">\s*(?:<span class="year">(?P<year>[^<]+)[^>]+>)?(?:<span class="hd">(?P<quality>[^<>]+))?.+?href="(?P<url>[^"]+)".+?src="(?P<thumb>[^"]+)".+?<h2 class="titleFilm">[^>]+>(?P<title>.+?)[ ]?(?:|\[(?P<lang>[^\]]+)\])?</a>.*?(?:IMDB\:</strong>[ ](?P<rating>.+?)<|</h2> )'
patronBlock = r'h1>(?P<block>.*?)<div class="row ismobile">'
if item.args == 'az':
@@ -60,8 +59,8 @@ def peliculas(item):
patron = r'<div class="wrapperImage">[ ]?(?:<span class="hd">(?P<quality>[^<>]+))?.+?href="(?P<url>[^"]+)".+?src="(?P<thumb>[^"]+)"'\
r'.+?<h2 class="titleFilm(?:Mobile)?">[^>]+>(?P<title>.+?)[ ]?(?:|\[(?P<lang>[^\]]+)\])?(?:\((?P<year>\d{4})\))?</a>.*?(IMDB\:[ ](?P<rating>.+?))<'
elif item.args == 'search':
patronBlock = r'<section id="lastUpdate">(?P<block>.*?)<div class="row ismobile">'
patron = r'<a href="(?P<url>[^"]+)">\s*<div class="wrapperImage">(?:<span class="year">(?P<year>[^<]+)<\/span>)?(?:<span class="hd">(?P<quality>[^<]+)<\/span>)?<img[^s]+src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)'
patronBlock = r'<section id="lastUpdate">(?P<block>.*?)(?:<div class="row ismobile">|<section)'
patron = r'<a href="(?P<url>[^"]+)">\s*<div class="wrapperImage">(?:\s*<span class="year">(?P<year>[^<]+)<\/span>)?(?:\s*<span class="hd">(?P<quality>[^<]+)<\/span>)?[^>]+>\s*<img[^s]+src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*(?P<rating>[^<]+)[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)'
if not item.args:
patronBlock = r'ULTIMI INSERITI(?P<block>.*?)<div class="sliderLastUpdate ismobile ">'
@@ -99,7 +98,7 @@ def search(item, texto):
support.info("search ", texto)
item.args = 'search'
item.url = host + "/search/" + texto
item.url = host + "?s=" + texto
try:
return peliculas(item)
# Continua la ricerca in caso di errore

View File

@@ -26,7 +26,7 @@ def mainlist(item):
@support.scrape
def menu(item):
action = 'peliculas'
data = support.match(item, patron= r'<a href="' + host + r'/category/' + item.args.lower() + r'/">' + item.args + r'</a><ul class="sub-menu">(.*?)</ul>').match
patronBlock= r'<a href="' + host + r'/category/' + item.args.lower() + r'/">' + item.args + r'</a>\s*<ul class="sub-menu">(?P<block>.*?)</ul>'
patronMenu = r'<a href="(?P<url>[^"]+)">(?P<title>[^<]+)<'
return locals()
@@ -85,7 +85,7 @@ def peliculas(item):
typeContentDict = {'movie':['movie']}
typeActionDict = {'findvideos':['movie']}
def ItemItemlistHook(item, itemlist):
def itemlistHook(itemlist):
if item.search:
itemlist = [ it for it in itemlist if ' Episodio ' not in it.title ]
if len(itemlist) == int(perpage):
@@ -97,6 +97,7 @@ def peliculas(item):
@support.scrape
def episodios(item):
anime = True
pagination = int(perpage)
patron = epPatron
return locals()
@@ -107,18 +108,19 @@ def findvideos(item):
if item.contentType == 'movie':
matches = support.match(item, patron=epPatron).matches
for title, url in matches:
get_video_list(url, title, itemlist)
# support.dbg()
get_video_list(item, url, title, itemlist)
else:
get_video_list(item.url, support.config.get_localized_string(30137), itemlist)
get_video_list(item, item.url, support.config.get_localized_string(30137), itemlist)
return support.server(item, itemlist=itemlist)
def get_video_list(url, title, itemlist):
def get_video_list(item, url, title, itemlist):
from requests import get
if not url.startswith('http'): url = host + url
url = support.match(get(url).url, string=True, patron=r'file=([^$]+)').match
if 'http' not in url: url = 'http://' + url
itemlist.append(support.Item(title=title, url=url, server='directo', action='play'))
itemlist.append(item.clone(title=title, url=url, server='directo', action='play'))
return itemlist

View File

@@ -27,7 +27,7 @@ def mainlist(item):
def submenu(item):
action = 'peliculas'
patronBlock = r'data-taxonomy="' + item.args + r'"(?P<block>.*?)</select'
patronMenu = r'<option class="level-\d+ (?P<u>[^"]+)"[^>]+>(?P<t>[^&]+)[^\(]+\((?P<num>\d+)'
patronMenu = r'<option class="level-\d+ (?P<u>[^"]+)"[^>]+>(?P<t>[^(]+)[^\(]+\((?P<num>\d+)'
def itemHook(item):
item.url += host + '/anime/' + item.args + '/' + item.u
item.title = support.typo(item.t, 'bold')
@@ -54,10 +54,10 @@ def newest(categoria):
return itemlist
def search(item, texto):
support.info(texto)
item.args = 'noorder'
item.url = host + '/?s=' + texto + '&cat=6010'
def search(item, text):
support.info('search',text)
item.search = text
item.url = host + '/lista-anime/'
item.contentType = 'tvshow'
try:
return peliculas(item)
@@ -71,6 +71,7 @@ def search(item, texto):
@support.scrape
def peliculas(item):
search = item.search
anime = True
if 'movie' in item.url:
action = 'findvideos'

View File

@@ -59,7 +59,7 @@ def peliculas(item):
anime = True
blacklist = ['top 10 anime da vedere']
if item.url != host: patronBlock = r'<div id="main-content(?P<block>.*?)<aside'
patron = r'<figure class="(?:mh-carousel-thumb|mh-posts-grid-thumb)"> <a (?:class="[^"]+" )?href="(?P<url>[^"]+)" title="(?P<title>.*?)(?: \((?P<year>\d+)\))? (?:(?P<lang>SUB ITA|ITA))(?: (?P<title2>[Mm][Oo][Vv][Ii][Ee]))?[^"]*"><img (?:class="[^"]+"|width="[^"]+" height="[^"]+") src="(?P<thumb>[^"]+)"[^>]+'
patron = r'<figure class="(?:mh-carousel-thumb|mh-posts-grid-thumb)">\s*<a (?:class="[^"]+" )?href="(?P<url>[^"]+)" title="(?P<title>.*?)(?: \((?P<year>\d+)\))? (?:(?P<lang>SUB ITA|ITA))(?: (?P<title2>[Mm][Oo][Vv][Ii][Ee]))?[^"]*"><img (?:class="[^"]+"|width="[^"]+" height="[^"]+") src="(?P<thumb>[^"]+)"[^>]+'
def itemHook(item):
if 'movie' in item.title.lower():
item.title = support.re.sub(' - [Mm][Oo][Vv][Ii][Ee]|[Mm][Oo][Vv][Ii][Ee]','',item.title)

View File

@@ -60,7 +60,7 @@ def newest(categoria):
def submenu(item):
data = support.match(item.url + item.args).data
action = 'filter'
patronMenu = r'<h5 class="[^"]+">(?P<title>[^<]+)[^>]+>[^>]+><select id="(?P<parameter>[^"]+)"[^>]+>(?P<url>.*?)</select>'
patronMenu = r'<h5 class="[^"]+">(?P<title>[^<]+)[^>]+>[^>]+>\s*<select id="(?P<parameter>[^"]+)"[^>]+>(?P<url>.*?)</select>'
def itemlistHook(itemlist):
itemlist.insert(0, item.clone(title=support.typo('Tutti','bold'), url=item.url + item.args, action='peliculas'))
return itemlist[:-1]
@@ -104,7 +104,7 @@ def peliculas(item):
data = support.match(item, post=post, headers=headers).data
if item.args == 'updated':
page = support.match(data, patron=r'data-page="(\d+)" title="Next">').match
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>[^"(]+)(?:\s*\((?P<year>\d+)\))?(?:\s*\((?P<lang>[A-Za-z-]+)\))?"><img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s\s*(?P<type>[^\s]+)\s*(?P<episode>\d+)'
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>[^"(]+)(?:\s*\((?P<year>\d+)\))?(?:\s*\((?P<lang>[A-Za-z-]+)\))?">\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s\s*(?P<type>[^\s]+)\s*(?P<episode>\d+)'
typeContentDict = {'Movie':'movie', 'Episodio':'episode'} #item.contentType='episode'
action = 'findvideos'
def itemlistHook(itemlist):
@@ -113,7 +113,7 @@ def peliculas(item):
return itemlist
elif 'filter' in item.args:
page = support.match(data, patron=r'totalPages:\s*(\d+)').match
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>[^"(]+)(?:\s*\((?P<year>\d+)\))?(?:\s*\((?P<lang>[A-Za-z-]+)\))?"><img src="(?P<thumb>[^"]+)"'
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>[^"(]+)(?:\s*\((?P<year>\d+)\))?(?:\s*\((?P<lang>[A-Za-z-]+)\))?">\s*<img src="(?P<thumb>[^"]+)"'
def itemlistHook(itemlist):
if item.nextpage: item.nextpage += 1
else: item.nextpage = 2
@@ -127,7 +127,7 @@ def peliculas(item):
patron = r'<a href="(?P<url>[^"]+)"[^>]+>(?P<title>[^<(]+)(?:\s*\((?P<year>\d+)\))?(?:\s*\((?P<lang>[A-za-z-]+)\))?</a>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<img width="[^"]+" height="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<plot>[^<]+)<'
else:
# debug=True
patron = r'<img src="(?P<thumb>[^"]+)" alt="(?P<title>[^"\(]+)(?:\((?P<lang>[Ii][Tt][Aa])\))?(?:\s*\((?P<year>\d+)\))?[^"]*"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+><a class="[^"]+" href="(?P<url>[^"]+)">[^>]+>[^>]+>[^>]+><p[^>]+>(?:(?P<plot>[^<]+))?<'
patron = r'<img src="(?P<thumb>[^"]+)" alt="(?P<title>[^"\(]+)(?:\((?P<lang>[Ii][Tt][Aa])\))?(?:\s*\((?P<year>\d+)\))?[^"]*"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a class="[^"]+" href="(?P<url>[^"]+)">[^>]+>[^>]+>[^>]+>\s*<p[^>]+>(?:(?P<plot>[^<]+))?<'
return locals()

View File

@@ -187,7 +187,7 @@ def peliculas(item):
itemlist.append(itm)
autorenumber.renumber(itemlist)
autorenumber.start(itemlist)
if len(itemlist) >= 30:
itemlist.append(item.clone(title=support.typo(support.config.get_localized_string(30992), 'color kod bold'), thumbnail=support.thumb(), page=page + 1))
@@ -212,7 +212,7 @@ def episodios(item):
contentType='episode',
url=it['link']))
autorenumber.renumber(itemlist, item, 'bold')
autorenumber.start(itemlist, item)
support.videolibrary(itemlist, item)
support.download(itemlist, item)
return itemlist

View File

@@ -84,12 +84,12 @@ def peliculas(item):
if not item.pag: item.pag = 1
anime=True
blacklist=['Altri Hentai']
# blacklist=['Altri Hentai']
data = support.match(host + '/wp-content/themes/animeuniverse/functions/ajax.php', post='sorter=recent&location=&loop=main+loop&action=sort&numarticles='+perpage+'&paginated='+str(item.pag)+'&currentquery%5B'+query+'%5D='+searchtext+'&thumbnail=1').data.replace('\\','')
patron=r'<a href="(?P<url>[^"]+)"><img width="[^"]+" height="[^"]+" src="(?P<thumb>[^"]+)" class="[^"]+" alt="" title="(?P<title>.*?)\s*(?P<lang>Sub ITA|ITA)?(?:"| \[)'
def ItemItemlistHook(item, itemlist):
if len(itemlist) == int(perpage) - len(blacklist):
def itemlistHook(itemlist):
if len(itemlist) == int(perpage):
item.pag += 1
itemlist.append(item.clone(title=support.typo(support.config.get_localized_string(30992), 'color kod bold'), action='peliculas'))
return itemlist

View File

@@ -88,7 +88,7 @@ def menu(item):
action = 'submenu'
# data = get_data(item)
patronMenu=r'<button[^>]+>\s*(?P<title>[A-Za-z0-9]+)\s*<span.[^>]+>(?P<other>.*?)</ul>'
def ItemItemlistHook(item, itemlist):
def itemlistHook(itemlist):
itemlist.insert(0, item.clone(title=support.typo('Tutti','bold'), action='peliculas'))
itemlist.append(item.clone(title=support.typo('Cerca...','bold'), action='search', search=True, thumbnail=support.thumb('search.png')))
return itemlist
@@ -174,7 +174,7 @@ def peliculas(item):
@support.scrape
def episodios(item):
anime=True
pagination = 50
pagination = 25
# data = get_data(item)
patronBlock= r'<div class="server\s*active\s*"(?P<block>.*?)(?:<div class="server|<link)'
patron = r'<li[^>]*>\s*<a.*?href="(?P<url>[^"]+)"[^>]*>(?P<episode>[^<]+)<'

View File

@@ -105,9 +105,9 @@ def peliculas(item):
action = 'select'
if item.args == 'newest':
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div> <div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?<(?:[^>]+>.+?(?:title="Nuovi episodi">(?P<episode>\d+x\d+)[ ]?(?P<lang2>Sub-Ita)?|title="IMDb">(?P<rating>[^<]+)))?'
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div>\s+<div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?<(?:[^>]+>.+?(?:title="Nuovi episodi">(?P<episode>\d+x\d+)[ ]?(?P<lang2>Sub-Ita)?|title="IMDb">(?P<rating>[^<]+)))?'
else:
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div> <div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?'
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div>\s+<div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?'
patronNext = r'<a href="([^"]+)" >Pagina'
# debug = True

View File

@@ -64,7 +64,7 @@ def peliculas(item):
if item.args == 'newest':
patron = r'<div id="blockvids">\s*<ul>\s*<li>\s*<a href="(?P<url>[^"]+)"[^>]+><img[^>]+src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^\[]+)\[(?P<lang>[^\]]+)\]'
else:
patron = r'<div class="span4">\s*<a href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+><\/a>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+> <h1>(?P<title>[^<\[]+)(?:\[(?P<lang>[^\]]+)\])?</h1></a>.*?-->(?:.*?<br />)?\s*(?P<plot>[^<]+)'
patron = r'<div class="span4">\s*<a href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+><\/a>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+> +<h1>(?P<title>[^<\[]+)(?:\[(?P<lang>[^\]]+)\])?</h1></a>.*?-->(?:.*?<br />)?\s*(?P<plot>[^<]+)'
patronNext = r'<link rel="next" href="([^"]+)"'
action = 'check'
return locals()
@@ -90,6 +90,7 @@ def episodios(item):
s = 1
e = 0
sp = 0
for match in item.url:
if 'stagione' in match.lower():
find_season = support.match(match, patron=r'Stagione\s*(\d+)').match
@@ -111,17 +112,17 @@ def episodios(item):
s += 1
e = ep - 1
title = str(season) + 'x' + str(ep-e).zfill(2) + ' - ' + title
data += title + '|' + match + '\n'
data += title + '|' + match + '\|'
else:
title += ' #movie'
data += title + '|' + match + '\n'
data += title + '|' + match + '\|'
def itemHook(item):
if '#movie' in item.title:
item.contentType='movie'
item.title = item.title.replace(' #movie','')
return item
patron = r'(?P<title>[^\|]+)\|(?P<url>[^\n]+)\n'
patron = r'(?P<title>[^\|]+)\|(?P<url>[^\|]+)\|'
action = 'findvideos'
return locals()

View File

@@ -76,7 +76,7 @@ def newest(categoria):
def search(item, text):
logger.info(item, "search", text)
logger.info("search", text)
if item.contentType == 'tvshow': item.url = host + '/serietv/'
else: item.url = host
try:
@@ -127,40 +127,57 @@ def peliculas(item):
@support.scrape
def episodios(item):
# support.dbg()
data = support.match(item.url, headers=headers).data
support.info(data)
if 'TUTTA LA ' in data:
folderUrl = scrapertools.find_single_match(data, r'TUTTA LA \w+\s+(?:&#8211;|-)\s+<a href="?([^" ]+)')
@support.scrape
def folder(item, data):
"""
Quando c'è un link ad una cartelle di vcrypt contenente più stagioni
"""
actLike = 'episodios'
addVideolibrary = False
downloadEnabled = False
folderUrl = scrapertools.find_single_match(data, r'TUTTA LA \w+\s+(?:&#8211;|-)\s+<a href="?([^" ]+)').replace(
'.net/', '.pw/') # vcrypt.pw non ha CF
data = httptools.downloadpage(folderUrl).data
patron = r'<a href="(?P<url>[^"]+)[^>]+>(?P<title>[^<]+)'
patron = r'><a href="(?P<url>[^"]+)[^>]+>(?P<title>[^<]+)'
sceneTitle = True
def itemHook(item):
item.serieFolder = True
return item
else:
patronBlock = r'(?P<block>sp-head[^>]+>\s*(?:STAGION[EI]\s*(?:DA\s*[0-9]+\s*A)?\s*[0-9]+|MINISERIE) - (?P<lang>[^-<]+)(?:- (?P<quality>[^-<]+))?.*?<\/div>.*?)spdiv[^>]*>'
patron = r'(?:/>|<p>|<strong>)(?P<url>.*?(?P<episode>[0-9]+(?:&#215;|×)[0-9]+)\s*(?P<title2>.*?)?(?:\s*&#8211;|\s*-|\s*<).*?)(?:<\/p>|<br)'
def itemlistHook(itemlist):
title_dict = {}
itlist = []
for item in itemlist:
item.title = re.sub(r'\.(\D)',' \\1', item.title)
match = support.match(item.title, patron=r'(\d+.\d+)').match.replace('x','')
item.order = match
if match not in title_dict:
title_dict[match] = item
elif match in title_dict and item.contentLanguage == title_dict[match].contentLanguage \
or item.contentLanguage == 'ITA' and not title_dict[match].contentLanguage \
or title_dict[match].contentLanguage == 'ITA' and not item.contentLanguage:
title_dict[match].url = item.url
else:
title_dict[match + '1'] = item
return locals()
for key, value in title_dict.items():
itlist.append(value)
# debug=True
data = support.match(item.url, headers=headers).data
folderItemlist = folder(item, data) if 'TUTTA LA ' in data else []
return sorted(itlist, key=lambda it: (it.contentLanguage, int(it.order)))
patronBlock = r'(?P<block>sp-head[^>]+>\s*(?:STAGION[EI]\s*(?:DA\s*[0-9]+\s*A)?\s*[0-9]+|MINISERIE) - (?P<lang>[^-<]+)(?:- (?P<quality>[^-<]+))?.*?<\/div>.*?)spdiv[^>]*>'
patron = r'(?:/>|<p>|<strong>)(?P<other>.*?(?P<episode>[0-9]+(?:&#215;|×)[0-9]+)\s*(?P<title2>.*?)?(?:\s*&#8211;|\s*-|\s*<).*?)(?:<\/p>|<br)'
def itemlistHook(itemlist):
title_dict = {}
itlist = []
for i in itemlist:
i.url = item.url
i.title = re.sub(r'\.(\D)',' \\1', i.title)
match = support.match(i.title, patron=r'(\d+.\d+)').match.replace('x','')
i.order = match
if match not in title_dict:
title_dict[match] = i
elif match in title_dict and i.contentLanguage == title_dict[match].contentLanguage \
or i.contentLanguage == 'ITA' and not title_dict[match].contentLanguage \
or title_dict[match].contentLanguage == 'ITA' and not i.contentLanguage:
title_dict[match].url = i.url
else:
title_dict[match + '1'] = i
for key, value in title_dict.items():
itlist.append(value)
itlist = sorted(itlist, key=lambda it: (it.contentLanguage, int(it.order)))
itlist.extend(folderItemlist)
return itlist
return locals()
@@ -172,14 +189,14 @@ def findvideos(item):
def load_links(itemlist, re_txt, desc_txt, quality=""):
streaming = scrapertools.find_single_match(data, re_txt).replace('"', '')
support.info('STREAMING', streaming)
support.info('STREAMING=', streaming)
logger.debug('STREAMING', streaming)
logger.debug('STREAMING=', streaming)
matches = support.match(streaming, patron = r'<td><a.*?href=([^ ]+) [^>]+>([^<]+)<').matches
for scrapedurl, scrapedtitle in matches:
logger.debug("##### findvideos %s ## %s ## %s ##" % (desc_txt, scrapedurl, scrapedtitle))
itemlist.append(item.clone(action="play", title=scrapedtitle, url=scrapedurl, server=scrapedtitle, quality=quality))
support.info()
logger.debug()
itemlist = []
@@ -211,34 +228,12 @@ def findvideos(item):
def findvid_serie(item):
def load_vid_series(html, item, itemlist, blktxt):
support.info('HTML',html)
# Estrae i contenuti
matches = support.match(html, patron=r'<a href=(?:")?([^ "]+)[^>]+>(?!<!--)(.*?)(?:</a>|<img)').matches
for url, server in matches:
item = item.clone(action="play", title=server, url=url, server=server, quality=blktxt)
if 'swzz' in item.url: item.url = support.swzz_get_url(item)
itemlist.append(item)
logger.debug()
data = re.sub(r'((?:<p>|<strong>)?[^\d]*\d*(?:&#215;|×)[0-9]+[^<]+)', '', item.other)
support.info()
itemlist = []
data = re.sub(r'((?:<p>|<strong>)?[^\d]*\d*(?:&#215;|×)[0-9]+[^<]+)', '' ,item.url)
# Blocks with split
blk = re.split(r"(?:>\s*)?([A-Za-z\s0-9]*):\s*<", data, re.S)
blktxt = ""
for b in blk:
if b[0:3] == "a h" or b[0:4] == "<a h":
load_vid_series("<%s>" % b, item, itemlist, blktxt)
blktxt = ""
elif len(b.strip()) > 1:
blktxt = b.strip()
return support.server(item, itemlist=itemlist)
return support.server(item, data=data)
def play(item):
support.info()
logger.debug()
return servertools.find_video_items(item, data=item.url)

View File

@@ -59,13 +59,12 @@ def peliculas(item):
patron = r'<a href="(?P<url>(?:https:\/\/.+?\/(?P<title>[^\/]+[a-zA-Z0-9\-]+)(?P<year>\d{4})))/".+?url\((?P<thumb>[^\)]+)\)">'
elif item.contentType == 'tvshow':
if item.args == 'update':
patron = r'<a href="(?P<url>[^"]+)"[^<]+?url\((?P<thumb>.+?)\)">\s<div class="titolo">(?P<title>.+?)(?: &#8211; Serie TV)?(?:\([sSuUbBiItTaA\-]+\))?[ ]?(?P<year>\d{4})?</div>[ ](?:<div class="genere">)?(?:[\w]+?\.?\s?[\s|S]?[\dx\-S]+?\s\(?(?P<lang>[iItTaA]+|[sSuUbBiItTaA\-]+)\)?\s?(?P<quality>[HD]+)?|.+?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?</div>)'
patron = r'<a href="(?P<url>[^"]+)"[^<]+?url\((?P<thumb>.+?)\)">\s+<div class="titolo">(?P<title>.+?)(?: &#8211; Serie TV)?(?:\([sSuUbBiItTaA\-]+\))?[ ]?(?P<year>\d{4})?</div>[ ](?:<div class="genere">)?(?:[\w]+?\.?\s?[\s|S]?[\dx\-S]+?\s\(?(?P<lang>[iItTaA]+|[sSuUbBiItTaA\-]+)\)?\s?(?P<quality>[HD]+)?|.+?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?</div>)'
pagination = 25
else:
patron = r'<a href="(?P<url>[^"]+)"\s*title="(?P<title>[^"\(]+)(?:"|\()(?:(?P<year>\d+)[^"]+)?.*?url\((?P<thumb>[^\)]+)\)(?:.*?<div class="voto">[^>]+>[^>]+>\s*(?P<rating>[^<]+))?.*?<div class="titolo">[^>]+>(?:<div class="genere">[^ ]*(?:\s\d+)?\s*(?:\()?(?P<lang>[^\)< ]+))?'
else:
#search
patron = r'<div class="col-lg-3">[^>]+>[^>]+>\s<a href="(?P<url>[^"]+)".+?url\((?P<thumb>[^\)]+)\)">[^>]+>[^>]+>[^>]+>(?:[^>]+>)?\s?(?P<rating>[\d\.]+)?[^>]+>(?P<title>.+?)(?:[ ]\((?P<year>\d{4})\))?<[^>]+>[^>]+>(.?[\d\-x]+\s\(?(?P<lang>[sSuUbBiItTaA\-]+)?\)?\s?(?P<quality>[\w]+)?[|]?\s?(?:[fFiInNeE]+)?\s?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?)?'
patron = r'<div class="col-lg-3">[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)".+?url\((?P<thumb>[^\)]+)\)">[^>]+>[^>]+>[^>]+>(?:[^>]+>)?\s?(?P<rating>[\d\.]+)?[^>]+>(?P<title>.+?)(?:[ ]\((?P<year>\d{4})\))?<[^>]+>[^>]+>(.?[\d\-x]+\s\(?(?P<lang>[sSuUbBiItTaA\-]+)?\)?\s?(?P<quality>[\w]+)?[|]?\s?(?:[fFiInNeE]+)?\s?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?)?'
def itemHook(item):
if 'sub' in item.contentLanguage.lower() and not 'ita' in item.contentLanguage.lower():
@@ -152,6 +151,7 @@ def newest(categoria):
return itemlist
def check(item):
support.info()
data = support.match(item.url, headers=headers).data
@@ -171,10 +171,11 @@ def check(item):
else:
item.contentType = 'movie'
item.url = data
item.data = data
return findvideos(item)
def findvideos(item):
support.info()
item.url = item.url.replace('http://rapidcrypt.net/verys/', '').replace('http://rapidcrypt.net/open/', '') #blocca la ricerca
return support.server(item, data= item.url)
item.data = item.data.replace('http://rapidcrypt.net/verys/', '').replace('http://rapidcrypt.net/open/', '') #blocca la ricerca
return support.server(item, data=item.data)

View File

@@ -89,9 +89,14 @@ def peliculas(item):
patronBlock = r'<div id="%s"[^>]+>(?P<block>.*?)<div class="vistaDettagliata"' % item.args[1]
patron = r'<li>\s*<a href="(?P<url>[^"]+)" title="(?P<title>[^"]+)" class="thumb">[^>]+>[^>]+>[^>]+>\s*[EePp]+\s*(?P<episode>\d+)[^>]+>\s<img src="(?P<thumb>[^"]+)"'
else:
patron = r'<div class="showStreaming"> <b>(?P<title>[^<]+)[^>]+>[^>]+>\s*<span>Lingua:\s*(?P<lang>[^>]+)?>[<>br\s]+a href="(?P<url>[^"]+)"[^>]+>.*?--image-url:url\(/*(?P<thumb>[^\)]+).*?Anno di inizio</b>:\s*(?P<year>[0-9]{4})'
patron = r'<div class="showStreaming"> +<b>(?P<title>[^<]+)[^>]+>[^>]+>\s*<span>Lingua:\s*(?P<lang>[^>]+)?>[<>br\s]+a href="(?P<url>[^"]+)"[^>]+>.*?--image-url:url\(/*(?P<thumb>[^\)]+).*?Anno di inizio</b>:\s*(?P<year>[0-9]{4})'
patronNext = '<li class="currentPage">[^>]+><li[^<]+<a href="([^"]+)">'
def itemHook(item):
if item.thumbnail and not item.thumbinail.startswith('http'):
item.thumbnail = 'http://' + item.thumbnail
return item
return locals()

View File

@@ -75,7 +75,7 @@ def peliculas(item):
else:
patron = r'<div class="cover-racolta">\s*<a href="(?P<url>[^"]+)"[^>]+>\s*<img width="[^"]+" height="[^"]+" src="(?P<thumb>[^"]+)".*?<p class="title[^>]+>(?P<title>[^<]+)<'
else:
patron = r'<article[^>]+>[^>]+>[^>]+>(?:<img width="[^"]+" height="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>)?.*?<a href="(?P<url>[^"]+)">\s*(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<p>(?P<plot>[^<]+)<'
patron = r'<article[^>]+>[^>]+>[^>]+>(?:<img width="[^"]+" height="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>)?.*?<a href="(?P<url>[^"]+)"[^>]*>\s*(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<p>(?P<plot>[^<]+)<'
patronNext = r'<a class="page-numbers next" href="([^"]+)">'
# select category
@@ -121,14 +121,14 @@ def episodios(item):
else:
patron = r'class="title-episodio">(?P<title>[^<]+)<(?P<url>.*?)<p'
def itemlistHook(itemlist):
counter = 0
for item in itemlist:
episode = support.match(item.title, patron=r'\d+').match
if episode == '1':
counter += 1
item.title = support.typo(str(counter) + 'x' + episode.zfill(2) + support.re.sub(r'\[[^\]]+\](?:\d+)?','',item.title),'bold')
return itemlist
# def itemlistHook(itemlist):
# counter = 0
# for item in itemlist:
# episode = support.match(item.title, patron=r'\d+').match
# if episode == '1':
# counter += 1
# item.title = support.typo(str(counter) + 'x' + episode.zfill(2) + support.re.sub(r'\[[^\]]+\](?:\d+)?','',item.title),'bold')
# return itemlist
return locals()

View File

@@ -12,7 +12,7 @@ def findhost(url):
host = 'https://'+permUrl['location'].replace('https://www.google.it/search?q=site:', '')
return host
host = support.config.get_channel_url(findhost)
host = support.config.get_channel_url()
headers = [['Referer', host]]
@support.menu

View File

@@ -25,14 +25,12 @@ host = config.get_channel_url()
headers = [['Referer', host]]
@support.menu
def mainlist(item):
Tvshow = [
('Aggiornamenti', ['', 'peliculas', '', 'update']),
('Cerca... {bold}{TV}', ['','search'])
('Aggiornamenti', ['', 'peliculas', 'update']),
('Cerca... {bold}{TV}', ['', 'search'])
]
# search = ''
@@ -46,6 +44,16 @@ def peliculas(item):
# support.dbg()
deflang = 'Sub-ITA'
# è una singola pagina con tutti gli episodi
if item.grouped and not support.scrapertools.find_single_match(item.url, '-[0-9]+x[0-9]+-'):
item.grouped = False
return episodios_args(item)
# ogni puntata è un articolo a se
if item.fulltitle:
item.url = host + '?s=' + item.fulltitle
actLike = 'episodios'
action = 'findvideos'
blacklist = ['']
if item.args == 'genres':
@@ -53,32 +61,45 @@ def peliculas(item):
patron = r'[^>]+>[^>]+>.+?href="(?P<url>[^"]+)[^>]>(?P<title>[^<]+)\s<'
action = 'episodios'
elif item.args == 'search':
patronBlock = r'</h1> </header>(?P<block>.*?)</main>'
patronMenu = r'(?:<img src="(?P<thumb>[^"]+)"[^>]+>)?[^>]+>[^>]+>[^>]+>[^>]+>[^>]+><a href="(?P<url>[^"]+)"[^>]+>(?:(?P<title>.+?)[ ](?P<episode>[\d&#;\d]+\d+|\d+..\d+)(?: \([a-zA-Z\s]+\) )(?:s\d+e\d+)?[ ]?(?:[&#\d;|.{3}]+)(?P<title2>[^&#\d;|^.{3}]+)(?:|.+?))<'
group = True
patronBlock = r'</header>(?P<block>.*?)</main>'
patron = '(?:<img[^>]+src="(?P<thumb>[^"]+)".*?)?<a href="(?P<url>[^"]+)"[^>]+>(?P<title>[^<]+?)(?:(?P<episode>\d+&#215;\d+|\d+×\d+)|\[[sS](?P<season>[0-9]+)[^]]+\])\s?(?:(?P<lang>\([a-zA-Z\s]+\)) (?:[Ss]\d+[Ee]\d+)?\s?(?:[&#\d;|.{3}]+)(?P<title2>[^”[<]+)(?:&#\d)?)?'
else:
patron = r'<div class="featured-thumb"> <a href="(?P<url>[^"]+)" title="(?:(?P<title>.+?)[ ]?(?P<episode>\d+&#215;\d+).+?&#8220;(?P<title2>.+?)&#8221;).+?">'
# è una singola pagina con tutti gli episodi
if item.args != 'update' and not support.scrapertools.find_single_match(item.url, '-[0-9]+x[0-9]+-'):
return episodios_args(item)
patron = r'<div class="featured-thumb"> +<a href="(?P<url>[^"]+)" title="(?P<title>[^[]+)\[(?P<episode>\d+&#215;\d+)?'
patronBlock = r'<main id="main"[^>]+>(?P<block>.*?)<div id="secondary'
# def itemlistHook(itemlist):
# from core import scraper
# return scraper.sort_episode_list(itemlist)
patronNext = '<a class="next page-numbers" href="(.*?)">Successivi'
#debug = True
# debug = True
return locals()
def episodios_args(item):
actLike = 'episodios'
# support.dbg()
deflang = 'Sub-ITA'
action = 'findvideos'
patron = '(?P<episode>\d+&#215;\d+|\d+[×.]+\d+)(?:\s?\((?P<lang>[a-zA-Z ]+)\))?(?:\s[Ss]\d+[Ee]+\d+)? +(?:“|&#8220;)(?P<title2>.*?)(?:”|&#8221;).*?(?P<other>.*?)(?:/>|<p)'
patronBlock = r'<main id="main" class="site-main" role="main">(?P<block>.*?)</main>'
patronNext = '<a class="next page-numbers" href="(.*?)">Successivi'
# debug = True
return locals()
@support.scrape
def episodios(item):
support.info(item)
#support.dbg()
return episodios_args(item)
deflang = 'Sub-ITA'
action = 'findvideos'
blacklist = ['']
patron = r'<div class="featured-thumb"> <a href="(?P<url>[^"]+)" title="(?:(?P<title>.+?)[ ]?(?P<episode>\d+&#215;\d+|\d+[×.]+\d+).+?&#8220;(?P<title2>.+?)&#8221;).+?">'
patronBlock = r'<main id="main" class="site-main" role="main">(?P<block>.*?)</main>'
patronNext = '<a class="next page-numbers" href="(.*?)">Successivi'
#debug = True
return locals()
@support.scrape
def genres(item):
@@ -140,38 +161,54 @@ def newest(categoria):
def findvideos(item):
support.info('findvideos ->', item)
itemlist = []
patronBlock = '<div class="entry-content">(?P<block>.*)<footer class="entry-footer">'
patron = r'<a href="([^"]+)">'
html = support.match(item, patron=patron, patronBlock=patronBlock, headers=headers)
matches = html.matches
data= html.data
if item.args != 'episodios':
item.infoLabels['mediatype'] = 'episode'
for scrapedurl in matches:
if 'is.gd' in scrapedurl:
resp = httptools.downloadpage(scrapedurl, follow_redirects=False)
data += resp.headers.get("location", "") + '\n'
itemlist = []
if item.other.startswith('http'):
resp = httptools.downloadpage(item.url, follow_redirects=False)
data = resp.headers.get("location", "") + '\n'
elif item.other:
html = support.match(item.other, patron=patron, headers=headers)
matches = html.matches
data = html.data
for scrapedurl in matches:
if 'is.gd' in scrapedurl:
resp = httptools.downloadpage(scrapedurl, follow_redirects=False)
data += resp.headers.get("location", "") + '\n'
elif not support.scrapertools.find_single_match(item.url, '-[0-9]+x[0-9]+-'):
return episodios(item)
else:
patronBlock = '<div class="entry-content">(?P<block>.*)<footer class="entry-footer">'
html = support.match(item, patron=patron, patronBlock=patronBlock, headers=headers)
matches = html.matches
data= html.data
if item.args != 'episodios':
item.infoLabels['mediatype'] = 'episode'
for scrapedurl in matches:
if 'is.gd' in scrapedurl:
resp = httptools.downloadpage(scrapedurl, follow_redirects=False)
data += resp.headers.get("location", "") + '\n'
itemlist += support.server(item, data)
data = support.match(item.url).data
patron = r'>Posted in <a href="https?://fastsubita.com/serietv/([^/]+)/(?:[^"]+)?"'
series = scrapertools.find_single_match(data, patron)
titles = support.typo(series.upper().replace('-', ' '), 'bold color kod')
goseries = support.typo("Vai alla Serie:", ' bold color kod')
itemlist.append(
item.clone(channel=item.channel,
title=goseries + titles,
fulltitle=titles,
show=series,
contentType='tvshow',
contentSerieName=series,
url=host+"/serietv/"+series,
action='episodios',
contentTitle=titles,
plot = "Vai alla Serie " + titles + " con tutte le puntate",
))
# data = support.match(item.url).data
# patron = r'>Posted in <a href="https?://fastsubita.com/serietv/([^/]+)/(?:[^"]+)?"'
# series = scrapertools.find_single_match(data, patron)
# titles = support.typo(series.upper().replace('-', ' '), 'bold color kod')
# goseries = support.typo("Vai alla Serie:", ' bold color kod')
# itemlist.append(
# item.clone(channel=item.channel,
# # title=goseries + titles,
# title=titles,
# fulltitle=titles,
# show=series,
# contentType='tvshow',
# contentSerieName=series,
# url=host+"/serietv/"+series,
# action='episodios',
# contentTitle=titles,
# plot = "Vai alla Serie " + titles + " con tutte le puntate",
# ))
return itemlist

View File

@@ -2,7 +2,7 @@
"id": "film4k",
"name": "Film4k",
"language": ["ita"],
"active": true,
"active": false,
"thumbnail": "film4k.png",
"banner": "film4k.png",
"categories": ["tvshow", "movie", "anime"],

View File

@@ -29,7 +29,7 @@ def mainlist(item):
def search(item, text):
logger.info()
logger.info('search', text)
item.url = item.url + "/?s=" + text
try:
return support.dooplay_search(item)

View File

@@ -99,7 +99,7 @@ def genres(item):
def select(item):
support.info()
patron=r'class="taxonomy category" ><span property="name">([^>]+)</span></a><meta property="position" content="2">'
patron=r'class="taxonomy category"\s*><span property="name">([^>]+)</span></a><meta property="position" content="2">'
block = support.match(item.url, patron=patron,headers=headers).match
if block.lower() != 'film':
support.info('select = ### è una serie ###')

View File

@@ -51,7 +51,7 @@ def episodios(item):
def search(item, text):
support.info('search', item)
support.info('search', text)
item.contentType = 'tvshow'
itemlist = []
text = text.replace(' ', '+')
@@ -66,5 +66,5 @@ def search(item, text):
def findvideos(item):
logger.info("[guardaserie_live] findvideos")
logger.debug()
return support.server(item, item.url)

View File

@@ -28,7 +28,7 @@ def mainlist(item):
@support.scrape
def peliculas(item):
patronBlock = r'movies-list movies-list-full(?P<block>.*?)footer>'
patron = r'<div data-movie-id[^>]+> <a href="(?P<url>[^"]+).*?<img data-original="(?P<thumbnail>[^"]+)[^>]+>[^>]+>[^>]+>(?P<title>[^<]+).*?jt-info[^>]+>[^:]+:\s*(?P<rating>[^<]+).*?rel="tag">(?P<year>\d+).*?jt-info">(?P<duration>\d+)'
patron = r'<div data-movie-id[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>[^>]+><img src="(?P<thumbnail>[^"]+)[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+).*?jt-info[^>]+>[^:]+:\s*(?P<rating>[^<]+)[^>]+>[^>]+>[^>]+>(?P<year>\d*)[^>]+>[^>]+>[^>]+>(?P<duration>\d*)'
patronNext = '<li class=.active.>.*?href=.(.*?).>'
action = 'episodios'
return locals()

View File

@@ -128,7 +128,7 @@ def search(item, text):
info(text)
itemlist = []
text = text.replace(' ', '+')
item.url = host + "/wp-json/wp/v2/search?search=" + text
item.url = host + "/wp-json/wp/v2/search?per_page=100&search=" + text
results = support.httptools.downloadpage(item.url).json
for r in results:
title = r['title']

View File

@@ -2,22 +2,11 @@
# ------------------------------------------------------------
# Canale per italiaserie
# ------------------------------------------------------------
"""
Problemi noti che non superano il test del canale:
Avvisi:
Ulteriori info:
"""
import re
from core import support, httptools, scrapertools
from core.item import Item
from platformcode import config
from platformcode import config, logger
host = config.get_channel_url()
headers = [['Referer', host]]
@@ -25,11 +14,11 @@ headers = [['Referer', host]]
@support.menu
def mainlist(item):
support.info()
tvshow = ['/category/serie-tv/',
('Aggiornamenti', ['/ultimi-episodi/', 'peliculas', 'update']),
('Generi', ['', 'category', 'Serie-Tv per Genere'])
tvshow = ['',
('Aggiornamenti', ['/aggiornamento-episodi/', 'peliculas', 'update']),
('Top 10', ['/top-10', 'peliculas', 'top']),
('Netflix {tv submenu}', ['/genere/netflix', 'peliculas']),
('A-Z', ['/lista-completa', 'peliculas', 'a-z'])
]
return locals()
@@ -37,44 +26,46 @@ def mainlist(item):
@support.scrape
def peliculas(item):
support.info()
action = 'episodios'
patron = r'<div class="post-thumb">\s*<a href="(?P<url>[^"]+)" '\
'title="(?P<title>[^"]+)">\s*<img src="(?P<thumb>[^"]+)"[^>]+>'
patron = r'<div class="post-thumb">\s*<a href="(?P<url>[^"]+)" title="(?P<title>[^"\[]+)[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>'
if item.args == 'update':
patron += r'.*?aj-eps">(?P<episode>.+?)[ ]?(?P<lang>Sub-Ita|Ita)</span>'
pagination = ''
patron = r'br />(?P<title>[^]+)[^<]+<a href="(?P<url>[^"]+)">(?P<episode>[^ ]+)\s*(?P<title2>[^\(<]+)(?:\((?P<lang>[^\)]+))??'
action = 'findvideos'
if item.args == 'top':
patron = r'<a href="(?P<url>[^"]+)">(?P<title>[^<]+)</a>[^>]+>[^>]+>[^>]+><img.*?src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>:\s*(?P<rating>[^/]+)'
if item.args =='a-z':
pagination = ''
patron = r'<li ><a href="(?P<url>[^"]+)" title="(?P<title>[^"]+)"'
patronNext = r'<a class="next page-numbers" href="(.*?)">'
## debug = True
def itemHook(item):
item.title = support.re.sub(r'<[^>]+>','', item.title)
return item
return locals()
@support.scrape
def episodios(item):
support.info()
res = support.match(item, patron=r'<a href="([^"]+)">&gt;')
if res.match: data = support.match(res.match).data
else: data = res.data
patronBlock = r'</i> Stagione (?P<block>(?P<season>\d+)</div> '\
'<div class="su-spoiler-content".*?)<div class="clearfix">'
patron = r'(?:(?P<season>\d+)?</div> <div class="su-spoiler-content"(:?.+?)?> )?'\
'<div class="su-link-ep">\s+<a.*?href="(?P<url>[^"]+)".*?strong>[ ]'\
'(?P<title>.+?)[ ](?P<episode>\d+-\d+|\d+)[ ](?:-\s+(?P<title2>.+?))?'\
'[ ]?(?:(?P<lang>Sub-ITA))?[ ]?</strong>'
patronBlock = r'(?:Stagione|STAGIONE)\s*(?P<lang>[^<]+)?(?:</p>)?(?P<block>.*?)</p>'
patron = r'(?:p>|/>)(?P<title>[^]+)(?P<data>.*?)(?:<br|$)'
#debug = True
def itemHook(item):
item.title = support.re.sub('<[^>]+>','', item.title)
return item
return locals()
@support.scrape
def category(item):
support.info()
action = 'peliculas'
patron = r'<li class="cat-item.*?href="(?P<url>[^"]+)".*?>(?P<title>.*?)</a>'
return locals()
@@ -111,41 +102,28 @@ def newest(categoria):
except:
import sys
for line in sys.exc_info():
support.info("{0}".format(line))
logger.error("{0}".format(line))
return []
return itemlist
def findvideos(item):
support.info()
logger.debug()
if item.args == 'update':
itemlist = []
item.infoLabels['mediatype'] = 'episode'
data = httptools.downloadpage(item.url, headers=headers).data
data = re.sub('\n|\t', ' ', data)
data = re.sub(r'>\s+<', '> <', data)
url_video = scrapertools.find_single_match(data, r'<a rel="[^"]+" target="[^"]+" act="[^"]+"\s+href="([^"]+)" class="[^"]+-link".+?\d+.+?</strong> </a>', -1)
url_serie = scrapertools.find_single_match(data, r'<link rel="canonical" href="([^"]+)" />')
data = support.match(item.url, headers=headers).data
url_video = support.match(data, patron=r'<a rel="[^"]+" target="[^"]+" act="[^"]+"\s+href="([^"]+)" class="[^"]+-link".+?\d+.+?</strong> </a>').matches
url_serie = support.match(data, patron=r'<link rel="canonical" href="([^"]+)" />').matches
goseries = support.typo("Vai alla Serie:", ' bold')
series = support.typo(item.contentSerieName, ' bold color kod')
itemlist = support.server(item, data=url_video)
itemlist.append(
Item(channel=item.channel,
title=goseries + series,
fulltitle=item.fulltitle,
show=item.show,
contentType='tvshow',
contentSerieName=item.contentSerieName,
url=url_serie,
action='episodios',
contentTitle=item.contentSerieName,
plot = goseries + series + "con tutte le puntate",
))
itemlist.append(item.clone(title=goseries + series, contentType='tvshow', url=url_serie, action='episodios', plot = goseries + series + "con tutte le puntate"))
return itemlist
else:
return support.server(item, data=item.url)
return support.server(item, data=item.data)

View File

@@ -87,24 +87,27 @@ def live(item):
for key in it['tuningInstruction']['urn:theplatform:tv:location:any']:
urls += key['publicUrls']
plot = support.typo(guide['currentListing']['mediasetlisting$epgTitle'],'bold') + '\n' + guide['currentListing']['mediasetlisting$shortDescription'] + '\n' + guide['currentListing']['description'] + '\n\n' + support.typo('A Seguire:' + guide['nextListing']['mediasetlisting$epgTitle'], 'bold')
itemlist.append(item.clone(title=support.typo(it['title'], 'bold'),
fulltitle=it['title'],
show=it['title'],
contentTitle=it['title'],
thumbnail=it['thumbnails']['channel_logo-100x100']['url'],
forcethumb = True,
urls=urls,
plot=plot,
action='play'))
fulltitle=it['title'],
show=it['title'],
contentTitle=it['title'],
thumbnail=it['thumbnails']['channel_logo-100x100']['url'],
forcethumb = True,
urls=urls,
plot=plot,
action='play'))
return support.thumb(itemlist, live=True)
def peliculas(item):
support.info()
itemlist = []
titlelist = []
contentType = ''
json = get_programs(item)
for it in json:
if item.search.lower() in it['title'].lower():
if item.search.lower() in it['title'].lower() and it['title'] not in titlelist:
titlelist.append(it['title'])
if item.contentType == 'movie':
action = 'findvideos'
urls = []
@@ -184,8 +187,10 @@ def episodios(item):
plot=it['longDescription'] if 'longDescription' in it else it['description'],
urls=urls,
url=it['mediasetprogram$pageUrl']))
if episode: support.videolibrary(itemlist, item)
return sorted(itemlist, key=lambda it: it.title)
if episode:
itemlist = sorted(itemlist, key=lambda it: it.title)
support.videolibrary(itemlist, item)
return itemlist
def findvideos(item):
support.info()

View File

@@ -13,7 +13,7 @@ headers = {'X-Requested-With': 'XMLHttpRequest'}
def mainlist(item):
item.url = host
action = 'peliculas'
patronBlock = r'<ul class="dropdown-menu(?P<block>.*?)</ul> </div'
patronBlock = r'<ul class="dropdown-menu(?P<block>.*?)</ul>\s*</div'
patron = r'<a href="(?P<url>[^"]+)"(?: class="")?>(?P<title>[^<]+)<'
def itemHook(item):
item.thumbnail = support.thumb('music')
@@ -24,7 +24,7 @@ def mainlist(item):
itemlist.append(
support.Item(
channel=item.channel,
title=support.typo('Cerca...', 'bold color kod'),
title=support.typo('Cerca...', 'bold'),
contentType='music',
url=item.url,
action='search',

View File

@@ -111,7 +111,7 @@ def episodios(item):
anime = True
pagination = 50
patronBlock = r'<table>(?P<block>.*?)</table>'
patron = r'<tr><td><b>(?P<title>(?:\d+)?.*?)\s*(?:(?P<episode>(?:\d+x\d+|\d+)))\s*(?P<title2>[^<]+)(?P<url>.*?)<tr>'
patron = r'<tr><td><b>(?P<title>(?:\d+)?.*?)\s*(?:(?P<episode>(?:\d+x\d+|\d+)))\s*(?P<title2>[^<]+)(?P<data>.*?)<tr>'
def itemHook(item):
clear = support.re.sub(r'\[[^\]]+\]', '', item.title)
if clear.isdigit():
@@ -121,4 +121,4 @@ def episodios(item):
def findvideos(item):
if item.contentType == 'movie': return support.server(item)
else: return support.server(item, item.url)
else: return support.server(item, item.data)

View File

@@ -29,7 +29,7 @@ def mainlist(item):
def search(item, text):
logger.info()
logger.info('search', text)
item.url = item.url + "/?s=" + text
try:
return support.dooplay_search(item)

View File

@@ -73,27 +73,28 @@ def peliculas(item):
pagination = pagination_values[support.config.get_setting('pagination','paramount')]
item.url = host + '/api/search?activeTab=' + Type + '&searchFilter=site&pageNumber=0&rowsPerPage=10000'
data = jsontools.load(support.match(item).data)['response']['items']
titles = []
for it in data:
title = it['meta']['header']['title']
support.info(title, it)
d = it['meta']['date'].split('/') if it['meta']['date'] else ['0000','00','00']
date = int(d[2] + d[1] + d[0])
if item.search.lower() in title.lower() \
and 'stagione' not in it['url'] \
and 'season' not in it['url'] \
and title not in ['Serie TV']:
itemlist.append(
item.clone(title=support.typo(title,'bold'),
action=action,
fulltitle=title,
show=title,
contentTitle=title if it['type'] == 'movie' else '',
contentSerieName=title if it['type'] != 'movie' else '',
plot= it['meta']['description'] if 'description' in it['meta'] else '',
url=host + it['url'],
date=date,
thumbnail='https:' + it['media']['image']['url'] if 'url' in it['media']['image'] else item.thumbnail))
if title not in titles:
titles.append(title)
d = it['meta']['date'].split('/') if it['meta']['date'] else ['0000','00','00']
date = int(d[2] + d[1] + d[0])
if item.search.lower() in title.lower() \
and 'stagione' not in it['url'] \
and 'season' not in it['url'] \
and title not in ['Serie TV']:
itemlist.append(
item.clone(title=support.typo(title,'bold'),
action=action,
fulltitle=title,
show=title,
contentTitle=title if it['type'] == 'movie' else '',
contentSerieName=title if it['type'] != 'movie' else '',
plot= it['meta']['description'] if 'description' in it['meta'] else '',
url=host + it['url'],
date=date,
thumbnail='https:' + it['media']['image']['url'] if 'url' in it['media']['image'] else item.thumbnail))
itemlist.sort(key=lambda item: item.fulltitle)
if not item.search:
itlist = []

View File

@@ -3,9 +3,9 @@
# Canale per Rai Play
# ------------------------------------------------------------
import requests
import requests, sys
from core import support
import sys
from platformcode import autorenumber
if sys.version_info[0] >= 3:
from concurrent import futures
else:
@@ -118,7 +118,6 @@ def replay(item):
return itemlist
def search(item, text):
# support.dbg()
support.info()
itemlist =[]
try:
@@ -224,13 +223,23 @@ def peliculas(item):
def select(item):
support.info()
itemlist = []
json = current_session.get(item.url).json()['blocks']
for key in json:
itemlist.append(item.clone(title = support.typo(key['name'],'bold'), url = key['sets'], action = 'episodios'))
if len(itemlist) == 1:
return episodios(itemlist[0])
if type(item.url) in [list, dict]:
json = item.url
else:
return itemlist
json = current_session.get(item.url).json()
if 'blocks' in json:
json = json['blocks']
season = ''
for key in json:
if item.fulltitle in key['name']: season = key['name'].replace(item.fulltitle, '').strip()
if not season.isdigit(): season = ''
itemlist.append(item.clone(title = support.typo(key['name'],'bold'), season = season, url = key['sets'], action = 'select'))
if len(itemlist) == 1:
return episodios(itemlist[0])
else:
for key in item.url:
itemlist.append(item.clone(title = support.typo(key['name'], 'bold'), url = getUrl(key['path_id']), contentType = 'tvshow', action = 'episodios'))
return itemlist
def episodios(item):
@@ -241,6 +250,8 @@ def episodios(item):
itemlist.append(item.clone(title = support.typo(key['name'], 'bold'), url = getUrl(key['path_id']), contentType = 'tvshow', action = 'episodios'))
elif type(item.url) in [list, dict]:
for key in item.url:
load_episodes(key, item)
with futures.ThreadPoolExecutor() as executor:
itlist = [executor.submit(load_episodes, key, item) for key in item.url]
for res in futures.as_completed(itlist):
@@ -254,6 +265,7 @@ def episodios(item):
itemlist = sorted(itemlist, key=lambda it: it.title)
else:
date = ''
if type(item.url) in [list, dict]: item.url = getUrl(item.url[0]['path_id'])
json = current_session.get(item.url).json()['items']
for key in json:
@@ -263,15 +275,30 @@ def episodios(item):
episode = ep[1].zfill(2)
title = support.re.sub(r'(?:St\s*\d+)?\s*Ep\s*\d+','',key['subtitle'])
title = season + 'x' + episode + (' - ' + title if not title.startswith(' ') else title if title else '')
elif item.season and support.match(item.title.lower(), patron =r'(puntate)').match:
title = key['subtitle'].strip()
if not title: title = key['name']
date = support.match(title, patron=r'(\d+/\d+/\d+)').match
if date:
date = title.split('/')
date = date[2][-2] + '/' + date[1] + '/' + date[0]
else:
title = key['subtitle'].strip()
# title = key['subtitle'].strip()
if not title:
title = key['name']
itemlist.append(item.clone(title = support.typo(title, 'bold'), action = 'findvideos', VL=True if ep else False, plot = key['description'],
fanart = getUrl(key['images']['landscape']), url = key['video_url'], contentType = 'episode'))
fanart = getUrl(key['images']['landscape']), url = key['video_url'], contentType = 'episode', date=date))
if item.season and support.match(item.title.lower(), patron =r'(puntate)').match:
itemlist = sorted(itemlist, key=lambda it: it.date)
for i, it in enumerate(itemlist):
episode = str(i + 1)
it.title = support.typo(item.season + 'x' + episode, 'bold') + (' - ' + it.title)
if itemlist and itemlist[0].VL: support.videolibrary(itemlist, item)
if itemlist and not support.match(itemlist[0].title, patron=r'[Ss]?(\d+)(?:x|_|\.|\s+)[Ee]?[Pp]?(\d+)').match:
autorenumber.start(itemlist, item)
return itemlist

View File

@@ -107,10 +107,8 @@ def episodios(item):
# for i, season in enumerate(seasons.matches):
# data += get_season(seasons.data if i == 0 else '', season[0], season[1])
import sys
if sys.version_info[0] >= 3:
from concurrent import futures
else:
from concurrent_py2 import futures
if sys.version_info[0] >= 3: from concurrent import futures
else: from concurrent_py2 import futures
with futures.ThreadPoolExecutor() as executor:
thL = []
for i, season in enumerate(seasons.matches):
@@ -118,12 +116,12 @@ def episodios(item):
for res in futures.as_completed(thL):
if res.result():
data += res.result()
patron = r'(?P<title>[^\|]+)\|(?P<url>[^\n]+)\n'
# debug = True
patron = r'(?P<season>\d+)x(?P<episode>\d+)\s*-\s*(?P<title>[^\|]+)\|(?P<url>[^ ]+)'
action = 'findvideos'
def itemlistHook(itemlist):
itemlist.sort(key=lambda item: int(support.re.sub(r'\[[^\]]+\]','',item.title).split('x')[0]))
itemlist.sort(key=lambda item: (item.infoLabels['season'], item.infoLabels['episode']))
return itemlist
return locals()

View File

@@ -25,7 +25,7 @@ def findhost(url):
host = support.match(url, patron=r'href="([^"]+)">\s*cliccando qui').matches[-1]
return host
host = config.get_channel_url(findhost)
host = config.get_channel_url()
headers = [['Referer', host]]

View File

@@ -337,7 +337,8 @@ def list_az(item):
item.clone(action="lista_serie",
data='\n\n'.join(alphabet[letter]),
title=letter,
fulltitle=letter))
fulltitle=letter,
args=''))
return itemlist

View File

@@ -4,6 +4,9 @@
# ------------------------------------------------------------
from core import support
import sys
if sys.version_info[0] >= 3: from concurrent import futures
else: from concurrent_py2 import futures
host = support.config.get_channel_url()
@@ -26,13 +29,23 @@ def mainlist(item):
return locals()
def search(item, texto):
support.info(texto)
item.args='search'
item.contentType='tvshow'
item.url = host + '/wp-json/wp/v2/search?search=' + texto
def search(item, text):
support.info(text)
# item.args='search'
item.text = text
itemlist = []
try:
return peliculas(item)
# item.url = host + '/lista-serie-tv/'
# item.contentType = 'tvshow'
# itemlist += peliculas(item)
with futures.ThreadPoolExecutor() as executor:
for par in [['/lista-serie-tv/', 'tvshow', ''],['/lista-anime-2/', 'tvshow', ''], ['/lista-anime-sub-ita/', 'tvshow', 'sub'], ['/lista-film-animazione/', 'movie', '']]:
item.url = host + par[0]
item.contentType = par[1]
item.args = par[2]
itemlist += executor.submit(peliculas, item).result()
return itemlist
# Continua la ricerca in caso di errore
except:
import sys
@@ -59,6 +72,7 @@ def newest(categoria):
@support.scrape
def peliculas(item):
search = item.text
pagination = ''
anime = True
action = 'findvideos' if item.contentType == 'movie' else 'episodios'

View File

@@ -30,7 +30,7 @@ def mainlist(item):
def search(item, text):
logger.info("[vedohd.py] " + item.url + " search " + text)
logger.info("search",text)
item.url = item.url + "/?s=" + text
return support.dooplay_search(item, blacklist)
@@ -44,7 +44,6 @@ def findvideos(item):
itemlist = []
for link in support.dooplay_get_links(item, host):
if link['title'] != 'Trailer':
logger.info(link['title'])
server, quality = scrapertools.find_single_match(link['title'], '([^ ]+) ?(HD|3D)?')
if quality:
title = server + " [COLOR blue][" + quality + "][/COLOR]"
@@ -63,7 +62,7 @@ def menu(item):
def play(item):
logger.info("[vedohd.py] play")
logger.debug()
data = support.swzz_get_url(item)

View File

@@ -4,19 +4,21 @@
# ----------------------------------------------------------
import requests, sys
from core import support, tmdb
from platformcode import autorenumber
from platformcode import autorenumber, logger
host = support.config.get_channel_url()
# Creating persistent session
current_session = requests.Session()
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0'}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'}
# Getting conn_id token from vvvvid and creating payload
login_page = host + '/user/login'
try:
conn_id = current_session.get(login_page, headers=headers).json()['data']['conn_id']
res = current_session.get(login_page, headers=headers)
conn_id = res.json()['data']['conn_id']
payload = {'conn_id': conn_id}
headers = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14', 'Cookie': res.headers['set-cookie']}
except:
conn_id = ''
@@ -126,7 +128,7 @@ def peliculas(item):
if 'category' in item.args:
support.thumb(itemlist,genre=True)
elif not 'filter' in item.args:
if item.contentType != 'movie': autorenumber.renumber(itemlist)
if item.contentType != 'movie': autorenumber.start(itemlist)
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
return itemlist
@@ -165,10 +167,10 @@ def episodios(item):
if type(title) == tuple: title = title[0]
itemlist.append(
item.clone(title = title,
url= host + show_id + '/season/' + str(key['season_id']) + '/',
url= host + show_id + '/season/' + str(key['season_id']),
action= 'findvideos',
video_id= key['video_id']))
autorenumber.renumber(itemlist, item, 'bold')
autorenumber.start(itemlist, item)
if autorenumber.check(item) == True \
or support.match(itemlist[0].title, patron=r"(\d+x\d+)").match:
support.videolibrary(itemlist,item)
@@ -181,11 +183,12 @@ def findvideos(item):
json_file = current_session.get(item.url, headers=headers, params=payload).json()
item.url = host + str(json_file['data'][0]['show_id']) + '/season/' + str(json_file['data'][0]['episodes'][0]['season_id']) + '/'
item.video_id = json_file['data'][0]['episodes'][0]['video_id']
logger.info('url=',item.url)
json_file = current_session.get(item.url, headers=headers, params=payload).json()
for episode in json_file['data']:
logger.info(episode)
if episode['video_id'] == item.video_id:
url = vvvvid_decoder.dec_ei(episode['embed_info'] or episode['embed_info'])
url = vvvvid_decoder.dec_ei(episode['embed_info'] or episode['embed_info_sd'])
if 'youtube' in url: item.url = url
item.url = url.replace('manifest.f4m','master.m3u8').replace('http://','https://').replace('/z/','/i/')
if 'https' not in item.url:

View File

@@ -14,15 +14,15 @@ YOUTUBE_V3_API_KEY = "AIzaSyCjsmBT0JZy1RT-PLwB-Zkfba87sa2inyI"
def youtube_api_call(method, parameters):
logger.info("method=" + method + ", parameters=" + repr(parameters))
logger.debug("method=" + method + ", parameters=" + repr(parameters))
encoded_parameters = urllib.urlencode(parameters)
url = "https://www.googleapis.com/youtube/v3/" + method + "?" + encoded_parameters + "&key=" + YOUTUBE_V3_API_KEY;
logger.info("url=" + url)
logger.debug("url=" + url)
data = httptools.downloadpage(url).data
logger.info("data=" + data)
logger.debug("data=" + data)
json_object = jsontools.load(data)
@@ -51,13 +51,13 @@ def youtube_get_playlist_items(playlist_id, pageToken=""):
# Show all YouTube playlists for the selected channel
def playlists(item, channel_id, pageToken=""):
logger.info()
logger.debug()
itemlist = []
json_object = youtube_get_user_playlists(channel_id, pageToken)
for entry in json_object["items"]:
logger.info("entry=" + repr(entry))
logger.debug("entry=" + repr(entry))
title = entry["snippet"]["title"]
plot = entry["snippet"]["description"]
@@ -85,13 +85,13 @@ def latest_videos(item, channel_id):
# Show all YouTube videos for the selected playlist
def videos(item, pageToken=""):
logger.info()
logger.debug()
itemlist = []
json_object = youtube_get_playlist_items(item.url, pageToken)
for entry in json_object["items"]:
logger.info("entry=" + repr(entry))
logger.debug("entry=" + repr(entry))
title = entry["snippet"]["title"]
plot = entry["snippet"]["description"]

View File

@@ -9,7 +9,7 @@ downloadenabled = addon.getSetting('downloadenabled')
def getmainlist(view="thumb_"):
logger.info()
logger.debug()
itemlist = list()
if config.dev_mode():
@@ -62,14 +62,14 @@ def getmainlist(view="thumb_"):
def getchanneltypes(view="thumb_"):
logger.info()
logger.debug()
# Category List
channel_types = ["movie", "tvshow", "anime", "documentary", "vos", "live", "torrent", "music"] #, "direct"
# Channel Language
channel_language = auto_filter()
logger.info("channel_language=%s" % channel_language)
logger.debug("channel_language=%s" % channel_language)
# Build Itemlist
itemlist = list()
@@ -92,7 +92,7 @@ def getchanneltypes(view="thumb_"):
def filterchannels(category, view="thumb_"):
from core import channeltools
logger.info('Filter Channels ' + category)
logger.debug('Filter Channels ' + category)
channelslist = []
@@ -103,14 +103,14 @@ def filterchannels(category, view="thumb_"):
appenddisabledchannels = True
channel_path = os.path.join(config.get_runtime_path(), 'channels', '*.json')
logger.info("channel_path = %s" % channel_path)
logger.debug("channel_path = %s" % channel_path)
channel_files = glob.glob(channel_path)
logger.info("channel_files found %s" % (len(channel_files)))
logger.debug("channel_files found %s" % (len(channel_files)))
# Channel Language
channel_language = auto_filter()
logger.info("channel_language=%s" % channel_language)
logger.debug("channel_language=%s" % channel_language)
for channel_path in channel_files:
logger.debug("channel in for = %s" % channel_path)
@@ -221,7 +221,7 @@ def get_thumb(thumb_name, view="thumb_"):
def set_channel_info(parameters):
logger.info()
logger.debug()
info = ''
language = ''

View File

@@ -29,7 +29,7 @@ def start(itemlist, item):
if item.global_search:
return itemlist
logger.info()
logger.debug()
global PLAYED
PLAYED = False
@@ -274,7 +274,7 @@ def start(itemlist, item):
def play_multi_channel(item, itemlist):
logger.info()
logger.debug()
start(itemlist, item)

View File

@@ -15,7 +15,7 @@ default_file = dict()
remote_path = 'https://raw.githubusercontent.com/kodiondemand/media/master/'
def is_enabled(channel_name):
logger.info("channel_name=" + channel_name)
logger.debug("channel_name=" + channel_name)
return get_channel_parameters(channel_name)["active"] and get_channel_setting("enabled", channel=channel_name,
default=True)
@@ -27,7 +27,7 @@ def get_channel_parameters(channel_name):
if channel_name not in dict_channels_parameters:
try:
channel_parameters = get_channel_json(channel_name)
# logger.debug(channel_parameters)
logger.debug(channel_parameters)
if channel_parameters:
# name and default changes
channel_parameters["title"] = channel_parameters.pop("name") + (' [DEPRECATED]' if 'deprecated' in channel_parameters and channel_parameters['deprecated'] else '')
@@ -87,7 +87,7 @@ def get_channel_parameters(channel_name):
def get_channel_json(channel_name):
# logger.info("channel_name=" + channel_name)
logger.debug("channel_name=" + channel_name)
from core import filetools
channel_json = None
try:
@@ -101,9 +101,9 @@ def get_channel_json(channel_name):
channel_name + ".json")
if filetools.isfile(channel_path):
# logger.info("channel_data=" + channel_path)
logger.debug("channel_data=" + channel_path)
channel_json = jsontools.load(filetools.read(channel_path))
# logger.info("channel_json= %s" % channel_json)
logger.debug("channel_json= %s" % channel_json)
except Exception as ex:
template = "An exception of type %s occured. Arguments:\n%r"
@@ -114,7 +114,7 @@ def get_channel_json(channel_name):
def get_channel_controls_settings(channel_name):
# logger.info("channel_name=" + channel_name)
logger.debug("channel_name=" + channel_name)
dict_settings = {}
# import web_pdb; web_pdb.set_trace()
# list_controls = get_channel_json(channel_name).get('settings', list())
@@ -137,7 +137,7 @@ def get_lang(channel_name):
if hasattr(channel, 'list_language'):
for language in channel.list_language:
list_language.append(language)
logger.info(list_language)
logger.debug(list_language)
else:
sub = False
langs = []

View File

@@ -253,7 +253,7 @@ class Downloader(object):
self.file.seek(2 ** 31, 0)
except OverflowError:
self._seekable = False
logger.info("Cannot do seek() or tell() in files larger than 2GB")
logger.error("Cannot do seek() or tell() in files larger than 2GB")
self.__get_download_info__()

View File

@@ -8,7 +8,6 @@ from __future__ import division
# from builtins import str
import io
from future.builtins import range
from past.utils import old_div
import sys
PY3 = False
@@ -814,7 +813,7 @@ def remove_tags(title):
@rtype: str
@return: string without tags
"""
logger.info()
logger.debug()
title_without_tags = scrapertools.find_single_match(title, r'\[color .+?\](.+)\[\/color\]')
@@ -832,7 +831,7 @@ def remove_smb_credential(path):
@return: chain without credentials
@rtype: str
"""
logger.info()
logger.debug()
if not scrapertools.find_single_match(path, r'(^\w+:\/\/)'):
return path

View File

@@ -234,7 +234,7 @@ def get_link(list_item, item, list_language, list_quality=None, global_filter_la
@return: Item list
@rtype: list[Item]
"""
logger.info()
logger.debug()
# if the required fields are None we leave
if list_item is None or item is None:
@@ -274,7 +274,7 @@ def get_links(list_item, item, list_language, list_quality=None, global_filter_l
@return: lista de Item
@rtype: list[Item]
"""
logger.info()
logger.debug()
# if the required fields are None we leave
@@ -362,7 +362,7 @@ def no_filter(item):
@return: lista de enlaces
@rtype: list[Item]
"""
logger.info()
logger.debug()
itemlist = []
for i in item.list_item_all:
@@ -384,7 +384,7 @@ def mainlist(channel, list_language, list_quality):
@return: Item list
@rtype: list[Item]
"""
logger.info()
logger.debug()
itemlist = []
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_FILTER)
@@ -425,8 +425,8 @@ def config_item(item):
@param item: item
@type item: Item
"""
logger.info()
logger.info("item %s" % item.tostring())
logger.debug()
logger.debug("item %s" % item.tostring())
# WE GET THE JSON DATA
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
@@ -448,8 +448,8 @@ def config_item(item):
else:
lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, default_lang)
list_quality = dict_series.get(tvshow, {}).get(TAG_QUALITY_ALLOWED, [x.lower() for x in item.list_quality])
# logger.info("lang selected {}".format(lang_selected))
# logger.info("list quality {}".format(list_quality))
# logger.debug("lang selected {}".format(lang_selected))
# logger.debug("list quality {}".format(list_quality))
active = True
custom_button = {'visible': False}
@@ -516,7 +516,7 @@ def config_item(item):
def delete(item, dict_values):
logger.info()
logger.debug()
if item:
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
@@ -554,7 +554,7 @@ def save(item, dict_data_saved):
@param dict_data_saved: dictionary with saved data
@type dict_data_saved: dict
"""
logger.info()
logger.debug()
if item and dict_data_saved:
logger.debug('item: %s\ndatos: %s' % (item.tostring(), dict_data_saved))
@@ -564,7 +564,7 @@ def save(item, dict_data_saved):
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
logger.info("Data is updated")
logger.debug("Data is updated")
list_quality = []
for _id, value in list(dict_data_saved.items()):
@@ -599,7 +599,7 @@ def save_from_context(item):
@param item: item
@type item: item
"""
logger.info()
logger.debug()
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_FILTER)
tvshow = item.show.strip().lower()
@@ -630,7 +630,7 @@ def delete_from_context(item):
@param item: item
@type item: item
"""
logger.info()
logger.debug()
# We come from get_links and no result has been obtained, in context menu and we delete
if item.to_channel != "":

View File

@@ -449,7 +449,7 @@ def downloadpage(url, **opt):
if not 'api.themoviedb' in url and not opt.get('alfa_s', False):
show_infobox(info_dict)
if not config.get_setting("debug"): logger.info('Page URL:',url)
return type('HTTPResponse', (), response)
def fill_fields_pre(url, opt, proxy_data, file_name):

View File

@@ -11,22 +11,22 @@ from inspect import stack
try:
import json
except:
logger.info("json included in the interpreter **NOT** available")
logger.error("json included in the interpreter **NOT** available")
try:
import simplejson as json
except:
logger.info("simplejson included in the interpreter **NOT** available")
logger.error("simplejson included in the interpreter **NOT** available")
try:
from lib import simplejson as json
except:
logger.info("simplejson in lib directory **NOT** available")
logger.error("simplejson in lib directory **NOT** available")
logger.error("A valid JSON parser was not found")
json = None
else:
logger.info("Using simplejson in the lib directory")
else:
logger.info("Using simplejson included in the interpreter")
logger.error("Using simplejson included in the interpreter")
# ~ else:
# ~ logger.info("Usando json incluido en el interprete")

View File

@@ -21,6 +21,7 @@ def find_and_set_infoLabels(item):
:param item:
:return: Boolean indicating if the 'code' could be found
"""
# from core.support import dbg;dbg()
global scraper
scraper = None
# logger.debug("item:\n" + item.tostring('\n'))
@@ -32,7 +33,7 @@ def find_and_set_infoLabels(item):
# Get the default Scraper of the configuration according to the content type
if item.contentType == "movie":
scraper_actual = ['tmdb'][config.get_setting("scraper_movies", "videolibrary")]
tipo_contenido = config.get_localized_string(70283)
tipo_contenido = "movie"
title = item.contentTitle
# Complete list of options for this type of content
list_opciones_cuadro.append(scrapers_disponibles['tmdb'])
@@ -61,7 +62,7 @@ def find_and_set_infoLabels(item):
# Check if there is a 'code'
if scraper_result and item.infoLabels['code']:
# correct code
logger.info("Identificador encontrado: %s" % item.infoLabels['code'])
logger.debug("Identificador encontrado: %s" % item.infoLabels['code'])
scraper.completar_codigos(item)
return True
elif scraper_result:
@@ -71,57 +72,18 @@ def find_and_set_infoLabels(item):
# Content not found
msg = config.get_localized_string(60228) % title
logger.info(msg)
logger.debug(msg)
# Show box with other options:
if scrapers_disponibles[scraper_actual] in list_opciones_cuadro:
list_opciones_cuadro.remove(scrapers_disponibles[scraper_actual])
index = platformtools.dialog_select(msg, list_opciones_cuadro)
if index < 0:
item = platformtools.dialog_info(item, scraper_actual)
if item.exit:
logger.debug("You have clicked 'cancel' in the window '%s'" % msg)
return False
elif index == 0:
# Ask the title
title = platformtools.dialog_input(title, config.get_localized_string(60229) % tipo_contenido)
if title:
if item.contentType == "movie":
item.contentTitle = title
else:
item.contentSerieName = title
else:
logger.debug("I clicked 'cancel' in the window 'Enter the correct name'")
return False
elif index == 1:
# You have to create a dialog box to enter the data
logger.info("Complete information")
if cuadro_completar(item):
# correct code
logger.info("Identifier found: %s" % str(item.infoLabels['code']))
return True
# raise
elif list_opciones_cuadro[index] in list(scrapers_disponibles.values()):
# Get the name of the scraper module
for k, v in list(scrapers_disponibles.items()):
if list_opciones_cuadro[index] == v:
if scrapers_disponibles[scraper_actual] not in list_opciones_cuadro:
list_opciones_cuadro.append(scrapers_disponibles[scraper_actual])
# We import the scraper k
scraper_actual = k
try:
scraper = None
scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual])
except ImportError:
exec("import core." + scraper_actual + " as scraper_module")
break
logger.error("Error importing the scraper module %s" % scraper_actual)
def cuadro_completar(item):
logger.info()
logger.debug()
global dict_default
dict_default = {}
@@ -234,7 +196,7 @@ def get_nfo(item):
@rtype: str
@return:
"""
logger.info()
logger.debug()
if "infoLabels" in item and "noscrap_id" in item.infoLabels:
# Create the xml file with the data obtained from the item since there is no active scraper
info_nfo = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'

View File

@@ -34,7 +34,7 @@ from platformcode import logger
def printMatches(matches):
i = 0
for match in matches:
logger.info("%d %s" % (i, match))
logger.debug("%d %s" % (i, match))
i = i + 1
@@ -447,7 +447,7 @@ def get_season_and_episode(title):
except:
pass
logger.info("'" + title + "' -> '" + filename + "'")
logger.debug("'" + title + "' -> '" + filename + "'")
return filename

View File

@@ -47,7 +47,7 @@ def find_video_items(item=None, data=None):
@return: returns the itemlist with the results
@rtype: list
"""
logger.info()
logger.debug()
itemlist = []
# Download the page
@@ -97,7 +97,7 @@ def get_servers_itemlist(itemlist, fnc=None, sort=False):
# Walk the patterns
for pattern in server_parameters.get("find_videos", {}).get("patterns", []):
logger.info(pattern["pattern"])
logger.debug(pattern["pattern"])
# Scroll through the results
for match in re.compile(pattern["pattern"], re.DOTALL).finditer(
"\n".join([item.url.split('|')[0] for item in itemlist if not item.server])):
@@ -144,7 +144,7 @@ def findvideos(data, skip=False):
return some link. It can also be an integer greater than 1, which would represent the maximum number of links to search.
:return:
"""
logger.info()
logger.debug()
devuelve = []
skip = int(skip)
servers_list = list(get_servers_list().keys())
@@ -181,7 +181,7 @@ def findvideosbyserver(data, serverid):
value = translate_server_name(server_parameters["name"]) , url, serverid, server_parameters.get("thumbnail", "")
if value not in devuelve and url not in server_parameters["find_videos"].get("ignore_urls", []):
devuelve.append(value)
logger.info(msg)
logger.debug(msg)
return devuelve
@@ -193,7 +193,7 @@ def guess_server_thumbnail(serverid):
def get_server_from_url(url):
logger.info()
logger.debug()
servers_list = list(get_servers_list().keys())
# Run findvideos on each active server
@@ -211,7 +211,7 @@ def get_server_from_url(url):
for n, pattern in enumerate(server_parameters["find_videos"].get("patterns", [])):
msg = "%s\npattern: %s" % (serverid, pattern["pattern"])
if not "pattern_compiled" in pattern:
# logger.info('compiled ' + serverid)
# logger.debug('compiled ' + serverid)
pattern["pattern_compiled"] = re.compile(pattern["pattern"])
dict_servers_parameters[serverid]["find_videos"]["patterns"][n]["pattern_compiled"] = pattern["pattern_compiled"]
# Scroll through the results
@@ -224,7 +224,7 @@ def get_server_from_url(url):
msg += "\nurl encontrada: %s" % url
value = translate_server_name(server_parameters["name"]), url, serverid, server_parameters.get("thumbnail", "")
if url not in server_parameters["find_videos"].get("ignore_urls", []):
logger.info(msg)
logger.debug(msg)
return value
return None
@@ -353,7 +353,7 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
video_urls.extend(response)
except:
logger.error("Error getting url in free mode")
error_messages.append(config.get_localized_string(60006) % server_name)
error_messages.append(config.get_localized_string(60014))
import traceback
logger.error(traceback.format_exc())
@@ -370,10 +370,10 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
elif response and response[0][0]:
error_messages.append(response[0][0])
else:
error_messages.append(config.get_localized_string(60006) % server_name)
error_messages.append(config.get_localized_string(60014))
except:
logger.error("Server errorr: %s" % opcion)
error_messages.append(config.get_localized_string(60006) % server_name)
error_messages.append(config.get_localized_string(60014))
import traceback
logger.error(traceback.format_exc())
@@ -394,7 +394,7 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
# If we do not have urls or error messages, we put a generic one
elif not video_urls and not error_messages:
error_messages.append(config.get_localized_string(60006) % get_server_parameters(server)["name"])
error_messages.append(config.get_localized_string(60014))
return video_urls, len(video_urls) > 0, "<br/>".join(error_messages)
@@ -478,6 +478,7 @@ def get_server_parameters(server):
if server not in dict_servers_parameters:
try:
path = ''
# Servers
if filetools.isfile(filetools.join(config.get_runtime_path(), "servers", server + ".json")):
path = filetools.join(config.get_runtime_path(), "servers", server + ".json")
@@ -489,6 +490,8 @@ def get_server_parameters(server):
# When the server is not well defined in the channel (there is no connector), it shows an error because there is no "path" and the channel has to be checked
dict_server = jsontools.load(filetools.read(path))
dict_server["name"] = translate_server_name(dict_server["name"])
# Images: url and local files are allowed inside "resources / images"
if dict_server.get("thumbnail") and "://" not in dict_server["thumbnail"]:
dict_server["thumbnail"] = filetools.join(config.get_runtime_path(), "resources", "media",
@@ -614,7 +617,7 @@ def get_server_setting(name, server, default=None):
dict_file['settings'] = dict_settings
# We create the file ../settings/channel_data.json
if not filetools.write(file_settings, jsontools.dump(dict_file)):
logger.info("ERROR saving file: %s" % file_settings)
logger.error("ERROR saving file: %s" % file_settings)
# We return the value of the local parameter 'name' if it exists, if default is not returned
return dict_settings.get(name, default)
@@ -636,7 +639,7 @@ def set_server_setting(name, value, server):
dict_file = jsontools.load(filetools.read(file_settings))
dict_settings = dict_file.get('settings', {})
except EnvironmentError:
logger.info("ERROR when reading the file: %s" % file_settings)
logger.error("ERROR when reading the file: %s" % file_settings)
dict_settings[name] = value
@@ -648,7 +651,7 @@ def set_server_setting(name, value, server):
# We create the file ../settings/channel_data.json
if not filetools.write(file_settings, jsontools.dump(dict_file)):
logger.info("ERROR saving file: %s" % file_settings)
logger.error("ERROR saving file: %s" % file_settings)
return None
return value
@@ -750,7 +753,7 @@ def check_video_link(item, timeout=3):
server_module = __import__('servers.%s' % server, None, None, ["servers.%s" % server])
except:
server_module = None
logger.info("[check_video_link] Cannot import server! %s" % server)
logger.error("[check_video_link] Cannot import server! %s" % server)
return item, NK
if hasattr(server_module, 'test_video_exists'):
@@ -760,20 +763,20 @@ def check_video_link(item, timeout=3):
try:
video_exists, message = server_module.test_video_exists(page_url=url)
if not video_exists:
logger.info("[check_video_link] Does not exist! %s %s %s" % (message, server, url))
logger.error("[check_video_link] Does not exist! %s %s %s" % (message, server, url))
resultado = KO
else:
logger.info("[check_video_link] check ok %s %s" % (server, url))
logger.debug("[check_video_link] check ok %s %s" % (server, url))
resultado = OK
except:
logger.info("[check_video_link] Can't check now! %s %s" % (server, url))
logger.error("[check_video_link] Can't check now! %s %s" % (server, url))
resultado = NK
finally:
httptools.HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT = ant_timeout # Restore download time
return item, resultado
logger.info("[check_video_link] There is no test_video_exists for server: %s" % server)
logger.debug("[check_video_link] There is no test_video_exists for server: %s" % server)
return item, NK
def translate_server_name(name):

View File

@@ -17,7 +17,7 @@ else:
from urllib import urlencode
from time import time
from core import httptools, scrapertools, servertools, tmdb, channeltools, autoplay
from core import httptools, scrapertools, servertools, tmdb, channeltools, autoplay, scraper
from core.item import Item
from lib import unshortenit
from platformcode import config
@@ -33,7 +33,7 @@ def hdpass_get_servers(item):
for mir_url, srv in scrapertools.find_multiple_matches(mir, patron_option):
mir_url = scrapertools.decodeHtmlentities(mir_url)
info(mir_url)
logger.debug(mir_url)
it = item.clone(action="play", quality=quality, title=srv, server=srv, url= mir_url)
if not servertools.get_server_parameters(srv.lower()): it = hdpass_get_url(it)[0] # do not exists or it's empty
ret.append(it)
@@ -143,12 +143,16 @@ def scrapeLang(scraped, lang, longtitle):
if language: longtitle += typo(language, '_ [] color kod')
return language, longtitle
def cleantitle(title):
if type(title) != str: title.decode('UTF-8')
title = scrapertools.decodeHtmlentities(title)
cleantitle = title.replace('"', "'").replace('×', 'x').replace('', '-').strip()
cleantitle = ''
if title:
if type(title) != str: title.decode('UTF-8')
title = scrapertools.decodeHtmlentities(title)
cleantitle = title.replace('"', "'").replace('×', 'x').replace('', '-').strip()
return cleantitle
def unifyEp(ep):
# ep = re.sub(r'\s-\s|-|&#8211;|&#215;|×', 'x', scraped['episode'])
ep = ep.replace('-', 'x')
@@ -157,7 +161,8 @@ def unifyEp(ep):
ep = ep.replace('×', 'x')
return ep
def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, typeContentDict, typeActionDict, blacklist, search, pag, function, lang, sceneTitle):
def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, typeContentDict, typeActionDict, blacklist, search, pag, function, lang, sceneTitle, group):
itemlist = []
if debug:
regexDbg(item, patron, headers, block)
@@ -184,6 +189,8 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
# AVVERTENZE: Se il titolo è trovato nella ricerca TMDB/TVDB/Altro allora le locandine e altre info non saranno quelle recuperate nel sito.!!!!
stagione = '' # per quei siti che hanno la stagione nel blocco ma non nelle puntate
contents = []
for i, match in enumerate(matches):
if pagination and (pag - 1) * pagination > i and not search: continue # pagination
if pagination and i >= pag * pagination and not search: break # pagination
@@ -207,45 +214,52 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
val = domain + val
scraped[kk] = val.strip() if type(val) == str else val
if scraped['season']:
stagione = scraped['season']
ep = unifyEp(scraped['episode'])
if 'x' in ep:
episode = ep.split('x')[0].strip()
second_episode = ep.split('x')[1].strip()
episode = ''
if not group or item.grouped:
if scraped['season'] and scraped['episode']:
stagione = scraped['season']
ep = unifyEp(scraped['episode'])
if 'x' in ep:
episode = ep.split('x')[0].strip()
second_episode = ep.split('x')[1].strip()
else:
episode = ep
second_episode = ''
item.infoLabels['season'] = int(scraped['season'])
item.infoLabels['episode'] = int(episode)
episode = str(int(scraped['season'])) +'x'+ str(int(episode)).zfill(2) + ('x' + str(int(second_episode)).zfill(2) if second_episode else '')
elif item.season:
item.infoLabels['season'] = int(item.season)
item.infoLabels['episode'] = int(scrapertools.find_single_match(scraped['episode'], r'(\d+)'))
episode = item.season +'x'+ scraped['episode']
elif item.contentType == 'tvshow' and (scraped['episode'] == '' and scraped['season'] == '' and stagione == ''):
item.news = 'season_completed'
episode = ''
else:
episode = ep
second_episode = ''
item.infoLabels['season'] = int(scraped['season'])
item.infoLabels['episode'] = int(episode)
episode = str(int(scraped['season'])) +'x'+ str(int(episode)).zfill(2) + ('x' + str(int(second_episode)).zfill(2) if second_episode else '')
elif item.season:
item.infoLabels['season'] = int(item.season)
item.infoLabels['episode'] = int(scrapertools.find_single_match(scraped['episode'], r'(\d+)'))
episode = item.season +'x'+ scraped['episode']
elif item.contentType == 'tvshow' and (scraped['episode'] == '' and scraped['season'] == '' and stagione == ''):
item.news = 'season_completed'
episode = ''
else:
episode = unifyEp(scraped['episode']) if scraped['episode'] else ''
try:
if 'x' in episode:
ep = episode.split('x')
episode = str(int(ep[0])).zfill(1) + 'x' + str(int(ep[1])).zfill(2)
item.infoLabels['season'] = int(ep[0])
item.infoLabels['episode'] = int(ep[1])
second_episode = scrapertools.find_single_match(episode, r'x\d+x(\d+)')
if second_episode: episode = re.sub(r'(\d+x\d+)x\d+',r'\1-', episode) + second_episode.zfill(2)
except:
logger.debug('invalid episode: ' + episode)
pass
episode = unifyEp(scraped['episode']) if scraped['episode'] else ''
try:
if 'x' in episode:
ep = episode.split('x')
episode = str(int(ep[0])).zfill(1) + 'x' + str(int(ep[1])).zfill(2)
item.infoLabels['season'] = int(ep[0])
item.infoLabels['episode'] = int(ep[1])
second_episode = scrapertools.find_single_match(episode, r'x\d+x(\d+)')
if second_episode: episode = re.sub(r'(\d+x\d+)x\d+',r'\1-', episode) + second_episode.zfill(2)
except:
logger.debug('invalid episode: ' + episode)
pass
#episode = re.sub(r'\s-\s|-|x|&#8211|&#215;', 'x', scraped['episode']) if scraped['episode'] else ''
title = cleantitle(scraped['title']) if scraped['title'] else ''
title2 = cleantitle(scraped['title2']) if scraped['title2'] else ''
quality = scraped['quality'].strip() if scraped['quality'] else ''
Type = scraped['type'] if scraped['type'] else ''
plot = cleantitle(scraped["plot"]) if scraped["plot"] else ''
title = cleantitle(scraped.get('title', ''))
if group and scraped.get('title', '') in contents and not item.grouped: # same title and grouping enabled
continue
if item.grouped and scraped.get('title', '') != item.fulltitle: # inside a group different tvshow should not be included
continue
contents.append(title)
title2 = cleantitle(scraped.get('title2', '')) if not group or item.grouped else ''
quality = scraped.get('quality', '')
# Type = scraped['type'] if scraped['type'] else ''
plot = cleantitle(scraped.get("plot", ''))
# if title is set, probably this is a list of episodes or video sources
# necessaria l'aggiunta di == scraped["title"] altrimenti non prende i gruppi dopo le categorie
@@ -339,7 +353,8 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
AC = name
break
else: AC = action
if (scraped["title"] not in blacklist) and (search.lower() in longtitle.lower()):
if (not scraped['title'] or scraped["title"] not in blacklist) and (search.lower() in longtitle.lower()):
contentType = 'episode' if function == 'episodios' else CT if CT else item.contentType
it = Item(
channel=item.channel,
@@ -349,17 +364,20 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
fulltitle=item.fulltitle if function == 'episodios' else title,
show=item.show if function == 'episodios' else title,
quality=quality,
url=scraped["url"],
url=scraped["url"] if scraped["url"] else item.url,
infoLabels=infolabels,
thumbnail=item.thumbnail if not scraped["thumb"] else scraped["thumb"],
thumbnail=item.prevthumb if item.prevthumb else item.thumbnail if not scraped["thumb"] else scraped["thumb"],
args=item.args,
contentSerieName= title if 'movie' not in [contentType] and function != 'episodios' else item.contentSerieName,
contentTitle= title if 'movie' in [contentType] and function == 'peliculas' else item.contentTitle,
contentLanguage = lang1,
contentEpisodeNumber=episode if episode else '',
news= item.news if item.news else '',
other = scraped['other'] if scraped['other'] else ''
other = scraped['other'] if scraped['other'] else '',
grouped=group
)
if scraped['episode'] and group and not item.grouped: # some adjustment for grouping feature
it.action = function
# for lg in list(set(listGroups).difference(known_keys)):
# it.__setattr__(lg, match[listGroups.index(lg)])
@@ -367,38 +385,24 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
it.__setattr__(lg, match[lg])
if 'itemHook' in args:
it = args['itemHook'](it)
try:
it = args['itemHook'](it)
except:
raise logger.ChannelScraperException
itemlist.append(it)
return itemlist, matches
def scrape(func):
# args is a dict containing the foolowing keys:
# patron: the patron to use for scraping page, all capturing group must match with listGroups
# listGroups: a list containing the scraping info obtained by your patron, in order
# accepted values are: url, title, thumb, quality, year, plot, duration, genre, rating, episode, lang
def html_uniform(data):
"""
replace all ' with " and eliminate newline, so we don't need to worry about
"""
return re.sub("='([^']+)'", '="\\1"', data.replace('\n', ' ').replace('\t', ' ').replace('&nbsp;', ' '))
# headers: values to pass to request header
# blacklist: titles that you want to exclude(service articles for example)
# data: if you want to pass data manually, maybe because you need some custom replacement
# patronBlock: patron to get parts of the page (to scrape with patron attribute),
# if you need a "block inside another block" you can create a list, please note that all matches
# will be packed as string
# patronNext: patron for scraping next page link
# action: if you want results perform an action different from "findvideos", useful when scraping film by genres
# addVideolibrary: if "add to videolibrary" should appear
# example usage:
# import support
# itemlist = []
# patron = 'blablabla'
# headers = [['Referer', host]]
# blacklist = 'Request a TV serie!'
# return support.scrape(item, itemlist, patron, ['thumb', 'quality', 'url', 'title', 'year', 'plot', 'episode', 'lang'],
# headers=headers, blacklist=blacklist)
# 'type' is a check for typologies of content e.g. Film or TV Series
# 'episode' is a key to grab episode numbers if it is separated from the title
# IMPORTANT 'type' is a special key, to work need typeContentDict={} and typeActionDict={}
def scrape(func):
"""https://github.com/kodiondemand/addon/wiki/decoratori#scrape"""
def wrapper(*args):
itemlist = []
@@ -406,33 +410,34 @@ def scrape(func):
args = func(*args)
function = func.__name__ if not 'actLike' in args else args['actLike']
# info('STACK= ',inspect.stack()[1][3])
item = args['item']
action = args['action'] if 'action' in args else 'findvideos'
anime = args['anime'] if 'anime' in args else ''
addVideolibrary = args['addVideolibrary'] if 'addVideolibrary' in args else True
search = args['search'] if 'search' in args else ''
blacklist = args['blacklist'] if 'blacklist' in args else []
data = args['data'] if 'data' in args else ''
patron = args['patron'] if 'patron' in args else args['patronMenu'] if 'patronMenu' in args else ''
action = args.get('action', 'findvideos')
anime = args.get('anime', '')
addVideolibrary = args.get('addVideolibrary', True)
search = args.get('search', '')
blacklist = args.get('blacklist', [])
data = args.get('data', '')
patron = args.get('patron', args.get('patronMenu', ''))
if 'headers' in args:
headers = args['headers']
elif 'headers' in func.__globals__:
headers = func.__globals__['headers']
else:
headers = ''
patronNext = args['patronNext'] if 'patronNext' in args else ''
patronBlock = args['patronBlock'] if 'patronBlock' in args else ''
typeActionDict = args['typeActionDict'] if 'typeActionDict' in args else {}
typeContentDict = args['typeContentDict'] if 'typeContentDict' in args else {}
debug = args['debug'] if 'debug' in args else False
debugBlock = args['debugBlock'] if 'debugBlock' in args else False
disabletmdb = args['disabletmdb'] if 'disabletmdb' in args else False
patronNext = args.get('patronNext', '')
patronBlock = args.get('patronBlock', '')
typeActionDict = args.get('typeActionDict', {})
typeContentDict = args.get('typeContentDict', {})
debug = args.get('debug', False)
debugBlock = args.get('debugBlock', False)
disabletmdb = args.get('disabletmdb', False)
if 'pagination' in args and inspect.stack()[1][3] not in ['add_tvshow', 'get_episodes', 'update', 'find_episodes']: pagination = args['pagination'] if args['pagination'] else 20
else: pagination = ''
lang = args['deflang'] if 'deflang' in args else ''
lang = args.get('deflang', '')
sceneTitle = args.get('sceneTitle')
group = args.get('group', False)
downloadEnabled = args.get('downloadEnabled', True)
pag = item.page if item.page else 1 # pagination
matches = []
@@ -440,24 +445,19 @@ def scrape(func):
logger.debug('PATRON= ', patron)
if not data:
page = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True)
data = re.sub("='([^']+)'", '="\\1"', page.data)
data = data.replace('\n', ' ')
data = data.replace('\t', ' ')
data = data.replace('&nbsp;', ' ')
data = re.sub(r'>\s{2,}<', '> <', data)
# replace all ' with " and eliminate newline, so we don't need to worry about
data = page.data
data = html_uniform(data)
scrapingTime = time()
if patronBlock:
if debugBlock:
regexDbg(item, patronBlock, headers, data)
blocks = scrapertools.find_multiple_matches_groups(data, patronBlock)
block = ""
for bl in blocks:
# info(len(blocks),bl)
if 'season' in bl and bl['season']:
item.season = bl['season']
blockItemlist, blockMatches = scrapeBlock(item, args, bl['block'], patron, headers, action, pagination, debug,
typeContentDict, typeActionDict, blacklist, search, pag, function, lang, sceneTitle)
typeContentDict, typeActionDict, blacklist, search, pag, function, lang, sceneTitle, group)
for it in blockItemlist:
if 'lang' in bl:
it.contentLanguage, it.title = scrapeLang(bl, it.contentLanguage, it.title)
@@ -468,36 +468,64 @@ def scrape(func):
matches.extend(blockMatches)
elif patron:
itemlist, matches = scrapeBlock(item, args, data, patron, headers, action, pagination, debug, typeContentDict,
typeActionDict, blacklist, search, pag, function, lang, sceneTitle)
typeActionDict, blacklist, search, pag, function, lang, sceneTitle, group)
if 'itemlistHook' in args:
itemlist = args['itemlistHook'](itemlist)
if 'ItemItemlistHook' in args:
itemlist = args['ItemItemlistHook'](item, itemlist)
try:
itemlist = args['itemlistHook'](itemlist)
except:
raise logger.ChannelScraperException
# if url may be changed and channel has findhost to update
if 'findhost' in func.__globals__ and not itemlist:
info('running findhost ' + func.__module__)
ch = func.__module__.split('.')[-1]
host = config.get_channel_url(func.__globals__['findhost'], ch, True)
try:
host = config.get_channel_url(func.__globals__['findhost'], ch, True)
parse = list(urlparse.urlparse(item.url))
parse[1] = scrapertools.get_domain_from_url(host)
item.url = urlparse.urlunparse(parse)
parse = list(urlparse.urlparse(item.url))
parse[1] = scrapertools.get_domain_from_url(host)
item.url = urlparse.urlunparse(parse)
except:
raise logger.ChannelScraperException
data = None
itemlist = []
matches = []
else:
break
if not data:
from platformcode.logger import WebErrorException
raise WebErrorException(urlparse.urlparse(item.url)[1], item.channel)
if group and item.grouped or args.get('groupExplode'):
import copy
nextArgs = copy.copy(args)
@scrape
def newFunc():
return nextArgs
nextArgs['item'] = nextPage(itemlist, item, data, patronNext, function)
nextArgs['group'] = False
if nextArgs['item']:
nextArgs['groupExplode'] = True
itemlist.pop() # remove next page just added
itemlist.extend(newFunc())
else:
nextArgs['groupExplode'] = False
nextArgs['item'] = item
itemlist = newFunc()
itemlist = [i for i in itemlist if i.action not in ['add_pelicula_to_library', 'add_serie_to_library']]
if action != 'play' and function != 'episodios' and 'patronMenu' not in args and item.contentType in ['movie', 'tvshow', 'episode', 'undefined'] and not disabletmdb:
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if (pagination and len(matches) <= pag * pagination) or not pagination: # next page with pagination
if patronNext and inspect.stack()[1][3] not in ['newest']:
if not group and not args.get('groupExplode') and ((pagination and len(matches) <= pag * pagination) or not pagination): # next page with pagination
if patronNext and inspect.stack()[1][3] not in ['newest'] and inspect.stack()[2][3] not in ['get_channel_results']:
nextPage(itemlist, item, data, patronNext, function)
# if function == 'episodios':
# scraper.sort_episode_list(itemlist)
# next page for pagination
if pagination and len(matches) > pag * pagination and not search:
if inspect.stack()[1][3] not in ['newest','get_newest']:
@@ -511,25 +539,31 @@ def scrape(func):
url=item.url,
args=item.args,
page=pag + 1,
thumbnail=thumb()))
thumbnail=thumb(),
prevthumb=item.prevthumb if item.prevthumb else item.thumbnail))
if anime:
if anime and inspect.stack()[1][3] not in ['find_episodes']:
from platformcode import autorenumber
if function == 'episodios' or item.action == 'episodios': autorenumber.renumber(itemlist, item, 'bold')
else: autorenumber.renumber(itemlist)
if (function == 'episodios' or item.action == 'episodios'): autorenumber.start(itemlist, item)
else: autorenumber.start(itemlist)
# if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
# pass
# else:
if addVideolibrary and (item.infoLabels["title"] or item.fulltitle):
# item.fulltitle = item.infoLabels["title"]
videolibrary(itemlist, item, function=function)
if function == 'episodios' or function == 'findvideos':
download(itemlist, item, function=function)
if inspect.stack()[1][3] not in ['find_episodes']:
if addVideolibrary and (item.infoLabels["title"] or item.fulltitle):
# item.fulltitle = item.infoLabels["title"]
videolibrary(itemlist, item, function=function)
if downloadEnabled and function == 'episodios' or function == 'findvideos':
download(itemlist, item, function=function)
if 'patronMenu' in args and itemlist:
itemlist = thumb(itemlist, genre=True)
if 'fullItemlistHook' in args:
itemlist = args['fullItemlistHook'](itemlist)
try:
itemlist = args['fullItemlistHook'](itemlist)
except:
raise logger.ChannelScraperException
# itemlist = filterLang(item, itemlist) # causa problemi a newest
@@ -634,63 +668,6 @@ def dooplay_menu(item, type):
return locals()
def swzz_get_url(item):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0'}
# dbg()
if "/link/" in item.url:
data = httptools.downloadpage(item.url, headers=headers).data
if "link =" in data:
data = scrapertools.find_single_match(data, 'link = "([^"]+)"')
if 'http' not in data:
data = 'https:' + data
elif 'linkId = ' in data:
id = scrapertools.find_single_match(data, 'linkId = "([^"]+)"')
data = stayonline(id)
else:
match = scrapertools.find_single_match(data, r'<meta name="og:url" content="([^"]+)"')
match = scrapertools.find_single_match(data, r'URL=([^"]+)">') if not match else match
if not match:
from lib import jsunpack
try:
data = scrapertools.find_single_match(data.replace('\n', ''), r"(eval\s?\(function\(p,a,c,k,e,d.*?)</script>")
data = jsunpack.unpack(data)
logger.debug("##### play /link/ unpack ##\n%s\n##" % data)
except:
logger.debug("##### The content is yet unpacked ##\n%s\n##" % data)
data = scrapertools.find_single_match(data, r'var link(?:\s)?=(?:\s)?"([^"]+)";')
data, c = unshortenit.unwrap_30x_only(data)
else:
data = match
if data.startswith('/'):
data = urlparse.urljoin("http://swzz.xyz", data)
if not "vcrypt" in data:
data = httptools.downloadpage(data).data
logger.debug("##### play /link/ data ##\n%s\n##" % data)
elif 'stayonline.pro' in item.url:
id = item.url.split('/')[-2]
data = stayonline(id)
else:
data = item.url
return data.replace('\\','')
def stayonline(id):
reqUrl = 'https://stayonline.pro/ajax/linkView.php'
p = urlencode({"id": id})
data = httptools.downloadpage(reqUrl, post=p).data
try:
import json
data = json.loads(data)['data']['value']
except:
data = scrapertools.find_single_match(data, r'"value"\s*:\s*"([^"]+)"')
return data
def menuItem(itemlist, filename, title='', action='', url='', contentType='undefined', args=[], style=True):
# Function to simplify menu creation
@@ -708,11 +685,13 @@ def menuItem(itemlist, filename, title='', action='', url='', contentType='undef
url = url,
extra = extra,
args = args,
contentType = contentType
contentType = contentType,
))
def menu(func):
"""https://github.com/kodiondemand/addon/wiki/decoratori#menu"""
def wrapper(*args):
args = func(*args)
@@ -732,7 +711,7 @@ def menu(func):
itemlist = []
for name in listUrls:
dictUrl[name] = args[name] if name in args else None
dictUrl[name] = args.get(name, None)
logger.debug(dictUrl[name])
if name == 'film': title = 'Film'
if name == 'tvshow': title = 'Serie TV'
@@ -782,7 +761,7 @@ def menu(func):
if name not in listUrls and name != 'item':
listUrls_extra.append(name)
for name in listUrls_extra:
dictUrl[name] = args[name] if name in args else None
dictUrl[name] = args.get(name, None)
for sub, var in dictUrl[name]:
menuItem(itemlist, filename,
title = sub + ' ',
@@ -827,7 +806,7 @@ def typo(string, typography=''):
typography = string.split('{')[1].strip(' }').lower()
string = string.replace('{' + typography + '}','').strip()
else:
string = string.strip()
string = string
typography.lower()
@@ -924,12 +903,7 @@ def match(item_url_string, **args):
data = httptools.downloadpage(url, **args).data
# format page data
data = re.sub("='([^']+)'", '="\\1"', data)
data = data.replace('\n', ' ')
data = data.replace('\t', ' ')
data = data.replace('&nbsp;', ' ')
data = re.sub(r'>\s+<', '><', data)
data = re.sub(r'([a-zA-Z])"([a-zA-Z])', "\1'\2", data)
data = html_uniform(data)
# collect blocks of a page
if patronBlock:
@@ -1064,7 +1038,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
# Simply add this function to add video library support
# Function_level is useful if the function is called by another function.
# If the call is direct, leave it blank
info()
logger.debug()
if item.contentType == 'movie':
action = 'add_pelicula_to_library'
@@ -1094,7 +1068,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
or (function == 'episodios' and contentType != 'movie'):
if config.get_videolibrary_support() and len(itemlist) > 0:
itemlist.append(
Item(channel=item.channel,
item.clone(channel=item.channel,
title=title,
fulltitle=item.fulltitle,
show=item.fulltitle,
@@ -1111,10 +1085,11 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
return itemlist
def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page='', resub=[]):
# Function_level is useful if the function is called by another function.
# If the call is direct, leave it blank
info()
logger.debug()
action = inspect.stack()[function_or_level][3] if type(function_or_level) == int else function_or_level
if next_page == '':
next_page = scrapertools.find_single_match(data, patron)
@@ -1124,9 +1099,9 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
if 'http' not in next_page:
next_page = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + (next_page if next_page.startswith('/') else '/' + next_page)
next_page = next_page.replace('&amp;', '&')
info('NEXT= ', next_page)
logger.debug('NEXT= ', next_page)
itemlist.append(
Item(channel=item.channel,
item.clone(channel=item.channel,
action = action,
contentType=item.contentType,
title=typo(config.get_localized_string(30992), 'color kod bold'),
@@ -1134,8 +1109,7 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
args=item.args,
nextPage=True,
thumbnail=thumb()))
return itemlist
return itemlist[-1]
def pagination(itemlist, item, page, perpage, function_level=1):
if len(itemlist) >= page * perpage:
@@ -1152,9 +1126,7 @@ def pagination(itemlist, item, page, perpage, function_level=1):
def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=True, Download=True, patronTag=None, Videolibrary=True):
info()
blacklisted_servers = config.get_setting("black_list", server='servers')
if not blacklisted_servers: blacklisted_servers = []
logger.debug()
if not data and not itemlist:
data = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True).data
if data:
@@ -1191,6 +1163,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
videoitem.contentType = item.contentType
videoitem.infoLabels = item.infoLabels
videoitem.quality = quality
videoitem.referer = item.url
videoitem.action = "play"
# videoitem.nfo = item.nfo
# videoitem.strm_path = item.strm_path
@@ -1199,7 +1172,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
with futures.ThreadPoolExecutor() as executor:
thL = [executor.submit(getItem, videoitem) for videoitem in itemlist if videoitem.url]
for it in futures.as_completed(thL):
if it.result() and it.result().server.lower() not in blacklisted_servers:
if it.result() and not config.get_setting("black_list", server=it.result().server.lower()):
verifiedItemlist.append(it.result())
try:
verifiedItemlist.sort(key=lambda it: int(re.sub(r'\D','',it.quality)))
@@ -1322,6 +1295,7 @@ def addQualityTag(item, itemlist, data, patron):
itemlist.insert(0,Item(channel=item.channel,
action="",
title=typo(qualityStr, '[] color kod bold'),
fulltitle=qualityStr,
plot=descr,
folder=False,
thumbnail=thumb('info')))
@@ -1417,7 +1391,7 @@ def thumb(item_itemlist_string=None, genre=False, live=False):
'_tvshow':['serie','tv', 'fiction']}
def autoselect_thumb(item, genre):
info('SPLIT',re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()))
# logger.debug('SPLIT',re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()))
if genre == False:
for thumb, titles in icon_dict.items():
if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in search):

View File

@@ -19,7 +19,7 @@ import ast, copy, re, sqlite3, time, xbmcaddon
from core import filetools, httptools, jsontools, scrapertools
from core.item import InfoLabels
from platformcode import config, logger
from platformcode import config, logger, platformtools
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
@@ -87,7 +87,7 @@ create_bd()
# The function name is the name of the decorator and receives the function that decorates.
def cache_response(fn):
logger.info()
logger.debug()
# import time
# start_time = time.time()
@@ -495,7 +495,7 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda=def_lang, lock=None
def find_and_set_infoLabels(item):
logger.info()
logger.debug()
global otmdb_global
tmdb_result = None
@@ -524,9 +524,7 @@ def find_and_set_infoLabels(item):
otmdb_global = Tmdb(id_Tmdb=item.infoLabels['tmdb_id'], tipo=tipo_busqueda, idioma_busqueda=def_lang)
results = otmdb_global.get_list_resultados()
if len(results) > 1:
from platformcode import platformtools
tmdb_result = platformtools.show_video_info(results, item=item, caption= tipo_contenido % title)
elif len(results) > 0:
tmdb_result = results[0]
@@ -904,7 +902,7 @@ class Tmdb(object):
cls.dic_generos[idioma][tipo] = {}
url = ('http://api.themoviedb.org/3/genre/%s/list?api_key=a1ab8b8669da03637a4b98fa39c39228&language=%s' % (tipo, idioma))
try:
logger.info("[Tmdb.py] Filling in dictionary of genres")
logger.debug("[Tmdb.py] Filling in dictionary of genres")
resultado = cls.get_json(url)
if not isinstance(resultado, dict):
@@ -936,7 +934,7 @@ class Tmdb(object):
'&language=%s' % (self.busqueda_id, source, self.busqueda_idioma))
buscando = "%s: %s" % (source.capitalize(), self.busqueda_id)
logger.info("[Tmdb.py] Searching %s:\n%s" % (buscando, url))
logger.debug("[Tmdb.py] Searching %s:\n%s" % (buscando, url))
resultado = self.get_json(url)
if not isinstance(resultado, dict):
resultado = ast.literal_eval(resultado.decode('utf-8'))
@@ -983,7 +981,7 @@ class Tmdb(object):
url += '&year=%s' % self.busqueda_year
buscando = self.busqueda_texto.capitalize()
logger.info("[Tmdb.py] Searching %s on page %s:\n%s" % (buscando, page, url))
logger.debug("[Tmdb.py] Searching %s on page %s:\n%s" % (buscando, page, url))
resultado = self.get_json(url)
if not isinstance(resultado, dict):
resultado = ast.literal_eval(resultado.decode('utf-8'))
@@ -1044,7 +1042,7 @@ class Tmdb(object):
url = ('http://api.themoviedb.org/3/%s?api_key=a1ab8b8669da03637a4b98fa39c39228&%s'
% (type_search, "&".join(params)))
logger.info("[Tmdb.py] Searcing %s:\n%s" % (type_search, url))
logger.debug("[Tmdb.py] Searcing %s:\n%s" % (type_search, url))
resultado = self.get_json(url, cache=False)
if not isinstance(resultado, dict):
resultado = ast.literal_eval(resultado.decode('utf-8'))
@@ -1109,7 +1107,7 @@ class Tmdb(object):
return True
def get_list_resultados(self, num_result=20):
# logger.info("self %s" % str(self))
# logger.debug("self %s" % str(self))
res = []
if num_result <= 0:
@@ -1329,7 +1327,7 @@ class Tmdb(object):
"&append_to_response=credits" % (self.result["id"], numtemporada, self.busqueda_idioma)
buscando = "id_Tmdb: " + str(self.result["id"]) + " season: " + str(numtemporada) + "\nURL: " + url
logger.info("[Tmdb.py] Searcing " + buscando)
logger.debug("[Tmdb.py] Searcing " + buscando)
try:
self.temporada[numtemporada] = self.get_json(url)
if not isinstance(self.temporada[numtemporada], dict):
@@ -1518,7 +1516,7 @@ class Tmdb(object):
items.extend(list(self.get_episodio(ret_infoLabels['season'], episodio).items()))
# logger.info("ret_infoLabels" % ret_infoLabels)
# logger.debug("ret_infoLabels" % ret_infoLabels)
for k, v in items:
if not v:

View File

@@ -128,7 +128,7 @@ def token_trakt(item):
def set_trakt_info(item):
logger.info()
logger.debug()
import xbmcgui
# Envia los datos a trakt
try:
@@ -139,7 +139,7 @@ def set_trakt_info(item):
pass
def get_trakt_watched(id_type, mediatype, update=False):
logger.info()
logger.debug()
id_list = []
id_dict = dict()
@@ -229,7 +229,7 @@ def trakt_check(itemlist):
def get_sync_from_file():
logger.info()
logger.debug()
sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt_data.json')
trakt_node = {}
if os.path.exists(sync_path):
@@ -241,7 +241,7 @@ def get_sync_from_file():
def update_trakt_data(mediatype, trakt_data):
logger.info()
logger.debug()
sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt_data.json')
if os.path.exists(sync_path):
@@ -251,7 +251,7 @@ def update_trakt_data(mediatype, trakt_data):
def ask_install_script():
logger.info()
logger.debug()
from platformcode import platformtools
@@ -265,7 +265,7 @@ def ask_install_script():
def wait_for_update_trakt():
logger.info()
logger.debug()
t = Thread(update_all)
t.setDaemon(True)
t.start()
@@ -274,7 +274,7 @@ def wait_for_update_trakt():
def update_all():
# from core.support import dbg;dbg()
from time import sleep
logger.info()
logger.debug()
sleep(20)
while xbmc.Player().isPlaying():
sleep(20)

View File

@@ -77,8 +77,9 @@ otvdb_global = None
def find_and_set_infoLabels(item):
logger.info()
# logger.info("item es %s" % item)
logger.debug()
# from core.support import dbg;dbg()
# logger.debug("item es %s" % item)
p_dialog = None
if not item.contentSeason:
@@ -89,16 +90,18 @@ def find_and_set_infoLabels(item):
title = item.contentSerieName
# If the title includes the (year) we will remove it
year = scrapertools.find_single_match(title, "^.+?\s*(\(\d{4}\))$")
year = scrapertools.find_single_match(title, r"^.+?\s*(\(\d{4}\))$")
if year:
title = title.replace(year, "").strip()
item.infoLabels['year'] = year[1:-1]
if not item.infoLabels.get("tvdb_id"):
if not item.infoLabels.get("imdb_id"):
if item.infoLabels.get("tvdb_id", '') in ['', 'None']:
if item.infoLabels['year']:
otvdb_global = Tvdb(search=title, year=item.infoLabels['year'])
else:
elif item.infoLabels.get("imdb_id"):
otvdb_global = Tvdb(imdb_id=item.infoLabels.get("imdb_id"))
else:
otvdb_global = Tvdb(search=title)
elif not otvdb_global or otvdb_global.get_id() != item.infoLabels['tvdb_id']:
otvdb_global = Tvdb(tvdb_id=item.infoLabels['tvdb_id'])
@@ -114,9 +117,16 @@ def find_and_set_infoLabels(item):
if len(results) > 1:
tvdb_result = platformtools.show_video_info(results, item=item, scraper=Tvdb, caption=config.get_localized_string(60298) % title)
# if not tvdb_result:
# res = platformtools.dialog_info(item, 'tvdb')
# if not res.exit: return find_and_set_infoLabels(res)
elif len(results) > 0:
tvdb_result = results[0]
# else:
# res = platformtools.dialog_info(item, 'tvdb')
# if not res.exit: return find_and_set_infoLabels(res)
# todo revisar
if isinstance(item.infoLabels, InfoLabels):
logger.debug("is an instance of infoLabels")
@@ -160,7 +170,7 @@ def set_infoLabels_item(item):
if 'infoLabels' in item and 'fanart' in item.infoLabels['fanart']:
item.fanart = item.infoLabels['fanart']
if 'infoLabels' in item and 'season' in item.infoLabels:
if 'infoLabels' in item and 'season' in item.infoLabels and item.contentType != 'tvshow':
try:
int_season = int(item.infoLabels['season'])
except ValueError:
@@ -372,7 +382,7 @@ class Tvdb(object):
@classmethod
def __check_token(cls):
# logger.info()
# logger.debug()
if TOKEN == "":
cls.__login()
else:
@@ -387,7 +397,7 @@ class Tvdb(object):
@staticmethod
def __login():
# logger.info()
# logger.debug()
global TOKEN
apikey = "106B699FDC04301C"
@@ -398,19 +408,13 @@ class Tvdb(object):
else: params = jsontools.dump(params)
try:
req = urllib.request.Request(url, data=params, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
dict_html = requests.post(url, data=params, headers=DEFAULT_HEADERS).json()
except Exception as ex:
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error: %s" % message)
else:
dict_html = jsontools.load(html)
# logger.debug("dict_html %s" % dict_html)
if "token" in dict_html:
token = dict_html["token"]
DEFAULT_HEADERS["Authorization"] = "Bearer " + token
@@ -419,22 +423,19 @@ class Tvdb(object):
@classmethod
def __refresh_token(cls):
# logger.info()
# logger.debug()
global TOKEN
is_success = False
url = HOST + "/refresh_token"
try:
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
req = requests.get(url, headers=DEFAULT_HEADERS)
except urllib.error.HTTPError as err:
logger.error("err.code %s" % err.code)
except req as err:
logger.error("err.code %s" % err.status_code)
# if there is error 401 it is that the token has passed the time and we have to call login again
if err.code == 401:
if err.status_code == 401:
cls.__login()
else:
raise
@@ -444,13 +445,15 @@ class Tvdb(object):
logger.error("error: %s" % message)
else:
dict_html = jsontools.load(html)
dict_html = req.json()
# logger.error("tokencito %s" % dict_html)
if "token" in dict_html:
token = dict_html["token"]
DEFAULT_HEADERS["Authorization"] = "Bearer " + token
TOKEN = config.set_setting("tvdb_token", token)
is_success = True
else:
cls.__login()
return is_success
@@ -518,7 +521,7 @@ class Tvdb(object):
]
}
"""
logger.info()
logger.debug()
if id_episode and self.episodes.get(id_episode):
return self.episodes.get(id_episode)
@@ -531,18 +534,16 @@ class Tvdb(object):
DEFAULT_HEADERS["Accept-Language"] = lang
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
req = requests.get(url, headers=DEFAULT_HEADERS)
except Exception as ex:
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error: %s" % message)
else:
dict_html = jsontools.load(html)
dict_html = req.json()
if 'Error' in dict_html:
logger.debug("code %s " % dict_html['Error'])
if "data" in dict_html and "id" in dict_html["data"][0]:
self.get_episode_by_id(dict_html["data"][0]["id"], lang)
return dict_html["data"]
@@ -588,27 +589,14 @@ class Tvdb(object):
}
}
"""
logger.info()
logger.debug()
try:
url = HOST + "/series/%s/episodes?page=%s" % (_id, page)
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
except Exception as ex:
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error: %s" % message)
else:
self.list_episodes[page] = jsontools.load(html)
# logger.info("dict_html %s" % self.list_episodes)
return self.list_episodes[page]
url = HOST + "/series/%s/episodes?page=%s" % (_id, page)
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
js = requests.get(url, headers=DEFAULT_HEADERS).json()
self.list_episodes[page] = js if 'Error' not in js else {}
return self.list_episodes[page]
def get_episode_by_id(self, _id, lang=DEFAULT_LANG, semaforo=None):
"""
@@ -674,31 +662,27 @@ class Tvdb(object):
"""
if semaforo:
semaforo.acquire()
logger.info()
logger.debug()
url = HOST + "/episodes/%s" % _id
# from core.support import dbg;dbg()
try:
DEFAULT_HEADERS["Accept-Language"] = lang
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
req = requests.get(url, headers=DEFAULT_HEADERS)
except Exception as ex:
# if isinstance(ex, urllib).HTTPError:
logger.debug("code %s " % ex.code)
logger.debug("code %s " % ex)
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error en: %s" % message)
else:
dict_html = jsontools.load(html)
dict_html = dict_html.pop("data")
logger.info("dict_html %s" % dict_html)
self.episodes[_id] = dict_html
dict_html = req.json()
# logger.debug("dict_html %s" % dict_html)
self.episodes[_id] = dict_html.pop("data") if 'Error' not in dict_html else {}
if semaforo:
semaforo.release()
@@ -728,39 +712,30 @@ class Tvdb(object):
"status": "string"
}
"""
logger.info()
logger.debug()
try:
params = {}
if name:
params["name"] = name
elif imdb_id:
params["imdbId"] = imdb_id
elif zap2it_id:
params["zap2itId"] = zap2it_id
params = {}
if name:
params["name"] = name
elif imdb_id:
params["imdbId"] = imdb_id
elif zap2it_id:
params["zap2itId"] = zap2it_id
params = urllib.parse.urlencode(params)
params = urllib.parse.urlencode(params)
DEFAULT_HEADERS["Accept-Language"] = lang
url = HOST + "/search/series?%s" % params
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
DEFAULT_HEADERS["Accept-Language"] = lang
url = HOST + "/search/series?%s" % params
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
dict_html = requests.get(url, headers=DEFAULT_HEADERS).json()
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
logger.info(html)
response.close()
except Exception as ex:
if 'Error' in dict_html:
# if isinstance(ex, urllib.parse).HTTPError:
logger.debug("code %s " % ex.code)
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error: %s" % message)
logger.debug("code %s " % dict_html['Error'])
else:
dict_html = jsontools.load(html)
if "errors" in dict_html and "invalidLanguage" in dict_html["errors"]:
# no hay información en idioma por defecto
@@ -827,20 +802,16 @@ class Tvdb(object):
}
}
"""
logger.info()
logger.debug()
resultado = {}
url = HOST + "/series/%s" % _id
try:
DEFAULT_HEADERS["Accept-Language"] = lang
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
req = requests.get(url, headers=DEFAULT_HEADERS)
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
response = urllib.request.urlopen(req)
html = response.read()
response.close()
except Exception as ex:
# if isinstance(ex, urllib).HTTPError:
logger.debug("code %s " % ex)
@@ -849,26 +820,24 @@ class Tvdb(object):
logger.error("error: %s" % message)
else:
dict_html = jsontools.load(html)
if "errors" in dict_html and "invalidLanguage" in dict_html["errors"]:
dict_html = req.json()
if "Error" in dict_html and "invalidLanguage" in dict_html["Error"]:
return {}
else:
resultado1 = dict_html["data"]
if not resultado1 and from_get_list:
return self.__get_by_id(_id, "en")
resultado1 = dict_html["data"]
if not resultado1 and from_get_list:
return self.__get_by_id(_id, "en")
logger.debug("Result %s" % dict_html)
resultado2 = {"image_poster": [{'keyType': 'poster', 'fileName': 'posters/%s-1.jpg' % _id}]}
resultado3 = {"image_fanart": [{'keyType': 'fanart', 'fileName': 'fanart/original/%s-1.jpg' % _id}]}
logger.debug("Result %s" % dict_html)
resultado2 = {"image_poster": [{'keyType': 'poster', 'fileName': 'posters/%s-1.jpg' % _id}]}
resultado3 = {"image_fanart": [{'keyType': 'fanart', 'fileName': 'fanart/original/%s-1.jpg' % _id}]}
resultado = resultado1.copy()
resultado.update(resultado2)
resultado.update(resultado3)
resultado = resultado1.copy()
resultado.update(resultado2)
resultado.update(resultado3)
logger.debug("total result %s" % resultado)
self.list_results = [resultado]
self.result = resultado
logger.debug("total result %s" % resultado)
self.list_results = [resultado]
self.result = resultado
return resultado
@@ -886,7 +855,7 @@ class Tvdb(object):
@rtype: dict
"""
logger.info()
logger.debug()
if self.result.get('image_season_%s' % season):
return self.result['image_season_%s' % season]
@@ -909,24 +878,26 @@ class Tvdb(object):
url = HOST + "/series/%s/images/query?%s" % (_id, params)
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
res = requests.get(url, headers=DEFAULT_HEADERS)
except Exception as ex:
# if isinstance(ex, urllib).HTTPError:
logger.debug("code %s " % ex)
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error: %s" % message)
return {}
else:
dict_html = jsontools.load(html)
dict_html = res.json()
if 'Error' in dict_html:
# if isinstance(ex, urllib.parse).HTTPError:
logger.debug("code %s " % dict_html['Error'])
else:
dict_html["image_" + image] = dict_html.pop("data")
self.result.update(dict_html)
dict_html["image_" + image] = dict_html.pop("data")
self.result.update(dict_html)
return dict_html
return dict_html
def get_tvshow_cast(self, _id, lang=DEFAULT_LANG):
"""
@@ -938,20 +909,23 @@ class Tvdb(object):
@return: dictionary with actors
@rtype: dict
"""
logger.info()
logger.debug()
url = HOST + "/series/%s/actors" % _id
DEFAULT_HEADERS["Accept-Language"] = lang
logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS))
req = urllib.request.Request(url, headers=DEFAULT_HEADERS)
response = urllib.request.urlopen(req)
html = response.read()
response.close()
dict_html = jsontools.load(html)
dict_html["cast"] = dict_html.pop("data")
try:
req = requests.get(url, headers=DEFAULT_HEADERS)
except Exception as ex:
logger.debug("code %s " % ex)
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
logger.error("error en: %s" % message)
else:
dict_html = req.json()
if 'Error' in dict_html:
logger.debug("code %s " % dict_html['Error'])
else:
dict_html["cast"] = dict_html.pop("data")
self.result.update(dict_html)
def get_id(self):
@@ -968,7 +942,7 @@ class Tvdb(object):
@rtype: list
@return: list of results
"""
logger.info()
logger.debug()
list_results = []
# if we have a result and it has seriesName, we already have the info of the series, it is not necessary to search again
@@ -1034,12 +1008,12 @@ class Tvdb(object):
if 'data' in thumbs:
ret_infoLabels['thumbnail'] = HOST_IMAGE + thumbs['data'][0]['fileName']
elif 'poster' in origen and origen['poster']:
ret_infoLabels['thumbnail'] = origen['poster']
ret_infoLabels['thumbnail'] = HOST_IMAGE + origen['poster']
fanarts = requests.get(HOST + '/series/' + str(origen['id']) + '/images/query?keyType=fanart').json()
if 'data' in fanarts:
ret_infoLabels['fanart'] = HOST_IMAGE + fanarts['data'][0]['fileName']
elif 'fanart' in origen and origen['fanart']:
ret_infoLabels['thumbnail'] = origen['fanart']
ret_infoLabels['fanart'] = HOST_IMAGE + origen['fanart']
if 'overview' in origen and origen['overview']:
ret_infoLabels['plot'] = origen['overview']
if 'duration' in origen and origen['duration']:

View File

@@ -78,7 +78,7 @@ def save_movie(item, silent=False):
@rtype fallidos: int
@return: the number of failed items or -1 if all failed
"""
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
insertados = 0
sobreescritos = 0
@@ -144,7 +144,7 @@ def save_movie(item, silent=False):
if not path:
# Create folder
path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip())
logger.info("Creating movie directory:" + path)
logger.debug("Creating movie directory:" + path)
if not filetools.mkdir(path):
logger.debug("Could not create directory")
return 0, 0, -1, path
@@ -159,7 +159,7 @@ def save_movie(item, silent=False):
if not nfo_exists:
# We create .nfo if it doesn't exist
logger.info("Creating .nfo: " + nfo_path)
logger.debug("Creating .nfo: " + nfo_path)
head_nfo = scraper.get_nfo(item)
item_nfo = Item(title=item.contentTitle, channel="videolibrary", action='findvideos',
@@ -182,7 +182,7 @@ def save_movie(item, silent=False):
if item_nfo and strm_exists:
if json_exists:
logger.info("The file exists. Is overwritten")
logger.debug("The file exists. Is overwritten")
sobreescritos += 1
else:
insertados += 1
@@ -209,7 +209,7 @@ def save_movie(item, silent=False):
item_nfo.library_urls[item.channel] = item.url
if filetools.write(nfo_path, head_nfo + item_nfo.tojson()):
#logger.info("FOLDER_MOVIES : %s" % FOLDER_MOVIES)
#logger.debug("FOLDER_MOVIES : %s" % FOLDER_MOVIES)
# We update the Kodi video library with the movie
if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent:
from platformcode import xbmc_videolibrary
@@ -238,7 +238,7 @@ def update_renumber_options(item, head_nfo, path):
json = json_file['TVSHOW_AUTORENUMBER']
if item.fulltitle in json:
item.channel_prefs[channel]['TVSHOW_AUTORENUMBER'] = json[item.fulltitle]
logger.info('UPDATED=\n' + str(item.channel_prefs))
logger.debug('UPDATED=\n' + str(item.channel_prefs))
filetools.write(tvshow_path, head_nfo + item.tojson())
def add_renumber_options(item, head_nfo, path):
@@ -426,7 +426,7 @@ def save_tvshow(item, episodelist, silent=False):
@rtype path: str
@return: serial directory
"""
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
path = ""
@@ -486,7 +486,7 @@ def save_tvshow(item, episodelist, silent=False):
if not path:
path = filetools.join(TVSHOWS_PATH, ("%s [%s]" % (base_name, _id)).strip())
logger.info("Creating series directory: " + path)
logger.debug("Creating series directory: " + path)
try:
filetools.mkdir(path)
except OSError as exception:
@@ -496,7 +496,7 @@ def save_tvshow(item, episodelist, silent=False):
tvshow_path = filetools.join(path, "tvshow.nfo")
if not filetools.exists(tvshow_path):
# We create tvshow.nfo, if it does not exist, with the head_nfo, series info and watched episode marks
logger.info("Creating tvshow.nfo: " + tvshow_path)
logger.debug("Creating tvshow.nfo: " + tvshow_path)
head_nfo = scraper.get_nfo(item)
item.infoLabels['mediatype'] = "tvshow"
item.infoLabels['title'] = item.contentSerieName
@@ -570,11 +570,11 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
@rtype fallidos: int
@return: the number of failed episodes
"""
logger.info()
logger.debug()
episodelist = filter_list(episodelist, serie.action, path)
# No episode list, nothing to save
if not len(episodelist):
logger.info("There is no episode list, we go out without creating strm")
logger.debug("There is no episode list, we go out without creating strm")
return 0, 0, 0
# process local episodes
@@ -589,7 +589,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
elif config.get_setting("local_episodes", "videolibrary"):
done, local_episodes_path = config_local_episodes_path(path, serie)
if done < 0:
logger.info("An issue has occurred while configuring local episodes, going out without creating strm")
logger.debug("An issue has occurred while configuring local episodes, going out without creating strm")
return 0, 0, done
item_nfo.local_episodes_path = local_episodes_path
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
@@ -601,7 +601,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
local_episodelist += get_local_content(local_episodes_path)
clean_list = []
for f in filetools.listdir(path):
match = scrapertools.find_single_match(f, r'[Ss]?(\d+)(?:x|_|\.|\s+)?[Ee]?[Pp]?(\d+)')
match = scrapertools.find_single_match(f, r'[Ss]?(\d+)(?:x|_|\s+)?[Ee]?[Pp]?(\d+)')
if match:
ep = '%dx%02d' % (int(match[0]), int(match[1]))
if ep in local_episodelist:
@@ -713,7 +713,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
# No episode list, nothing to save
if not len(new_episodelist):
logger.info("There is no episode list, we go out without creating strm")
logger.debug("There is no episode list, we go out without creating strm")
return 0, 0, 0
local_episodelist += get_local_content(path)
@@ -745,12 +745,12 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower())
if season_episode in local_episodelist:
logger.info('Skipped: Serie ' + serie.contentSerieName + ' ' + season_episode + ' available as local content')
logger.debug('Skipped: Serie ' + serie.contentSerieName + ' ' + season_episode + ' available as local content')
continue
# check if the episode has been downloaded
if filetools.join(path, "%s [downloads].json" % season_episode) in ficheros:
logger.info('INFO: "%s" episode %s has been downloaded, skipping it' % (serie.contentSerieName, season_episode))
logger.debug('INFO: "%s" episode %s has been downloaded, skipping it' % (serie.contentSerieName, season_episode))
continue
strm_exists = strm_path in ficheros
@@ -806,7 +806,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
if filetools.write(json_path, e.tojson()):
if not json_exists:
logger.info("Inserted: %s" % json_path)
logger.debug("Inserted: %s" % json_path)
insertados += 1
# We mark episode as unseen
news_in_playcounts[season_episode] = 0
@@ -817,14 +817,14 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
news_in_playcounts[serie.contentSerieName] = 0
else:
logger.info("Overwritten: %s" % json_path)
logger.debug("Overwritten: %s" % json_path)
sobreescritos += 1
else:
logger.info("Failed: %s" % json_path)
logger.debug("Failed: %s" % json_path)
fallidos += 1
else:
logger.info("Failed: %s" % json_path)
logger.debug("Failed: %s" % json_path)
fallidos += 1
if not silent and p_dialog.iscanceled():
@@ -894,7 +894,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
def config_local_episodes_path(path, item, silent=False):
logger.info(item)
logger.debug(item)
from platformcode.xbmc_videolibrary import search_local_path
local_episodes_path=search_local_path(item)
if not local_episodes_path:
@@ -906,11 +906,11 @@ def config_local_episodes_path(path, item, silent=False):
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(80043))
local_episodes_path = platformtools.dialog_browse(0, config.get_localized_string(80046))
if local_episodes_path == '':
logger.info("User has canceled the dialog")
logger.debug("User has canceled the dialog")
return -2, local_episodes_path
elif path in local_episodes_path:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(80045))
logger.info("Selected folder is the same of the TV show one")
logger.debug("Selected folder is the same of the TV show one")
return -2, local_episodes_path
if local_episodes_path:
@@ -925,7 +925,7 @@ def config_local_episodes_path(path, item, silent=False):
def process_local_episodes(local_episodes_path, path):
logger.info()
logger.debug()
sub_extensions = ['.srt', '.sub', '.sbv', '.ass', '.idx', '.ssa', '.smi']
artwork_extensions = ['.jpg', '.jpeg', '.png']
@@ -964,7 +964,7 @@ def process_local_episodes(local_episodes_path, path):
def get_local_content(path):
logger.info()
logger.debug()
local_episodelist = []
for root, folders, files in filetools.walk(path):
@@ -993,7 +993,7 @@ def add_movie(item):
@type item: item
@param item: item to be saved.
"""
logger.info()
logger.debug()
from platformcode.launcher import set_search_temp; set_search_temp(item)
# To disambiguate titles, TMDB is caused to ask for the really desired title
@@ -1006,17 +1006,17 @@ def add_movie(item):
item = generictools.update_title(item) # We call the method that updates the title with tmdb.find_and_set_infoLabels
#if item.tmdb_stat:
# del item.tmdb_stat # We clean the status so that it is not recorded in the Video Library
if item:
new_item = item.clone(action="findvideos")
insertados, sobreescritos, fallidos, path = save_movie(new_item)
# if item:
new_item = item.clone(action="findvideos")
insertados, sobreescritos, fallidos, path = save_movie(new_item)
if fallidos == 0:
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(30135) % new_item.contentTitle) # 'has been added to the video library'
else:
filetools.rmdirtree(path)
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(60066) % new_item.contentTitle) # "ERROR, the movie has NOT been added to the video library")
if fallidos == 0:
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(30135) % new_item.contentTitle) # 'has been added to the video library'
else:
filetools.rmdirtree(path)
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(60066) % new_item.contentTitle) # "ERROR, the movie has NOT been added to the video library")
def add_tvshow(item, channel=None):
@@ -1040,7 +1040,7 @@ def add_tvshow(item, channel=None):
@param channel: channel from which the series will be saved. By default, item.from_channel or item.channel will be imported.
"""
logger.info("show=#" + item.show + "#")
logger.debug("show=#" + item.show + "#")
from platformcode.launcher import set_search_temp; set_search_temp(item)
if item.channel == "downloads":
@@ -1073,21 +1073,26 @@ def add_tvshow(item, channel=None):
# If the second screen is canceled, the variable "scraper_return" will be False. The user does not want to continue
item = generictools.update_title(item) # We call the method that updates the title with tmdb.find_and_set_infoLabels
if not item: return
#if item.tmdb_stat:
# del item.tmdb_stat # We clean the status so that it is not recorded in the Video Library
# Get the episode list
# from core.support import dbg;dbg()
itemlist = getattr(channel, item.action)(item)
if itemlist and not scrapertools.find_single_match(itemlist[0].title, r'(\d+x\d+)'):
from platformcode.autorenumber import select_type, renumber, check
if itemlist and not scrapertools.find_single_match(itemlist[0].title, r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)'):
from platformcode.autorenumber import start, check
if not check(item):
action = item.action
select_type(item)
item.renumber = True
start(item)
item.renumber = False
item.action = action
return add_tvshow(item, channel)
if not item.exit:
return add_tvshow(item, channel)
itemlist = getattr(channel, item.action)(item)
else:
itemlist = renumber(itemlist)
itemlist = getattr(channel, item.action)(item)
global magnet_caching
magnet_caching = False
@@ -1112,7 +1117,7 @@ def add_tvshow(item, channel=None):
else:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60070) % item.show)
logger.info("%s episodes of series %s have been added to the video library" % (insertados, item.show))
logger.debug("%s episodes of series %s have been added to the video library" % (insertados, item.show))
if config.is_xbmc():
if config.get_setting("sync_trakt_new_tvshow", "videolibrary"):
import xbmc
@@ -1128,7 +1133,7 @@ def add_tvshow(item, channel=None):
def emergency_urls(item, channel=None, path=None, headers={}):
logger.info()
logger.debug()
import re
from servers import torrent
try:

View File

@@ -17,8 +17,8 @@ from core import filetools
class ziptools(object):
def extract(self, file, dir, folder_to_extract="", overwrite_question=False, backup=False):
logger.info("file= %s" % file)
logger.info("dir= %s" % dir)
logger.debug("file= %s" % file)
logger.debug("dir= %s" % dir)
if not dir.endswith(':') and not filetools.exists(dir):
filetools.mkdir(dir)
@@ -30,13 +30,13 @@ class ziptools(object):
for nameo in zf.namelist():
name = nameo.replace(':', '_').replace('<', '_').replace('>', '_').replace('|', '_').replace('"', '_').replace('?', '_').replace('*', '_')
logger.info("name=%s" % nameo)
logger.debug("name=%s" % nameo)
if not name.endswith('/'):
logger.info("it's not a directory")
logger.debug("it's not a directory")
try:
(path, filename) = filetools.split(filetools.join(dir, name))
logger.info("path=%s" % path)
logger.info("name=%s" % name)
logger.debug("path=%s" % path)
logger.debug("name=%s" % name)
if folder_to_extract:
if path != filetools.join(dir, folder_to_extract):
break
@@ -49,7 +49,7 @@ class ziptools(object):
else:
outfilename = filetools.join(dir, name)
logger.info("outfilename=%s" % outfilename)
logger.debug("outfilename=%s" % outfilename)
try:
if filetools.exists(outfilename) and overwrite_question:
from platformcode import platformtools
@@ -74,7 +74,7 @@ class ziptools(object):
try:
zf.close()
except:
logger.info("Error closing .zip " + file)
logger.error("Error closing .zip " + file)
def _createstructure(self, file, dir):
self._makedirs(self._listdirs(file), dir)

View File

@@ -8,10 +8,12 @@ import sys
import xbmc
# on kodi 18 its xbmc.translatePath, on 19 xbmcvfs.translatePath
# functions that on kodi 19 moved to xbmcvfs
try:
import xbmcvfs
xbmc.translatePath = xbmcvfs.translatePath
xbmc.validatePath = xbmcvfs.validatePath
xbmc.makeLegalFilename = xbmcvfs.makeLegalFilename
except:
pass
from platformcode import config, logger

View File

@@ -27,7 +27,7 @@ class ChromeOSImage:
"""
def __init__(self, imgpath):
logger.info('Image Path: ' + imgpath)
logger.debug('Image Path: ' + imgpath)
"""Prepares the image"""
self.imgpath = imgpath
self.bstream = self.get_bstream(imgpath)
@@ -59,7 +59,7 @@ class ChromeOSImage:
self.seek_stream(entries_start * lba_size)
if not calcsize(part_format) == entry_size:
logger.info('Partition table entries are not 128 bytes long')
logger.debug('Partition table entries are not 128 bytes long')
return 0
for index in range(1, entries_num + 1): # pylint: disable=unused-variable
@@ -71,7 +71,7 @@ class ChromeOSImage:
break
if not offset:
logger.info('Failed to calculate losetup offset.')
logger.debug('Failed to calculate losetup offset.')
return 0
return offset
@@ -93,7 +93,7 @@ class ChromeOSImage:
while True:
chunk2 = self.read_stream(chunksize)
if not chunk2:
logger.info('File %s not found in the ChromeOS image' % filename)
logger.debug('File %s not found in the ChromeOS image' % filename)
return False
chunk = chunk1 + chunk2

View File

@@ -47,7 +47,7 @@ def query(name, type='A', server=DOH_SERVER, path="/dns-query", fallback=True):
else:
retval = []
except Exception as ex:
logger.info("Exception occurred: '%s'" % ex)
logger.error("Exception occurred: '%s'" % ex)
if retval is None and fallback:
if type == 'A':

View File

@@ -25,7 +25,7 @@ intervenido_sucuri = 'Access Denied - Sucuri Website Firewall'
def update_title(item):
logger.info()
logger.debug()
from core import scraper,support
@@ -41,7 +41,7 @@ def update_title(item):
The channel must add a method to be able to receive the call from Kodi / Alfa, and be able to call this method:
def actualizar_titulos(item):
logger.info()
logger.debug()
itemlist = []
from lib import generictools
from platformcode import launcher
@@ -129,7 +129,8 @@ def update_title(item):
scraper_return = scraper.find_and_set_infoLabels(item)
if not scraper_return: # If the user has canceled, we restore the data to the initial situation and leave
item = new_item.clone()
return
# item = new_item.clone()
else:
# If the user has changed the data in "Complete Information" you must see the final title in TMDB
if not item.infoLabels['tmdb_id']:
@@ -205,7 +206,7 @@ def update_title(item):
def refresh_screen(item):
logger.info()
logger.debug()
"""
#### Kodi 18 compatibility ####
@@ -239,7 +240,7 @@ def refresh_screen(item):
def post_tmdb_listado(item, itemlist):
logger.info()
logger.debug()
itemlist_fo = []
"""
@@ -484,7 +485,7 @@ def post_tmdb_listado(item, itemlist):
def post_tmdb_seasons(item, itemlist):
logger.info()
logger.debug()
"""
@@ -644,7 +645,7 @@ def post_tmdb_seasons(item, itemlist):
def post_tmdb_episodios(item, itemlist):
logger.info()
logger.debug()
itemlist_fo = []
"""
@@ -995,7 +996,7 @@ def post_tmdb_episodios(item, itemlist):
def post_tmdb_findvideos(item, itemlist):
logger.info()
logger.debug()
"""
@@ -1215,7 +1216,7 @@ def post_tmdb_findvideos(item, itemlist):
def get_field_from_kodi_DB(item, from_fields='*', files='file'):
logger.info()
logger.debug()
"""
Call to read from the Kodi DB the input fields received (from_fields, by default "*") of the video indicated in Item
@@ -1293,7 +1294,7 @@ def get_field_from_kodi_DB(item, from_fields='*', files='file'):
def fail_over_newpct1(item, patron, patron2=None, timeout=None):
logger.info()
logger.debug()
import ast
"""
@@ -1494,7 +1495,7 @@ def fail_over_newpct1(item, patron, patron2=None, timeout=None):
def web_intervenida(item, data, desactivar=True):
logger.info()
logger.debug()
"""
@@ -1577,7 +1578,7 @@ def web_intervenida(item, data, desactivar=True):
def regenerate_clones():
logger.info()
logger.debug()
import json
from core import videolibrarytools
@@ -1591,7 +1592,7 @@ def regenerate_clones():
# Find the paths where to leave the control .json file, and the Video Library
json_path = filetools.exists(filetools.join(config.get_runtime_path(), 'verify_cached_torrents.json'))
if json_path:
logger.info('Previously repaired video library: WE ARE GOING')
logger.debug('Previously repaired video library: WE ARE GOING')
return False
json_path = filetools.join(config.get_runtime_path(), 'verify_cached_torrents.json')
filetools.write(json_path, json.dumps({"CINE_verify": True})) # Prevents another simultaneous process from being launched
@@ -1631,7 +1632,7 @@ def regenerate_clones():
# Delete the Tvshow.nfo files and check if the .nfo has more than one channel and one is clone Newpct1
for file in files:
# logger.info('file - nfos: ' + file)
# logger.debug('file - nfos: ' + file)
if 'tvshow.nfo' in file:
file_path = filetools.join(root, 'tvshow.nfo')
filetools.remove(file_path)
@@ -1697,7 +1698,7 @@ def regenerate_clones():
for file in files:
file_path = filetools.join(root, file)
if '.json' in file:
logger.info('** file: ' + file)
logger.debug('** file: ' + file)
canal_json = scrapertools.find_single_match(file, r'\[(\w+)\].json')
if canal_json not in nfo.library_urls:
filetools.remove(file_path) # we delete the .json is a zombie
@@ -1740,7 +1741,7 @@ def regenerate_clones():
def dejuice(data):
logger.info()
logger.debug()
# Method to unobtrusive JuicyCodes data
import base64

View File

@@ -29,7 +29,7 @@ def website(config):
rebulk = rebulk.regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True)
rebulk.defaults(name="website")
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'tlds-alpha-by-domain.txt')) as tld_file:
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'tlds-alpha-by-domain.txt'), 'rb') as tld_file:
tlds = [
tld.strip().decode('utf-8')
for tld in tld_file.readlines()

View File

@@ -492,7 +492,6 @@ class UnshortenIt(object):
except Exception as e:
return uri, str(e)
def _unshorten_vcrypt(self, uri):
uri = uri.replace('.net', '.pw')
try:
@@ -508,15 +507,15 @@ class UnshortenIt(object):
from Crypto.Cipher import AES
str = str.replace("_ppl_", "+").replace("_eqq_", "=").replace("_sll_", "/")
iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
key = "naphajU2usWUswec"
iv = b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
key = b"naphajU2usWUswec"
decoded = b64decode(str)
decoded = decoded + '\0' * (len(decoded) % 16)
decoded = decoded + b'\0' * (len(decoded) % 16)
crypt_object = AES.new(key, AES.MODE_CBC, iv)
decrypted = ''
decrypted = b''
for p in range(0, len(decoded), 16):
decrypted += crypt_object.decrypt(decoded[p:p + 16]).replace('\0', '')
return decrypted
decrypted += crypt_object.decrypt(decoded[p:p + 16]).replace(b'\0', b'')
return decrypted.decode('ascii')
if 'shield' in uri.split('/')[-2]:
uri = decrypt(uri.split('/')[-1])
else:
@@ -537,7 +536,7 @@ class UnshortenIt(object):
r = httptools.downloadpage(uri, timeout=self._timeout, headers=headers, follow_redirects=False)
if 'Wait 1 hour' in r.data:
uri = ''
logger.info('IP bannato da vcrypt, aspetta un ora')
logger.error('IP bannato da vcrypt, aspetta un ora')
else:
prev_uri = uri
uri = r.headers['location']
@@ -549,7 +548,11 @@ class UnshortenIt(object):
if 'out_generator' in uri:
uri = re.findall('url=(.*)$', uri)[0]
elif '/decode/' in uri:
uri = httptools.downloadpage(uri, follow_redirects=True).url
scheme, netloc, path, query, fragment = urlsplit(uri)
splitted = path.split('/')
splitted[1] = 'outlink'
uri = httptools.downloadpage(scheme + '://' + netloc + "/".join(splitted) + query + fragment, follow_redirects=False,
post={'url': splitted[2]}).headers['location']
# uri = decrypt(uri.split('/')[-1])
return uri, r.code if r else 200
@@ -557,7 +560,6 @@ class UnshortenIt(object):
logger.error(e)
return uri, 0
def _unshorten_linkup(self, uri):
try:
r = None

View File

@@ -1,5 +1,6 @@
import sys
import xbmc
if sys.version_info[0] > 2: from urllib.parse import unquote
else: from urllib2 import unquote
def dec_ei(h):
g = 'MNOPIJKL89+/4567UVWXQRSTEFGHABCDcdefYZabstuvopqr0123wxyzklmnghij'
@@ -7,23 +8,14 @@ def dec_ei(h):
for e in range(0,len(h)):
c.append(g.find(h[e]))
for e in range(len(c)*2-1,-1,-1):
#print 'e=' + str(e)
a = c[e % len(c)] ^ c[(e+1)%len(c)]
#print 'a='+str(a)
c[e%len(c)] = a
#print 'c['+str(e % len(c))+']='+ str(c[e % len(c)])
c = f(c)
d = ''
for e in range(0,len(c)):
d += '%'+ (('0'+ (str(format(c[e],'x'))))[-2:])
# if python 3
if sys.version_info[0] > 2:
import urllib
return urllib.parse.unquote(d)
else:
import urllib2
return urllib2.unquote(d)
return unquote(d)
def f(m):
l = list()

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
import xbmc, xbmcgui
import xbmcaddon
import json
from platformcode import config, logger
import requests
import sys
@@ -236,63 +235,3 @@ def test_conn(is_exit, check_dns, view_msg,
# else:
# return False
# def for creating the channels.json file
def check_channels(inutile=''):
"""
I read the channel hosts from the channels.json file, I check them,
I write the channels-test.json file with the error code and the new url in case of redirect
urls MUST have http (s)
During the urls check the ip, asdl and dns checks are carried out.
This is because it can happen that at any time the connection may have problems. If it does, check it
relative writing of the file is interrupted with a warning message
"""
logger.info()
folderJson = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('path')).decode('utf-8')
fileJson = 'channels.json'
with open(folderJson+'/'+fileJson) as f:
data = json.load(f)
risultato = {}
for chann, host in sorted(data['direct'].items()):
ris = []
# to get an idea of the timing
# useful only if you control all channels
# for channels with error 522 about 40 seconds are lost ...
logger.info("check #### INIZIO #### channel - host :%s - %s " % (chann, host))
rslt = Kdicc(lst_urls = [host]).http_Resp()
# all right
if rslt['code'] == 200:
risultato[chann] = host
# redirect
elif str(rslt['code']).startswith('3'):
# risultato[chann] = str(rslt['code']) +' - '+ rslt['redirect'][:-1]
if rslt['redirect'].endswith('/'):
rslt['redirect'] = rslt['redirect'][:-1]
risultato[chann] = rslt['redirect']
# non-existent site
elif rslt['code'] == -2:
risultato[chann] = 'Host Sconosciuto - '+ str(rslt['code']) +' - '+ host
# site not reachable - probable dns not set
elif rslt['code'] == 111:
risultato[chann] = ['Host non raggiungibile - '+ str(rslt['code']) +' - '+ host]
else:
# other types of errors
# risultato[chann] = 'Errore Sconosciuto - '+str(rslt['code']) +' - '+ host
risultato[chann] = host
logger.info("check #### FINE #### rslt :%s " % (rslt))
risultato = {'findhost': data['findhost'], 'direct': risultato}
fileJson_test = 'channels-test.json'
# I write the updated file
with open(folderJson+'/'+fileJson_test, 'w') as f:
data = json.dump(risultato, f, sort_keys=True, indent=4)
logger.info(data)

View File

@@ -0,0 +1,604 @@
# -*- coding: utf-8 -*-
import xbmc, xbmcgui, sys, channelselector, time
from core.support import dbg, typo, tmdb
from core.item import Item
from core import channeltools, servertools, scrapertools
from platformcode import platformtools, config, logger
from platformcode.launcher import run
from threading import Thread
if sys.version_info[0] >= 3: from concurrent import futures
else: from concurrent_py2 import futures
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
def busy(state):
if state: xbmc.executebuiltin('ActivateWindow(busydialognocancel)')
else: xbmc.executebuiltin('Dialog.Close(busydialognocancel)')
def set_workers():
workers = config.get_setting('thread_number') if config.get_setting('thread_number') > 0 else None
return workers
def Search(item):
xbmc.executebuiltin('Dialog.Close(all,true)')
SearchWindow('GlobalSearch.xml', config.get_runtime_path()).start(item)
xbmc.sleep(600)
# Actions
LEFT = 1
RIGHT = 2
UP = 3
DOWN = 4
EXIT = 10
BACKSPACE = 92
SWIPEUP = 531
CONTEXT = 117
# Container
SEARCH = 1
EPISODES = 2
SERVERS = 3
NORESULTS = 4
LOADING = 5
# Search
MAINTITLE = 100
CHANNELS = 101
RESULTS = 102
PROGRESS = 500
COUNT = 501
MENU = 502
BACK = 503
CLOSE = 504
QUALITYTAG = 505
# Servers
EPISODESLIST = 200
SERVERLIST = 300
class SearchWindow(xbmcgui.WindowXML):
def start(self, item):
logger.debug()
self.exit = False
self.item = item
self.lastSearch()
if not self.item.text: return
self.type = self.item.mode
self.channels = []
self.find = []
self.persons = []
self.episodes = []
self.servers = []
self.results = {}
self.channelsList = self.get_channels()
self.focus = SEARCH
self.process = True
self.page = 1
self.moduleDict = {}
self.searchActions = []
self.thread = None
self.doModal()
def lastSearch(self):
logger.debug()
if not self.item.text:
if config.get_setting('last_search'): last_search = channeltools.get_channel_setting('Last_searched', 'search', '')
else: last_search = ''
if not self.item.text: self.item.text = platformtools.dialog_input(default=last_search, heading='')
if self.item.text: channeltools.set_channel_setting('Last_searched', self.item.text, 'search')
def select(self):
logger.debug()
self.PROGRESS.setVisible(False)
items = []
if self.persons:
tmdb_info = tmdb.discovery(self.item, dict_=self.item.discovery)
results = tmdb_info.results.get('cast',[])
else:
tmdb_info = tmdb.Tmdb(texto_buscado=self.item.text, tipo=self.item.mode.replace('show', ''))
results = tmdb_info.results
for result in results:
logger.info(result)
result = tmdb_info.get_infoLabels(result, origen=result)
movie = result.get('title','')
tvshow = result.get('name','')
title = tvshow if tvshow else movie
result['mode'] = 'tvshow' if tvshow else 'movie'
self.find.append(result)
thumb = 'Infoplus/' + result['mode'].replace('show','') + '.png'
it = xbmcgui.ListItem(title)
it.setProperty('thumb', result.get('thumbnail', thumb))
it.setProperty('fanart', result.get('fanart',''))
it.setProperty('plot', result.get('overview', ''))
it.setProperty('search','search')
year = result.get('release_date','')
if year: it.setProperty('year','[' + year.split('/')[-1] + ']')
else:
year = result.get('first_air_date','')
if year: it.setProperty('year','[' + year.split('-')[0] + ']')
items.append(it)
if items:
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.setFocusId(RESULTS)
else:
self.NORESULTS.setVisible(True)
def actors(self):
logger.debug()
self.PROGRESS.setVisible(False)
items = []
dict_ = {'url': 'search/person', 'language': def_lang, 'query': self.item.text, 'page':self.page}
prof = {'Acting': 'Actor', 'Directing': 'Director', 'Production': 'Productor'}
plot = ''
self.item.search_type = 'person'
tmdb_inf = tmdb.discovery(self.item, dict_=dict_)
results = tmdb_inf.results
for elem in results:
name = elem.get('name', '')
if not name: continue
rol = elem.get('known_for_department', '')
rol = prof.get(rol, rol)
know_for = elem.get('known_for', '')
cast_id = elem.get('id', '')
if know_for:
t_k = know_for[0].get('title', '')
if t_k: plot = '%s in %s' % (rol, t_k)
t = elem.get('profile_path', '')
if t: thumb = 'https://image.tmdb.org/t/p/original' + t
else : thumb = 'Infoplus/no_photo.png'
discovery = {'url': 'person/%s/combined_credits' % cast_id, 'page': '1', 'sort_by': 'primary_release_date.desc', 'language': def_lang}
self.persons.append(discovery)
it = xbmcgui.ListItem(name)
it.setProperty('thumb', thumb)
it.setProperty('plot', plot)
it.setProperty('search','persons')
items.append(it)
if len(results) > 19:
it = xbmcgui.ListItem(config.get_localized_string(70006))
it.setProperty('thumb', 'Infoplus/next_focus.png')
it.setProperty('search','next')
items.append(it)
if self.page > 1:
it = xbmcgui.ListItem(config.get_localized_string(70005))
it.setProperty('thumb', 'Infoplus/previous_focus.png')
it.setProperty('search','previous')
items.insert(0, it)
if items:
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.setFocusId(RESULTS)
else:
self.NORESULTS.setVisible(True)
def get_channels(self):
logger.debug()
channels_list = []
all_channels = channelselector.filterchannels('all')
for ch in all_channels:
channel = ch.channel
ch_param = channeltools.get_channel_parameters(channel)
if not ch_param.get("active", False):
continue
list_cat = ch_param.get("categories", [])
if not ch_param.get("include_in_global_search", False):
continue
if 'anime' in list_cat:
n = list_cat.index('anime')
list_cat[n] = 'tvshow'
if self.item.mode == 'all' or self.item.type in list_cat:
if config.get_setting("include_in_global_search", channel) and ch_param.get("active", False):
channels_list.append(channel)
logger.debug('search in channels:',channels_list)
return channels_list
def getModule(self, channel):
logger.debug()
try:
module = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel])
mainlist = getattr(module, 'mainlist')(Item(channel=channel, global_search=True))
action = [elem for elem in mainlist if elem.action == "search" and (self.item.mode == 'all' or elem.contentType in [self.item.mode, 'undefined'])]
return module, action
except:
import traceback
logger.error('error importing/getting search items of ' + channel)
logger.error(traceback.format_exc())
return None, None
def search(self):
count = 0
self.count = 0
self.LOADING.setVisible(True)
with futures.ThreadPoolExecutor() as executor:
for channel in self.channelsList:
if self.exit: break
module, action = executor.submit(self.getModule, channel).result()
if module and action:
self.moduleDict[channel] = module
self.searchActions += action
count += 1
percent = (float(count) / len(self.channelsList)) * 100
self.PROGRESS.setPercent(percent)
self.COUNT.setText('%s/%s' % (count, len(self.channelsList)))
with futures.ThreadPoolExecutor(max_workers=set_workers()) as executor:
for searchAction in self.searchActions:
if self.exit: break
executor.submit(self.get_channel_results, self.item, self.moduleDict, searchAction)
def get_channel_results(self, item, module_dict, search_action):
logger.debug()
channel = search_action.channel
results = []
valid = []
other = []
module = module_dict[channel]
searched_id = item.infoLabels['tmdb_id']
try:
results.extend(module.search(search_action, item.text))
if len(results) == 1:
if not results[0].action or config.get_localized_string(70006).lower() in results[0].title.lower():
results = []
if self.item.mode != 'all':
for elem in results:
if not elem.infoLabels.get('year', ""):
elem.infoLabels['year'] = '-'
tmdb.set_infoLabels_item(elem)
if elem.infoLabels['tmdb_id'] == searched_id:
elem.from_channel = channel
elem.verified ='ok.png'
valid.append(elem)
else:
other.append(elem)
except:
pass
self.count += 1
if self.item.mode == 'all': self.update(channel, results)
else: self.update(channel, valid + other)
def makeItem(self, item):
logger.debug()
thumb = item.thumbnail if item.thumbnail else 'Infoplus/' + item.contentType.replace('show','') + 'png'
logger.info('THUMB', thumb)
it = xbmcgui.ListItem(item.title)
it.setProperty('year', '[' + str(item.year if item.year else item.infoLabels.get('year','')) + ']')
it.setProperty('thumb', thumb)
it.setProperty('fanart', item.fanart)
it.setProperty('plot', item.plot)
it.setProperty('verified', item.verified)
if item.server:
color = scrapertools.find_single_match(item.alive, r'(FF[^\]]+)')
it.setProperty('channel', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('thumb', "https://raw.githubusercontent.com/kodiondemand/media/master/resources/servers/%s.png" % item.server.lower())
it.setProperty('servername', servertools.get_server_parameters(item.server.lower()).get('name',item.server))
it.setProperty('color', color if color else 'FF0082C2')
return it
def update(self, channel, results):
logger.debug('Search on channel', channel)
if results:
channelParams = channeltools.get_channel_parameters(channel)
name = channelParams['title']
if name not in self.results:
self.results[name] = [results, len(self.channels)]
item = xbmcgui.ListItem(name)
item.setProperty('thumb', channelParams['thumbnail'])
item.setProperty('position', '0')
item.setProperty('results', str(len(results)))
item.setProperty('verified', results[0].verified)
self.channels.append(item)
else:
self.results[name].append([results, len(self.channels)])
self.channels[int(self.results[name][1])].setProperty('results', str(len(results)))
pos = self.CHANNELS.getSelectedPosition()
self.CHANNELS.reset()
self.CHANNELS.addItems(self.channels)
self.CHANNELS.selectItem(pos)
if len(self.channels) == 1:
self.setFocusId(CHANNELS)
items = []
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
percent = (float(self.count) / len(self.searchActions)) * 100
self.LOADING.setVisible(False)
self.PROGRESS.setPercent(percent)
self.COUNT.setText('%s/%s [%s"]' % (self.count, len(self.searchActions), int(time.time() - self.time) ))
if percent == 100 and not self.results:
self.PROGRESS.setVisible(False)
self.NORESULTS.setVisible(True)
def onInit(self):
self.time = time.time()
# collect controls
self.CHANNELS = self.getControl(CHANNELS)
self.RESULTS = self.getControl(RESULTS)
self.PROGRESS = self.getControl(PROGRESS)
self.COUNT = self.getControl(COUNT)
self.MAINTITLE = self.getControl(MAINTITLE)
self.MAINTITLE.setText(typo(config.get_localized_string(30993).replace('...','') % '"%s"' % self.item.text, 'bold'))
self.SEARCH = self.getControl(SEARCH)
self.EPISODES = self.getControl(EPISODES)
self.EPISODESLIST = self.getControl(EPISODESLIST)
self.SERVERS = self.getControl(SERVERS)
self.SERVERLIST = self.getControl(SERVERLIST)
self.NORESULTS = self.getControl(NORESULTS)
self.NORESULTS.setVisible(False)
self.LOADING = self.getControl(LOADING)
self.LOADING.setVisible(False)
self.Focus(self.focus)
if self.type:
self.type = None
if self.item.mode in ['all', 'search']:
if self.item.type: self.item.mode = self.item.type
self.thread = Thread(target=self.search)
self.thread.start()
elif self.item.mode in ['movie', 'tvshow']:
self.select()
elif self.item.mode in ['person']:
self.actors()
def Focus(self, focusid):
if focusid in [SEARCH]:
self.focus = CHANNELS
self.SEARCH.setVisible(True)
self.EPISODES.setVisible(False)
self.SERVERS.setVisible(False)
if focusid in [EPISODES]:
self.focus = focusid
self.SEARCH.setVisible(False)
self.EPISODES.setVisible(True)
self.SERVERS.setVisible(False)
if focusid in [SERVERS]:
self.focus = SERVERLIST
self.SEARCH.setVisible(False)
self.EPISODES.setVisible(False)
self.SERVERS.setVisible(True)
def onAction(self, action):
action = action.getId()
focus = self.getFocusId()
if action in [CONTEXT] and focus in [RESULTS, EPISODESLIST, SERVERLIST]:
self.context()
elif action in [SWIPEUP] and self.CHANNELS.isVisible() :
self.setFocusId(CHANNELS)
pos = self.CHANNELS.getSelectedPosition()
self.CHANNELS.selectItem(pos)
elif action in [LEFT, RIGHT] and focus in [CHANNELS] and self.CHANNELS.isVisible():
items = []
name = self.CHANNELS.getSelectedItem().getLabel()
subpos = int(self.CHANNELS.getSelectedItem().getProperty('position'))
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.RESULTS.selectItem(subpos)
elif action in [DOWN] and focus in [BACK, CLOSE, MENU]:
if self.SERVERS.isVisible(): self.setFocusId(SERVERLIST)
elif self.EPISODES.isVisible(): self.setFocusId(EPISODESLIST)
else: self.setFocusId(RESULTS)
elif focus in [RESULTS] and self.item.mode == 'all':
pos = self.RESULTS.getSelectedPosition()
self.CHANNELS.getSelectedItem().setProperty('position', str(pos))
if action in [BACKSPACE]:
self.Back()
elif action in [EXIT]:
self.Close()
def onClick(self, control_id):
if self.RESULTS.getSelectedItem(): search = self.RESULTS.getSelectedItem().getProperty('search')
else: search = None
if control_id in [CHANNELS]:
items = []
name = self.CHANNELS.getSelectedItem().getLabel()
subpos = int(self.CHANNELS.getSelectedItem().getProperty('position'))
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.RESULTS.selectItem(subpos)
self.CHANNELS.getSelectedItem().setProperty('position', str(subpos))
# self.setFocusId(RESULTS)
elif control_id in [BACK]:
self.Back()
elif control_id in [CLOSE]:
self.Close()
elif control_id in [MENU]:
self.context()
elif search:
pos = self.RESULTS.getSelectedPosition()
if search == 'next':
self.page += 1
self.actors()
elif search == 'previous':
self.page -= 1
self.actors()
elif search == 'persons':
self.item.discovery = self.persons[pos]
self.select()
else:
result = self.find[pos]
name = self.RESULTS.getSelectedItem().getLabel()
item = Item(mode='search', type=result['mode'], contentType=result['mode'], infoLabels=result, selected = True, text=name)
if self.item.mode == 'movie': item.contentTitle = self.RESULTS.getSelectedItem().getLabel()
else: item.contentSerieName = self.RESULTS.getSelectedItem().getLabel()
return Search(item)
elif control_id in [RESULTS, EPISODESLIST]:
busy(True)
if control_id in [RESULTS]:
name = self.CHANNELS.getSelectedItem().getLabel()
self.pos = self.RESULTS.getSelectedPosition()
item = self.results[name][0][self.pos]
else:
self.pos = self.EPISODESLIST.getSelectedPosition()
item = self.episodes[self.pos]
try:
self.channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel])
self.itemsResult = getattr(self.channel, item.action)(item)
except:
import traceback
logger.error('error importing/getting search items of ' + item.channel)
logger.error(traceback.format_exc())
self.itemsResult = []
if self.itemsResult and self.itemsResult[0].action in ['play', '']:
if config.get_setting('checklinks') and not config.get_setting('autoplay'):
self.itemsResult = servertools.check_list_links(self.itemsResult, config.get_setting('checklinks_number'))
self.servers = self.itemsResult
self.itemsResult = []
uhd = []
fhd = []
hd = []
sd = []
unknown = []
for i, item in enumerate(self.servers):
if item.server:
it = self.makeItem(item)
it.setProperty('index', str(i))
if item.quality in ['4k', '2160p', '2160', '4k2160p', '4k2160', '4k 2160p', '4k 2160', '2k']:
it.setProperty('quality', 'uhd.png')
uhd.append(it)
elif item.quality in ['fullhd', 'fullhd 1080', 'fullhd 1080p', 'full hd', 'full hd 1080', 'full hd 1080p', 'hd1080', 'hd1080p', 'hd 1080', 'hd 1080p', '1080', '1080p']:
it.setProperty('quality', 'Fhd.png')
fhd.append(it)
elif item.quality in ['hd', 'hd720', 'hd720p', 'hd 720', 'hd 720p', '720', '720p', 'hdtv']:
it.setProperty('quality', 'hd.png')
hd.append(it)
elif item.quality in ['sd', '480p', '480', '360p', '360', '240p', '240']:
it.setProperty('quality', 'sd.png')
sd.append(it)
else:
it.setProperty('quality', '')
unknown.append(it)
elif not item.action:
self.getControl(QUALITYTAG).setText(item.fulltitle)
uhd.sort(key=lambda it: it.getProperty('index'))
fhd.sort(key=lambda it: it.getProperty('index'))
hd.sort(key=lambda it: it.getProperty('index'))
sd.sort(key=lambda it: it.getProperty('index'))
unknown.sort(key=lambda it: it.getProperty('index'))
serverlist = uhd + fhd + hd + sd + unknown
self.Focus(SERVERS)
self.SERVERLIST.reset()
self.SERVERLIST.addItems(serverlist)
self.setFocusId(SERVERLIST)
else:
self.episodes = self.itemsResult
self.itemsResult = []
episodes = []
for item in self.episodes:
if item.action == 'findvideos':
it = xbmcgui.ListItem(item.title)
episodes.append(it)
self.Focus(EPISODES)
self.EPISODESLIST.reset()
self.EPISODESLIST.addItems(episodes)
self.setFocusId(EPISODESLIST)
busy(False)
elif control_id in [SERVERLIST]:
index = int(self.getControl(control_id).getSelectedItem().getProperty('index'))
server = self.servers[index]
server.player_mode = 0
run(server)
def Back(self):
self.getControl(QUALITYTAG).setText('')
if self.SERVERS.isVisible():
if self.episodes:
self.Focus(EPISODES)
self.setFocusId(EPISODESLIST)
else:
self.Focus(SEARCH)
self.setFocusId(RESULTS)
self.RESULTS.selectItem(self.pos)
elif self.EPISODES.isVisible():
self.episodes = []
self.Focus(SEARCH)
self.setFocusId(RESULTS)
self.RESULTS.selectItem(self.pos)
elif self.item.mode in ['person'] and self.find:
self.find = []
self.actors()
else:
self.Close()
def Close(self):
self.exit = True
if self.thread:
busy(True)
while self.thread.is_alive(): xbmc.sleep(200)
busy(False)
self.close()
def context(self):
pos = self.RESULTS.getSelectedPosition()
name = self.CHANNELS.getSelectedItem().getLabel()
item = self.results[name][0][pos]
context = [config.get_localized_string(70739), config.get_localized_string(70557), config.get_localized_string(60359)]
context_commands = ["RunPlugin(%s?%s)" % (sys.argv[0], 'action=open_browser&url=' + item.url),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=kodfavorites&action=addFavourite&from_channel=' + item.channel + '&from_action=' + item.action),
"RunPlugin(%s?%s)" % (sys.argv[0], 'channel=trailertools&action=buscartrailer&contextual=True&search_title=' + item.contentTitle if item.contentTitle else item.fulltitle)]
if item.contentType == 'movie':
context += [config.get_localized_string(60353), config.get_localized_string(60354)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'action=add_pelicula_to_library&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' +item.action)]
else:
context += [config.get_localized_string(60352), config.get_localized_string(60355), config.get_localized_string(60357)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'action=add_serie_to_library&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel +'&from_action=' + item.action)]
if self.EPISODES.isVisible() or self.SERVERS.isVisible():
pos = self.EPISODESLIST.getSelectedPosition()
item = self.episodes[pos]
context += [config.get_localized_string(60356)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' +item.action)]
index = xbmcgui.Dialog().contextmenu(context)
if index > 0: xbmc.executebuiltin(context_commands[index])

View File

@@ -191,7 +191,8 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.getControl(NUMBER).setText(support.typo(config.get_localized_string(70362),'uppercase bold'))
else:
it = xbmcgui.ListItem(item.infoLabels['title'])
it.setProperty('channel', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('channelname', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('channel', item.channel)
it.setProperty('action', item.action)
it.setProperty('server', servertools.get_server_parameters(item.server.lower()).get('name',item.server))
it.setProperty('url', item.url)
@@ -213,7 +214,6 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.commands.append(itemlist[0].clone(channel='downloads', action='save_download', from_channel=itemlist[0].channel, from_action=itemlist[0].action, thumbnail=support.thumb('downloads')))
else:
self.commands.append(Info.clone(channel='downloads', action='save_download', from_channel=Info.channel, from_action=Info.action, thumbnail=support.thumb('downloads')))
if self.commands:
commands = []
for command in self.commands:
@@ -248,7 +248,8 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
if action == 'play':
item.server = self.getControl(RECOMANDED).getSelectedItem().getProperty('server')
self.close()
platformtools.play_video(item)
from platformcode.launcher import run
run(item)
xbmc.sleep(500)
while xbmc.Player().isPlaying():
xbmc.sleep(500)

View File

@@ -19,7 +19,7 @@ def start():
Within this function all calls should go to
functions that we want to execute as soon as we open the plugin.
"""
logger.info()
logger.debug()
# config.set_setting('show_once', True)
# Test if all the required directories are created
config.verify_directories_created()
@@ -37,7 +37,7 @@ def start():
updater.showSavedChangelog()
def run(item=None):
logger.info()
logger.debug()
if not item:
# Extract item from sys.argv
if sys.argv[2]:
@@ -94,7 +94,7 @@ def run(item=None):
# If item has no action, stops here
if item.action == "":
logger.info("Item without action")
logger.debug("Item without action")
return
# Action for main menu in channelselector
@@ -135,6 +135,12 @@ def run(item=None):
from platformcode import infoplus
return infoplus.Main(item)
elif config.get_setting('new_search') and item.channel == "search" and item.action == 'new_search':
from platformcode.globalsearch import Search
item.contextual = True
Search(item)
return
elif item.channel == "backup":
from platformcode import backup
return getattr(backup, item.action)(item)
@@ -187,7 +193,7 @@ def run(item=None):
channel_file = os.path.join(config.get_runtime_path(), CHANNELS, item.channel + ".py")
logger.info("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel)
logger.debug("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel)
channel = None
@@ -207,12 +213,12 @@ def run(item=None):
trakt_tools.set_trakt_info(item)
except:
pass
logger.info("item.action=%s" % item.action.upper())
logger.debug("item.action=%s" % item.action.upper())
# logger.debug("item_toPlay: " + "\n" + item.tostring('\n'))
# First checks if channel has a "play" function
if hasattr(channel, 'play'):
logger.info("Executing channel 'play' method")
logger.debug("Executing channel 'play' method")
itemlist = channel.play(item)
b_favourite = item.isFavourite
# Play should return a list of playable URLS
@@ -233,7 +239,7 @@ def run(item=None):
# If player don't have a "play" function, not uses the standard play from platformtools
else:
logger.info("Executing core 'play' method")
logger.debug("Executing core 'play' method")
platformtools.play_video(item)
# Special action for findvideos, where the plugin looks for known urls
@@ -246,8 +252,7 @@ def run(item=None):
# If not, uses the generic findvideos function
else:
logger.info("No channel 'findvideos' method, "
"executing core method")
logger.debug("No channel 'findvideos' method, " "executing core method")
itemlist = servertools.find_video_items(item)
if config.get_setting("max_links", "videolibrary") != 0:
@@ -291,7 +296,7 @@ def run(item=None):
else:
filetools.remove(temp_search_file)
logger.info("item.action=%s" % item.action.upper())
logger.debug("item.action=%s" % item.action.upper())
from core import channeltools
if config.get_setting('last_search'):
@@ -312,7 +317,7 @@ def run(item=None):
# For all other actions
else:
# import web_pdb; web_pdb.set_trace()
logger.info("Executing channel '%s' method" % item.action)
logger.debug("Executing channel '%s' method" % item.action)
itemlist = getattr(channel, item.action)(item)
if config.get_setting('trakt_sync'):
from core import trakt_tools
@@ -336,13 +341,10 @@ def run(item=None):
logger.error(traceback.format_exc())
patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"'
Channel = scrapertools.find_single_match(traceback.format_exc(), patron)
platformtools.dialog_ok(
config.get_localized_string(59985) + Channel,
config.get_localized_string(60013) %(e))
except:
config.get_localized_string(59985) % e.channel,
config.get_localized_string(60013) % e.url)
except Exception as e:
import traceback
from core import scrapertools
@@ -351,26 +353,15 @@ def run(item=None):
patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"'
Channel = scrapertools.find_single_match(traceback.format_exc(), patron)
try:
import xbmc
if config.get_platform(True)['num_version'] < 14:
log_name = "xbmc.log"
else:
log_name = "kodi.log"
log_message = config.get_localized_string(50004) + xbmc.translatePath("special://logpath") + log_name
except:
log_message = ""
if Channel:
if Channel or e.__class__ == logger.ChannelScraperException:
if item.url:
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message, nolabel='ok', yeslabel=config.get_localized_string(70739)):
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014), nolabel='ok', yeslabel=config.get_localized_string(70739)):
run(Item(action="open_browser", url=item.url))
else:
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message)
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014))
else:
platformtools.dialog_ok(
config.get_localized_string(60038),
config.get_localized_string(60015) + '\n' + log_message)
if platformtools.dialog_yesno(config.get_localized_string(60038), config.get_localized_string(60015)):
run(Item(channel="setting", action="report_menu"))
def new_search(item, channel=None):
@@ -393,7 +384,7 @@ def set_search_temp(item):
filetools.write(temp_search_file, f)
def reorder_itemlist(itemlist):
logger.info()
logger.debug()
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
new_list = []
@@ -431,7 +422,7 @@ def reorder_itemlist(itemlist):
new_list.extend(mod_list)
new_list.extend(not_mod_list)
logger.info("Modified Titles:%i |Unmodified:%i" % (modified, not_modified))
logger.debug("Modified Titles:%i |Unmodified:%i" % (modified, not_modified))
if len(new_list) == 0:
new_list = itemlist
@@ -441,7 +432,7 @@ def reorder_itemlist(itemlist):
def limit_itemlist(itemlist):
logger.info()
logger.debug()
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
try:
@@ -474,7 +465,7 @@ def play_from_library(item):
itemlist=[]
item.fromLibrary = True
logger.info()
logger.debug()
# logger.debug("item: \n" + item.tostring('\n'))
# Try to reproduce an image (this does nothing and also does not give an error)

View File

@@ -3,7 +3,7 @@
# Logger (kodi)
# --------------------------------------------------------------------------------
from __future__ import unicode_literals
import inspect, os, xbmc, sys
import inspect,os, xbmc, sys
from platformcode import config
# for test suite
@@ -53,5 +53,11 @@ def log(*args, **kwargs):
class WebErrorException(Exception):
def __init__(self, *args, **kwargs):
def __init__(self, url, channel, *args, **kwargs):
self.url = url
self.channel = channel
Exception.__init__(self, *args, **kwargs)
class ChannelScraperException(Exception):
pass

View File

@@ -178,6 +178,60 @@ def dialog_register(heading, user=False, email=False, password=False, user_defau
dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img)
return dialog
def dialog_info(item, scraper):
class TitleOrIDWindow(xbmcgui.WindowXMLDialog):
def Start(self, item, scraper):
self.item = item
self.item.exit = False
self.title = item.show if item.show else item.fulltitle
self.id = item.infoLabels.get('tmdb_id', '') if scraper == 'tmdb' else item.infoLabels.get('tvdb_id', '')
self.scraper = scraper
self.idtitle = 'TMDB ID' if scraper == 'tmdb' else 'TVDB ID'
self.doModal()
return self.item
def onInit(self):
#### Kodi 18 compatibility ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
self.HEADER = self.getControl(100)
self.TITLE = self.getControl(101)
self.ID = self.getControl(102)
self.EXIT = self.getControl(103)
self.EXIT2 = self.getControl(104)
self.HEADER.setText(config.get_localized_string(60228) % self.title)
self.TITLE.setLabel('[UPPERCASE]' + config.get_localized_string(60230).replace(':','') + '[/UPPERCASE]')
self.ID.setLabel(self.idtitle)
self.setFocusId(101)
def onClick(self, control):
if control in [101]:
result = dialog_input(self.title)
if result:
if self.item.contentType == 'movie': self.item.contentTitle = result
else: self.item.contentSerieName = result
self.close()
elif control in [102]:
result = dialog_numeric(0, self.idtitle, self.id)
if result:
if self.scraper == 'tmdb': self.item.infoLabels['tmdb_id'] = result
elif self.scraper == 'tvdb': self.item.infoLabels['tvdb_id'] = result
self.close()
elif control in [103, 104]:
self.item.exit = True
self.close()
def onAction(self, action):
action = action.getId()
if action in [92, 10]:
self.item.exit = True
self.close()
dialog = TitleOrIDWindow('TitleOrIDWindow.xml', config.get_runtime_path()).Start(item, scraper)
return dialog
def itemlist_refresh():
# pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
@@ -202,7 +256,7 @@ def render_items(itemlist, parent_item):
"""
Function used to render itemlist on kodi
"""
logger.info('START render_items')
logger.debug('START render_items')
thumb_type = config.get_setting('video_thumbnail_type')
from platformcode import shortcuts
# from core import httptools
@@ -287,7 +341,7 @@ def render_items(itemlist, parent_item):
set_view_mode(itemlist[0], parent_item)
xbmcplugin.endOfDirectory(_handle)
logger.info('END render_items')
logger.debug('END render_items')
def getCurrentView(item=None, parent_item=None):
@@ -344,11 +398,11 @@ def set_view_mode(item, parent_item):
if content:
mode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
if mode == 0:
logger.info('default mode')
logger.debug('default mode')
mode = 55
xbmcplugin.setContent(handle=int(sys.argv[1]), content=Type)
xbmc.executebuiltin('Container.SetViewMode(%s)' % mode)
logger.info('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content)
logger.debug('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content)
def set_infolabels(listitem, item, player=False):
@@ -568,10 +622,10 @@ def is_playing():
def play_video(item, strm=False, force_direct=False, autoplay=False):
logger.info()
logger.debug()
logger.debug(item.tostring('\n'))
if item.channel == 'downloads':
logger.info("Play local video: %s [%s]" % (item.title, item.url))
logger.debug("Play local video: %s [%s]" % (item.title, item.url))
xlistitem = xbmcgui.ListItem(path=item.url)
xlistitem.setArt({"thumb": item.thumbnail})
set_infolabels(xlistitem, item, True)
@@ -579,18 +633,22 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
return
default_action = config.get_setting("default_action")
logger.info("default_action=%s" % default_action)
logger.debug("default_action=%s" % default_action)
# pass referer
from core import httptools
httptools.default_headers['Referer'] = item.referer
# Open the selection dialog to see the available options
opciones, video_urls, seleccion, salir = get_dialogo_opciones(item, default_action, strm, autoplay)
if salir: return
if salir: exit()
# get default option of addon configuration
seleccion = get_seleccion(default_action, opciones, seleccion, video_urls)
if seleccion < 0: return # Canceled box
if seleccion < 0: exit() # Canceled box
logger.info("selection=%d" % seleccion)
logger.info("selection=%s" % opciones[seleccion])
logger.debug("selection=%d" % seleccion)
logger.debug("selection=%s" % opciones[seleccion])
# run the available option, jdwonloader, download, favorites, add to the video library ... IF IT IS NOT PLAY
salir = set_opcion(item, seleccion, opciones, video_urls)
@@ -751,7 +809,7 @@ def alert_unsopported_server():
def handle_wait(time_to_wait, title, text):
logger.info("handle_wait(time_to_wait=%d)" % time_to_wait)
logger.debug("handle_wait(time_to_wait=%d)" % time_to_wait)
espera = dialog_progress(' ' + title, "")
secs = 0
@@ -770,15 +828,15 @@ def handle_wait(time_to_wait, title, text):
break
if cancelled:
logger.info('Wait canceled')
logger.debug('Wait canceled')
return False
else:
logger.info('Wait finished')
logger.debug('Wait finished')
return True
def get_dialogo_opciones(item, default_action, strm, autoplay):
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
from core import servertools
@@ -827,10 +885,6 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
# "Add to Favorites"
opciones.append(config.get_localized_string(30155))
if not strm and item.contentType == 'movie' and item.channel != 'videolibrary':
# "Add to video library"
opciones.append(config.get_localized_string(30161))
if default_action == 3:
seleccion = len(opciones) - 1
@@ -844,13 +898,14 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
if not autoplay:
if item.server != "":
if "<br/>" in motivo:
ret = dialog_yesno(config.get_localized_string(60362), motivo.split("<br/>")[0] + '\n' + motivo.split("<br/>")[1] + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, motivo.split("<br/>")[0] + '\n' + motivo.split("<br/>")[1], nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), motivo + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, motivo, nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363) + '\n' + config.get_localized_string(60364) + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, config.get_localized_string(60363) + '\n' + config.get_localized_string(60364), nolabel='ok', yeslabel=config.get_localized_string(70739))
if ret:
xbmc.executebuiltin("Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
xbmc.executebuiltin("Container.Update (%s?%s)" %
(sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
if item.channel == "favorites":
# "Remove from favorites"
opciones.append(config.get_localized_string(30154))
@@ -862,7 +917,7 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
def set_opcion(item, seleccion, opciones, video_urls):
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
salir = False
# You have not chosen anything, most likely because you have given the ESC
@@ -912,7 +967,7 @@ def set_opcion(item, seleccion, opciones, video_urls):
def get_video_seleccionado(item, seleccion, video_urls):
logger.info()
logger.debug()
mediaurl = ""
view = False
wait_time = 0
@@ -938,7 +993,7 @@ def get_video_seleccionado(item, seleccion, video_urls):
mpd = True
# If there is no mediaurl it is because the video is not there :)
logger.info("mediaurl=" + mediaurl)
logger.debug("mediaurl=" + mediaurl)
if mediaurl == "":
if item.server == "unknown":
alert_unsopported_server()
@@ -955,7 +1010,7 @@ def get_video_seleccionado(item, seleccion, video_urls):
def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=None, item_nfo=None):
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
# Moved del conector "torrent" here
if item.server == "torrent":
@@ -969,7 +1024,10 @@ def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=No
xbmc_player.setSubtitles(item.subtitle)
else:
player_mode = config.get_setting("player_mode")
if type(item.player_mode) == int:
player_mode = item.player_mode
else:
player_mode = config.get_setting("player_mode")
if (player_mode == 3 and mediaurl.startswith("rtmp")) or item.play_from == 'window' or item.nfo: player_mode = 0
elif "megacrypter.com" in mediaurl: player_mode = 3
logger.info("mediaurl=" + mediaurl)
@@ -989,9 +1047,10 @@ def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=No
elif player_mode == 1:
logger.info('Player Mode: setResolvedUrl')
xlistitem.setPath(mediaurl)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem)
xbmc.sleep(2500)
# xlistitem.setPath(mediaurl)
par = int(sys.argv[1])
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=mediaurl))
# xbmc.sleep(2500)
elif player_mode == 2:
logger.info('Player Mode: Built-In')
@@ -1038,7 +1097,7 @@ def torrent_client_installed(show_tuple=False):
def play_torrent(item, xlistitem, mediaurl):
logger.info()
logger.debug()
import time
from servers import torrent
@@ -1074,7 +1133,7 @@ def play_torrent(item, xlistitem, mediaurl):
torrent.mark_auto_as_watched(item)
while is_playing() and not xbmc.abortRequested:
while is_playing() and not xbmc.Monitor().abortRequested():
time.sleep(3)

View File

@@ -65,7 +65,7 @@ class Recaptcha(xbmcgui.WindowXMLDialog):
data = httptools.downloadpage(self.url, post=post, headers=self.headers).data
from platformcode import logger
logger.info(data)
logger.debug(data)
self.result = scrapertools.find_single_match(data, '<div class="fbc-verification-token">.*?>([^<]+)<')
if self.result:
platformtools.dialog_notification("Captcha corretto", "Verifica conclusa")

View File

@@ -126,7 +126,7 @@ def SettingOnPosition(item):
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.kod)')
category = item.category if item.category else 0
setting = item.setting if item.setting else 0
logger.info('SETTING= ' + str(setting))
logger.debug('SETTING= ' + str(setting))
xbmc.executebuiltin('SetFocus(%i)' % (category - 100))
xbmc.executebuiltin('SetFocus(%i)' % (setting - 80))

View File

@@ -43,7 +43,7 @@ def set_menu_settings(item):
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def check_user_home(item):
logger.info()
logger.debug()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
if 'user_home' in menu_node:
@@ -55,7 +55,7 @@ def check_user_home(item):
return item
def set_custom_start(item):
logger.info()
logger.debug()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
else:
@@ -69,7 +69,7 @@ def set_custom_start(item):
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def get_start_page():
logger.info()
logger.debug()
dictCategory = {
config.get_localized_string(70137): 'peliculas',
@@ -355,7 +355,7 @@ class Main(xbmcgui.WindowXMLDialog):
self.focus -= 1
def run_action(self, item):
logger.info()
logger.debug()
if item.menu != True:
self.close()
xbmc.executebuiltin("Container.update(%s)"%launcher.run(item))

View File

@@ -84,7 +84,7 @@ def regex_tvshow(compare, file, sub=""):
def set_Subtitle():
logger.info()
logger.debug()
exts = [".srt", ".sub", ".txt", ".smi", ".ssa", ".ass"]
subtitle_folder_path = filetools.join(config.get_data_path(), "subtitles")
@@ -216,7 +216,7 @@ def searchSubtitle(item):
filetools.mkdir(full_path_tvshow) # title_new + ".mp4"
full_path_video_new = xbmc.translatePath(
filetools.join(full_path_tvshow, "%s %sx%s.mp4" % (tvshow_title, season, episode)))
logger.info(full_path_video_new)
logger.debug(full_path_video_new)
listitem = xbmcgui.ListItem(title_new, iconImage="DefaultVideo.png", thumbnailImage="")
listitem.setInfo("video", {"Title": title_new, "Genre": "Tv shows", "episode": int(episode), "season": int(season), "tvshowtitle": tvshow_title})
@@ -230,7 +230,7 @@ def searchSubtitle(item):
try:
filetools.copy(path_video_temp, full_path_video_new)
copy = True
logger.info("nuevo path =" + full_path_video_new)
logger.debug("nuevo path =" + full_path_video_new)
time.sleep(2)
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear()
@@ -288,7 +288,7 @@ def get_from_subdivx(sub_url):
:return: The path to the unzipped subtitle
"""
logger.info()
logger.debug()
sub = ''
sub_dir = os.path.join(config.get_data_path(), 'temp_subs')
@@ -312,9 +312,9 @@ def get_from_subdivx(sub_url):
filetools.write(filename, data_dl)
sub = extract_file_online(sub_dir, filename)
except:
logger.info('sub invalid')
logger.debug('sub invalid')
else:
logger.info('sub invalid')
logger.debug('sub invalid')
return sub
@@ -328,7 +328,7 @@ def extract_file_online(path, filename):
:return:
"""
logger.info()
logger.debug()
url = "http://online.b1.org/rest/online/upload"

View File

@@ -1,14 +1,21 @@
# -*- coding: utf-8 -*-
import xbmcgui
import xbmcgui, sys
from core.tmdb import Tmdb
from platformcode import config, logger
from core import filetools
if sys.version_info[0] >= 3:
from concurrent import futures
else:
from concurrent_py2 import futures
BACKGROUND = 30000
LOADING = 30001
SELECT = 30002
CLOSE = 30003
EXIT = 10
BACKSPACE = 92
def imagepath(image):
if len(image.split('.')) == 1: image += '.png'
@@ -25,23 +32,30 @@ class InfoWindow(xbmcgui.WindowXMLDialog):
self.scraper = scraper
self.doModal()
logger.info('RESPONSE',self.response)
logger.debug('RESPONSE',self.response)
return self.response
def make_items(self, i, result):
infoLabels = self.scraper().get_infoLabels(origen=result)
it = xbmcgui.ListItem(infoLabels['title'])
it.setProperty('fanart', infoLabels.get('fanart', ''))
it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv')))
it.setProperty('genre', infoLabels.get('genre', 'N/A'))
it.setProperty('rating', str(infoLabels.get('rating', 'N/A')))
it.setProperty('plot', str(infoLabels.get('plot', '')))
it.setProperty('year', str(infoLabels.get('year', '')))
it.setProperty('position', str(i))
return it
def onInit(self):
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
for result in self.results:
infoLabels = self.scraper().get_infoLabels(origen=result)
it = xbmcgui.ListItem(infoLabels['title'])
it.setProperty('fanart', infoLabels.get('fanart', ''))
it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv')))
it.setProperty('genre', infoLabels.get('genre', 'N/A'))
it.setProperty('rating', str(infoLabels.get('rating', 'N/A')))
it.setProperty('plot', str(infoLabels.get('plot', '')))
it.setProperty('year', str(infoLabels.get('year', '')))
self.items.append(it)
with futures.ThreadPoolExecutor() as executor:
for i, result in enumerate(self.results):
logger.debug(result)
if ('seriesName' in result and result['seriesName']) or ('name' in result and result['name']) or ('title' in result and result['title']):
self.items += [executor.submit(self.make_items, i, result).result()]
self.items.sort(key=lambda it: int(it.getProperty('position')))
self.getControl(SELECT).addItems(self.items)
self.getControl(BACKGROUND).setImage(self.items[0].getProperty('fanart'))
@@ -51,5 +65,16 @@ class InfoWindow(xbmcgui.WindowXMLDialog):
def onClick(self, control_id):
if control_id == SELECT:
self.response = self.results[self.getControl(SELECT).getSelectedPosition()]
self.close()
self.close()
elif control_id == CLOSE:
self.close()
def onAction(self, action):
if self.getFocusId() in [SELECT]:
fanart = self.getControl(self.getFocusId()).getSelectedItem().getProperty('fanart')
self.getControl(BACKGROUND).setImage(fanart)
if action in [BACKSPACE]:
self.close()
elif action in [EXIT]:
self.close()

View File

@@ -22,7 +22,7 @@ from xml.dom import minidom
def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
def mark_as_watched_subThread(item, nfo_path, head_nfo, item_nfo):
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
time_limit = time.time() + 30
@@ -53,7 +53,7 @@ def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
# Mark as Watched
if actual_time > mark_time and not marked:
logger.debug("Marked as Watched")
logger.info("Marked as Watched")
item.playcount = 1
marked = True
show_server = False
@@ -104,7 +104,7 @@ def sync_trakt_addon(path_folder):
"""
Updates the values of episodes seen if
"""
logger.info()
logger.debug()
# if the addon exists we do the search
if xbmc.getCondVisibility('System.HasAddon("script.trakt")'):
# we import dependencies
@@ -230,7 +230,7 @@ def sync_trakt_kodi(silent=True):
notificacion = False
xbmc.executebuiltin('RunScript(script.trakt,action=sync,silent=%s)' % silent)
logger.info("Synchronization with Trakt started")
logger.debug("Synchronization with Trakt started")
if notificacion:
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(60045), sound=False, time=2000)
@@ -244,7 +244,7 @@ def mark_content_as_watched_on_kodi(item, value=1):
@type value: int
@param value: > 0 for seen, 0 for not seen
"""
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
payload_f = ''
@@ -316,7 +316,7 @@ def mark_season_as_watched_on_kodi(item, value=1):
@type value: int
@param value: > 0 for seen, 0 for not seen
"""
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
# We can only mark the season as seen in the Kodi database if the database is local, in case of sharing database this functionality will not work
@@ -350,7 +350,7 @@ def mark_content_as_watched_on_kod(path):
@type str: path
@param path: content folder to mark
"""
logger.info()
logger.debug()
#logger.debug("path: " + path)
FOLDER_MOVIES = config.get_setting("folder_movies")
@@ -443,7 +443,7 @@ def get_data(payload):
import urllib.request as urllib
except ImportError:
import urllib
logger.info("payload: %s" % payload)
logger.debug("payload: %s" % payload)
# Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type
headers = {'content-type': 'application/json'}
@@ -460,7 +460,7 @@ def get_data(payload):
response = f.read()
f.close()
logger.info("get_data: response %s" % response)
logger.debug("get_data: response %s" % response)
data = jsontools.load(response)
except Exception as ex:
template = "An exception of type %s occured. Arguments:\n%r"
@@ -476,7 +476,7 @@ def get_data(payload):
logger.error("error en xbmc.executeJSONRPC: %s" % message)
data = ["error"]
logger.info("data: %s" % data)
logger.debug("data: %s" % data)
return data
@@ -490,7 +490,7 @@ def update(folder_content=config.get_setting("folder_tvshows"), folder=""):
@type folder: str
@param folder: name of the folder to scan.
"""
logger.info(folder)
logger.debug(folder)
payload = {
"jsonrpc": "2.0",
@@ -554,7 +554,7 @@ def set_content(content_type, silent=False, custom=False):
@type content_type: str ('movie' o 'tvshow')
@param content_type: content type to configure, series or movies
"""
logger.info()
logger.debug()
continuar = True
msg_text = ""
videolibrarypath = config.get_setting("videolibrarypath")
@@ -580,7 +580,7 @@ def set_content(content_type, silent=False, custom=False):
try:
# Install metadata.themoviedb.org
xbmc.executebuiltin('InstallAddon(metadata.themoviedb.org)', True)
logger.info("Instalado el Scraper de películas de TheMovieDB")
logger.debug("Instalado el Scraper de películas de TheMovieDB")
except:
pass
@@ -634,7 +634,7 @@ def set_content(content_type, silent=False, custom=False):
try:
# Install metadata.tvdb.com
xbmc.executebuiltin('InstallAddon(metadata.tvdb.com)', True)
logger.info("The TVDB series Scraper installed ")
logger.debug("The TVDB series Scraper installed ")
except:
pass
@@ -729,7 +729,7 @@ def set_content(content_type, silent=False, custom=False):
strScraper = 'metadata.universal'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.universal/settings.xml")
if not os.path.exists(path_settings):
logger.info("%s: %s" % (content_type, path_settings + " doesn't exist"))
logger.debug("%s: %s" % (content_type, path_settings + " doesn't exist"))
return continuar
settings_data = filetools.read(path_settings)
strSettings = ' '.join(settings_data.split()).replace("> <", "><")
@@ -748,7 +748,7 @@ def set_content(content_type, silent=False, custom=False):
strScraper = 'metadata.tvshows.themoviedb.org'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml")
if not os.path.exists(path_settings):
logger.info("%s: %s" % (content_type, path_settings + " doesn't exist"))
logger.debug("%s: %s" % (content_type, path_settings + " doesn't exist"))
return continuar
settings_data = filetools.read(path_settings)
strSettings = ' '.join(settings_data.split()).replace("> <", "><")
@@ -758,7 +758,7 @@ def set_content(content_type, silent=False, custom=False):
videolibrarypath += sep
strPath = videolibrarypath + config.get_setting("folder_tvshows") + sep
logger.info("%s: %s" % (content_type, strPath))
logger.debug("%s: %s" % (content_type, strPath))
# We check if strPath already exists in the DB to avoid duplicates
sql = 'SELECT idPath FROM path where strPath="%s"' % strPath
nun_records, records = execute_sql_kodi(sql)
@@ -800,15 +800,15 @@ def set_content(content_type, silent=False, custom=False):
heading = config.get_localized_string(70103) % content_type
msg_text = config.get_localized_string(70104)
logger.info("%s: %s" % (heading, msg_text))
logger.debug("%s: %s" % (heading, msg_text))
return continuar
def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvshows_folder, new_tvshows_folder, progress):
def path_replace(path, old, new):
logger.info()
logger.info('path: ' + path + ', old: ' + old + ', new: ' + new)
logger.debug()
logger.debug('path: ' + path + ', old: ' + old + ', new: ' + new)
if new.startswith("special://") or '://' in new: sep = '/'
else: sep = os.sep
@@ -819,7 +819,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
return path
logger.info()
logger.debug()
sql_old_path = old_path
if sql_old_path.startswith("special://"):
@@ -831,10 +831,10 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
if not sql_old_path.endswith(sep):
sql_old_path += sep
logger.info('sql_old_path: ' + sql_old_path)
logger.debug('sql_old_path: ' + sql_old_path)
# search MAIN path in the DB
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# change main path
@@ -842,7 +842,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = records[0][0]
strPath = path_replace(records[0][1], old_path, new_path)
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
else:
progress.update(100)
@@ -859,7 +859,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
# Search Main Sub Folder
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# Change Main Sub Folder
@@ -868,13 +868,13 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# Search if Sub Folder exixt in all paths
sql_old_folder += '%'
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
#Change Sub Folder in all paths
@@ -883,7 +883,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
@@ -891,27 +891,27 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
# if is Movie Folder
# search and modify in "movie"
sql = 'SELECT idMovie, c22 FROM movie where c22 LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
for record in records:
idMovie = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE movie SET c22="%s" WHERE idMovie=%s' % (strPath, idMovie)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
else:
# if is TV Show Folder
# search and modify in "episode"
sql = 'SELECT idEpisode, c18 FROM episode where c18 LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
for record in records:
idEpisode = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE episode SET c18="%s" WHERE idEpisode=%s' % (strPath, idEpisode)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
p += 5
progress.update(p, config.get_localized_string(20000) + '\n' + config.get_localized_string(80013))
@@ -936,26 +936,26 @@ def clean(path_list=[]):
return path, sep
logger.info()
logger.debug()
progress = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80025))
progress.update(0)
# if the path list is empty, clean the entire video library
if not path_list:
logger.info('the path list is empty, clean the entire video library')
logger.debug('the path list is empty, clean the entire video library')
if not config.get_setting("videolibrary_kodi"):
sql_path, sep = sql_format(config.get_setting("videolibrarypath"))
if not sql_path.endswith(sep): sql_path += sep
sql = 'SELECT idPath FROM path where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
idPath = records[0][0]
sql = 'DELETE from path WHERE idPath=%s' % idPath
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
sql = 'DELETE from path WHERE idParentPath=%s' % idPath
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
from core import videolibrarytools
@@ -969,7 +969,7 @@ def clean(path_list=[]):
if filetools.exists(tvshow_nfo):
path_list.append(filetools.join(config.get_setting("videolibrarypath"), videolibrarytools.FOLDER_TVSHOWS, folder))
logger.info('path_list: ' + str(path_list))
logger.debug('path_list: ' + str(path_list))
if path_list: t = float(100) / len(path_list)
for i, path in enumerate(path_list):
progress.update(int(math.ceil((i + 1) * t)))
@@ -979,13 +979,13 @@ def clean(path_list=[]):
sql_path, sep = sql_format(path)
if filetools.isdir(path) and not sql_path.endswith(sep): sql_path += sep
logger.info('path: ' + path)
logger.info('sql_path: ' + sql_path)
logger.debug('path: ' + path)
logger.debug('sql_path: ' + sql_path)
if filetools.isdir(path):
# search movie in the DB
sql = 'SELECT idMovie FROM movie where c22 LIKE "%s"' % (sql_path + '%')
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete movie
if records:
@@ -994,7 +994,7 @@ def clean(path_list=[]):
continue
# search TV show in the DB
sql = 'SELECT idShow FROM tvshow_view where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete TV show
if records:
@@ -1003,7 +1003,7 @@ def clean(path_list=[]):
elif config.get_setting("folder_movies") in sql_path:
# search movie in the DB
sql = 'SELECT idMovie FROM movie where c22 LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete movie
if records:
@@ -1012,7 +1012,7 @@ def clean(path_list=[]):
else:
# search episode in the DB
sql = 'SELECT idEpisode FROM episode where c18 LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete episode
if records:
@@ -1031,7 +1031,7 @@ def check_db(path):
ret = False
sql_path = '%' + sep + path.split(sep)[-1] + sep + '%'
sql = 'SELECT idShow FROM tvshow_view where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
ret = True
@@ -1048,7 +1048,7 @@ def execute_sql_kodi(sql):
@return: list with the query result
@rtype records: list of tuples
"""
logger.info()
logger.debug()
file_db = ""
nun_records = 0
records = None
@@ -1069,14 +1069,14 @@ def execute_sql_kodi(sql):
break
if file_db:
logger.info("DB file: %s" % file_db)
logger.debug("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.info("Running sql: %s" % sql)
logger.debug("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
@@ -1090,7 +1090,7 @@ def execute_sql_kodi(sql):
nun_records = conn.total_changes
conn.close()
logger.info("Query executed. Records: %s" % nun_records)
logger.debug("Query executed. Records: %s" % nun_records)
except:
logger.error("Error executing sql query")
@@ -1110,7 +1110,7 @@ def check_sources(new_movies_path='', new_tvshows_path=''):
if not path.endswith(sep): path += sep
return path
logger.info()
logger.debug()
new_movies_path = format_path(new_movies_path)
new_tvshows_path = format_path(new_tvshows_path)
@@ -1140,7 +1140,7 @@ def check_sources(new_movies_path='', new_tvshows_path=''):
def update_sources(new='', old=''):
logger.info()
logger.debug()
if new == old: return
SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml")
@@ -1182,9 +1182,9 @@ def update_sources(new='', old=''):
# create new path
list_path = [p.firstChild.data for p in paths_node]
if new in list_path:
logger.info("The path %s already exists in sources.xml" % new)
logger.debug("The path %s already exists in sources.xml" % new)
return
logger.info("The path %s does not exist in sources.xml" % new)
logger.debug("The path %s does not exist in sources.xml" % new)
# if the path does not exist we create one
source_node = xmldoc.createElement("source")
@@ -1223,7 +1223,7 @@ def update_sources(new='', old=''):
def ask_set_content(silent=False):
logger.info()
logger.debug()
logger.debug("videolibrary_kodi %s" % config.get_setting("videolibrary_kodi"))
def do_config(custom=False):
@@ -1280,7 +1280,7 @@ def ask_set_content(silent=False):
def next_ep(item):
from core.item import Item
logger.info()
logger.debug()
item.next_ep = False
# check if next file exist
@@ -1296,7 +1296,7 @@ def next_ep(item):
nextIndex = fileList.index(current_filename) + 1
if nextIndex == 0 or nextIndex == len(fileList): next_file = None
else: next_file = fileList[nextIndex]
logger.info('Next File:' + str(next_file))
logger.debug('Next File:' + str(next_file))
# start next episode window afther x time
if next_file:

View File

@@ -589,7 +589,7 @@ msgid "%.2f %s of %.2f %s a %.2f %s/s (%d/%d)"
msgstr ""
msgctxt "#59985"
msgid "Error in the channel "
msgid "Channel %s unreachable"
msgstr ""
msgctxt "#59986"
@@ -669,7 +669,7 @@ msgid ""
msgstr ""
msgctxt "#60006"
msgid "An error has occurred in %s"
msgid "[B]An error has occurred in %s:[/B]"
msgstr ""
msgctxt "#60007"
@@ -697,15 +697,15 @@ msgid "No video to play"
msgstr ""
msgctxt "#60013"
msgid "This website seems to be unavailable, try later, if the problem persists, check with a browser: %s. If the web page is working correctly, please report the error on : https://t.me/kodiondemand"
msgid "This website [B]%s[/B] seems to be unavailable, try later. if the web page is working correctly, please report the error on: https://github.com/kodiondemand/addon/issues"
msgstr ""
msgctxt "#60014"
msgid "It may be due to a connection problem, the web page of the channel has changed its structure, or an internal error of KoD. To have more details, see the log file."
msgid "It may be due to a connection problem, the web page of the channel has changed its structure, or an internal error of KoD. If on browser it works, report the issue using [B]Help->Report an issue.[B]"
msgstr ""
msgctxt "#60015"
msgid "Check the log for more details on the error."
msgid "Do you want to report the issue?\n(Be sure you follow all steps and give a clear and comprehensive explanation of what happened"
msgstr ""
msgctxt "#60016"
@@ -800,8 +800,8 @@ msgctxt "#60038"
msgid "An error has occurred in KoD"
msgstr ""
msgctxt "#60039"
msgid "Error on channel %s"
msgctxt "60039"
msgid "Channel %s unreachable"
msgstr ""
msgctxt "#60040"
@@ -1633,7 +1633,7 @@ msgid "Super favourites menu"
msgstr ""
msgctxt "#60362"
msgid "You can't watch this video because..."
msgid "Unexpected error on server %s"
msgstr ""
msgctxt "#60363"
@@ -6086,6 +6086,44 @@ msgctxt "#70821"
msgid "Search results"
msgstr ""
# RENUMBER
msgctxt "#70822"
msgid "Renumber new episodes of: "
msgstr ""
msgctxt "#70823"
msgid "Renumber episodes of: "
msgstr ""
msgctxt "#70824"
msgid "Select the specials of: "
msgstr ""
msgctxt "#70825"
msgid "Select Season"
msgstr ""
msgctxt "#70826"
msgid "Select Episode"
msgstr ""
msgctxt "#70827"
msgid "Select Specials"
msgstr ""
msgctxt "#70828"
msgid "Manual renumbering"
msgstr ""
msgctxt "#70829"
msgid "Delete Numbering for: "
msgstr ""
msgctxt "#70830"
msgid "The series / episode number should only be changed if the series has relative numbering."
msgstr ""
# DNS start [ settings and declaration ]
msgctxt "#707401"
msgid "Enable DNS check alert"

View File

@@ -588,8 +588,8 @@ msgid "%.2f %s of %.2f %s a %.2f %s/s (%d/%d)"
msgstr "%.2f %s di %.2f %s a %.2f %s/s (%d/%d)"
msgctxt "#59985"
msgid "Error in the channel "
msgstr "Errore nel canale "
msgid "Channel %s unreachable"
msgstr "Canale %s irraggiungibile"
msgctxt "#59986"
msgid "Error loading the server: %s\n"
@@ -668,8 +668,8 @@ msgid ""
msgstr ""
msgctxt "#60006"
msgid "An error has occurred in %s"
msgstr "Si è verificato un errore in %s"
msgid "[B]An error has occurred in %s:[/B]"
msgstr "[B]Si è verificato un errore in %s:[/B]"
msgctxt "#60007"
msgid "An error has occurred on %s"
@@ -696,16 +696,16 @@ msgid "No video to play"
msgstr "Nessun video da riprodurre"
msgctxt "#60013"
msgid "This website seems to be unavailable, try later, if the problem persists, check with a browser: %s. If the web page is working correctly, please report the error on : https://t.me/kodiondemand"
msgstr "Questo sito non sembra essere disponibile, riprova più tardi, se il problema persiste verifica mediante un browser: %s. Se la pagina web funziona correttamente segnala l'errore su : https://t.me/kodiondemand"
msgid "This website [B]%s[/B] seems to be unavailable, try later. if the web page is working correctly, please report the error on: https://github.com/kodiondemand/addon/issues"
msgstr "Il sito [B]%s[/B] non sembra essere disponibile, riprova più tardi. Se la pagina web funziona correttamente segnala l'errore qui: https://github.com/kodiondemand/addon/issues"
msgctxt "#60014"
msgid "It may be due to a connection problem, the web page of the channel has changed its structure, or an internal error of KoD. To have more details, see the log file."
msgstr "Potrebbe essere dovuto a un problema di connessione, la pagina web del canale ha cambiato la sua struttura, oppure un errore interno di KoD. Per avere maggiori dettagli, consulta il file di log."
msgid "It may be due to a connection problem, the web page of the channel has changed its structure, or an internal error of KoD. If on browser it works, report the issue using [B]Help->Report an issue.[B]"
msgstr "Potrebbe essere dovuto a un problema di connessione, la pagina web del canale ha cambiato la sua struttura, oppure un errore interno di KoD. Se sul browser funziona, segnala il problema andando in [B]Aiuto->Segnala un problema[/B]."
msgctxt "#60015"
msgid "Check the log for more details on the error."
msgstr "Controlla il log per avere maggiori dettagli sull'errore."
msgid "Do you want to report the issue?\n(Be sure you follow all steps and give a clear and comprehensive explanation of what happened"
msgstr "Vuoi fare una segnalazione agli sviluppatori?\n(Assicurati di seguire bene tutti i punti e dai una spiegazione chiara ed esaustiva di quanto accaduto)"
msgctxt "#60016"
msgid "Segna film come non visto"
@@ -1632,8 +1632,8 @@ msgid "Super favourites menu"
msgstr "Menu super favoriti"
msgctxt "#60362"
msgid "You can't watch this video because..."
msgstr "Non è possibile vedere questo video perchè..."
msgid "Unexpected error on server %s"
msgstr "Errore inaspettato sul server %s"
msgctxt "#60363"
msgid "The server on which it is hosted"
@@ -6087,6 +6087,43 @@ msgctxt "#70821"
msgid "Search results"
msgstr "Risultati della ricerca"
# RENUMBER
msgctxt "#70822"
msgid "Renumber new episodes of: "
msgstr "Rinumera i nuovi episodi di: "
msgctxt "#70823"
msgid "Renumber episodes of: "
msgstr "Rinumera gli episodi di: "
msgctxt "#70824"
msgid "Select the specials of: "
msgstr "Seleziona gli speciali di: "
msgctxt "#70825"
msgid "Select Season"
msgstr "Seleziona Stagione"
msgctxt "#70826"
msgid "Select Episode"
msgstr "Seleziona Episodio"
msgctxt "#70827"
msgid "Select Specials"
msgstr "Seleziona Speciali"
msgctxt "#70828"
msgid "Manual renumbering"
msgstr "Rinumerazione Manuale"
msgctxt "#70829"
msgid "Delete Numbering for: "
msgstr "Elimina Numerazione per: "
msgctxt "#70830"
msgid "The series / episode number should only be changed if the series has relative numbering."
msgstr "Il numero della serie / episodio deve essere modificato solo se la serie ha una numerazione relativa."
# DNS start [ settings and declaration ]
msgctxt "#707401"
msgid "Enable DNS check alert"

View File

@@ -81,6 +81,7 @@
<!-- Search -->
<category label="60423">
<setting label="60422" type="lsep"/>
<setting id="new_search" type="bool" label="Usa la nuova ricerca globale dove disponibile" default="true" visible="true"/>
<setting id="last_search" type="bool" label="60678" default="true" visible="true"/>
<setting id="saved_searches_limit" type="slider" option="int" range="10,10,40" label="60677" default="10" visible="eq(-1,0)" subsetting="true"/>
<setting id="result_mode" type="select" label="60657" lvalues="60675|60676" default="0"/>

View File

@@ -0,0 +1,627 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<window>
<depth>0.52</depth>
<coordinates>
<left>0</left>
<top>0</top>
</coordinates>
<controls>
<!-- control groups -->
<control type='group' id="1"/>
<control type='group' id="2"/>
<control type='group' id="3"/>
<control type='group' id="4"/>
<control type='group' id="5"/>
<control type="image"> <!-- BACKGROUND -->
<description>Window Background</description>
<width>100%</width>
<height>100%</height>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<control type="group"> <!-- CONTROLS GROUP -->
<description>Main Group</description>
<left>0</left>
<top>0</top>
<animation type="WindowOpen" reversible="false">
<effect type="fade" delay="160" end="100" time="300" />
</animation>
<animation type="WindowClose" reversible="false">
<effect type="fade" delay="160" start="100" end="0" time="300" />
</animation>
<control type="image">
<description>Fanart</description>
<width>100%</width>
<height>100%</height>
<aspectratio>scale</aspectratio>
<texture colordiffuse="FF555555">$INFO[Container(102).ListItem.Property(fanart)]</texture>
</control>
<control type="group"> <!-- SEARCH GROUP-->
<description>Search Group</description>
<visible>Control.IsVisible(1)</visible>
<control type="textbox" id='100'>
<description>Title</description>
<left>30</left>
<top>30</top>
<width>1000</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<visible>Integer.IsGreater(Container(101).NumItems, 0)</visible>
<align>left</align>
<aligny>center</aligny>
</control>
<control type="group"> <!-- Search Result Group -->
<description>Search Result Group</description>
<visible>Integer.IsGreater(Container(102).NumItems, 0)</visible>
<animation effect="fade" time="200">Visible</animation>
<control type="textbox">
<description>Item Title</description>
<left>400</left>
<top>90</top>
<width>840</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[Container(102).ListItem.Label] [B][COLOR FFAAAAAA]$INFO[Container(102).ListItem.Property(year)][/COLOR][/B]</label>
<align>left</align>
<aligny>center</aligny>
</control>
<control type="textbox">
<description>Item Title</description>
<right>40</right>
<top>90</top>
<width>200</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B][COLOR FFAAAAAA]$INFO[Container(102).CurrentItem]/$INFO[Container(102).NumItems][/COLOR][/B]</label>
<align>right</align>
<aligny>center</aligny>
</control>
<control type="textbox">
<description>Item Plot</description>
<left>400</left>
<top>150</top>
<width>840</width>
<height>170</height>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[Container(102).ListItem.Property(plot)]</label>
<align>left</align>
</control>
<control type="wraplist" id="102">
<description>Search Results list</description>
<bottom>70</bottom>
<left>0</left>
<width>100%</width>
<height>570</height>
<ondown>101</ondown>
<onup>503</onup>
<orientation>horizontal</orientation>
<scrolltime tween="cubic" easing="out">300</scrolltime>
<itemlayout height="570" width="180">
<control type="image">
<description>Item Poster</description>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
<texture>$INFO[ListItem.Property(thumb)]</texture>
<bordersize>10</bordersize>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Item Verified</description>
<top>315</top>
<left>145</left>
<width>20</width>
<height>20</height>
<texture colordiffuse="FF0082C2">$INFO[ListItem.Property(verified)]</texture>
<aspectratio>scale</aspectratio>
</control>
</itemlayout>
<focusedlayout height="570" width="380">
<control type="image">
<description>Item Poster</description>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>
<texture>$INFO[ListItem.Property(thumb)]</texture>
<bordersize>10</bordersize>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Item Verified</description>
<top>15</top>
<left>330</left>
<width>40</width>
<height>40</height>
<texture colordiffuse="FF0082C2">$INFO[ListItem.Property(verified)]</texture>
<aspectratio>scale</aspectratio>
</control>
</focusedlayout>
</control>
</control> <!-- END Search Result Group -->
<control type="group"> <!-- Chennels Group-->
<description>Chennels Group</description>
<bottom>-100</bottom>
<width>100%</width>
<height>150</height>
<animation effect="slide" start="0,150" time="500" condition="Integer.IsGreater(Container(101).NumItems, 0)">Conditional</animation>
<animation effect="slide" start="0,-100" time="200" condition="!Control.HasFocus(101)">Conditional</animation>
<visible>Integer.IsGreater(Container(101).NumItems, 0)</visible>
<control type="image">
<description>Chennels Bar Background Opacity on hover</description>
<width>100%</width>
<height>100%</height>
<animation effect="fade" start='100' end='0' time="200" condition="!Control.HasFocus(101)">Conditional</animation>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<control type="image">
<description>Chennels Bar Background</description>
<width>100%</width>
<height>100%</height>
<texture colordiffuse="88232323">white.png</texture>
</control>
<control type="list" id="101">
<description>Channels list</description>
<width>100%</width>
<height>150</height>
<onup>102</onup>
<orientation>horizontal</orientation>
<scrolltime tween="cubic" easing="out">300</scrolltime>
<itemlayout height="150" width="150">
<control type="image">
<description>Channel Icon</description>
<top>0</top>
<left>0</left>
<width>150</width>
<height>150</height>
<texture colordiffuse="55FFFFFF">$INFO[ListItem.Property(thumb)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Results Count Background</description>
<top>0</top>
<left>110</left>
<width>40</width>
<height>40</height>
<texture colordiffuse="20232323">white.png</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="textbox">
<description>Results Count</description>
<right>5</right>
<top>5</top>
<width>30</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>22FFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(results)][/B]</label>
<align>center</align>
<aligny>center</aligny>
</control>
<control type="image">
<description>Verified</description>
<top>5</top>
<left>5</left>
<width>30</width>
<height>30</height>
<texture colordiffuse="880082C2">$INFO[ListItem.Property(verified)]</texture>
<aspectratio>scale</aspectratio>
</control>
</itemlayout>
<focusedlayout height="150" width="150">
<control type="image">
<description>Channel Icon</description>
<top>0</top>
<left>0</left>
<width>150</width>
<height>150</height>
<texture>$INFO[ListItem.Property(thumb)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Results Count Background</description>
<top>0</top>
<left>110</left>
<width>40</width>
<height>40</height>
<texture colordiffuse="880082C2">white.png</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Results Count</description>
<top>5</top>
<left>5</left>
<width>30</width>
<height>30</height>
<texture colordiffuse="FF0082C2">$INFO[ListItem.Property(verified)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="textbox">
<description>Verified</description>
<right>5</right>
<top>5</top>
<width>30</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(results)][/B]</label>
<align>center</align>
<aligny>center</aligny>
</control>
</focusedlayout>
</control>
</control> <!-- END Chennels Group-->
</control> <!-- END SEARCH GROUP-->
<control type="group"> <!-- EPISODES GROUP-->
<description>Episodes Group</description>
<visible>Control.IsVisible(2)</visible>
<control type="image">
<description>Poster</description>
<top>0</top>
<left>0</left>
<width>480</width>
<height>720</height>
<texture>$INFO[Container(102).ListItem.Property(thumb)]</texture>
</control>
<control type="textbox">
<description>Main Title</description>
<left>520</left>
<top>40</top>
<width>1150</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>$INFO[Container(102).ListItem.Label()]</label>
</control>
<control type="list" id="200"> <!-- Episodes List -->
<description>Episodes List</description>
<bottom>40</bottom>
<left>520</left>
<width>700</width>
<height>570</height>
<onleft>503</onleft>
<onright>503</onright>
<scrolltime tween="cubic" easing="out">300</scrolltime>
<itemlayout height="60" width="700">
<control type="textbox">
<description>Episode Title</description>
<left>20</left>
<width>660</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>[COLOR FFAAAAAA]$INFO[ListItem.Label()][/COLOR]</label>
</control>
</itemlayout>
<focusedlayout height="60" width="700">
<control type="image">
<description>Selected Background</description>
<width>700</width>
<height>60</height>
<texture colordiffuse="88000000">white.png</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="textbox">
<description>Episode Title</description>
<left>20</left>
<width>660</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>$INFO[ListItem.Label]</label>
</control>
</focusedlayout>
</control> <!-- END Episodes List -->
</control> <!-- END EPISODES GROUP -->
<control type="group"> <!-- SERVERS GROUP-->
<description>Servers Group</description>
<visible>Control.IsVisible(3)</visible>
<control type="image">
<description>Poster</description>
<top>0</top>
<left>0</left>
<width>480</width>
<height>720</height>
<texture>$INFO[Container(102).ListItem.Property(thumb)]</texture>
</control>
<control type="textbox">
<description>Main Title</description>
<left>520</left>
<top>40</top>
<width>1150</width>
<height>30</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>$INFO[Container(102).ListItem.Label]</label>
</control>
<control type="list" id="300"> <!-- Servers List -->
<description>Servers List</description>
<bottom>40</bottom>
<left>520</left>
<width>700</width>
<height>570</height>
<onleft>503</onleft>
<onright>503</onright>
<scrolltime tween="cubic" easing="out">300</scrolltime>
<itemlayout height="140" width="700">
<control type="image">
<description>Servers Icon</description>
<top>5</top>
<left>5</left>
<width>120</width>
<height>120</height>
<texture>$INFO[ListItem.Property(thumb)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="group">
<visible>ListItem.Property(quality)</visible>
<control type="image">
<description>Servers Quality</description>
<top>35</top>
<left>150</left>
<width>60</width>
<height>60</height>
<texture>$INFO[ListItem.Property(quality)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="textbox">
<description>Server Title</description>
<left>220</left>
<top>35</top>
<width>450</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>[B][COLOR FFAAAAAA]$INFO[ListItem.Property(servername)][/COLOR][/B]</label>
</control>
</control>
<control type="textbox">
<visible>!ListItem.Property(quality)</visible>
<description>Server Title</description>
<left>150</left>
<top>35</top>
<width>450</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>[B][COLOR FFAAAAAA]$INFO[ListItem.Property(servername)][/COLOR][/B]</label>
</control>
</itemlayout>
<focusedlayout height="140" width="700">
<control type="image">
<description>Selection Background</description>
<width>700</width>
<height>130</height>
<texture colordiffuse="88000000">white.png</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Servers Color</description>
<top>0</top>
<left>0</left>
<width>130</width>
<height>130</height>
<visible>Control.HasFocus(300)</visible>
<texture colordiffuse="$INFO[ListItem.Property(color)]">white.png</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="image">
<description>Servers Icon</description>
<top>5</top>
<left>5</left>
<width>120</width>
<height>120</height>
<texture>$INFO[ListItem.Property(thumb)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="group">
<visible>ListItem.Property(quality)</visible>
<control type="image">
<description>Servers Quality</description>
<top>35</top>
<left>150</left>
<width>60</width>
<height>60</height>
<texture>$INFO[ListItem.Property(quality)]</texture>
<aspectratio>scale</aspectratio>
</control>
<control type="textbox">
<description>Server Title</description>
<left>220</left>
<top>35</top>
<width>450</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>[B][COLOR FFAAAAAA]$INFO[ListItem.Property(servername)][/COLOR][/B]</label>
</control>
</control>
<control type="textbox">
<visible>!ListItem.Property(quality)</visible>
<description>Server Title</description>
<left>150</left>
<top>35</top>
<width>450</width>
<height>60</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>left</align>
<aligny>center</aligny>
<label>[B][COLOR FFAAAAAA]$INFO[ListItem.Property(servername)][/COLOR][/B]</label>
</control>
</focusedlayout>
</control> <!-- END Servers List -->
</control> <!-- END SERVERS GROUP -->
</control> <!-- CONTROLS GROUP -->
<control type="progress" id="500">
<description>Progress Bar</description>
<top>350</top>
<left>240</left>
<width>800</width>
<height>20</height>
<reveal>true</reveal>
<lefttexture colordiffuse="FF232323">white.png</lefttexture>
<righttexture colordiffuse="FF0082C2">white.png</righttexture>
<texturebg colordiffuse="22ffffff">progress.png</texturebg>
<midtexture colordiffuse="FF0082C2">progress.png</midtexture>
<animation effect="zoom" center="auto" end="163,40" time="600" condition="Integer.IsGreater(Container(102).NumItems, 0)">Conditional</animation>
<animation effect="slide" tween="linear" center="auto" end="0,-890" time="600" condition="Integer.IsGreater(Container(102).NumItems, 0)">Conditional</animation>
</control>
<control type="textbox" id="501">
<description>Progress Count</description>
<top>340</top>
<right>130</right>
<width>200</width>
<height>40</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>right</align>
<aligny>center</aligny>
<animation effect="slide" tween="linear" center="auto" end="-40,-311" time="200" condition="Integer.IsGreater(Container(101).NumItems, 0)">Conditional</animation>
<visible>Control.IsVisible(500)</visible>
</control>
<control type="textbox">
<description>No Results</description>
<top>340</top>
<left>0</left>
<width>100%</width>
<height>40</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>center</align>
<aligny>center</aligny>
<label>[UPPERCASE]$ADDON[plugin.video.kod 60473][/UPPERCASE]</label>
<visible>Control.IsVisible(4)</visible>
</control>
<control type="textbox">
<description>Load Channels</description>
<top>300</top>
<left>0</left>
<width>100%</width>
<height>40</height>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>center</align>
<aligny>center</aligny>
<label>[UPPERCASE]$ADDON[plugin.video.kod 60519][/UPPERCASE]</label>
<visible>Control.IsVisible(5)</visible>
</control>
<control type="button" id="502">
<description>Menu</description>
<top>30</top>
<right>110</right>
<height>40</height>
<width>40</width>
<onleft>504</onleft>
<onright>503</onright>
<texturefocus colordiffuse="FFFFFFFF">menu.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">menu.png</texturenofocus>
<visible>Integer.IsGreater(Container(101).NumItems, 0)</visible>
</control>
<control type="button" id="503">
<description>Back</description>
<top>30</top>
<right>70</right>
<height>40</height>
<width>40</width>
<onleft>502</onleft>
<onright>504</onright>
<texturefocus colordiffuse="FFFFFFFF">left.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">left.png</texturenofocus>
</control>
<control type="button" id="504">
<description>Close</description>
<top>30</top>
<right>30</right>
<height>40</height>
<width>40</width>
<onleft>503</onleft>
<onright>502</onright>
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus>
</control>
<control type="textbox" id="505">
<description>Load Channels</description>
<top>670</top>
<right>20</right>
<width>200</width>
<height>40</height>
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<align>right</align>
<aligny>center</aligny>
<visible>Control.IsVisible(3)</visible>
</control>
</controls>
</window>

View File

@@ -67,7 +67,7 @@
<itemlayout height="570" width="180">
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -83,7 +83,7 @@
<top>10</top>
<width>840</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Label] [COLOR FFAAAAAA] $INFO[ListItem.Property(year)][/COLOR][/B] </label>
@@ -96,7 +96,7 @@
<top>70</top>
<width>840</width>
<height>190</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(plot)]</label>
@@ -105,7 +105,7 @@
</control>
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>
@@ -125,7 +125,7 @@
<itemlayout height="570" width="180">
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -141,7 +141,7 @@
<top>10</top>
<width>840</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(title)][/B] </label>
@@ -154,7 +154,7 @@
<top>50</top>
<width>840</width>
<height>30</height>
<font>font30</font>
<!-- <font>font30</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(job)][/B]</label>
@@ -166,7 +166,7 @@
<top>90</top>
<width>830</width>
<height>180</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(bio)]</label>
@@ -175,7 +175,7 @@
</control>
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>
@@ -195,7 +195,7 @@
<itemlayout height="570" width="180">
<!-- Background -->
<control type="image">
<bottom>0</bottom>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -205,7 +205,7 @@
</control>
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -216,11 +216,11 @@
<!-- DEPARTMENT -->
<control type="textbox">
<visible>String.IsEmpty(ListItem.Property(thumbnail))</visible>
<left>0</left>
<bottom>0</bottom>
<width>180</width>
<left>10</left>
<top>300</top>
<width>160</width>
<height>270</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Property(department)][/B]</label>
<autoscroll delay="3000" time="2000" repeat="3000"></autoscroll>
@@ -235,7 +235,7 @@
<top>10</top>
<width>840</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(title)][/B] </label>
@@ -248,7 +248,7 @@
<top>50</top>
<width>840</width>
<height>30</height>
<font>font30</font>
<!-- <font>font30</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(job)][/B]</label>
@@ -260,7 +260,7 @@
<top>90</top>
<width>830</width>
<height>180</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(bio)]</label>
@@ -269,7 +269,7 @@
</control>
<!-- Background -->
<control type="image">
<bottom>0</bottom>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>
@@ -279,7 +279,7 @@
</control>
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>
@@ -294,7 +294,7 @@
<top>0</top>
<width>380</width>
<height>570</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<label>$INFO[ListItem.Property(department)]</label>
<autoscroll delay="3000" time="2000" repeat="3000"></autoscroll>
@@ -322,7 +322,7 @@
<height>50</height>
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<label></label>
<align>left</align>
<aligny>center</aligny>

View File

@@ -6,18 +6,6 @@
<top>0</top>
</coordinates>
<controls>
<!-- CLOSE BUTTON / BACKGROUND -->
<control type="button">
<left>0</left>
<top>0</top>
<width>100%</width>
<height>100%</height>
<texturefocus colordiffuse="FF232323">white.png</texturefocus>
<texturenofocus colordiffuse="FF232323">white.png</texturenofocus>
<animation effect="fade" time="200">WindowOpen</animation>
<animation effect="fade" time="200">WindowClose</animation>
<onclick>Action(close)</onclick>
</control>
<!-- GROUP CONTROLS -->
<control type="group">
<left>0</left>
@@ -32,6 +20,13 @@
</animation>
<!-- BACKGROUND -->
<control type="image">
<width>1280</width>
<height>720</height>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<!-- FANART -->
<control type="image" id='30000'>
<width>1280</width>
<height>720</height>
@@ -48,6 +43,19 @@
<animation effect="zoom" pulse ="true" center="auto" start="0,100" end="100,100" time="1000" condition="Control.IsVisible(30001)">Conditional</animation>
</control>
<control type="button" id="30003">
<top>40</top>
<right>40</right>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus>
<ondown>30002</ondown>
</control>
<!-- SELECTION -->
<control type="fixedlist" id="30002">
<top>40</top>
@@ -56,10 +64,11 @@
<viewtype>wrap</viewtype>
<orientation>horizontal</orientation>
<scrolltime tween="cubic" easing="out">300</scrolltime>
<itemlayout height="640" width="180">
<onup>30003</onup>
<itemlayout width="180">
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>370</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -68,14 +77,14 @@
<bordersize>10</bordersize>
</control>
</itemlayout>
<focusedlayout height="640" width="480">
<focusedlayout width="427">
<!-- Title -->
<control type="textbox">
<left>500</left>
<left>447</left>
<top>10</top>
<width>730</width>
<width>783</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Label] [COLOR FFAAAAAA] $INFO[ListItem.Property(year)][/COLOR][/B] </label>
@@ -84,11 +93,11 @@
</control>
<!-- info -->
<control type="textbox">
<left>500</left>
<left>447</left>
<top>50</top>
<width>730</width>
<width>783</width>
<height>30</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$ADDON[plugin.video.kod 60382] $INFO[ListItem.Property(genre)] | $ADDON[plugin.video.kod 60380] [B]$INFO[ListItem.Property(rating)][/B]</label>
@@ -96,11 +105,11 @@
</control>
<!-- Plot -->
<control type="textbox">
<left>500</left>
<left>447</left>
<top>90</top>
<width>730</width>
<width>783</width>
<height>250</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(plot)]</label>
@@ -111,7 +120,7 @@
<control type="image">
<bottom>0</bottom>
<left>0</left>
<width>480</width>
<width>427</width>
<height>640</height>
<texture>$INFO[ListItem.Property(thumbnail)]</texture>
<aspectratio>scale</aspectratio>

View File

@@ -0,0 +1,631 @@
<?xml version="1.0" encoding="utf-8"?>
<window>
<allowoverlays>false</allowoverlays>
<animation type="WindowOpen" reversible="false">
<effect type="fade" start="0" end="100" time="200" />
</animation>
<animation type="WindowClose" reversible="false">
<effect type="fade" start="100" end="0" time="200" />
</animation>
<controls>
<!-- MAIN SELECTION -->
<control type='group' id='100'>
<height>100%</height>
<width>100%</width>
<!-- Background -->
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="CC232323">white.png</texture>
</control>
<control type="textbox">
<top>640</top>
<left>40</left>
<height>40</height>
<width>1200</width>
<align>center</align>
<aligny>center</aligny>
<textcolor>80FFFFFF</textcolor>
<label>$ADDON[plugin.video.kod 70830]</label>
</control>
<!-- main selection window -->
<control type="group">
<top>288.5</top>
<left>370</left>
<height>140</height>
<width>540</width>
<!-- Beckground -->
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<control type="button" id="101">
<top>30</top>
<left>20</left>
<height>60</height>
<width>100</width>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FFFFFFFF" border="-20,0,-20,0">updn.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF" border="-20,0,-20,0">updn.png</texturenofocus>
</control>
<!-- divider -->
<control type="textbox">
<top>30</top>
<left>120</left>
<height>60</height>
<width>20</width>
<textcolor>FFFFFFFF</textcolor>
<align>center</align>
<aligny>center</aligny>
<label>[B]X[/B]</label>
</control>
<control type="button" id="102">
<top>30</top>
<left>140</left>
<height>60</height>
<width>100</width>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FFFFFFFF" border="-20,0,-20,0">updn.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF" border="-20,0,-20,0">updn.png</texturenofocus>
</control>
<!-- ok -->
<control type="button" id="103">
<top>35</top>
<left>260</left>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">ok.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">ok.png</texturenofocus>
</control>
<!-- Select Specials -->
<control type="button" id="104">
<top>35</top>
<left>310</left>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">specials.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">specials.png</texturenofocus>
</control>
<!-- Manual renumeration -->
<control type="button" id="105">
<top>35</top>
<left>360</left>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">manual.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">manual.png</texturenofocus>
</control>
<!-- delete -->
<control type="button" id="106">
<top>35</top>
<left>410</left>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">delete.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">delete.png</texturenofocus>
</control>
<!-- annulla -->
<control type="button" id="107">
<top>35</top>
<left>460</left>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus>
</control>
<control type="label" id="108">
<bottom>5</bottom>
<width>100%</width>
<height>30</height>
<textcolor>FFFFFFFF</textcolor>
<align>center</align>
<aligny>center</aligny>
</control>
</control>
</control>
<!-- END MAIN SELECTION -->
<!-- SPECIALS -->
<control type='group' id='200'>
<height>100%</height>
<width>100%</width>
<!-- BACKGROUND -->
<control type="image" id="208">
<top>0</top>
<left>0</left>
<height>100%</height>
<width>100%</width>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<!-- POSTER -->
<control type="image" id="201">
<top>0</top>
<left>0</left>
<height>720</height>
<width>480</width>
<texture/>
</control>
<!-- EPISODES LIST -->
<control type="list" id="202">
<top>140</top>
<left>520</left>
<height>540</height>
<width>340</width>
<onleft>10002</onleft>
<onright>203</onright>
<itemlayout width="340" height="60">
<control type="label">
<height>100%</height>
<width>300</width>
<left>20</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]Episodio $INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
</itemlayout>
<focusedlayout width="340" height="60">
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="22FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">Control.HasFocus(202)</visible>
</control>
<control type="image">
<top>10</top>
<left>290</left>
<height>40</height>
<width>40</width>
<texture colordiffuse="FFFFFFFF">add.png</texture>
<visible allowhiddenfocus="true">Control.HasFocus(202)</visible>
</control>
<control type="label">
<height>100%</height>
<width>300</width>
<left>20</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]Episodio $INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
</focusedlayout>
</control>
<!-- SPECIALS LIST -->
<control type='group'>
<top>140</top>
<left>900</left>
<height>540</height>
<width>340</width>
<control type="list" id="203">
<height>540</height>
<width>340</width>
<onleft>202</onleft>
<onright>204</onright>
<itemlayout width="340" height="60">
<!-- EP NUMBER -->
<control type="label">
<left>20</left>
<height>60</height>
<width>140</width>
<textcolor>80FFFFFF</textcolor>
<aligny>center</aligny>
<label>[B]0x$INFO[ListItem.Label()] - Ep. $INFO[ListItem.Property(title)][/B]</label>
</control>
</itemlayout>
<focusedlayout width="340" height="60">
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="22FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">!Control.HasFocus(202)</visible>
</control>
<!-- EP NUMBER -->
<control type="label">
<left>20</left>
<height>60</height>
<width>140</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<label>[B]0x$INFO[ListItem.Label()] - Ep. $INFO[ListItem.Property(title)][/B]</label>
</control>
</focusedlayout>
</control>
<!-- ITEM ACTIONS -->
<control type="group" id='204'>
<visible allowhiddenfocus="true">Integer.IsGreater(Container(203).Position,-1)</visible>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,0)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,1)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,2)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,3)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,4)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,5)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,6)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,7)">Conditional</animation>
<!-- move up -->
<control type="button" id="205">
<top>10</top>
<right>90</right>
<height>40</height>
<width>40</width>
<onleft>203</onleft>
<onright>206</onright>
<onup>Control.Move(203,-1)</onup>
<ondown>Control.Move(203,1)</ondown>
<texturefocus colordiffuse="FFFFFFFF">up.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">up.png</texturenofocus>
</control>
<!-- move down -->
<control type="button" id="206">
<top>10</top>
<right>50</right>
<height>40</height>
<width>40</width>
<onleft>205</onleft>
<onright>207</onright>
<onup>Control.Move(203,-1)</onup>
<ondown>Control.Move(203,1)</ondown>
<texturefocus colordiffuse="FFFFFFFF">down.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">down.png</texturenofocus>
</control>
<!-- remove -->
<control type="button" id="207">
<top>10</top>
<right>10</right>
<height>40</height>
<width>40</width>
<onleft>206</onleft>
<onright>10002</onright>
<onup>Control.Move(203,-1)</onup>
<ondown>Control.Move(203,1)</ondown>
<texturefocus colordiffuse="FFFFFFFF">delete.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">delete.png</texturenofocus>
</control>
</control>
</control>
</control>
<!-- END SPECIALS -->
<!-- MANUAL -->
<control type='group' id='300'>
<height>100%</height>
<width>100%</width>
<!-- BACKGROUND -->
<control type="image" id="310">
<top>0</top>
<left>0</left>
<height>100%</height>
<width>100%</width>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<!-- POSTER -->
<control type="image" id="301">
<top>0</top>
<left>0</left>
<height>720</height>
<width>480</width>
</control>
<!-- EPISODES LIST -->
<control type='group'>
<top>140</top>
<left>520</left>
<height>540</height>
<width>340</width>
<onleft>10002</onleft>
<onright>306</onright>
<control type="list" id="302">
<height>100%</height>
<width>100%</width>
<onleft>10002</onleft>
<onright>306</onright>
<itemlayout width="340" height="60">
<control type="label">
<height>100%</height>
<width>120</width>
<left>20</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]Episodio $INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
<!-- first season number -->
<control type="textbox">
<right>100</right>
<height>60</height>
<width>60</width>
<onleft>302</onleft>
<onright>307</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>80FFFFFF</textcolor>
<label>[B]$INFO[ListItem.Property(season)][/B]</label>
</control>
<!-- divider -->
<control type="textbox">
<right>80</right>
<height>60</height>
<width>20</width>
<textcolor>80FFFFFF</textcolor>
<align>center</align>
<aligny>center</aligny>
<label>[B]X[/B]</label>
</control>
<!-- first episode number -->
<control type="textbox">
<right>20</right>
<height>60</height>
<width>60</width>
<onleft>306</onleft>
<onright>308</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>80FFFFFF</textcolor>
<label>[B]$INFO[ListItem.Property(episode)][/B]</label>
</control>
</itemlayout>
<focusedlayout width="340" height="60">
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="22FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">Control.HasFocus(302)</visible>
</control>
<control type="label">
<height>100%</height>
<width>120</width>
<left>20</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]Episodio $INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
<!-- first season number -->
<control type="textbox">
<right>100</right>
<height>60</height>
<width>60</width>
<onleft>302</onleft>
<onright>307</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Property(season)][/B]</label>
</control>
<!-- divider -->
<control type="textbox">
<right>80</right>
<height>60</height>
<width>20</width>
<textcolor>FFFFFFFF</textcolor>
<align>center</align>
<aligny>center</aligny>
<label>[B]X[/B]</label>
</control>
<!-- first episode number -->
<control type="textbox">
<right>20</right>
<height>60</height>
<width>60</width>
<onleft>306</onleft>
<onright>308</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Property(episode)][/B]</label>
</control>
</focusedlayout>
</control>
<!-- MANUAL EPISODE CONTROL -->
<control type='group' id='305'>
<visible allowhiddenfocus="true">Integer.IsGreater(Container(302).Position,-1)</visible>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,0)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,1)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,2)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,3)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,4)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,5)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,6)">Conditional</animation>
<animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,7)">Conditional</animation>
<!-- first season number -->
<control type="button" id="306">
<right>100</right>
<height>60</height>
<width>60</width>
<onleft>302</onleft>
<onright>307</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FFFFFFFF">updn.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">updn.png</texturenofocus>
</control>
<!-- first episode number -->
<control type="button" id="307">
<right>20</right>
<height>60</height>
<width>60</width>
<onleft>306</onleft>
<onright>303</onright>
<align>center</align>
<aligny>center</aligny>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FFFFFFFF">updn.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">updn.png</texturenofocus>
</control>
</control>
</control>
<!-- SEASONS LIST -->
<control type='list' id='303'>
<top>140</top>
<left>880</left>
<height>540</height>
<width>80</width>
<onleft>302</onleft>
<onright>304</onright>
<itemlayout width="80" height="60">
<control type="label">
<height>100%</height>
<width>100%</width>
<textcolor>80FFFFFF</textcolor>
<label>[B]$INFO[ListItem.Label()][/B]</label>
<align>center</align>
<aligny>center</aligny>
</control>
</itemlayout>
<focusedlayout width="80" height="60">
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="22FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">Control.HasFocus(303)</visible>
</control>
<control type="label">
<height>100%</height>
<width>100%</width>
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Label()][/B]</label>
<align>center</align>
<aligny>center</aligny>
<visible allowhiddenfocus="true">Control.HasFocus(303)</visible>
</control>
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="11FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">!Control.HasFocus(303)</visible>
</control>
<control type="label">
<height>100%</height>
<width>100%</width>
<textcolor>80FFFFFF</textcolor>
<label>[B]$INFO[ListItem.Label()][/B]</label>
<align>center</align>
<aligny>center</aligny>
<visible allowhiddenfocus="true">!Control.HasFocus(303)</visible>
</control>
</focusedlayout>
</control>
<control type="image">
<top>140</top>
<left>960</left>
<height>540</height>
<height>100%</height>
<width>290</width>
<texture colordiffuse="11FFFFFF">white.png</texture>
</control>
<!-- EPISODES LIST -->
<control type='list' id='304'>
<top>140</top>
<left>970</left>
<height>540</height>
<width>270</width>
<onleft>303</onleft>
<onright>10002</onright>
<itemlayout width="270" height="60">
<control type="label">
<height>100%</height>
<width>200</width>
<left>40</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
</itemlayout>
<focusedlayout width="270" height="60">
<control type="image">
<height>100%</height>
<width>100%</width>
<texture colordiffuse="22FFFFFF">white.png</texture>
<visible allowhiddenfocus="true">Control.HasFocus(304)</visible>
</control>
<control type="label">
<height>100%</height>
<width>200</width>
<left>40</left>
<textcolor>FFFFFFFF</textcolor>
<label>[B]$INFO[ListItem.Label()][/B]</label>
<aligny>center</aligny>
</control>
</focusedlayout>
</control>
</control>
<!-- END MANUAL -->
<!-- MAIN ACTIONS -->
<control type='group' id='10000'>
<visible allowhiddenfocus="true">Control.IsVisible(200) | Control.IsVisible(300)</visible>
<!-- info -->
<control type="label" id="10001">
<top>40</top>
<left>540</left>
<height>50</height>
<width>560</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
</control>
<!-- ok -->
<control type="button" id="10002">
<top>40</top>
<right>90</right>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">ok.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">ok.png</texturenofocus>
<ondown condition="Control.IsVisible(200)">202</ondown>
<ondown condition="Control.IsVisible(300)">302</ondown>
<onleft>10003</onleft>
<onright>10003</onright>
</control>
<!-- annulla -->
<control type="button" id="10003">
<top>40</top>
<right>40</right>
<height>50</height>
<width>50</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
<texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus>
<ondown condition="Control.IsVisible(200)">202</ondown>
<ondown condition="Control.IsVisible(300)">302</ondown>
<onleft>10002</onleft>
<onright>10002</onright>
</control>
</control>
<!-- END MAIN ACTIONS -->
</controls>
</window>

View File

@@ -52,7 +52,7 @@
<top>50</top>
<width>1000</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[UPPERCASE]$ADDON[plugin.video.kod 70821][/UPPERCASE]</label>
@@ -71,7 +71,7 @@
<itemlayout height="570" width="180">
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>300</top>
<left>0</left>
<width>180</width>
<height>270</height>
@@ -87,7 +87,7 @@
<top>10</top>
<width>800</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Label] [COLOR FFAAAAAA]$INFO[ListItem.Property(year)][/COLOR][/B] </label>
@@ -100,7 +100,7 @@
<top>50</top>
<width>800</width>
<height>30</height>
<font>font30</font>
<!-- <font>font30</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(channel)][/B]</label>
@@ -112,7 +112,7 @@
<top>90</top>
<width>800</width>
<height>170</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(plot)]</label>
@@ -120,7 +120,7 @@
</control>
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>0</top>
<left>0</left>
<width>380</width>
<height>570</height>

View File

@@ -52,7 +52,7 @@
<top>50</top>
<width>1000</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[UPPERCASE]$ADDON[plugin.video.kod 70145][/UPPERCASE]</label>
@@ -71,7 +71,7 @@
<itemlayout height="400" width="200">
<!-- Poster -->
<control type="image">
<bottom>0</bottom>
<top>200</top>
<left>0</left>
<width>200</width>
<height>200</height>
@@ -87,7 +87,7 @@
<top>0</top>
<width>800</width>
<height>30</height>
<font>font30_title</font>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>[B]$INFO[ListItem.Property(server)] [COLOR FFAAAAAA]$INFO[ListItem.Property(quality)][/COLOR][/B] </label>
@@ -100,7 +100,7 @@
<top>40</top>
<width>800</width>
<height>120</height>
<font>font13</font>
<!-- <font>font13</font> -->
<textcolor>FFFFFFFF</textcolor>
<shadowcolor>00000000</shadowcolor>
<label>$INFO[ListItem.Property(plot)]</label>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<window>
<allowoverlays>false</allowoverlays>
<animation type="WindowOpen" reversible="false">
<effect type="fade" start="0" end="100" time="300" />
</animation>
<animation type="WindowClose" reversible="false">
<effect type="fade" start="100" end="0" time="300" />
</animation>
<controls>
<control type="button" id="104">
<description>CLOSE</description>
<top>0</top>
<left>0</left>
<height>100%</height>
<width>100%</width>
<texturefocus colordiffuse="80232323">white.png</texturefocus>
<texturenofocus colordiffuse="80232323">white.png</texturenofocus>
</control>
<control type="textbox" id="100">
<description>Not Found</description>
<top>150</top>
<left>40</left>
<height>40</height>
<width>1200</width>
<!-- <font>font30_title</font> -->
<textcolor>CCFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<label/>
</control>
<control type="group">
<top>260</top>
<left>400</left>
<height>200</height>
<width>480</width>
<control type="image">
<description>Background</description>
<height>100%</height>
<width>100%</width>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<control type="textbox">
<description>Modify</description>
<top>20</top>
<left>40</left>
<height>40</height>
<width>100</width>
<!-- <font>font30_title</font> -->
<textcolor>FFFFFFFF</textcolor>
<label>$ADDON[plugin.video.kod 70714]</label>
<aligny>center</aligny>
<align>left</align>
<label/>
</control>
<control type="image">
<description>Separator</description>
<top>80</top>
<left>0</left>
<height>1</height>
<width>480</width>
<texture colordiffuse="FFFFFFFF">white.png</texture>
</control>
<control type="button" id="103">
<description>CLOSE</description>
<top>20</top>
<right>20</right>
<height>40</height>
<width>40</width>
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
<texturenofocus colordiffuse="88FFFFFF">close.png</texturenofocus>
<ondown>101</ondown>
</control>
<control type="grouplist">
<top>120</top>
<left>40</left>
<height>40</height>
<width>400</width>
<orientation>horizontal</orientation>
<itemgap>40</itemgap>
<onup>103</onup>
<control type="button" id="101">
<description>Title</description>
<height>40</height>
<width>180</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus border="10" colordiffuse="22FFFFFF">white.png</texturefocus>
<texturenofocus border="10"></texturenofocus>
</control>
<control type="button" id="102">
<description>ID</description>
<height>40</height>
<width>180</width>
<textcolor>FFFFFFFF</textcolor>
<aligny>center</aligny>
<align>center</align>
<texturefocus border="10" colordiffuse="22FFFFFF">white.png</texturefocus>
<texturenofocus border="10"></texturenofocus>
</control>
</control>
</control>
</controls>
</window>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Some files were not shown because too many files have changed in this diff Show More