KoD 1.5
-Nuova Ricerca Globale\n-Nuova Rinumerazione\n-Messaggi di Errore più chiari\n-Fix var\n
28
.github/workflows/updateDomains.yml
vendored
Normal 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 }}
|
||||
@@ -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>
|
||||
|
||||
104
channels.json
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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">'
|
||||
|
||||
@@ -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 =============
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)+'¤tquery%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
|
||||
|
||||
@@ -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>[^<]+)<'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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+(?:–|-)\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+(?:–|-)\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]+(?:×|ÃÂ)[0-9]+)\s*(?P<title2>.*?)?(?:\s*–|\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]+(?:×|ÃÂ)[0-9]+)\s*(?P<title2>.*?)?(?:\s*–|\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*(?:×|Ã)[0-9]+[^<]+)', '', item.other)
|
||||
|
||||
support.info()
|
||||
|
||||
itemlist = []
|
||||
|
||||
data = re.sub(r'((?:<p>|<strong>)?[^\d]*\d*(?:×|Ã)[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)
|
||||
|
||||
@@ -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>.+?)(?: – 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>.+?)(?: – 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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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+×\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+×\d+).+?“(?P<title2>.+?)”).+?">'
|
||||
# è 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+×\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+×\d+|\d+[Ã.]+\d+)(?:\s?\((?P<lang>[a-zA-Z ]+)\))?(?:\s[Ss]\d+[Ee]+\d+)? +(?:“|“)(?P<title2>.*?)(?:”|”).*?(?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+×\d+|\d+[Ã.]+\d+).+?“(?P<title2>.+?)”).+?">'
|
||||
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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "film4k",
|
||||
"name": "Film4k",
|
||||
"language": ["ita"],
|
||||
"active": true,
|
||||
"active": false,
|
||||
"thumbnail": "film4k.png",
|
||||
"banner": "film4k.png",
|
||||
"categories": ["tvshow", "movie", "anime"],
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ###')
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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="([^"]+)">>')
|
||||
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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]]
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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__()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 != "":
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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" ?>'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
366
core/support.py
@@ -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|-|–|×|×', '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|–|×', '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(' ', ' '))
|
||||
|
||||
# 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(' ', ' ')
|
||||
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(' ', ' ')
|
||||
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('&', '&')
|
||||
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):
|
||||
|
||||
22
core/tmdb.py
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
242
core/tvdb.py
@@ -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']:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
604
platformcode/globalsearch.py
Normal 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])
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
627
resources/skins/Default/720p/GlobalSearch.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
631
resources/skins/Default/720p/Renumber.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
105
resources/skins/Default/720p/TitleOrIDWindow.xml
Normal 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>
|
||||
BIN
resources/skins/Default/media/add.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
resources/skins/Default/media/delete.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
resources/skins/Default/media/down.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/skins/Default/media/exit.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/skins/Default/media/fhd.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
resources/skins/Default/media/hd.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
resources/skins/Default/media/left.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/skins/Default/media/manual.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
resources/skins/Default/media/menu.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
resources/skins/Default/media/ok.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
resources/skins/Default/media/pause.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |