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:
marco
2022-02-12 12:54:50 +01:00
parent fa99565e9f
commit 41e0823f62
86 changed files with 1660 additions and 3471 deletions

View File

@@ -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>

View File

@@ -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"
}
}

View 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": []
}

View 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)

View File

@@ -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" :[]
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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": []
}

View File

@@ -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)

View File

@@ -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")

View File

@@ -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>.+?)(?: &#8211; 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:

View File

@@ -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)

View File

@@ -1,10 +0,0 @@
{
"id": "dsda",
"name": "D.S.D.A",
"language": ["ita"],
"active": false,
"thumbnail": "dsda.png",
"banner": "dsda.png",
"categories": ["documentary"],
"settings": []
}

View File

@@ -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)

View File

@@ -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": []
}

View File

@@ -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+&#215;\d+|\d+×\d+)|\[[sS](?P<season>[0-9]+)[^]]+\])\s?(?:(?P<lang>\([a-zA-Z\s]+\)) (?:[Ss]\d+[Ee]\d+)?\s?(?:[&#\d;|.{3}]+)(?P<title2>[^”[<]+)(?:&#\d)?)?'
else:
# è una singola pagina con tutti gli episodi
if item.args != 'update' and not support.scrapertools.find_single_match(item.url, '-[0-9]+x[0-9]+-'):
return episodios_args(item)
patron = r'<div class="featured-thumb"> +<a href="(?P<url>[^"]+)" title="(?P<title>[^[]+)\[(?P<episode>\d+&#215;\d+)?'
patronBlock = r'<main id="main"[^>]+>(?P<block>.*?)<div id="secondary'
# def itemlistHook(itemlist):
# from core import scraper
# return scraper.sort_episode_list(itemlist)
patronNext = '<a class="next page-numbers" href="(.*?)">Successivi'
# debug = True
return locals()
def episodios_args(item):
actLike = 'episodios'
# support.dbg()
deflang = 'Sub-ITA'
action = 'findvideos'
patron = '(?P<episode>\d+&#215;\d+|\d+[×.]+\d+)(?:\s?\((?P<lang>[a-zA-Z ]+)\))?(?:\s[Ss]\d+[Ee]+\d+)? +(?:“|&#8220;)(?P<title2>.*?)(?:”|&#8221;).*?(?P<other>.*?)(?:/>|<p)'
patronBlock = r'<main id="main" class="site-main" role="main">(?P<block>.*?)</main>'
patronNext = '<a class="next page-numbers" href="(.*?)">Successivi'
# debug = True
return locals()
@support.scrape
def episodios(item):
support.info(item)
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

View File

@@ -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": []
}

View File

@@ -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()

View File

@@ -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
}
]
}

View File

@@ -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)

View File

@@ -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()

View File

@@ -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>[^<]+))?'

View File

@@ -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)

View File

@@ -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"],

View File

@@ -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):

View File

@@ -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="([^"]+)">(?:&raquo|»)'
typeContentDict = {'': 'music'}
def itemHook(item):
item.contentType = 'music'
item.thumbnail = item.thumbnail.replace('https:','http:')
return item
return locals()

View File

@@ -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": []
}

View File

@@ -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()

View File

@@ -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]

View File

@@ -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&{}'

View File

@@ -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": []
}

View File

@@ -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)

View File

@@ -1,10 +0,0 @@
{
"id": "pufimovies",
"name": "PufiMovies",
"active": false,
"language": ["ita", "sub-ita"],
"thumbnail": "pufimovies.png",
"banner": "pufimovies.png",
"categories": ["movie","tvshow"],
"settings": []
}

View File

@@ -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="([^"]+)"[^>]+>&raquo;'
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)

View File

@@ -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'

View File

@@ -1,11 +0,0 @@
{
"id": "seriehd",
"name": "SerieHD",
"active": false,
"language": ["ita"],
"thumbnail": "seriehd.png",
"banner": "seriehd.png",
"categories": ["tvshow"],
"settings": [],
"cloudflare": true
}

View File

@@ -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('&amp;', '&')
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]

View File

@@ -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": []
}

View File

@@ -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>[^"]+)"(?:|.+?)?>(?:&nbsp;&nbsp;)?[ ]?(?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

View File

@@ -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"]
}
]
}

View File

@@ -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
# ================================================================================================================

View File

@@ -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": []
}

View File

@@ -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)

View File

@@ -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('&quot;','"'))
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('&quot;','"').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')]

View File

@@ -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>[^<]+)<'

View File

@@ -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:

View File

@@ -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": []
}

View File

@@ -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)

View File

@@ -1,10 +0,0 @@
{
"id": "vedohd",
"name": "VedoHD",
"language": ["ita"],
"active": false,
"thumbnail": "vedohd.png",
"banner": "vedohd.png",
"categories": ["movie"],
"settings": []
}

View File

@@ -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 &#x25b6; TROVA L&#8217;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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ''

View File

@@ -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:

View File

@@ -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": "laudio è stato registrato tramite jack collegato alla macchina da presa, pertanto di discreta qualità.",
"DD": "audio ricavato dai dischi DTS cinema. Laudio è 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)

View File

@@ -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'):

View File

@@ -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)

View File

@@ -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()]

View File

@@ -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

View File

@@ -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')

View File

@@ -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)

View File

@@ -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()

View File

@@ -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):
"""

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"/>

View 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>

View File

@@ -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

View File

@@ -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, ""

View File

@@ -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

View File

@@ -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
}
]
}

View File

@@ -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

View File

@@ -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"
}
]
},

View File

@@ -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

View File

@@ -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"
}
]

View File

@@ -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):

View File

@@ -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

View File

@@ -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')

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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")),

View File

@@ -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)"
},
{

View File

@@ -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 ...