KoD 1.7.4
- Nuove visualizzazioni Server\n- Fix Gestione Viste\n- Aggiunto Pluto TV\n- Fix e migliorie varie\n\n
This commit is contained in:
11
addon.xml
11
addon.xml
@@ -1,4 +1,4 @@
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.7.3" provider-name="KoD Team">
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" provider-name="KoD Team" version="1.7.4">
|
||||
<requires>
|
||||
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
|
||||
<import addon="metadata.themoviedb.org"/>
|
||||
@@ -6,7 +6,7 @@
|
||||
<!-- <import addon="metadata.tvdb.com"/> -->
|
||||
|
||||
</requires>
|
||||
<extension point="xbmc.python.pluginsource" library="default.py">
|
||||
<extension library="default.py" point="xbmc.python.pluginsource">
|
||||
<provides>video</provides>
|
||||
</extension>
|
||||
<extension point="kodi.context.item">
|
||||
@@ -27,7 +27,10 @@
|
||||
<screenshot>resources/media/screenshot-2.png</screenshot>
|
||||
<screenshot>resources/media/screenshot-3.png</screenshot>
|
||||
</assets>
|
||||
<news>- fix vari
|
||||
<news>- Nuove visualizzazioni Server
|
||||
- Fix Gestione Viste
|
||||
- Aggiunto Pluto TV
|
||||
- Fix e migliorie varie
|
||||
</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]
|
||||
@@ -38,6 +41,6 @@
|
||||
<forum>https://t.me/kodiondemand</forum>
|
||||
<source>https://github.com/kodiondemand/addon</source>
|
||||
</extension>
|
||||
<extension point="xbmc.service" library="service.py" start="login|startup">
|
||||
<extension library="service.py" point="xbmc.service" start="login|startup">
|
||||
</extension>
|
||||
</addon>
|
||||
@@ -1,10 +1,8 @@
|
||||
{
|
||||
"direct": {
|
||||
"altadefinizione01": "https://www.altadefinizione01.day",
|
||||
"altadefinizione01_link": "https://altadefinizione01.travel",
|
||||
"altadefinizione01": "https://www.altadefinizione01.sbs",
|
||||
"animealtadefinizione": "https://www.animealtadefinizione.it",
|
||||
"animeforce": "https://www.animeforce.it",
|
||||
"animeleggendari": "https://animezeus.com",
|
||||
"animesaturn": "https://www.animesaturn.it",
|
||||
"animeunity": "https://www.animeunity.tv",
|
||||
"animeuniverse": "https://www.animeuniverse.it",
|
||||
@@ -12,14 +10,11 @@
|
||||
"aniplay": "https://aniplay.it",
|
||||
"casacinema": "https://www.casacinema.page",
|
||||
"cb01anime": "https://www.cineblog01.red",
|
||||
"cineblog01": "https://cb01.uno",
|
||||
"cinemalibero": "https://cinemalibero.top",
|
||||
"cinetecadibologna": "https://cinestore.cinetecadibologna.it",
|
||||
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
|
||||
"discoveryplus": "https://www.discoveryplus.com",
|
||||
"dreamsub": "https://dreamsub.stream",
|
||||
"dsda": "https://www.dsda.press",
|
||||
"dreamsub": "https://dreamsub.cc",
|
||||
"eurostreaming": "https://eurostreaming.town",
|
||||
"filmigratis": "https://filmigratis.org",
|
||||
"guardaseriecam": "https://guardaserie.cam",
|
||||
"guardaserieclick": "https://www.guardaserie.builders",
|
||||
"guardaserieicu": "https://guardaserie.construction",
|
||||
@@ -33,23 +28,20 @@
|
||||
"paramount": "https://www.mtv.it",
|
||||
"piratestreaming": "https://www.piratestreaming.design",
|
||||
"plutotv": "https://pluto.tv",
|
||||
"polpotv": "https://roma.polpo.tv",
|
||||
"raiplay": "https://www.raiplay.it",
|
||||
"seriehd": "https://altadefinizionecommunity.casa",
|
||||
"serietvonline": "https://serietvonline.art",
|
||||
"serietvsubita": "http://serietvsubita.xyz",
|
||||
"serietvu": "https://www.serietvu.live",
|
||||
"streamingcommunity": "https://streamingcommunity.host",
|
||||
"streamingita": "https://www.streamingita.site",
|
||||
"streamtime": "https://t.me/s/StreamTime",
|
||||
"tantifilm": "https://www.tantifilm.codes",
|
||||
"tapmovie": "https://it.tapmovie.net",
|
||||
"toonitalia": "https://toonitalia.co",
|
||||
"vvvvid": "https://www.vvvvid.it"
|
||||
},
|
||||
"findhost": {
|
||||
"altadefinizione": "https://altadefinizione.nuovo.live",
|
||||
"altadefinizionecommunity": "https://altaregistrazione.net",
|
||||
"animealtadefinizione": "https://www.animealtadefinizione.it",
|
||||
"cineblog01": "https://cb01.uno",
|
||||
"filmpertutti": "https://filmpertuttiii.nuovo.live"
|
||||
}
|
||||
}
|
||||
10
channels/altadefinizione.json
Normal file
10
channels/altadefinizione.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "altadefinizione",
|
||||
"name": "Altadefinizione",
|
||||
"language": ["ita", "sub-ita"],
|
||||
"active": false,
|
||||
"thumbnail": "altadefinizione.png",
|
||||
"banner": "altadefinizione.png",
|
||||
"categories": ["movie", "tvshow", "vos"],
|
||||
"settings": []
|
||||
}
|
||||
88
channels/altadefinizione.py
Normal file
88
channels/altadefinizione.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per altadefinizione
|
||||
# ------------------------------------------------------------
|
||||
|
||||
|
||||
from core import httptools, support
|
||||
from platformcode import config, logger
|
||||
|
||||
|
||||
def findhost(url):
|
||||
host = support.match(url, patron=r'<h2[^>]+><a href="([^"]+)').match.rstrip('/')
|
||||
return host
|
||||
|
||||
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
film = [('Al Cinema', ['/al-cinema/', 'peliculas']),
|
||||
('Generi', ['', 'genres']),
|
||||
('Sub-ITA', ['/sub-ita/', 'peliculas'])]
|
||||
|
||||
tvshow = ['/genere/serie-tv/']
|
||||
|
||||
search = ''
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
action = 'peliculas'
|
||||
blacklist = ['Scegli il Genere', 'Film', 'Serie TV', 'Sub-Ita', 'Anime']
|
||||
patronMenu = r'<option value="(?P<url>[^"]+)">(?P<title>[^<]+)'
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
logger.debug(text)
|
||||
item.url = "{}/?s={}".format(host, text)
|
||||
|
||||
try:
|
||||
return peliculas(item)
|
||||
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("search except: %s" % line)
|
||||
return []
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
n = '22' if '/?s=' in item.url else '8'
|
||||
item.contentType = "undefined"
|
||||
action = 'check'
|
||||
patron = r'data-src="(?P<thumb>http[^"]+)(?:[^>]+>){' + n + r'}\s*<a href="(?P<url>[^"]+)[^>]+>\s*(?P<title>[^\[\(\<]+)(?:\[(?P<quality>[^\]]+)\])?\s*(?:\((?P<lang>[a-zA-z-]+)\))?\s*(?:\((?P<year>\d+)\))?\s*</a>\s*</h2>'
|
||||
patronNext = r'href="([^"]+)[^>]+>»'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
item.quality = ''
|
||||
data = item.data
|
||||
action='findvideos'
|
||||
patronBlock = r'Stagione[^;]+;\s(?P<lang>(?:Sub-)?ITA)(?: in )?(?P<quality>[^<]*)?(?:[^>]+>){4}(?P<block>.*?)/p>'
|
||||
patron = r'(?P<season>\d+)&[^:]+;(?P<episode>\d+)(?P<data>.*?)(?:<br|$)'
|
||||
return locals()
|
||||
|
||||
|
||||
def check(item):
|
||||
item.data = httptools.downloadpage(item.url).data
|
||||
if 'rel="tag">Serie TV' in item.data:
|
||||
return episodios(item)
|
||||
else:
|
||||
return findvideos(item)
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
logger.debug()
|
||||
if item.contentType == 'movie':
|
||||
item.data = support.match(item.data, patron=r'data-id="([^"]+)').matches
|
||||
return support.server(item, item.data)
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"id": "altadefinizione01_link",
|
||||
"name": "Altadefinizione01 L",
|
||||
"active": false,
|
||||
"language": ["ita","sub-ita"],
|
||||
"thumbnail": "altadefinizione01_L.png",
|
||||
"banner": "altadefinizione01_L.png",
|
||||
"categories": ["movie","vos"],
|
||||
"settings" :[]
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- Channel altadefinizione01_link -*-
|
||||
|
||||
from core import support
|
||||
from core.item import Item
|
||||
from platformcode import config, logger
|
||||
|
||||
__channel__ = "altadefinizione01_link"
|
||||
|
||||
# ======== def per utility INIZIO ============================
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
# =========== home menu ===================
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
support.info('mainlist',item)
|
||||
|
||||
film = [
|
||||
('Al Cinema', ['/film-del-cinema', 'peliculas', '']),
|
||||
('Generi', ['', 'genres', 'genres']),
|
||||
('Anni', ['', 'genres', 'years']),
|
||||
('Qualità', ['/piu-visti.html', 'genres', 'quality']),
|
||||
('Mi sento fortunato', ['/piu-visti.html', 'genres', 'lucky']),
|
||||
('Popolari', ['/piu-visti.html', 'peliculas', '']),
|
||||
('Sub-ITA', ['/film-sub-ita/', 'peliculas', ''])
|
||||
]
|
||||
return locals()
|
||||
|
||||
# ======== def in ordine di action dal menu ===========================
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
# debug = True
|
||||
support.info('peliculas',item)
|
||||
|
||||
patron = r'<a href="(?P<url>[^"]+)">(?P<title>[^<]+)(?:[^>]+>){5}\s*<div class="[^"]+" style="background-image:url\((?P<thumb>[^\)]+)(?:[^>]+>){6}\s*(?P<year>\d{4})[^>]+>[^>]+>(?:\s*(?P<duration>\d+))?(?:[^>]+>){0,2}\s+(?P<quality>[a-zA-Z]+)\s+(?:[^>]+>){2}\s*(?P<lang>[^>]+)\s+[^>]+>'
|
||||
patronNext = r'<span>\d</span> <a href="([^"]+)">'
|
||||
# debug = True
|
||||
return locals()
|
||||
|
||||
# =========== def pagina categorie ======================================
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
support.info('genres',item)
|
||||
|
||||
action = 'peliculas'
|
||||
if item.args == 'genres':
|
||||
patronBlock = r'<ul class="listSubCat" id="Film">(?P<block>.*)<ul class="listSubCat" id="Anno">'
|
||||
elif item.args == 'years':
|
||||
patronBlock = r'<ul class="listSubCat" id="Anno">(?P<block>.*)<ul class="listSubCat" id="Qualita">'
|
||||
elif item.args == 'quality':
|
||||
patronBlock = r'<ul class="listSubCat" id="Qualita">(?P<block>.*)<blockquote'
|
||||
elif item.args == 'lucky': # sono i titoli random nella pagina
|
||||
patronBlock = r'FILM RANDOM.*?class="listSubCat">(?P<block>.*)</ul>'
|
||||
action = 'findvideos'
|
||||
patronMenu = r'<li><a href="(?P<url>[^"]+)">(?P<title>[^<]+)<'
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
# =========== def per cercare film/serietv =============
|
||||
#host+/index.php?do=search&story=avatar&subaction=search
|
||||
def search(item, text):
|
||||
support.info('search', item)
|
||||
itemlist = []
|
||||
text = text.replace(" ", "+")
|
||||
item.url = host+"/index.php?do=search&story=%s&subaction=search" % (text)
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Se captura la excepcion, para no interrumpir al buscador global si un canal falla
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
# =========== def per le novità nel menu principale =============
|
||||
|
||||
def newest(categoria):
|
||||
support.info('newest', categoria)
|
||||
itemlist = []
|
||||
item = Item()
|
||||
try:
|
||||
if categoria == "peliculas":
|
||||
item.url = host
|
||||
item.action = "peliculas"
|
||||
item.contentType='movie'
|
||||
itemlist = peliculas(item)
|
||||
|
||||
if itemlist[-1].action == "peliculas":
|
||||
itemlist.pop()
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
def findvideos(item):
|
||||
support.info('findvideos', item)
|
||||
return support.server(item, support.match(item, patron='<ul class="playernav">.*?</ul>', headers=headers).match)
|
||||
@@ -74,20 +74,15 @@ def search(item, text):
|
||||
def peliculas(item):
|
||||
search = item.search
|
||||
anime = True
|
||||
# debug = True
|
||||
if 'movie' in item.url:
|
||||
action = 'findvideos'
|
||||
else:
|
||||
action = 'check'
|
||||
action = 'check'
|
||||
|
||||
# if not item.args:
|
||||
# pagination = ''
|
||||
# patron = r'<a\s*href="(?P<url>[^"]+)"\s*title="(?P<title>[^"]+)">'
|
||||
# else:
|
||||
patron = r'<a href="(?P<url>[^"]+)"[^>]+>\s*<img src="(?P<thumb>[^"]+)" alt="(?P<title>.*?)(?: Sub| sub| SUB|")'
|
||||
|
||||
if search:
|
||||
patron = r'<a href="(?P<url>[^"]+)"\s*title="(?P<title>.*?)(?: Sub| sub| SUB|")'
|
||||
|
||||
if item.args == 'newest': item.action = 'findvideos'
|
||||
|
||||
|
||||
patronNext = '<li class="page-item disabled">(?:[^>]+>){4}<a class="page-link" href="([^"]+)'
|
||||
|
||||
def itemHook(item):
|
||||
@@ -100,7 +95,7 @@ def peliculas(item):
|
||||
|
||||
|
||||
def check(item):
|
||||
m = support.match(item, headers=headers, patron=r'Tipologia[^>]+><a href="([^"]+)"')
|
||||
m = support.match(item, headers=headers, patron=r'Tipologia[^>]+>\s*<a href="([^"]+)"')
|
||||
item.data = m.data
|
||||
if 'movie' in m.match:
|
||||
item.contentType = 'movie'
|
||||
@@ -112,6 +107,7 @@ def check(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
anime = True
|
||||
pagination = 50
|
||||
data = item.data
|
||||
|
||||
if '<h6>Streaming</h6>' in data:
|
||||
@@ -130,30 +126,37 @@ def episodios(item):
|
||||
def findvideos(item):
|
||||
support.info(item)
|
||||
itemlist = []
|
||||
|
||||
if 'adf.ly' in item.url:
|
||||
from servers.decrypters import adfly
|
||||
url = adfly.get_long_url(item.url)
|
||||
|
||||
elif 'bit.ly' in item.url:
|
||||
url = support.httptools.downloadpage(item.url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
|
||||
if item.data:
|
||||
url = support.match(item.data, patron=r'<a\s*href="([^"]+)"\s*title="[^"]+"\s*class="btn btn-dark mb-1">').match
|
||||
else:
|
||||
url = host
|
||||
for u in item.url.split('/'):
|
||||
if u and 'animeforce' not in u and 'http' not in u:
|
||||
url += '/' + u
|
||||
url = item.url
|
||||
|
||||
if 'php?' in url:
|
||||
url = support.httptools.downloadpage(url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
url = support.match(url, patron=r'class="button"><a href=(?:")?([^" ]+)', headers=headers).match
|
||||
else:
|
||||
if item.data: url = item.data
|
||||
url = support.match(url, patron=r'data-href="([^"]+)" target').match
|
||||
if not url: url = support.match(url, patron=[r'<source src=(?:")?([^" ]+)',r'name="_wp_http_referer" value="([^"]+)"']).match
|
||||
if url.startswith('//'): url = 'https:' + url
|
||||
elif url.startswith('/'): url = 'https:/' + url
|
||||
if 'vvvvid' in url: itemlist.append(item.clone(action="play", title='VVVVID', url=url, server='vvvvid'))
|
||||
else: itemlist.append(item.clone(action="play", title=support.config.get_localized_string(30137), url=url, server='directo'))
|
||||
# if 'adf.ly' in item.url:
|
||||
# from servers.decrypters import adfly
|
||||
# url = adfly.get_long_url(item.url)
|
||||
|
||||
# elif 'bit.ly' in item.url:
|
||||
# url = support.httptools.downloadpage(item.url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
|
||||
# else:
|
||||
# url = host
|
||||
# for u in item.url.split('/'):
|
||||
# if u and 'animeforce' not in u and 'http' not in u:
|
||||
# url += '/' + u
|
||||
|
||||
|
||||
# if 'php?' in url:
|
||||
# url = support.httptools.downloadpage(url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
# url = support.match(url, patron=r'class="button"><a href=(?:")?([^" ]+)', headers=headers).match
|
||||
# else:
|
||||
# if item.data: url = item.data
|
||||
# if item.contentType == 'movie': url = support.match()
|
||||
# url = support.match(url, patron=r'data-href="([^"]+)" target').match
|
||||
# if not url: url = support.match(url, patron=[r'<source src=(?:")?([^" ]+)',r'name="_wp_http_referer" value="([^"]+)"']).match
|
||||
# if url.startswith('//'): url = 'https:' + url
|
||||
# elif url.startswith('/'): url = 'https:/' + url
|
||||
url = support.match(url, patron=r'data-href="([^"]+)" target').match
|
||||
if 'vvvvid' in url: itemlist.append(item.clone(action="play", title='VVVVID', url=url, server='vvvvid'))
|
||||
else: itemlist.append(item.clone(action="play", title=support.config.get_localized_string(30137), url=url, server='directo'))
|
||||
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "animeleggendari",
|
||||
"name": "AnimePerTutti",
|
||||
"active": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "animepertutti.png",
|
||||
"bannermenu": "animepertutti.png",
|
||||
"categories": ["anime", "vos"],
|
||||
"not_active":["include_in_newest_peliculas", "include_in_newest_series", "include_in_newest_anime"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per animeleggendari
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
from lib.js2py.host import jsfunctions
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
|
||||
headers = [['User-Agent', 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'],
|
||||
['Referer', host]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
anime = [
|
||||
# ('Leggendari', ['/category/anime-leggendari/', 'peliculas']),
|
||||
('ITA', ['/category/anime-ita/', 'peliculas']),
|
||||
('SUB-ITA', ['/category/anime-sub-ita/', 'peliculas']),
|
||||
('Conclusi', ['/category/serie-anime-concluse/', 'peliculas']),
|
||||
('in Corso', ['/category/serie-anime-in-corso/', 'peliculas']),
|
||||
('Genere', ['', 'genres'])
|
||||
]
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, texto):
|
||||
support.info(texto)
|
||||
|
||||
item.url = host + "/?s=" + texto
|
||||
try:
|
||||
return peliculas(item)
|
||||
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
blacklist = ['Contattaci','Privacy Policy', 'DMCA']
|
||||
patronMenu = r'<a href="(?P<url>[^"]+)">(?P<title>[^<]+)<'
|
||||
patronBlock = r'Generi</a>\s*<ul[^>]+>(?P<block>.*?)<\/ul>'
|
||||
action = 'peliculas'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
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)">\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)
|
||||
item.title += support.typo('Movie','_ () bold')
|
||||
item.contentType = 'movie'
|
||||
item.action = 'findvideos'
|
||||
return item
|
||||
def itemlistHook(itemlist):
|
||||
itlist = []
|
||||
for item in itemlist:
|
||||
if 'nuovo episodio:' not in item.title.lower():
|
||||
itlist += [item]
|
||||
return itlist
|
||||
|
||||
patronNext = r'<a class="next page-numbers" href="([^"]+)">'
|
||||
action = 'episodios'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
data = support.match(item, headers=headers, patronBlock=r'entry-content clearfix">(.*?)class="mh-widget mh-posts-2 widget_text').block
|
||||
if not 'pagination clearfix' in data:
|
||||
support.info('NOT IN DATA')
|
||||
patron = r'<iframe.*?src="(?P<url>[^"]+)"'
|
||||
title = item.title
|
||||
def fullItemlistHook(itemlist):
|
||||
if len(itemlist) > 0:
|
||||
urls = []
|
||||
for item in itemlist:
|
||||
urls.append(item.url)
|
||||
item = itemlist[0]
|
||||
item.data = urls
|
||||
item.title = title
|
||||
item.contentType = 'movie'
|
||||
itemlist = []
|
||||
itemlist.append(item)
|
||||
return itemlist
|
||||
else:
|
||||
url = item.url
|
||||
anime = True
|
||||
patronBlock = r'(?:<p style="text-align: left;">|<div class="pagination clearfix">\s*)(?P<block>.*?)</span></a></div>'
|
||||
patron = r'(?:<a href="(?P<url>[^"]+)"[^>]+>)?<span class="pagelink">(?P<episode>\d+)'
|
||||
def itemHook(item):
|
||||
if not item.url:
|
||||
item.url = url
|
||||
if 'Movie Parte' in data:
|
||||
item.title = support.typo(item.fulltitle + ' - Part ','bold') + item.title
|
||||
item.contentType = 'movie'
|
||||
else:
|
||||
item.title = support.typo('Episodio ', 'bold') + item.title
|
||||
return item
|
||||
return locals()
|
||||
|
||||
def check(item):
|
||||
data = support.match(item, headers=headers).data
|
||||
if 'Lista Episodi' not in data:
|
||||
item.data = data
|
||||
return findvideos(item)
|
||||
|
||||
data = ''
|
||||
return data
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
if item.data:
|
||||
data = item.data
|
||||
else:
|
||||
matches = support.match(item, patron=r'<iframe.*?src="(?P<url>[^"]+)"').matches
|
||||
data = ''
|
||||
if matches:
|
||||
for match in matches:
|
||||
try: data += str(jsfunctions.unescape(support.re.sub('@|g','%', match)))
|
||||
except: data += ''
|
||||
data += str(match)
|
||||
else:
|
||||
data = ''
|
||||
|
||||
return support.server(item,data)
|
||||
@@ -9,14 +9,14 @@ from core import scrapertools, httptools, servertools, support
|
||||
from platformcode import logger, config
|
||||
|
||||
|
||||
# def findhost(url):
|
||||
# host = httptools.downloadpage(url, follow_redirect=True).url
|
||||
# if host == 'https://cb01.uno/':
|
||||
# host = support.match(host, patron=r'<a href="([^"]+)').match
|
||||
# return host
|
||||
def findhost(url):
|
||||
host = httptools.downloadpage(url, follow_redirect=True).url
|
||||
if host == 'https://cb01.uno/':
|
||||
host = support.match(host, patron=r'<a href="([^"]+)').match
|
||||
return host
|
||||
|
||||
|
||||
host = config.get_channel_url()
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ def findvideos(item):
|
||||
patronvideos = r'([\w.]+)</strong></div></td>'
|
||||
support.addQualityTag(item, itemlist, data, patronvideos)
|
||||
|
||||
return itemlist
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
# Estrae i contenuti - Download
|
||||
# load_links(itemlist, '<strong>Download:</strong>(.*?)<tableclass=cbtable height=30>', "aqua", "Download")
|
||||
|
||||
@@ -7,6 +7,7 @@ import re
|
||||
|
||||
from core import httptools, support, scrapertools
|
||||
from core.item import Item
|
||||
from core.support import typo
|
||||
from platformcode import config
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
@@ -57,11 +58,13 @@ def peliculas(item):
|
||||
patron = r'<div class="col-lg-3">[^>]+>[^>]+>\s<a href="(?P<url>[^"]+)".+?url\((?P<thumb>[^\)]+)\)">[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>(?:[^>]+>)?\s?(?P<rating>[\d\.]+)?[^>]+>.+?(?:[ ]\((?P<year>\d{4})\))?<[^>]+>[^>]+>(.?[\d\-x]+\s\(?(?P<lang>[sSuUbBiItTaA\-]+)?\)?\s?(?P<quality>[\w]+)?[|]?\s?(?:[fFiInNeE]+)?\s?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?)?'
|
||||
pagination = 25
|
||||
elif item.contentType == 'movie':
|
||||
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>.+?)(?:[ ]\[(?P<lang>[sSuUbB\-iItTaA]+)\])?(?:[ ]\((?P<year>\d{4})\))?"\s*alt="[^"]+"\s*class="[^"]+"(?: style="background-image: url\((?P<thumb>.+?)\)">)?\s*<div class="voto">[^>]+>[^>]+>.(?P<rating>[\d\.a-zA-Z\/]+)?[^>]+>[^>]+>[^>]+>(?:<div class="genere">(?P<quality>[^<]+)</div>)?'
|
||||
# action = 'findvideos'
|
||||
patron = r'<a href="(?P<url>[^"]+)" title="(?P<title>.+?)(?:[ ]\[(?P<lang>[sSuUbB\-iItTaA]+)\])?(?:[ ]\((?P<year>\d{4})?\))?"\s*alt="[^"]+"\s*class="[^"]+"(?: style="background-image: url\((?P<thumb>.+?)\)">)?\s*<div class="voto">[^>]+>[^>]+>.(?P<rating>[\d\.a-zA-Z\/]+)?[^>]+>[^>]+>[^>]+>(?:<div class="genere">(?P<quality>[^<]+)</div>)?'
|
||||
if item.args == 'update':
|
||||
patronBlock = r'<section id="slider">(?P<block>.*?)</section>'
|
||||
patron = r'<a href="(?P<url>(?:https:\/\/.+?\/(?P<title>[^\/]+[a-zA-Z0-9\-]+)(?P<year>\d{4})))/".+?url\((?P<thumb>[^\)]+)\)">'
|
||||
patron = r'<a href="(?P<url>(?:https:\/\/.+?\/(?P<title>[^\/]+[a-zA-Z0-9\-]+)(?P<year>\d{4})?))/".+?url\((?P<thumb>[^\)]+)\)">'
|
||||
elif item.contentType == 'tvshow':
|
||||
# action = 'episodios'
|
||||
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>\s*?(?:<div class="genere">)?(?:[\w]+?\.?\s?[\s|S]?[\dx\-S]+?\s\(?(?P<lang>[iItTaA]+|[sSuUbBiItTaA\-]+)\)?\s?(?P<quality>[HD]+)?|.+?\(?(?P<lang2>[sSuUbBiItTaA\-]+)?\)?</div>)'
|
||||
pagination = 25
|
||||
@@ -92,7 +95,7 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
data = item.data
|
||||
# debug = True
|
||||
# debugBlock = True
|
||||
if item.args == 'anime':
|
||||
support.info("Anime :", item)
|
||||
# blacklist = ['Clipwatching', 'Verystream', 'Easybytez', 'Flix555', 'Cloudvideo']
|
||||
@@ -132,7 +135,7 @@ def episodios(item):
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
for s in servers:
|
||||
executor.submit(get_ep, s)
|
||||
ret.extend([it.clone(title=ep, contentSeason=int(ep.split('x')[0]), contentEpisodeNumber=int(ep.split('x')[1]), servers=[srv.tourl() for srv in episodes[ep]]) for ep in episodes])
|
||||
ret.extend([it.clone(title=ep+typo(it.contentLanguage, '_ [] color kod'), contentSeason=int(ep.split('x')[0]), contentEpisodeNumber=int(ep.split('x')[1]), servers=[srv.tourl() for srv in episodes[ep]]) for ep in episodes])
|
||||
else:
|
||||
ret.append(it)
|
||||
return sorted(ret, key=lambda i: i.title)
|
||||
@@ -142,7 +145,6 @@ def episodios(item):
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
|
||||
action='peliculas'
|
||||
patron_block=r'<div id="bordobar" class="dropdown-menu(?P<block>.*?)</li>'
|
||||
patronMenu=r'<a class="dropdown-item" href="(?P<url>[^"]+)" title="(?P<title>[A-z]+)"'
|
||||
@@ -203,11 +205,16 @@ def check(item):
|
||||
item.contentType = 'tvshow'
|
||||
item.args = 'anime'
|
||||
item.data = data
|
||||
return episodios(item)
|
||||
itemlist = episodios(item)
|
||||
if not itemlist:
|
||||
item.data = data
|
||||
item.action = 'findvideos'
|
||||
return findvideos(item)
|
||||
|
||||
elif ck == 'film':
|
||||
item.contentType = 'movie'
|
||||
item.data = data
|
||||
item.action = 'findvideos'
|
||||
return findvideos(item)
|
||||
|
||||
else:
|
||||
@@ -217,8 +224,9 @@ def check(item):
|
||||
if not itemlist:
|
||||
item.contentType = 'movie'
|
||||
item.data = data
|
||||
item.action = 'findvideos'
|
||||
return findvideos(item)
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
@@ -234,9 +242,27 @@ def findvideos(item):
|
||||
if item.servers:
|
||||
return support.server(item, itemlist=[Item().fromurl(s) for s in item.servers])
|
||||
if not item.data:
|
||||
item.data = support.match(item, patron='<p>\s*<strong>\s*<u>.*?</p>').match
|
||||
item.data = httptools.downloadpage(item.url)
|
||||
item.data = scrapertools.find_single_match(item.data, '<div class="at-above-post addthis_tool"(.*?)<div class="at-below-post')
|
||||
|
||||
servers = []
|
||||
if item.args == 'anime':
|
||||
if item.urls: # this is a episode
|
||||
return support.server(item, itemlist=[Item(url=support.unshortenit.FileCrypt().unshorten(u)) for u in item.urls])
|
||||
itemlist = []
|
||||
episodes = {}
|
||||
# support.dbg()
|
||||
for uri in support.unshortenit.FileCrypt().find(item.data):
|
||||
for ep in support.unshortenit.FileCrypt(uri).list_files():
|
||||
ep = ('.'.join(ep[0].split('.')[:-1]), ep[1]) # remove extension
|
||||
if not ep[0] in episodes:
|
||||
episodes[ep[0]] = []
|
||||
episodes[ep[0]].append(ep[1])
|
||||
for ep in episodes.keys():
|
||||
itemlist.append(item.clone(title=ep, urls=episodes[ep], action='findvideos', data=''))
|
||||
return itemlist
|
||||
total_servers = support.server(item, data=item.data)
|
||||
|
||||
if item.contentType == 'episode' and len(set([srv.server for srv in total_servers])) < len([srv.server for srv in total_servers]):
|
||||
# i link contengono più puntate, cerco quindi quella selezionata
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
|
||||
@@ -67,7 +67,7 @@ def live(item):
|
||||
logger.debug()
|
||||
itemlist =[]
|
||||
for name, values in liveDict().items():
|
||||
itemlist.append(item.clone(title=typo(name,'bold'), fulltitle=name, plot=values['plot'], url=values['url'], id=values['id'], action='play', forcethumb=True, no_return=True))
|
||||
itemlist.append(item.clone(title=typo(name,'bold'), fulltitle=name, plot=values['plot'], url=values['url'], id=values['id'], action='findvideos', forcethumb=True, no_return=True))
|
||||
return support.thumb(itemlist, live=True)
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ def episodios(item):
|
||||
fulltitle=title,
|
||||
plot=plot,
|
||||
id=episode['id'],
|
||||
action='play',
|
||||
action='findvideos',
|
||||
contentType='episode',
|
||||
season=option['id'],
|
||||
episode=episode['attributes']['episodeNumber'],
|
||||
@@ -182,7 +182,7 @@ def episodios(item):
|
||||
return itemlist
|
||||
|
||||
|
||||
def play(item):
|
||||
def findvideos(item):
|
||||
if item.livefilter:
|
||||
item.id = liveDict()[item.livefilter]['id']
|
||||
item.fulltitle = item.livefilter
|
||||
@@ -198,4 +198,4 @@ def play(item):
|
||||
else:
|
||||
item.url = data['streaming']['hls']['url']
|
||||
item.manifest = 'hls'
|
||||
return [item]
|
||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"id": "dsda",
|
||||
"name": "D.S.D.A",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "dsda.png",
|
||||
"banner": "dsda.png",
|
||||
"categories": ["documentary"],
|
||||
"settings": []
|
||||
}
|
||||
140
channels/dsda.py
140
channels/dsda.py
@@ -1,140 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per documentaristreamingda
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
from core.item import Item
|
||||
from platformcode import logger, config
|
||||
|
||||
host = config.get_channel_url()
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
docu = [('Documentari {bullet bold}',('/elenco-documentari','peliculas')),
|
||||
('Categorie {submenu}',('','menu')),
|
||||
('Cerca... {bullet bold}',('','search')),]
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
action = 'peliculas'
|
||||
patronMenu = r'<li class="menu-item menu-item-type-taxonomy[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>(?P<title>[^<]+)<'
|
||||
def fullItemlistHook(itemlist):
|
||||
item_list = []
|
||||
title_list = []
|
||||
for item in itemlist:
|
||||
if item.title not in title_list:
|
||||
item_list.append(item)
|
||||
title_list.append(item.title)
|
||||
itemlist = item_list
|
||||
return itemlist
|
||||
return locals()
|
||||
|
||||
def newest(categoria):
|
||||
support.info()
|
||||
item = Item()
|
||||
try:
|
||||
if categoria == "documentales":
|
||||
item.url = host + "/elenco-documentari"
|
||||
item.action = "peliculas"
|
||||
return peliculas(item)
|
||||
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
|
||||
def search(item, texto):
|
||||
support.info(texto)
|
||||
item.url = host + "/?s=" + texto
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
blacklist = ['GUIDA PRINCIPIANTI Vedere film e documentari streaming gratis', 'Guida Dsda']
|
||||
data = support.match(item).data
|
||||
# debug =True
|
||||
if item.args == 'collection':
|
||||
if 'class="panel"' in data:
|
||||
item.args = 'raccolta'
|
||||
patron = r'class="title-episodio">(?P<title>[^<]+)<(?P<url>.*?)<p'
|
||||
# patron = r'<a (?:style="[^"]+" )?href="(?P<url>[^"]+)"[^>]+>(?:[^>]+><strong>)?(?P<title>[^<]+)(?:</a>)?</strong'
|
||||
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>[^<]+)<'
|
||||
patronNext = r'<a class="page-numbers next" href="([^"]+)">'
|
||||
|
||||
# select category
|
||||
def itemHook(item):
|
||||
title = support.re.sub(r'(?:[Ss]erie\s*|[Ss]treaming(?:\s*[Dd][Aa])?\s*|[Cc]ollezione\s*|[Rr]accolta\s*|[Dd]ocumentari(?:o)?\s*)?','',item.fulltitle).strip()
|
||||
if 'serie' in item.fulltitle.lower():
|
||||
item.contentType = 'tvshow'
|
||||
item.action = 'episodios'
|
||||
item.contentSerieName = title
|
||||
item.contentTitle = ''
|
||||
elif 'collezion' in item.fulltitle.lower() or \
|
||||
'raccolt' in item.fulltitle.lower() or \
|
||||
'filmografia' in item.fulltitle.lower():
|
||||
item.args = 'collection'
|
||||
item.action = 'peliculas'
|
||||
item.contentTitle = title
|
||||
item.contentSerieName = ''
|
||||
else:
|
||||
item.contentTitle = title
|
||||
item.contentSerieName = ''
|
||||
|
||||
item.title = support.typo(title,'bold')
|
||||
item.fulltitle = item.show = title
|
||||
return item
|
||||
# remove duplicates
|
||||
def fullItemlistHook(itemlist):
|
||||
item_list = []
|
||||
title_list = []
|
||||
for item in itemlist:
|
||||
if item.title not in title_list:
|
||||
item_list.append(item)
|
||||
title_list.append(item.title)
|
||||
itemlist = item_list
|
||||
return itemlist
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
html = support.match(item, patron=r'class="title-episodio">(\d+x\d+)')
|
||||
data = html.data
|
||||
if html.match:
|
||||
patron = r'class="title-episodio">(?P<episode>[^<]+)<(?P<url>.*?)<p'
|
||||
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
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
if item.args == 'raccolta' or item.contentType == 'episode':
|
||||
return support.server(item, item.url)
|
||||
else:
|
||||
return support.server(item)
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "fastsubita",
|
||||
"name": "Fastsubita",
|
||||
"language": ["sub-ita"],
|
||||
"active": false,
|
||||
"thumbnail": "fastsubita.png",
|
||||
"banner": "fastsubita.png",
|
||||
"categories": ["tvshow", "vos"],
|
||||
"not_active": ["include_in_newest_peliculas", "include_in_newest_anime"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per fastsubita.py
|
||||
# ------------------------------------------------------------
|
||||
"""
|
||||
|
||||
Su questo canale, nella categoria 'Ricerca Globale'
|
||||
non saranno presenti le voci 'Aggiungi alla Videoteca'
|
||||
e 'Scarica Film'/'Scarica Serie', dunque,
|
||||
la loro assenza, nel Test, NON dovrà essere segnalata come ERRORE.
|
||||
|
||||
Novità. Indicare in quale/i sezione/i è presente il canale:
|
||||
- serie
|
||||
|
||||
Ulteriori info:
|
||||
- SOLO SUB-ITA
|
||||
|
||||
"""
|
||||
from core import support, httptools, scrapertools
|
||||
from core.item import Item
|
||||
from core.support import info
|
||||
from platformcode import config
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
Tvshow = [
|
||||
('Aggiornamenti', ['', 'peliculas', 'update']),
|
||||
('Cerca... {bold}{TV}', ['', 'search'])
|
||||
]
|
||||
|
||||
# search = ''
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.info(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':
|
||||
patronBlock = r'<h4 id="mctm1-.">'+item.fulltitle+'</h4>(?P<block>.+?)</div>'
|
||||
patron = r'[^>]+>[^>]+>.+?href="(?P<url>[^"]+)[^>]>(?P<title>[^<]+)\s<'
|
||||
action = 'episodios'
|
||||
elif item.args == 'search':
|
||||
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:
|
||||
# è 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
|
||||
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)
|
||||
return episodios_args(item)
|
||||
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
support.info()
|
||||
#support.dbg()
|
||||
|
||||
action = 'peliculas'
|
||||
patronBlock = r'<div id="mcTagMapNav">(?P<block>.+?)</div>'
|
||||
patron = r'<a href="(?P<url>[^"]+)">(?P<title>.+?)</a>'
|
||||
|
||||
def itemHook(item):
|
||||
item.url = host+'/elenco-serie-tv/'
|
||||
item.contentType = 'tvshow'
|
||||
return item
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.info('search', item)
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '?s=' + text
|
||||
try:
|
||||
item.args = 'search'
|
||||
item.contentType = 'tvshow'
|
||||
return peliculas(item)
|
||||
# Se captura la excepcion, para no interrumpir al buscador global si un canal falla
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
info('search log:', line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
support.info('newest ->', categoria)
|
||||
itemlist = []
|
||||
item = Item()
|
||||
if categoria == 'series':
|
||||
try:
|
||||
item.contentType = 'tvshow'
|
||||
item.args = 'newest'
|
||||
item.url = host
|
||||
item.action = 'peliculas'
|
||||
itemlist = peliculas(item)
|
||||
|
||||
if itemlist[-1].action == 'peliculas':
|
||||
itemlist.pop()
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info('newest log: ', line)
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.info('findvideos ->', item)
|
||||
patron = r'<a href="([^"]+)">'
|
||||
|
||||
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,
|
||||
# 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
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "film4k",
|
||||
"name": "Film4k",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "film4k.png",
|
||||
"banner": "film4k.png",
|
||||
"categories": ["tvshow", "movie", "anime"],
|
||||
"not_active": ["include_in_newest_peliculas", "include_in_newest_anime", "include_in_newest_series"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per film4k
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
from platformcode import logger, config
|
||||
|
||||
|
||||
def findhost(url):
|
||||
return support.httptools.downloadpage(url).url
|
||||
|
||||
host = config.get_channel_url(findhost)
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
film = ['movies',
|
||||
('Qualità', ['', 'menu', 'quality']),
|
||||
('Generi', ['movies', 'menu', 'genres']),
|
||||
('Anno', ['movies', 'menu', 'releases']),
|
||||
('Più popolari', ['trending/?get=movies', 'peliculas']),
|
||||
('Più votati', ['ratings/?get=movies', 'peliculas'])]
|
||||
tvshow = ['/tvshows',
|
||||
('Più popolari', ['trending/?get=tv', 'peliculas']),
|
||||
('Più votati', ['ratings/?get=tv', 'peliculas'])]
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
logger.info('search', text)
|
||||
item.url = item.url + "/?s=" + text
|
||||
try:
|
||||
return support.dooplay_search(item)
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
if 'anime' in item.url:
|
||||
return support.dooplay_peliculas(item, True)
|
||||
else:
|
||||
return support.dooplay_peliculas(item, False)
|
||||
|
||||
|
||||
def episodios(item):
|
||||
itemlist = support.dooplay_get_episodes(item)
|
||||
return itemlist
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = []
|
||||
if item.contentType == 'episode':
|
||||
linkHead = support.httptools.downloadpage(item.url, only_headers=True).headers['link']
|
||||
epId = support.scrapertools.find_single_match(linkHead, r'\?p=([0-9]+)>')
|
||||
for link in support.dooplay_get_links(item, host, paramList=[['tv', epId, 1, 'title', 'server']]):
|
||||
itemlist.append(
|
||||
item.clone(action="play", url=link['url']))
|
||||
else:
|
||||
for link, quality in support.match(item.url, patron="(" + host + """links/[^"]+).*?class="quality">([^<]+)""").matches:
|
||||
srv = support.servertools.find_video_items(data=support.httptools.downloadpage(link).data)
|
||||
for s in srv:
|
||||
s.quality = quality
|
||||
itemlist.extend(srv)
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
action = 'peliculas'
|
||||
if item.args in ['genres','releases']:
|
||||
patronBlock = r'<nav class="' + item.args + r'">(?P<block>.*?)</nav'
|
||||
patronMenu= r'<a href="(?P<url>[^"]+)"[^>]*>(?P<title>[^<]+)<'
|
||||
else:
|
||||
patronBlock = r'class="main-header">(?P<block>.*?)headitems'
|
||||
patronMenu = r'(?P<url>' + host + r'quality/[^/]+/\?post_type=movies)">(?P<title>[^<]+)'
|
||||
return locals()
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"id": "filmigratis",
|
||||
"name": "Filmi Gratis",
|
||||
"active": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "filmigratis.png",
|
||||
"banner": "filmigratis.png",
|
||||
"categories": ["movie","tvshow"],
|
||||
"settings": [
|
||||
{
|
||||
"id": "include_in_newest_peliculas",
|
||||
"type": "bool",
|
||||
"label": "@70727",
|
||||
"default": false,
|
||||
"enabled": false,
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_series",
|
||||
"type": "bool",
|
||||
"label": "@70727",
|
||||
"default": false,
|
||||
"enabled": false,
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_anime",
|
||||
"type": "bool",
|
||||
"label": "@70727",
|
||||
"default": false,
|
||||
"enabled": false,
|
||||
"visible": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per Filmi Gratis
|
||||
# ------------------------------------------------------------
|
||||
"""
|
||||
La voce "Al cinema" si riferisce ai titoli che scorrono nella home page
|
||||
|
||||
Problemi:
|
||||
- Nessuno noto
|
||||
|
||||
Novità, il canale, è presente in:
|
||||
- FILM
|
||||
"""
|
||||
import re
|
||||
|
||||
from core import httptools, support
|
||||
from core.item import Item
|
||||
from platformcode import config
|
||||
|
||||
host = config.get_channel_url()
|
||||
|
||||
|
||||
|
||||
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
film = [
|
||||
('Al Cinema ', ['', 'peliculas', 'cinema']),
|
||||
('Categorie', ['', 'genres', 'genres']),
|
||||
]
|
||||
|
||||
tvshow = ['/serie/ALL',
|
||||
('Generi', ['', 'genres', 'genres'])
|
||||
]
|
||||
|
||||
search = ''
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.info()
|
||||
|
||||
if item.args == 'search':
|
||||
action = ''
|
||||
patron = r'<div class="cnt">.*?src="([^"]+)"[^>]+>[^>]+>[^>]+>\s+(?P<title>.+?)(?:\[(?P<lang>Sub-ITA|SUB-ITA|SUB)\])?\s?(?:\[?(?P<quality>HD).+\]?)?\s?(?:\(?(?P<year>\d+)?\)?)?\s+<[^>]+>[^>]+>[^>]+>\s<a href="(?P<url>[^"]+)"[^<]+<'
|
||||
patronBlock = r'<div class="container">(?P<block>.*?)</main>'
|
||||
elif item.contentType == 'movie':
|
||||
if not item.args:
|
||||
# voce menu: Film
|
||||
patronBlock = r'<h1>Film streaming ita in alta definizione</h1>(?P<block>.*?)<div class="content-sidebar">'
|
||||
patron = r'<div class="timeline-right">[^>]+>\s<a href="(?P<url>.*?)".*?src="(?P<thumb>.*?)".*?<h3 class="timeline-post-title">(?:(?P<title>.+?)\s\[?(?P<lang>Sub-ITA)?\]?\s?\[?(?P<quality>HD)?\]?\s?\(?(?P<year>\d+)?\)?)<'
|
||||
patronNext = r'<a class="page-link" href="([^"]+)">>'
|
||||
elif item.args == 'cinema':
|
||||
patronBlock = r'<div class="owl-carousel" id="postCarousel">(?P<block>.*?)<section class="main-content">'
|
||||
patron = r'background-image: url\((?P<thumb>.*?)\).*?<h3.*?>(?:(?P<title>.+?)\s\[?(?P<lang>Sub-ITA)?\]?\s?\[?(?P<quality>HD)?\]?\s?\(?(?P<year>\d+)?\)?)<.+?<a.+?<a href="(?P<url>[^"]+)"[^>]+>'
|
||||
elif item.args == 'genres':
|
||||
# ci sono dei titoli dove ' viene sostituito con " da support
|
||||
data = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True).data
|
||||
data = re.sub('\n|\t', ' ', data)
|
||||
patron = r'<div class="cnt">\s.*?src="([^"]+)".+?title="((?P<title>.+?)(?:[ ]\[(?P<lang>Sub-ITA|SUB-ITA)\])?(?:[ ]\[(?P<quality>.*?)\])?(?:[ ]\((?P<year>\d+)\))?)"\s*[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s+<a href="(?P<url>[^"]+)"'
|
||||
patronBlock = r'<div class="container">(?P<block>.*?)</main>'
|
||||
pagination = ''
|
||||
|
||||
patronNext = '<a class="page-link" href="([^"]+)">>>'
|
||||
else:
|
||||
action = 'episodios'
|
||||
patron = r'<div class="cnt">\s.*?src="([^"]+)".+?title="((?P<title>.+?)(?:[ ]\[(?P<lang>Sub-ITA|SUB-ITA)\])?(?:[ ]\[(?P<quality>.*?)\])?(?:[ ]\((?P<year>\d+)\))?)"\s*[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s+<a href="(?P<url>[^"]+)"'
|
||||
## if item.args == 'search':
|
||||
## patron = r'<div class="cnt">.*?src="([^"]+)".+?[^>]+>[^>]+>[^>]+>\s+((?P<title>.+?)(?:[ ]\[(?P<lang>Sub-ITA|SUB-ITA)\])?(?:[ ]\[(?P<quality>.*?)\])?(?:[ ]\((?P<year>\d+)\))?)\s+<[^>]+>[^>]+>[^>]+>[ ]<a href="(?P<url>[^"]+)"'
|
||||
patronBlock = r'<div class="container">(?P<block>.*?)</main>'
|
||||
|
||||
def itemHook(item):
|
||||
if item.args == 'search':
|
||||
if 'series' in item.url:
|
||||
item.action = 'episodios'
|
||||
item.contentType = 'tvshow'
|
||||
else:
|
||||
item.action = 'findvideos'
|
||||
item.contentType = 'movie'
|
||||
return item
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
support.info()
|
||||
|
||||
action = 'findvideos'
|
||||
patronBlock = r'<div class="row">(?P<block>.*?)<section class="main-content">'
|
||||
patron = r'href="(?P<url>.*?)">(?:.+?)?\s+S(?P<season>\d+)\s\-\sEP\s(?P<episode>\d+)[^<]+<'
|
||||
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
support.info()
|
||||
|
||||
if item.contentType == 'movie':
|
||||
action = 'peliculas'
|
||||
patron = r'<a href="(?P<url>.*?)">(?P<title>.*?)<'
|
||||
patronBlock = r'CATEGORIES.*?<ul>(?P<block>.*?)</ul>'
|
||||
else:
|
||||
item.contentType = 'tvshow'
|
||||
action = 'peliculas'
|
||||
blacklist = ['Al-Cinema']
|
||||
patron = r'<a href="(?P<url>.*?)">(?P<title>.*?)<'
|
||||
patronBlock = r'class="material-button submenu-toggle"> SERIE TV.*?<ul>.*?</li>(?P<block>.*?)</ul>'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.info('search', item)
|
||||
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/search/?s=' + text
|
||||
try:
|
||||
item.args = 'search'
|
||||
return peliculas(item)
|
||||
# Se captura la excepcion, para no interrumpir al buscador global si un canal falla
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info('search log:', line)
|
||||
return []
|
||||
|
||||
def newest(categoria):
|
||||
support.info('newest ->', categoria)
|
||||
itemlist = []
|
||||
item = Item()
|
||||
try:
|
||||
if categoria == 'peliculas':
|
||||
item.url = host
|
||||
item.contentType = 'movie'
|
||||
item.action = 'peliculas'
|
||||
itemlist = peliculas(item)
|
||||
|
||||
if itemlist[-1].action == 'peliculas':
|
||||
itemlist.pop()
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info({0}.format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
return support.server(item)
|
||||
@@ -35,8 +35,9 @@ def list(item):
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
# debug = True
|
||||
patron = r'<div class="mlnh-thumb"><a href="(?P<url>[^"]+).*?title="(?P<title>[^"]+).*?src="(?P<thumb>[^"]+).*?hdn">(?P<year>[0-9]{4})'
|
||||
patronNext = 'pagenavi.*?<span>.</span>.*?<a href="([^"]+)'
|
||||
patronNext = 'pagenavi.*?<a href="([^"]+)">\d+'
|
||||
action = 'episodios'
|
||||
return locals()
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ def mainlist(item):
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
debug = True
|
||||
# debug = True
|
||||
# patronBlock = r'movies-list movies-list-full(?P<block>.*?)footer>'
|
||||
if item.args == 'search':
|
||||
patron = r'<div data-movie-id[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>(?:\s*<span class="mli-quality">(?P<quality>[^>]+)</span>)?\s*<img src="(?P<thumbnail>[^"]+)[^>]+>[^>]+>[^>]+>(?P<title>[^<]+).*?jt-info[^>]+>[^:]+:\s*(?P<rating>[^<]+)[^>]+>[^>]+>[^>]+>(?P<year>\d*)[^>]+>[^>]+>[^>]+>(?P<duration>\d*).*?"f-desc">(?:\s*<p>(?P<plot>[^<]+))?'
|
||||
|
||||
@@ -34,8 +34,8 @@ def mainlist(item):
|
||||
|
||||
|
||||
def live(item):
|
||||
itemlist = [item.clone(title=support.typo('La7', 'bold'), fulltitle='La7', url= host + '/dirette-tv', action='play', forcethumb = True, no_return=True),
|
||||
item.clone(title=support.typo('La7d', 'bold'), fulltitle='La7d', url= host + '/live-la7d', action='play', forcethumb = True, no_return=True)]
|
||||
itemlist = [item.clone(title=support.typo('La7', 'bold'), fulltitle='La7', url= host + '/dirette-tv', action='findvideos', forcethumb = True, no_return=True),
|
||||
item.clone(title=support.typo('La7d', 'bold'), fulltitle='La7d', url= host + '/live-la7d', action='findvideos', forcethumb = True, no_return=True)]
|
||||
return support.thumb(itemlist, live=True)
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ def replay_menu(item):
|
||||
|
||||
@support.scrape
|
||||
def replay(item):
|
||||
action = 'play'
|
||||
action = 'findvideos'
|
||||
patron = r'guida-tv"><[^>]+><[^>]+>(?P<hour>[^<]+)<[^>]+><[^>]+><[^>]+>\s*<a href="(?P<url>[^"]+)"><[^>]+><div class="[^"]+" data-background-image="(?P<t>[^"]+)"><[^>]+><[^>]+><[^>]+><[^>]+>\s*(?P<name>[^<]+)<[^>]+><[^>]+><[^>]+>(?P<plot>[^<]+)<'
|
||||
def itemHook(item):
|
||||
item.title = support.typo(item.hour + ' - ' + item.name,'bold')
|
||||
@@ -99,7 +99,7 @@ def peliculas(item):
|
||||
def episodios(item):
|
||||
data = support.match(item).data
|
||||
# debug = True
|
||||
action = 'play'
|
||||
action = 'findvideos'
|
||||
if '>puntate<' in data:
|
||||
patronBlock = r'>puntate<(?P<block>.*?)home-block-outbrain'
|
||||
url = support.match(data, patron=r'>puntate<[^>]+>[^>]+>[^>]+><a href="([^"]+)"').match
|
||||
@@ -127,7 +127,7 @@ def episodios(item):
|
||||
return locals()
|
||||
|
||||
|
||||
def play(item):
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
if item.livefilter:
|
||||
for it in live(item):
|
||||
@@ -169,5 +169,6 @@ def play(item):
|
||||
match = support.match(data, patron='/content/entry/data/(.*?).mp4').match
|
||||
if match:
|
||||
url = 'https://awsvodpkg.iltrovatore.it/local/hls/,/content/entry/data/' + support.match(item, patron='/content/entry/data/(.*?).mp4').match + '.mp4.urlset/master.m3u8'
|
||||
item = item.clone(title='Direct', url=url, server='directo', action='play')
|
||||
return support.servertools.find_video_items(item, data=url)
|
||||
|
||||
item = item.clone(title='Direct', server='directo', url=url, action='play')
|
||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"id": "mediasetplay",
|
||||
"name": "Mediaset Play",
|
||||
"name": "Mediaset play infinity [free]",
|
||||
"active": true,
|
||||
"language": ["ita"],
|
||||
"thumbnail": "mediasetplay.png",
|
||||
"banner": "mediasetplay.png",
|
||||
"thumbnail": "mediasetplayinfinity.png",
|
||||
"banner": "mediasetplayinfinity.png",
|
||||
"categories": ["movie", "tvshow", "documentary", "live"],
|
||||
"not_active": ["include_in_newest"],
|
||||
"default_off": ["include_in_global_search"],
|
||||
|
||||
@@ -95,7 +95,7 @@ def live(item):
|
||||
urls=guide['tuningInstruction']['urn:theplatform:tv:location:any'],
|
||||
plot=plot,
|
||||
url=url,
|
||||
action='play',
|
||||
action='findvideos',
|
||||
thumbnail=thumb,
|
||||
forcethumb=True))
|
||||
|
||||
@@ -141,7 +141,7 @@ def peliculas(item):
|
||||
else:
|
||||
contentType = 'movie'
|
||||
video_id = it['guid']
|
||||
action = 'play'
|
||||
action = 'findvideos'
|
||||
for k, v in it['thumbnails'].items():
|
||||
if 'image_vertical' in k and not thumb:
|
||||
thumb = v['url'].replace('.jpg', '@3.jpg')
|
||||
@@ -228,13 +228,13 @@ def episodios(item):
|
||||
thumbnail=thumb,
|
||||
forcethumb=True,
|
||||
contentType='episode',
|
||||
action='play',
|
||||
action='findvideos',
|
||||
video_id=it['guid']))
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def play(item):
|
||||
def findvideos(item):
|
||||
logger.debug()
|
||||
item.no_return=True
|
||||
# support.dbg()
|
||||
@@ -262,7 +262,7 @@ def play(item):
|
||||
|
||||
else:
|
||||
item.manifest = 'hls'
|
||||
return[item]
|
||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||
|
||||
elif item.video_id:
|
||||
payload = '{"contentId":"' + item.video_id + ' ","streamType":"VOD","delivery":"Streaming","createDevice":true}'
|
||||
@@ -288,7 +288,7 @@ def play(item):
|
||||
else:
|
||||
item.manifest = 'hls'
|
||||
|
||||
return [item]
|
||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||
|
||||
|
||||
def get_from_id(item):
|
||||
|
||||
@@ -41,6 +41,10 @@ def peliculas(item):
|
||||
patron= r'<img src="[^"]+" alt="(?P<title>[^"]+)" data-echo="(?P<thumb>[^"]+)"(?:[^>]+>){7}<a href="(?P<url>[^"]+)"'
|
||||
patronNext = r'<a href="([^"]+)">(?:»|»)'
|
||||
typeContentDict = {'': 'music'}
|
||||
def itemHook(item):
|
||||
item.contentType = 'music'
|
||||
item.thumbnail = item.thumbnail.replace('https:','http:')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "netfreex",
|
||||
"name": "Netfreex",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "netfreex.png",
|
||||
"banner": "netfreex.png",
|
||||
"categories": ["tvshow", "movie", "anime"],
|
||||
"not_active": ["include_in_newest_peliculas", "include_in_newest_anime", "include_in_newest_series"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per netfreex
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
from core.item import Item
|
||||
from platformcode import logger, config
|
||||
|
||||
# def findhost(url):
|
||||
# return 'https://' + support.match('https://netfreex.uno/', patron='value="site:([^"]+)"').match
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = ""
|
||||
|
||||
IDIOMAS = {'Italiano': 'IT'}
|
||||
list_language = IDIOMAS.values()
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
film = ['/film',
|
||||
('Generi', ['', 'menu', 'genres'])
|
||||
]
|
||||
tvshow = ['/serietv']
|
||||
anime = ['/genere/anime']
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
logger.info('search', text)
|
||||
item.url = item.url + "/?s=" + text
|
||||
try:
|
||||
return support.dooplay_search(item)
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
if 'anime' in item.url:
|
||||
return support.dooplay_peliculas(item, True)
|
||||
else:
|
||||
return support.dooplay_peliculas(item, False)
|
||||
|
||||
|
||||
def episodios(item):
|
||||
return support.dooplay_get_episodes(item)
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
from core import jsontools
|
||||
itemlist = []
|
||||
matches = support.match(item, patron=r'<li id="player-option-[0-9]".*?data-type="([^"]+)" data-post="([^"]+)" data-nume="([^"]+)".*?<span class="title".*?>([^<>]+)</span>(?:<span class="server">([^<>]+))?').matches
|
||||
for Type, Post, Nume, Quality, Server in matches:
|
||||
dataAdmin = support.match(host + '/wp-json/dooplayer/v1/post/%s?type=%s&source=%s' %(Post, Type, Nume)).data
|
||||
js = jsontools.load(dataAdmin)
|
||||
link = js['embed_url'] if 'embed_url' in js else ''
|
||||
itemlist.append( item.clone(server=Server, quality=Quality, url=link, action='play'))
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
action = 'peliculas'
|
||||
data = support.match(item, patron=r'<a href="#">Genere<(.*?)</ul').match
|
||||
patronMenu= r'<a href="(?P<url>[^"]+)"[^>]*>(?P<title>[^<]+)<'
|
||||
return locals()
|
||||
@@ -7,6 +7,8 @@ from core import support, jsontools
|
||||
from platformcode import autorenumber, logger
|
||||
from collections import OrderedDict
|
||||
|
||||
from specials import videolibrary
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
@@ -64,7 +66,7 @@ def live(item):
|
||||
logger.debug()
|
||||
itemlist=[]
|
||||
for key, value in liveDict().items():
|
||||
itemlist.append(item.clone(title=support.typo(key,'bold'), contentTitle=key, fulltitle=key, show=key, url=value['url'], plot=value['plot'], action='play', forcethumb=True, no_return=True))
|
||||
itemlist.append(item.clone(title=support.typo(key,'bold'), contentTitle=key, fulltitle=key, show=key, url=value['url'], plot=value['plot'], action='findvideos', forcethumb=True, no_return=True))
|
||||
return support.thumb(itemlist, live=True)
|
||||
|
||||
|
||||
@@ -160,19 +162,22 @@ def episodios(item):
|
||||
|
||||
def findvideos(item):
|
||||
logger.debug()
|
||||
return support.server(item, itemlist=[item.clone(title='Paramount', server='directo', action='play')], Download=False)
|
||||
|
||||
|
||||
def play(item):
|
||||
logger.debug()
|
||||
item.manifest = 'hls'
|
||||
mgid = support.match(item.url, patron=r'uri":"([^"]+)"').match
|
||||
url = 'https://media.mtvnservices.com/pmt/e1/access/index.html?uri=' + mgid + '&configtype=edge&ref=' + item.url
|
||||
ID, rootUrl = support.match(url, patron=[r'"id":"([^"]+)",',r'brightcove_mediagenRootURL":"([^"]+)"']).matches
|
||||
item.url = jsontools.load(support.match(rootUrl.replace('&device={device}','').format(uri = ID)).data)['package']['video']['item'][0]['rendition'][0]['src']
|
||||
return support.server(item, itemlist=[item.clone(title='Paramount', server='directo', action='play')], Download=False, Videolibrary=False)
|
||||
|
||||
if item.livefilter:
|
||||
d = liveDict()[item.livefilter]
|
||||
item = item.clone(title=support.typo(item.livefilter, 'bold'), fulltitle=item.livefilter, url=d['url'], plot=d['plot'], action='play', forcethumb=True, no_return=True)
|
||||
support.thumb(item, live=True)
|
||||
return [item]
|
||||
|
||||
# def play(item):
|
||||
# logger.debug()
|
||||
# item.manifest = 'hls'
|
||||
# mgid = support.match(item.url, patron=r'uri":"([^"]+)"').match
|
||||
# url = 'https://media.mtvnservices.com/pmt/e1/access/index.html?uri=' + mgid + '&configtype=edge&ref=' + item.url
|
||||
# ID, rootUrl = support.match(url, patron=[r'"id":"([^"]+)",',r'brightcove_mediagenRootURL":"([^"]+)"']).matches
|
||||
# item.url = jsontools.load(support.match(rootUrl.replace('&device={device}','').format(uri = ID)).data)['package']['video']['item'][0]['rendition'][0]['src']
|
||||
|
||||
|
||||
# return [item]
|
||||
@@ -45,7 +45,7 @@ def live(item):
|
||||
itemlist.append(item.clone(title= '[B]{}[/B] | {}'.format(it['name'], guide[it['number']][0]),
|
||||
number=it['number'],
|
||||
contentTitle=it['name'],
|
||||
action='play',
|
||||
action='findvideos',
|
||||
thumbnail=it['solidLogoPNG']['path'],
|
||||
fanart=it['featuredImage']['path'],
|
||||
plot='{}\n\n[B]A seguire:[/B]\n{}'.format(it['summary'], guide[it['number']][1]),
|
||||
@@ -84,12 +84,11 @@ def peliculas(item):
|
||||
contentSerieName= it['name'] if it['type'] == 'series' else '',
|
||||
plot=it['description'],
|
||||
contentType='tvshow' if it['type'] == 'series' else 'movie',
|
||||
action='episodios' if it['type'] == 'series' else 'play',
|
||||
action='episodios' if it['type'] == 'series' else 'findvideos',
|
||||
thumbnail= it['covers'][0]['url'],
|
||||
fanart= it['covers'][2]['url'] if len(it['covers']) > 2 else '',
|
||||
id= it['_id'],
|
||||
videourl= it['stitched']['urls'][0]['url'].split('?')[0],
|
||||
forcethumb=True)
|
||||
videourl= it['stitched']['urls'][0]['url'].split('?')[0])
|
||||
|
||||
if i < 20 or item.search:
|
||||
itemlist.append(itm)
|
||||
@@ -115,8 +114,7 @@ def episodios(item):
|
||||
plot=episode['description'],
|
||||
thumbnail=episode['covers'][1]['url'],
|
||||
videourl=episode['stitched']['urls'][0]['url'].split('?')[0],
|
||||
action='play',
|
||||
forcethumb=True))
|
||||
action='findvideos'))
|
||||
|
||||
if config.get_setting('episode_info'):
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
@@ -124,7 +122,7 @@ def episodios(item):
|
||||
return itemlist
|
||||
|
||||
|
||||
def play(item):
|
||||
def findvideos(item):
|
||||
item.server = 'directo'
|
||||
item.manifest='hls'
|
||||
params = '{}?deviceDNT=0&deviceVersion=unknow&appVersion=unknow&deviceType=web&deviceMake=firefox&deviceModel=firefox&appName=web&{}'
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"id": "polpotv",
|
||||
"name": "PolpoTV",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "polpotv.png",
|
||||
"banner": "polpotv.png",
|
||||
"categories": ["movie","tvshow"],
|
||||
"not_active":[],
|
||||
"default_off":["include_in_newest"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# KoD - XBMC Plugin
|
||||
# Canale polpotv
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support, jsontools
|
||||
from core.item import Item
|
||||
from platformcode import config
|
||||
import datetime
|
||||
|
||||
host = config.get_channel_url()
|
||||
|
||||
headers = [['Accept', 'application/ld+json']]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
# menu = [
|
||||
# ('Ultimi Film aggiunti', ['/api/movies', 'peliculas', '']),
|
||||
# ('Ultime Serie TV aggiunte', ['/api/shows', 'peliculas', '']),
|
||||
# ('Generi', ['/api/genres', 'search_movie_by_genre', '']),
|
||||
# ('Anni {film}', ['', 'search_movie_by_year', '']),
|
||||
# ('Cerca... bold', ['', 'search', ''])
|
||||
# ]
|
||||
film = ['/api/movies',
|
||||
('Generi', ['/api/genres', 'search_movie_by_genre', '']),
|
||||
('Anni', ['', 'search_movie_by_year', '']),]
|
||||
|
||||
tvshow=['/api/shows']
|
||||
|
||||
search=''
|
||||
|
||||
return locals()
|
||||
|
||||
def newest(categoria):
|
||||
support.info()
|
||||
item = Item()
|
||||
if categoria == 'peliculas':
|
||||
item.contentType = 'movie'
|
||||
item.url = host + '/api/movies'
|
||||
elif categoria == 'series':
|
||||
item.contentType = 'tvshow'
|
||||
item.url = host+'/api/shows'
|
||||
return peliculas(item)
|
||||
|
||||
def peliculas(item):
|
||||
support.info()
|
||||
itemlist = []
|
||||
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for element in json_object['hydra:member']:
|
||||
if 'shows' not in item.url:
|
||||
item.contentType='movie'
|
||||
else:
|
||||
item.contentType='tvshow'
|
||||
itemlist.append(get_itemlist_element(element, item))
|
||||
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
try:
|
||||
if support.inspect.stack()[1][3] not in ['newest']:
|
||||
support.nextPage(itemlist, item, next_page=json_object['hydra:view']['hydra:next'])
|
||||
except:
|
||||
pass
|
||||
|
||||
return itemlist
|
||||
|
||||
def episodios(item):
|
||||
support.info()
|
||||
itemlist = []
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for season in json_object['seasons']:
|
||||
seas_url=host+season['@id']+'/releases'
|
||||
itemlist_season=get_season(item, seas_url, season['seasonNumber'])
|
||||
if(len(itemlist_season)>0):
|
||||
itemlist.extend(itemlist_season)
|
||||
|
||||
support.videolibrary(itemlist, item, 'color kod bold')
|
||||
support.download(itemlist, item)
|
||||
|
||||
return itemlist
|
||||
|
||||
def get_season(item, seas_url, seasonNumber):
|
||||
support.info()
|
||||
itemlist = []
|
||||
data = support.match(seas_url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for episode in json_object['hydra:member']:
|
||||
itemlist.append(
|
||||
item.clone(action='findvideos',
|
||||
contentType='episode',
|
||||
title=support.typo(str(seasonNumber)+"x"+str("%02d"%episode['episodeNumber']), 'bold'),
|
||||
url=seas_url,
|
||||
extra=str(len(json_object['hydra:member'])-episode['episodeNumber'])))
|
||||
return itemlist[::-1]
|
||||
|
||||
def search(item, texto):
|
||||
support.info(item.url, "search", texto)
|
||||
itemlist=[]
|
||||
try:
|
||||
item.url = host + "/api/movies?originalTitle="+texto+"&translations.name=" +texto
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for movie in json_object['hydra:member']:
|
||||
item.contentType='movie'
|
||||
itemlist.append(get_itemlist_element(movie,item))
|
||||
item.url = host + "/api/shows?originalTitle="+texto+"&translations.name=" +texto
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for tvshow in json_object['hydra:member']:
|
||||
item.contentType='tvshow'
|
||||
itemlist.append(get_itemlist_element(tvshow,item))
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
return itemlist
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
def search_movie_by_genre(item):
|
||||
support.info()
|
||||
itemlist = []
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
for genre in json_object['hydra:member']:
|
||||
itemlist.append(
|
||||
item.clone(action="peliculas",
|
||||
title=support.typo(genre['name'],'bold'),
|
||||
contentType='movie',
|
||||
url="%s/api/movies?genres.id=%s" %(host,genre['id'])))
|
||||
return support.thumb(itemlist, True)
|
||||
|
||||
|
||||
def search_movie_by_year(item):
|
||||
support.info()
|
||||
now = datetime.datetime.now()
|
||||
year = int(now.year)
|
||||
itemlist = []
|
||||
for i in range(100):
|
||||
year_to_search = year - i
|
||||
itemlist.append(
|
||||
item.clone(channel=item.channel,url="%s/api/movies?releaseDate=%s" %(host,year_to_search),
|
||||
plot="1",
|
||||
type="movie",
|
||||
title=support.typo(year_to_search,'bold'),
|
||||
action="peliculas"))
|
||||
return itemlist
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
itemlist = []
|
||||
try:
|
||||
data = support.match(item.url, headers=headers).data
|
||||
json_object = jsontools.load(data)
|
||||
array_index=0
|
||||
if item.contentType!='movie':
|
||||
array_index=int(item.extra)
|
||||
for video in json_object['hydra:member'][array_index]['playlist']['videos']:
|
||||
itemlist.append(
|
||||
item.clone(action="play",
|
||||
title='Direct',
|
||||
url=video['src'],
|
||||
server='directo',
|
||||
quality=str(video['size'])+ 'p',
|
||||
folder=False))
|
||||
except:
|
||||
pass
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
|
||||
def get_itemlist_element(element,item):
|
||||
support.info()
|
||||
contentSerieName = ''
|
||||
contentTitle =''
|
||||
try:
|
||||
if element['originalLanguage']['id']=='it':
|
||||
scrapedtitle=element['originalTitle']
|
||||
else:
|
||||
scrapedtitle=element['translations'][1]['name']
|
||||
if scrapedtitle=='':
|
||||
scrapedtitle=element['originalTitle']
|
||||
except:
|
||||
scrapedtitle=element['originalTitle']
|
||||
try:
|
||||
scrapedplot=element['translations'][1]['overview']
|
||||
except:
|
||||
scrapedplot = ""
|
||||
try:
|
||||
scrapedthumbnail="https:"+element['bestPosters'].values()[0]
|
||||
except:
|
||||
scrapedthumbnail=""
|
||||
# try:
|
||||
# scrapedfanart="http:"+element['backdropPath']
|
||||
# except:
|
||||
# scrapedfanart=""
|
||||
|
||||
infoLabels = {}
|
||||
if item.contentType=='movie':
|
||||
contentTitle = scrapedtitle
|
||||
next_action='findvideos'
|
||||
quality=support.typo(element['lastQuality'].upper(), '_ [] color kod bold')
|
||||
url="%s%s/releases"
|
||||
infoLabels['tmdb_id']=element['tmdbId']
|
||||
else:
|
||||
contentSerieName = scrapedtitle
|
||||
next_action='episodios'
|
||||
quality=''
|
||||
url="%s%s"
|
||||
|
||||
return item.clone(action=next_action,
|
||||
title=support.typo(scrapedtitle, 'bold') + quality,
|
||||
fulltitle=scrapedtitle,
|
||||
show=scrapedtitle,
|
||||
plot=scrapedplot,
|
||||
# fanart=scrapedfanart,
|
||||
thumbnail=scrapedthumbnail,
|
||||
contentTitle=contentTitle,
|
||||
contentSerieName=contentSerieName,
|
||||
contentType=item.contentType,
|
||||
url=url % (host, element['@id']),
|
||||
infoLabels=infoLabels)
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"id": "pufimovies",
|
||||
"name": "PufiMovies",
|
||||
"active": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "pufimovies.png",
|
||||
"banner": "pufimovies.png",
|
||||
"categories": ["movie","tvshow"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per PufiMovies
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
|
||||
|
||||
|
||||
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
film = [
|
||||
('Generi', ['', 'menu', 'Film']),
|
||||
('Più Visti', ['','peliculas', 'most'])
|
||||
]
|
||||
|
||||
tvshow = ['',
|
||||
('Generi', ['', 'menu', 'Serie Tv']),
|
||||
('Ultimi Episodi', ['','peliculas', 'last'])
|
||||
]
|
||||
|
||||
search = ''
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
action = 'peliculas'
|
||||
patronBlock = item.args + r' Categorie</a>\s*<ul(?P<block>.*?)</ul>'
|
||||
patronMenu = r'<a href="(?P<url>[^"]+)"[^>]+>(?P<title>[^>]+)<'
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.info('search', item)
|
||||
itemlist = []
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/search/keyword/' + text
|
||||
try:
|
||||
item.args = 'search'
|
||||
itemlist = peliculas(item)
|
||||
if itemlist[-1].action == 'peliculas':
|
||||
itemlist.pop()
|
||||
return itemlist
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info('search log:', line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
support.info(categoria)
|
||||
itemlist = []
|
||||
item = support.Item()
|
||||
item.url = host
|
||||
item.action = 'peliculas'
|
||||
try:
|
||||
if categoria == 'peliculas':
|
||||
item.contentType = 'movie'
|
||||
itemlist = peliculas(item)
|
||||
else:
|
||||
item.args = 'last'
|
||||
item.contentType = 'tvshow'
|
||||
itemlist = peliculas(item)
|
||||
|
||||
if itemlist[-1].action == 'peliculas':
|
||||
itemlist.pop()
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
if item.contentType == 'tvshow' and not item.args:
|
||||
action = 'episodios'
|
||||
patron = r'<div class="movie-box">\s*<a href="(?P<url>[^"]+)">[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)[^>]+>[^>]+>[^>]+>(?P<quality>[^<]+)[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?P<year>\d+)'
|
||||
elif item.contentType == 'movie' and not item.args:
|
||||
patron = r'<div class="existing_item col-6 col-lg-3 col-sm-4 col-xl-4">\s*<div class="movie-box">\s*<a href="(?P<url>(?:http(?:s)://[^/]+)?/(?P<type>[^/]+)/[^"]+)">[^>]+>[^>]+>\D+Streaming\s*(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?:(?P<year>\d+))?[^>]+>[^>]+>[^>]+>[^>]+>(?P<plot>[^<]*)<'
|
||||
elif item.args == 'last':
|
||||
patron = r'<div class="episode-box">[^>]+>[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>[^^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>\D*(?P<season>\d+)[^>]+>\D*(?P<episode>\d+)'
|
||||
elif item.args == 'most':
|
||||
patron =r'div class="sm-113 item">\s*<a href="(?P<url>[^"]+)">[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*(?P<title>[^<]+)'
|
||||
else:
|
||||
patron = r'<div class="movie-box">\s*<a href="(?P<url>(?:http(?:s)://[^/]+)?/(?P<type>[^/]+)/[^"]+)">[^>]+>[^>]+>\D+Streaming\s*(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?:(?P<year>\d+))?[^>]+>[^>]+>[^>]+>[^>]+>(?P<plot>[^<]*)<'
|
||||
typeActionDict = {'findvideos':['movie'], 'episodios':['tvshow']}
|
||||
typeContentDict = {'movie':['movie'], 'tvshow':['tvshow']}
|
||||
patronNext = r'<a href="([^"]+)"[^>]+>»'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
patron = r'<div class="episode-box">[^>]+>[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>\D*(?P<season>\d+)[^>]+>\D*(?P<episode>\d+)'
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
# match = support.match(item, patron='wstream', debug=True)
|
||||
return support.server(item)
|
||||
@@ -142,7 +142,7 @@ def live(item):
|
||||
current = it['currentItem']
|
||||
next = it['nextItem']
|
||||
plot = '[B]{}[/B]\n{}\n\nA Seguire: [B]{}[/B]\n{}'.format(current['name'], current['description'], next['name'], next['description'])
|
||||
itemlist.append(item.clone(title=title, fulltitle=title, fanart=fanart, plot=plot, url=url, video_url=url + '.json', action='play'))
|
||||
itemlist.append(item.clone(title=title, fulltitle=title, fanart=fanart, plot=plot, url=url, video_url=url + '.json', action='findvideos'))
|
||||
itemlist.sort(key=lambda it: support.channels_order.get(it.fulltitle, 999))
|
||||
support.thumb(itemlist, live=True)
|
||||
return itemlist
|
||||
@@ -209,7 +209,7 @@ def replay(item):
|
||||
plot = info['description'],
|
||||
url = getUrl(it['weblink']),
|
||||
video_url = getUrl(it['path_id']),
|
||||
action = 'play',
|
||||
action = 'findvideos',
|
||||
forcethumb = True)
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ def replay(item):
|
||||
return itemlist
|
||||
|
||||
|
||||
def play(item):
|
||||
def findvideos(item):
|
||||
logger.debug()
|
||||
|
||||
res = requests.get(item.video_url).json()
|
||||
@@ -245,7 +245,7 @@ def play(item):
|
||||
|
||||
item = item.clone(server='directo', url=url, no_return=True) # , manifest='hls')
|
||||
|
||||
return [item]
|
||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||
|
||||
|
||||
def getUrl(url):
|
||||
@@ -306,7 +306,7 @@ def addinfo(items, item):
|
||||
order=n)
|
||||
|
||||
if 'Genere' not in key.get('sub_type', '') and ('layout' not in key or key['layout'] == 'single'):
|
||||
it.action = 'play'
|
||||
it.action = 'findvideos'
|
||||
it.contentTitle = it.fulltitle
|
||||
else:
|
||||
it.action = 'episodios'
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "seriehd",
|
||||
"name": "SerieHD",
|
||||
"active": false,
|
||||
"language": ["ita"],
|
||||
"thumbnail": "seriehd.png",
|
||||
"banner": "seriehd.png",
|
||||
"categories": ["tvshow"],
|
||||
"settings": [],
|
||||
"cloudflare": true
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per SerieHD
|
||||
# ------------------------------------------------------------
|
||||
|
||||
|
||||
from core import support
|
||||
def findhost(url):
|
||||
return support.match(url, patron=r'<h2[^>]+><a href="([^"]+)"').match
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
tvshow = [('Genere', ['', 'menu', 'genre']),
|
||||
('A-Z', ['', 'menu', 'a-z']),
|
||||
('In Corso', ['/category/serie-tv-streaming/serie-in-corso', 'peliculas']),
|
||||
('Complete', ['/category/serie-tv-streaming/serie-complete', 'peliculas']),
|
||||
('Americane', ['/category/serie-tv-streaming/serie-tv-americane', 'peliculas']),
|
||||
('Italiane', ['/category/serie-tv-streaming/serie-tv-italiane', 'peliculas']),
|
||||
('Ultimi Episodi', ['/aggiornamenti', 'peliculas', 'last']),
|
||||
('Evidenza', ['', 'peliculas', 'best'])]
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, texto):
|
||||
support.info(texto)
|
||||
|
||||
|
||||
item.contentType = 'tvshow'
|
||||
item.url = host + "/?s=" + texto
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore .
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
support.info(categoria)
|
||||
|
||||
itemlist = []
|
||||
item = support.Item()
|
||||
item.url = host + '/aggiornamenti'
|
||||
item.args = 'last'
|
||||
try:
|
||||
if categoria == "series":
|
||||
item.contentType = 'tvshow'
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
# debug = True
|
||||
|
||||
if item.args == 'last':
|
||||
action = 'findvideos'
|
||||
patron = r'singleUpdate">(?:[^>]+>){2}\s*<img src="(?P<thumb>[^"]+)"(?:[^>]+>){3}\s*<h2>(?P<title>[^<]+)<(?:[^>]+>){14,16}\s*<a href="(?P<url>[^"]+)">(?:[^>]+>){3}\s*(?P<season>\d+)\D+(?P<episode>\d+)(?:[^\(]*\()?(?P<lang>[^\)]+)?(?:\))?'
|
||||
elif item.args == 'best':
|
||||
action='episodios'
|
||||
patron = r'col-md-3">\s*<a href="(?P<url>[^"]+)">[^>]+>\s*<div class="infoVetrina">[^>]+>(?P<year>\d{4})(?:[^>]+>){2}(?P<title>[^<]+)<(?:[^>]+>){4}(?P<rating>[^<]+)(?:[^>]+>){4}\s*<img src="(?P<thumb>[^"]+)"'
|
||||
else:
|
||||
action='episodios'
|
||||
# patron = r'<a href="(?P<url>[^"]+)">[^>]+>\s*<div class="infoSeries">\s*<h2>(?P<title>[^<]+)<(?:[^>]+>){5}(?P<rating>[^<]+)?(?:[^>]+>){3}\s*<img src="(?P<thumb>[^"]+)"(?:[^>]+>){3}(?P<quality>[^<]+)<(?:[^>]+>){2}(?P<year>\d{4})'
|
||||
patron = r'<a href="(?P<url>[^"]+)">[^>]+>\s*<div class="infoSeries">\s*<h2>(?P<title>[^<]+?)(?:\[(?P<lang>[^\]]+)\])?<(?:[^>]+>){5}(?P<rating>[^<]+)?(?:[^>]+>){3}\s*(?:<img src="(?P<thumb>[^"]+)"[^>]+>)?(?:[^>]+>){0,2}(?P<quality>[^<]+)<(?:[^>]+>){2}(?P<year>\d{4})'
|
||||
patronNext=r'next page-numbers" href="([^"]+)"'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
def get_season(pageData, seas_url, season):
|
||||
data = ''
|
||||
episodes = support.match(pageData if pageData else seas_url, patronBlock=patron_episode, patron=patron_option).matches
|
||||
for episode_url, episode in episodes:
|
||||
# episode_url = support.urlparse.urljoin(item.url, episode_url)
|
||||
# if '-' in episode: episode = episode.split('-')[0].zfill(2) + 'x' + episode.split('-')[1].zfill(2)
|
||||
title = season + "x" + episode.zfill(2) + ' - ' + item.fulltitle
|
||||
data += title + '|' + episode_url + '\n'
|
||||
return data
|
||||
|
||||
patron_season = '<div class="[^"]+" id="seasonsModal"[^>]+>(.*?)</ul>'
|
||||
patron_episode = '<div class="[^"]+" id="episodesModal"[^>]+>(.*?)</ul>'
|
||||
patron_option = r'<a href="([^"]+?)".*?>(?:Stagione |Episodio )([^<]+?)</a>'
|
||||
|
||||
url = support.match(item, patron=r'<iframe id="iframeVid" width="[^"]+" height="[^"]+" src="([^"]+)" allowfullscreen').match
|
||||
seasons = support.match(url, patronBlock=patron_season, patron=patron_option)
|
||||
|
||||
data = ''
|
||||
|
||||
# debugging
|
||||
# support.dbg()
|
||||
# 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
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
thL = []
|
||||
for i, season in enumerate(seasons.matches):
|
||||
thL.append(executor.submit(get_season, seasons.data if i == 0 else '', season[0], season[1]))
|
||||
for res in futures.as_completed(thL):
|
||||
if res.result():
|
||||
data += res.result()
|
||||
# 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: (item.infoLabels['season'], item.infoLabels['episode']))
|
||||
return itemlist
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
if item.args == 'genre':
|
||||
patronMenu = r'<a href="(?P<url>[^"]+)">(?P<title>[^<]+)</a>'
|
||||
else:
|
||||
patronMenu = r'<a href="(?P<url>[^"]+)" class="">(?P<title>[^<]+)'
|
||||
|
||||
blacklist = ['Serie TV Streaming','Serie TV Americane','Serie TV Italiane','Serie Complete','Serie in Corso','altadefinizione']
|
||||
action = 'peliculas'
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
item.url = item.url.replace('&', '&')
|
||||
support.info(item)
|
||||
if item.args == 'last':
|
||||
url = support.match(item, patron = r'<iframe id="iframeVid" width="[^"]+" height="[^"]+" src="([^"]+)" allowfullscreen').match
|
||||
matches = support.match(url,patron=r'<a href="([^"]+)">(\d+)<', patronBlock=r'<h3>EPISODIO</h3><ul>(.*?)</ul>').matches
|
||||
if matches: item.url = support.urlparse.urljoin(url, matches[-1][0])
|
||||
return support.hdpass_get_servers(item)
|
||||
|
||||
|
||||
def play(item):
|
||||
if 'hdpass' in item.url:
|
||||
return support.hdpass_get_url(item)
|
||||
return [item]
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "serietvonline",
|
||||
"name": "SerieTvOnline",
|
||||
"active": false,
|
||||
"language": ["ita"],
|
||||
"thumbnail": "serietvonline.png",
|
||||
"bannermenu": "serietvonline.png",
|
||||
"categories": ["anime","tvshow","movie","documentary"],
|
||||
"not_active": ["include_in_newest_anime"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per serietvonline.py
|
||||
# ----------------------------------------------------------
|
||||
"""
|
||||
Novità. Indicare in quale/i sezione/i è presente il canale:
|
||||
- film, serie
|
||||
|
||||
Avvisi:
|
||||
- Al massimo 25 titoli per le sezioni: Film
|
||||
- Al massimo 35 titoli per le sezioni: Tutte le altre
|
||||
Per aggiungere in videoteca le Anime:
|
||||
Se hanno la forma 1x01:
|
||||
-si posso aggiungere direttamente dalla pagina della serie, sulla voce in fondo "aggiungi in videoteca".
|
||||
Altrimenti:
|
||||
- Prima fare la 'Rinumerazione' dal menu contestuale dal titolo della serie
|
||||
"""
|
||||
import re
|
||||
from core import support, httptools, scrapertools
|
||||
from platformcode import config
|
||||
from core.item import Item
|
||||
|
||||
|
||||
# def findhost(url):
|
||||
# host = support.match(url, patron=r'href="([^"]+)">\s*cliccando qui').matches[-1]
|
||||
# return host
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
support.info()
|
||||
|
||||
|
||||
film = ['/ultimi-film-aggiunti/',
|
||||
('A-Z', ['/lista-film/', 'peliculas', 'lista'])
|
||||
]
|
||||
|
||||
tvshow = ['',
|
||||
('Aggiornamenti', ['/ultimi-episodi-aggiunti/', 'peliculas', 'update']),
|
||||
('Tutte', ['/lista-serie-tv/', 'peliculas', 'qualcosa']),
|
||||
('Italiane', ['/lista-serie-tv-italiane/', 'peliculas', 'qualcosa']),
|
||||
('Anni 50-60-70-80', ['/lista-serie-tv-anni-60-70-80/', 'peliculas', 'qualcosa']),
|
||||
('HD', ['/lista-serie-tv-in-altadefinizione/', 'peliculas', 'qualcosa'])
|
||||
]
|
||||
|
||||
anime = ['/lista-cartoni-animati-e-anime/']
|
||||
|
||||
documentari = [('Documentari {bullet bold}', ['/lista-documentari/' , 'peliculas' , 'doc', 'tvshow'])]
|
||||
|
||||
search = ''
|
||||
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.info()
|
||||
anime = True
|
||||
|
||||
blacklist = ['DMCA', 'Contatti', 'Attenzione NON FARTI OSCURARE', 'Lista Cartoni Animati e Anime']
|
||||
patronBlock = r'<h1>.+?</h1>(?P<block>.*?)<div class="footer_c">'
|
||||
patronNext = r'<div class="siguiente"><a href="([^"]+)" >'
|
||||
# debug = True
|
||||
|
||||
if item.args == 'search':
|
||||
patronBlock = r'>Lista Serie Tv</a></li></ul></div><div id="box_movies">(?P<block>.*?)<div id="paginador">'
|
||||
patron = r'<div class="movie">[^>]+[^>]+>\s*<img src="(?P<thumb>[^"]+)" alt="(?P<title>.+?)(?:(?P<year>\d{4})|")[^>]*>\s*<a href="(?P<url>[^"]+)'
|
||||
elif item.contentType == 'episode':
|
||||
pagination = 35
|
||||
action = 'findvideos'
|
||||
patron = r'<td><a href="(?P<url>[^"]+)"(?:[^>]+)?>\s?(?P<title>.*?)(?P<episode>\d+x\d+)[ ]?(?P<title2>[^<]+)?<'
|
||||
|
||||
elif item.contentType == 'tvshow':
|
||||
# SEZIONE Serie TV- Anime - Documentari
|
||||
pagination = 35
|
||||
|
||||
if not item.args and 'anime' not in item.url:
|
||||
patron = r'<div class="movie">[^>]+>.+?src="(?P<thumb>[^"]+)" alt="[^"]+".+? href="(?P<url>[^"]+)">.*?<h2>(?P<title>[^"]+)</h2>\s?(?:<span class="year">(?P<year>\d+|\-\d+))?<'
|
||||
else:
|
||||
anime = True
|
||||
patron = r'(?:<td>)?<a href="(?P<url>[^"]+)"(?:[^>]+)?>\s?(?P<title>[^<]+)(?P<episode>[\d\-x]+)?(?P<title2>[^<]+)?<'
|
||||
else:
|
||||
# SEZIONE FILM
|
||||
pagination = 25
|
||||
|
||||
if item.args == 'lista':
|
||||
patron = r'href="(?P<url>[^"]+)"[^>]+>(?P<title>.+?)(?:\s(?P<year>\d{4})|<)'
|
||||
patronBlock = r'Lista dei film disponibili in streaming e anche in download\.</p>(?P<block>.*?)<div class="footer_c">'
|
||||
else:
|
||||
patron = r'<tr><td><a href="(?P<url>[^"]+)"(?:|.+?)?>(?: )?[ ]?(?P<title>.*?)[ ]?(?P<quality>HD)?[ ]?(?P<year>\d+)?(?: | HD[^<]*| Streaming[^<]*| MD(?: iSTANCE)? [^<]*)?</a>'
|
||||
|
||||
def itemHook(item):
|
||||
if 'film' in item.url:
|
||||
item.action = 'findvideos'
|
||||
item.contentType = 'movie'
|
||||
elif item.args == 'update':
|
||||
pass
|
||||
else:
|
||||
item.contentType = 'tvshow'
|
||||
item.action = 'episodios'
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
support.info()
|
||||
anime = True
|
||||
action = 'findvideos'
|
||||
patronBlock = r'<table>(?P<block>.*)<\/table>'
|
||||
patron = r'<tr><td>(?P<title>.*?)?[ ](?:Parte)?(?P<episode>\d+x\d+|\d+)(?:|[ ]?(?P<title2>.+?)?(?:avi)?)<(?P<data>.*?)<\/td><tr>'
|
||||
def itemlistHook(itemlist):
|
||||
for i, item in enumerate(itemlist):
|
||||
ep = support.match(item.title, patron=r'\d+x(\d+)').match
|
||||
if ep == '00':
|
||||
item.title = item.title.replace('x00', 'x' + str(i+1).zfill(2)).replace('- ..','')
|
||||
return itemlist
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.info("CERCA :" ,text, item)
|
||||
|
||||
item.url = "%s/?s=%s" % (host, text)
|
||||
|
||||
try:
|
||||
item.args = 'search'
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info("%s" % line)
|
||||
return []
|
||||
|
||||
def newest(categoria):
|
||||
support.info(categoria)
|
||||
|
||||
itemlist = []
|
||||
item = Item()
|
||||
|
||||
if categoria == 'peliculas':
|
||||
item.contentType = 'movie'
|
||||
item.url = host + '/ultimi-film-aggiunti/'
|
||||
elif categoria == 'series':
|
||||
item.args = 'update'
|
||||
item.contentType = 'episode'
|
||||
item.url = host +'/ultimi-episodi-aggiunti/'
|
||||
try:
|
||||
item.action = 'peliculas'
|
||||
itemlist = peliculas(item)
|
||||
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
def findvideos(item):
|
||||
support.info()
|
||||
if item.contentType == 'movie':
|
||||
return support.server(item, headers=headers)
|
||||
else:
|
||||
|
||||
if item.args != 'update':
|
||||
return support.server(item, item.data)
|
||||
else:
|
||||
itemlist = []
|
||||
item.infoLabels['mediatype'] = 'episode'
|
||||
|
||||
data = support.match(item.url, headers=headers).data
|
||||
url_video = scrapertools.find_single_match(data, r'<tr><td>(.+?)</td><tr>', -1)
|
||||
url_serie = scrapertools.find_single_match(data, r'<link rel="canonical" href="([^"]+)"\s?/>')
|
||||
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.clone(title=goseries + series, contentType='tvshow', url=url_serie, action='episodios', plot = goseries + series + "con tutte le puntate", args=''))
|
||||
|
||||
return itemlist
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"id": "serietvsubita",
|
||||
"name": "Serie TV Sub ITA",
|
||||
"active": false,
|
||||
"language": ["ita"],
|
||||
"thumbnail": "serietvsubita.png",
|
||||
"banner": "serietvsubita.png",
|
||||
"categories": ["tvshow"],
|
||||
"settings": [
|
||||
{
|
||||
"id": "include_in_global_search",
|
||||
"type": "bool",
|
||||
"label": "Includi ricerca globale",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_series",
|
||||
"type": "bool",
|
||||
"label": "Includi in Novità - Serie TV",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "checklinks",
|
||||
"type": "bool",
|
||||
"label": "Verifica se i link esistono",
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "checklinks_number",
|
||||
"type": "list",
|
||||
"label": "Numero de link da verificare",
|
||||
"default": 1,
|
||||
"enabled": true,
|
||||
"visible": "eq(-1,true)",
|
||||
"lvalues": [ "1", "3", "5", "10" ]
|
||||
},
|
||||
{
|
||||
"id": "filter_languages",
|
||||
"type": "list",
|
||||
"label": "Mostra link in lingua...",
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": ["Non filtrare","IT"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per Serietvsubita
|
||||
# Thanks to Icarus crew & Alfa addon & 4l3x87
|
||||
# ----------------------------------------------------------
|
||||
|
||||
import re
|
||||
import time
|
||||
|
||||
from core import httptools, tmdb, scrapertools, support
|
||||
from core.item import Item
|
||||
from core.support import info
|
||||
from platformcode import logger, config
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
IDIOMAS = {'Italiano': 'IT'}
|
||||
list_language = IDIOMAS.values()
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
info()
|
||||
itemlist = []
|
||||
tvshowSub = [
|
||||
('Novità {bold}',[ '', 'peliculas_tv', '', 'tvshow']),
|
||||
('Serie TV {bold}',[ '', 'lista_serie', '', 'tvshow']),
|
||||
('Per Lettera', ['', 'list_az', 'serie', 'tvshow'])
|
||||
]
|
||||
cerca = [(support.typo('Cerca...', 'bold'),[ '', 'search', '', 'tvshow'])]
|
||||
## support.aplay(item, itemlist, list_servers, list_quality)
|
||||
## support.channel_config(item, itemlist)
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def cleantitle(scrapedtitle):
|
||||
scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle.strip())
|
||||
scrapedtitle = scrapedtitle.replace('[HD]', '').replace('’', '\'').replace('×', 'x').replace('Game of Thrones –','')\
|
||||
.replace('In The Dark 2019', 'In The Dark (2019)').replace('"', "'").strip()
|
||||
year = scrapertools.find_single_match(scrapedtitle, r'\((\d{4})\)')
|
||||
if year:
|
||||
scrapedtitle = scrapedtitle.replace('(' + year + ')', '')
|
||||
|
||||
return scrapedtitle.strip()
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def findvideos(item):
|
||||
info()
|
||||
data = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True).data
|
||||
data = re.sub(r'\n|\t|\s+', ' ', data)
|
||||
# recupero il blocco contenente i link
|
||||
blocco = scrapertools.find_single_match(data, r'<div class="entry">([\s\S.]*?)<div class="post').replace('..:: Episodio ', 'Episodio ').strip()
|
||||
matches = scrapertools.find_multiple_matches(blocco, r'(S(\d*)E(\d*))\s')
|
||||
if len(matches) > 0:
|
||||
for fullseasonepisode, season, episode in matches:
|
||||
blocco = blocco.replace(fullseasonepisode + ' ', 'Episodio ' + episode + ' ')
|
||||
|
||||
blocco = blocco.replace('Episodio ', '..:: Episodio ')
|
||||
|
||||
episodio = item.infoLabels['episode']
|
||||
patron = r'\.\.:: Episodio %s([\s\S]*?)(<div class="post|..:: Episodio)' % episodio
|
||||
info(patron)
|
||||
info(blocco)
|
||||
|
||||
matches = scrapertools.find_multiple_matches(blocco, patron)
|
||||
if len(matches):
|
||||
data = matches[0][0]
|
||||
|
||||
patron = r'href="(https?://www\.keeplinks\.(?:co|eu)/p(?:[0-9]*)/([^"]+))"'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
for keeplinks, id in matches:
|
||||
headers2 = [['Cookie', 'flag[' + id + ']=1; defaults=1; nopopatall=' + str(int(time.time()))],
|
||||
['Referer', keeplinks]]
|
||||
|
||||
html = httptools.downloadpage(keeplinks, headers=headers2).data
|
||||
data += str(scrapertools.find_multiple_matches(html, '</lable><a href="([^"]+)" target="_blank"'))
|
||||
|
||||
return support.server(item, data=data)
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def lista_serie(item):
|
||||
info()
|
||||
itemlist = []
|
||||
|
||||
PERPAGE = 15
|
||||
|
||||
p = 1 if not item.args else int(item.args)
|
||||
|
||||
if '||' in item.data:
|
||||
series = item.data.split('\n\n')
|
||||
matches = []
|
||||
for i, serie in enumerate(series):
|
||||
matches.append(serie.split('||'))
|
||||
else:
|
||||
# Extrae las entradas
|
||||
patron = r'<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron=patron, headers=headers).matches
|
||||
for i, (scrapedurl, scrapedtitle) in enumerate(matches):
|
||||
scrapedplot = ""
|
||||
scrapedthumbnail = ""
|
||||
if (p - 1) * PERPAGE > i: continue
|
||||
if i >= p * PERPAGE: break
|
||||
title = cleantitle(scrapedtitle)
|
||||
itemlist.append(
|
||||
item.clone(action="episodios",
|
||||
title=title,
|
||||
url=scrapedurl,
|
||||
thumbnail=scrapedthumbnail,
|
||||
fulltitle=title,
|
||||
show=title,
|
||||
plot=scrapedplot,
|
||||
contentType='episode',
|
||||
originalUrl=scrapedurl))
|
||||
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
# Paginazione
|
||||
if len(matches) >= p * PERPAGE:
|
||||
item.args = p + 1
|
||||
support.nextPage(itemlist, item, next_page=item.url)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def episodios(item, itemlist=[]):
|
||||
info()
|
||||
patron = r'<div class="post-meta">\s*<a href="([^"]+)"\s*title="([^"]+)"\s*class=".*?"></a>.*?'
|
||||
patron += r'<p><a href="([^"]+)">'
|
||||
|
||||
|
||||
html = support.match(item, patron=patron, headers=headers)
|
||||
matches = html.matches
|
||||
data = html.data
|
||||
|
||||
for scrapedurl, scrapedtitle, scrapedthumbnail in matches:
|
||||
scrapedplot = ""
|
||||
scrapedtitle = cleantitle(scrapedtitle)
|
||||
if "(Completa)" in scrapedtitle:
|
||||
data = httptools.downloadpage(scrapedurl, headers=headers).data
|
||||
scrapedtitle = scrapedtitle.replace(" – Miniserie", " – Stagione 1")
|
||||
title = scrapedtitle.split(" – Stagione")[0].strip()
|
||||
|
||||
# recupero la stagione
|
||||
season = scrapertools.find_single_match(scrapedtitle, 'Stagione ([0-9]*)')
|
||||
blocco = scrapertools.find_single_match(data, r'<div class="entry">[\s\S.]*?<div class="post')
|
||||
blocco = blocco.replace('<strong>Episodio ', '<strong>Episodio ').replace(' </strong>', ' </strong>')
|
||||
blocco = blocco.replace('<strong>Episodio ', '<strong>S' + season.zfill(2) + 'E')
|
||||
matches = scrapertools.find_multiple_matches(blocco, r'(S(\d*)E(\d*))\s')
|
||||
episodes = []
|
||||
if len(matches) > 0:
|
||||
for fullepisode_s, season, episode in matches:
|
||||
season = season.lstrip("0")
|
||||
|
||||
episodes.append([
|
||||
"".join([season, "x", episode]),
|
||||
season,
|
||||
episode
|
||||
])
|
||||
|
||||
else:
|
||||
title = scrapedtitle.split(" S0")[0].strip()
|
||||
title = title.split(" S1")[0].strip()
|
||||
title = title.split(" S2")[0].strip()
|
||||
episodes = scrapertools.find_multiple_matches(scrapedtitle, r'((\d*)x(\d*))')
|
||||
|
||||
for fullepisode, season, episode in episodes:
|
||||
infoLabels = {}
|
||||
infoLabels['season'] = season
|
||||
infoLabels['episode'] = episode
|
||||
fullepisode += ' ' + support.typo("Sub-ITA", '_ [] color kod')
|
||||
itemlist.append(
|
||||
item.clone(action="findvideos",
|
||||
fulltitle=scrapedtitle,
|
||||
show=scrapedtitle,
|
||||
title=fullepisode,
|
||||
url=scrapedurl,
|
||||
thumbnail=scrapedthumbnail,
|
||||
plot=scrapedplot,
|
||||
contentSerieName=title,
|
||||
infoLabels=infoLabels))
|
||||
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
# Paginazionazione
|
||||
patron = r'<strong class="on">\d+</strong>\s*<a href="([^<]+)">\d+</a>'
|
||||
next_page = scrapertools.find_single_match(data, patron)
|
||||
if next_page != "":
|
||||
item.url = next_page
|
||||
itemlist = episodios(item, itemlist)
|
||||
else:
|
||||
item.url = item.originalUrl
|
||||
support.videolibrary(itemlist, item, 'bold color kod')
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def peliculas_tv(item):
|
||||
info()
|
||||
itemlist = []
|
||||
|
||||
patron = r'<div class="post-meta">\s*<a href="([^"]+)"\s*title="([^"]+)"\s*class=".*?"></a>'
|
||||
|
||||
html = support.match(item, patron=patron, headers=headers)
|
||||
matches = html.matches
|
||||
data = html.data
|
||||
|
||||
for scrapedurl, scrapedtitle in matches:
|
||||
if scrapedtitle in ["FACEBOOK", "RAPIDGATOR", "WELCOME!"]:
|
||||
continue
|
||||
|
||||
scrapedthumbnail = ""
|
||||
scrapedplot = ""
|
||||
scrapedtitle = cleantitle(scrapedtitle)
|
||||
infoLabels = {}
|
||||
episode = scrapertools.find_multiple_matches(scrapedtitle, r'((\d*)x(\d*))')
|
||||
if episode: # workaround per quando mettono le serie intere o altra roba, sarebbero da intercettare TODO
|
||||
episode = episode[0]
|
||||
title = scrapedtitle.split(" S0")[0].strip()
|
||||
title = title.split(" S1")[0].strip()
|
||||
title = title.split(" S2")[0].strip()
|
||||
|
||||
infoLabels['season'] = episode[1]
|
||||
infoLabels['episode'] = episode[2].zfill(2)
|
||||
|
||||
itemlist.append(
|
||||
item.clone(action="findvideos",
|
||||
fulltitle=scrapedtitle,
|
||||
show=scrapedtitle,
|
||||
title=title + " - " + episode[0] + " " + support.typo("Sub-ITA", '_ [] color kod'),
|
||||
url=scrapedurl,
|
||||
thumbnail=scrapedthumbnail,
|
||||
contentSerieName=title,
|
||||
contentLanguage='Sub-ITA',
|
||||
plot=scrapedplot,
|
||||
infoLabels=infoLabels))
|
||||
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
# Paginazione
|
||||
patron = r'<strong class="on">\d+</strong>\s?<a href="([^<]+)">\d+</a>'
|
||||
support.nextPage(itemlist, item, data, patron)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def newest(categoria):
|
||||
info(categoria)
|
||||
itemlist = []
|
||||
item = Item()
|
||||
item.url = host
|
||||
item.extra = 'serie'
|
||||
try:
|
||||
if categoria == "series":
|
||||
itemlist = peliculas_tv(item)
|
||||
if itemlist[-1].action == 'peliculas_tv':
|
||||
itemlist.pop(-1)
|
||||
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def search(item, texto):
|
||||
info(texto)
|
||||
itemlist = []
|
||||
try:
|
||||
patron = r'<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron=patron, headers=headers).matches
|
||||
for i, (scrapedurl, scrapedtitle) in enumerate(matches):
|
||||
if texto.upper() in scrapedtitle.upper():
|
||||
scrapedthumbnail = ""
|
||||
scrapedplot = ""
|
||||
title = cleantitle(scrapedtitle)
|
||||
itemlist.append(
|
||||
item.clone(action="episodios",
|
||||
title=title,
|
||||
url=scrapedurl,
|
||||
thumbnail=scrapedthumbnail,
|
||||
fulltitle=title,
|
||||
show=title,
|
||||
plot=scrapedplot,
|
||||
contentType='episode',
|
||||
originalUrl=scrapedurl))
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.info('search log:', line)
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_az(item):
|
||||
info()
|
||||
itemlist = []
|
||||
|
||||
alphabet = dict()
|
||||
patron = r'<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron=patron, headers=headers).matches
|
||||
for i, (scrapedurl, scrapedtitle) in enumerate(matches):
|
||||
letter = scrapedtitle[0].upper()
|
||||
if letter not in alphabet:
|
||||
alphabet[letter] = []
|
||||
alphabet[letter].append(scrapedurl + '||' + scrapedtitle)
|
||||
|
||||
for letter in sorted(alphabet):
|
||||
itemlist.append(
|
||||
item.clone(action="lista_serie",
|
||||
data='\n\n'.join(alphabet[letter]),
|
||||
title=letter,
|
||||
fulltitle=letter,
|
||||
args=''))
|
||||
|
||||
return itemlist
|
||||
|
||||
# ================================================================================================================
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "streamingaltadefinizione",
|
||||
"name": "Popcorn Stream",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "popcornstream.png",
|
||||
"banner": "popcornstream.png",
|
||||
"categories": ["movie","tvshow","anime"],
|
||||
"not_active":["include_in_newest_peliculas", "include_in_newest_series", "include_in_newest_anime"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per Popcorn Stream
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support, httptools
|
||||
from core.item import Item
|
||||
from platformcode import config
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
from urllib.parse import unquote
|
||||
else:
|
||||
from urllib import unquote
|
||||
|
||||
|
||||
def findhost(url):
|
||||
data = httptools.downloadpage(url).data
|
||||
return support.scrapertools.find_single_match(data, '<a href="([^"]+)')
|
||||
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
film = ["/film/"]
|
||||
anime = ["/genere/anime/"]
|
||||
tvshow = ["/serietv/"]
|
||||
top = [('Generi',['', 'genre'])]
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.info("[streamingaltadefinizione.py] " + item.url + " search " + text)
|
||||
item.url = item.url + "/?s=" + text
|
||||
try:
|
||||
return support.dooplay_search(item)
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.logger.error("%s" % line)
|
||||
return []
|
||||
|
||||
|
||||
@support.scrape
|
||||
def genre(item):
|
||||
patronMenu = '<a href="(?P<url>[^"#]+)">(?P<title>[a-zA-Z]+)'
|
||||
patronBlock='<a href="#">Genere</a><ul class="sub-menu">(?P<block>.*?)</ul>'
|
||||
action='peliculas'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
return support.dooplay_peliculas(item, True if "/genere/" in item.url else False)
|
||||
|
||||
|
||||
def episodios(item):
|
||||
return support.dooplay_get_episodes(item)
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = []
|
||||
matches = support.match(item, patron=r'<a href="([^"]+)[^>]+>Download[^>]+>[^>]+>[^>]+><strong class="quality">([^<]+)<').matches
|
||||
for url, quality in matches:
|
||||
itemlist.append(
|
||||
item.clone(caction="play",
|
||||
url=unquote(support.match(url, patron=[r'dest=([^"]+)"',r'/(http[^"]+)">Click']).match),
|
||||
quality=quality))
|
||||
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -113,9 +113,8 @@ def newest(category):
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
# getHeaders()
|
||||
logger.debug()
|
||||
|
||||
if item.mainThumb: item.thumbnail = item.mainThumb
|
||||
global host
|
||||
itemlist = []
|
||||
items = []
|
||||
@@ -159,17 +158,19 @@ def peliculas(item):
|
||||
|
||||
itemlist.sort(key=lambda item: item.n)
|
||||
if not item.newest:
|
||||
item.mainThumb = item.thumbnail
|
||||
if recordlist:
|
||||
itemlist.append(item.clone(title=support.typo(support.config.get_localized_string(30992), 'color kod bold'), thumbnail=support.thumb(), page=page, records=recordlist))
|
||||
elif len(itemlist) >= 20:
|
||||
itemlist.append(item.clone(title=support.typo(support.config.get_localized_string(30992), 'color kod bold'), thumbnail=support.thumb(), records=[], page=page + 1))
|
||||
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
support.check_trakt(itemlist)
|
||||
return itemlist
|
||||
|
||||
def makeItem(n, it, item):
|
||||
info = session.post(host + '/api/titles/preview/{}'.format(it['id']), headers=headers).json()
|
||||
logger.debug(jsontools.dump(it))
|
||||
title = info['name']
|
||||
lang = 'Sub-ITA' if 'sub-ita' in title.lower() else 'ITA'
|
||||
title = support.cleantitle(re.sub('\[|\]|[Ss][Uu][Bb]-[Ii][Tt][Aa]', '', title))
|
||||
@@ -203,7 +204,7 @@ def episodios(item):
|
||||
js = json.loads(support.match(item.url, patron=r'seasons="([^"]+)').match.replace('"','"'))
|
||||
|
||||
for episodes in js:
|
||||
logger.debug(jsontools.dump(js))
|
||||
# logger.debug(jsontools.dump(js))
|
||||
for it in episodes['episodes']:
|
||||
|
||||
itemlist.append(
|
||||
@@ -225,16 +226,12 @@ def episodios(item):
|
||||
|
||||
if config.get_setting('episode_info') and not support.stackCheck(['add_tvshow', 'get_newest']):
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
support.check_trakt(itemlist)
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
return itemlist
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = [item.clone(title = channeltools.get_channel_parameters(item.channel)['title'], server='directo')]
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = [item.clone(title = channeltools.get_channel_parameters(item.channel)['title'], server='directo')]
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -246,8 +243,12 @@ def play(item):
|
||||
|
||||
data = support.httptools.downloadpage(item.url + item.episodeid, headers=headers).data.replace('"','"').replace('\\','')
|
||||
scws_id = support.match(data, patron=r'scws_id"\s*:\s*(\d+)').match
|
||||
# support.dbg()
|
||||
|
||||
if not scws_id:
|
||||
if '<strong>Prossimamente' in data:
|
||||
platformtools.dialog_ok('StreamingCommunity', 'Il sito notifica che il contenuto sarà disponibile prossimamente')
|
||||
platformtools.play_canceled = True
|
||||
return []
|
||||
|
||||
# Calculate Token
|
||||
@@ -255,6 +256,21 @@ def play(item):
|
||||
expires = int(time() + 172800)
|
||||
token = b64encode(md5('{}{} Yc8U6r8KjAKAepEA'.format(expires, client_ip).encode('utf-8')).digest()).decode('utf-8').replace('=', '').replace('+', '-').replace('/', '_')
|
||||
|
||||
url = 'https://scws.xyz/master/{}?token={}&expires={}&n=1|User-Agent={}&Referer={}'.format(scws_id, token, expires, httptools.get_user_agent(), host)
|
||||
url = 'https://scws.xyz/master/{}?token={}&expires={}&n=1'.format(scws_id, token, expires)
|
||||
subs = []
|
||||
urls = []
|
||||
|
||||
return [item.clone(title = channeltools.get_channel_parameters(item.channel)['title'], server='directo', url=url, manifest='hls')]
|
||||
info = support.match(url, patron=r'LANGUAGE="([^"]+)",\s*URI="([^"]+)|RESOLUTION=\d+x(\d+).*?(http[^"\s]+)').matches
|
||||
if info:
|
||||
for lang, sub, res, url in info:
|
||||
if sub:
|
||||
if lang == 'auto': lang = 'ita-forced'
|
||||
s = config.get_temp_file(lang +'.srt')
|
||||
subs.append(s)
|
||||
filetools.write(s, support.vttToSrt(httptools.downloadpage(support.match(sub, patron=r'(http[^\s\n]+)').match).data))
|
||||
elif url:
|
||||
urls.append(['hls [{}]'.format(res), url])
|
||||
|
||||
return [item.clone(title = channeltools.get_channel_parameters(item.channel)['title'], server='directo', video_urls=urls, subtitle=subs, manifest='hls')]
|
||||
else:
|
||||
return [item.clone(title = channeltools.get_channel_parameters(item.channel)['title'], server='directo', url=url, manifest='hls')]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Canale per streamingITA
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support, httptools
|
||||
from core import httptools, support
|
||||
from platformcode import logger, config
|
||||
|
||||
host = config.get_channel_url()
|
||||
@@ -34,7 +34,8 @@ def search(item, text):
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
return support.dooplay_peliculas(item, False)
|
||||
mixed = True if item.contentType == 'undefined' else False
|
||||
return support.dooplay_peliculas(item, mixed)
|
||||
|
||||
|
||||
def episodios(item):
|
||||
@@ -53,7 +54,7 @@ def findvideos(item):
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
action = 'peliculas'
|
||||
# debug = True
|
||||
item.contentType = 'undefined'
|
||||
if item.args in ['genres', 'releases']:
|
||||
patronBlock = r'<nav class="' + item.args + r'">(?P<block>.*?)</nav'
|
||||
patronMenu= r'<a href="(?P<url>[^"]+)"[^>]*>(?P<title>[^<]+)<'
|
||||
|
||||
@@ -54,7 +54,7 @@ def search(item, texto):
|
||||
|
||||
item.url = host + "/?s=" + texto
|
||||
try:
|
||||
item.contentType = 'undefined'
|
||||
item.args = 'search'
|
||||
return peliculas(item)
|
||||
|
||||
# Continua la ricerca in caso di errore
|
||||
@@ -78,11 +78,11 @@ def newest(categoria):
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
if item.contentType == 'undefined':
|
||||
action = 'check'
|
||||
action = 'check'
|
||||
item.contentType = 'undefined'
|
||||
if item.args == 'search':
|
||||
patron = r'<a href="(?P<url>[^"]+)" title="Permalink to\s*(?P<title>[^"]+) \((?P<year>[0-9]+)[^<]*\)[^"]*"[^>]+>\s*<img[^s]+src="(?P<thumb>[^"]+)".*?<div class="calitate">\s*<p>(?P<quality>[^<]+)<\/p>'
|
||||
else:
|
||||
action = 'findvideos' if item.contentType == 'movie' else 'episodios'
|
||||
patronNext = r'<a class="nextpostslink" rel="next" href="([^"]+)">'
|
||||
patron = r'<div class="mediaWrap mediaWrapAlt">\s*<a href="(?P<url>[^"]+)"(?:[^>]+)?>?\s*(?:<img[^s]+src="(?P<thumb>[^"]+)"[^>]+>\s*)?<\/a>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+?)(?P<lang>[sS][uU][bB]\-[iI][tT][aA]+)?(?:[ ]?\((?P<year>\d{4})-?(?:\d{4})?)\).[^<]+[^>]+><\/a>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*(?P<quality>[a-zA-Z-0-9\.]+)?'
|
||||
patronBlock = r'<div id="main_col">(?P<block>.*?)<!\-\- main_col \-\->'
|
||||
@@ -124,6 +124,7 @@ def episodios(item):
|
||||
if res.result():
|
||||
data += res.result()
|
||||
patron = r'(?P<season>\d+)x(?P<episode>\d+)\s*-\s*(?P<title>[^\|]+)\|(?P<url>[^ ]+)'
|
||||
# debug = True
|
||||
action = 'findvideos'
|
||||
|
||||
def itemlistHook(itemlist):
|
||||
@@ -139,14 +140,14 @@ def check(item):
|
||||
if 'sub' in check.lower():
|
||||
item.contentLanguage = 'Sub-ITA'
|
||||
logger.debug("CHECK : ", check)
|
||||
if 'anime' in check.lower():
|
||||
item.contentType = 'tvshow'
|
||||
logger.debug('select = ### è una anime ###')
|
||||
try:
|
||||
return episodios(item)
|
||||
except:
|
||||
pass
|
||||
elif 'serie' in check.lower():
|
||||
# if 'anime' in check.lower():
|
||||
# item.contentType = 'tvshow'
|
||||
# logger.debug('select = ### è una anime ###')
|
||||
# try:
|
||||
# return episodios(item)
|
||||
# except:
|
||||
# pass
|
||||
if 'serie' in check.lower():
|
||||
item.contentType = 'tvshow'
|
||||
return episodios(item)
|
||||
else:
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"id": "tapmovie",
|
||||
"name": "Tap Movie",
|
||||
"language": ["ita", "sub-ita"],
|
||||
"active": false,
|
||||
"thumbnail": "tapmovie.png",
|
||||
"banner": "tapmovie.png",
|
||||
"categories": ["movie", "tvshow", "anime"],
|
||||
"not_active": ["include_in_newest"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per 'dvdita'
|
||||
|
||||
from core import support, httptools
|
||||
from core.item import Item
|
||||
import sys
|
||||
if sys.version_info[0] >= 3: from concurrent import futures
|
||||
else: from concurrent_py2 import futures
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
api_url = '/api/v2/'
|
||||
per_page = 24
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
film = ['/browse/movie']
|
||||
tvshow = ['/browse/tvshow']
|
||||
search = ''
|
||||
|
||||
# [Voce Menu,['url','action','args',contentType]
|
||||
top = [('Generi', ['', 'genres', '', 'undefined'])]
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def episodios(item):
|
||||
support.info(item)
|
||||
itemlist = []
|
||||
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
thL = []
|
||||
for season in httptools.downloadpage(host + api_url + 'tvshow', post={'tvshow_id': item.id}).json.get('season', []):
|
||||
season_id = season['season_number']
|
||||
thL.append(executor.submit(httptools.downloadpage, host + api_url + 'episodes', post={'tvshow_id': item.id, 'season_id': season_id}))
|
||||
for th in futures.as_completed(thL):
|
||||
for episode in th.result().json.get('episodes', []):
|
||||
itemlist.append(item.clone(action="findvideos", contentSeason=episode['season_id'], contentEpisodeNumber=episode['episode_number'], id=item.id,
|
||||
title=episode['season_id']+'x'+episode['episode_number'], contentType='episode'))
|
||||
support.scraper.sort_episode_list(itemlist)
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def genres(item):
|
||||
itemlist = []
|
||||
for n, genre in enumerate(httptools.downloadpage(host + api_url + 'categories', post={}).json.get('categories', [])):
|
||||
itemlist.append(item.clone(action="peliculas", genre=genre.get('name'), title=genre.get('value'), n=n))
|
||||
return support.thumb(itemlist, genre=True)
|
||||
|
||||
|
||||
def peliculas(item, text=''):
|
||||
support.info('search', item)
|
||||
itemlist = []
|
||||
filter_type = False
|
||||
if item.genre:
|
||||
text = item.genre
|
||||
cmd = 'search/category'
|
||||
else:
|
||||
cmd = 'search'
|
||||
if not text:
|
||||
filter_type = True
|
||||
|
||||
try:
|
||||
page = int(item.url.split('?p=')[1])
|
||||
except:
|
||||
page = 1
|
||||
results = httptools.downloadpage(host + api_url + cmd, post={'search': text, 'page': page}).json.get('results', [])
|
||||
for result in results:
|
||||
contentType = 'movie' if result['type'] == 'FILM' else 'tvshow'
|
||||
if not filter_type or (filter_type and contentType == item.contentType):
|
||||
itemlist.append(item.clone(id=result.get('id'), title=result.get('title'), contentTitle=result.get('title'),
|
||||
contentSerieName='' if contentType == 'movie' else result.get('title'),
|
||||
contentPlot=result.get('description'), thumbnail=result.get('poster'),
|
||||
fanart=result.get('backdrop'), year=result.get('year'), action='episodios' if contentType == 'tvshow' else 'findvideos',
|
||||
url='{}/{}/{}-{}'.format('https://filmigratis.org', contentType, result.get('id'), support.scrapertools.slugify(result.get('title'))),
|
||||
contentType=contentType))
|
||||
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
if len(results) >= per_page:
|
||||
page += 1
|
||||
support.nextPage(itemlist, item, next_page='https://filmigratis.org/category/' + str(item.n) + '/' + item.genre + '?p=' + str(page))
|
||||
return itemlist
|
||||
|
||||
|
||||
def search(item, text):
|
||||
return peliculas(item, text)
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = []
|
||||
if not item.contentSeason: # film
|
||||
json = httptools.downloadpage(host + api_url + 'movie', post={'movie_id': item.id}).json
|
||||
else:
|
||||
json = httptools.downloadpage(host + api_url + 'episode/links', post={'tvshow_id': item.id, 'season_id': item.contentSeason, 'episode_id': item.contentEpisodeNumber}).json
|
||||
|
||||
for i in json.get('links', []) + json.get('special', []):
|
||||
itemlist.append(Item(url=i.get('link')))
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"id": "vedohd",
|
||||
"name": "VedoHD",
|
||||
"language": ["ita"],
|
||||
"active": false,
|
||||
"thumbnail": "vedohd.png",
|
||||
"banner": "vedohd.png",
|
||||
"categories": ["movie"],
|
||||
"settings": []
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per vedohd
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import scrapertools, support, autoplay
|
||||
from platformcode import logger, config
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = ""
|
||||
|
||||
IDIOMAS = {'Italiano': 'IT'}
|
||||
list_language = IDIOMAS.values()
|
||||
|
||||
|
||||
|
||||
#esclusione degli articoli 'di servizio'
|
||||
blacklist = ['CB01.UNO ▶ TROVA L’INDIRIZZO UFFICIALE ', 'AVVISO IMPORTANTE – CB01.UNO', 'GUIDA VEDOHD']
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
film = [
|
||||
('I più votati', ["ratings/?get=movies", 'peliculas']),
|
||||
('I più popolari', ["trending/?get=movies", 'peliculas']),
|
||||
('Generi', ['ratings/?get=movies', 'menu', 'genres']),
|
||||
('Anno', ["", 'menu', 'releases']),
|
||||
]
|
||||
return locals()
|
||||
|
||||
|
||||
def search(item, text):
|
||||
logger.info("search",text)
|
||||
item.url = item.url + "/?s=" + text
|
||||
|
||||
return support.dooplay_search(item, blacklist)
|
||||
|
||||
|
||||
def peliculas(item):
|
||||
return support.dooplay_peliculas(item, False, blacklist)
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
itemlist = []
|
||||
for link in support.dooplay_get_links(item, host):
|
||||
if link['title'] != 'Trailer':
|
||||
server, quality = scrapertools.find_single_match(link['title'], '([^ ]+) ?(HD|3D)?')
|
||||
if quality:
|
||||
title = server + " [COLOR blue][" + quality + "][/COLOR]"
|
||||
else:
|
||||
title = server
|
||||
itemlist.append(item.clone(action="play", title=title, url=link['url'], server=server, quality=quality,))
|
||||
|
||||
autoplay.start(itemlist, item)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def menu(item):
|
||||
return support.dooplay_menu(item, item.args)
|
||||
|
||||
|
||||
def play(item):
|
||||
logger.debug()
|
||||
|
||||
data = support.swzz_get_url(item)
|
||||
|
||||
return support.server(item, data, headers=headers)
|
||||
@@ -90,6 +90,7 @@ def search(item, text):
|
||||
def newest(categoria):
|
||||
item = support.Item()
|
||||
item.args = 'channel/10007/last/'
|
||||
item.newest = True
|
||||
if categoria == 'peliculas':
|
||||
item.contentType = 'movie'
|
||||
item.url = main_host + 'film/'
|
||||
@@ -133,24 +134,25 @@ def peliculas(item):
|
||||
make_itemlist(itemlist, item, json_file)
|
||||
|
||||
itlist = []
|
||||
for i, it in enumerate(itemlist):
|
||||
if pagination and (item.page - 1) * pagination > i: continue # pagination
|
||||
if pagination and i >= item.page * pagination: break # pagination
|
||||
if not item.newest:
|
||||
for i, it in enumerate(itemlist):
|
||||
if pagination and (item.page - 1) * pagination > i: continue # pagination
|
||||
if pagination and i >= item.page * pagination: break # pagination
|
||||
|
||||
itlist.append(it)
|
||||
itlist.append(it)
|
||||
|
||||
if pagination and len(itemlist) >= pagination:
|
||||
if inspect.stack()[1][3] != 'get_newest':
|
||||
itlist.append(
|
||||
item.clone(action='peliculas',
|
||||
title=support.typo(config.get_localized_string(30992), 'color kod bold'),
|
||||
fulltitle=item.fulltitle,
|
||||
show=item.show,
|
||||
url=item.url,
|
||||
args=item.args,
|
||||
page=item.page + 1,
|
||||
thumbnail=support.thumb()))
|
||||
itemlist = itlist
|
||||
if pagination and len(itemlist) >= pagination:
|
||||
if inspect.stack()[1][3] != 'get_newest':
|
||||
itlist.append(
|
||||
item.clone(action='peliculas',
|
||||
title=support.typo(config.get_localized_string(30992), 'color kod bold'),
|
||||
fulltitle=item.fulltitle,
|
||||
show=item.show,
|
||||
url=item.url,
|
||||
args=item.args,
|
||||
page=item.page + 1,
|
||||
thumbnail=support.thumb()))
|
||||
itemlist = itlist
|
||||
|
||||
if 'category' in item.args:
|
||||
support.thumb(itemlist,genre=True)
|
||||
|
||||
@@ -29,6 +29,8 @@ def start(itemlist, item):
|
||||
|
||||
if item.global_search or item.from_action or item.contentAction: # from_action means that's a special function calling this (ex: add to videolibrary)
|
||||
return itemlist
|
||||
if len([s for s in itemlist if s.server]) == 1:
|
||||
return itemlist
|
||||
logger.debug()
|
||||
|
||||
global PLAYED
|
||||
|
||||
@@ -355,7 +355,7 @@ class Item(object):
|
||||
dump = "".encode("utf8")
|
||||
return str(urllib.quote(base64.b64encode(dump)))
|
||||
|
||||
def fromurl(self, url):
|
||||
def fromurl(self, url, silent=False):
|
||||
"""
|
||||
Generate an item from a text string. The string can be created by the tourl () function or have
|
||||
the old format: plugin: //plugin.video.kod/? channel = ... (+ other parameters)
|
||||
@@ -369,7 +369,7 @@ class Item(object):
|
||||
decoded = False
|
||||
try:
|
||||
str_item = base64.b64decode(urllib.unquote(url))
|
||||
json_item = json.load(str_item, object_hook=self.toutf8)
|
||||
json_item = json.load(str_item, object_hook=self.toutf8, silent=silent)
|
||||
if json_item is not None and len(json_item) > 0:
|
||||
self.__dict__.update(json_item)
|
||||
decoded = True
|
||||
|
||||
@@ -16,15 +16,22 @@ if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||||
|
||||
|
||||
def load(*args, **kwargs):
|
||||
silent = False
|
||||
if 'silent' in kwargs:
|
||||
silent = kwargs['silent']
|
||||
kwargs.pop('silent')
|
||||
|
||||
if "object_hook" not in kwargs:
|
||||
kwargs["object_hook"] = to_utf8
|
||||
|
||||
try:
|
||||
value = json.loads(*args, **kwargs)
|
||||
except:
|
||||
logger.error("**NOT** able to load the JSON")
|
||||
logger.error(traceback.format_exc())
|
||||
logger.error('ERROR STACK ' + str(stack()[1][3]))
|
||||
if not silent:
|
||||
logger.error("**NOT** able to load the JSON")
|
||||
logger.error(traceback.format_exc())
|
||||
if len(stack()) > 1:
|
||||
logger.error('ERROR STACK {}'.format(stack()[2]) )
|
||||
value = {}
|
||||
|
||||
return value
|
||||
|
||||
@@ -504,3 +504,49 @@ def title_unify(title):
|
||||
u_title = spl[0] if len(spl[0]) > 5 else spl[1]
|
||||
|
||||
return u_title.strip()
|
||||
|
||||
|
||||
def girc(page_data, url, co):
|
||||
"""
|
||||
Code adapted from https://github.com/vb6rocod/utils/
|
||||
Copyright (C) 2019 vb6rocod
|
||||
and https://github.com/addon-lab/addon-lab_resolver_Project
|
||||
Copyright (C) 2021 ADDON-LAB, KAR10S
|
||||
"""
|
||||
import re
|
||||
from core import httptools
|
||||
hdrs = {'Referer': url}
|
||||
rurl = 'https://www.google.com/recaptcha/api.js'
|
||||
aurl = 'https://www.google.com/recaptcha/api2'
|
||||
key = re.search(r'(?:src="{0}\?.*?render|data-sitekey)="?([^"]+)'.format(rurl), page_data)
|
||||
if key:
|
||||
key = key.group(1)
|
||||
rurl = '{0}?render={1}'.format(rurl, key)
|
||||
page_data1 = httptools.downloadpage(rurl, headers=hdrs).data
|
||||
v = re.findall('releases/([^/]+)', page_data1)[0]
|
||||
rdata = {'ar': 1,
|
||||
'k': key,
|
||||
'co': co,
|
||||
'hl': 'en',
|
||||
'v': v,
|
||||
'size': 'invisible',
|
||||
'cb': '123456789'}
|
||||
page_data2 = httptools.downloadpage('{0}/anchor?{1}'.format(aurl, httptools.urlparse.urlencode(rdata)), headers=hdrs).data
|
||||
rtoken = re.search('recaptcha-token.+?="([^"]+)', page_data2)
|
||||
if rtoken:
|
||||
rtoken = rtoken.group(1)
|
||||
else:
|
||||
return ''
|
||||
pdata = {'v': v,
|
||||
'reason': 'q',
|
||||
'k': key,
|
||||
'c': rtoken,
|
||||
'sa': '',
|
||||
'co': co}
|
||||
hdrs.update({'Referer': aurl})
|
||||
page_data3 = httptools.downloadpage('{0}/reload?k={1}'.format(aurl, key), post=pdata, headers=hdrs).data
|
||||
gtoken = re.search('rresp","([^"]+)', page_data3)
|
||||
if gtoken:
|
||||
return gtoken.group(1)
|
||||
|
||||
return ''
|
||||
|
||||
@@ -254,7 +254,7 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
|
||||
if isinstance(video_password, list):
|
||||
return video_password, len(video_password) > 0, "<br/>".join(error_messages)
|
||||
logger.info("Server: %s, url is good" % server)
|
||||
video_urls.append(["%s [%s]" % (urlparse.urlparse(url)[2][-4:], config.get_localized_string(30137)), url])
|
||||
video_urls.append(["%s [%s]" % (urlparse.urlparse(url)[2].split('|')[0][-4:], config.get_localized_string(30137)), url])
|
||||
|
||||
# Find out the video URL
|
||||
else:
|
||||
|
||||
@@ -604,11 +604,11 @@ def scrape(func):
|
||||
if function == 'episodios': autorenumber.start(itemlist, item)
|
||||
else: autorenumber.start(itemlist)
|
||||
|
||||
if action != 'play' and 'patronMenu' not in args and not disabletmdb and function != 'episodios' \
|
||||
and item.contentType in ['movie', 'tvshow', 'episode', 'undefined']:
|
||||
if action != 'play' and 'patronMenu' not in args and 'patronGenreMenu' not in args \
|
||||
and not stackCheck(['add_tvshow', 'get_newest']) and (function not in ['episodes', 'mainlist'] \
|
||||
or (function in ['episodes'] and config.get_setting('episode_info'))):
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
|
||||
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 len(inspect.stack()) > 2 and inspect.stack()[2][3] not in ['get_channel_results']:
|
||||
nextPage(itemlist, item, data, patronNext, function)
|
||||
@@ -655,9 +655,7 @@ def scrape(func):
|
||||
|
||||
# itemlist = filterLang(item, itemlist) # causa problemi a newest
|
||||
|
||||
if config.get_setting('trakt_sync'):
|
||||
from core import trakt_tools
|
||||
trakt_tools.trakt_check(itemlist)
|
||||
check_trakt(itemlist)
|
||||
return itemlist
|
||||
|
||||
return wrapper
|
||||
@@ -731,6 +729,7 @@ def dooplay_search(item, blacklist=""):
|
||||
|
||||
|
||||
def dooplay_search_vars(item, blacklist):
|
||||
actLike = 'peliculas'
|
||||
if item.contentType == 'undefined': # ricerca globale
|
||||
type = '(?P<type>movies|tvshows)'
|
||||
typeActionDict = {'findvideos': ['movies'], 'episodios': ['tvshows']}
|
||||
@@ -1280,26 +1279,23 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
|
||||
videoitem.server = videoitem.server.lower()
|
||||
|
||||
if videoitem.video_urls or srv_param.get('active', False):
|
||||
title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' or (config.get_localized_string(30161) in item.title) else item.title
|
||||
vi = item.clone(server=videoitem.server,
|
||||
extraInfo=videoitem.extraInfo,
|
||||
serverName=videoitem.serverName,
|
||||
url=videoitem.url,
|
||||
videoUrls= videoitem.videoUrlsn,
|
||||
ch_name=channeltools.get_channel_parameters(item.channel)['title'],
|
||||
action = "play")
|
||||
|
||||
quality = videoitem.quality if videoitem.quality else item.quality if item.quality else ''
|
||||
videoitem.title = (title if item.channel not in ['url'] else '')\
|
||||
+ (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "")\
|
||||
+ (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")\
|
||||
+ (typo(videoitem.contentLanguage, '_ color kod []') if videoitem.contentLanguage else "")\
|
||||
+ (typo(videoitem.extraInfo, '_ color kod []') if videoitem.extraInfo else "")
|
||||
videoitem.plot = typo(videoitem.title, 'bold') + (typo(quality, '_ [] bold') if quality else '')
|
||||
videoitem.channel = item.channel
|
||||
videoitem.fulltitle = item.fulltitle
|
||||
videoitem.show = item.show
|
||||
if not videoitem.video_urls: videoitem.thumbnail = item.thumbnail
|
||||
videoitem.contentType = item.contentType
|
||||
videoitem.infoLabels = item.infoLabels
|
||||
videoitem.quality = quality
|
||||
videoitem.referer = item.referer if item.referer else item.url
|
||||
videoitem.action = "play"
|
||||
# videoitem.nfo = item.nfo
|
||||
# videoitem.strm_path = item.strm_path
|
||||
if videoitem.title: vi.serverName = videoitem.title
|
||||
if videoitem.quality: vi.quality = videoitem.quality
|
||||
if not vi.referer: vi.referer = item.url
|
||||
vi.contentFanart = item.infoLabels['fanart']
|
||||
vi.contentThumb = item.infoLabels['fanart']
|
||||
if videoitem.forcethumb:
|
||||
vi.thumbnail = videoitem.thumbnail
|
||||
vi.forcethumb = True
|
||||
videoitem = vi
|
||||
return videoitem
|
||||
|
||||
# non threaded for webpdb
|
||||
@@ -1409,7 +1405,7 @@ def addQualityTag(item, itemlist, data, patron):
|
||||
"DTS": "audio ricavato dai dischi DTS2, quindi la qualità audio è elevata.",
|
||||
"LD": "l’audio è stato registrato tramite jack collegato alla macchina da presa, pertanto di discreta qualità.",
|
||||
"DD": "audio ricavato dai dischi DTS cinema. L’audio è di buona qualità, ma potreste riscontrare il fatto che non potrebbe essere più riproducibile.",
|
||||
"AC3": "audio in Dolby Digital puo' variare da 2.0 a 5.1 canali in alta qualità.",
|
||||
"AC3": "audio in Dolby Digital può variare da 2.0 a 5.1 canali in alta qualità.",
|
||||
"MP3": "codec per compressione audio utilizzato MP3.",
|
||||
"RESYNC": "il film è stato lavorato e re sincronizzato con una traccia audio. A volte potresti riscontrare una mancata sincronizzazione tra audio e video.",
|
||||
}
|
||||
@@ -1436,7 +1432,7 @@ def addQualityTag(item, itemlist, data, patron):
|
||||
descr = ''
|
||||
itemlist.insert(0,Item(channel=item.channel,
|
||||
action="",
|
||||
title=typo(qualityStr, '[] color kod bold'),
|
||||
title=typo(qualityStr, 'bold'),
|
||||
fulltitle=qualityStr,
|
||||
plot=descr,
|
||||
folder=False,
|
||||
@@ -1600,3 +1596,45 @@ def thumb(item_itemlist_string=None, genre=False, live=False):
|
||||
|
||||
else:
|
||||
return get_thumb('next.png')
|
||||
|
||||
|
||||
def vttToSrt(data):
|
||||
# Code adapted by VTT_TO_SRT.PY (c) Jansen A. Simanullang
|
||||
ret = ''
|
||||
|
||||
data = re.sub(r'(\d\d:\d\d:\d\d).(\d\d\d) --> (\d\d:\d\d:\d\d).(\d\d\d)(?:[ \-\w]+:[\w\%\d:]+)*\n', r'\1,\2 --> \3,\4\n', data)
|
||||
data = re.sub(r'(\d\d:\d\d).(\d\d\d) --> (\d\d:\d\d).(\d\d\d)(?:[ \-\w]+:[\w\%\d:]+)*\n', r'00:\1,\2 --> 00:\3,\4\n', data)
|
||||
data = re.sub(r'(\d\d).(\d\d\d) --> (\d\d).(\d\d\d)(?:[ \-\w]+:[\w\%\d:]+)*\n', r'00:00:\1,\2 --> 00:00:\3,\4\n', data)
|
||||
data = re.sub(r'WEBVTT\n', '', data)
|
||||
data = re.sub(r'Kind:[ \-\w]+\n', '', data)
|
||||
data = re.sub(r'Language:[ \-\w]+\n', '', data)
|
||||
data = re.sub(r'<c[.\w\d]*>', '', data)
|
||||
data = re.sub(r'</c>', '', data)
|
||||
data = re.sub(r'<\d\d:\d\d:\d\d.\d\d\d>', '', data)
|
||||
data = re.sub(r'::[\-\w]+\([\-.\w\d]+\)[ ]*{[.,:;\(\) \-\w\d]+\n }\n', '', data)
|
||||
data = re.sub(r'Style:\n##\n', '', data)
|
||||
|
||||
lines = data.split(os.linesep)
|
||||
|
||||
for n, line in enumerate(lines):
|
||||
if re.match(r"((\d\d:){2}\d\d),(\d{3}) --> ((\d\d:){2}\d\d),(\d{3})", line):
|
||||
ret += str(n + 1) + os.linesep + line + os.linesep
|
||||
else:
|
||||
ret += line + os.linesep
|
||||
|
||||
return ret
|
||||
|
||||
def check_trakt(itemlist):
|
||||
if config.get_setting('trakt_sync'):
|
||||
from core import trakt_tools
|
||||
trakt_tools.trakt_check(itemlist)
|
||||
return itemlist
|
||||
|
||||
|
||||
def stackCheck(values):
|
||||
stacks = [s[3] for s in inspect.stack()]
|
||||
logger.debug('STAKS', stacks)
|
||||
if type(values) == str:
|
||||
return values in stacks
|
||||
else:
|
||||
return any(v in values for v in stacks)
|
||||
26
core/tmdb.py
26
core/tmdb.py
@@ -393,18 +393,17 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang):
|
||||
if search_type == 'tv':
|
||||
# Serial search by title and filtering your results if necessary
|
||||
searched_title = scrapertools.unescape(item.infoLabels['tvshowtitle'])
|
||||
# searched_title = searched_title.split('-')[0].strip()
|
||||
otmdb = Tmdb(searched_text=searched_title, search_type=search_type,
|
||||
search_language=search_language, filtro=item.infoLabels.get('filtro', {}),
|
||||
year=item.infoLabels['year'])
|
||||
else:
|
||||
# Movie search by title ...
|
||||
# if item.infoLabels['year'] or item.infoLabels['filtro']:
|
||||
# ...and year or filter
|
||||
searched_title = scrapertools.unescape(item.infoLabels['title'])
|
||||
# searched_title = searched_title.split('-')[0].strip()
|
||||
# from core.support import dbg;dbg()
|
||||
otmdb = Tmdb(searched_text=searched_title, search_type=search_type, search_language=search_language,
|
||||
filtro=item.infoLabels.get('filtro', {}), year=item.infoLabels['year'])
|
||||
if otmdb is not None and not otmdb.get_id():
|
||||
otmdb = Tmdb(searched_text=searched_title, search_type=search_type, search_language=search_language,
|
||||
filtro=item.infoLabels.get('filtro', {}), year=item.infoLabels['year'])
|
||||
filtro=item.infoLabels.get('filtro', {}))
|
||||
if otmdb is not None:
|
||||
if otmdb.get_id() and config.get_setting("tmdb_plus_info", default=False):
|
||||
# If the search has been successful and you are not looking for a list of items,
|
||||
@@ -471,10 +470,9 @@ def find_and_set_infoLabels(item):
|
||||
item.infoLabels['year'] = year[1:-1]
|
||||
|
||||
if not item.infoLabels.get("tmdb_id") or not item.infoLabels.get("tmdb_id")[0].isdigit():
|
||||
if not item.infoLabels.get("imdb_id"):
|
||||
otmdb_global = Tmdb(searched_text=scrapertools.unescape(title), search_type=search_type, year=item.infoLabels['year'])
|
||||
else:
|
||||
otmdb_global = Tmdb(external_id=item.infoLabels.get("imdb_id"), external_source="imdb_id", search_type=search_type)
|
||||
if item.infoLabels.get("imdb_id"): otmdb_global = Tmdb(external_id=item.infoLabels.get("imdb_id"), external_source="imdb_id", search_type=search_type)
|
||||
else: otmdb_global = Tmdb(searched_text=scrapertools.unescape(title), search_type=search_type, year=item.infoLabels['year'])
|
||||
|
||||
elif not otmdb_global or str(otmdb_global.result.get("id")) != item.infoLabels['tmdb_id']:
|
||||
otmdb_global = Tmdb(id_Tmdb=item.infoLabels['tmdb_id'], search_type=search_type, search_language=def_lang)
|
||||
|
||||
@@ -537,10 +535,7 @@ def get_nfo(item, search_groups=False):
|
||||
info_nfo = 'https://www.themoviedb.org/tv/{}/episode_group/{}'.format(item.infoLabels['tmdb_id'], Id)
|
||||
return info_nfo + '\n'
|
||||
else: return
|
||||
# from core.support import dbg;dbg()
|
||||
# if "season" in item.infoLabels and "episode" in item.infoLabels:
|
||||
# info_nfo = "https://www.themoviedb.org/tv/{}/season/{}/episode/{}" .format(item.infoLabels['tmdb_id'], item.contentSeason, item.contentEpisodeNumber)
|
||||
# else:
|
||||
|
||||
info_nfo = ', '.join(item.infoLabels['url_scraper'])
|
||||
|
||||
return info_nfo + '\n'
|
||||
@@ -644,10 +639,11 @@ class ResultDictDefault(dict):
|
||||
|
||||
def __missing__(self, key):
|
||||
"""
|
||||
default values in case the requested key does not exist
|
||||
default values in case the requested key does not exist
|
||||
"""
|
||||
if key in ['genre_ids', 'genre', 'genres']:
|
||||
return list()
|
||||
|
||||
elif key == 'images_posters':
|
||||
posters = dict()
|
||||
if 'images' in list(super(ResultDictDefault, self).keys()) and 'posters' in super(ResultDictDefault, self).__getitem__('images'):
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# -*- Created for Alfa-addon -*-
|
||||
# -*- By the Alfa Develop Group -*
|
||||
|
||||
#from builtins import str
|
||||
|
||||
import os, xbmc
|
||||
from core import httptools, jsontools
|
||||
from core import httptools, jsontools
|
||||
from core.item import Item
|
||||
from platformcode import config, logger
|
||||
from threading import Thread
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] >= 3: from concurrent import futures
|
||||
else: from concurrent_py2 import futures
|
||||
@@ -26,7 +29,7 @@ def auth_trakt():
|
||||
post = {'client_id': client_id}
|
||||
post = jsontools.dump(post)
|
||||
# Se solicita url y código de verificación para conceder permiso a la app
|
||||
url = "http://api.trakt.tv/oauth/device/code"
|
||||
url = "http://api-v2launch.trakt.tv/oauth/device/code"
|
||||
data = httptools.downloadpage(url, post=post, headers=headers).data
|
||||
data = jsontools.load(data)
|
||||
item.verify_url = data["verification_url"]
|
||||
@@ -57,14 +60,13 @@ def token_trakt(item):
|
||||
try:
|
||||
if item.extra == "renew":
|
||||
refresh = config.get_setting("refresh_token_trakt", "trakt")
|
||||
url = "http://api.trakt.tv/oauth/device/token"
|
||||
url = "https://api.trakt.tv/oauth/token"
|
||||
post = {'refresh_token': refresh, 'client_id': client_id, 'client_secret': client_secret,
|
||||
'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', 'grant_type': 'refresh_token'}
|
||||
post = jsontools.dump(post)
|
||||
data = httptools.downloadpage(url, post=post, headers=headers).data
|
||||
data = httptools.downloadpage(url, post=post).data
|
||||
data = jsontools.load(data)
|
||||
elif item.action == "token_trakt":
|
||||
url = "http://api.trakt.tv/oauth/device/token"
|
||||
url = "https://api-v2launch.trakt.tv/oauth/device/token"
|
||||
post = "code=%s&client_id=%s&client_secret=%s" % (item.device_code, client_id, client_secret)
|
||||
data = httptools.downloadpage(url, post=post, headers=headers).data
|
||||
data = jsontools.load(data)
|
||||
@@ -83,7 +85,7 @@ def token_trakt(item):
|
||||
config.set_setting("trakt_sync", False)
|
||||
return
|
||||
|
||||
url = "http://api.trakt.tv/oauth/device/token"
|
||||
url = "http://api-v2launch.trakt.tv/oauth/device/token"
|
||||
post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret}
|
||||
post = jsontools.dump(post)
|
||||
data = httptools.downloadpage(url, post=post, headers=headers).data
|
||||
@@ -106,9 +108,7 @@ def token_trakt(item):
|
||||
config.set_setting("refresh_token_trakt", refresh, "trakt")
|
||||
if not item.folder:
|
||||
platformtools.dialog_notification(config.get_localized_string(60255), config.get_localized_string(60256))
|
||||
if config.is_xbmc():
|
||||
import xbmc
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
return
|
||||
|
||||
except:
|
||||
@@ -166,8 +166,12 @@ def get_trakt_watched(id_type, mediatype, update=False):
|
||||
if token_auth:
|
||||
headers.append(['Authorization', "Bearer %s" % token_auth])
|
||||
url = "https://api.trakt.tv/sync/watched/%s" % mediatype
|
||||
data = httptools.downloadpage(url, headers=headers).data
|
||||
watched_dict = jsontools.load(data)
|
||||
data = httptools.downloadpage(url, headers=headers)
|
||||
if data.code == 401:
|
||||
token_trakt(Item(extra="renew"))
|
||||
return get_trakt_watched(id_type, mediatype, update)
|
||||
|
||||
watched_dict = jsontools.load(data.data)
|
||||
|
||||
if mediatype == 'shows':
|
||||
|
||||
@@ -266,14 +270,12 @@ def ask_install_script():
|
||||
|
||||
def wait_for_update_trakt():
|
||||
logger.debug()
|
||||
t = Thread(target=update_all)
|
||||
t = Thread(update_all)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
t.is_alive()
|
||||
|
||||
|
||||
def update_all():
|
||||
# from core.support import dbg;dbg()
|
||||
from time import sleep
|
||||
logger.debug()
|
||||
sleep(20)
|
||||
@@ -282,4 +284,3 @@ def update_all():
|
||||
for mediatype in ['movies', 'shows']:
|
||||
trakt_data = get_trakt_watched('tmdb', mediatype, True)
|
||||
update_trakt_data(mediatype, trakt_data)
|
||||
|
||||
|
||||
@@ -974,7 +974,7 @@ def add_movie(item):
|
||||
@param item: item to be saved.
|
||||
"""
|
||||
logger.debug()
|
||||
from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||||
# from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||||
item.contentType = 'movie'
|
||||
|
||||
# To disambiguate titles, TMDB is caused to ask for the really desired title
|
||||
@@ -1023,7 +1023,7 @@ def add_tvshow(item, channel=None, itemlist=[]):
|
||||
|
||||
logger.debug("show=#" + item.show + "#")
|
||||
item.contentType = 'tvshow'
|
||||
from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||||
# from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||||
|
||||
if item.channel == "downloads":
|
||||
itemlist = [item.clone()]
|
||||
|
||||
@@ -695,14 +695,13 @@ class UnshortenIt(object):
|
||||
return httptools.downloadpage(uri, only_headers=True, follow_redirects=False).headers.get('location', uri), 200
|
||||
|
||||
def _unshorten_uprot(self, uri):
|
||||
from core.support import dbg
|
||||
dbg()
|
||||
for link in scrapertools.find_multiple_matches(httptools.downloadpage(uri, cloudscraper=True).data, '<a[^>]+href="([^"]+)'):
|
||||
if link.startswith('https://maxstream.video') or link.startswith('https://uprot.net') and link != uri:
|
||||
return link, 200
|
||||
return uri, 200
|
||||
|
||||
|
||||
|
||||
def decrypt_aes(text, key):
|
||||
try:
|
||||
from Cryptodome.Cipher import AES
|
||||
@@ -775,3 +774,25 @@ def findlinks(text):
|
||||
else:
|
||||
text += '\n' + str(link.result()[0])
|
||||
return text
|
||||
|
||||
|
||||
class FileCrypt:
|
||||
def __init__(self, uri=None):
|
||||
self.uri = uri
|
||||
|
||||
def find(self, data):
|
||||
_filecrypt_regex = r'https?://\w+\.filecrypt\.cc/[a-zA-Z0-9_=/]+'
|
||||
return scrapertools.find_multiple_matches(data, _filecrypt_regex)
|
||||
|
||||
def list_files(self):
|
||||
reg = """<td title="([^"]+).*?<button onclick="openLink\('([^']+)"""
|
||||
data = httptools.downloadpage(self.uri).data
|
||||
ret = scrapertools.find_multiple_matches(data, reg)
|
||||
return ret
|
||||
|
||||
def unshorten(self, link):
|
||||
link_data = httptools.downloadpage('https://www.filecrypt.cc/Link/' + link + '.html').data
|
||||
time.sleep(0.1)
|
||||
url = httptools.downloadpage(scrapertools.find_single_match(link_data, "location.href='([^']+)"), headers={'Referer': 'http://www.filecrypt.cc/'}, only_headers=True).url
|
||||
logger.info(url)
|
||||
return url
|
||||
|
||||
@@ -74,16 +74,21 @@ def get_platform(full_version=False):
|
||||
codename = {"10": "dharma", "11": "eden", "12": "frodo",
|
||||
"13": "gotham", "14": "helix", "15": "isengard",
|
||||
"16": "jarvis", "17": "krypton", "18": "leia",
|
||||
"19": "matrix"}
|
||||
code_db = {'10': 'MyVideos37.db', '11': 'MyVideos60.db', '12': 'MyVideos75.db',
|
||||
"19": "matrix", '20': 'nexus'}
|
||||
video_db = {'10': 'MyVideos37.db', '11': 'MyVideos60.db', '12': 'MyVideos75.db',
|
||||
'13': 'MyVideos78.db', '14': 'MyVideos90.db', '15': 'MyVideos93.db',
|
||||
'16': 'MyVideos99.db', '17': 'MyVideos107.db', '18': 'MyVideos116.db',
|
||||
'19': 'MyVideos119.db'}
|
||||
'19': 'MyVideos119.db', '20': 'MyVideos120.db'}
|
||||
view_db = {'10': 'ViewModes1.db', '11': 'ViewModes4.db', '12': 'ViewModes4.db',
|
||||
'13': 'ViewModes6.db', '14': 'ViewModes6.db', '15': 'ViewModes6.db',
|
||||
'16': 'ViewModes6.db', '17': 'ViewModes6.db', '18': 'ViewModes6.db',
|
||||
'19': 'ViewModes6.db', '20': 'ViewModes6.db'}
|
||||
|
||||
num_version = xbmc.getInfoLabel('System.BuildVersion')
|
||||
num_version = re.match("\d+\.\d+", num_version).group(0)
|
||||
ret['name_version'] = codename.get(num_version.split('.')[0], num_version)
|
||||
ret['video_db'] = code_db.get(num_version.split('.')[0], "")
|
||||
ret['video_db'] = video_db.get(num_version.split('.')[0], "")
|
||||
ret['view_db'] = view_db.get(num_version.split('.')[0], "")
|
||||
ret['num_version'] = float(num_version)
|
||||
if ret['num_version'] < 14:
|
||||
ret['platform'] = "xbmc-" + ret['name_version']
|
||||
@@ -443,3 +448,9 @@ def get_online_server_thumb(server):
|
||||
|
||||
def get_language():
|
||||
return get_localized_string(20001)
|
||||
|
||||
def get_skin():
|
||||
import xbmc
|
||||
from core import jsontools
|
||||
js = '{"jsonrpc": "2.0", "method": "Settings.GetSettingValue", "params": {"setting": "lookandfeel.skin"}, "id": 1 }'
|
||||
return jsontools.load(xbmc.executeJSONRPC(js)).get('result', {}).get('value')
|
||||
|
||||
@@ -2,27 +2,20 @@
|
||||
# ------------------------------------------------------------
|
||||
# XBMC Launcher (xbmc / kodi)
|
||||
# ------------------------------------------------------------
|
||||
import datetime
|
||||
import json
|
||||
import sys, os
|
||||
|
||||
import requests
|
||||
|
||||
PY3 = False
|
||||
if sys.version_info[0] >= 3:PY3 = True; unicode = str; unichr = chr; long = int
|
||||
|
||||
import sys
|
||||
from core.item import Item
|
||||
from core import filetools, jsontools
|
||||
from platformcode import config, logger, platformtools, xbmc_videolibrary
|
||||
from core import filetools
|
||||
from platformcode import config, logger, platformtools
|
||||
from platformcode.logger import WebErrorException
|
||||
temp_search_file = config.get_temp_file('temp-search')
|
||||
|
||||
|
||||
def start():
|
||||
""" First function that is executed when entering the plugin.
|
||||
'''
|
||||
First function that is executed when entering the plugin.
|
||||
Within this function all calls should go to
|
||||
functions that we want to execute as soon as we open the plugin.
|
||||
"""
|
||||
'''
|
||||
logger.debug()
|
||||
|
||||
if not config.dev_mode():
|
||||
@@ -31,124 +24,65 @@ def start():
|
||||
changelog = fileC.read()
|
||||
if changelog.strip():
|
||||
platformtools.dialog_ok('Kodi on Demand', 'Aggiornamenti applicati:\n' + changelog)
|
||||
os.remove(config.changelogFile)
|
||||
filetools.remove(config.changelogFile)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def run(item=None):
|
||||
logger.debug()
|
||||
# Extract item from sys.argv
|
||||
if not item: item = makeItem()
|
||||
|
||||
if not item:
|
||||
# Extract item from sys.argv
|
||||
if sys.argv[2]:
|
||||
sp = sys.argv[2].split('&')
|
||||
url = sp[0]
|
||||
item = Item().fromurl(url)
|
||||
if len(sp) > 1:
|
||||
for e in sp[1:]:
|
||||
key, val = e.split('=')
|
||||
item.__setattr__(key, val)
|
||||
# If no item, this is mainlist
|
||||
else:
|
||||
item = Item(channel="channelselector", action="getmainlist", viewmode="movie")
|
||||
if not config.get_setting('show_once'):
|
||||
if not config.get_all_settings_addon():
|
||||
logger.error('corrupted settings.xml!!')
|
||||
settings_xml = os.path.join(config.get_data_path(), "settings.xml")
|
||||
settings_bak = os.path.join(config.get_data_path(), "settings.bak")
|
||||
if filetools.exists(settings_bak):
|
||||
filetools.copy(settings_bak, settings_xml, True)
|
||||
logger.info('restored settings.xml from backup')
|
||||
else:
|
||||
filetools.write(settings_xml, '<settings version="2">\n</settings>') # resetted settings
|
||||
else:
|
||||
from platformcode import xbmc_videolibrary
|
||||
xbmc_videolibrary.ask_set_content(silent=False)
|
||||
config.set_setting('show_once', True)
|
||||
# Load or Repare Settings
|
||||
if not config.get_setting('show_once'): showOnce()
|
||||
|
||||
logger.info(item.tostring())
|
||||
|
||||
reload = False
|
||||
from core import db
|
||||
if db['OnPlay'].get('addon', False):
|
||||
reload = True
|
||||
db['OnPlay']['addon'] = False
|
||||
db.close()
|
||||
# Acrions
|
||||
logger.debug(item.tostring())
|
||||
|
||||
try:
|
||||
# Active tmdb
|
||||
if not config.get_setting('tmdb_active'):
|
||||
config.set_setting('tmdb_active', True)
|
||||
|
||||
# If item has no action, stops here
|
||||
if item.action == "":
|
||||
logger.debug("Item without action")
|
||||
if item.action == '':
|
||||
logger.debug('Item without action')
|
||||
return
|
||||
|
||||
# Action for main menu in channelselector
|
||||
elif item.action == "getmainlist":
|
||||
# Channel Selector
|
||||
if item.channel == 'channelselector':
|
||||
itemlist = []
|
||||
import channelselector
|
||||
|
||||
itemlist = channelselector.getmainlist()
|
||||
|
||||
if item.action == 'getmainlist': # Action for main menu in channelselector
|
||||
itemlist = channelselector.getmainlist()
|
||||
elif item.action == 'getchanneltypes': # Action for channel types on channelselector: movies, series, etc.
|
||||
itemlist = channelselector.getchanneltypes()
|
||||
elif item.action == 'filterchannels': # Action for channel listing on channelselector
|
||||
itemlist = channelselector.filterchannels(item.channel_type)
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
# Action for channel types on channelselector: movies, series, etc.
|
||||
elif item.action == "getchanneltypes":
|
||||
import channelselector
|
||||
itemlist = channelselector.getchanneltypes()
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
# Action for channel listing on channelselector
|
||||
elif item.action == "filterchannels":
|
||||
import channelselector
|
||||
itemlist = channelselector.filterchannels(item.channel_type)
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
# Special action for playing a video from the library
|
||||
elif item.action == "play_from_library":
|
||||
play_from_library(item)
|
||||
return
|
||||
elif item.action == 'play_from_library':
|
||||
return playFromLibrary(item)
|
||||
|
||||
elif item.action == "keymap":
|
||||
from platformcode import keymaptools
|
||||
if item.open:
|
||||
return keymaptools.open_shortcut_menu()
|
||||
else:
|
||||
return keymaptools.set_key()
|
||||
# Special play action
|
||||
elif item.action == 'play': play(item)
|
||||
|
||||
elif item.channel == "infoplus":
|
||||
from platformcode import infoplus
|
||||
return infoplus.Main(item)
|
||||
# Special findvideos Action
|
||||
elif item.action == 'findvideos': findvideos(item)
|
||||
|
||||
elif item.channel == "backup":
|
||||
from platformcode import backup
|
||||
return getattr(backup, item.action)(item)
|
||||
# Special action for searching, first asks for the words then call the "search" function
|
||||
elif item.action == 'search': search(item)
|
||||
|
||||
elif item.channel == "elementum_download":
|
||||
from platformcode import elementum_download
|
||||
return getattr(elementum_download, item.action)(item)
|
||||
######## Following shares must be improved ########
|
||||
|
||||
elif item.channel == "shortcuts":
|
||||
from platformcode import shortcuts
|
||||
return getattr(shortcuts, item.action)(item)
|
||||
|
||||
elif item.channel == "autorenumber":
|
||||
from platformcode import autorenumber
|
||||
return getattr(autorenumber, item.action)(item)
|
||||
|
||||
elif item.action == "delete_key":
|
||||
from platformcode import keymaptools
|
||||
return keymaptools.delete_key()
|
||||
|
||||
elif item.action == "script":
|
||||
from core import tmdb
|
||||
tmdb.clean_cache()
|
||||
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(60011), time=2000, sound=False)
|
||||
# Special itemInfo Action
|
||||
elif item.action == "itemInfo":
|
||||
platformtools.dialog_textviewer('Item info', item.parent)
|
||||
|
||||
# Special action for open item.url in browser
|
||||
elif item.action == "open_browser":
|
||||
import webbrowser
|
||||
if not webbrowser.open(item.url):
|
||||
@@ -157,6 +91,8 @@ def run(item=None):
|
||||
xbmc.executebuiltin('StartAndroidActivity("", "android.intent.action.VIEW", "", "%s")' % item.url)
|
||||
else:
|
||||
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(70740) % "\n".join([item.url[j:j+57] for j in range(0, len(item.url), 57)]))
|
||||
|
||||
# Special gotopage Action
|
||||
elif item.action == "gotopage":
|
||||
page = platformtools.dialog_numeric(0, config.get_localized_string(70513))
|
||||
if page:
|
||||
@@ -169,163 +105,52 @@ def run(item=None):
|
||||
item.url = re.sub('([=/])[0-9]+(/?)$', '\g<1>' + page + '\g<2>', item.url)
|
||||
xbmc.executebuiltin("Container.Update(%s?%s)" % (sys.argv[0], item.tourl()))
|
||||
|
||||
elif reload and item.channel == 'filmontv' and item.action == 'new_search':
|
||||
platformtools.fakeVideo()
|
||||
import xbmc
|
||||
return xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")")
|
||||
else:
|
||||
# Checks if channel exists
|
||||
if os.path.isfile(os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py")):
|
||||
CHANNELS = 'channels'
|
||||
# Special action for adding a movie to the library
|
||||
elif item.action == "add_pelicula_to_library":
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_movie(item)
|
||||
|
||||
# Special action for adding a serie to the library
|
||||
elif item.action == "add_serie_to_library":
|
||||
channel = importChannel(item)
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_tvshow(item, channel)
|
||||
|
||||
# Special action for adding a undefined to the library
|
||||
elif item.action == "add_to_library":
|
||||
channel = importChannel(item)
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_to_videolibrary(item, channel)
|
||||
|
||||
# Special action for downloading all episodes from a serie
|
||||
elif item.action == "download_all_episodes":
|
||||
from specials import downloads
|
||||
item.action = item.extra
|
||||
del item.extra
|
||||
downloads.save_download(item)
|
||||
|
||||
# keymaptools special actions
|
||||
elif item.action == "keymap":
|
||||
from platformcode import keymaptools
|
||||
if item.open:
|
||||
return keymaptools.open_shortcut_menu()
|
||||
else:
|
||||
CHANNELS = 'specials'
|
||||
return keymaptools.set_key()
|
||||
elif item.action == "delete_key":
|
||||
from platformcode import keymaptools
|
||||
return keymaptools.delete_key()
|
||||
|
||||
channel_file = os.path.join(config.get_runtime_path(), CHANNELS, item.channel + ".py")
|
||||
# delete tmdb cache
|
||||
elif item.action == "script":
|
||||
from core import tmdb
|
||||
tmdb.clean_cache()
|
||||
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(60011), time=2000, sound=False)
|
||||
|
||||
logger.debug("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel)
|
||||
################################################
|
||||
|
||||
channel = None
|
||||
# For all other actions
|
||||
else: actions(item)
|
||||
|
||||
if os.path.exists(channel_file):
|
||||
try:
|
||||
channel = __import__('%s.%s' % (CHANNELS, item.channel), None, None, ['%s.%s' % (CHANNELS, item.channel)])
|
||||
except ImportError:
|
||||
exec("import " + CHANNELS + "." + item.channel + " as channel")
|
||||
|
||||
logger.info("Running channel %s | %s" % (channel.__name__, channel.__file__))
|
||||
|
||||
# Special play action
|
||||
if item.action == "play":
|
||||
# define la info para trakt
|
||||
try:
|
||||
from core import trakt_tools
|
||||
trakt_tools.set_trakt_info(item)
|
||||
except:
|
||||
pass
|
||||
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.debug("Executing channel 'play' method")
|
||||
itemlist = channel.play(item)
|
||||
b_favourite = item.isFavourite
|
||||
# Play should return a list of playable URLS
|
||||
if len(itemlist) > 0 and isinstance(itemlist[0], Item):
|
||||
item = itemlist[0]
|
||||
if b_favourite:
|
||||
item.isFavourite = True
|
||||
platformtools.play_video(item)
|
||||
|
||||
# Permitir varias calidades desde play en el Channel
|
||||
elif len(itemlist) > 0 and isinstance(itemlist[0], list):
|
||||
item.video_urls = itemlist
|
||||
platformtools.play_video(item)
|
||||
|
||||
# If not, shows user an error message
|
||||
else:
|
||||
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(60339))
|
||||
|
||||
# If player don't have a "play" function, not uses the standard play from platformtools
|
||||
else:
|
||||
logger.debug("Executing core 'play' method")
|
||||
platformtools.play_video(item)
|
||||
|
||||
# Special action for findvideos, where the plugin looks for known urls
|
||||
elif item.action == "findvideos":
|
||||
from core import servertools
|
||||
if reload:
|
||||
item.autoplay = True
|
||||
platformtools.fakeVideo()
|
||||
|
||||
# First checks if channel has a "findvideos" function
|
||||
if hasattr(channel, 'findvideos'):
|
||||
itemlist = getattr(channel, item.action)(item)
|
||||
|
||||
# If not, uses the generic findvideos function
|
||||
else:
|
||||
logger.debug("No channel 'findvideos' method, " "executing core method")
|
||||
itemlist = servertools.find_video_items(item)
|
||||
|
||||
if config.get_setting("max_links", "videolibrary") != 0:
|
||||
itemlist = limit_itemlist(itemlist)
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
# Special action for adding a movie to the library
|
||||
elif item.action == "add_pelicula_to_library":
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_movie(item)
|
||||
|
||||
# Special action for adding a serie to the library
|
||||
elif item.action == "add_serie_to_library":
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_tvshow(item, channel)
|
||||
|
||||
# Special action for adding a undefined to the library
|
||||
elif item.action == "add_to_library":
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_to_videolibrary(item, channel)
|
||||
|
||||
# Special action for downloading all episodes from a serie
|
||||
elif item.action == "download_all_episodes":
|
||||
from specials import downloads
|
||||
item.action = item.extra
|
||||
del item.extra
|
||||
downloads.save_download(item)
|
||||
|
||||
# Special action for searching, first asks for the words then call the "search" function
|
||||
elif item.action == "search":
|
||||
if filetools.isfile(temp_search_file) and config.get_setting('videolibrary_kodi'):
|
||||
itemlist = []
|
||||
f = filetools.read(temp_search_file)
|
||||
strList = f.split(',')
|
||||
if strList[0] == '[V]' and strList[1] == item.channel:
|
||||
for it in strList:
|
||||
if it and it not in ['[V]', item.channel]:
|
||||
itemlist.append(Item().fromurl(it))
|
||||
filetools.write(temp_search_file, f[4:])
|
||||
return platformtools.render_items(itemlist, item)
|
||||
else:
|
||||
filetools.remove(temp_search_file)
|
||||
|
||||
logger.debug("item.action=%s" % item.action.upper())
|
||||
from core import channeltools
|
||||
|
||||
if config.get_setting('last_search'):
|
||||
last_search = channeltools.get_channel_setting('Last_searched', 'search', '')
|
||||
else:
|
||||
last_search = ''
|
||||
|
||||
search_text = platformtools.dialog_input(last_search)
|
||||
|
||||
if search_text is not None:
|
||||
channeltools.set_channel_setting('Last_searched', search_text, 'search')
|
||||
itemlist = new_search(item.clone(text=search_text), channel)
|
||||
else:
|
||||
return
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
# For all other actions
|
||||
else:
|
||||
|
||||
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
|
||||
token_auth = config.get_setting("token_trakt", "trakt")
|
||||
if not token_auth:
|
||||
trakt_tools.auth_trakt()
|
||||
else:
|
||||
import xbmc
|
||||
if not xbmc.getCondVisibility('System.HasAddon(script.trakt)') and config.get_setting('install_trakt'):
|
||||
trakt_tools.ask_install_script()
|
||||
itemlist = trakt_tools.trakt_check(itemlist)
|
||||
else:
|
||||
config.set_setting('install_trakt', True)
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
|
||||
except WebErrorException as e:
|
||||
@@ -337,24 +162,25 @@ def run(item=None):
|
||||
platformtools.dialog_ok(
|
||||
config.get_localized_string(59985) % e.channel,
|
||||
config.get_localized_string(60013) % e.url)
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
from core import scrapertools
|
||||
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"'
|
||||
patron = r'File "{}([^.]+)\.py"'.format(filetools.join(config.get_runtime_path(), 'channels', '').replace('\\', '\\\\'))
|
||||
Channel = scrapertools.find_single_match(traceback.format_exc(), patron)
|
||||
|
||||
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), nolabel='ok', yeslabel=config.get_localized_string(70739)):
|
||||
run(Item(action="open_browser", url=item.url))
|
||||
run(Item(action='open_browser', url=item.url))
|
||||
else:
|
||||
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014))
|
||||
else:
|
||||
if platformtools.dialog_yesno(config.get_localized_string(60038), config.get_localized_string(60015)):
|
||||
platformtools.itemlist_update(Item(channel="setting", action="report_menu"), True)
|
||||
platformtools.itemlist_update(Item(channel='setting', action='report_menu'), True)
|
||||
finally:
|
||||
# db need to be closed when not used, it will cause freezes
|
||||
from core import db
|
||||
@@ -374,196 +200,195 @@ def new_search(item, channel=None):
|
||||
writelist = item.channel
|
||||
for it in itemlist:
|
||||
writelist += ',' + it.tourl()
|
||||
filetools.write(temp_search_file, writelist)
|
||||
# filetools.write(temp_search_file, writelist)
|
||||
return itemlist
|
||||
|
||||
def set_search_temp(item):
|
||||
if filetools.isfile(temp_search_file) and config.get_setting('videolibrary_kodi'):
|
||||
f = '[V],' + filetools.read(temp_search_file)
|
||||
filetools.write(temp_search_file, f)
|
||||
|
||||
def reorder_itemlist(itemlist):
|
||||
def limitItemlist(itemlist):
|
||||
logger.debug()
|
||||
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
|
||||
|
||||
new_list = []
|
||||
mod_list = []
|
||||
not_mod_list = []
|
||||
|
||||
modified = 0
|
||||
not_modified = 0
|
||||
|
||||
to_change = [[config.get_localized_string(60335), '[V]'], [config.get_localized_string(60336), '[D]']]
|
||||
|
||||
for item in itemlist:
|
||||
if not PY3:
|
||||
old_title = unicode(item.title, "utf8").lower().encode("utf8")
|
||||
else:
|
||||
old_title = item.title.lower()
|
||||
for before, after in to_change:
|
||||
if before in item.title:
|
||||
item.title = item.title.replace(before, after)
|
||||
break
|
||||
|
||||
if not PY3:
|
||||
new_title = unicode(item.title, "utf8").lower().encode("utf8")
|
||||
else:
|
||||
new_title = item.title.lower()
|
||||
if old_title != new_title:
|
||||
mod_list.append(item)
|
||||
modified += 1
|
||||
else:
|
||||
not_mod_list.append(item)
|
||||
not_modified += 1
|
||||
|
||||
# logger.debug("OLD: %s | NEW: %s" % (old_title, new_title))
|
||||
|
||||
new_list.extend(mod_list)
|
||||
new_list.extend(not_mod_list)
|
||||
|
||||
logger.debug("Modified Titles:%i |Unmodified:%i" % (modified, not_modified))
|
||||
|
||||
if len(new_list) == 0:
|
||||
new_list = itemlist
|
||||
|
||||
# logger.debug("Outlet itemlist size: %i" % len(new_list))
|
||||
return new_list
|
||||
|
||||
|
||||
def limit_itemlist(itemlist):
|
||||
logger.debug()
|
||||
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
|
||||
|
||||
try:
|
||||
opt = config.get_setting("max_links", "videolibrary")
|
||||
if opt == 0:
|
||||
value = config.get_setting('max_links', 'videolibrary')
|
||||
if value == 0:
|
||||
new_list = itemlist
|
||||
else:
|
||||
i_max = 30 * opt
|
||||
new_list = itemlist[:i_max]
|
||||
|
||||
# logger.debug("Outlet itemlist size: %i" % len(new_list))
|
||||
new_list = itemlist[:value]
|
||||
return new_list
|
||||
except:
|
||||
return itemlist
|
||||
|
||||
|
||||
def play_from_library(item):
|
||||
"""
|
||||
The .strm files when played from kodi, this expects it to be a "playable" file so it cannot contain
|
||||
more items, at most a selection dialog can be placed.
|
||||
We solve this by "cheating kodi" and making him believe that something has been reproduced, so later by
|
||||
"Container.Update ()" we load the strm as if an item from inside the addon were treated, removing all
|
||||
the limitations and allowing to reproduce through the general function without having to create new methods to
|
||||
the video library.
|
||||
@type item: item
|
||||
@param item: item with information
|
||||
"""
|
||||
|
||||
def get_played_time(item):
|
||||
from core import videolibrarytools
|
||||
|
||||
if item.contentType == 'movie':
|
||||
nfo_path = item.nfo
|
||||
if nfo_path.startswith('\\') or nfo_path.startswith('/'):
|
||||
nfo_path = filetools.join(videolibrarytools.MOVIES_PATH, nfo_path)
|
||||
|
||||
else:
|
||||
nfo_path =item.strm_path.replace('strm','nfo')
|
||||
if nfo_path.startswith('\\') or nfo_path.startswith('/'):
|
||||
nfo_path = filetools.join(videolibrarytools.TVSHOWS_PATH, nfo_path)
|
||||
|
||||
if nfo_path and filetools.isfile(nfo_path):
|
||||
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
|
||||
sleep(1)
|
||||
played_time = platformtools.get_played_time(item_nfo)
|
||||
|
||||
else: played_time = 0
|
||||
|
||||
return played_time
|
||||
|
||||
import xbmcgui, xbmcplugin, xbmc
|
||||
from time import sleep
|
||||
|
||||
if not item.autoplay and not item.next_ep:
|
||||
platformtools.fakeVideo()
|
||||
|
||||
|
||||
itemlist=[]
|
||||
item.fromLibrary = True
|
||||
item.window = True
|
||||
def makeItem():
|
||||
logger.debug()
|
||||
|
||||
# Modify the action (currently the video library needs "findvideos" since this is where the sources are searched
|
||||
item.action = item.next_action if item.next_action else "findvideos"
|
||||
|
||||
if item.contentType == 'movie' or item.contentType != 'movie' and config.get_setting('next_ep') < 3:
|
||||
window_type = config.get_setting("window_type", "videolibrary")
|
||||
else: window_type = 1
|
||||
|
||||
# and launch kodi again
|
||||
if (xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1) or item.action != 'findvideos':
|
||||
xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")")
|
||||
|
||||
if sys.argv[2]:
|
||||
sp = sys.argv[2].split('&')
|
||||
url = sp[0]
|
||||
item = Item().fromurl(url)
|
||||
if len(sp) > 1:
|
||||
for e in sp[1:]:
|
||||
key, val = e.split('=')
|
||||
if val.lower() == 'false': val = False
|
||||
elif val.lower() == 'true': val = True
|
||||
item.__setattr__(key, val)
|
||||
# If no item, this is mainlist
|
||||
else:
|
||||
# Pop-up window
|
||||
from specials import videolibrary
|
||||
from core.channeltools import get_channel_parameters
|
||||
item = Item(channel='channelselector', action='getmainlist', viewmode='movie')
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def showOnce():
|
||||
if not config.get_all_settings_addon():
|
||||
logger.error('corrupted settings.xml!!')
|
||||
settings_xml = filetools.join(config.get_data_path(), 'settings.xml')
|
||||
settings_bak = filetools.join(config.get_data_path(), 'settings.bak')
|
||||
if filetools.exists(settings_bak):
|
||||
filetools.copy(settings_bak, settings_xml, True)
|
||||
logger.info('restored settings.xml from backup')
|
||||
else:
|
||||
filetools.write(settings_xml, '<settings version="2">\n</settings>') # resetted settings
|
||||
else:
|
||||
from platformcode import xbmc_videolibrary
|
||||
xbmc_videolibrary.ask_set_content(silent=False)
|
||||
config.set_setting('show_once', True)
|
||||
|
||||
|
||||
def play(item):
|
||||
channel = importChannel(item)
|
||||
|
||||
# define info for trakt
|
||||
try:
|
||||
from core import trakt_tools
|
||||
trakt_tools.set_trakt_info(item)
|
||||
except:
|
||||
pass
|
||||
logger.debug('item.action=', item.action.upper())
|
||||
|
||||
# First checks if channel has a "play" function
|
||||
if hasattr(channel, 'play'):
|
||||
logger.debug('Executing channel "play" method')
|
||||
itemlist = channel.play(item)
|
||||
# Play should return a list of playable URLS
|
||||
if len(itemlist) > 0 and isinstance(itemlist[0], Item):
|
||||
item = itemlist[0]
|
||||
platformtools.play_video(item)
|
||||
|
||||
# Allow several qualities from Play in El Channel
|
||||
elif len(itemlist) > 0 and isinstance(itemlist[0], list):
|
||||
item.video_urls = itemlist
|
||||
platformtools.play_video(item)
|
||||
|
||||
# If not, shows user an error message
|
||||
else:
|
||||
platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(60339))
|
||||
|
||||
# If player don't have a "play" function, not uses the standard play from platformtools
|
||||
else:
|
||||
logger.debug('Executing core "play" method')
|
||||
platformtools.play_video(item)
|
||||
|
||||
|
||||
def findvideos(item, itemlist=[]):
|
||||
if not itemlist:
|
||||
logger.debug('Executing channel', item.channel, 'method', item.action)
|
||||
channel = importChannel(item)
|
||||
from core import servertools
|
||||
|
||||
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(60683))
|
||||
p_dialog.update(0, '')
|
||||
item.play_from = 'window'
|
||||
itemlist = videolibrary.findvideos(item)
|
||||
p_dialog.update(100, ''); sleep(0.5); p_dialog.close()
|
||||
played = False
|
||||
p_dialog.update(0)
|
||||
|
||||
# The number of links to show is limited
|
||||
if config.get_setting("max_links", "videolibrary") != 0: itemlist = limit_itemlist(itemlist)
|
||||
# The list of links is slightly "cleaned"
|
||||
if config.get_setting("replace_VD", "videolibrary") == 1: itemlist = reorder_itemlist(itemlist)
|
||||
try:
|
||||
# First checks if channel has a "findvideos" function
|
||||
if hasattr(channel, 'findvideos'):
|
||||
itemlist = getattr(channel, item.action)(item)
|
||||
|
||||
if len(itemlist) > 0:
|
||||
reopen = False
|
||||
# If not, uses the generic findvideos function
|
||||
else:
|
||||
logger.debug('No channel "findvideos" method, executing core method')
|
||||
itemlist = servertools.find_video_items(item)
|
||||
|
||||
while not xbmc.Monitor().abortRequested():
|
||||
played = True
|
||||
# if config.get_setting('next_ep') == 3 and xbmc.Player().playnext:
|
||||
# return
|
||||
# The user chooses the mirror
|
||||
if not platformtools.is_playing():
|
||||
if config.get_setting('next_ep') == 3:
|
||||
xbmc.sleep(500)
|
||||
if platformtools.is_playing():
|
||||
return
|
||||
if config.get_setting('autoplay') or reopen:
|
||||
played_time = get_played_time(item)
|
||||
if not played_time and played:
|
||||
return
|
||||
itemlist = limitItemlist(itemlist)
|
||||
except Exception as ex:
|
||||
template = "An exception of type %s occured. Arguments:\n%r"
|
||||
message = template % (type(ex).__name__, ex.args)
|
||||
logger.error(" %s" % message)
|
||||
|
||||
options = []
|
||||
selection_implementation = 0
|
||||
for item in itemlist:
|
||||
item.thumbnail = config.get_online_server_thumb(item.server)
|
||||
quality = '[B][' + item.quality + '][/B]' if item.quality else ''
|
||||
if item.server:
|
||||
path = filetools.join(config.get_runtime_path(), 'servers', item.server.lower() + '.json')
|
||||
name = jsontools.load(open(path, "rb").read())['name']
|
||||
if name.startswith('@'): name = config.get_localized_string(int(name.replace('@','')))
|
||||
logger.debug(item)
|
||||
it = xbmcgui.ListItem('\n[B]%s[/B] %s - %s [%s]' % (name, quality, item.contentTitle, get_channel_parameters(item.contentChannel)['title']))
|
||||
it.setArt({'thumb':item.thumbnail})
|
||||
options.append(it)
|
||||
else:
|
||||
selection_implementation += 1
|
||||
# The selection window opens
|
||||
if (item.contentSerieName and item.contentSeason and item.contentEpisodeNumber): head = ("%s - %sx%s | %s" % (item.contentSerieName, item.contentSeason, item.contentEpisodeNumber, config.get_localized_string(30163)))
|
||||
else: head = config.get_localized_string(30163)
|
||||
selection = platformtools.dialog_select(head, options, preselect= -1, useDetails=True)
|
||||
if selection == -1:
|
||||
return
|
||||
else:
|
||||
item = videolibrary.play(itemlist[selection + selection_implementation])[0]
|
||||
platformtools.play_video(item)
|
||||
reopen = True
|
||||
if item.server == 'torrent': return
|
||||
# if (platformtools.is_playing() and item.action) or item.server == 'torrent' or config.get_setting('autoplay'): break
|
||||
p_dialog.update(100)
|
||||
p_dialog.close()
|
||||
|
||||
serverlist = [s for s in itemlist if s.server]
|
||||
if itemlist and not serverlist:
|
||||
platformtools.render_items(itemlist, item)
|
||||
if not serverlist:
|
||||
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(60347))
|
||||
elif len(serverlist) == 1:
|
||||
# If there is only one server play it immediately
|
||||
play(itemlist[0].clone(no_return=True))
|
||||
else:
|
||||
platformtools.serverWindow(item, itemlist)
|
||||
|
||||
|
||||
def search(item):
|
||||
channel = importChannel(item)
|
||||
from core import channeltools
|
||||
|
||||
if config.get_setting('last_search'):
|
||||
last_search = channeltools.get_channel_setting('Last_searched', 'search', '')
|
||||
else:
|
||||
last_search = ''
|
||||
|
||||
search_text = platformtools.dialog_input(last_search)
|
||||
|
||||
if search_text is not None:
|
||||
channeltools.set_channel_setting('Last_searched', search_text, 'search')
|
||||
itemlist = new_search(item.clone(text=search_text), channel)
|
||||
else:
|
||||
return
|
||||
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
|
||||
def addToLibrary(item):
|
||||
channel = importChannel(item)
|
||||
from core import videolibrarytools
|
||||
videolibrarytools.add_to_videolibrary(item, channel)
|
||||
|
||||
|
||||
def importChannel(item):
|
||||
channel = platformtools.channelImport(item.channel)
|
||||
if not channel:
|
||||
logger.debug('Channel', item.channel, 'not exist!')
|
||||
return
|
||||
|
||||
logger.debug('Running channel', channel.__name__, '|', channel.__file__)
|
||||
return channel
|
||||
|
||||
|
||||
def actions(item):
|
||||
logger.debug('Executing channel', item.channel, 'method', item.action)
|
||||
channel = importChannel(item)
|
||||
itemlist = getattr(channel, item.action)(item)
|
||||
if type(itemlist) == list:
|
||||
if config.get_setting('trakt_sync'):
|
||||
from core import trakt_tools
|
||||
token_auth = config.get_setting('token_trakt', 'trakt')
|
||||
if not token_auth:
|
||||
trakt_tools.auth_trakt()
|
||||
else:
|
||||
import xbmc
|
||||
if not xbmc.getCondVisibility('System.HasAddon(script.trakt)') and config.get_setting('install_trakt'):
|
||||
trakt_tools.ask_install_script()
|
||||
itemlist = trakt_tools.trakt_check(itemlist)
|
||||
else:
|
||||
config.set_setting('install_trakt', True)
|
||||
|
||||
if item.action in ['check'] and len([s for s in itemlist if s.server]) > 0:
|
||||
findvideos(item, itemlist)
|
||||
else:
|
||||
platformtools.render_items(itemlist, item)
|
||||
|
||||
|
||||
def playFromLibrary(item):
|
||||
if not item.next_ep: platformtools.fakeVideo()
|
||||
item.action = item.next_action if item.next_action else 'findvideos'
|
||||
logger.debug('Executing channel', item.channel, 'method', item.action)
|
||||
return run(item)
|
||||
|
||||
@@ -10,9 +10,12 @@ import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
PY3 = True
|
||||
import urllib.parse as urllib
|
||||
from concurrent import futures
|
||||
else:
|
||||
PY3 = False
|
||||
import urllib
|
||||
from concurrent_py2 import futures
|
||||
|
||||
|
||||
import os, xbmc, xbmcgui, xbmcplugin
|
||||
from past.utils import old_div
|
||||
@@ -310,47 +313,70 @@ def render_items(itemlist, parent_item):
|
||||
"""
|
||||
Function used to render itemlist on kodi
|
||||
"""
|
||||
|
||||
# if it's not a list, do nothing
|
||||
if not isinstance(itemlist, list):
|
||||
return
|
||||
|
||||
logger.debug('START render_items')
|
||||
logger.debug('START renderItems')
|
||||
thumb_type = config.get_setting('video_thumbnail_type')
|
||||
from platformcode import shortcuts
|
||||
# from core import httptools
|
||||
_handle = int(sys.argv[1])
|
||||
default_fanart = config.get_fanart()
|
||||
def_context_commands = shortcuts.context()
|
||||
|
||||
# if there's no item, add "no elements" item
|
||||
if not len(itemlist):
|
||||
itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png')))
|
||||
from core.support import thumb
|
||||
itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=thumb('nofolder')))
|
||||
|
||||
mode, Type = get_view_mode(itemlist[0], parent_item)
|
||||
# from core.support import dbg;dbg()
|
||||
if mode:
|
||||
set_view_mode(sys.argv[2], mode)
|
||||
|
||||
dirItems = []
|
||||
for n, item in enumerate(itemlist):
|
||||
# item.itemlistPosition = n + 1
|
||||
|
||||
def setItem(n, item, parent_item):
|
||||
item.itemlistPosition = n
|
||||
item_url = item.tourl()
|
||||
|
||||
if item.category == "":
|
||||
item.category = parent_item.category
|
||||
if not item.title:
|
||||
item.title = ''
|
||||
# If there is no action or it is findvideos / play, folder = False because no listing will be returned
|
||||
if item.action in ['play', '']:
|
||||
if item.action in ['play', 'findvideos', '']:
|
||||
item.folder = False
|
||||
if item.fanart == "":
|
||||
item.fanart = parent_item.fanart
|
||||
if item.action == 'play' and thumb_type == 1 and not item.forcethumb:
|
||||
item.thumbnail = config.get_online_server_thumb(item.server)
|
||||
|
||||
icon_image = "DefaultFolder.png" if item.folder else "DefaultVideo.png"
|
||||
listitem = xbmcgui.ListItem(item.title)
|
||||
listitem.setArt({'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail,
|
||||
'fanart': item.fanart if item.fanart else default_fanart})
|
||||
|
||||
title = item.title
|
||||
|
||||
|
||||
listitem = xbmcgui.ListItem(title)
|
||||
art = {'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail, 'fanart': item.fanart if item.fanart else default_fanart}
|
||||
if item.infoLabels.get('landscape'): art['landscape'] = item.infoLabels['landscape']
|
||||
if item.infoLabels.get('clearlogo'): art['clearlogo'] = item.infoLabels['clearlogo']
|
||||
if item.infoLabels.get('clearart'): art['clearart'] = item.infoLabels['clearart']
|
||||
if item.infoLabels.get('banner'): art['banner'] = item.infoLabels['banner']
|
||||
if item.infoLabels.get('disc'): art['disc'] = item.infoLabels['disc']
|
||||
listitem.setProperty('ResumeTime', str(get_played_time(item)))
|
||||
|
||||
listitem.setArt(art)
|
||||
|
||||
if config.get_setting("player_mode") == 1 and item.action == "play" and not item.nfo:
|
||||
listitem.setProperty('IsPlayable', 'true')
|
||||
|
||||
if item.infoLabels.get('castandrole'):
|
||||
try:
|
||||
cast = [{'name':c[0], 'role':c[1], 'thumbnail':c[2], 'order':c[3]} for c in item.infoLabels.get("castandrole", [])]
|
||||
cast.sort(key=lambda c: c['order'])
|
||||
listitem.setCast(cast)
|
||||
del item.infoLabels['castandrole']
|
||||
except:
|
||||
pass
|
||||
|
||||
set_infolabels(listitem, item)
|
||||
|
||||
# context menu
|
||||
@@ -359,12 +385,31 @@ def render_items(itemlist, parent_item):
|
||||
else:
|
||||
context_commands = def_context_commands
|
||||
listitem.addContextMenuItems(context_commands)
|
||||
return item, item_url, listitem
|
||||
|
||||
dirItems.append(('%s?%s' % (sys.argv[0], item_url), listitem, item.folder))
|
||||
# For Debug
|
||||
# from core.support import dbg;dbg()
|
||||
# r_list = [setItem(i, item, parent_item) for i, item in enumerate(itemlist)]
|
||||
|
||||
set_view_mode(itemlist[0], parent_item)
|
||||
r_list = []
|
||||
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
searchList = [executor.submit(setItem, i, item, parent_item) for i, item in enumerate(itemlist)]
|
||||
for res in futures.as_completed(searchList):
|
||||
r_list.append(res.result())
|
||||
r_list.sort(key=lambda it: it[0].itemlistPosition)
|
||||
|
||||
|
||||
for item, item_url, listitem in r_list:
|
||||
dirItems.append(('{}?{}'.format(sys.argv[0], item_url), listitem, item.folder, len(r_list)))
|
||||
xbmcplugin.addDirectoryItems(_handle, dirItems)
|
||||
|
||||
if Type: xbmcplugin.setContent(handle=int(sys.argv[1]), content=Type)
|
||||
|
||||
if parent_item.sorted:
|
||||
if parent_item.sorted == 'year': xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
|
||||
elif parent_item.sorted == 'name':xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
|
||||
|
||||
if parent_item.list_type == '':
|
||||
breadcrumb = parent_item.category #.capitalize()
|
||||
else:
|
||||
@@ -378,40 +423,41 @@ def render_items(itemlist, parent_item):
|
||||
|
||||
xbmcplugin.setPluginCategory(handle=_handle, category=breadcrumb)
|
||||
|
||||
xbmcplugin.endOfDirectory(_handle, succeeded=True, updateListing=False, cacheToDisc= True) # if parent_item.action in ['news', 'search', 'new_search', 'now_on_tv'] else False)
|
||||
|
||||
# if mode:
|
||||
# xbmc.sleep(50)
|
||||
# xbmc.executebuiltin('Container.SetViewMode(%s)' % mode)
|
||||
|
||||
# cacheToDisc = False
|
||||
# if (parent_item.action == 'findvideos' and config.get_setting('autoplay')) or parent_item.action == 'search':
|
||||
# cacheToDisc = True
|
||||
|
||||
xbmcplugin.endOfDirectory(_handle, succeeded=True, updateListing=False, cacheToDisc=True)
|
||||
logger.debug('END render_items')
|
||||
from core import db; db.close()
|
||||
logger.debug('END renderItems')
|
||||
|
||||
|
||||
def viewmodeMonitor():
|
||||
# logger.debug('WINDOW:',get_window())
|
||||
# logger.debug('WINDOW:',get_window(), xbmcgui.getCurrentWindowId())
|
||||
if get_window() == 'WINDOW_VIDEO_NAV':
|
||||
try:
|
||||
currentModeName = xbmc.getInfoLabel('Container.Viewmode')
|
||||
parent_info = xbmc.getInfoLabel('Container.FolderPath')
|
||||
item_info = xbmc.getInfoLabel('Container.ListItemPosition(2).FileNameAndPath')
|
||||
win = xbmcgui.Window(10025)
|
||||
currentMode = int(win.getFocusId())
|
||||
# logger.debug('CM', currentMode, 'CN',currentModeName, 'label',xbmc.getInfoLabel('Container.FolderPath'))
|
||||
# if not parent_info:
|
||||
if 'plugin.video.kod' in parent_info:
|
||||
parent = Item().fromurl(parent_info, silent=True)
|
||||
item = Item().fromurl(xbmc.getInfoLabel('Container.ListItemPosition(2).FileNameAndPath'), silent=True)
|
||||
currentModeName = xbmc.getInfoLabel('Container.Viewmode')
|
||||
currentMode = int(xbmcgui.Window(10025).getFocusId())
|
||||
# logger.debug('SAVE VIEW 1', currentMode, parent.action, item.action)
|
||||
if 50 <= currentMode < 520 and parent and parent.action != item.action:
|
||||
content, Type = getCurrentView(item, parent)
|
||||
view_mode_type = config.get_setting('view_mode_%s' % content)
|
||||
# logger.debug('VIEW MODE TYPE')
|
||||
if view_mode_type:
|
||||
defaultMode = int(view_mode_type.split(',')[-1])
|
||||
if content and currentMode != defaultMode:
|
||||
config.set_setting('view_mode_%s' % content, currentModeName + ', ' + str(currentMode))
|
||||
# logger.debug('SAVE VIEW 2', defaultMode, '->', currentMode)
|
||||
if config.get_setting('viewchange_notify'):
|
||||
dialog_notification(config.get_localized_string(70153),
|
||||
config.get_localized_string(70187) % (content, currentModeName),
|
||||
sound=False)
|
||||
|
||||
if currentModeName and 'plugin.video.kod' in parent_info and 50 <= currentMode < 1000:# and currentMode >= 50: # inside addon and in itemlist view
|
||||
# logger.debug('CAMBIO VISUALE')
|
||||
content, Type = getCurrentView(Item().fromurl(item_info) if item_info else Item(), Item().fromurl(parent_info))
|
||||
if content:
|
||||
defaultMode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
|
||||
if currentMode != defaultMode:
|
||||
# logger.debug('viewmode changed: ' + currentModeName + '-' + str(currentMode) + ' - content: ' + content)
|
||||
config.set_setting('view_mode_%s' % content, currentModeName + ', ' + str(currentMode))
|
||||
if config.get_setting('viewchange_notify'):
|
||||
dialog_notification(config.get_localized_string(70153),
|
||||
config.get_localized_string(70187) % (content, currentModeName),
|
||||
sound=False)
|
||||
except:
|
||||
import traceback
|
||||
logger.error(traceback.print_exc())
|
||||
@@ -422,20 +468,9 @@ def getCurrentView(item=None, parent_item=None):
|
||||
if not item:
|
||||
item = Item()
|
||||
if not parent_item:
|
||||
logger.debug('ESCO')
|
||||
# logger.debug('ESCO')
|
||||
return None, None
|
||||
|
||||
# if not parent_item:
|
||||
# info = xbmc.getInfoLabel('Container.FolderPath')
|
||||
# if not info:
|
||||
# return None, None
|
||||
# parent_item = Item().fromurl(info)
|
||||
# if not item:
|
||||
# info = xbmc.getInfoLabel('Container.ListItemPosition(2).FileNameAndPath') # first addon listitem (consider "..")
|
||||
# if not info:
|
||||
# item = Item()
|
||||
# else:
|
||||
# item = Item().fromurl(info) if info else Item()
|
||||
parent_actions = ['peliculas', 'novedades', 'search', 'get_from_temp', 'newest', 'discover_list', 'new_search', 'channel_search']
|
||||
|
||||
addons = 'addons' if config.get_setting('touch_view') else ''
|
||||
@@ -446,6 +481,9 @@ def getCurrentView(item=None, parent_item=None):
|
||||
elif parent_item.action == 'mainlist':
|
||||
return 'channel', addons
|
||||
|
||||
elif item.contentType == 'music':
|
||||
return 'musicvideo', 'musicvideos'
|
||||
|
||||
elif (item.contentType in ['movie'] and parent_item.action in parent_actions) \
|
||||
or (item.channel in ['videolibrary'] and parent_item.action in ['list_movies']) \
|
||||
or (parent_item.channel in ['favorites'] and parent_item.action in ['mainlist']) \
|
||||
@@ -460,11 +498,10 @@ def getCurrentView(item=None, parent_item=None):
|
||||
return 'episode', 'tvshows'
|
||||
|
||||
elif parent_item.action in ['get_seasons']:
|
||||
logger.debug('CONTENTTYPE:',item.contentType)
|
||||
return 'season', 'tvshows'
|
||||
|
||||
elif parent_item.action in ['getmainlist', '', 'getchanneltypes']:
|
||||
return 'home', addons
|
||||
return None, None
|
||||
|
||||
elif parent_item.action in ['filterchannels']:
|
||||
return 'channels', addons
|
||||
@@ -476,27 +513,84 @@ def getCurrentView(item=None, parent_item=None):
|
||||
return None, None
|
||||
|
||||
|
||||
|
||||
def set_view_mode(item, parent_item):
|
||||
def get_view_mode(item, parent_item):
|
||||
def reset_view_mode():
|
||||
for mode in ['home','menu','channels','channel','movie','tvshow','season','episode','server']:
|
||||
config.set_setting('skin_name', xbmc.getSkinDir())
|
||||
config.set_setting('view_mode_%s' % mode, config.get_localized_string(70003) + ' , 0')
|
||||
|
||||
content, Type = getCurrentView(item, parent_item)
|
||||
|
||||
if xbmc.getSkinDir() != config.get_setting('skin_name') or not config.get_setting('skin_name'):
|
||||
reset_view_mode()
|
||||
xbmcplugin.setContent(handle=int(sys.argv[1]), content='')
|
||||
xbmc.executebuiltin('Container.SetViewMode(%s)' % 55)
|
||||
return 55, Type
|
||||
|
||||
content, Type = getCurrentView(item, parent_item)
|
||||
if content:
|
||||
mode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
|
||||
if mode == 0:
|
||||
logger.debug('default mode')
|
||||
mode = 55
|
||||
xbmcplugin.setContent(handle=int(sys.argv[1]), content=Type)
|
||||
xbmc.executebuiltin('Container.SetViewMode(%s)' % mode)
|
||||
logger.debug('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content)
|
||||
return mode, Type
|
||||
|
||||
return None, None
|
||||
|
||||
|
||||
def set_view_mode(url, mode):
|
||||
import re
|
||||
find = re.findall('(%\d\w)', url, flags=re.DOTALL)
|
||||
for f in find:
|
||||
url = url.replace(f, f.lower())
|
||||
|
||||
def get_connection():
|
||||
from core import filetools
|
||||
|
||||
file_db = ""
|
||||
|
||||
# We look for the archive of the video database according to the version of kodi
|
||||
view_db = config.get_platform(True)['view_db']
|
||||
if view_db:
|
||||
file_db = filetools.join(xbmc.translatePath("special://userdata/Database"), view_db)
|
||||
|
||||
# alternative method to locate the database
|
||||
if not file_db or not filetools.exists(file_db):
|
||||
file_db = ""
|
||||
for f in filetools.listdir(xbmc.translatePath("special://userdata/Database")):
|
||||
path_f = filetools.join(xbmc.translatePath("special://userdata/Database"), f)
|
||||
|
||||
if filetools.isfile(path_f) and f.lower().startswith('viewmodes') and f.lower().endswith('.db'):
|
||||
file_db = path_f
|
||||
break
|
||||
try:
|
||||
import sqlite3
|
||||
return sqlite3.connect(file_db)
|
||||
except:
|
||||
return None
|
||||
|
||||
def execute_sql(conn, sql):
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(sql)
|
||||
conn.commit()
|
||||
|
||||
return cursor.fetchall()
|
||||
|
||||
conn = get_connection()
|
||||
if conn:
|
||||
skin_name = config.get_skin()
|
||||
try:
|
||||
sql = 'select idView from view where (path="{}{}" and skin="{}")'.format(sys.argv[0], url, skin_name)
|
||||
records = execute_sql(conn, sql)
|
||||
if records:
|
||||
# from core.support import dbg;dbg()
|
||||
sql = 'update view set viewMode={} where idView={}'.format(mode, records[0][0])
|
||||
records = execute_sql(conn, sql)
|
||||
else:
|
||||
# from core.support import dbg;dbg()
|
||||
sql = 'INSERT INTO view (window, path, viewMode, sortMethod, sortOrder, sortAttributes, skin) VALUES ' \
|
||||
'(10025, "{}{}", {}, 0, 1, 0, "{}")'.format(sys.argv[0], url, mode, skin_name)
|
||||
records = execute_sql(conn, sql)
|
||||
except:
|
||||
pass
|
||||
conn.close()
|
||||
|
||||
|
||||
def set_infolabels(listitem, item, player=False):
|
||||
@@ -511,33 +605,23 @@ def set_infolabels(listitem, item, player=False):
|
||||
@type item: item
|
||||
"""
|
||||
|
||||
infoLabels_dict = {'aired': 'aired', 'album': 'album', 'artist': 'artist', 'cast': 'cast',
|
||||
'castandrole': 'castandrole', 'tmdb_id': 'code', 'code': 'code', 'country': 'country',
|
||||
'credits': 'credits', 'release_date': 'dateadded', 'dateadded': 'dateadded', 'dbid': 'dbid',
|
||||
'director': 'director', 'duration': 'duration', 'episode': 'episode',
|
||||
'episodio_sinopsis': 'episodeguide', 'episodio_air_date': 'None', 'episodio_imagen': 'None',
|
||||
'episodio_titulo': 'title', 'episodio_vote_average': 'rating', 'episodio_vote_count': 'votes',
|
||||
'fanart': 'None', 'genre': 'genre', 'homepage': 'None', 'imdb_id': 'imdbnumber',
|
||||
'imdbnumber': 'imdbnumber', 'in_production': 'None', 'last_air_date': 'lastplayed',
|
||||
'mediatype': 'mediatype', 'mpaa': 'mpaa', 'number_of_episodes': 'None',
|
||||
'number_of_seasons': 'None', 'original_language': 'None', 'originaltitle': 'originaltitle',
|
||||
'overlay': 'overlay', 'poster_path': 'path', 'popularity': 'None', 'playcount': 'playcount',
|
||||
'plot': 'plot', 'plotoutline': 'plotoutline', 'premiered': 'premiered', 'quality': 'None',
|
||||
'rating': 'rating', 'season': 'season', 'set': 'set', 'setid': 'setid',
|
||||
'setoverview': 'setoverview', 'showlink': 'showlink', 'sortepisode': 'sortepisode',
|
||||
'sortseason': 'sortseason', 'sorttitle': 'sorttitle', 'status': 'status', 'studio': 'studio',
|
||||
'tag': 'tag', 'tagline': 'tagline', 'temporada_air_date': 'None', 'temporada_nombre': 'None',
|
||||
'temporada_num_episodios': 'None', 'temporada_poster': 'None', 'title': 'title',
|
||||
'top250': 'top250', 'tracknumber': 'tracknumber', 'trailer': 'trailer', 'thumbnail': 'None',
|
||||
'tvdb_id': 'None', 'tvshowtitle': 'tvshowtitle', 'type': 'None', 'userrating': 'userrating',
|
||||
'url_scraper': 'None', 'votes': 'votes', 'writer': 'writer', 'year': 'year'}
|
||||
infoLabels_dict = {'aired': 'aired', 'album': 'album', 'artist': 'artist', 'cast': 'cast', 'castandrole': 'castandrole',
|
||||
'tmdb_id': 'code', 'code': 'code', 'country': 'country', 'credits': 'credits', 'release_date': 'dateadded',
|
||||
'dateadded': 'dateadded', 'dbid': 'dbid', 'director': 'director', 'duration': 'duration', 'episode': 'episode',
|
||||
'episode_plot': 'episodeguide', 'episode_title': 'title', 'episode_vote_average': 'rating', 'episode_vote_count': 'votes',
|
||||
'genre': 'genre', 'imdb_id': 'imdbnumber', 'imdbnumber': 'imdbnumber', 'last_air_date': 'lastplayed', 'mediatype': 'mediatype',
|
||||
'mpaa': 'mpaa', 'originaltitle': 'originaltitle', 'overlay': 'overlay', 'poster_path': 'path', 'playcount': 'playcount',
|
||||
'plot': 'plot', 'plotoutline': 'plotoutline', 'premiered': 'premiered', 'rating': 'rating', 'season': 'season', 'set': 'set',
|
||||
'setid': 'setid', 'setoverview': 'setoverview', 'showlink': 'showlink', 'sortepisode': 'sortepisode', 'sortseason': 'sortseason',
|
||||
'sorttitle': 'sorttitle', 'status': 'status', 'studio': 'studio', 'tag': 'tag', 'tagline': 'tagline', 'title': 'title',
|
||||
'top250': 'top250', 'tracknumber': 'tracknumber', 'trailer': 'trailer', 'tvshowtitle': 'tvshowtitle', 'userrating': 'userrating',
|
||||
'votes': 'votes', 'writer': 'writer', 'year': 'year'}
|
||||
# if item.infoLabels:
|
||||
try:
|
||||
infoLabels_kodi = {infoLabels_dict[label_tag]: item.infoLabels[label_tag] for label_tag, label_value in list(item.infoLabels.items()) if infoLabels_dict[label_tag] != 'None'}
|
||||
infoLabels_kodi = {infoLabels_dict[label_tag]: label_value for label_tag, label_value in list(item.infoLabels.items()) if label_tag in infoLabels_dict}
|
||||
listitem.setInfo("video", infoLabels_kodi)
|
||||
except:
|
||||
listitem.setInfo("video", item.infoLabels)
|
||||
# logger.error(item.infoLabels)
|
||||
|
||||
|
||||
def set_context_commands(item, item_url, parent_item, **kwargs):
|
||||
@@ -605,39 +689,16 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
||||
else:
|
||||
context_commands.append((command["title"], "RunPlugin(%s?%s)" % (sys.argv[0], item.clone(**command).tourl())))
|
||||
# Do not add more predefined options if you are inside kodfavoritos
|
||||
# if parent_item.channel == 'kodfavorites':
|
||||
# return context_commands
|
||||
if parent_item.channel == 'kodfavorites':
|
||||
if config.dev_mode():
|
||||
context_commands.insert(0, ("item info", "Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl())))
|
||||
return context_commands
|
||||
# Options according to criteria, only if the item is not a tag, nor is it "Add to the video library", etc...
|
||||
if item.action and item.action not in ["add_pelicula_to_library", "add_serie_to_library", "buscartrailer", "actualizar_titulos"]:
|
||||
# Show information: if the item has a plot, we assume that it is a series, season, chapter or movie
|
||||
# if item.infoLabels['plot'] and (num_version_xbmc < 17.0 or item.contentType == 'season'):
|
||||
# context_commands.append((config.get_localized_string(60348), "Action(Info)"))
|
||||
|
||||
if item.channel != "videolibrary" and item.videolibrary != False and not item.disable_videolibrary:
|
||||
# Add Series to the video library
|
||||
if item.action in ["episodios", "get_episodios", "get_seasons"] and item.contentSerieName:
|
||||
context_commands.append((config.get_localized_string(60352), "RunPlugin(%s?%s&%s)" % (
|
||||
sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action)))
|
||||
# Add Movie to Video Library
|
||||
elif item.action in ["detail", "findvideos"] and item.contentType == 'movie' and item.contentTitle:
|
||||
context_commands.append((config.get_localized_string(60353), "RunPlugin(%s?%s&%s)" % (
|
||||
sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action)))
|
||||
# Add to Video Library
|
||||
elif item.action in ['check'] and item.contentTitle:
|
||||
context_commands.append((config.get_localized_string(30161), "RunPlugin(%s?%s&%s)" % (
|
||||
sys.argv[0], item_url, 'action=add_to_library&from_action=' + item.action)))
|
||||
|
||||
# Search trailer...
|
||||
if (item.contentTitle and item.contentType in ['movie', 'tvshow']) or "buscar_trailer" in context:
|
||||
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
|
||||
|
||||
# Add to kodfavoritos (My links)
|
||||
if item.channel not in ["favorites", "videolibrary", "help", ""] and parent_item.channel != "kodfavorites":
|
||||
context_commands.append( (config.get_localized_string(70557), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
|
||||
# Add to kodfavoritos
|
||||
if parent_item.channel == 'globalsearch':
|
||||
context_commands.append( (config.get_localized_string(30155), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "favorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
|
||||
|
||||
# InfoPlus
|
||||
if config.get_setting("infoplus"):
|
||||
#if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id'] or \
|
||||
@@ -645,8 +706,35 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
||||
if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id']:
|
||||
context_commands.append(("InfoPlus", "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=Main&from_channel=' + item.channel)))
|
||||
|
||||
# Search in other channels
|
||||
if item.contentTitle and item.contentType in ['movie', 'tvshow'] and parent_item.channel not in ['search', 'globalsearch'] and item.action not in ['play']: #and parent_item.action != 'mainlist':
|
||||
if item.channel != "videolibrary" and item.videolibrary != False and not item.disable_videolibrary:
|
||||
# Add Series to the video library
|
||||
if item.action in ["episodios", "get_episodios", "get_seasons"] and item.contentSerieName:
|
||||
context_commands.append((config.get_localized_string(60352), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action)))
|
||||
# Add Movie to Video Library
|
||||
elif item.action in ["detail", "findvideos"] and item.contentType == 'movie' and item.contentTitle:
|
||||
context_commands.append((config.get_localized_string(60353), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action)))
|
||||
# Add to Video Library
|
||||
elif item.action in ['check'] and item.contentTitle:
|
||||
context_commands.append((config.get_localized_string(30161), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_to_library&from_action=' + item.action)))
|
||||
|
||||
# Search trailer...
|
||||
if (item.contentTitle and item.contentType in ['movie', 'tvshow']) or "buscar_trailer" in context:
|
||||
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
|
||||
|
||||
# Add to kodfavoritos (My links)
|
||||
if item.channel not in ["favorites", "videolibrary", "help", ""] and parent_item.channel != "favorites" and parent_item.from_channel != "kodfavorites":
|
||||
context_commands.append( (config.get_localized_string(70557), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
|
||||
|
||||
# Add to kodfavoritos
|
||||
if parent_item.channel == 'globalsearch':
|
||||
context_commands.append( (config.get_localized_string(30155), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "favorites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action}))))
|
||||
|
||||
# Open in browser and previous menu
|
||||
if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist":
|
||||
context_commands.append((config.get_localized_string(70739), "Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())))
|
||||
|
||||
# Search in other channels
|
||||
if item.contentTitle and item.contentType in ['movie', 'tvshow'] and parent_item.channel not in ['search', 'globalsearch'] and item.action not in ['play'] and parent_item.action != 'mainlist':
|
||||
|
||||
# Search in other channels
|
||||
if item.contentSerieName != '':
|
||||
@@ -665,11 +753,6 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
|
||||
context_commands.append((config.get_localized_string(60350), "Container.Refresh (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted}))))
|
||||
context_commands.append( (config.get_localized_string(70561), "Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id']))))
|
||||
|
||||
|
||||
# Open in browser and previous menu
|
||||
if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist" and not parent_item.noMainMenu:
|
||||
context_commands.append((config.get_localized_string(70739), "Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())))
|
||||
|
||||
if not item.local and item.channel not in ["downloads", "filmontv", "search"] and item.server != 'torrent' and parent_item.action != 'mainlist' and config.get_setting('downloadenabled') and not item.disable_videolibrary:
|
||||
# Download movie
|
||||
if item.contentType == "movie":
|
||||
@@ -960,6 +1043,7 @@ def get_window():
|
||||
|
||||
|
||||
def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
from core import httptools
|
||||
logger.debug()
|
||||
logger.debug(item.tostring('\n'))
|
||||
|
||||
@@ -977,7 +1061,6 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
|
||||
# pass referer
|
||||
if item.referer:
|
||||
from core import httptools
|
||||
httptools.default_headers['Referer'] = item.referer
|
||||
|
||||
# Open the selection dialog to see the available options
|
||||
@@ -999,9 +1082,33 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
# we get the selected video
|
||||
mediaurl, view, mpd, hls = get_video_seleccionado(item, seleccion, video_urls, autoplay)
|
||||
if not mediaurl: return
|
||||
# to better disguise KoD as a browser
|
||||
headers = {'User-Agent': httptools.get_user_agent(), 'Referer': item.referer if item.server == 'directo' else item.url}
|
||||
# Kodi does not seems to allow this, leaving there as may work in the future
|
||||
# if config.get_setting('resolver_dns'):
|
||||
# try:
|
||||
# import urllib.parse as urlparse
|
||||
# except ImportError:
|
||||
# import urlparse
|
||||
# from lib import doh
|
||||
# try:
|
||||
# parse = urlparse.urlparse(mediaurl)
|
||||
# if parse.netloc:
|
||||
# domain = parse.netloc
|
||||
# if not scrapertools.find_single_match(domain, '\d+\.\d+\.\d+\.\d+'):
|
||||
# ip = doh.query(domain)[0]
|
||||
# logger.info('Query DoH: ' + domain + ' = ' + str(ip))
|
||||
# parse = list(parse)
|
||||
# parse[1] = ip
|
||||
# mediaurl = urlparse.urlunparse(parse)
|
||||
# headers['Host'] = domain
|
||||
# except:
|
||||
# logger.error('Failed to resolve hostname, fallback to normal dns')
|
||||
if '|' not in mediaurl:
|
||||
mediaurl = mediaurl + '|' + urllib.urlencode(headers)
|
||||
|
||||
# video information is obtained.
|
||||
xlistitem = xbmcgui.ListItem(path=item.url)
|
||||
xlistitem = xbmcgui.ListItem(item.title, path=item.url)
|
||||
xlistitem.setArt({"thumb": item.contentThumbnail if item.contentThumbnail else item.thumbnail})
|
||||
set_infolabels(xlistitem, item, True)
|
||||
|
||||
@@ -1016,12 +1123,14 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
xlistitem.setProperty("inputstream.adaptive.license_type", item.drm)
|
||||
xlistitem.setProperty("inputstream.adaptive.license_key", item.license)
|
||||
xlistitem.setMimeType('application/dash+xml')
|
||||
xlistitem.setProperty('inputstream.adaptive.stream_headers', httptools.get_user_agent())
|
||||
elif hls or item.manifest == 'hls':# or (mediaurl.split('|')[0].endswith('m3u8') and mediaurl.startswith('http')):
|
||||
if not install_inputstream():
|
||||
return
|
||||
xlistitem.setProperty('inputstream' if PY3 else 'inputstreamaddon', 'inputstream.adaptive')
|
||||
xlistitem.setProperty('inputstream.adaptive.manifest_type', 'hls')
|
||||
xlistitem.setMimeType('application/x-mpegURL')
|
||||
xlistitem.setProperty('inputstream.adaptive.stream_headers', httptools.get_user_agent())
|
||||
|
||||
if force_direct: item.play_from = 'window'
|
||||
|
||||
@@ -1368,7 +1477,10 @@ def get_video_seleccionado(item, seleccion, video_urls, autoplay=False):
|
||||
def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
logger.debug()
|
||||
item.options = {'strm':False}
|
||||
# logger.debug("item:\n" + item.tostring('\n'))
|
||||
if item.subtitle:
|
||||
if type(item.subtitle) != list: item.subtitle = [item.subtitle]
|
||||
# item.subtitle.reverse()
|
||||
xlistitem.setSubtitles(item.subtitle)
|
||||
|
||||
# Moved del conector "torrent" here
|
||||
if item.server == "torrent":
|
||||
@@ -1377,9 +1489,6 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
# If it is a strm file, play is not necessary
|
||||
elif strm:
|
||||
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem)
|
||||
if item.subtitle:
|
||||
xbmc.sleep(2000)
|
||||
xbmc_player.setSubtitles(item.subtitle)
|
||||
|
||||
else:
|
||||
if type(item.player_mode) == int:
|
||||
@@ -1389,11 +1498,10 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
if (player_mode == 3 and mediaurl.startswith("rtmp")): player_mode = 0
|
||||
elif "megacrypter.com" in mediaurl: player_mode = 3
|
||||
logger.info("mediaurl=" + mediaurl)
|
||||
|
||||
prevent_busy()
|
||||
if player_mode in [0,1]:
|
||||
prevent_busy(item)
|
||||
if player_mode in [1]:
|
||||
item.played_time = resume_playback(get_played_time(item))
|
||||
xlistitem.setProperty('StartOffset','{}'.format(resume_playback(get_played_time(item))))
|
||||
|
||||
logger.info('Player Mode:',['Direct', 'Bookmark'][player_mode])
|
||||
# Add the listitem to a playlist
|
||||
@@ -1418,26 +1526,13 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
download_and_play.download_and_play(mediaurl, "download_and_play.tmp", config.get_setting("downloadpath"))
|
||||
return
|
||||
|
||||
# ALL LOOKING TO REMOVE VIEW
|
||||
if item.subtitle and view:
|
||||
logger.info("External subtitles: " + item.subtitle)
|
||||
xbmc.sleep(2000)
|
||||
xbmc_player.setSubtitles(item.subtitle)
|
||||
|
||||
# if it is a video library file send to mark as seen
|
||||
if strm or item.strm_path: item.options['strm'] = True
|
||||
# if player_mode == 1: item.options['continue'] = True
|
||||
|
||||
if not mediaurl.startswith('plugin'):
|
||||
from platformcode import xbmc_videolibrary
|
||||
xbmc_videolibrary.mark_auto_as_watched(item)
|
||||
|
||||
# for cases where the audio playback window appears in place of the video one
|
||||
if item.focusOnVideoPlayer:
|
||||
while is_playing() and xbmcgui.getCurrentWindowId() != 12006:
|
||||
continue
|
||||
xbmc.sleep(500)
|
||||
xbmcgui.Window(12005).show()
|
||||
|
||||
|
||||
def add_next_to_playlist(item):
|
||||
import threading
|
||||
@@ -1451,7 +1546,7 @@ def add_next_to_playlist(item):
|
||||
nfo_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"), next.strm_path.replace('strm','nfo'))
|
||||
if nfo_path and filetools.isfile(nfo_path):
|
||||
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
|
||||
nextItem = xbmcgui.ListItem(path=item_nfo.url)
|
||||
nextItem = xbmcgui.ListItem(item_nfo.fulltitle, path=item_nfo.url)
|
||||
nextItem.setArt({"thumb": item_nfo.contentThumbnail if item_nfo.contentThumbnail else item_nfo.thumbnail})
|
||||
set_infolabels(nextItem, item_nfo, True)
|
||||
nexturl = "plugin://plugin.video.kod/?" + next.tourl()
|
||||
@@ -1495,7 +1590,7 @@ def play_torrent(item, xlistitem, mediaurl):
|
||||
selection = 0
|
||||
|
||||
if selection >= 0:
|
||||
prevent_busy(item)
|
||||
prevent_busy()
|
||||
|
||||
mediaurl = urllib.quote_plus(item.url)
|
||||
torr_client = torrent_options[selection][0]
|
||||
@@ -1650,7 +1745,7 @@ def get_played_time(item):
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
del db['viewed'][ID]
|
||||
|
||||
# db.close()
|
||||
return played_time
|
||||
|
||||
|
||||
@@ -1680,19 +1775,264 @@ def set_played_time(item):
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
del db['viewed'][ID]
|
||||
db.close()
|
||||
|
||||
def prevent_busy():
|
||||
xbmc.executebuiltin('Dialog.Close(all,true)')
|
||||
|
||||
|
||||
def prevent_busy(item=None):
|
||||
if item and (not item.autoplay and item.channel != 'videolibrary' and not item.window):
|
||||
fakeVideo()
|
||||
else:
|
||||
xbmc.executebuiltin('Dialog.Close(all,true)')
|
||||
|
||||
|
||||
def fakeVideo():
|
||||
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True,
|
||||
xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "resources", "kod.mp4")))
|
||||
sleep = 200
|
||||
def fakeVideo(sleep = False):
|
||||
mediaurl = os.path.join(config.get_runtime_path(), "resources", "kod.mp4")
|
||||
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=mediaurl))
|
||||
while not is_playing():
|
||||
xbmc.sleep(sleep)
|
||||
xbmc.sleep(200)
|
||||
xbmc.Player().stop()
|
||||
|
||||
|
||||
def channelImport(channelId):
|
||||
from core import filetools
|
||||
ch = ''
|
||||
path = filetools.join(config.get_runtime_path(), '{}', channelId + ".py")
|
||||
if filetools.exists(path.format('channels')): ch = 'channels.{}'.format(channelId)
|
||||
elif filetools.exists(path.format('specials')): ch = 'specials.{}'.format(channelId)
|
||||
elif filetools.exists(path.format('platformcode')): ch = 'platformcode.{}'.format(channelId)
|
||||
elif filetools.exists(path.format('core')): ch = 'core.{}'.format(channelId)
|
||||
if ch:
|
||||
channel = __import__(ch, None, None, [ch])
|
||||
else:
|
||||
logger.info('Channel {} not Exist'.format(channelId))
|
||||
channel = None
|
||||
return channel
|
||||
|
||||
def serverWindow(item, itemlist):
|
||||
from core import db
|
||||
LEFT = 1
|
||||
RIGHT = 2
|
||||
UP = 3
|
||||
DOWN = 4
|
||||
ENTER = 7
|
||||
EXIT = 10
|
||||
BACKSPACE = 92
|
||||
|
||||
CONTEXT = 117
|
||||
|
||||
class ServerWindow(xbmcgui.WindowXMLDialog):
|
||||
def start(self, item, itemlist):
|
||||
prevent_busy()
|
||||
self.itemlist = itemlist
|
||||
self.item = item
|
||||
self.servers = []
|
||||
items = []
|
||||
self.selection = -1
|
||||
self.actions = {}
|
||||
for videoitem in self.itemlist:
|
||||
videoitem.thumbnail = config.get_online_server_thumb(videoitem.server)
|
||||
quality = ' [' + videoitem.quality + ']' if videoitem.quality else ''
|
||||
info = ' [' + videoitem.extraInfo + ']' if videoitem.extraInfo else ''
|
||||
if videoitem.server:
|
||||
color = scrapertools.find_single_match(videoitem.alive, r'(FF[^\]]+)')
|
||||
it = xbmcgui.ListItem('{}{}{}'.format(videoitem.serverName, quality, info))
|
||||
|
||||
# format Title
|
||||
if videoitem.contentSeason and videoitem.contentEpisodeNumber:
|
||||
title = '{}x{:02d}. {}'.format(videoitem.contentSeason, videoitem.contentEpisodeNumber, videoitem.contentTitle)
|
||||
elif videoitem.contentEpisodeNumber:
|
||||
title = '{:02d}. {}'.format(videoitem.contentEpisodeNumber, videoitem.contentTitle)
|
||||
else:
|
||||
title = videoitem.title
|
||||
|
||||
it.setProperties({'name': title, 'channel': videoitem.ch_name, 'color': color if color else 'FF0082C2'})
|
||||
it.setArt({'poster':videoitem.contentThumbnail, 'thumb':videoitem.thumbnail, 'fanart':videoitem.contentFanart})
|
||||
self.servers.append(it)
|
||||
items.append(videoitem)
|
||||
else:
|
||||
it = xbmcgui.ListItem(videoitem.title)
|
||||
if 'library' in videoitem.action:
|
||||
self.actions['videolibrary'] = videoitem
|
||||
if 'download' in videoitem.action:
|
||||
self.actions['download'] = videoitem
|
||||
|
||||
self.itemlist = items
|
||||
self.doModal()
|
||||
return self.selection
|
||||
|
||||
def onInit(self):
|
||||
self.SERVERS = self.getControl(100)
|
||||
self.VIDEOLIBRARY = self.getControl(103)
|
||||
self.DOWNLOAD = self.getControl(104)
|
||||
if 'videolibrary' not in self.actions.keys():
|
||||
self.VIDEOLIBRARY.setVisible(False)
|
||||
if 'download' not in self.actions.keys():
|
||||
self.DOWNLOAD.setVisible(False)
|
||||
self.SERVERS.reset()
|
||||
self.SERVERS.addItems(self.servers)
|
||||
self.setFocusId(100)
|
||||
# from core.support import dbg;dbg()
|
||||
|
||||
def onFocus(self, control):
|
||||
if is_playing() and db['controls'].get('reopen', False):
|
||||
self.close()
|
||||
serverWindow(self.item, self.itemlist)
|
||||
|
||||
def onAction(self, action):
|
||||
action = action.getId()
|
||||
focus = self.getFocusId()
|
||||
if action in [UP, DOWN, LEFT, RIGHT] and focus not in [100, 101, 102, 103, 104]:
|
||||
self.setFocusId(100)
|
||||
elif action in [EXIT, BACKSPACE]:
|
||||
self.close()
|
||||
if action in [CONTEXT]:
|
||||
context(self)
|
||||
|
||||
def onClick(self, control):
|
||||
if control == 100:
|
||||
self.selection = self.itemlist[self.SERVERS.getSelectedPosition()].clone(window=True)
|
||||
self.close()
|
||||
elif control in [101]:
|
||||
self.close()
|
||||
elif control in [102]:
|
||||
context(self)
|
||||
elif control in [103]:
|
||||
self.run(self.actions['videolibrary'])
|
||||
elif control in [104]:
|
||||
self.run(self.actions['download'])
|
||||
|
||||
def run(self, action):
|
||||
from platformcode.launcher import run
|
||||
run(action)
|
||||
|
||||
class ServerSkinWindow(xbmcgui.WindowXMLDialog):
|
||||
def start(self, item, itemlist):
|
||||
prevent_busy()
|
||||
self.item = item
|
||||
self.itemlist = itemlist
|
||||
self.selection = -1
|
||||
self.actions = []
|
||||
self.doModal()
|
||||
return self.selection
|
||||
|
||||
def onInit(self):
|
||||
try:
|
||||
self.SERVERS = self.getControl(6)
|
||||
self.exit = self.getControl(5)
|
||||
self.exit.setNavigation(self.exit, self.exit, self.SERVERS, self.SERVERS)
|
||||
except:
|
||||
pass
|
||||
|
||||
try: self.getControl(7).setVisible(False)
|
||||
except: pass
|
||||
try: self.getControl(8).setVisible(False)
|
||||
except: pass
|
||||
|
||||
self.exit.setLabel(config.get_localized_string(60396))
|
||||
|
||||
for item in itemlist:
|
||||
if item.server: break
|
||||
if item.contentSeason and item.contentEpisodeNumber:
|
||||
title = '{}x{:02d}. {}'.format(item.contentSeason, item.contentEpisodeNumber, item.contentTitle)
|
||||
elif item.contentEpisodeNumber:
|
||||
title = '{:02d}. {}'.format(item.contentEpisodeNumber, item.contentTitle)
|
||||
else:
|
||||
title = item.fulltitle
|
||||
|
||||
self.getControl(1).setLabel(title)
|
||||
|
||||
items = []
|
||||
|
||||
from core.support import typo
|
||||
for videoitem in self.itemlist:
|
||||
if videoitem.server:
|
||||
logger.debug(videoitem)
|
||||
videoitem.thumbnail = config.get_online_server_thumb(videoitem.server)
|
||||
quality = ' [' + videoitem.quality + ']' if videoitem.quality else ''
|
||||
color = scrapertools.find_single_match(videoitem.alive, r'(FF[^\]]+)')
|
||||
color = typo(' •', 'bold color 0x{}'.format(color)) if color else ''
|
||||
info = ' [' + videoitem.extraInfo + ']' if videoitem.extraInfo else ''
|
||||
title = '{}{}{}{}'.format(videoitem.serverName, quality, info, color)
|
||||
else:
|
||||
title = videoitem.title
|
||||
it = xbmcgui.ListItem(title)
|
||||
if videoitem.ch_name:
|
||||
it.setLabel2(videoitem.ch_name)
|
||||
elif not videoitem.action:
|
||||
it.setLabel2(videoitem.plot)
|
||||
else:
|
||||
it.setLabel2(videoitem.fulltitle)
|
||||
it.setArt({'thumb': videoitem.thumbnail})
|
||||
|
||||
items.append(it)
|
||||
self.SERVERS.reset()
|
||||
self.SERVERS.addItems(items)
|
||||
self.setFocus(self.SERVERS)
|
||||
|
||||
def onFocus(self, control):
|
||||
if is_playing() and db['controls'].get('reopen', False):
|
||||
self.close()
|
||||
serverWindow(self.item, self.itemlist)
|
||||
|
||||
def onAction(self, action):
|
||||
action = action.getId()
|
||||
if action in [CONTEXT]:
|
||||
context(self)
|
||||
if action in [EXIT, BACKSPACE]:
|
||||
self.close()
|
||||
|
||||
def onClick(self, control):
|
||||
if control == 6:
|
||||
self.selection = self.itemlist[self.SERVERS.getSelectedPosition()]
|
||||
if not self.selection.action:
|
||||
it = self.selection
|
||||
self.selection = -1
|
||||
dialog_textviewer(it.title, it.plot)
|
||||
else:
|
||||
self.close()
|
||||
if control == 5:
|
||||
self.close()
|
||||
elif control == 7:
|
||||
from platformcode.launcher import run
|
||||
run(self.actions[1])
|
||||
elif control == 8:
|
||||
from platformcode.launcher import run
|
||||
run(self.actions[0])
|
||||
|
||||
|
||||
def context(self):
|
||||
pos = self.SERVERS.getSelectedPosition()
|
||||
parent = self.item
|
||||
item = self.itemlist[pos]
|
||||
if not item.server:
|
||||
return
|
||||
commands = set_context_commands(item, item.tourl(), parent)
|
||||
context = [c[0] for c in commands]
|
||||
context_commands = [c[1].replace('Container.Refresh', 'RunPlugin').replace('Container.Update', 'RunPlugin') for c in commands]
|
||||
index = xbmcgui.Dialog().contextmenu(context)
|
||||
if index > 0: xbmc.executebuiltin(context_commands[index])
|
||||
|
||||
|
||||
if itemlist:
|
||||
def monitor(itemlist):
|
||||
reopen = False
|
||||
while not xbmc.Monitor().abortRequested():
|
||||
if not is_playing():
|
||||
if reopen:
|
||||
xbmc.sleep(200)
|
||||
if not db['controls'].get('reopen', False):
|
||||
break
|
||||
if config.get_setting('window_type') == 0:
|
||||
selection = ServerSkinWindow("DialogSelect.xml", config.get_runtime_path()).start(item, itemlist)
|
||||
else:
|
||||
selection = ServerWindow('Servers.xml', config.get_runtime_path()).start(item, itemlist)
|
||||
|
||||
if selection == -1:
|
||||
break
|
||||
|
||||
else:
|
||||
from platformcode.launcher import run
|
||||
run(selection)
|
||||
reopen = True
|
||||
if not selection.server or selection.server == 'torrent': break
|
||||
|
||||
db.close()
|
||||
logger.debug('Server Window EXIT')
|
||||
import threading
|
||||
threading.Thread(target=monitor, args=[itemlist]).start()
|
||||
|
||||
@@ -33,7 +33,6 @@ def mark_auto_as_watched(item):
|
||||
marked = False
|
||||
sync = False
|
||||
next_episode = None
|
||||
show_server = True
|
||||
mark_time = 0
|
||||
|
||||
percentage = float(config.get_setting("watched_setting")) / 100
|
||||
@@ -53,22 +52,18 @@ def mark_auto_as_watched(item):
|
||||
except: pass
|
||||
try: total_time = xbmc.Player().getTotalTime()
|
||||
except: pass
|
||||
if item.played_time and xbmcgui.getCurrentWindowId() == 12005:
|
||||
xbmc.Player().seekTime(item.played_time)
|
||||
item.played_time = 0 # Fix for Slow Devices
|
||||
|
||||
mark_time = total_time * percentage
|
||||
difference = total_time - actual_time
|
||||
|
||||
# Mark as Watched
|
||||
if actual_time > mark_time and not marked:
|
||||
if mark_time and total_time > actual_time > mark_time and not marked:
|
||||
logger.info("Marked as Watched")
|
||||
item.playcount = 1
|
||||
marked = True
|
||||
item.played_time = 0
|
||||
platformtools.set_played_time(item)
|
||||
if item.options['strm'] : sync = True
|
||||
show_server = False
|
||||
from specials import videolibrary
|
||||
videolibrary.mark_content_as_watched2(item)
|
||||
if not next_episode:
|
||||
@@ -86,9 +81,16 @@ def mark_auto_as_watched(item):
|
||||
break
|
||||
|
||||
# if item.options['continue']:
|
||||
if actual_time < mark_time and mark_time:
|
||||
from core import db
|
||||
if marked:
|
||||
logger.debug('CLOSE')
|
||||
item.played_time = 0
|
||||
db['controls']['reopen'] = False
|
||||
else:
|
||||
logger.debug('REOPEN')
|
||||
item.played_time = actual_time
|
||||
else: item.played_time = 0
|
||||
db['controls']['reopen'] = True
|
||||
db.close()
|
||||
platformtools.set_played_time(item)
|
||||
|
||||
# Silent sync with Trakt
|
||||
@@ -97,23 +99,14 @@ def mark_auto_as_watched(item):
|
||||
while platformtools.is_playing():
|
||||
xbmc.sleep(100)
|
||||
|
||||
if not show_server and item.play_from != 'window' and not item.no_return:
|
||||
xbmc.sleep(700)
|
||||
xbmc.executebuiltin('Action(ParentDir)')
|
||||
xbmc.sleep(500)
|
||||
|
||||
if next_episode and next_episode.next_ep and config.get_setting('next_ep') < 3:
|
||||
from platformcode.launcher import run
|
||||
run(next_episode)
|
||||
|
||||
# db need to be closed when not used, it will cause freezes
|
||||
from core import db
|
||||
db.close()
|
||||
|
||||
# If it is configured to mark as seen
|
||||
if config.get_setting("mark_as_watched", "videolibrary"):
|
||||
threading.Thread(target=mark_as_watched_subThread, args=[item]).start()
|
||||
|
||||
logger.debug('EXIT MONITOR')
|
||||
|
||||
def sync_trakt_addon(path_folder):
|
||||
"""
|
||||
|
||||
@@ -2605,12 +2605,12 @@ msgid "Links view"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#60622"
|
||||
msgid "Normal window"
|
||||
msgid "Pop-up window"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#60623"
|
||||
msgid "Pop-up window"
|
||||
msgstr ""
|
||||
msgid "Fullscreen window"
|
||||
msgstr "
|
||||
|
||||
msgctxt "#60624"
|
||||
msgid " Maximum number of links to display"
|
||||
|
||||
@@ -2604,13 +2604,13 @@ msgid "Links view"
|
||||
msgstr "Visualizzazione collegamenti"
|
||||
|
||||
msgctxt "#60622"
|
||||
msgid "Normal window"
|
||||
msgstr "Finestra normale"
|
||||
|
||||
msgctxt "#60623"
|
||||
msgid "Pop-up window"
|
||||
msgstr "Finestra pop-up"
|
||||
|
||||
msgctxt "#60623"
|
||||
msgid "Fullscreen window"
|
||||
msgstr "Finestra a schermo intero"
|
||||
|
||||
msgctxt "#60624"
|
||||
msgid " Maximum number of links to display"
|
||||
msgstr " Numero massimo di link da visualizzare"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<setting id="autoplay" type="bool" label="70562" default="false" visible="true"/>
|
||||
<setting id="servers_favorites" visible="true" type="action" label="60551" action="RunPlugin(plugin://plugin.video.kod/?ew0KICAgICJhY3Rpb24iOiAic2VydmVyc19mYXZvcml0ZXMiLA0KICAgICJjaGFubmVsIjogInNldHRpbmciDQp9==)"/>
|
||||
<setting id="servers_blacklist" visible="true" type="action" label="60550" action="RunPlugin(plugin://plugin.video.kod/?ew0KICAgICJhY3Rpb24iOiAic2VydmVyc19ibGFja2xpc3QiLA0KICAgICJjaGFubmVsIjogInNldHRpbmciDQp9==)"/>
|
||||
|
||||
<setting id="window_type" type="select" lvalues="60622|60623" label="60621" default="0"/>
|
||||
<!-- <setting id="hide_servers" type="bool" label="70747" default="false" visible="eq(-1,true)" subsetting="true"/> -->
|
||||
<setting id="checklinks" type="bool" label="30020" default="false"/>
|
||||
<setting id="checklinks_number" type="slider" option="int" range="5,5,20" label="30021" default="5" visible="eq(-1,true)" subsetting="true"/>
|
||||
@@ -92,6 +92,7 @@
|
||||
<setting id="tmdb_active" default="true" visible="false"/>
|
||||
<!-- <setting id="tmdb_threads" type="slider" option="int" range="5,5,30" label="70155" default="20"/>-->
|
||||
<setting id="tmdb_plus_info" type="bool" label="70156" default="false"/>
|
||||
<setting id="episode_info" type="bool" label="60292" default="false"/>
|
||||
<setting id="tmdb_cache" type="bool" label="70157" default="true"/>
|
||||
<setting id="tmdb_cache_expire" type="select" lvalues="70158|70159|70160|70161|70170" label="70162" enable="eq(-1,true)" default="4"/>
|
||||
<setting id="tmdb_clean_db_cache" type="action" label="70163" action="RunPlugin(plugin://plugin.video.kod/?ew0KICAgICJhY3Rpb24iOiAic2NyaXB0Ig0KfQ==)" />
|
||||
@@ -136,7 +137,7 @@
|
||||
<setting id="enable_library_menu" label="30131" type="bool" default="true"/>
|
||||
<setting label="30000" type="lsep"/>
|
||||
<setting id="touch_view" label='30002' type="bool" default="false"/>
|
||||
<setting id="viewchange_notify" label='70514' type="bool" default="true"/>
|
||||
<setting id="viewchange_notify" label='70514' type="bool" default="false"/>
|
||||
<!-- View Mode (hidden)-->
|
||||
<setting id="skin_name" label='Skin Name' type="text" default="skin.estuary" visible="false"/>
|
||||
<setting id="view_mode_home" type="action" label="70009" default= "Default, 0" visible="false"/>
|
||||
@@ -148,6 +149,7 @@
|
||||
<setting id="view_mode_season" type="action" label="30140" default= "Default, 0" visible="false"/>
|
||||
<setting id="view_mode_episode" type="action" label="70362" default= "Default, 0" visible="false"/>
|
||||
<setting id="view_mode_server" type="action" label="70145" default= "Default, 0" visible="false"/>
|
||||
<setting id="view_mode_musicvideo" type="action" label="70145" default= "Default, 0" visible="false"/>
|
||||
<!-- Contextual -->
|
||||
<setting label="30024" type="lsep"/>
|
||||
<setting id="quick_menu" type="bool" label="60360" default="true"/>
|
||||
|
||||
252
resources/skins/Default/720p/Servers.xml
Normal file
252
resources/skins/Default/720p/Servers.xml
Normal file
@@ -0,0 +1,252 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<window>
|
||||
<zorder>0.52</zorder>
|
||||
<coordinates>
|
||||
<left>0</left>
|
||||
<top>0</top>
|
||||
</coordinates>
|
||||
<controls>
|
||||
<control type="group">
|
||||
<description>Servers Group</description>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="fade" delay="160" end="100" time="200" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="fade" delay="300" start="100" end="0" time="200" />
|
||||
</animation>
|
||||
<control type="image">
|
||||
<description>Window Background</description>
|
||||
<width>100%</width>
|
||||
<height>100%</height>
|
||||
<texture colordiffuse="FF232323">white.png</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
<description>Fanart</description>
|
||||
<width>100%</width>
|
||||
<height>100%</height>
|
||||
<aspectratio>scale</aspectratio>
|
||||
<texture colordiffuse="FF555555">$INFO[Container(100).ListItem.Art(fanart)]</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
<description>Poster</description>
|
||||
<top>0</top>
|
||||
<left>0</left>
|
||||
<width>480</width>
|
||||
<height>720</height>
|
||||
<texture>$INFO[Container(100).ListItem.Art(poster)]</texture>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="slide" delay="160" start="-100,0" end="0,0" time="200" />
|
||||
<effect type="fade" delay="160" start="0" end="100" time="200" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,0" end="-100,0" time="200" />
|
||||
<effect type="fade" delay="160" start="100" end="0" time="200" />
|
||||
</animation>
|
||||
</control>
|
||||
<control type="textbox">
|
||||
<description>Main Title</description>
|
||||
<left>520</left>
|
||||
<top>40</top>
|
||||
<width>1150</width>
|
||||
<height>30</height>
|
||||
<font>font13</font>
|
||||
<textcolor>FFFFFFFF</textcolor>
|
||||
<shadowcolor>00000000</shadowcolor>
|
||||
<align>left</align>
|
||||
<aligny>center</aligny>
|
||||
<label>$INFO[Container(100).ListItem.Property(name)]</label>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,-70" end="0,0" time="200" />
|
||||
<effect type="fade" delay="160" start="0" end="100" time="200" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,0" end="0,-70" time="200" />
|
||||
<effect type="fade" delay="160" start="100" end="0" time="200" />
|
||||
</animation>
|
||||
</control>
|
||||
<control type="list" id="100">
|
||||
<description>Servers List</description>
|
||||
<bottom>40</bottom>
|
||||
<left>520</left>
|
||||
<width>700</width>
|
||||
<height>570</height>
|
||||
<onup>101</onup>
|
||||
<onleft>101</onleft>
|
||||
<onright>101</onright>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="slide" delay="160" start="100,0" end="0,0" time="200" />
|
||||
<effect type="fade" delay="160" start="0" end="100" time="200" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,0" end="100,0" time="200" />
|
||||
<effect type="fade" delay="160" start="100" end="0" time="200" />
|
||||
</animation>
|
||||
<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.Art(thumb)]</texture>
|
||||
<aspectratio>scale</aspectratio>
|
||||
</control>
|
||||
<control type="textbox">
|
||||
<description>Server Title</description>
|
||||
<left>150</left>
|
||||
<top>30</top>
|
||||
<width>450</width>
|
||||
<height>30</height>
|
||||
<font>font13</font>
|
||||
<textcolor>FFFFFFFF</textcolor>
|
||||
<shadowcolor>00000000</shadowcolor>
|
||||
<align>left</align>
|
||||
<aligny>center</aligny>
|
||||
<label>[B]$INFO[ListItem.Label][/B]</label>
|
||||
</control>
|
||||
<control type="textbox">
|
||||
<description>Channel</description>
|
||||
<left>150</left>
|
||||
<top>65</top>
|
||||
<width>450</width>
|
||||
<height>30</height>
|
||||
<font>font13</font>
|
||||
<textcolor>FFAAAAAA</textcolor>
|
||||
<shadowcolor>00000000</shadowcolor>
|
||||
<align>left</align>
|
||||
<aligny>center</aligny>
|
||||
<label>[B]$INFO[ListItem.Property(channel)][/B]</label>
|
||||
</control>
|
||||
</itemlayout>
|
||||
<focusedlayout height="140" width="700">
|
||||
<control type="image">
|
||||
<description>Selection Background</description>
|
||||
<width>700</width>
|
||||
<height>130</height>
|
||||
<texture colordiffuse="CCFFFFFF">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>
|
||||
<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.Art(thumb)]</texture>
|
||||
<aspectratio>scale</aspectratio>
|
||||
</control>
|
||||
<control type="textbox">
|
||||
<description>Server Title</description>
|
||||
<left>150</left>
|
||||
<top>30</top>
|
||||
<width>450</width>
|
||||
<height>30</height>
|
||||
<font>font13</font>
|
||||
<textcolor>FF232323</textcolor>
|
||||
<shadowcolor>00000000</shadowcolor>
|
||||
<align>left</align>
|
||||
<aligny>center</aligny>
|
||||
<label>[B]$INFO[ListItem.Label][/B]</label>
|
||||
</control>
|
||||
<control type="textbox">
|
||||
<description>Channel</description>
|
||||
<left>150</left>
|
||||
<top>65</top>
|
||||
<width>450</width>
|
||||
<height>30</height>
|
||||
<font>font13</font>
|
||||
<textcolor>FF555555</textcolor>
|
||||
<shadowcolor>00000000</shadowcolor>
|
||||
<align>left</align>
|
||||
<aligny>center</aligny>
|
||||
<label>[B]$INFO[ListItem.Property(channel)][/B]</label>
|
||||
</control>
|
||||
</focusedlayout>
|
||||
</control>
|
||||
<!-- END Servers List -->
|
||||
<control type="group">
|
||||
<top>30</top>
|
||||
<right>30</right>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,-70" end="0,0" time="200" />
|
||||
<effect type="fade" delay="160" start="0" end="100" time="200" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="slide" delay="160" start="0,0" end="0,-70" time="200" />
|
||||
<effect type="fade" delay="160" start="100" end="0" time="200" />
|
||||
</animation>
|
||||
<control type="button" id="101">
|
||||
<description>Close</description>
|
||||
<top>0</top>
|
||||
<right>0</right>
|
||||
<height>40</height>
|
||||
<width>40</width>
|
||||
<onup>100</onup>
|
||||
<ondown>100</ondown>
|
||||
<onleft condition="Control.IsVisible(102)">102</onleft>
|
||||
<onleft condition="Control.IsVisible(103)">103</onleft>
|
||||
<onleft>100</onleft>
|
||||
<onright>100</onright>
|
||||
<texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus>
|
||||
<texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus>
|
||||
<!-- <onclick>Action(close)</onclick> -->
|
||||
</control>
|
||||
<control type="button" id="102">
|
||||
<description>Menu</description>
|
||||
<top>0</top>
|
||||
<right>40</right>
|
||||
<height>40</height>
|
||||
<width>40</width>
|
||||
<onup>100</onup>
|
||||
<ondown>100</ondown>
|
||||
<onleft condition="Control.IsVisible(103)">103</onleft>
|
||||
<onleft condition="!Control.IsVisible(103) + Control.IsVisible(104)">104</onleft>
|
||||
<onleft>100</onleft>
|
||||
<onright>101</onright>
|
||||
<texturefocus colordiffuse="FFFFFFFF">menu.png</texturefocus>
|
||||
<texturenofocus colordiffuse="80FFFFFF">menu.png</texturenofocus>
|
||||
</control>
|
||||
<control type="button" id="103">
|
||||
<description>videolibrary</description>
|
||||
<top>0</top>
|
||||
<right>80</right>
|
||||
<height>40</height>
|
||||
<width>40</width>
|
||||
<onup>100</onup>
|
||||
<ondown>100</ondown>
|
||||
<onleft condition="Control.IsVisible(104)">104</onleft>
|
||||
<onleft condition="!Control.IsVisible(104)">100</onleft>
|
||||
<onright>102</onright>
|
||||
<texturefocus colordiffuse="FFFFFFFF">add.png</texturefocus>
|
||||
<texturenofocus colordiffuse="80FFFFFF">add.png</texturenofocus>
|
||||
</control>
|
||||
<control type="button" id="104">
|
||||
<description>Download</description>
|
||||
<top>0</top>
|
||||
<right>80</right>
|
||||
<animation effect="slide" end="-40,0" condition="Control.IsVisible(103)">Conditional</animation>
|
||||
<height>40</height>
|
||||
<width>40</width>
|
||||
<onup>100</onup>
|
||||
<ondown>100</ondown>
|
||||
<onleft>100</onleft>
|
||||
<onright condition="Control.IsVisible(103)">102</onright>
|
||||
<onright>102</onright>
|
||||
<texturefocus colordiffuse="FFFFFFFF">down.png</texturefocus>
|
||||
<texturenofocus colordiffuse="80FFFFFF">down.png</texturenofocus>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
<!-- END SERVERS GROUP -->
|
||||
</controls>
|
||||
</window>
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from core import httptools
|
||||
from core import httptools, support
|
||||
from platformcode import logger, config
|
||||
|
||||
|
||||
@@ -19,8 +19,13 @@ def test_video_exists(page_url):
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
video_urls = []
|
||||
data = response.json
|
||||
|
||||
url = data.get('qualities', {}).get('auto', [{}])[0].get('url','')
|
||||
|
||||
return [["m3u8 [dailymotion]", url]]
|
||||
urls = support.match(url, patron=r'NAME="([^"]+)"\s*,\s*PROGRESSIVE-URI="([^"]+)').matches
|
||||
for quality, uri in urls:
|
||||
video_urls.append(["mp4 [{}p] [dailymotion]".format(quality), uri])
|
||||
|
||||
return video_urls
|
||||
@@ -14,7 +14,7 @@ def test_video_exists(page_url):
|
||||
data = page.data.replace('"', "'")
|
||||
real_url = page.url
|
||||
|
||||
if "Not Found" in data or "File Does not Exist" in data:
|
||||
if "Not Found" in data or "File Does not Exist" in data or "File doesn't exits" in data:
|
||||
return False, config.get_localized_string(70449) % "DeltaBit"
|
||||
return True, ""
|
||||
|
||||
|
||||
@@ -10,6 +10,6 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.debug("(page_url='%s')" % page_url)
|
||||
|
||||
video_urls = [["%s %s" % (page_url[-4:], config.get_localized_string(30137)), page_url]]
|
||||
video_urls = [["%s %s" % (page_url.split('|')[0][-4:], config.get_localized_string(30137)), page_url]]
|
||||
|
||||
return video_urls
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "(rapidgator.net/file/\\w+(?:\\.html|))",
|
||||
"url": "http://\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": false,
|
||||
"id": "rapidgator",
|
||||
"name": "Rapid Gator",
|
||||
"premium": [
|
||||
"realdebrid",
|
||||
"alldebrid"
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "@70708",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.debug("(page_url='%s')" % page_url)
|
||||
video_urls = []
|
||||
return video_urls
|
||||
@@ -4,12 +4,12 @@
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "(?:streamsb|sbembed|sbembed1|sbplay1|sbplay|pelistop|tubesb|playersb|embedsb|watchsb).\\w{2,4}/(?:embed-|d/|e/)?([A-z0-9]+)",
|
||||
"url": "https://streamsb.net/\\1"
|
||||
"pattern": "(?:streamsb|sbembed|sbembed1|sbplay1|sbplay|pelistop|tubesb|playersb|embedsb|watchsb|streamas).\\w{2,5}/(?:embed-|d/|e/)?([A-z0-9]+)",
|
||||
"url": "https://streamsb.net/d/\\1"
|
||||
},
|
||||
{
|
||||
"pattern": "(?:cloudemb.com)/([A-z0-9]+)",
|
||||
"url": "https://streamsb.net/\\1"
|
||||
"url": "https://streamsb.net/d/\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
# https://github.com/tvaddonsco/script.module.urlresolver/blob/master/lib/urlresolver/plugins/streamsb.py
|
||||
|
||||
from core import httptools, scrapertools
|
||||
from platformcode import config, logger
|
||||
import time
|
||||
|
||||
host = 'streamsb.net'
|
||||
from platformcode import config
|
||||
import base64
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
@@ -21,8 +19,8 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
video_urls = []
|
||||
global data
|
||||
host = scrapertools.get_domain_from_url(page_url)
|
||||
sources = scrapertools.find_multiple_matches(data, r'download_video([^"]+)[^\d]+\d+x(\d+)')
|
||||
time.sleep(1)
|
||||
if sources:
|
||||
sources.sort(key=lambda x: int(x[1]), reverse=True)
|
||||
sources = [(x[1] + 'p', x[0]) for x in sources]
|
||||
@@ -30,9 +28,14 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
code, mode, hash = eval(s[1])
|
||||
dl_url = 'https://{0}/dl?op=download_orig&id={1}&mode={2}&hash={3}'.format(host, code, mode, hash)
|
||||
data = httptools.downloadpage(dl_url).data
|
||||
media_url = scrapertools.find_single_match(data, 'href="([^"]+)">Direct')
|
||||
if media_url:
|
||||
video_urls.append([s[0], media_url])
|
||||
|
||||
captcha = scrapertools.girc(data, 'https://{0}/'.format(host), base64.b64encode('https://{0}:443'.format(host).encode('utf-8')).decode('utf-8').replace('=', ''))
|
||||
if captcha:
|
||||
data = httptools.downloadpage(dl_url, post={'op': 'download_orig', 'id': code, 'mode': mode,
|
||||
'hash': hash, 'g-recaptcha-response': captcha}, timeout=10).data
|
||||
media_url = scrapertools.find_single_match(data, 'href="([^"]+)">Direct')
|
||||
if media_url:
|
||||
video_urls.append([s[0], media_url])
|
||||
return video_urls
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "(http:\\/\\/(?:[a-zA-Z0-9]+)\\.torrent)",
|
||||
"pattern": "(https?:\/\/\\S+.torrent)",
|
||||
"url": "\\1"
|
||||
},
|
||||
{
|
||||
@@ -49,7 +49,7 @@
|
||||
"url": "\\1"
|
||||
},
|
||||
{
|
||||
"pattern": "(http://tumejorjuego.com/descargar/index.php\\?link=[^\"]+)",
|
||||
"pattern": "(http[s]?://tumejorjuego.com/descargar/index.php\\?link=[^\"]+)",
|
||||
"url": "\\1"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -219,8 +219,11 @@ def find_file(hash):
|
||||
def elementum_actions(parameter, TorrentHash):
|
||||
elementum_setting, elementum_host, TorrentPath = setting()
|
||||
if elementum_setting:
|
||||
if parameter == 'delete': monitor_update(TorrentPath, TorrentHash, remove=True)
|
||||
requests.get('%s/%s/%s' %(elementum_host, parameter, TorrentHash))
|
||||
try:
|
||||
if parameter == 'delete': monitor_update(TorrentPath, TorrentHash, remove=True)
|
||||
requests.get('%s/%s/%s' %(elementum_host, parameter, TorrentHash))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def process_filename(filename, Title, ext=True):
|
||||
|
||||
@@ -30,7 +30,7 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
for url in matches:
|
||||
url = url+'|Referer='+page_url
|
||||
# url = url+'|Referer='+page_url
|
||||
video_urls.append(["[uqload]", url])
|
||||
|
||||
return video_urls
|
||||
|
||||
12
service.py
12
service.py
@@ -513,8 +513,8 @@ if __name__ == "__main__":
|
||||
# scan new info
|
||||
xbmc.executebuiltin('UpdateLibrary(video)')
|
||||
xbmc.executebuiltin('CleanLibrary(video)')
|
||||
while xbmc.getCondVisibility('Library.IsScanningVideo()'):
|
||||
xbmc.sleep(1000)
|
||||
# while xbmc.getCondVisibility('Library.IsScanningVideo()'):
|
||||
# xbmc.sleep(1000)
|
||||
|
||||
# check if the user has any connection problems
|
||||
from platformcode.checkhost import test_conn
|
||||
@@ -546,8 +546,12 @@ if __name__ == "__main__":
|
||||
logger.debug(threading.enumerate())
|
||||
break
|
||||
|
||||
if monitor.waitForAbort(1): # every second
|
||||
if monitor.waitForAbort(1): # every second
|
||||
logger.debug('KoD service EXIT')
|
||||
# db need to be closed when not used, it will cause freezes
|
||||
db.close()
|
||||
join_threads()
|
||||
logger.debug('Close Threads')
|
||||
db.close()
|
||||
logger.debug('Close DB')
|
||||
break
|
||||
logger.debug('KoD service STOPPED')
|
||||
@@ -238,7 +238,7 @@ def peliculas(item, json='', key='', itemlist=[]):
|
||||
itemlist += itlist
|
||||
|
||||
if item.sort:
|
||||
itemlist.sort(key=lambda x: x.title, reverse=False)
|
||||
itemlist.sort(key=lambda x: x.title.lower(), reverse=False)
|
||||
if Pagination and len(itemlist) >= Pagination:
|
||||
if inspect.stack()[1][3] != 'get_newest':
|
||||
item.title = support.typo(config.get_localized_string(30992), 'color kod bold')
|
||||
@@ -286,9 +286,9 @@ def get_seasons(item):
|
||||
'get_newest'] and defp and not item.disable_pagination:
|
||||
itemlist = pagination(item, itemlist)
|
||||
|
||||
if show_seasons:
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
# if show_seasons:
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
return itemlist
|
||||
|
||||
|
||||
@@ -393,6 +393,9 @@ def episodios(item, json='', key='', itemlist=[]):
|
||||
filterseason=str(season),
|
||||
path=item.path))
|
||||
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
|
||||
elif defp and inspect.stack()[1][3] not in ['get_seasons'] and not item.disable_pagination:
|
||||
if Pagination and len(itemlist) >= Pagination:
|
||||
if inspect.stack()[1][3] != 'get_newest':
|
||||
@@ -400,9 +403,10 @@ def episodios(item, json='', key='', itemlist=[]):
|
||||
item.page = pag + 1
|
||||
item.thumbnail = support.thumb()
|
||||
itemlist.append(item)
|
||||
if not show_seasons:
|
||||
|
||||
if inspect.stack()[1][3] not in ['get_seasons'] and not show_seasons:
|
||||
support.videolibrary(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
support.download(itemlist, item)
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
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 in ['all', 'person'] or elem.contentType in [self.item.mode, 'undefined'])]
|
||||
self.item.mode in ['all', 'person'] or elem.contentType in [self.item.type, 'undefined'])]
|
||||
self.moduleDict[channel] = module
|
||||
self.searchActions += action
|
||||
except:
|
||||
@@ -343,11 +343,11 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
for searchAction in self.getActions():
|
||||
if self.exit: break
|
||||
self.search_threads.append(executor.submit(self.get_channel_results, searchAction))
|
||||
# for res in futures.as_completed(self.search_threads):
|
||||
# if self.exit: break
|
||||
# if res.result():
|
||||
# channel, valid, results = res.result()
|
||||
# self.update(channel, valid, results)
|
||||
for res in futures.as_completed(self.search_threads):
|
||||
if self.exit: break
|
||||
if res.result():
|
||||
channel, valid, results = res.result()
|
||||
self.update(channel, valid, results)
|
||||
|
||||
# if results:
|
||||
# name = results[0].channel
|
||||
@@ -363,7 +363,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
self.count = len(self.searchActions)
|
||||
|
||||
def get_channel_results(self, searchAction):
|
||||
def search(text):
|
||||
def channel_search(text):
|
||||
valid = []
|
||||
other = []
|
||||
results = self.moduleDict[channel].search(searchAction, text)
|
||||
@@ -388,7 +388,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
other = []
|
||||
|
||||
try:
|
||||
results, valid, other = search(self.item.text)
|
||||
results, valid, other = channel_search(self.item.text)
|
||||
if self.exit: return
|
||||
|
||||
# if we are on movie search but no valid results is found, and there's a lot of results (more pages), try
|
||||
@@ -396,7 +396,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
if self.item.contentType == 'movie' and not valid and other and other[-1].nextPage \
|
||||
and self.item.infoLabels['year']:
|
||||
logger.debug('retring adding year on channel ' + channel)
|
||||
dummy, valid, dummy = search(self.item.text + " " + str(self.item.infoLabels['year']))
|
||||
dummy, valid, dummy = channel_search(self.item.text + " " + str(self.item.infoLabels['year']))
|
||||
|
||||
if self.exit: return
|
||||
# some channels may use original title
|
||||
@@ -404,17 +404,18 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
original = scrapertools.title_unify(self.item.infoLabels.get('originaltitle'))
|
||||
if self.item.text != original:
|
||||
logger.debug('retring with original title on channel ' + channel)
|
||||
dummy, valid, dummy = search(original)
|
||||
dummy, valid, dummy = channel_search(original)
|
||||
except:
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
if self.exit: return
|
||||
update_lock.acquire()
|
||||
# update_lock.acquire()
|
||||
self.count += 1
|
||||
# return channel, valid, other if other else results
|
||||
|
||||
return channel, valid, other if other else results
|
||||
self.update(channel, valid, other if other else results)
|
||||
update_lock.release()
|
||||
# update_lock.release()
|
||||
|
||||
def makeItem(self, url):
|
||||
item = Item().fromurl(url)
|
||||
@@ -676,7 +677,7 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
busy(False)
|
||||
return
|
||||
|
||||
if item.action in ['add_pelicula_to_library', 'add_serie_to_library','save_download']: # special items (add to videolibrary, download ecc.)
|
||||
if item.action:
|
||||
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item_url + ")")
|
||||
busy(False)
|
||||
return
|
||||
@@ -684,85 +685,32 @@ class SearchWindow(xbmcgui.WindowXML):
|
||||
try:
|
||||
self.channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel])
|
||||
self.itemsResult = getattr(self.channel, item.action)(item)
|
||||
if self.itemsResult and self.itemsResult[0].server:
|
||||
from platformcode.launcher import findvideos
|
||||
findvideos(self.item, self.itemsResult)
|
||||
return
|
||||
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', '']:
|
||||
self.episodes = self.itemsResult if self.itemsResult else []
|
||||
self.itemsResult = []
|
||||
ep = []
|
||||
for item in self.episodes:
|
||||
it = xbmcgui.ListItem(item.title)
|
||||
it.setProperty('item', item.tourl())
|
||||
ep.append(it)
|
||||
|
||||
if config.get_setting('checklinks') and not config.get_setting('autoplay'):
|
||||
self.itemsResult = servertools.check_list_links(self.itemsResult, config.get_setting('checklinks_number'))
|
||||
servers = self.itemsResult if self.itemsResult else []
|
||||
self.itemsResult = []
|
||||
uhd = []
|
||||
fhd = []
|
||||
hd = []
|
||||
sd = []
|
||||
unknown = []
|
||||
other = []
|
||||
for i, item in enumerate(servers):
|
||||
if item.server:
|
||||
it = self.makeItem(item.tourl())
|
||||
it.setProperty('index', str(i))
|
||||
if item.quality.lower() in ['4k', '2160p', '2160', '4k2160p', '4k2160', '4k 2160p', '4k 2160', '2k']:
|
||||
it.setProperty('quality', 'uhd.png')
|
||||
uhd.append(it)
|
||||
elif item.quality.lower() 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.lower() in ['hd', 'hd720', 'hd720p', 'hd 720', 'hd 720p', '720', '720p', 'hdtv']:
|
||||
it.setProperty('quality', 'hd.png')
|
||||
hd.append(it)
|
||||
elif item.quality.lower() 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)
|
||||
else:
|
||||
it = self.makeItem(item.tourl())
|
||||
other.append(it)
|
||||
if not ep:
|
||||
ep = [xbmcgui.ListItem(config.get_localized_string(60347))]
|
||||
ep[0].setProperty('thumb', channelselector.get_thumb('nofolder.png'))
|
||||
|
||||
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 + other
|
||||
if not serverlist:
|
||||
serverlist = [xbmcgui.ListItem(config.get_localized_string(60347))]
|
||||
serverlist[0].setProperty('thumb', channelselector.get_thumb('nofolder.png'))
|
||||
|
||||
self.Focus(SERVERS)
|
||||
self.SERVERLIST.reset()
|
||||
self.SERVERLIST.addItems(serverlist)
|
||||
self.setFocusId(SERVERLIST)
|
||||
|
||||
if config.get_setting('autoplay'):
|
||||
busy(False)
|
||||
|
||||
else:
|
||||
self.episodes = self.itemsResult if self.itemsResult else []
|
||||
self.itemsResult = []
|
||||
ep = []
|
||||
for item in self.episodes:
|
||||
it = xbmcgui.ListItem(item.title)
|
||||
it.setProperty('item', item.tourl())
|
||||
ep.append(it)
|
||||
|
||||
if not ep:
|
||||
ep = [xbmcgui.ListItem(config.get_localized_string(60347))]
|
||||
ep[0].setProperty('thumb', channelselector.get_thumb('nofolder.png'))
|
||||
|
||||
self.Focus(EPISODES)
|
||||
self.EPISODESLIST.reset()
|
||||
self.EPISODESLIST.addItems(ep)
|
||||
self.setFocusId(EPISODESLIST)
|
||||
self.Focus(EPISODES)
|
||||
self.EPISODESLIST.reset()
|
||||
self.EPISODESLIST.addItems(ep)
|
||||
self.setFocusId(EPISODESLIST)
|
||||
|
||||
busy(False)
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
# from builtins import str
|
||||
import sys
|
||||
|
||||
from lib import requests
|
||||
PY3 = False
|
||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||||
from builtins import object
|
||||
@@ -158,9 +160,9 @@ def addFavourite(item):
|
||||
return False
|
||||
|
||||
# If it is a movie / series, fill in tmdb information if tmdb_plus_info is not activated (for season / episode it is not necessary because the "second pass" will have already been done)
|
||||
if (item.contentType == 'movie' or item.contentType == 'tvshow') and not config.get_setting('tmdb_plus_info', default=False):
|
||||
from core import tmdb
|
||||
tmdb.set_infoLabels(item, True) # get more data in "second pass" (actors, duration, ...)
|
||||
# if (item.contentType == 'movie' or item.contentType == 'tvshow') and not config.get_setting('tmdb_plus_info', default=False):
|
||||
# from core import tmdb
|
||||
# tmdb.set_infoLabels(item, True) # get more data in "second pass" (actors, duration, ...)
|
||||
|
||||
# Add date saved
|
||||
item.date_added = fechahora_actual()
|
||||
@@ -224,6 +226,7 @@ def mostrar_perfil(item):
|
||||
for i_enlace, enlace in enumerate(alfav.user_favorites[i_perfil]['items']):
|
||||
|
||||
it = Item().fromurl(enlace)
|
||||
it.from_channel = 'kodfavorites'
|
||||
it.context = [ {'title': config.get_localized_string(70617), 'channel': item.channel, 'action': 'acciones_enlace',
|
||||
'i_enlace': i_enlace, 'i_perfil': i_perfil} ]
|
||||
|
||||
@@ -232,16 +235,20 @@ def mostrar_perfil(item):
|
||||
it.plot += '[CR]Url: ' + it.url if isinstance(it.url, str) else '...'
|
||||
if it.date_added != '': it.plot += '[CR]' + config.get_localized_string(70469) + ': ' + it.date_added
|
||||
|
||||
if it.server:
|
||||
it.thumbnail = it.contentThumbnail
|
||||
it.title += ' [{}]'.format(it.serverName)
|
||||
|
||||
# If it is not a url, nor does it have the system path, convert the path since it will have been copied from another device.
|
||||
# It would be more optimal if the conversion was done with an import menu, but at the moment it is controlled in run-time.
|
||||
if it.thumbnail and '://' not in it.thumbnail and not it.thumbnail.startswith(ruta_runtime):
|
||||
ruta, fichero = filetools.split(it.thumbnail)
|
||||
if ruta == '' and fichero == it.thumbnail: # in linux the split with a windows path does not separate correctly
|
||||
ruta, fichero = filetools.split(it.thumbnail.replace('\\','/'))
|
||||
if 'channels' in ruta and 'thumb' in ruta:
|
||||
it.thumbnail = filetools.join(ruta_runtime, 'resources', 'media', 'channels', 'thumb', fichero)
|
||||
elif 'themes' in ruta and 'default' in ruta:
|
||||
it.thumbnail = filetools.join(ruta_runtime, 'resources', 'media', 'themes', 'default', fichero)
|
||||
# if it.thumbnail and '://' not in it.thumbnail and not it.thumbnail.startswith(ruta_runtime):
|
||||
# ruta, fichero = filetools.split(it.thumbnail)
|
||||
# if ruta == '' and fichero == it.thumbnail: # in linux the split with a windows path does not separate correctly
|
||||
# ruta, fichero = filetools.split(it.thumbnail.replace('\\','/'))
|
||||
# if 'channels' in ruta and 'thumb' in ruta:
|
||||
# it.thumbnail = filetools.join(ruta_runtime, 'resources', 'media', 'channels', 'thumb', fichero)
|
||||
# elif 'themes' in ruta and 'default' in ruta:
|
||||
# it.thumbnail = filetools.join(ruta_runtime, 'resources', 'media', 'themes', 'default', fichero)
|
||||
|
||||
itemlist.append(it)
|
||||
|
||||
@@ -420,37 +427,30 @@ def editar_enlace_thumbnail(item):
|
||||
# Dialog to choose thumbnail (the channel or predefined icons)
|
||||
opciones = []
|
||||
ids = []
|
||||
try:
|
||||
from core import channeltools
|
||||
channel_parameters = channeltools.get_channel_parameters(it.channel)
|
||||
if channel_parameters['thumbnail'] != '':
|
||||
nombre = 'Canal %s' % it.channel
|
||||
if is_kodi17:
|
||||
it_thumb = xbmcgui.ListItem(nombre)
|
||||
it_thumb.setArt({ 'thumb': channel_parameters['thumbnail'] })
|
||||
opciones.append(it_thumb)
|
||||
else:
|
||||
opciones.append(nombre)
|
||||
ids.append(channel_parameters['thumbnail'])
|
||||
except:
|
||||
pass
|
||||
# try:
|
||||
# from core import channeltools
|
||||
# channel_parameters = channeltools.get_channel_parameters(it.channel)
|
||||
# if channel_parameters['thumbnail'] != '':
|
||||
# nombre = 'Channel %s' % it.channel
|
||||
# if is_kodi17:
|
||||
# it_thumb = xbmcgui.ListItem(nombre)
|
||||
# it_thumb.setArt({ 'thumb': channel_parameters['thumbnail'] })
|
||||
# opciones.append(it_thumb)
|
||||
# else:
|
||||
# opciones.append(nombre)
|
||||
# ids.append(channel_parameters['thumbnail'])
|
||||
# except:
|
||||
# pass
|
||||
|
||||
resource_path = os.path.join(config.get_runtime_path(), 'resources', 'media', 'themes', 'default')
|
||||
for f in sorted(os.listdir(resource_path)):
|
||||
if f.startswith('thumb_') and not f.startswith('thumb_intervenido') and f != 'thumb_back.png':
|
||||
nombre = f.replace('thumb_', '').replace('_', ' ').replace('.png', '')
|
||||
if is_kodi17:
|
||||
it_thumb = xbmcgui.ListItem(nombre)
|
||||
it_thumb.setArt({ 'thumb': os.path.join(resource_path, f) })
|
||||
opciones.append(it_thumb)
|
||||
else:
|
||||
opciones.append(nombre)
|
||||
ids.append(os.path.join(resource_path, f))
|
||||
resource_path = 'https://api.github.com/repos/kodiondemand/media/git/trees/b36040432b9be120f04e986277fd34f09dcdb4db'
|
||||
for f in sorted(requests.get(resource_path).json().get('tree', []), key=lambda p: p.get('path')):
|
||||
nombre = f['path'].replace('thumb_', '').replace('.png', '')
|
||||
it_thumb = xbmcgui.ListItem(nombre)
|
||||
it_thumb.setArt({ 'thumb': support.thumb(nombre)})
|
||||
opciones.append(it_thumb)
|
||||
ids.append(support.thumb(nombre))
|
||||
|
||||
if is_kodi17:
|
||||
ret = xbmcgui.Dialog().select(config.get_localized_string(70554), opciones, useDetails=True)
|
||||
else:
|
||||
ret = platformtools.dialog_select(config.get_localized_string(70554), opciones)
|
||||
ret = xbmcgui.Dialog().select(config.get_localized_string(70554), opciones, useDetails=True)
|
||||
|
||||
if ret == -1: return False # order cancel
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ def mainlist(item):
|
||||
if platformtools.get_window() not in ('WINDOW_SETTINGS_MENU', 'WINDOW_SETTINGS_INTERFACE', 'WINDOW_SKIN_SETTINGS')\
|
||||
and xbmc.getInfoLabel('System.CurrentWindow') in ('Home', '') and config.get_setting('new_search'):
|
||||
itemlist = [Item(channel='globalsearch', title=config.get_localized_string(70276), action='Search', mode='all', thumbnail=get_thumb("search.png"), folder=False),
|
||||
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30122), action='Search', mode='movie', thumbnail=get_thumb("search_movie.png"),folder=False),
|
||||
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30123), action='Search', mode='tvshow', thumbnail=get_thumb("search_tvshow.png"), folder=False),
|
||||
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30122), action='Search', mode='movie', type='movie', thumbnail=get_thumb("search_movie.png"),folder=False),
|
||||
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30123), action='Search', mode='tvshow', type='tvshow',thumbnail=get_thumb("search_tvshow.png"), folder=False),
|
||||
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(70314), action='Search', page=1, mode='person', thumbnail=get_thumb("search_star.png"), folder=False)]
|
||||
else:
|
||||
itemlist = [Item(channel=item.channel, title=config.get_localized_string(70276), action='new_search', mode='all', thumbnail=get_thumb("search.png")),
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
"type": "list",
|
||||
"label": "@60618",
|
||||
"default": 0,
|
||||
"visible": false,
|
||||
"enabled": "!eq(-4,@60615)",
|
||||
"lvalues": [
|
||||
"@60619",
|
||||
@@ -110,7 +111,7 @@
|
||||
"label": "@60653",
|
||||
"default": true,
|
||||
"enabled": "eq(-1,TVDB)",
|
||||
"visible": true
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"id": "info_language",
|
||||
@@ -127,18 +128,6 @@
|
||||
"pt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "window_type",
|
||||
"type": "list",
|
||||
"label": "@60621",
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": [
|
||||
"@60622",
|
||||
"@60623"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "max_links",
|
||||
"type": "list",
|
||||
@@ -162,7 +151,7 @@
|
||||
"type": "bool",
|
||||
"label": "@60626",
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"visible": false,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -170,7 +159,7 @@
|
||||
"type": "bool",
|
||||
"label": "@60627",
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"visible": false,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -178,7 +167,7 @@
|
||||
"type": "bool",
|
||||
"label": "@60628",
|
||||
"enabled": "eq(-4,@60623)",
|
||||
"visible": true,
|
||||
"visible": false,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -223,7 +212,7 @@
|
||||
"type": "bool",
|
||||
"label": "@60638",
|
||||
"default": false,
|
||||
"visible": true,
|
||||
"visible": false,
|
||||
"enabled": "eq(-3,true)"
|
||||
},
|
||||
{
|
||||
@@ -231,7 +220,7 @@
|
||||
"type": "bool",
|
||||
"label": "@60639",
|
||||
"default": true,
|
||||
"visible": true,
|
||||
"visible": false,
|
||||
"enabled": "eq(-1,true)"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,12 +16,11 @@ def http_Resp(lst_urls):
|
||||
s = httplib2.Http()
|
||||
code, resp = s.request(sito, body=None)
|
||||
if code.previous:
|
||||
print("r1 http_Resp: %s %s %s %s" %
|
||||
(code.status, code.reason, code.previous['status'],
|
||||
code.previous['-x-permanent-redirect-url']))
|
||||
rslt['code'] = code.previous['status']
|
||||
rslt['redirect'] = code.previous['-x-permanent-redirect-url']
|
||||
rslt['redirect'] = code.get('content-location', sito)
|
||||
rslt['status'] = code.status
|
||||
print("r1 http_Resp: %s %s %s %s" %
|
||||
(code.status, code.reason, rslt['code'], rslt['redirect']))
|
||||
else:
|
||||
rslt['code'] = code.status
|
||||
except httplib2.ServerNotFoundError as msg:
|
||||
@@ -32,6 +31,7 @@ def http_Resp(lst_urls):
|
||||
# [Errno 111] Connection refused
|
||||
rslt['code'] = 111
|
||||
except:
|
||||
print()
|
||||
rslt['code'] = 'Connection error'
|
||||
return rslt
|
||||
|
||||
@@ -50,6 +50,8 @@ if __name__ == '__main__':
|
||||
print(chann + ' not exists anymore')
|
||||
del data[k][chann]
|
||||
continue
|
||||
if k == 'findhost':
|
||||
continue
|
||||
# to get an idea of the timing
|
||||
# useful only if you control all channels
|
||||
# for channels with error 522 about 40 seconds are lost ...
|
||||
|
||||
Reference in New Issue
Block a user