KoD 0.7.1
- A grande richiesta, è ora possibile riprodurre in automatico l'episodio successivo di una serie in libreria - aggiunta la possibilità di nascondere la lista dei server, quando si usa l'autoplay - aggiunto canale pufimovies.com - fix vari
@@ -1,6 +1,7 @@
|
||||
# Kodi On Demand
|
||||
### Un fork italiano di [Alfa](https://github.com/alfa-addon)
|
||||
Ognuno è libero (anzi, invitato!) a collaborare, per farlo è possibile utilizzare i pull request.
|
||||
KOD funziona con Kodi fino alla versione 18 (Python 2).
|
||||
|
||||
KOD, come Alfa, è sotto licenza GPL v3, pertanto siete liberi di utilizzare parte del codice, a patto di rispettare i termini di suddetta licenza, che si possono riassumere in:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" provider-name="KOD Team" version="0.7">
|
||||
<addon id="plugin.video.kod" name="Kodi on Demand" provider-name="KOD Team" version="0.7.1">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
<import addon="script.module.libtorrent" optional="true"/>
|
||||
@@ -19,9 +19,10 @@
|
||||
<screenshot>resources/media/themes/ss/2.png</screenshot>
|
||||
<screenshot>resources/media/themes/ss/3.png</screenshot>
|
||||
</assets>
|
||||
<news>- nuovo metodo di override DNS
|
||||
- aggiunta opzione nascondi server, se usi l'autoplay
|
||||
- migliorie al codice e fix vari</news>
|
||||
<news>- A grande richiesta, è ora possibile riprodurre in automatico l'episodio successivo di una serie in libreria
|
||||
- aggiunta la possibilità di nascondere la lista dei server, quando si usa l'autoplay
|
||||
- aggiunto canale pufimovies.com
|
||||
- fix vari</news>
|
||||
<description lang="it">Naviga velocemente sul web e guarda i contenuti presenti</description>
|
||||
<disclaimer>[COLOR red]The owners and submitters to this addon do not host or distribute any of the content displayed by these addons nor do they have any affiliation with the content providers.[/COLOR]
|
||||
[COLOR yellow]Kodi © is a registered trademark of the XBMC Foundation. We are not connected to or in any other way affiliated with Kodi, Team Kodi, or the XBMC Foundation. Furthermore, any software, addons, or products offered by us will receive no support in official Kodi channels, including the Kodi forums and various social networks.[/COLOR]</disclaimer>
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
"altadefinizione01": "https://www.altadefinizione01.tel",
|
||||
"altadefinizione01_link": "https://altadefinizione01.cam",
|
||||
"animeforce": "https://ww1.animeforce.org",
|
||||
"animeleggendari": "https://animepertutti.com",
|
||||
"animeleggendari": "https://animepertutti.com",
|
||||
"animesaturn": "https://animesaturn.com",
|
||||
"animestream": "https://www.animeworld.it",
|
||||
"animesubita": "http://www.animesubita.org",
|
||||
"animetubeita": "http://www.animetubeita.com",
|
||||
"animeworld": "https://www1.animeworld.tv",
|
||||
"casacinema": "https://www.casacinema.cloud",
|
||||
"animeworld": "https://www.animeworld.cc",
|
||||
"animeunity": "https://www.animeunity.it",
|
||||
"casacinema": "https://www.casacinema.biz",
|
||||
"casacinemaInfo": "https://casacinema.kim",
|
||||
"cb01anime": "https://www.cineblog01.ink",
|
||||
"cinemalibero": "https://www.cinemalibero.live",
|
||||
"cb01anime": "https://www.cineblog01.ink",
|
||||
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
|
||||
"documentaristreamingda": "https://documentari-streaming-da.com",
|
||||
"dreamsub": "https://www.dreamsub.stream",
|
||||
"dreamsub": "https://dreamsub.stream",
|
||||
"fastsubita": "https://fastsubita.com",
|
||||
"filmgratis": "https://www.filmaltadefinizione.org",
|
||||
"filmigratis": "https://filmigratis.org",
|
||||
@@ -26,9 +27,10 @@
|
||||
"ilgeniodellostreaming": "https://igds.one",
|
||||
"italiaserie": "https://italiaserie.org",
|
||||
"mondoserietv": "https://mondoserietv.com",
|
||||
"netfreex": "https://www.netfreex.online",
|
||||
"netfreex": "https://www.netfreex.icu",
|
||||
"piratestreaming": "https://www.piratestreaming.gratis",
|
||||
"polpotv": "https://polpo.tv",
|
||||
"pufimovies": "https://pufimovies.com",
|
||||
"seriehd": "https://www.seriehd.watch",
|
||||
"serietvonline": "https://serietvonline.monster",
|
||||
"serietvsubita": "http://serietvsubita.xyz",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"language": ["ita", "sub-ita"],
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"thumbnail": "https://raw.githubusercontent.com/Zanzibar82/images/master/posters/altadefinizione01.png",
|
||||
"banner": "https://raw.githubusercontent.com/Zanzibar82/images/master/posters/altadefinizione01.png",
|
||||
"thumbnail": "altadefinizione01.png",
|
||||
"banner": "altadefinizione01.png",
|
||||
"categories": ["movie", "vos"],
|
||||
"settings": []
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ def findhost():
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
list_servers = ['verystream','openload','rapidvideo','streamango']
|
||||
list_servers = ['mixdrop','vidoza','cloudvideo','vup','supervideo','gounlimited']
|
||||
list_quality = ['default']
|
||||
|
||||
@support.menu
|
||||
|
||||
@@ -26,7 +26,7 @@ __channel__ = "altadefinizione01_link"
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
list_servers = ['supervideo', 'streamcherry','rapidvideo', 'streamango', 'openload']
|
||||
list_servers = ['mixdrop', 'vup', 'supervideo']
|
||||
list_quality = ['default']
|
||||
|
||||
# =========== home menu ===================
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": ["ita","sub-ita"],
|
||||
"thumbnail": "https:\/\/raw.githubusercontent.com\/Zanzibar82\/images\/master\/posters\/altadefinizioneclick.png",
|
||||
"bannermenu": "https:\/\/raw.githubusercontent.com\/Zanzibar82\/images\/master\/posters\/altadefinizioneciclk.png",
|
||||
"thumbnail": "altadefinizioneclick.png",
|
||||
"bannermenu": "altadefinizioneciclk.png",
|
||||
"categories": ["movie","vos"],
|
||||
"settings": []
|
||||
}
|
||||
|
||||
@@ -28,9 +28,8 @@ def findhost():
|
||||
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
list_servers = ['verystream', 'rapidvideo', 'openload', 'streamango', 'vidoza',
|
||||
'vidcloud', 'thevideo', 'okru', 'hdload', 'youtube']
|
||||
list_quality = ['1080p', '720', '360']
|
||||
list_servers = ['mixdrop', 'vidcloud', 'vidoza', 'supervideo', 'hdload', 'mystream']
|
||||
list_quality = ['1080p', '720p', '360p']
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
# Canale per AnimeForce
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from servers.decrypters import adfly
|
||||
from core import support
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
|
||||
IDIOMAS = {'Italiano': 'IT'}
|
||||
list_language = IDIOMAS.values()
|
||||
list_servers = ['directo', 'openload', 'vvvvid']
|
||||
list_servers = ['directo', 'vvvvid']
|
||||
list_quality = ['default']
|
||||
|
||||
|
||||
@@ -45,47 +42,40 @@ def newest(categoria):
|
||||
|
||||
return itemlist
|
||||
|
||||
@support.scrape
|
||||
def search(item, texto):
|
||||
# debug = True
|
||||
search = texto
|
||||
support.log(texto)
|
||||
item.args = 'noorder'
|
||||
item.url = host + '/?s=' + texto + '&cat=6010'
|
||||
item.contentType = 'tvshow'
|
||||
patron = r'<a href="(?P<url>[^"]+)">\s*<strong[^>]+>(?P<title>[^<]+)<'
|
||||
action = 'episodios'
|
||||
return locals()
|
||||
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 peliculas(item):
|
||||
anime = True
|
||||
action = 'episodios'
|
||||
|
||||
if item.args == 'newest':
|
||||
patron = r'<a href="(?P<url>[^"]+)">\s*<img src="(?P<thumb>[^"]+)" alt="(?P<title>.*?)(?: Sub| sub| SUB|")'
|
||||
action = 'findvideos'
|
||||
|
||||
elif item.args == 'last':
|
||||
patron = r'<a href="(?P<url>[^"]+)">\s*<img src="(?P<thumb>[^"]+)" alt="(?P<title>.*?)(?: Sub| sub| SUB|")'
|
||||
|
||||
if not item.args:
|
||||
pagination = ''
|
||||
patron = r'<a\s*href="(?P<url>[^"]+)"\s*title="(?P<title>[^"]+)">'
|
||||
elif item.args == 'corso':
|
||||
pagination = ''
|
||||
patron = r'<strong><a href="(?P<url>[^"]+)">(?P<title>.*?) [Ss][Uu][Bb]'
|
||||
else:
|
||||
pagination = ''
|
||||
patron = r'<a href="(?P<url>[^"]+)">\s*<strong[^>]+>(?P<title>[^<]+)<'
|
||||
patron = r'<a href="(?P<url>[^"]+)"[^>]+>\s*<img src="(?P<thumb>[^"]+)" alt="(?P<title>.*?)(?: Sub| sub| SUB|")'
|
||||
|
||||
if item.args == 'newest': item.action = 'findvideos'
|
||||
|
||||
def itemHook(item):
|
||||
if 'sub-ita' in item.url:
|
||||
if item.args != 'newest': item.title = item.title + support.typo('Sub-ITA','_ [] color kod')
|
||||
item.contentLanguage = 'Sub-ITA'
|
||||
if item.args == 'newest':
|
||||
url = support.match(item, '<a href="([^"]+)" title="[^"]+" target="[^"]+" class="btn', headers=headers)[0]
|
||||
item.url = url[0] if url else ''
|
||||
delete = support.scrapertools.find_single_match(item.fulltitle, r'( Episodi.*)')
|
||||
episode = support.scrapertools.find_single_match(item.title, r'Episodi(?:o)? (?:\d+÷)?(\d+)')
|
||||
item.title = support.typo(episode + ' - ','bold') + item.title.replace(delete,'')
|
||||
item.fulltitle = item.show = item.title.replace(delete,'')
|
||||
item.episode = episode
|
||||
return item
|
||||
|
||||
return locals()
|
||||
@@ -94,9 +84,15 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
anime = True
|
||||
patron = r'<td style[^>]+>\s*.*?(?:<span[^>]+)?<strong>(?P<title>[^<]+)<\/strong>.*?<td style[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>'
|
||||
data = support.match(item, headers=headers).data
|
||||
if '<h6>Streaming</h6>' in data:
|
||||
patron = r'<td style[^>]+>\s*.*?(?:<span[^>]+)?<strong>(?P<title>[^<]+)<\/strong>.*?<td style[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>'
|
||||
else:
|
||||
patron = r'<a\s*href="(?P<url>[^"]+)"\s*title="(?P<title>[^"]+)"\s*class="btn btn-dark mb-1">'
|
||||
def itemHook(item):
|
||||
item.url = item.url.replace(host, '')
|
||||
support.log(item)
|
||||
if item.url.startswith('//'): item.url= 'https:' + item.url
|
||||
elif item.url.startswith('/'): item.url= 'https:/' + item.url
|
||||
return item
|
||||
action = 'findvideos'
|
||||
return locals()
|
||||
@@ -104,38 +100,81 @@ def episodios(item):
|
||||
|
||||
def findvideos(item):
|
||||
support.log(item)
|
||||
|
||||
# try:
|
||||
# from urlparse import urljoin
|
||||
# except:
|
||||
# from urllib.parse import urljoin
|
||||
# support.dbg()
|
||||
itemlist = []
|
||||
|
||||
if item.episode:
|
||||
from lib import unshortenit
|
||||
url, c = unshortenit.unshorten(item.url)
|
||||
url = support.match(item, r'<a href="([^"]+)"[^>]*>', patronBlock=r'Episodio %s(.*?)</tr>' % item.episode ,url=url)[0]
|
||||
item.url = url[0] if url else ''
|
||||
|
||||
if 'vvvvid' in item.url:
|
||||
item.action = 'play'
|
||||
itemlist.append(item)
|
||||
import requests
|
||||
from lib import vvvvid_decoder
|
||||
|
||||
if support.match(item.url, string=True, patron=r'(\d+/\d+)').match:
|
||||
item.action = 'play'
|
||||
itemlist.append(item)
|
||||
else:
|
||||
# VVVVID vars
|
||||
vvvvid_host = 'https://www.vvvvid.it/vvvvid/ondemand/'
|
||||
vvvvid_headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0'}
|
||||
|
||||
if 'http' not in item.url:
|
||||
if '//' in item.url[:2]:
|
||||
item.url = 'http:' + item.url
|
||||
elif host not in item.url:
|
||||
item.url = host + item.url
|
||||
# VVVVID session
|
||||
current_session = requests.Session()
|
||||
login_page = 'https://www.vvvvid.it/user/login'
|
||||
conn_id = current_session.get(login_page, headers=vvvvid_headers).json()['data']['conn_id']
|
||||
payload = {'conn_id': conn_id}
|
||||
|
||||
|
||||
# collect parameters
|
||||
show_id = support.match(item.url, string=True, patron=r'(\d+)').match
|
||||
ep_number = support.match(item.title, patron=r'(\d+)').match
|
||||
json_file = current_session.get(vvvvid_host + show_id + '/seasons/', headers=vvvvid_headers, params=payload).json()
|
||||
season_id = str(json_file['data'][0]['season_id'])
|
||||
json_file = current_session.get(vvvvid_host + show_id + '/season/' + season_id +'/', headers=vvvvid_headers, params=payload).json()
|
||||
|
||||
# select the correct episode
|
||||
for episode in json_file['data']:
|
||||
support.log('Number',int(episode['number']),int(ep_number))
|
||||
if int(episode['number']) == int(ep_number):
|
||||
url = vvvvid_decoder.dec_ei(episode['embed_info'] or episode['embed_info'])
|
||||
if 'youtube' in url: item.url = url
|
||||
item.url = url.replace('manifest.f4m','master.m3u8').replace('http://','https://').replace('/z/','/i/')
|
||||
if 'https' not in item.url:
|
||||
url = support.match(item, url='https://or01.top-ix.org/videomg/_definst_/mp4:' + item.url + '/playlist.m3u')[1]
|
||||
url = url.split()[-1]
|
||||
itemlist.append(
|
||||
support.Item(action= 'play',
|
||||
url= 'https://or01.top-ix.org/videomg/_definst_/mp4:' + item.url + '/' + url,
|
||||
server= 'directo'))
|
||||
|
||||
elif 'adf.ly' in item.url:
|
||||
from servers.decrypters import adfly
|
||||
url = adfly.get_long_url(item.url)
|
||||
|
||||
if 'adf.ly' in item.url:
|
||||
item.url = adfly.get_long_url(item.url)
|
||||
elif 'bit.ly' in item.url:
|
||||
item.url = support.httptools.downloadpage(item.url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
url = support.httptools.downloadpage(item.url, only_headers=True, follow_redirects=False).headers.get("location")
|
||||
|
||||
else:
|
||||
url = host
|
||||
for u in item.url.split('/'):
|
||||
# support.log(i)
|
||||
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:
|
||||
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
|
||||
|
||||
matches = support.match(item, r'button"><a href="([^"]+)"')[0]
|
||||
|
||||
for video in matches:
|
||||
itemlist.append(
|
||||
support.Item(channel=item.channel,
|
||||
action="play",
|
||||
title='diretto',
|
||||
url=video,
|
||||
title='Diretto',
|
||||
url=url,
|
||||
server='directo'))
|
||||
|
||||
return support.server(item, itemlist=itemlist)
|
||||
|
||||
@@ -74,10 +74,10 @@ def peliculas(item):
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
data = support.match(item, headers=headers)[1]
|
||||
if not any(x in data for x in ['Lista Episodi', 'Movie Parte']):
|
||||
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.log('NOT IN DATA')
|
||||
patron = r'(?:iframe src|str)="(?P<url>[^"]+)"'
|
||||
patron = r'<iframe.*?src="(?P<url>[^"]+)"'
|
||||
title = item.title
|
||||
def fullItemlistHook(itemlist):
|
||||
url = ''
|
||||
@@ -107,7 +107,7 @@ def episodios(item):
|
||||
return locals()
|
||||
|
||||
def check(item):
|
||||
data = support.match(item, headers=headers)[1]
|
||||
data = support.match(item, headers=headers).data
|
||||
if 'Lista Episodi' not in data:
|
||||
item.data = data
|
||||
return findvideos(item)
|
||||
@@ -120,7 +120,7 @@ def findvideos(item):
|
||||
if item.data:
|
||||
data = item.data
|
||||
else:
|
||||
matches = support.match(item, '(?:str="([^"]+)"|iframe src="([^"]+)")')[0]
|
||||
matches = support.match(item, patron=r'<iframe.*?src="(?P<url>[^"]+)"').matches
|
||||
data = ''
|
||||
if matches:
|
||||
for match in matches:
|
||||
|
||||
@@ -7,79 +7,5 @@
|
||||
"thumbnail": "animesaturn.png",
|
||||
"banner": "animesaturn.png",
|
||||
"categories": ["anime"],
|
||||
"settings": [
|
||||
{
|
||||
"id": "modo_grafico",
|
||||
"type": "bool",
|
||||
"label": "Cerca informazioni extra",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "channel_host",
|
||||
"type": "text",
|
||||
"label": "Host del canale",
|
||||
"default": "https://www.animesaturn.com",
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_global_search",
|
||||
"type": "bool",
|
||||
"label": "Includi ricerca globale",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_anime",
|
||||
"type": "bool",
|
||||
"label": "Includi in Novità - Anime",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_italiano",
|
||||
"type": "bool",
|
||||
"label": "Includi in Novità - Italiano",
|
||||
"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": "autorenumber",
|
||||
"type": "bool",
|
||||
"label": "@70712",
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "autorenumber_mode",
|
||||
"type": "bool",
|
||||
"label": "@70688",
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"visible": "eq(-1,true)"
|
||||
}
|
||||
]
|
||||
"settings": []
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
from core import support
|
||||
|
||||
__channel__ = "animesaturn"
|
||||
host = support.config.get_setting("channel_host", __channel__)
|
||||
# __channel__ = "animesaturn"
|
||||
# host = support.config.get_setting("channel_host", __channel__)
|
||||
host = support.config.get_channel_url()
|
||||
headers={'X-Requested-With': 'XMLHttpRequest'}
|
||||
|
||||
IDIOMAS = {'Italiano': 'ITA'}
|
||||
list_language = IDIOMAS.values()
|
||||
list_servers = ['openload', 'fembed', 'animeworld']
|
||||
|
||||
list_servers = ['directo', 'fembed', 'animeworld']
|
||||
list_quality = ['default', '480p', '720p', '1080p']
|
||||
|
||||
@support.menu
|
||||
@@ -33,6 +33,9 @@ def search(item, texto):
|
||||
anime = True
|
||||
patron = r'href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<|(]+)(?:(?P<lang>\(([^\)]+)\)))?<|\)'
|
||||
action = 'check'
|
||||
def itemHook(item):
|
||||
item.url = item.url.replace('www.','')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
@@ -58,6 +61,9 @@ def newest(categoria):
|
||||
def menu(item):
|
||||
patronMenu = r'u>(?P<title>[^<]+)<u>(?P<url>.*?)</div> </div>'
|
||||
action = 'peliculas'
|
||||
def itemHook(item):
|
||||
item.url = item.url.replace('www.','')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
@@ -67,7 +73,7 @@ def peliculas(item):
|
||||
deflang= 'Sub-ITA'
|
||||
if item.args == 'updated':
|
||||
post = "page=" + str(item.page if item.page else 1) if item.page > 1 else None
|
||||
page, data = support.match(item, r'data-page="(\d+)" title="Next">', post=post, headers=headers)
|
||||
page= support.match(item, patron=r'data-page="(\d+)" title="Next">', post=post, headers=headers).match
|
||||
patron = r'<img alt="[^"]+" src="(?P<thumb>[^"]+)" [^>]+></div></a>\s*<a href="(?P<url>[^"]+)"><div class="testo">(?P<title>[^\(<]+)(?:(?P<lang>\(([^\)]+)\)))?</div></a>\s*<a href="[^"]+"><div class="testo2">[^\d]+(?P<episode>\d+)</div></a>'
|
||||
if page: nextpage = page
|
||||
item.contentType='episode'
|
||||
@@ -78,17 +84,20 @@ def peliculas(item):
|
||||
action = 'check'
|
||||
else:
|
||||
pagination = ''
|
||||
if item.args == 'incorso': patron = r'"slider_title" href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+>(?P<title>[^\(<]+)(?:\((?P<year>\d+)\))?</a>'
|
||||
if item.args == 'incorso': patron = r'"slider_title"\s*href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+>(?P<title>[^\(<]+)(?:\((?P<year>\d+)\))?</a>'
|
||||
else: patron = r'href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>.+?)(?:\((?P<lang>ITA)\))?(?:(?P<year>\((\d+)\)))?</span>'
|
||||
action = 'check'
|
||||
def itemHook(item):
|
||||
item.url = item.url.replace('www.','')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
def check(item):
|
||||
movie, data = support.match(item, r'Episodi:</b> (\d*) Movie')
|
||||
anime_id = support.match(data, r'anime_id=(\d+)')[0][0]
|
||||
movie = support.match(item, patron=r'Episodi:</b> (\d*) Movie')
|
||||
anime_id = support.match(movie.data, patron=r'anime_id=(\d+)').match
|
||||
item.url = host + "/loading_anime?anime_id=" + anime_id
|
||||
if movie:
|
||||
if movie.match:
|
||||
item.contentType = 'movie'
|
||||
episodes = episodios(item)
|
||||
if len(episodes) > 0: item.url = episodes[0].url
|
||||
@@ -102,16 +111,20 @@ def check(item):
|
||||
def episodios(item):
|
||||
if item.contentType != 'movie': anime = True
|
||||
patron = r'<strong" style="[^"]+">(?P<title>[^<]+)</b></strong></td>\s*<td style="[^"]+"><a href="(?P<url>[^"]+)"'
|
||||
def itemHook(item):
|
||||
item.url = item.url.replace('www.','')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.log()
|
||||
itemlist = []
|
||||
urls = support.match(item, r'<a href="([^"]+)"><div class="downloadestreaming">', headers=headers)[0]
|
||||
# support.dbg()
|
||||
urls = support.match(item, patron=r'<a href="([^"]+)"><div class="downloadestreaming">', headers=headers, debug=False).matches
|
||||
if urls:
|
||||
links = support.match(item, r'(?:<source type="[^"]+"\s*src=|file:\s*)"([^"]+)"', url=urls[0], headers=headers)[0]
|
||||
for link in links:
|
||||
links = support.match(urls[0].replace('www.',''), patron=r'(?:<source type="[^"]+"\s*src=|file:\s*)"([^"]+)"', headers=headers, debug=False)
|
||||
for link in links.matches:
|
||||
itemlist.append(
|
||||
support.Item(channel=item.channel,
|
||||
action="play",
|
||||
@@ -123,7 +136,7 @@ def findvideos(item):
|
||||
show=item.show,
|
||||
contentType=item.contentType,
|
||||
folder=False))
|
||||
return support.server(item, itemlist=itemlist)
|
||||
return support.server(item, links, itemlist=itemlist)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def newest(categoria):
|
||||
|
||||
if itemlist[-1].action == "ultimiep":
|
||||
itemlist.pop()
|
||||
# Continua l'esecuzione in caso di errore
|
||||
# Continua l'esecuzione in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
@@ -50,7 +50,7 @@ def search(item, texto):
|
||||
item.args = 'alt'
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
@@ -67,10 +67,9 @@ def genres(item):
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
def peliculas(item):
|
||||
anime = True
|
||||
if item.args == 'updated':
|
||||
#patron = r'<div class="post-thumbnail">\s*<a href="(?P<url>[^"]+)" title="(?P<title>.*?)\s*(?P<episode>Episodio \d+)[^"]+"[^>]*>\s*<img[^src]+src="(?P<thumb>[^"]+)"'
|
||||
patron = r'<div class="post-thumbnail">\s*<a href="(?P<url>[^"]+)" title="(?P<title>.*?)\s*Episodio (?P<episode>\d+) (?P<lang>[a-zA-Z-\s]+)[^"]*"> <img[^src]+src="(?P<thumb>[^"]+)"'
|
||||
patronNext = r'<link rel="next" href="([^"]+)"\s*/>'
|
||||
action = 'findvideos'
|
||||
@@ -98,32 +97,27 @@ def findvideos(item):
|
||||
itemlist = []
|
||||
|
||||
if item.args == 'updated':
|
||||
ep = support.match(item.fulltitle,r'(Episodio\s*\d+)')[0][0]
|
||||
item.url = support.re.sub(r'episodio-\d+-|oav-\d+-', '',item.url)
|
||||
ep = support.match(item.fulltitle, patron=r'(\d+)').match
|
||||
item.url = support.re.sub(r'episodio-\d+-|oav-\d+-'+ep, '',item.url)
|
||||
if 'streaming' not in item.url: item.url = item.url.replace('sub-ita','sub-ita-streaming')
|
||||
item.url = support.match(item, r'<a href="([^"]+)"[^>]+>', ep + '(.*?)</tr>', )[0][0]
|
||||
item.url = support.match(item, patron= ep + r'[^>]+>[^>]+>[^>]+><a href="([^"]+)"').match
|
||||
|
||||
urls = support.match(item.url, r'(episodio\d*.php.*)')[0]
|
||||
for url in urls:
|
||||
url = host + '/' + url
|
||||
headers['Referer'] = url
|
||||
data = support.match(item, headers=headers, url=url)[1]
|
||||
cookies = ""
|
||||
matches = support.re.compile('(.%s.*?)\n' % host.replace("http://", "").replace("www.", ""), support.re.DOTALL).findall(support.config.get_cookie_data())
|
||||
for cookie in matches:
|
||||
cookies += cookie.split('\t')[5] + "=" + cookie.split('\t')[6] + ";"
|
||||
# post
|
||||
url = host + '/' + support.match(item.url, patron=r'(episodio\d*.php.*?)"').match.replace('%3F','?').replace('%3D','=')
|
||||
headers['Referer'] = url
|
||||
cookies = ""
|
||||
matches = support.re.compile('(.%s.*?)\n' % host.replace("http://", "").replace("www.", ""), support.re.DOTALL).findall(support.config.get_cookie_data())
|
||||
for cookie in matches:
|
||||
cookies += cookie.split('\t')[5] + "=" + cookie.split('\t')[6] + ";"
|
||||
headers['Cookie'] = cookies[:-1]
|
||||
|
||||
headers['Cookie'] = cookies[:-1]
|
||||
|
||||
url = support.match(data, r'<source src="([^"]+)"[^>]+>')[0][0] + '|' + support.urllib.urlencode(headers)
|
||||
itemlist.append(
|
||||
support.Item(channel=item.channel,
|
||||
action="play",
|
||||
title='diretto',
|
||||
quality='',
|
||||
url=url,
|
||||
server='directo',
|
||||
fulltitle=item.fulltitle,
|
||||
show=item.show))
|
||||
url = support.match(url, patron=r'<source src="([^"]+)"[^>]+>').match
|
||||
|
||||
return support.server(item,url,itemlist)
|
||||
itemlist.append(
|
||||
support.Item(channel=item.channel,
|
||||
action="play",
|
||||
title='Diretto',
|
||||
url=url + '|' + support.urllib.urlencode(headers),
|
||||
server='directo'))
|
||||
|
||||
return support.server(item,itemlist=itemlist)
|
||||
@@ -98,11 +98,11 @@ def episodios(item):
|
||||
def findvideos(item):
|
||||
itemlist=[]
|
||||
if item.args == 'last':
|
||||
match = support.match(item, r'href="(?P<url>[^"]+)"[^>]+><strong>DOWNLOAD & STREAMING</strong>', url=item.url)[0]
|
||||
match = support.match(item, patron=r'href="(?P<url>[^"]+)"[^>]+><strong>DOWNLOAD & STREAMING</strong>').match
|
||||
if match:
|
||||
patronBlock = r'<h6>Episodio</h6>(?P<block>.*?)(?:<!--|</table>)'
|
||||
patron = r'<a href="http://link\.animetubeita\.com/2361078/(?P<url>[^"]+)"'
|
||||
match = support.match(item, patron, patronBlock, headers, match[0])[0]
|
||||
match = support.match(match, patron=patron, patronBlock=patronBlock, headers=headers).match
|
||||
else: return itemlist
|
||||
|
||||
if match: item.url = match[-1]
|
||||
|
||||
11
channels/animeunity.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "animeunity",
|
||||
"name": "AnimeUnity",
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "animeunity.png",
|
||||
"banner": "animeunity.png",
|
||||
"categories": ["anime"],
|
||||
"settings": []
|
||||
}
|
||||
123
channels/animeunity.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per AnimeUnity
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
|
||||
list_servers = ['mixdrop', 'wstream', 'vupplayer', 'supervideo', 'cloudvideo', 'gounlimited']
|
||||
list_quality = ['default','1080p', '720p', '480p', '360p']
|
||||
|
||||
headers = [['Referer', host]]
|
||||
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
anime = ['/anime.php?c=archive&page=*',
|
||||
('In Corso',['/anime.php?c=onair', 'peliculas']),
|
||||
('Ultimi Episodi', ['', 'peliculas', 'news']),
|
||||
('Ultimi Aggiunti', ['', 'peliculas', 'last'])
|
||||
]
|
||||
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.log('search', item)
|
||||
item.url = host + '/anime.php?c=archive&page=*'
|
||||
item.search = text
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.log('search log:', line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
support.log(categoria)
|
||||
itemlist = []
|
||||
item = support.Item()
|
||||
item.url = host
|
||||
item.args = 'news'
|
||||
item.action = 'peliculas'
|
||||
try:
|
||||
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.log({0}.format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
# debug = True
|
||||
pagination = 20
|
||||
anime = True
|
||||
if item.args == 'news':
|
||||
patron = r'col-lg-3 col-md-6 col-sm-6 col-xs-6 mobile-col">\s*<a href="(?P<url>[^"]+)">[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<img class="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^-]+)\D+Episodio\s*(?P<episode>\d+)'
|
||||
patronNext = r'page-link" href="([^"]+)">'
|
||||
elif item.args == 'last':
|
||||
patronBlock = r'ULTIME AGGIUNTE[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<block>.*?)<div class="row"'
|
||||
patron = r'<img class="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>\s*<a class="[^"]+" href="(?P<url>[^"]+)"\s*>(?P<title>[^<]+)</a>'
|
||||
else:
|
||||
search = item.search
|
||||
patron = r'<div class="card-img-top archive-card-img"> <a href="(?P<url>[^"]+)"> <img class="[^"]+" src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<\(]+)(?:\((?P<lang>[^\)]+)\))?'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
# debug = True
|
||||
data = item.data
|
||||
anime = True
|
||||
pagination = 50
|
||||
patron = r'<a href="(?P<url>[^"]+)" class="\D+ep-button">(?P<episode>\d+)'
|
||||
def itemHook(item):
|
||||
item.title = item.title + support.typo(item.fulltitle,'-- bold')
|
||||
return item
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.log()
|
||||
html = support.match(item, patron=r'TIPO:\s*</b>\s*([A-Za-z]+)')
|
||||
if html.match == 'TV' and item.contentType != 'episode':
|
||||
item.contentType = 'tvshow'
|
||||
item.data = html.data
|
||||
return episodios(item)
|
||||
else:
|
||||
itemlist = []
|
||||
if item.contentType != 'episode': item.contentType = 'movie'
|
||||
video = support.match(html.data, patron=r'<source src="([^"]+)"').match
|
||||
itemlist.append(
|
||||
support.Item(
|
||||
channel=item.channel,
|
||||
action="play",
|
||||
title='Diretto',
|
||||
quality='',
|
||||
url=video,
|
||||
server='directo',
|
||||
fulltitle=item.fulltitle,
|
||||
show=item.show,
|
||||
contentType=item.contentType,
|
||||
folder=False))
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -10,7 +10,7 @@ headers = [['Referer', host]]
|
||||
|
||||
__channel__ = 'animeworld'
|
||||
|
||||
list_servers = ['animeworld', 'verystream', 'streamango', 'openload', 'directo']
|
||||
list_servers = ['directo', 'animeworld', 'vvvvid']
|
||||
list_quality = ['default', '480p', '720p', '1080p']
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def mainlist(item):
|
||||
def genres(item):
|
||||
support.log()
|
||||
itemlist = []
|
||||
matches = support.match(item, r'<input.*?name="([^"]+)" value="([^"]+)"\s*>[^>]+>([^<]+)<\/label>' , r'<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown"> Generi <span.[^>]+>(.*?)</ul>', headers=headers)[0]
|
||||
matches = support.match(item, patron=r'<input.*?name="([^"]+)" value="([^"]+)"\s*>[^>]+>([^<]+)<\/label>' , patronBlock=r'<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown"> Generi <span.[^>]+>(.*?)</ul>', headers=headers).matches
|
||||
for name, value, title in matches:
|
||||
support.menuItem(itemlist, __channel__, support.typo(title, 'bold'), 'peliculas', host + '/filter?' + name + '=' + value + '&sort=' + order(), 'tvshow', args='sub')
|
||||
return itemlist
|
||||
@@ -44,7 +44,7 @@ def build_menu(item):
|
||||
support.log()
|
||||
itemlist = []
|
||||
support.menuItem(itemlist, __channel__, 'Tutti bold', 'peliculas', item.url , 'tvshow' , args=item.args)
|
||||
matches = support.match(item,r'<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown"> (.*?) <span.[^>]+>(.*?)</ul>',r'<form class="filters.*?>(.*?)</form>', headers=headers)[0]
|
||||
matches = support.match(item, patron=r'<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown"> (.*?) <span.[^>]+>(.*?)</ul>', patronBlock=r'<form class="filters.*?>(.*?)</form>', headers=headers).matches
|
||||
for title, html in matches:
|
||||
if title not in 'Lingua Ordine':
|
||||
support.menuItem(itemlist, __channel__, title + ' submenu bold', 'build_sub_menu', html, 'tvshow', args=item.args)
|
||||
@@ -127,7 +127,7 @@ def peliculas(item):
|
||||
def episodios(item):
|
||||
anime=True
|
||||
pagination = 50
|
||||
data = support.match(item, headers=headers)[1]
|
||||
data = support.match(item, headers=headers).data
|
||||
if 'VVVVID' in data: patronBlock= r'<div class="server\s*active\s*"(?P<block>.*?)</ul>'
|
||||
else: patronBlock= r'server active(?P<block>.*?)server hidden '
|
||||
patron = r'<li><a [^=]+="[^"]+"[^=]+="[^"]+"[^=]+="[^"]+"[^=]+="[^"]+"[^=]+="[^"]+" href="(?P<url>[^"]+)"[^>]+>(?P<episode>[^<]+)<'
|
||||
@@ -143,9 +143,11 @@ def findvideos(item):
|
||||
import time
|
||||
support.log(item)
|
||||
itemlist = []
|
||||
matches, data = support.match(item, r'class="tab.*?data-name="([0-9]+)">', headers=headers)
|
||||
matches = support.match(item, patron=r'class="tab.*?data-name="([0-9]+)">', headers=headers)
|
||||
data = matches.data
|
||||
matches = matches.matches
|
||||
videoData = ''
|
||||
|
||||
|
||||
for serverid in matches:
|
||||
if not item.number: item.number = support.scrapertools.find_single_match(item.title, r'(\d+) -')
|
||||
block = support.scrapertools.find_multiple_matches(data, 'data-id="' + serverid + '">(.*?)<div class="server')
|
||||
@@ -153,7 +155,7 @@ def findvideos(item):
|
||||
support.log('ID= ',serverid)
|
||||
if id:
|
||||
if serverid == '26':
|
||||
matches = support.match(item, r'<a href="([^"]+)"', url='%s/ajax/episode/serverPlayer?id=%s' % (host, item.url.split('/')[-1]))[0]
|
||||
matches = support.match('%s/ajax/episode/serverPlayer?id=%s' % (host, item.url.split('/')[-1]), patron=r'<a href="([^"]+)"', ).matches
|
||||
for url in matches:
|
||||
videoData += '\n' + url
|
||||
else:
|
||||
@@ -162,7 +164,7 @@ def findvideos(item):
|
||||
json = jsontools.load(dataJson)
|
||||
support.log(json)
|
||||
if 'keepsetsu' in json['grabber']:
|
||||
matches = support.match(item, r'<iframe\s*src="([^"]+)"', url=json['grabber'])[0]
|
||||
matches = support.match(json['grabber'], patron=r'<iframe\s*src="([^"]+)"'),matches
|
||||
for url in matches:
|
||||
videoData += '\n' + url
|
||||
else:
|
||||
|
||||
@@ -2,34 +2,12 @@
|
||||
# ------------------------------------------------------------
|
||||
# Canale per 'casacinema'
|
||||
# ------------------------------------------------------------
|
||||
"""
|
||||
|
||||
Problemi noti che non superano il test del canale:
|
||||
- Nella ricerca globale non sono presenti le voci:
|
||||
- "Aggiungi in videoteca"
|
||||
- "Scarica film/serie"
|
||||
presenti però quando si entra nella pagina
|
||||
|
||||
Avvisi:
|
||||
|
||||
|
||||
Novità:
|
||||
- Film, SerieTv
|
||||
|
||||
Ulteriori info:
|
||||
|
||||
"""
|
||||
import re
|
||||
from core import support
|
||||
from platformcode import config
|
||||
|
||||
# in caso di necessità
|
||||
from core import scrapertools, httptools
|
||||
from core.item import Item
|
||||
|
||||
|
||||
##### fine import
|
||||
host = config.get_channel_url()
|
||||
host = support.config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
list_servers = ['verystream', 'openload', 'wstream', 'speedvideo']
|
||||
@@ -37,9 +15,6 @@ list_quality = ['HD', 'SD']
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
support.log(item)
|
||||
## support.dbg()
|
||||
|
||||
film = ['/category/film',
|
||||
('Generi', ['', 'genres', 'genres']),
|
||||
('Sub-ITA', ['/category/sub-ita/', 'peliculas', 'sub'])
|
||||
@@ -53,24 +28,90 @@ def mainlist(item):
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
action = 'peliculas'
|
||||
blacklist = ['PRIME VISIONI', 'ULTIME SERIE TV', 'ULTIMI FILM']
|
||||
patronMenu = r'<li><a href="(?P<url>[^"]+)">(?P<title>[^<>]+)</a></li>'
|
||||
patronBlock = r'<div class="container home-cats">(?P<block>.*?)<div class="clear">'
|
||||
return locals()
|
||||
|
||||
|
||||
def select(item):
|
||||
item.data = support.match(item).data
|
||||
if 'continua con il video' in item.data.lower():
|
||||
support.log('select = ### è un film ###')
|
||||
item.contentType = 'movie'
|
||||
return findvideos(item)
|
||||
else:
|
||||
support.log('select = ### è una serie ###')
|
||||
item.contentType = 'tvshow'
|
||||
return episodios(item)
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.log(text)
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/?s=' + text
|
||||
item.args = 'search'
|
||||
try:
|
||||
item.contentType = '' # non fa uscire le voci nel context menu
|
||||
return peliculas(item)
|
||||
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
support.log('search log:', line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
itemlist = []
|
||||
item = support.Item()
|
||||
item.args = 'newest'
|
||||
|
||||
try:
|
||||
if categoria == 'series':
|
||||
item.contentType = 'tvshow'
|
||||
item.url = host+'/aggiornamenti-serie-tv'
|
||||
|
||||
else:
|
||||
item.contentType = 'movie'
|
||||
item.url = host+'/category/film'
|
||||
|
||||
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.log('newest log: ', {0}.format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.log(item)
|
||||
## support.dbg() # decommentare per attivare web_pdb
|
||||
|
||||
if item.contentType == 'movie':
|
||||
action = 'findvideos'
|
||||
elif item.contentType == 'tvshow':
|
||||
action = 'episodios'
|
||||
pagination = ''
|
||||
else:
|
||||
# è una ricerca
|
||||
action = 'select'
|
||||
blacklist = ['']
|
||||
|
||||
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div> <div[^>]+>(?P<title>.*?)[ ]?(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?<(?:[^>]+>.+?(?:title="Nuovi episodi">(?P<episode>\d+x\d+)[ ]?(?P<lang2>Sub-Ita)?|title="IMDb">(?P<rating>[^<]+)))?'
|
||||
patronBlock = r'<h1>.+?</h1>(?P<block>.*?)<aside>'
|
||||
patronNext = '<a href="([^"]+)" >Pagina'
|
||||
if item.args == 'newest':
|
||||
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div> <div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?<(?:[^>]+>.+?(?:title="Nuovi episodi">(?P<episode>\d+x\d+)[ ]?(?P<lang2>Sub-Ita)?|title="IMDb">(?P<rating>[^<]+)))?'
|
||||
else:
|
||||
patron = r'<li><a href="(?P<url>[^"]+)"[^=]+="(?P<thumb>[^"]+)"><div> <div[^>]+>(?P<title>[^\(\[<]+)(?:\[(?P<quality1>HD)\])?[ ]?(?:\(|\[)?(?P<lang>Sub-ITA)?(?:\)|\])?[ ]?(?:\[(?P<quality>.+?)\])?[ ]?(?:\((?P<year>\d+)\))?<'
|
||||
|
||||
patronNext = r'<a href="([^"]+)" >Pagina'
|
||||
|
||||
def itemHook(item):
|
||||
if item.quality1:
|
||||
@@ -82,125 +123,31 @@ def peliculas(item):
|
||||
if item.args == 'novita':
|
||||
item.title = item.title
|
||||
return item
|
||||
|
||||
## debug = True # True per testare le regex sul sito
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
support.log(item)
|
||||
#dbg
|
||||
if item.data1:
|
||||
data = item.data1
|
||||
if item.data:
|
||||
data = item.data
|
||||
action = 'findvideos'
|
||||
item.contentType = 'tvshow'
|
||||
blacklist = ['']
|
||||
patron = r'(?P<episode>\d+(?:×|×)?\d+\-\d+|\d+(?:×|×)\d+)[;]?(?:(?P<title>[^<]+)<(?P<url>.*?)|(\2[ ])(?:<(\3.*?)))(?:<br />|</p>)'
|
||||
patronBlock = r'<strong>(?P<block>(?:.+?Stagione*.+?(?P<lang>[Ii][Tt][Aa]|[Ss][Uu][Bb][\-]?[iI][tT][aA]))?(?:.+?|</strong>)(/?:</span>)?</p>.*?</p>)'
|
||||
|
||||
## debug = True
|
||||
return locals()
|
||||
|
||||
# Questa def è utilizzata per generare il menu 'Generi' del canale
|
||||
# per genere, per anno, per lettera, per qualità ecc ecc
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
support.log(item)
|
||||
#dbg
|
||||
|
||||
action = 'peliculas'
|
||||
blacklist = ['PRIME VISIONI', 'ULTIME SERIE TV', 'ULTIMI FILM']
|
||||
patron = r'<li><a href="(?P<url>[^"]+)">(?P<title>[^<>]+)</a></li>'
|
||||
patronBlock = r'<div class="container home-cats">(?P<block>.*?)<div class="clear">'
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
def select(item):
|
||||
support.log('select --->', item)
|
||||
## debug = True
|
||||
#support.dbg()
|
||||
data = httptools.downloadpage(item.url, headers=headers).data
|
||||
data = re.sub('\n|\t', ' ', data)
|
||||
data = re.sub(r'>\s+<', '> <', data)
|
||||
if 'continua con il video' in data.lower():
|
||||
## block = scrapertools.find_single_match(data, r'<div class="col-md-8 bg-white rounded-left p-5"><div>(.*?)<div style="margin-left: 0.5%; color: #FFF;">')
|
||||
## if re.findall('rel="category tag">serie', data, re.IGNORECASE):
|
||||
support.log('select = ### è un film ###')
|
||||
return findvideos(Item(channel=item.channel,
|
||||
title=item.title,
|
||||
fulltitle=item.fulltitle,
|
||||
url=item.url,
|
||||
#args='serie',
|
||||
contentType='movie',
|
||||
data1 = data
|
||||
))
|
||||
else:
|
||||
support.log('select = ### è una serie ###')
|
||||
return episodios(Item(channel=item.channel,
|
||||
title=item.title,
|
||||
fulltitle=item.fulltitle,
|
||||
url=item.url,
|
||||
#args='serie',
|
||||
contentType='tvshow',
|
||||
data1 = data
|
||||
))
|
||||
|
||||
############## Fondo Pagina
|
||||
|
||||
def search(item, text):
|
||||
support.log('search ->', item)
|
||||
itemlist = []
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/?s=' + text
|
||||
item.args = 'search'
|
||||
try:
|
||||
item.contentType = 'episode' # non fa uscire le voci nel context menu
|
||||
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.log('search log:', line)
|
||||
return []
|
||||
|
||||
def newest(categoria):
|
||||
support.log('newest ->', categoria)
|
||||
itemlist = []
|
||||
item = Item()
|
||||
|
||||
try:
|
||||
if categoria == 'series':
|
||||
item.contentType = 'tvshow'
|
||||
item.url = host+'/aggiornamenti-serie-tv'
|
||||
item.args = 'novita'
|
||||
else:
|
||||
item.contentType = 'movie'
|
||||
item.url = host+'/category/film'
|
||||
|
||||
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.log('newest log: ', {0}.format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
def findvideos(item):
|
||||
support.log('findvideos ->', item)
|
||||
itemlist = []
|
||||
if item.contentType != 'movie':
|
||||
return support.server(item, item.url)
|
||||
links = support.match(item.url, patron=r'href="([^"]+)"').matches
|
||||
else:
|
||||
links = str(support.match(item, r'SRC="([^"]+)"', patronBlock=r'<div class="col-md-10">(.+?)<div class="swappable" id="links">')[0])
|
||||
if links:
|
||||
links = links.replace('#', 'speedvideo.net')
|
||||
return support.server(item, links)
|
||||
else:
|
||||
return support.server(item)
|
||||
matchData = item.data if item.data else item
|
||||
links = support.match(matchData, patron=r'(?:SRC|href)="([^"]+)"', patronBlock=r'<div class="col-md-10">(.+?)<div class="ads">').matches
|
||||
data = ''
|
||||
from lib.unshortenit import unshorten_only
|
||||
for link in links:
|
||||
support.log('URL=',link)
|
||||
url, c = unshorten_only(link.replace('#', 'speedvideo.net'))
|
||||
data += url + '\n'
|
||||
return support.server(item, data)
|
||||
|
||||
@@ -59,7 +59,7 @@ def peliculas(item):
|
||||
blacklist = Blacklist
|
||||
item.contentType = 'tvshow'
|
||||
if item.args == 'newest':
|
||||
data = support.match(item)[1]
|
||||
# data = support.match(item).data
|
||||
patron = r'<div id="blockvids"><ul><li><a href="(?P<url>[^"]+)"[^>]+><img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^\[]+)\[(?P<lang>[^\]]+)\]'
|
||||
else:
|
||||
patron = r'<div class="span4">\s*<a href="(?P<url>[^"]+)"><img src="(?P<thumb>[^"]+)"[^>]+><\/a>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+> <h1>(?P<title>[^<\[]+)(?:\[(?P<lang>[^\]]+)\])?</h1></a>.*?-->(?:.*?<br />)?\s*(?P<plot>[^<]+)'
|
||||
@@ -68,7 +68,7 @@ def peliculas(item):
|
||||
return locals()
|
||||
|
||||
def check(item):
|
||||
item.url = support.match(item,r'(?:<p>|/>)(.*?)(?:<br|</td>|</p>)', r'Streaming:(.*?)</tr>')[0]
|
||||
item.url = support.match(item, patron=r'(?:<p>|/>)(.*?)(?:<br|</td>|</p>)', patronBlock=r'Streaming:(.*?)</tr>').matches
|
||||
if 'Episodio' in str(item.url):
|
||||
item.contentType = 'tvshow'
|
||||
return episodios(item)
|
||||
@@ -87,14 +87,14 @@ def episodios(item):
|
||||
sp = 0
|
||||
for match in item.url:
|
||||
if 'stagione' in match.lower():
|
||||
find_season = support.match(match, r'Stagione\s*(\d+)')[0]
|
||||
season = int(find_season[0]) if find_season else season + 1 if 'prima' not in match.lower() else season
|
||||
find_season = support.match(match, patron=r'Stagione\s*(\d+)').match
|
||||
season = int(find_season) if find_season else season + 1 if 'prima' not in match.lower() else season
|
||||
else:
|
||||
try: title = support.match(match,'<a[^>]+>([^<]+)</a>')[0][0]
|
||||
try: title = support.match(match, patron=r'<a[^>]+>([^<]+)</a>').match
|
||||
except: title = ''
|
||||
if title:
|
||||
if 'episodio' in title.lower():
|
||||
ep = support.match(match, r'Episodio ((?:\d+.\d|\d+|\D+))')[0][0]
|
||||
ep = support.match(match, patron=r'Episodio ((?:\d+.\d|\d+|\D+))').match
|
||||
check = ep.isdigit()
|
||||
if check or '.' in ep:
|
||||
if '.' in ep:
|
||||
|
||||
@@ -22,7 +22,7 @@ def findhost():
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
list_servers = ['verystream', 'openload', 'streamango', 'wstream']
|
||||
list_servers = ['mixdrop', 'akstream', 'wstream', 'backin']
|
||||
list_quality = ['HD', 'SD', 'default']
|
||||
|
||||
checklinks = config.get_setting('checklinks', 'cineblog01')
|
||||
|
||||
@@ -12,7 +12,11 @@ from platformcode import config
|
||||
list_servers = ['akstream', 'wstream', 'backin', 'clipwatching', 'cloudvideo', 'verystream', 'onlystream', 'mixdrop']
|
||||
list_quality = ['default']
|
||||
|
||||
host = config.get_channel_url()
|
||||
def findhost():
|
||||
permUrl = httptools.downloadpage('https://www.cinemalibero.online/', follow_redirects=False).headers
|
||||
return 'https://www.' + permUrl['location'].replace('https://www.google.com/search?q=site:', '')
|
||||
|
||||
host = config.get_channel_url(findhost)
|
||||
headers = [['Referer', host]]
|
||||
|
||||
@support.menu
|
||||
|
||||
@@ -73,7 +73,7 @@ def findvideos(item):
|
||||
support.log()
|
||||
itemlist = []
|
||||
|
||||
matches = support.match(item, 'filename: "(.*?)"')[0]
|
||||
matches = support.match(item, patron=r'filename: "(.*?)"').matches
|
||||
|
||||
for url in matches:
|
||||
itemlist.append(
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
"thumbnail": "dreamsub.png",
|
||||
"banner": "dreamsub.png",
|
||||
"categories": ["anime", "vos"],
|
||||
"not_active": ["include_in_newest"],
|
||||
"settings": []
|
||||
}
|
||||
|
||||
@@ -2,214 +2,54 @@
|
||||
# ------------------------------------------------------------
|
||||
# Canale per 'dreamsub'
|
||||
# ------------------------------------------------------------
|
||||
# ------------------------------------------------------------
|
||||
"""
|
||||
|
||||
Problemi noti che non superano il test del canale:
|
||||
- Nessuno noto!
|
||||
|
||||
Avvisi per i tester:
|
||||
1. Gli episodi sono divisi per pagine di 20
|
||||
2. In Novità->Anime, cliccare sulla home il bottone "Ultime inserite"
|
||||
Se avete più titoli in KOD, ridimensiona il browser in modo che si vedano i titoli
|
||||
a gruppi di 3 e ricontrollare, è un problema del sito.
|
||||
|
||||
3.Passaggi per Aggiungere in videoteca e/o scaricare Serie:
|
||||
1. sul titolo -> menu contestuale -> Rinumerazione
|
||||
Solo dopo questo passaggio appariranno le voci, sul titolo -> menu contestuale ->:
|
||||
- Aggiungi in videoteca (senza rinumerazione non appare
|
||||
la voce)
|
||||
- Scarica Serie e Scarica Stagione ( Se download Abilitato! )
|
||||
|
||||
4. ### PIù IMPORTANTE!!! ###
|
||||
#### NON E' DA CONSIDERARE ERRORE NEL TEST QUANTO RIPORTATO DI SEGUITO!!!! ####
|
||||
1. Il sito permette un filtro tra anime e film, tramite url.
|
||||
Se nell'url c'è /anime/, sul titolo e proseguendo fino alla pagina del video, saranno
|
||||
presenti le voci:
|
||||
- 'Rinumerazione', prima, e dopo: 'Aggiungi in videoteca', 'Scarica Serie' etc...
|
||||
Tutto il resto è trattato come film e si avranno le voci solite:
|
||||
AD eccezione per quei "FILM" che hanno 2 o più titoli all'interno, in questo caso:
|
||||
1. Non apparirà nessuna voce tra "Aggiungi in videoteca" e "Scarica Film" e nemmeno "rinumerazione"
|
||||
2. Dopo essere entrato nella pagina del Titolo Principale, troverai una lista di titoli dove sarà possibile scaricare
|
||||
il filmato (chiamato EPISODIO) stessa cosa accedendo alla pagina ultima del video
|
||||
3. Questi TITOLI NON POSSONO ESSERE AGGIUNTI IN VIDEOTECA
|
||||
le voci "Scarica FILM" si avranno dopo.
|
||||
|
||||
Es:
|
||||
https://www.dreamsub.stream/movie/5-centimetri-al-secondo -> film ma ha 3 titoli
|
||||
|
||||
Il Canale NON è presente nelle novità(globale) -> Anime
|
||||
|
||||
|
||||
"""
|
||||
# Qui gli import
|
||||
import re
|
||||
|
||||
from core import support
|
||||
from platformcode import config
|
||||
from core import scrapertools, httptools, servertools, tmdb
|
||||
from core.item import Item
|
||||
|
||||
##### fine import
|
||||
host = config.get_channel_url()
|
||||
host = support.config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
|
||||
# server di esempio...
|
||||
list_servers = ['directo', 'verystream', 'streamango', 'openload']
|
||||
# quality di esempio
|
||||
list_quality = ['default']
|
||||
|
||||
#### Inizio delle def principali ###
|
||||
|
||||
@support.menu
|
||||
def mainlist(item):
|
||||
support.log(item)
|
||||
|
||||
anime = ['/anime',
|
||||
## ('Novità', ['']),
|
||||
## ('OAV', ['/search/oav', 'peliculas', 'oav']),
|
||||
## ('OVA', ['/search/ova', 'peliculas', 'ova']),
|
||||
('Movie', ['/search/movie', 'peliculas', '', 'movie']),
|
||||
('Film', ['/search/film', 'peliculas', '', 'movie']),
|
||||
('Categorie', ['/filter?genere=','genres']),
|
||||
## ('Ultimi Episodi', ['', 'last'])
|
||||
anime = ['/search?typeY=tv',
|
||||
('Movie', ['/search?typeY=movie', 'peliculas', '', 'movie']),
|
||||
('OAV', ['/search?typeY=oav', 'peliculas', '', 'tvshow']),
|
||||
('Spinoff', ['/search?typeY=spinoff', 'peliculas', '', 'tvshow']),
|
||||
('Generi', ['','menu','Generi']),
|
||||
('Stato', ['','menu','Stato']),
|
||||
('Ultimi Episodi', ['', 'peliculas', ['last', 'episodiRecenti']]),
|
||||
('Ultimi Aggiornamenti', ['', 'peliculas', ['last', 'episodiNuovi']])
|
||||
]
|
||||
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
support.log(item)
|
||||
#dbg # decommentare per attivare web_pdb
|
||||
|
||||
anime = True
|
||||
if item.args == 'newest':
|
||||
patronBlock = r'<div class="showRoomGoLeft" sr="ultime"></div>(?P<block>.*?)<div class="showRoomGoRight" sr="ultime">'
|
||||
else:
|
||||
patronBlock = r'<input type="submit" value="Vai!" class="blueButton">(?P<block>.*?)<div class="footer">'
|
||||
|
||||
## patron = r'<div class="showStreaming"> <b>(?P<title>[^<]+).+?Stato streaming: '\
|
||||
## '(?:[^<]+)<.*?Lingua:[ ](?P<lang1>ITA\/JAP|ITA|JAP)?(?:[ ])?'\
|
||||
## '(?P<lang2>SUB ITA)?<br>.+?href="(?P<url>[^"]+)".+?'\
|
||||
## 'background: url\((?P<thumb>[^"]+)\).+?<div class="tvTitle">.+?'\
|
||||
## '<strong>Anno di inizio</strong>: (?P<year>\d+)<br>'
|
||||
|
||||
patron = r'<div class="showStreaming"> <b>(?P<title>[^<]+).+?Stato streaming: (?:[^<]+)<.*?Lingua:[ ](?P<lang1>ITA\/JAP|ITA|JAP)?(?:[ ])?(?P<lang2>SUB ITA)?<br>.+?href="(?P<url>[^"]+)".+?background: url\((?P<thumb>[^"]+)\).+?<div class="tvTitle">.+?Episodi[^>]+>.\s?(?P<nep>\d+).+?<strong>Anno di inizio</strong>: (?P<year>\d+)<br>'
|
||||
patronNext = '<li class="currentPage">[^>]+><li[^<]+<a href="([^"]+)">'
|
||||
|
||||
def itemHook(item):
|
||||
support.log("ITEMHOOK -> ", item)
|
||||
item = language(item)
|
||||
|
||||
if 'anime' in item.url:
|
||||
item.contentType = 'tvshow'
|
||||
item.action = 'episodios'
|
||||
#item.args = 'anime'
|
||||
else:
|
||||
if item.nep == '1':
|
||||
item.contentType = 'movie'
|
||||
item.action = 'findvideos'
|
||||
else:
|
||||
item.contentType = 'episode'
|
||||
item.args = ''
|
||||
item.nep = item.nep
|
||||
item.action = 'findmovie'
|
||||
return item
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
support.log(item)
|
||||
#support.dbg()
|
||||
|
||||
action = 'findvideos'
|
||||
patronBlock = r'<div class="seasonEp">(?P<block>.*?)<div class="footer">'
|
||||
patron = r'<li><a href="(?P<url>[^"]+)"[^<]+<b>(?:.+?)[ ](?P<episode>\d+)<\/b>[^>]+>(?P<title>[^<]+)<\/i>[ ]\(?(?P<lang1>ITA|Sub ITA)?\s?.?\s?(?P<lang2>Sub ITA)?.+?\)?<\/a>'
|
||||
|
||||
def itemHook(item):
|
||||
item = language(item)
|
||||
return item
|
||||
|
||||
pagination = ''
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
@support.scrape
|
||||
def genres(item):
|
||||
support.log(item)
|
||||
#dbg
|
||||
|
||||
def menu(item):
|
||||
item.contentType = ''
|
||||
action = 'peliculas'
|
||||
blacklist = ['tutti']
|
||||
patron = r'<option value="(?P<title>[^"]+)">'
|
||||
patronBlock = r'<select name="genere" id="genere" class="selectInput">(?P<block>.*?)</select>'
|
||||
|
||||
patronBlock = r'<div class="filter-header"><b>%s</b>(?P<block>.*?)<div class="filter-box">' % item.args
|
||||
patronMenu = r'<a class="[^"]+" data-state="[^"]+" (?P<other>[^>]+)>[^>]+></i>[^>]+></i>[^>]+></i>(?P<title>[^>]+)</a>'
|
||||
|
||||
def itemHook(item):
|
||||
item.contentTitle = item.contentTitle.replace(' ', '+')
|
||||
item.url = host+'/filter?genere='+item.contentTitle
|
||||
support.log(item.type)
|
||||
for Type, ID in support.match(item.other, patron=r'data-type="([^"]+)" data-id="([^"]+)"').matches:
|
||||
item.url = host + '/search?' + Type + 'Y=' + ID
|
||||
return item
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def findmovie(item):
|
||||
support.log(item)
|
||||
|
||||
patronBlock = r'<div class="seasonEp">(?P<block>.*?)<div class="footer">'
|
||||
item.contentType = 'episode'
|
||||
item.nep = 2
|
||||
patron = r'<li><a href="(?P<url>[^"]+)"[^>]+>.(?P<title2>.+?)-.+?-[ ]<b>(?P<title>.+?)</b>\s+\(?(?P<lang1>ITA)?\s?(?P<lang2>Sub ITA)?.+?\)?'
|
||||
|
||||
def itemHook(item):
|
||||
item = language(item)
|
||||
return item
|
||||
|
||||
#debug = True
|
||||
return locals()
|
||||
|
||||
|
||||
def language(item):
|
||||
lang = []
|
||||
|
||||
if item.lang1:
|
||||
if item.lang1.lower() == 'ita/jap' or item.lang1.lower() == 'ita':
|
||||
lang.append('ITA')
|
||||
|
||||
if item.lang1.lower() == 'jap' and item.lang1.lower() == 'sub ita':
|
||||
lang.append('Sub-ITA')
|
||||
|
||||
if item.lang2:
|
||||
if item.lang2.lower() == 'sub ita':
|
||||
lang.append('Sub-ITA')
|
||||
|
||||
item.contentLanguage = lang
|
||||
|
||||
if len(lang) ==2:
|
||||
item.title += support.typo(lang[0], '_ [] color kod') + support.typo(lang[1], '_ [] color kod')
|
||||
#item.show += support.typo(lang[0], '_ [] color kod') + support.typo(lang[1], '_ [] color kod')
|
||||
elif len(lang) == 1:
|
||||
item.title += support.typo(lang[0], '_ [] color kod')
|
||||
#item.show += support.typo(lang[0], '_ [] color kod')
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def search(item, text):
|
||||
support.log('search', item)
|
||||
itemlist = []
|
||||
support.log(text)
|
||||
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/search/' + text
|
||||
item.args = 'search'
|
||||
try:
|
||||
return peliculas(item)
|
||||
# Se captura la excepcion, para no interrumpir al buscador global si un canal falla
|
||||
# Continua la ricerca in caso di errore
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
@@ -217,77 +57,88 @@ def search(item, text):
|
||||
return []
|
||||
|
||||
|
||||
# da adattare... ( support.server ha vari parametri )
|
||||
#support.server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=True)
|
||||
def newest(categoria):
|
||||
support.log(categoria)
|
||||
item = support.Item()
|
||||
try:
|
||||
if categoria == "anime":
|
||||
item.url = host
|
||||
item.args = ['last', 'episodiNuovi']
|
||||
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 []
|
||||
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
anime = True
|
||||
if 'movie' in item.url:
|
||||
item.contentType = 'movie'
|
||||
action = 'findvideos'
|
||||
else:
|
||||
item.contentType = 'tvshow'
|
||||
action = 'episodios'
|
||||
|
||||
if len(item.args) > 1 and item.args[0] == 'last':
|
||||
patronBlock = r'<div id="%s"[^>]+>(?P<block>.*?)<div class="vistaDettagliata"' % item.args[1]
|
||||
patron = r'<li>\s*<a href="(?P<url>[^"]+)" title="(?P<title>[^"]+)" class="thumb">[^>]+>[^>]+>[^>]+>\s*[EePp]+\s*(?P<episode>\d+)[^>]+>[^>]+>[^>]+>(?P<lang>[^<]*)<[^>]+>[^>]+>\s<img src="(?P<thumb>[^"]+)"'
|
||||
else:
|
||||
patron = r'<div class="showStreaming"> <b>(?P<title>[^<]+)[^>]+>[^>]+>\s*Stato streaming: (?:[^<]+)<[^>]+>[^>]+>\s*Lingua:[ ](?P<lang>ITA\/JAP|ITA|JAP|SUB ITA)?[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<div class="[^"]+" style="background: url\((?P<thumb>[^\)]+)\)'
|
||||
patronNext = '<li class="currentPage">[^>]+><li[^<]+<a href="([^"]+)">'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
anime = True
|
||||
pagination = 100
|
||||
|
||||
if item.data:
|
||||
data = item.data
|
||||
|
||||
patron = r'<div class="sli-name">\s*<a href="(?P<url>[^"]+)"[^>]+>(?P<title>[^<]+)<'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.log("ITEM ---->", item)
|
||||
itemlist = []
|
||||
support.log()
|
||||
|
||||
data = httptools.downloadpage(item.url).data
|
||||
data = re.sub(r'\n|\t', ' ', data)
|
||||
data = re.sub(r'>\s\s*<', '><', data)
|
||||
patronBlock = r'LINK STREAMING(?P<block>.*?)LINK DOWNLOAD'
|
||||
patron = r'href="(.+?)"'
|
||||
block = scrapertools.find_single_match(data, patronBlock)
|
||||
urls = scrapertools.find_multiple_matches(block, patron)
|
||||
#support.regexDbg(item, patron, headers, data=data)
|
||||
matches = support.match(item, patron=r'<a href="([^"]+)"', patronBlock=r'<div style="white-space: (.*?)<div id="main-content"')
|
||||
|
||||
for url in urls:
|
||||
titles = item.infoLabels['title']
|
||||
lang = ''
|
||||
if 'sub_ita' in url.lower():
|
||||
lang = 'Sub-ITA'
|
||||
else:
|
||||
lang = 'ITA'
|
||||
if not matches.matches:
|
||||
item.data = matches.data
|
||||
item.contentType = 'tvshow'
|
||||
return episodios(item)
|
||||
|
||||
if 'keepem.online' in data:
|
||||
urls = scrapertools.find_multiple_matches(data, r'(https://keepem\.online/f/[^"]+)"')
|
||||
for url in urls:
|
||||
url = httptools.downloadpage(url).url
|
||||
itemlist += servertools.find_video_items(data=url)
|
||||
# matches.matches.sort()
|
||||
|
||||
elif 'keepsetsu' in url.lower() or 'woof' in url.lower():
|
||||
if 'keepsetsu' in url.lower():
|
||||
support.log("keepsetsu url -> ", url )
|
||||
data = httptools.downloadpage(url).url
|
||||
support.log("LINK-DATA :", data)
|
||||
|
||||
data = httptools.downloadpage(data).data
|
||||
support.log("LINK-DATA2 :", data)
|
||||
video_urls = scrapertools.find_single_match(data, r'<meta name="description" content="([^"]+)"')
|
||||
|
||||
else:
|
||||
|
||||
data = httptools.downloadpage(url).data
|
||||
#host_video = scrapertools.find_single_match(data, r'var thisPageUrl = "(http[s]\:\/\/[^\/]+).+?"')
|
||||
host_video = scrapertools.find_single_match(data, r'(?:let|var) thisPageUrl = "(http[s]\:\/\/[^\/]+).+?"')
|
||||
link = scrapertools.find_single_match(data, r'<video src="([^"]+)"')
|
||||
video_urls = host_video+link
|
||||
|
||||
title_show = support.typo(titles,'_ bold') + support.typo(lang,'_ [] color kod')
|
||||
for url in matches.matches:
|
||||
lang = url.split('/')[-2]
|
||||
if 'ita' in lang.lower():
|
||||
language = 'ITA'
|
||||
if 'sub' in lang.lower():
|
||||
language = 'Sub-' + language
|
||||
quality = url.split('/')[-1]
|
||||
|
||||
itemlist.append(
|
||||
support.Item(channel=item.channel,
|
||||
action="play",
|
||||
contentType=item.contentType,
|
||||
title=title_show,
|
||||
fulltitle=item.fulltitle,
|
||||
show=item.fulltitle,
|
||||
url=link if 'http' in link else video_urls,
|
||||
infoLabels = item.infoLabels,
|
||||
thumbnail=item.thumbnail,
|
||||
contentSerieName= item.fulltitle,
|
||||
contentTitle=title_show,
|
||||
contentLanguage = 'ITA' if lang == [] else lang,
|
||||
args=item.args,
|
||||
title=language,
|
||||
url=url,
|
||||
contentLanguage = language,
|
||||
quality = quality,
|
||||
order = quality.replace('p','').zfill(4),
|
||||
server='directo',
|
||||
))
|
||||
|
||||
if item.contentType != 'episode' and int(item.nep) < 2 :
|
||||
# Link Aggiungi alla Libreria
|
||||
if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findservers':
|
||||
support.videolibrary(itemlist, item)
|
||||
# link per scaricare
|
||||
if config.get_setting('downloadenabled'):
|
||||
support.download(itemlist, item)
|
||||
return itemlist
|
||||
itemlist.sort(key=lambda x: (x.title, x.order), reverse=False)
|
||||
return support.server(item, itemlist=itemlist)
|
||||
@@ -145,7 +145,9 @@ def findvideos(item):
|
||||
itemlist = []
|
||||
patronBlock = '<div class="entry-content">(?P<block>.*)<footer class="entry-footer">'
|
||||
patron = r'<a href="([^"]+)">'
|
||||
matches, data = support.match(item, patron, patronBlock, headers)
|
||||
html = support.match(item, patron=patron, patronBlock=patronBlock, headers=headers)
|
||||
matches = html.matches
|
||||
data= html.data
|
||||
|
||||
if item.args != 'episodios':
|
||||
item.infoLabels['mediatype'] = 'episode'
|
||||
@@ -156,7 +158,7 @@ def findvideos(item):
|
||||
|
||||
itemlist += support.server(item, data)
|
||||
|
||||
data = httptools.downloadpage(item.url).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')
|
||||
|
||||
@@ -2,19 +2,7 @@
|
||||
# ------------------------------------------------------------
|
||||
# Canale per filmpertutti.py
|
||||
# ------------------------------------------------------------
|
||||
"""
|
||||
Questi sono commenti per i beta-tester.
|
||||
|
||||
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à (globale). Indicare in quale/i sezione/i è presente il canale:
|
||||
- film, serie
|
||||
- I titoli in questa sezione a gruppi di 20
|
||||
|
||||
"""
|
||||
import re
|
||||
|
||||
from core import scrapertools, httptools, support
|
||||
@@ -24,7 +12,7 @@ from platformcode import config
|
||||
|
||||
host = config.get_channel_url()
|
||||
headers = [['Referer', host]]
|
||||
list_servers = ['speedvideo', 'verystream', 'openload', 'streamango', 'wstream', 'akvideo']
|
||||
list_servers = ['mixdrop', 'akvideo', 'wstream', 'onlystream', 'speedvideo']
|
||||
list_quality = ['HD', 'SD']
|
||||
|
||||
@support.menu
|
||||
@@ -74,16 +62,11 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
|
||||
data = httptools.downloadpage(item.url, headers=headers).data
|
||||
data = re.sub('\n|\t', ' ', data)
|
||||
data = re.sub(r'>\s+<', '> <', data)
|
||||
support.log('SERIES DATA= ',data)
|
||||
data = support.match(item.url, headers=headers).data
|
||||
if 'accordion-item' in data:
|
||||
patronBlock = r'<span class="season[^>]*>\d+[^>]+>[^>]+>[^>]+>[^>]+>\D*(?:STAGIONE|Stagione)[ -]+(?P<lang>[a-zA-Z\- ]+)[^<]*</span>(?P<block>.*?)<div id="(?:season|disqus)'
|
||||
patron = r'<img src="(?P<thumb>[^"]+)">.*?<li class="season-no">(?P<episode>[^<]+)<\/li>(?P<url>.*?javascript:;">)(?P<title>[^<]+)'
|
||||
patron = r'<img src="(?P<thumb>[^"]+)">.*?<li class="season-no">(?P<episode>[^<]+)<\/li>(?P<url>.*?javascript:;">(?P<title>[^<]+).*?</tbody>)'
|
||||
else:
|
||||
# patronBlock = r'<div id="info" class="pad">(?P<block>.*?)<div id="disqus_thread">'
|
||||
# deflang='Sub-ITA'
|
||||
patronBlock = r'(?:STAGIONE|Stagione)(?:<[^>]+>)?\s*(?:(?P<lang>[A-Za-z- ]+))?(?P<block>.*?)(?: |<strong>|<div class="addtoany)'
|
||||
patron = r'(?:/>|p>)\s*(?P<season>\d+)(?:×|×|x)(?P<episode>\d+)[^<]+(?P<url>.*?)(?:<br|</p)'
|
||||
def itemHook(item):
|
||||
@@ -104,17 +87,16 @@ def genres(item):
|
||||
|
||||
action = 'peliculas'
|
||||
patronBlock = r'<select class="cats">(?P<block>.*?)<\/select>'
|
||||
patronMenu = r'<option data-src="(?P<url>[^"]+)">(?P<title>.*?)<\/option>'
|
||||
patronMenu = r'<option data-src="(?P<url>[^"]+)">(?P<title>[^<]+)<\/option>'
|
||||
|
||||
return locals()
|
||||
|
||||
|
||||
def select(item):
|
||||
support.log()
|
||||
|
||||
data = httptools.downloadpage(item.url, headers=headers).data
|
||||
patronBlock = scrapertools.find_single_match(data, r'class="taxonomy category" ><span property="name">(.*?)</span></a><meta property="position" content="2">')
|
||||
if patronBlock.lower() != 'film':
|
||||
patron=r'class="taxonomy category" ><span property="name">([^>]+)</span></a><meta property="position" content="2">'
|
||||
block = support.match(item.url, patron=patron,headers=headers).match
|
||||
if block.lower() != 'film':
|
||||
support.log('select = ### è una serie ###')
|
||||
item.contentType='tvshow'
|
||||
return episodios(item)
|
||||
|
||||
@@ -213,7 +213,9 @@ def findvideos(item):
|
||||
log()
|
||||
itemlist =[]
|
||||
|
||||
matches, data = support.match(item, '<iframe class="metaframe rptss" src="([^"]+)"[^>]+>',headers=headers)
|
||||
html = support.match(item, patron='<iframe class="metaframe rptss" src="([^"]+)"[^>]+>',headers=headers)
|
||||
matches = html.matches
|
||||
data = html.data
|
||||
for url in matches:
|
||||
html = httptools.downloadpage(url, headers=headers).data
|
||||
data += str(scrapertools.find_multiple_matches(html, '<meta name="og:url" content="([^"]+)">'))
|
||||
@@ -224,7 +226,7 @@ def findvideos(item):
|
||||
|
||||
data = httptools.downloadpage(item.url).data
|
||||
patron = r'<div class="item"><a href="'+host+'/serietv/([^"\/]+)\/"><i class="icon-bars">'
|
||||
series = scrapertools.find_single_match(data, patron)
|
||||
series = support.match(data, patron=patron).matches
|
||||
titles = support.typo(series.upper().replace('-', ' '), 'bold color kod')
|
||||
goseries = support.typo("Vai alla Serie:", ' bold')
|
||||
itemlist.append(
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": ["ita","sub-ita"],
|
||||
"thumbnail": "https:\/\/raw.githubusercontent.com\/Zanzibar82\/images\/master\/posters\/italiaserie.png",
|
||||
"bannermenu": "https:\/\/raw.githubusercontent.com\/Zanzibar82\/images\/master\/posters\/italiaserie.png",
|
||||
"thumbnail": "italiaserie.png",
|
||||
"bannermenu": "italiaserie.png",
|
||||
"categories": ["tvshow", "vos"],
|
||||
"not_active": ["include_in_newest_peliculas", "include_in_newest_anime"],
|
||||
"settings": []
|
||||
|
||||
@@ -99,7 +99,7 @@ def findvideos(item):
|
||||
if item.contentType == 'episode':
|
||||
data = item.url
|
||||
else:
|
||||
data = support.match(item)[1]
|
||||
data = support.match(item).data
|
||||
if 'link-episode' in data:
|
||||
item.data = data
|
||||
return episodios(item)
|
||||
|
||||
11
channels/pufimovies.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "pufimovies",
|
||||
"name": "PufiMovies",
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": ["ita", "sub-ita"],
|
||||
"thumbnail": "pufimovies.png",
|
||||
"banner": "pufimovies.png",
|
||||
"categories": ["movie","tvshow"],
|
||||
"settings": []
|
||||
}
|
||||
111
channels/pufimovies.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# Canale per PufiMovies
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from core import support
|
||||
|
||||
host = support.config.get_channel_url()
|
||||
|
||||
list_servers = ['mixdrop', 'wstream', 'vupplayer', 'supervideo', 'cloudvideo', 'gounlimited']
|
||||
list_quality = ['default','1080p', '720p', '480p', '360p']
|
||||
|
||||
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.log('search', item)
|
||||
|
||||
text = text.replace(' ', '+')
|
||||
item.url = host + '/search/keyword/' + 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.log('search log:', line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
support.log(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.log({0}.format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@support.scrape
|
||||
def peliculas(item):
|
||||
if item.contentType == 'tvshow' and not item.args:
|
||||
action = 'episodios'
|
||||
patron = r'<div class="movie-box">\s*<a href="(?P<url>[^"]+)">[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)[^>]+>[^>]+>[^>]+>(?P<quality>[^<]+)[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?P<year>\d+)'
|
||||
elif item.contentType == 'movie' and not item.args:
|
||||
patron = r'<div class="existing_item col-6 col-lg-3 col-sm-4 col-xl-4">\s*<div class="movie-box">\s*<a href="(?P<url>(?:http(?:s)://[^/]+)?/(?P<type>[^/]+)/[^"]+)">[^>]+>[^>]+>\D+Streaming\s*(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?:(?P<year>\d+))?[^>]+>[^>]+>[^>]+>[^>]+>(?P<plot>[^<]*)<'
|
||||
elif item.args == 'last':
|
||||
patron = r'<div class="episode-box">[^>]+>[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>[^^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>\D*(?P<season>\d+)[^>]+>\D*(?P<episode>\d+)'
|
||||
elif item.args == 'most':
|
||||
patron =r'div class="sm-113 item">\s*<a href="(?P<url>[^"]+)">[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*(?P<title>[^<]+)'
|
||||
else:
|
||||
patron = r'<div class="movie-box">\s*<a href="(?P<url>(?:http(?:s)://[^/]+)?/(?P<type>[^/]+)/[^"]+)">[^>]+>[^>]+>\D+Streaming\s*(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^>]+>[^>]+>[^>]+>[^>]+>(?P<rating>[^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)[^>]+>[^>]+>[^>]+>\s*(?:(?P<year>\d+))?[^>]+>[^>]+>[^>]+>[^>]+>(?P<plot>[^<]*)<'
|
||||
typeActionDict = {'findvideos':['movie'], 'episodios':['tvshow']}
|
||||
typeContentDict = {'movie':['movie'], 'tvshow':['tvshow']}
|
||||
patronNext = r'<a href="([^"]+)"[^>]+>»'
|
||||
return locals()
|
||||
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
patron = r'<div class="episode-box">[^>]+>[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>\D*(?P<season>\d+)[^>]+>\D*(?P<episode>\d+)'
|
||||
return locals()
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
support.log()
|
||||
# match = support.match(item, patron='wstream', debug=True)
|
||||
return support.server(item)
|
||||
@@ -34,11 +34,11 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
data =''
|
||||
url = support.match(item, patronBlock=r'<iframe width=".+?" height=".+?" src="([^"]+)" allowfullscreen frameborder="0">')[1]
|
||||
seasons = support.match(item, r'<a href="([^"]+)">(\d+)<', r'<h3>STAGIONE</h3><ul>(.*?)</ul>', headers, url)[0]
|
||||
url = support.match(item, patron=r'<iframe width=".+?" height=".+?" src="([^"]+)" allowfullscreen frameborder="0">').match
|
||||
seasons = support.match(url, patron=r'<a href="([^"]+)">(\d+)<', patronBlock=r'<h3>STAGIONE</h3><ul>(.*?)</ul>', headers=headers).matches
|
||||
for season_url, season in seasons:
|
||||
season_url = support.urlparse.urljoin(url, season_url)
|
||||
episodes = support.match(item, r'<a href="([^"]+)">(\d+)<', '<h3>EPISODIO</h3><ul>(.*?)</ul>', headers, season_url)[0]
|
||||
episodes = support.match(season_url, patron=r'<a href="([^"]+)">(\d+)<', patronBlock=r'<h3>EPISODIO</h3><ul>(.*?)</ul>', headers=headers).matches
|
||||
for episode_url, episode in episodes:
|
||||
episode_url = support.urlparse.urljoin(url, episode_url)
|
||||
title = season + "x" + episode.zfill(2) + ' - ' + item.fulltitle
|
||||
|
||||
@@ -108,7 +108,7 @@ def lista_serie(item):
|
||||
else:
|
||||
# Extrae las entradas
|
||||
patron = r'<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron, headers=headers)[0]
|
||||
matches = support.match(item, patron=patron, headers=headers).matches
|
||||
for i, (scrapedurl, scrapedtitle) in enumerate(matches):
|
||||
scrapedplot = ""
|
||||
scrapedthumbnail = ""
|
||||
@@ -148,7 +148,9 @@ def episodios(item, itemlist=[]):
|
||||
patron += r'<p><a href="([^"]+)">'
|
||||
|
||||
|
||||
matches, data = support.match(item, patron, headers=headers)
|
||||
html = support.match(item, patron=patron, headers=headers)
|
||||
matches = html.matches
|
||||
data = html.data
|
||||
|
||||
for scrapedurl, scrapedtitle, scrapedthumbnail in matches:
|
||||
scrapedplot = ""
|
||||
@@ -224,7 +226,9 @@ def peliculas_tv(item):
|
||||
|
||||
patron = '<div class="post-meta">\s*<a href="([^"]+)"\s*title="([^"]+)"\s*class=".*?"></a>'
|
||||
|
||||
matches, data = support.match(item, patron, headers=headers)
|
||||
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!"]:
|
||||
@@ -298,7 +302,7 @@ def search(item, texto):
|
||||
itemlist = []
|
||||
|
||||
patron = '<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron, headers=headers)[0]
|
||||
matches = support.match(item, patron=patron, headers=headers).matches
|
||||
for i, (scrapedurl, scrapedtitle) in enumerate(matches):
|
||||
if texto.upper() in scrapedtitle.upper():
|
||||
scrapedthumbnail = ""
|
||||
@@ -333,7 +337,7 @@ def list_az(item):
|
||||
|
||||
alphabet = dict()
|
||||
patron = '<li class="cat-item cat-item-\d+"><a href="([^"]+)"\s?>([^<]+)</a>'
|
||||
matches = support.match(item, patron, headers=headers)[0]
|
||||
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:
|
||||
|
||||
@@ -35,7 +35,6 @@ def mainlist(item):
|
||||
def peliculas(item):
|
||||
patronBlock = r'<div class="wrap">\s*<h.>.*?</h.>(?P<block>.*?)<footer>'
|
||||
|
||||
|
||||
if item.args != 'update':
|
||||
action = 'episodios'
|
||||
patron = r'<div class="item">\s*<a href="(?P<url>[^"]+)" data-original="(?P<thumb>[^"]+)" class="lazy inner">[^>]+>[^>]+>[^>]+>[^>]+>(?P<title>[^<]+)<'
|
||||
@@ -50,14 +49,15 @@ def peliculas(item):
|
||||
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
seasons, data = support.match(item, r'<option value="(\d+)"[^>]*>\D+(\d+)')
|
||||
seasons = support.match(item, patron=r'<option value="(\d+)"[^>]*>\D+(\d+)').matches
|
||||
patronBlock = r'</select><div style="clear:both"></div></h2>(?P<block>.*?)<div id="trailer" class="tab">'
|
||||
patron = r'(?:<div class="list (?:active)?" data-id="(?P<season>\d+)">[^>]+>)?\s*<a data-id="(?P<episode>\d+)(?:[ ](?P<lang>[SuUbBiItTaA\-]+))?"(?P<url>[^>]+)>[^>]+>[^>]+>(?P<title>.+?)(?:\sSub-ITA)?<'
|
||||
patron = r'(?:<div class="list (?:active)?")?\s*<a data-id="\d+(?:[ ](?P<lang>[SuUbBiItTaA\-]+))?"(?P<other>[^>]+)>.*?Episodio [0-9]+\s?(?:<br>(?P<title>[^<]+))?.*?Stagione (?P<season>[0-9]+) , Episodio - (?P<episode>[0-9]+).*?<(?P<url>.*?<iframe)'
|
||||
def itemHook(item):
|
||||
for value, season in seasons:
|
||||
log(value)
|
||||
log(season)
|
||||
item.title = item.title.replace(value+'x',season+'x')
|
||||
item.url += '\n' + item.other
|
||||
return item
|
||||
return locals()
|
||||
|
||||
@@ -110,7 +110,11 @@ def newest(categoria):
|
||||
def findvideos(item):
|
||||
log()
|
||||
if item.args != 'update':
|
||||
return support.server(item, data=item.url)
|
||||
data = item.url
|
||||
toUnshorten = scrapertools.find_multiple_matches(data, 'https?://buckler.link/[a-zA-Z0-9]+')
|
||||
for link in toUnshorten:
|
||||
data += '\n' + httptools.downloadpage(link, follow_redirects=False).headers["Location"]
|
||||
return support.server(item, data=data)
|
||||
else:
|
||||
itemlist = []
|
||||
item.infoLabels['mediatype'] = 'episode'
|
||||
|
||||
@@ -149,15 +149,15 @@ def findvideos(item):
|
||||
id = item.args['id']
|
||||
season = str(item.args['season'])
|
||||
episode = str(item.args['episode'])
|
||||
res = support.match(item, 'src="([^"]+)"[^>]*></video>', url=url, headers=[['Referer', domain]])
|
||||
res = support.match(url, patron='src="([^"]+)"[^>]*></video>', headers=[['Referer', domain]]).match
|
||||
itemlist = []
|
||||
|
||||
if res[0]:
|
||||
if res:
|
||||
itemlist.append(
|
||||
Item(channel=item.channel,
|
||||
action="play",
|
||||
title='contentful',
|
||||
url=res[0][0],
|
||||
url=res,
|
||||
server='directo',
|
||||
fulltitle=item.fulltitle,
|
||||
thumbnail=item.thumbnail,
|
||||
|
||||
@@ -124,7 +124,7 @@ def anime(item):
|
||||
log()
|
||||
itemlist = []
|
||||
|
||||
seasons = support.match(item, r'<div class="sp-body[^"]+">(.*?)<\/div>')[0]
|
||||
seasons = support.match(item, patron=r'<div class="sp-body[^"]+">(.*?)<\/div>').matches
|
||||
for season in seasons:
|
||||
episodes = scrapertools.find_multiple_matches(season, r'<a.*?href="([^"]+)"[^>]+>([^<]+)<\/a>(.*?)<(:?br|\/p)')
|
||||
for url, title, urls, none in episodes:
|
||||
@@ -208,7 +208,7 @@ def newest(categoria):
|
||||
item = Item()
|
||||
item.url = host +'/aggiornamenti/'
|
||||
|
||||
matches = support.match(item, r'mediaWrapAlt recomended_videos"[^>]+>\s*<a href="([^"]+)" title="([^"]+)" rel="bookmark">\s*<img[^s]+src="([^"]+)"[^>]+>')[0]
|
||||
matches = support.match(item, patron=r'mediaWrapAlt recomended_videos"[^>]+>\s*<a href="([^"]+)" title="([^"]+)" rel="bookmark">\s*<img[^s]+src="([^"]+)"[^>]+>').matches
|
||||
|
||||
for url, title, thumb in matches:
|
||||
title = scrapertools.decodeHtmlentities(title).replace("Permalink to ", "").replace("streaming", "")
|
||||
@@ -236,11 +236,11 @@ def findvideos(item):
|
||||
## data = item.url
|
||||
## else:
|
||||
## data = httptools.downloadpage(item.url, headers=headers).data
|
||||
data = httptools.downloadpage(item.url, headers=headers).data
|
||||
data = support.match(item.url, headers=headers).data
|
||||
|
||||
data = re.sub('\n|\t', ' ', data)
|
||||
data = re.sub(r'>\s+<', '> <', data)
|
||||
check = scrapertools.find_single_match(data, r'<div class="category-film">\s+<h3>\s+(.*?)\s+</h3>\s+</div>')
|
||||
check = support.match(data, patron=r'<div class="category-film">\s+<h3>\s+(.*?)\s+</h3>\s+</div>').match
|
||||
if 'sub' in check.lower():
|
||||
item.contentLanguage = 'Sub-ITA'
|
||||
support.log("CHECK : ", check)
|
||||
|
||||
@@ -104,7 +104,7 @@ def peliculas(item):
|
||||
@support.scrape
|
||||
def episodios(item):
|
||||
anime = True
|
||||
data = support.match(item, headers=headers)[1]
|
||||
data = support.match(item, headers=headers).data
|
||||
if 'https://vcrypt.net' in data:
|
||||
patron = r'(?:<br /> |<p>)(?P<title>[^<]+)<a href="(?P<url>[^"]+)"'
|
||||
else:
|
||||
|
||||
@@ -4,33 +4,8 @@
|
||||
"language": ["ita"],
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"thumbnail": "https://vedohd.pw/wp-content/uploads/2018/12/imgpsh_fullsize.png",
|
||||
"banner": "https://vedohd.pw/wp-content/uploads/2018/12/imgpsh_fullsize.png",
|
||||
"thumbnail": "vedohd.png",
|
||||
"banner": "vedohd.png",
|
||||
"categories": ["movie"],
|
||||
"settings": [
|
||||
{
|
||||
"id": "include_in_global_search",
|
||||
"type": "bool",
|
||||
"label": "Includi in Ricerca Globale",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_peliculas",
|
||||
"type": "bool",
|
||||
"label": "Includi in Novità - Film",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_italiano",
|
||||
"type": "bool",
|
||||
"label": "Includi in Novità - Italiano",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
"settings": []
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ def peliculas(item):
|
||||
|
||||
elif '=' in item.args:
|
||||
json_file = current_session.get(item.url + 'channels', headers=headers, params=payload).json()
|
||||
Filter = support.match(item.args,r'\?([^=]+)=')[0][0]
|
||||
Filter = support.match(item.args, patron=r'\?([^=]+)=').match
|
||||
keys = [i[Filter] for i in json_file['data'] if Filter in i][0]
|
||||
for key in keys:
|
||||
if key not in ['1','2']:
|
||||
@@ -162,7 +162,7 @@ def episodios(item):
|
||||
for episode in episodes:
|
||||
for key in episode:
|
||||
if 'stagione' in key['title'].encode('utf8').lower():
|
||||
match = support.match(key['title'].encode('utf8'), r'[Ss]tagione\s*(\d+) - [Ee]pisodio\s*(\d+)')[0][0]
|
||||
match = support.match(key['title'].encode('utf8'), patron=r'[Ss]tagione\s*(\d+) - [Ee]pisodio\s*(\d+)').match
|
||||
title = match[0]+'x'+match[1] + ' - ' + item.fulltitle
|
||||
make_item = True
|
||||
elif int(key['season_id']) == int(season_id):
|
||||
@@ -206,7 +206,7 @@ def findvideos(item):
|
||||
if 'youtube' in url: item.url = url
|
||||
item.url = url.replace('manifest.f4m','master.m3u8').replace('http://','https://').replace('/z/','/i/')
|
||||
if 'https' not in item.url:
|
||||
url = support.match(item, url='https://or01.top-ix.org/videomg/_definst_/mp4:' + item.url + '/playlist.m3u')[1]
|
||||
url = support.match('https://or01.top-ix.org/videomg/_definst_/mp4:' + item.url + '/playlist.m3u')
|
||||
url = url.split()[-1]
|
||||
itemlist.append(
|
||||
Item(action= 'play',
|
||||
|
||||
@@ -313,8 +313,8 @@ def set_channel_info(parameters):
|
||||
else:
|
||||
content = config.get_localized_category(cat)
|
||||
|
||||
info = '[COLOR yellow]' + config.get_localized_string(70567) + ' [/COLOR]' + content + '\n\n'
|
||||
info += '[COLOR yellow]' + config.get_localized_string(70568) + ' [/COLOR] ' + language
|
||||
info = '[B]' + config.get_localized_string(70567) + ' [/B]' + content + '\n\n'
|
||||
info += '[B]' + config.get_localized_string(70568) + ' [/B] ' + language
|
||||
return info
|
||||
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ def cuadro_completar(item):
|
||||
global dict_default
|
||||
dict_default = {}
|
||||
|
||||
COLOR = ["0xFF8A4B08", "0xFFF7BE81"]
|
||||
COLOR = ["0xFF65B3DA", "0xFFFFFFFF"]
|
||||
# Creamos la lista de campos del infoLabel
|
||||
controls = [("title", "text", config.get_localized_string(60230)),
|
||||
("originaltitle", "text", config.get_localized_string(60231)),
|
||||
|
||||
118
core/support.py
@@ -180,7 +180,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
if debug:
|
||||
regexDbg(item, patron, headers, block)
|
||||
|
||||
known_keys = ['url', 'title', 'title2', 'season', 'episode', 'thumb', 'quality', 'year', 'plot', 'duration', 'genere', 'rating', 'type', 'lang']
|
||||
known_keys = ['url', 'title', 'title2', 'season', 'episode', 'thumb', 'quality', 'year', 'plot', 'duration', 'genere', 'rating', 'type', 'lang', 'other']
|
||||
# Legenda known_keys per i groups nei patron
|
||||
# known_keys = ['url', 'title', 'title2', 'season', 'episode', 'thumb', 'quality',
|
||||
# 'year', 'plot', 'duration', 'genere', 'rating', 'type', 'lang']
|
||||
@@ -201,8 +201,8 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
|
||||
stagione = '' # per quei siti che hanno la stagione nel blocco ma non nelle puntate
|
||||
for i, match in enumerate(matches):
|
||||
if pagination and (pag - 1) * pagination > i: continue # pagination
|
||||
if pagination and i >= pag * pagination: break # pagination
|
||||
if pagination and (pag - 1) * pagination > i and not search: continue # pagination
|
||||
if pagination and i >= pag * pagination and not search: break # pagination
|
||||
listGroups = match.keys()
|
||||
match = match.values()
|
||||
|
||||
@@ -214,12 +214,12 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
for kk in known_keys:
|
||||
val = match[listGroups.index(kk)] if kk in listGroups else ''
|
||||
if val and (kk == "url" or kk == 'thumb') and 'http' not in val:
|
||||
val = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + val
|
||||
val = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + (val if val.startswith('/') else '/' + val)
|
||||
scraped[kk] = val
|
||||
|
||||
if scraped['season']:
|
||||
stagione = scraped['season']
|
||||
episode = scraped['season'] +'x'+ scraped['episode']
|
||||
episode = scraped['season'] +'x'+ scraped['episode'].zfill(2)
|
||||
elif item.season:
|
||||
episode = item.season +'x'+ scraped['episode']
|
||||
elif item.contentType == 'tvshow' and (scraped['episode'] == '' and scraped['season'] == '' and stagione == ''):
|
||||
@@ -295,13 +295,14 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
|
||||
quality=quality,
|
||||
url=scraped["url"],
|
||||
infoLabels=infolabels,
|
||||
thumbnail=item.thumbnail if function == 'episodios' else scraped["thumb"] ,
|
||||
thumbnail=item.thumbnail if function == 'episodios' and not scraped["thumb"] else scraped["thumb"] ,
|
||||
args=item.args,
|
||||
contentSerieName= scraped['title'] if item.contentType or CT != 'movie' and function != 'episodios' else item.fulltitle if function == 'episodios' else '',
|
||||
contentTitle= scraped['title'] if item.contentType or CT == 'movie' else '',
|
||||
contentLanguage = lang1,
|
||||
contentEpisodeNumber=episode if episode else '',
|
||||
news= item.news if item.news else ''
|
||||
news= item.news if item.news else '',
|
||||
other = scraped['other'] if scraped['other'] else ''
|
||||
)
|
||||
|
||||
for lg in list(set(listGroups).difference(known_keys)):
|
||||
@@ -445,7 +446,7 @@ def scrape(func):
|
||||
if anime:
|
||||
if function == 'episodios' or item.action == 'episodios': autorenumber.renumber(itemlist, item, 'bold')
|
||||
else: autorenumber.renumber(itemlist)
|
||||
if anime and autorenumber.check(item) == False and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
|
||||
if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
|
||||
pass
|
||||
else:
|
||||
if addVideolibrary and (item.infoLabels["title"] or item.fulltitle):
|
||||
@@ -637,8 +638,9 @@ def menu(func):
|
||||
|
||||
item = args['item']
|
||||
host = func.__globals__['host']
|
||||
list_servers = func.__globals__['list_servers'] if 'list_servers' in func.__globals__ else 'directo'
|
||||
list_quality = func.__globals__['list_quality'] if 'list_quality' in func.__globals__ else 'default'
|
||||
list_servers = func.__globals__['list_servers'] if 'list_servers' in func.__globals__ else ['directo']
|
||||
list_quality = func.__globals__['list_quality'] if 'list_quality' in func.__globals__ else ['default']
|
||||
log('LIST QUALITY', list_quality)
|
||||
filename = func.__module__.split('.')[1]
|
||||
global_search = False
|
||||
# listUrls = ['film', 'filmSub', 'tvshow', 'tvshowSub', 'anime', 'animeSub', 'search', 'top', 'topSub']
|
||||
@@ -772,31 +774,91 @@ def typo(string, typography=''):
|
||||
return string
|
||||
|
||||
|
||||
def match(item, patron='', patronBlock='', headers='', url='', post=''):
|
||||
def match(item_url_string, **args):
|
||||
'''
|
||||
match is a function that combines httptools and scraper tools:
|
||||
'''
|
||||
log(item_url_string)
|
||||
|
||||
matches = []
|
||||
if type(item) == str:
|
||||
data = item
|
||||
url = None
|
||||
# arguments allowed for scrape
|
||||
patron = args.get('patron', None)
|
||||
patronBlock = args.get('patronBlock', None)
|
||||
patronBlocks = args.get('patronBlock', None)
|
||||
debug = args.get('debug', False)
|
||||
debugBlock = args.get('debugBlock', False)
|
||||
string = args.get('string', False)
|
||||
# remove scrape arguments
|
||||
args = dict([(key, val) for key, val in args.items() if key not in ['patron', 'patronBlock', 'patronBlocks', 'debug', 'debugBlock', 'string']])
|
||||
# dbg()
|
||||
# check type of item_url_string
|
||||
if type(item_url_string) == str:
|
||||
if item_url_string.startswith('http') and not string: url = item_url_string
|
||||
else : data = item_url_string
|
||||
else:
|
||||
url = url if url else item.url
|
||||
if post:
|
||||
data = httptools.downloadpage(url, headers=headers, ignore_response_code=True, post=post).data.replace("'", '"')
|
||||
else:
|
||||
data = httptools.downloadpage(url, headers=headers, ignore_response_code=True).data.replace("'", '"')
|
||||
# if item_url_string is an item use item.url as url
|
||||
url = item_url_string.url
|
||||
|
||||
# if there is a url, download the page
|
||||
if url:
|
||||
if args.get('ignore_response_code', None) is None:
|
||||
args['ignore_response_code'] = True
|
||||
data = httptools.downloadpage(url, **args).data.replace("'", '"')
|
||||
|
||||
# format page data
|
||||
data = re.sub(r'\n|\t', ' ', data)
|
||||
data = re.sub(r'>\s\s*<', '><', data)
|
||||
log('DATA= ', data)
|
||||
|
||||
# collect blocks of a page
|
||||
if patronBlock:
|
||||
block = scrapertools.find_single_match(data, patronBlock)
|
||||
log('BLOCK= ',block)
|
||||
blocks = [scrapertools.find_single_match(data, patronBlock)]
|
||||
elif patronBlocks:
|
||||
blocks = scrapertools.find_multiple_matches(data, patronBlock)
|
||||
else:
|
||||
block = data
|
||||
blocks = [data]
|
||||
|
||||
# match
|
||||
if patron:
|
||||
matches = scrapertools.find_multiple_matches(block, patron)
|
||||
log('MATCHES= ',matches)
|
||||
if type(patron) == str: patron = [patron]
|
||||
for b in blocks:
|
||||
for p in patron:
|
||||
matches += scrapertools.find_multiple_matches(b, p)
|
||||
|
||||
return matches, block
|
||||
# debug mode
|
||||
if config.dev_mode():
|
||||
if debugBlock:
|
||||
match_dbg(data, patronBlock)
|
||||
if debug:
|
||||
for block in blocks:
|
||||
for p in patron:
|
||||
match_dbg(block, p)
|
||||
|
||||
# create a item
|
||||
item = Item(data=data,
|
||||
blocks=blocks,
|
||||
block=blocks[0] if len(blocks) > 0 else '',
|
||||
matches=matches,
|
||||
match=matches[0] if len(matches) > 0 else '')
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def match_dbg(data, patron):
|
||||
import json, urllib2, webbrowser
|
||||
url = 'https://regex101.com'
|
||||
headers = {'content-type': 'application/json'}
|
||||
data = {
|
||||
'regex': patron,
|
||||
'flags': 'gm',
|
||||
'testString': data,
|
||||
'delimiter': '"""',
|
||||
'flavor': 'python'
|
||||
}
|
||||
r = urllib2.Request(url + '/api/regex', json.dumps(data, encoding='latin1'), headers=headers)
|
||||
r = urllib2.urlopen(r).read()
|
||||
permaLink = json.loads(r)['permalinkFragment']
|
||||
webbrowser.open(url + "/r/" + permaLink)
|
||||
|
||||
|
||||
def download(itemlist, item, typography='', function_level=1, function=''):
|
||||
@@ -981,7 +1043,7 @@ def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
|
||||
channel_node = autoplay_node.get(item.channel, {})
|
||||
settings_node = channel_node.get('settings', {})
|
||||
AP = get_setting('autoplay') or settings_node['active']
|
||||
APS = get_setting('autoplay_server_list')
|
||||
HS = config.get_setting('hide_servers')
|
||||
|
||||
if CL and not AP:
|
||||
if get_setting('checklinks', item.channel):
|
||||
@@ -994,7 +1056,7 @@ def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
|
||||
checklinks_number = get_setting('checklinks_number')
|
||||
itemlist = servertools.check_list_links(itemlist, checklinks_number)
|
||||
|
||||
if AutoPlay == True and not 'downloads' in inspect.stack()[3][1] + inspect.stack()[4][1] and item.contentChannel != 'videolibrary':
|
||||
if AutoPlay == True and not 'downloads' in inspect.stack()[3][1] + inspect.stack()[4][1]:
|
||||
autoplay.start(itemlist, item)
|
||||
|
||||
if item.contentChannel != 'videolibrary': videolibrary(itemlist, item, function_level=3)
|
||||
@@ -1010,7 +1072,7 @@ def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
|
||||
VL = True
|
||||
except:
|
||||
pass
|
||||
if not AP or VL or not APS:
|
||||
if not AP or VL or not HS:
|
||||
return itemlist
|
||||
|
||||
def filterLang(item, itemlist):
|
||||
|
||||
51
core/tmdb.py
@@ -160,7 +160,7 @@ def cache_response(fn):
|
||||
conn = sqlite3.connect(fname, timeout=15)
|
||||
c = conn.cursor()
|
||||
url = re.sub('&year=-', '', args[0])
|
||||
logger.error('la url %s' % url)
|
||||
# logger.error('la url %s' % url)
|
||||
url_base64 = base64.b64encode(url)
|
||||
c.execute("SELECT response, added FROM tmdb_cache WHERE url=?", (url_base64,))
|
||||
row = c.fetchone()
|
||||
@@ -185,7 +185,7 @@ def cache_response(fn):
|
||||
# error al obtener los datos
|
||||
except Exception, ex:
|
||||
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
|
||||
logger.error("error en: %s" % message)
|
||||
logger.error("error in: %s" % message)
|
||||
|
||||
return result
|
||||
|
||||
@@ -214,10 +214,10 @@ def set_infoLabels(source, seekTmdb=True, idioma_busqueda=def_lang, forced=False
|
||||
start_time = time.time()
|
||||
if type(source) == list:
|
||||
ret = set_infoLabels_itemlist(source, seekTmdb, idioma_busqueda)
|
||||
logger.debug("Se han obtenido los datos de %i enlaces en %f segundos" % (len(source), time.time() - start_time))
|
||||
logger.debug("The data of %i links were obtained in %f seconds" % (len(source), time.time() - start_time))
|
||||
else:
|
||||
ret = set_infoLabels_item(source, seekTmdb, idioma_busqueda)
|
||||
logger.debug("Se han obtenido los datos del enlace en %f segundos" % (time.time() - start_time))
|
||||
logger.debug("The data of %i links were obtained in %f seconds" % (time.time() - start_time))
|
||||
return ret
|
||||
|
||||
|
||||
@@ -242,6 +242,7 @@ def set_infoLabels_itemlist(item_list, seekTmdb=False, idioma_busqueda=def_lang,
|
||||
negativo en caso contrario.
|
||||
@rtype: list
|
||||
"""
|
||||
|
||||
if not config.get_setting('tmdb_active') and not forced:
|
||||
return
|
||||
import threading
|
||||
@@ -314,7 +315,7 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda=def_lang, lock=None
|
||||
try:
|
||||
numtemporada = int(item.infoLabels['season'])
|
||||
except ValueError:
|
||||
logger.debug("El numero de temporada no es valido")
|
||||
logger.debug("The season number is not valid.")
|
||||
return -1 * len(item.infoLabels)
|
||||
|
||||
if lock:
|
||||
@@ -340,7 +341,7 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda=def_lang, lock=None
|
||||
try:
|
||||
episode = int(item.infoLabels['episode'])
|
||||
except ValueError:
|
||||
logger.debug("El número de episodio (%s) no es valido" % repr(item.infoLabels['episode']))
|
||||
logger.debug("The episode number (%s) is not valid" % repr(item.infoLabels['episode']))
|
||||
return -1 * len(item.infoLabels)
|
||||
|
||||
# Tenemos numero de temporada y numero de episodio validos...
|
||||
@@ -847,7 +848,7 @@ class Tmdb(object):
|
||||
self.__discover()
|
||||
|
||||
else:
|
||||
logger.debug("Creado objeto vacio")
|
||||
logger.debug("Created empty object")
|
||||
|
||||
@staticmethod
|
||||
@cache_response
|
||||
@@ -879,7 +880,7 @@ class Tmdb(object):
|
||||
# error al obtener los datos
|
||||
except Exception, ex:
|
||||
message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args))
|
||||
logger.error("error en: %s" % message)
|
||||
logger.error("error in: %s" % message)
|
||||
dict_data = {}
|
||||
|
||||
return dict_data
|
||||
@@ -895,7 +896,7 @@ class Tmdb(object):
|
||||
url = ('http://api.themoviedb.org/3/genre/%s/list?api_key=a1ab8b8669da03637a4b98fa39c39228&language=%s'
|
||||
% (tipo, idioma))
|
||||
try:
|
||||
logger.info("[Tmdb.py] Rellenando dicionario de generos")
|
||||
logger.info("[Tmdb.py] Filling in dictionary of genres")
|
||||
|
||||
resultado = cls.get_json(url)
|
||||
lista_generos = resultado["genres"]
|
||||
@@ -903,7 +904,7 @@ class Tmdb(object):
|
||||
for i in lista_generos:
|
||||
cls.dic_generos[idioma][tipo][str(i["id"])] = i["name"]
|
||||
except:
|
||||
logger.error("Error generando diccionarios")
|
||||
logger.error("Error generating dictionaries")
|
||||
|
||||
def __by_id(self, source='tmdb'):
|
||||
|
||||
@@ -923,7 +924,7 @@ class Tmdb(object):
|
||||
'&language=%s' % (self.busqueda_id, source, self.busqueda_idioma))
|
||||
buscando = "%s: %s" % (source.capitalize(), self.busqueda_id)
|
||||
|
||||
logger.info("[Tmdb.py] Buscando %s:\n%s" % (buscando, url))
|
||||
logger.info("[Tmdb.py] Searching %s:\n%s" % (buscando, url))
|
||||
resultado = self.get_json(url)
|
||||
|
||||
if resultado:
|
||||
@@ -940,8 +941,8 @@ class Tmdb(object):
|
||||
|
||||
else:
|
||||
# No hay resultados de la busqueda
|
||||
msg = "La busqueda de %s no dio resultados." % buscando
|
||||
logger.debug(msg)
|
||||
msg = "The search of %s gave no results" % buscando
|
||||
# logger.debug(msg)
|
||||
|
||||
def __search(self, index_results=0, page=1):
|
||||
self.result = ResultDictDefault()
|
||||
@@ -963,7 +964,7 @@ class Tmdb(object):
|
||||
url += '&year=%s' % self.busqueda_year
|
||||
|
||||
buscando = self.busqueda_texto.capitalize()
|
||||
logger.info("[Tmdb.py] Buscando %s en pagina %s:\n%s" % (buscando, page, url))
|
||||
logger.info("[Tmdb.py] Searching %s on page %s:\n%s" % (buscando, page, url))
|
||||
resultado = self.get_json(url)
|
||||
|
||||
total_results = resultado.get("total_results", 0)
|
||||
@@ -984,7 +985,7 @@ class Tmdb(object):
|
||||
if index_results >= len(results):
|
||||
# Se ha solicitado un numero de resultado mayor de los obtenidos
|
||||
logger.error(
|
||||
"La busqueda de '%s' dio %s resultados para la pagina %s\nImposible mostrar el resultado numero %s"
|
||||
"The search for '%s' gave %s results for the page %s \n It is impossible to show the result number %s"
|
||||
% (buscando, len(results), page, index_results))
|
||||
return 0
|
||||
|
||||
@@ -997,7 +998,7 @@ class Tmdb(object):
|
||||
|
||||
else:
|
||||
# No hay resultados de la busqueda
|
||||
msg = "La busqueda de '%s' no dio resultados para la pagina %s" % (buscando, page)
|
||||
msg = "The search for '%s' gave no results for page %s" % (buscando, page)
|
||||
logger.error(msg)
|
||||
return 0
|
||||
|
||||
@@ -1021,7 +1022,7 @@ class Tmdb(object):
|
||||
url = ('http://api.themoviedb.org/3/%s?api_key=a1ab8b8669da03637a4b98fa39c39228&%s'
|
||||
% (type_search, "&".join(params)))
|
||||
|
||||
logger.info("[Tmdb.py] Buscando %s:\n%s" % (type_search, url))
|
||||
logger.info("[Tmdb.py] Searcing %s:\n%s" % (type_search, url))
|
||||
resultado = self.get_json(url)
|
||||
|
||||
total_results = resultado.get("total_results", -1)
|
||||
@@ -1045,7 +1046,7 @@ class Tmdb(object):
|
||||
|
||||
if index_results >= len(results):
|
||||
logger.error(
|
||||
"La busqueda de '%s' no dio %s resultados" % (type_search, index_results))
|
||||
"The search for '%s' did not give %s results" % (type_search, index_results))
|
||||
return 0
|
||||
|
||||
# Retornamos el numero de resultados de esta pagina
|
||||
@@ -1061,7 +1062,7 @@ class Tmdb(object):
|
||||
return len(self.results)
|
||||
else:
|
||||
# No hay resultados de la busqueda
|
||||
logger.error("La busqueda de '%s' no dio resultados" % type_search)
|
||||
logger.error("The search for '%s' gave no results" % type_search)
|
||||
return 0
|
||||
|
||||
def load_resultado(self, index_results=0, page=1):
|
||||
@@ -1311,20 +1312,20 @@ class Tmdb(object):
|
||||
url = "http://api.themoviedb.org/3/tv/%s/season/%s?api_key=a1ab8b8669da03637a4b98fa39c39228&language=%s" \
|
||||
"&append_to_response=credits" % (self.result["id"], numtemporada, self.busqueda_idioma)
|
||||
|
||||
buscando = "id_Tmdb: " + str(self.result["id"]) + " temporada: " + str(numtemporada) + "\nURL: " + url
|
||||
logger.info("[Tmdb.py] Buscando " + buscando)
|
||||
buscando = "id_Tmdb: " + str(self.result["id"]) + " season: " + str(numtemporada) + "\nURL: " + url
|
||||
logger.info("[Tmdb.py] Searcing " + buscando)
|
||||
try:
|
||||
self.temporada[numtemporada] = self.get_json(url)
|
||||
|
||||
except:
|
||||
logger.error("No se ha podido obtener la temporada")
|
||||
logger.error("Unable to get the season")
|
||||
self.temporada[numtemporada] = {"status_code": 15, "status_message": "Failed"}
|
||||
self.temporada[numtemporada] = {"episodes": {}}
|
||||
|
||||
if "status_code" in self.temporada[numtemporada]:
|
||||
#Se ha producido un error
|
||||
msg = config.get_localized_string(70496) + buscando + config.get_localized_string(70497)
|
||||
msg += "\nError de tmdb: %s %s" % (
|
||||
msg += "\nTmdb error: %s %s" % (
|
||||
self.temporada[numtemporada]["status_code"], self.temporada[numtemporada]["status_message"])
|
||||
logger.debug(msg)
|
||||
self.temporada[numtemporada] = {}
|
||||
@@ -1351,7 +1352,7 @@ class Tmdb(object):
|
||||
capitulo = int(capitulo)
|
||||
numtemporada = int(numtemporada)
|
||||
except ValueError:
|
||||
logger.debug("El número de episodio o temporada no es valido")
|
||||
logger.debug("The episode or season number is not valid")
|
||||
return {}
|
||||
|
||||
temporada = self.get_temporada(numtemporada)
|
||||
@@ -1361,7 +1362,7 @@ class Tmdb(object):
|
||||
|
||||
if len(temporada["episodes"]) == 0 or len(temporada["episodes"]) < capitulo:
|
||||
# Se ha producido un error
|
||||
logger.error("Episodio %d de la temporada %d no encontrado." % (capitulo, numtemporada))
|
||||
logger.error("Episode %d of the season %d not found." % (capitulo, numtemporada))
|
||||
return {}
|
||||
|
||||
ret_dic = dict()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# https://github.com/VeNoMouS/cloudscraper
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
@@ -38,7 +37,7 @@ except ImportError:
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
__version__ = '1.2.16'
|
||||
__version__ = '1.2.19'
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
@@ -163,7 +162,6 @@ class CloudScraper(Session):
|
||||
|
||||
def request(self, method, url, *args, **kwargs):
|
||||
# pylint: disable=E0203
|
||||
|
||||
if kwargs.get('proxies') and kwargs.get('proxies') != self.proxies:
|
||||
self.proxies = kwargs.get('proxies')
|
||||
|
||||
@@ -198,6 +196,7 @@ class CloudScraper(Session):
|
||||
else:
|
||||
if not resp.is_redirect and resp.status_code not in [429, 503]:
|
||||
self._solveDepthCnt = 0
|
||||
|
||||
return resp
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
@@ -243,7 +242,7 @@ class CloudScraper(Session):
|
||||
return False
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
# check if the response contains a valid Cloudflare reCaptcha challenge
|
||||
# check if the response contains Firewall 1020 Error
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
@staticmethod
|
||||
@@ -270,10 +269,7 @@ class CloudScraper(Session):
|
||||
def is_Challenge_Request(self, resp):
|
||||
if self.is_Firewall_Blocked(resp):
|
||||
sys.tracebacklimit = 0
|
||||
raise RuntimeError(
|
||||
'Cloudflare has a restriction on your IP (Code 1020 Detected), '
|
||||
'you are BLOCKED.'
|
||||
)
|
||||
raise RuntimeError('Cloudflare has blocked this request (Code 1020 Detected).')
|
||||
|
||||
if self.is_reCaptcha_Challenge(resp) or self.is_IUAM_Challenge(resp):
|
||||
return True
|
||||
@@ -434,6 +430,7 @@ class CloudScraper(Session):
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
if submit_url:
|
||||
|
||||
def updateAttr(obj, name, newValue):
|
||||
try:
|
||||
obj[name].update(newValue)
|
||||
@@ -450,13 +447,18 @@ class CloudScraper(Session):
|
||||
'data',
|
||||
submit_url['data']
|
||||
)
|
||||
|
||||
urlParsed = urlparse(resp.url)
|
||||
cloudflare_kwargs['headers'] = updateAttr(
|
||||
cloudflare_kwargs,
|
||||
'headers',
|
||||
{'Referer': resp.url}
|
||||
{
|
||||
'Origin': '{}://{}'.format(urlParsed.scheme, urlParsed.netloc),
|
||||
'Referer': resp.url
|
||||
}
|
||||
)
|
||||
|
||||
ret = self.request(
|
||||
challengeSubmitResponse = self.request(
|
||||
'POST',
|
||||
submit_url['url'],
|
||||
**cloudflare_kwargs
|
||||
@@ -464,13 +466,44 @@ class CloudScraper(Session):
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
# Return response if Cloudflare is doing content pass through instead of 3xx
|
||||
# else request with redirect URL also handle protocol scheme change http -> https
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
if not ret.is_redirect:
|
||||
return ret
|
||||
if not challengeSubmitResponse.is_redirect:
|
||||
return challengeSubmitResponse
|
||||
else:
|
||||
cloudflare_kwargs = deepcopy(kwargs)
|
||||
|
||||
if not urlparse(challengeSubmitResponse.headers['Location']).netloc:
|
||||
cloudflare_kwargs['headers'] = updateAttr(
|
||||
cloudflare_kwargs,
|
||||
'headers',
|
||||
{'Referer': '{}://{}'.format(urlParsed.scheme, urlParsed.netloc)}
|
||||
)
|
||||
return self.request(
|
||||
resp.request.method,
|
||||
'{}://{}{}'.format(
|
||||
urlParsed.scheme,
|
||||
urlParsed.netloc,
|
||||
challengeSubmitResponse.headers['Location']
|
||||
),
|
||||
**cloudflare_kwargs
|
||||
)
|
||||
else:
|
||||
redirectParsed = urlparse(challengeSubmitResponse.headers['Location'])
|
||||
cloudflare_kwargs['headers'] = updateAttr(
|
||||
cloudflare_kwargs,
|
||||
'headers',
|
||||
{'Referer': '{}://{}'.format(redirectParsed.scheme, redirectParsed.netloc)}
|
||||
)
|
||||
return self.request(
|
||||
resp.request.method,
|
||||
challengeSubmitResponse.headers['Location'],
|
||||
**cloudflare_kwargs
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
# Cloudflare is doing http 3xx instead of pass through again....
|
||||
# We shouldn't be here...
|
||||
# Re-request the original query and/or process again....
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
@@ -554,6 +587,17 @@ class CloudScraper(Session):
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
if ssl.OPENSSL_VERSION_INFO < (1, 1, 1):
|
||||
print(
|
||||
"DEPRECATION: The OpenSSL being used by this python install ({}) does not meet the minimum supported "
|
||||
"version (>= OpenSSL 1.1.1) in order to support TLS 1.3 required by Cloudflare, "
|
||||
"You may encounter an unexpected reCaptcha or cloudflare 1020 blocks.".format(
|
||||
ssl.OPENSSL_VERSION
|
||||
)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------- #
|
||||
|
||||
create_scraper = CloudScraper.create_scraper
|
||||
get_tokens = CloudScraper.get_tokens
|
||||
get_cookie_string = CloudScraper.get_cookie_string
|
||||
|
||||
@@ -37,7 +37,7 @@ class UnshortenIt(object):
|
||||
_rapidcrypt_regex = r'rapidcrypt\.net'
|
||||
_cryptmango_regex = r'cryptmango|xshield\.net'
|
||||
_vcrypt_regex = r'vcrypt\.net'
|
||||
_linkup_regex = r'linkup\.pro'
|
||||
_linkup_regex = r'linkup\.pro|buckler.link'
|
||||
|
||||
_maxretries = 5
|
||||
|
||||
|
||||
@@ -429,6 +429,7 @@ def limit_itemlist(itemlist):
|
||||
|
||||
|
||||
def play_from_library(item):
|
||||
itemlist=[]
|
||||
"""
|
||||
Los .strm al reproducirlos desde kodi, este espera que sea un archivo "reproducible" asi que no puede contener
|
||||
más items, como mucho se puede colocar un dialogo de seleccion.
|
||||
@@ -440,12 +441,13 @@ def play_from_library(item):
|
||||
@param item: elemento con información
|
||||
"""
|
||||
logger.info()
|
||||
#logger.debug("item: \n" + item.tostring('\n'))
|
||||
# logger.debug("item: \n" + item.tostring('\n'))
|
||||
|
||||
import xbmcgui
|
||||
import xbmcplugin
|
||||
import xbmc
|
||||
from time import sleep
|
||||
from time import sleep, time
|
||||
from specials import nextep
|
||||
|
||||
# Intentamos reproducir una imagen (esto no hace nada y ademas no da error)
|
||||
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True,
|
||||
@@ -458,8 +460,10 @@ def play_from_library(item):
|
||||
|
||||
# modificamos el action (actualmente la videoteca necesita "findvideos" ya que es donde se buscan las fuentes
|
||||
item.action = "findvideos"
|
||||
check_next_ep = nextep.check(item)
|
||||
|
||||
window_type = config.get_setting("window_type", "videolibrary")
|
||||
|
||||
window_type = 1 if check_next_ep else config.get_setting("window_type", "videolibrary")
|
||||
|
||||
# y volvemos a lanzar kodi
|
||||
if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1:
|
||||
@@ -467,66 +471,85 @@ def play_from_library(item):
|
||||
xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")")
|
||||
|
||||
else:
|
||||
|
||||
# Ventana emergente
|
||||
from specials import videolibrary
|
||||
item.show_server = True
|
||||
|
||||
from specials import videolibrary, autoplay
|
||||
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(70004))
|
||||
p_dialog.update(0, '')
|
||||
|
||||
itemlist = videolibrary.findvideos(item)
|
||||
|
||||
if check_next_ep and autoplay.is_active(item.contentChannel):
|
||||
p_dialog.update(100, '')
|
||||
sleep(0.5)
|
||||
p_dialog.close()
|
||||
item = nextep.return_item(item)
|
||||
if item.next_ep:
|
||||
return play_from_library(item)
|
||||
|
||||
while platformtools.is_playing():
|
||||
# Ventana convencional
|
||||
sleep(5)
|
||||
p_dialog.update(50, '')
|
||||
else:
|
||||
while platformtools.is_playing():
|
||||
# Ventana convencional
|
||||
sleep(5)
|
||||
p_dialog.update(50, '')
|
||||
|
||||
'''# Se filtran los enlaces segun la lista negra
|
||||
if config.get_setting('filter_servers', "servers"):
|
||||
itemlist = servertools.filter_servers(itemlist)'''
|
||||
it = item
|
||||
if item.show_server or not check_next_ep:
|
||||
|
||||
# Se limita la cantidad de enlaces a mostrar
|
||||
if config.get_setting("max_links", "videolibrary") != 0:
|
||||
itemlist = limit_itemlist(itemlist)
|
||||
'''# Se filtran los enlaces segun la lista negra
|
||||
if config.get_setting('filter_servers', "servers"):
|
||||
itemlist = servertools.filter_servers(itemlist)'''
|
||||
|
||||
# Se "limpia" ligeramente la lista de enlaces
|
||||
if config.get_setting("replace_VD", "videolibrary") == 1:
|
||||
itemlist = reorder_itemlist(itemlist)
|
||||
# Se limita la cantidad de enlaces a mostrar
|
||||
if config.get_setting("max_links", "videolibrary") != 0:
|
||||
itemlist = limit_itemlist(itemlist)
|
||||
|
||||
# Se "limpia" ligeramente la lista de enlaces
|
||||
if config.get_setting("replace_VD", "videolibrary") == 1:
|
||||
itemlist = reorder_itemlist(itemlist)
|
||||
|
||||
|
||||
import time
|
||||
p_dialog.update(100, '')
|
||||
time.sleep(0.5)
|
||||
p_dialog.close()
|
||||
p_dialog.update(100, '')
|
||||
sleep(0.5)
|
||||
p_dialog.close()
|
||||
|
||||
|
||||
if len(itemlist) > 0:
|
||||
while not xbmc.Monitor().abortRequested():
|
||||
# El usuario elige el mirror
|
||||
opciones = []
|
||||
for item in itemlist:
|
||||
opciones.append(item.title)
|
||||
if len(itemlist) > 0:
|
||||
while not xbmc.Monitor().abortRequested():
|
||||
# El usuario elige el mirror
|
||||
opciones = []
|
||||
for item in itemlist:
|
||||
opciones.append(item.title)
|
||||
|
||||
# Se abre la ventana de seleccion
|
||||
if (item.contentSerieName != "" and
|
||||
item.contentSeason != "" and
|
||||
item.contentEpisodeNumber != ""):
|
||||
cabecera = ("%s - %sx%s -- %s" %
|
||||
(item.contentSerieName,
|
||||
item.contentSeason,
|
||||
item.contentEpisodeNumber,
|
||||
config.get_localized_string(30163)))
|
||||
else:
|
||||
cabecera = config.get_localized_string(30163)
|
||||
# Se abre la ventana de seleccion
|
||||
if (item.contentSerieName != "" and
|
||||
item.contentSeason != "" and
|
||||
item.contentEpisodeNumber != ""):
|
||||
cabecera = ("%s - %sx%s -- %s" %
|
||||
(item.contentSerieName,
|
||||
item.contentSeason,
|
||||
item.contentEpisodeNumber,
|
||||
config.get_localized_string(30163)))
|
||||
else:
|
||||
cabecera = config.get_localized_string(30163)
|
||||
|
||||
seleccion = platformtools.dialog_select(cabecera, opciones)
|
||||
|
||||
if seleccion == -1:
|
||||
return
|
||||
else:
|
||||
item = videolibrary.play(itemlist[seleccion])[0]
|
||||
item.play_from = 'window'
|
||||
platformtools.play_video(item)
|
||||
seleccion = platformtools.dialog_select(cabecera, opciones)
|
||||
|
||||
if seleccion == -1:
|
||||
return
|
||||
else:
|
||||
item = videolibrary.play(itemlist[seleccion])[0]
|
||||
item.play_from = 'window'
|
||||
platformtools.play_video(item)
|
||||
|
||||
if (platformtools.is_playing() and item.action) or item.server == 'torrent' or autoplay.is_active(item.contentChannel):
|
||||
break
|
||||
|
||||
if it.show_server and check_next_ep:
|
||||
nextep.run(it)
|
||||
sleep(0.5)
|
||||
p_dialog.close()
|
||||
|
||||
from specials import autoplay
|
||||
if (platformtools.is_playing() and item.action) or item.server == 'torrent' or autoplay.is_active(item.contentChannel):
|
||||
break
|
||||
|
||||
@@ -12,7 +12,7 @@ import os
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
import config
|
||||
# import config
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
@@ -22,7 +22,7 @@ from channelselector import get_thumb
|
||||
from core import channeltools
|
||||
from core import trakt_tools, scrapertools
|
||||
from core.item import Item
|
||||
from platformcode import logger, keymaptools
|
||||
from platformcode import logger, keymaptools, config
|
||||
from platformcode import unify
|
||||
|
||||
addon = xbmcaddon.Addon('plugin.video.kod')
|
||||
@@ -683,8 +683,8 @@ def is_playing():
|
||||
|
||||
def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
logger.info()
|
||||
if item.play_from == 'window':
|
||||
force_direct=True
|
||||
# if item.play_from == 'window':
|
||||
# force_direct=True
|
||||
# logger.debug(item.tostring('\n'))
|
||||
logger.debug('item play: %s'%item)
|
||||
xbmc_player = XBMCPlayer()
|
||||
@@ -726,8 +726,8 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
|
||||
mediaurl, view, mpd = get_video_seleccionado(item, seleccion, video_urls)
|
||||
if mediaurl == "":
|
||||
return
|
||||
# no certificate verification
|
||||
mediaurl = mediaurl.replace('https://', 'http://')
|
||||
# # no certificate verification
|
||||
# mediaurl = mediaurl.replace('https://', 'http://')
|
||||
|
||||
# se obtiene la información del video.
|
||||
if not item.contentThumbnail:
|
||||
@@ -1079,7 +1079,7 @@ def get_video_seleccionado(item, seleccion, video_urls):
|
||||
|
||||
def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
logger.info()
|
||||
logger.debug("item:\n" + item.tostring('\n'))
|
||||
# logger.debug("item:\n" + item.tostring('\n'))
|
||||
|
||||
# Movido del conector "torrent" aqui
|
||||
if item.server == "torrent":
|
||||
@@ -1101,7 +1101,7 @@ def set_player(item, xlistitem, mediaurl, view, strm):
|
||||
download_and_play.download_and_play(mediaurl, "download_and_play.mp4", config.get_setting("downloadpath"))
|
||||
return
|
||||
|
||||
elif config.get_setting("player_mode") == 0 or \
|
||||
elif config.get_setting("player_mode") == 0 or item.play_from == 'window' or\
|
||||
(config.get_setting("player_mode") == 3 and mediaurl.startswith("rtmp")):
|
||||
# Añadimos el listitem a una lista de reproducción (playlist)
|
||||
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
|
||||
@@ -251,7 +251,7 @@ def searchSubtitle(item):
|
||||
|
||||
|
||||
def saveSubtitleName(item):
|
||||
if item.show in item.title:
|
||||
if not item.show or item.show in item.title:
|
||||
title = item.title
|
||||
else:
|
||||
title = item.show + " - " + item.title
|
||||
|
||||
@@ -132,8 +132,12 @@ def check():
|
||||
urllib.urlretrieve(file['raw_url'], os.path.join(addonDir, file['filename']))
|
||||
else: # è un file NON testuale, lo devo scaricare
|
||||
# se non è già applicato
|
||||
if not (filetools.isfile(addonDir + file['filename']) and getSha(addonDir + file['filename']) == file['sha']):
|
||||
urllib.urlretrieve(file['raw_url'], os.path.join(addonDir, file['filename']))
|
||||
filename = os.path.join(addonDir, file['filename'])
|
||||
dirname = os.path.dirname(filename)
|
||||
if not (filetools.isfile(addonDir + file['filename']) and getSha(filename) == file['sha']):
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
urllib.urlretrieve(file['raw_url'], filename)
|
||||
alreadyApplied = False
|
||||
elif file['status'] == 'removed':
|
||||
remove(addonDir+file["filename"])
|
||||
|
||||
@@ -5702,7 +5702,39 @@ msgid "Enter another year..."
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70746"
|
||||
msgid "Hide server selection from Autoplay"
|
||||
msgid "When playback ends"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70747"
|
||||
msgid "Hide server selection"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70748"
|
||||
msgid "Go to the next episode"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70749"
|
||||
msgid "Seconds before notification"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70750"
|
||||
msgid "Next Episode in"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70751"
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70752"
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70753"
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#70754"
|
||||
msgid "Compact mode"
|
||||
msgstr ""
|
||||
|
||||
# DNS start [ settings and declaration ]
|
||||
|
||||
@@ -5706,8 +5706,40 @@ msgid "Enter another year..."
|
||||
msgstr "Inserisci un altro anno..."
|
||||
|
||||
msgctxt "#70746"
|
||||
msgid "Hide server selection from Autoplay"
|
||||
msgstr "Nascondi la selezione del server da Autoplay"
|
||||
msgid "When playback ends"
|
||||
msgstr "Al termine della riproduzione"
|
||||
|
||||
msgctxt "#70747"
|
||||
msgid "Hide server selection"
|
||||
msgstr "Nascondi la selezione del server"
|
||||
|
||||
msgctxt "#70748"
|
||||
msgid "Go to the next episode"
|
||||
msgstr "Vai all'episodio successivo"
|
||||
|
||||
msgctxt "#70749"
|
||||
msgid "Seconds before notification"
|
||||
msgstr "Secondi prima della notifica"
|
||||
|
||||
msgctxt "#70750"
|
||||
msgid "Next Episode in"
|
||||
msgstr "Episodio Successivo fra"
|
||||
|
||||
msgctxt "#70751"
|
||||
msgid "seconds"
|
||||
msgstr "secondi"
|
||||
|
||||
msgctxt "#70752"
|
||||
msgid "Do nothing"
|
||||
msgstr "Non fare nulla"
|
||||
|
||||
msgctxt "#70753"
|
||||
msgid "Playback"
|
||||
msgstr "Riproduzione"
|
||||
|
||||
msgctxt "#70754"
|
||||
msgid "Compact mode"
|
||||
msgstr "Modalità compatta"
|
||||
|
||||
# DNS start [ settings and declaration ]
|
||||
msgctxt "#707401"
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
<settings>
|
||||
<!-- General -->
|
||||
<category label="70168">
|
||||
<setting id="player_mode" type="enum" values="Direct|SetResolvedUrl|Built-In|Download and Play" label="30044" default="1"/>
|
||||
<setting id="default_action" type="enum" lvalues="30006|30007|30008" label="30005" default="0"/>
|
||||
<setting id="autoplay" type="bool" label="70562" default="false" visible="true"/>
|
||||
<!-- <setting id="autoplay_next" type="bool" label="Riproduci episodio successivo" default="false" visible="true"/>-->
|
||||
<setting id="autoplay_server_list" type="bool" label="70746" default="false" visible="true"/>
|
||||
<setting id="checklinks" type="bool" label="30020" default="false"/>
|
||||
<setting id="checklinks_number" type="enum" values="5|10|15|20" label="30021" default="0" visible="eq(-1,true)"/>
|
||||
|
||||
<setting id="thumbnail_type" type="enum" lvalues="30011|30012|30200" label="30010" default="2"/>
|
||||
<setting id="channel_language" type="labelenum" values="auto|all|ita" label="30019" default="all"/>
|
||||
<setting id="trakt_sync" type="bool" label="70109" default="false"/>
|
||||
<setting id="forceview" type="bool" label="30043" default="false"/>
|
||||
<setting id="faster_item_serialization" type="bool" label="30300" default="false"/>
|
||||
<setting id="resolver_dns" type="bool" label="707408" default="true" enable="true" visible="true"/>
|
||||
<setting id="debug" type="bool" label="30003" default="false"/>
|
||||
<setting label="70169" type="lsep"/>
|
||||
@@ -40,6 +35,16 @@
|
||||
<setting id="enable_library_menu" label="30131" type="bool" default="true"/>
|
||||
</category>
|
||||
|
||||
<!-- Playback -->
|
||||
<category label="70753">
|
||||
<setting id="player_mode" type="enum" values="Direct|SetResolvedUrl|Built-In|Download and Play" label="30044" default="1"/>
|
||||
<setting id="default_action" type="enum" lvalues="30006|30007|30008" label="30005" default="0"/>
|
||||
<setting id="autoplay" type="bool" label="70562" default="false" visible="true"/>
|
||||
<setting id="hide_servers" type="bool" label="70747" default="false" visible="eq(-1,true)"/>
|
||||
<setting id="checklinks" type="bool" label="30020" default="false"/>
|
||||
<setting id="checklinks_number" type="enum" values="5|10|15|20" label="30021" default="0" visible="eq(-1,true)"/>
|
||||
</category>
|
||||
|
||||
<!-- Videolibrary -->
|
||||
<category label="30131">
|
||||
<!-- <setting id="downloadpath" type="folder" label="30017" default=""/>
|
||||
@@ -53,6 +58,9 @@
|
||||
<setting id="videolibrary_kodi_force" type="bool" label="" default="false" visible="false"/>
|
||||
<setting id="videolibrary_kodi" type="bool" label="70120" enable="lt(-1,2)+eq(0,false)" default="false"/>
|
||||
<setting id="videolibrary_max_quality" type="bool" label="70729" default="false" visible="true"/>
|
||||
<setting id="next_ep" type="enum" label="70746" lvalues="70752|70747|70748" default="0"/>
|
||||
<setting id="next_ep_type" type="bool" label="70754" default="false" visible="eq(-1,2)"/>
|
||||
<setting id="next_ep_seconds" type="enum" values="20|30|40|50|60" label="70749" default="2" visible="!eq(-2,0)"/>
|
||||
</category>
|
||||
|
||||
|
||||
@@ -70,61 +78,8 @@
|
||||
<setting id="custom_theme" type="folder" label="70565" default="" visible="eq(-1,true)"/>
|
||||
<setting id="infoplus_set" type="labelenum" label="70128" lvalues="70129|70130" default="70129"/>
|
||||
<setting id="video_thumbnail_type" type="enum" label="70131" lvalues="70132|70133" default="0"/>
|
||||
<!-- <setting label="70167" type="lsep"/>
|
||||
<setting id="unify" type="bool" label="70134" default="false"/>
|
||||
<setting id="title_color" type="bool" label="70135" default="false" visible="eq(-1,true)"/>
|
||||
<setting id="movie_color" type="labelenum" label="70137"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-1,true)+eq(-2,true)"/>
|
||||
<setting id="tvshow_color" type="labelenum" label="30123"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-2,true)+eq(-3,true)"/>
|
||||
<setting id="year_color" type="labelenum" label="60232"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-3,true)+eq(-4,true)"/>
|
||||
<setting id="rating_1_color" type="labelenum" label="70138"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-4,true)+eq(-5,true)"/>
|
||||
<setting id="rating_2_color" type="labelenum" label="70139"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-5,true)+eq(-6,true)"/>
|
||||
<setting id="rating_3_color" type="labelenum" label="70140"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-6,true)+eq(-7,true)"/>
|
||||
<setting id="quality_color" type="labelenum" label="70141"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-7,true)+eq(-8,true)"/>
|
||||
<setting id="cast_color" type="labelenum" label="59980"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-8,true)+eq(-9,true)"/>
|
||||
<setting id="lat_color" type="labelenum" label="59981"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-9,true)+eq(-10,true)"/>
|
||||
<setting id="vose_color" type="labelenum" label="70142"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-10,true)+eq(-11,true)"/>
|
||||
<setting id="sub-ita_color" type="labelenum" label="70566"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-11,true)+eq(-12,true)"/>
|
||||
<setting id="vos_color" type="labelenum" label="70143"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-12,true)+eq(-13,true)"/>
|
||||
<setting id="vo_color" type="labelenum" label="70144"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-13,true)+eq(-14,true)"/>
|
||||
<setting id="server_color" type="labelenum" label="70145"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-14,true)+eq(-15,true)"/>
|
||||
<setting id="library_color" type="labelenum" label="70146"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-15,true)+eq(-16,true)"/>
|
||||
<setting id="update_color" type="labelenum" label="70147"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-16,true)+eq(-17,true)"/>
|
||||
<setting id="no_update_color" type="labelenum" label="70148"
|
||||
values="[COLOR white]white[/COLOR]|[COLOR cyan]cyan[/COLOR]|[COLOR deepskyblue]deepskyblue[/COLOR]|[COLOR firebrick]firebrick[/COLOR]|[COLOR gold]gold[/COLOR]|[COLOR goldenrod]goldenrod[/COLOR]|[COLOR hotpink]hotpink[/COLOR]|[COLOR limegreen]limegreen[/COLOR]|[COLOR orange]orange[/COLOR]|[COLOR orchid]orchid[/COLOR]|[COLOR red]red[/COLOR]|[COLOR salmon]salmon[/COLOR]|[COLOR yellow]yellow[/COLOR]"
|
||||
default="white" visible="eq(-17,true)+eq(-18,true)"/> -->
|
||||
</category>
|
||||
|
||||
<!-- Other -->
|
||||
<category label="70149">
|
||||
<setting label="70150" type="lsep"/>
|
||||
@@ -137,6 +92,7 @@
|
||||
|
||||
<setting type="sep"/>
|
||||
<setting label="70154" type="lsep"/>
|
||||
<setting id="tmdb_active" default="true" visible="false"/>
|
||||
<setting id="tmdb_threads" type="labelenum" values="5|10|15|20|25|30" label="70155" default="20"/>
|
||||
<setting id="tmdb_plus_info" type="bool" label="70156" default="false"/>
|
||||
<setting id="tmdb_cache" type="bool" label="70157" default="true"/>
|
||||
@@ -155,9 +111,6 @@
|
||||
|
||||
<setting label="Lista activa" type="text" id="lista_activa" default="kodfavorites-default.json" visible="false"/>
|
||||
|
||||
<!-- <setting type="sep"/>
|
||||
<setting label="70583" type="lsep"/>
|
||||
<setting id="addon_quasar_update" type="bool" label="70584" default="false"/> -->
|
||||
</category>
|
||||
<!-- Custom Start -->
|
||||
<category label="70121">
|
||||
@@ -172,5 +125,4 @@
|
||||
|
||||
</category>
|
||||
|
||||
|
||||
</settings>
|
||||
|
||||
88
resources/skins/Default/720p/NextDialog.xml
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<window>
|
||||
<defaultcontrol always="true">20</defaultcontrol>
|
||||
<onload>Dialog.Close(fullscreeninfo,true)</onload>
|
||||
<onload>Dialog.Close(videoosd,true)</onload>
|
||||
<controls>
|
||||
<control type="group">
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="fade" start="0" end="100" time="600" />
|
||||
<effect type="slide" start="115,0" end="0,0" time="600" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="fade" start="100" end="0" time="400" />
|
||||
<effect type="slide" start="0,0" end="115,0" time="400" />
|
||||
</animation>
|
||||
<control type="group">
|
||||
<right>0</right>
|
||||
<top>15</top>
|
||||
<height>40</height>
|
||||
<width>100%</width>
|
||||
<!-- Background -->
|
||||
<control type="image">
|
||||
<top>0</top>
|
||||
<width>100%</width>
|
||||
<height>40</height>
|
||||
<texture colordiffuse="00111111">NextDialog/background-diffuse.png</texture>
|
||||
</control>
|
||||
<control type="group">
|
||||
<top>0</top>
|
||||
<right>0</right>
|
||||
<width>100%</width>
|
||||
<!-- buttons -->
|
||||
<control type="button" id="3012">
|
||||
<left>-1000</left>
|
||||
<top>-1000</top>
|
||||
<height>1</height>
|
||||
<width>1</width>
|
||||
</control>
|
||||
<control type="grouplist" id="20">
|
||||
<orientation>horizontal</orientation>
|
||||
<height>40</height>
|
||||
<itemgap>0</itemgap>
|
||||
<align>right</align>
|
||||
<control type="button" id="11">
|
||||
<label>$ADDON[plugin.video.kod 70750] $INFO[Player.TimeRemaining(ss),,] $ADDON[plugin.video.kod 70751]</label>
|
||||
<onclick>SendClick(3012)</onclick>
|
||||
<height>40</height>
|
||||
<width min="50">auto</width>
|
||||
<font>font30_title</font>
|
||||
<textoffsetx>20</textoffsetx>
|
||||
<textcolor>80FFFFFF</textcolor>
|
||||
<focusedcolor>FFFFFFFF</focusedcolor>
|
||||
<selectedcolor>80FFFFFF</selectedcolor>
|
||||
<shadowcolor>22000000</shadowcolor>
|
||||
<aligny>center</aligny>
|
||||
<align>center</align>
|
||||
<texturefocus border="10" colordiffuse="88232323">NextDialog/background-diffuse.png</texturefocus>
|
||||
<texturenofocus border="10" colordiffuse="88232323">NextDialog/background-diffuse.png</texturenofocus>
|
||||
<pulseonselect>no</pulseonselect>
|
||||
</control>
|
||||
<control type="button" id="3013">
|
||||
<label>$ADDON[plugin.video.kod 60396]</label>
|
||||
<height>40</height>
|
||||
<width min="50">auto</width>
|
||||
<font>font30_title</font>
|
||||
<textoffsetx>20</textoffsetx>
|
||||
<textcolor>80FFFFFF</textcolor>
|
||||
<focusedcolor>FFFFFFFF</focusedcolor>
|
||||
<selectedcolor>80FFFFFF</selectedcolor>
|
||||
<shadowcolor>22000000</shadowcolor>
|
||||
<aligny>center</aligny>
|
||||
<align>center</align>
|
||||
<texturefocus border="10" colordiffuse="88232323">NextDialog/background-diffuse.png</texturefocus>
|
||||
<texturenofocus border="10" colordiffuse="88232323">NextDialog/background-diffuse.png</texturenofocus>
|
||||
<pulseonselect>no</pulseonselect>
|
||||
</control>
|
||||
<control type="image">
|
||||
<top>0</top>
|
||||
<width>30</width>
|
||||
<height>40</height>
|
||||
<texture colordiffuse="88232323">NextDialog/background-diffuse.png</texture>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</controls>
|
||||
</window>
|
||||
89
resources/skins/Default/720p/NextDialogCompact.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<window>
|
||||
<defaultcontrol always="true">20</defaultcontrol>
|
||||
<onload>Dialog.Close(fullscreeninfo,true)</onload>
|
||||
<onload>Dialog.Close(videoosd,true)</onload>
|
||||
<controls>
|
||||
<control type="group">
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="fade" start="0" end="100" time="600" />
|
||||
<effect type="slide" start="115,0" end="0,0" time="600" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="fade" start="100" end="0" time="400" />
|
||||
<effect type="slide" start="0,0" end="115,0" time="400" />
|
||||
</animation>
|
||||
<control type="group">
|
||||
<right>0</right>
|
||||
<top>15</top>
|
||||
<height>50</height>
|
||||
<width>100%</width>
|
||||
<!-- Background -->
|
||||
<control type="image">
|
||||
<top>0</top>
|
||||
<width>100%</width>
|
||||
<height>40</height>
|
||||
<!-- <texture colordiffuse="00111111">NextDialog/button-bg.png</texture> -->
|
||||
</control>
|
||||
<control type="group">
|
||||
<top>0</top>
|
||||
<right>0</right>
|
||||
<width>100%</width>
|
||||
<!-- buttons -->
|
||||
<control type="button" id="3012">
|
||||
<left>-1000</left>
|
||||
<top>-1000</top>
|
||||
<height>1</height>
|
||||
<width>1</width>
|
||||
</control>
|
||||
<control type="grouplist" id="20">
|
||||
<orientation>horizontal</orientation>
|
||||
<height>40</height>
|
||||
<itemgap>0</itemgap>
|
||||
<align>right</align>
|
||||
<control type="button" id="11">
|
||||
<label>[B]$INFO[Player.TimeRemaining(ss),,][/B]</label>
|
||||
<onclick>SendClick(3012)</onclick>
|
||||
<!-- <visible>!Integer.IsGreater(Player.TimeRemaining,59)</visible> -->
|
||||
<height>40</height>
|
||||
<width>65</width>
|
||||
<font>font30_title</font>
|
||||
<textoffsetx>12</textoffsetx>
|
||||
<textcolor>80FFFFFF</textcolor>
|
||||
<focusedcolor>FFFFFFFF</focusedcolor>
|
||||
<selectedcolor>80FFFFFF</selectedcolor>
|
||||
<shadowcolor>22000000</shadowcolor>
|
||||
<aligny>center</aligny>
|
||||
<align>left</align>
|
||||
<texturefocus border="10">NextDialog/play-fo.png</texturefocus>
|
||||
<texturenofocus border="10">NextDialog/play-nf.png</texturenofocus>
|
||||
<pulseonselect>no</pulseonselect>
|
||||
</control>
|
||||
<control type="button" id="3013">
|
||||
<label></label>
|
||||
<height>40</height>
|
||||
<width>40</width>
|
||||
<font>font30_title</font>
|
||||
<textoffsetx>30</textoffsetx>
|
||||
<textcolor>80FFFFFF</textcolor>
|
||||
<focusedcolor>FFFFFFFF</focusedcolor>
|
||||
<selectedcolor>80FFFFFF</selectedcolor>
|
||||
<shadowcolor>22000000</shadowcolor>
|
||||
<aligny>center</aligny>
|
||||
<align>center</align>
|
||||
<texturefocus border="10">NextDialog/close-fo.png</texturefocus>
|
||||
<texturenofocus border="10">NextDialog/close-nf.png</texturenofocus>
|
||||
<pulseonselect>no</pulseonselect>
|
||||
</control>
|
||||
<control type="image">
|
||||
<top>0</top>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<texture>NextDialog/background.png</texture>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
</controls>
|
||||
</window>
|
||||
BIN
resources/skins/Default/media/NextDialog/background-diffuse.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/skins/Default/media/NextDialog/background.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
resources/skins/Default/media/NextDialog/close-fo.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
resources/skins/Default/media/NextDialog/close-nf.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
resources/skins/Default/media/NextDialog/play-fo.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/skins/Default/media/NextDialog/play-nf.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/skins/Default/media/Shortcut - Copia/close.png
Normal file
|
After Width: | Height: | Size: 874 B |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/skins/Default/media/Shortcut - Copia/logo.png
Normal file
|
After Width: | Height: | Size: 838 B |
BIN
resources/skins/Default/media/Shortcut - Copia/white.png
Normal file
|
After Width: | Height: | Size: 167 B |
BIN
resources/skins/Default/media/Shortcut - Copia/white70.png
Normal file
|
After Width: | Height: | Size: 177 B |
@@ -37,7 +37,7 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
i = 0
|
||||
for media_url in matches:
|
||||
# URL del vídeo
|
||||
video_urls.append([vres[i] + " mp4 [Akvideo] ", media_url + '|' + _headers])
|
||||
video_urls.append([vres[i] + " mp4 [Akvideo] ", media_url.replace('https://', 'http://') + '|' + _headers])
|
||||
i = i + 1
|
||||
|
||||
for video_url in video_urls:
|
||||
|
||||
@@ -9,8 +9,10 @@ from platformcode import logger
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
data = httptools.downloadpage(page_url)
|
||||
if data.code == 404:
|
||||
html = httptools.downloadpage(page_url)
|
||||
global data
|
||||
data = html.data
|
||||
if html.code == 404:
|
||||
return False, config.get_localized_string(70292) % "CloudVideo"
|
||||
return True, ""
|
||||
|
||||
@@ -18,7 +20,8 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
global data
|
||||
# data = httptools.downloadpage(page_url).data
|
||||
# enc_data = scrapertools.find_single_match(data, "text/javascript">(.+?)</script>")
|
||||
# dec_data = jsunpack.unpack(enc_data)
|
||||
sources = scrapertools.find_single_match(data, "<source(.*?)</source")
|
||||
|
||||
@@ -20,11 +20,12 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
patronvideos = [
|
||||
r'(https?://(gestyy|rapidteria|sprysphere)\.com/[a-zA-Z0-9]+)',
|
||||
r'(https?://(?:www\.)?(vcrypt|linkup)\.[^/]+/[^/]+/[a-zA-Z0-9_]+)',
|
||||
r'(https?://(?:www\.)?(bit)\.ly/[a-zA-Z0-9]+)',
|
||||
r'(https?://(?:www\.)?(bit|buckler)\.[^/]+/[a-zA-Z0-9]+)',
|
||||
r'(https?://(?:www\.)?(xshield)\.[^/]+/[^/]+/[^/]+/[a-zA-Z0-9_\.]+)'
|
||||
]
|
||||
|
||||
for patron in patronvideos:
|
||||
# from core.support import dbg; dbg()
|
||||
logger.info(" find_videos #" + patron + "#")
|
||||
matches = re.compile(patron).findall(page_url)
|
||||
|
||||
@@ -51,9 +52,10 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
continue
|
||||
else:
|
||||
from lib import unshortenit
|
||||
data, status = unshortenit.unshorten(url)
|
||||
sh = unshortenit.UnshortenIt()
|
||||
data, status = sh.unshorten(url)
|
||||
logger.info("Data - Status zcrypt vcrypt.net: [%s] [%s] " %(data, status))
|
||||
elif 'linkup' in url or 'bit.ly' in url:
|
||||
elif 'linkup' in url or 'bit.ly' in url or 'buckler' in url:
|
||||
logger.info("DATA LINK {}".format(url))
|
||||
if '/tv/' in url:
|
||||
url = url.replace('/tv/','/tva/')
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "mixdrop.co/(?:f|e)/([a-z0-9]+)",
|
||||
"pattern": "mixdrop.[^/]+/(?:f|e)/([a-z0-9]+)",
|
||||
"url": "https://mixdrop.co/e/\\1"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@ import ast
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
global data
|
||||
data = httptools.downloadpage(page_url, cookies=False).data
|
||||
if 'File Not Found' in data:
|
||||
return False, config.get_localized_string(70449) % "SuperVideo"
|
||||
@@ -20,27 +20,35 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
logger.info('SUPER DATA= '+data)
|
||||
# data = httptools.downloadpage(page_url).data
|
||||
global data
|
||||
|
||||
code_data = scrapertools.find_single_match(data, "<script type='text/javascript'>(eval.*)")
|
||||
if code_data:
|
||||
code = jsunpack.unpack(code_data)
|
||||
|
||||
# corrections
|
||||
if 'file' in code and not '"file"'in code: code = code.replace('file','"file"')
|
||||
if 'label' in code and not '"label"'in code: code = code.replace('label','"label"')
|
||||
|
||||
match = scrapertools.find_single_match(code, r'sources:(\[[^]]+\])')
|
||||
lSrc = ast.literal_eval(match)
|
||||
|
||||
lQuality = ['360p', '720p', '1080p', '4k'][:len(lSrc)-1]
|
||||
lQuality.reverse()
|
||||
# lQuality = ['360p', '720p', '1080p', '4k'][:len(lSrc)-1]
|
||||
# lQuality.reverse()
|
||||
|
||||
for source in lSrc:
|
||||
quality = source['label'] if source.has_key('label') else 'auto'
|
||||
video_urls.append(['.' + source['file'].split('.')[-1] + ' [' + quality + '] [SuperVideo]', source['file']])
|
||||
|
||||
for n, source in enumerate(lSrc):
|
||||
quality = 'auto' if n==0 else lQuality[n-1]
|
||||
video_urls.append(['.' + source.split('.')[-1] + '(' + quality + ') [SuperVideo]', source])
|
||||
else:
|
||||
logger.info('ELSE!')
|
||||
matches = scrapertools.find_multiple_matches(data, r'src:\s*"([^"]+)",\s*type:\s*"[^"]+"(?:\s*, res:\s(\d+))?')
|
||||
for url, quality in matches:
|
||||
if url.split('.')[-1] != 'm3u8':
|
||||
video_urls.append([url.split('.')[-1] + ' [' + quality + ']', url])
|
||||
video_urls.append([url.split('.')[-1] + ' [' + quality + '] [SuperVideo]', url])
|
||||
else:
|
||||
video_urls.append([url.split('.')[-1], url])
|
||||
video_urls.sort(key=lambda x: x[0].split()[-1])
|
||||
|
||||
video_urls.sort(key=lambda x: x[0].split()[-2])
|
||||
return video_urls
|
||||
|
||||
@@ -8,6 +8,7 @@ from platformcode import logger
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
global data
|
||||
data = httptools.downloadpage(page_url).data
|
||||
if "Page not found" in data or "File was deleted" in data:
|
||||
return False, "[vidoza] El archivo no existe o ha sido borrado"
|
||||
@@ -19,7 +20,7 @@ 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)
|
||||
data = httptools.downloadpage(page_url).data
|
||||
global data
|
||||
video_urls = []
|
||||
|
||||
s = scrapertools.find_single_match(data, r'sourcesCode\s*:\s*(\[\{.*?\}\])')
|
||||
@@ -30,8 +31,8 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
if 'src' in enlace or 'file' in enlace:
|
||||
url = enlace['src'] if 'src' in enlace else enlace['file']
|
||||
tit = ''
|
||||
if 'label' in enlace: tit += '[%s]' % enlace['label']
|
||||
if 'res' in enlace: tit += '[%s]' % enlace['res']
|
||||
if 'label' in enlace: tit += ' [%s]' % enlace['label']
|
||||
if 'res' in enlace: tit += ' [%s]' % enlace['res']
|
||||
if tit == '' and 'type' in enlace: tit = enlace['type']
|
||||
if tit == '': tit = '.mp4'
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "(https://vup.to/embed-[A-z0-9]+.html)",
|
||||
"url": "\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "vup",
|
||||
"name": "VUP",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "@60654",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "@60655",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "server_vupplayer.png"
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# --------------------------------------------------------
|
||||
# Conector vup By Alfa development Group
|
||||
# --------------------------------------------------------
|
||||
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
data = httptools.downloadpage(page_url).data
|
||||
if "no longer exists" in data or "to copyright issues" in data:
|
||||
return False, "[vup] El video ha sido borrado"
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, user="", password="", video_password=""):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
data = httptools.downloadpage(page_url).data
|
||||
bloque = scrapertools.find_single_match(data, 'sources:.*?\]')
|
||||
video_urls = []
|
||||
videourl = scrapertools.find_multiple_matches(bloque, '"(http[^"]+)')
|
||||
for video in videourl:
|
||||
video_urls.append([".MP4 [vup]", video])
|
||||
video_urls = video_urls[::-1]
|
||||
return video_urls
|
||||
@@ -7,6 +7,8 @@ from platformcode import logger, config
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
data = httptools.downloadpage(page_url)
|
||||
global data
|
||||
data = data.data
|
||||
if data.code == 404:
|
||||
return False, config.get_localized_string(70449)
|
||||
return True, ""
|
||||
@@ -15,8 +17,7 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
logger.info('VUP DATA= '+ data)
|
||||
global data
|
||||
patron = r'sources:\s*\[\{src:\s*"([^"]+)"'
|
||||
matches = scrapertools.find_multiple_matches(data, patron)
|
||||
for url in matches:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"find_videos": {
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "wstream\\.video.*?(?<!api)(?:=|/)(?:embed-)?(?<!streaming\\.php\\?id=)([a-z0-9A-Z]+)(?:[^/_.a-z0-9A-Z]|$)",
|
||||
"pattern": "wstream\\.video(?!<).*?(?<!api)(?:=|/)(?:embed-)?(?<!streaming\\.php\\?id=)([a-z0-9A-Z]+)(?:[^/_.a-z0-9A-Z]|$)",
|
||||
"url": "https://wstream.video/video.php?file_code=\\1"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -11,8 +11,21 @@ headers = [['User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
resp = httptools.downloadpage(page_url)
|
||||
global data
|
||||
data = httptools.downloadpage(page_url).data
|
||||
data = resp.data
|
||||
page_url = resp.url
|
||||
if '/streaming.php' in page_url in page_url:
|
||||
code = httptools.downloadpage(page_url, headers=headers, follow_redirects=False).headers['location'].split('/')[-1].replace('.html','')
|
||||
logger.info('WCODE='+code)
|
||||
page_url = 'https://wstream.video/video.php?file_code=' + code
|
||||
data = httptools.downloadpage(page_url, headers=headers, follow_redirects=True).data
|
||||
|
||||
ID, code = scrapertools.find_single_match(data, r"""input\D*id=(?:'|")([^'"]+)(?:'|").*?value='([a-z0-9]+)""")
|
||||
post = urllib.urlencode({ID: code})
|
||||
|
||||
data = httptools.downloadpage(page_url, headers=headers, post=post, follow_redirects=True).data
|
||||
|
||||
if "Not Found" in data or "File was deleted" in data:
|
||||
return False, config.get_localized_string(70449) % 'Wstream'
|
||||
return True, ""
|
||||
@@ -24,20 +37,7 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
video_urls = []
|
||||
global data
|
||||
|
||||
if '/streaming.php' in page_url or 'html' in page_url:
|
||||
try:
|
||||
code = httptools.downloadpage(page_url, headers=headers, follow_redirects=False).headers['location'].split('/')[-1].replace('.html','')
|
||||
logger.info('WCODE='+code)
|
||||
page_url = 'https://wstream.video/video.php?file_code=' + code
|
||||
data = httptools.downloadpage(page_url, headers=headers, follow_redirects=True).data
|
||||
except:
|
||||
pass
|
||||
|
||||
code = page_url.split('=')[-1]
|
||||
ID = scrapertools.find_single_match(data, r'''input\D*id=(?:'|")([^'"]+)(?:'|")''')
|
||||
post = urllib.urlencode({ID: code})
|
||||
|
||||
data = httptools.downloadpage(page_url, headers=headers, post=post, follow_redirects=True).data
|
||||
headers.append(['Referer', page_url])
|
||||
_headers = urllib.urlencode(dict(headers))
|
||||
|
||||
|
||||
@@ -547,11 +547,9 @@ def episodios(item):
|
||||
if pagination and i >= pag * pagination: break # pagination
|
||||
match = []
|
||||
if episode.has_key('number'):
|
||||
match = support.match(episode['number'], r'(?P<season>\d+)x(?P<episode>\d+)')[0]
|
||||
if match:
|
||||
match = match[0]
|
||||
match = support.match(episode['number'], patron=r'(?P<season>\d+)x(?P<episode>\d+)').match
|
||||
if not match and episode.has_key('title'):
|
||||
match = support.match(episode['title'], r'(?P<season>\d+)x(?P<episode>\d+)')[0]
|
||||
match = support.match(episode['title'], patron=r'(?P<season>\d+)x(?P<episode>\d+)').match
|
||||
if match: match = match[0]
|
||||
if match:
|
||||
episode_number = match[1]
|
||||
@@ -561,7 +559,7 @@ def episodios(item):
|
||||
season_number = episode['season'] if episode.has_key('season') else season if season else 1
|
||||
episode_number = episode['number'] if episode.has_key('number') else ''
|
||||
if not episode_number.isdigit():
|
||||
episode_number = support.match(episode['title'], r'(?P<episode>\d+)')[0][0]
|
||||
episode_number = support.match(episode['title'], patron=r'(?P<episode>\d+)').match
|
||||
ep = int(episode_number) if episode_number else ep
|
||||
if not episode_number:
|
||||
episode_number = str(ep).zfill(2)
|
||||
|
||||
180
specials/nextep.py
Normal file
@@ -0,0 +1,180 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import xbmc, xbmcgui, os
|
||||
from platformcode import config, platformtools, logger
|
||||
from time import time, sleep
|
||||
from core import scrapertools
|
||||
from core import jsontools, filetools
|
||||
from lib.concurrent import futures
|
||||
|
||||
PLAYER_STOP = 13
|
||||
ND = 'NextDialogCompact.xml' if config.get_setting('next_ep_type') else 'NextDialog.xml'
|
||||
|
||||
def check(item):
|
||||
return True if config.get_setting('next_ep') > 0 and item.contentType != 'movie' else False
|
||||
|
||||
|
||||
def return_item(item):
|
||||
logger.info()
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
future = executor.submit(next_ep, item)
|
||||
item = future.result()
|
||||
return item
|
||||
|
||||
def run(item):
|
||||
logger.info()
|
||||
with futures.ThreadPoolExecutor() as executor:
|
||||
future = executor.submit(next_ep, item)
|
||||
item = future.result()
|
||||
if item.next_ep:
|
||||
from platformcode.launcher import play_from_library
|
||||
return play_from_library(item)
|
||||
|
||||
|
||||
def videolibrary(item):
|
||||
from threading import Thread
|
||||
item.videolibrary = True
|
||||
Thread(target=next_ep, args=[item]).start()
|
||||
|
||||
|
||||
def next_ep(item):
|
||||
logger.info()
|
||||
condition = config.get_setting('next_ep')
|
||||
item.next_ep = False
|
||||
item.show_server = True
|
||||
|
||||
VL = True if item.videolibrary else False
|
||||
|
||||
time_over = False
|
||||
time_limit = time() + 30
|
||||
time_steps = [20,30,40,50,60]
|
||||
TimeFromEnd = time_steps[config.get_setting('next_ep_seconds')]
|
||||
|
||||
# wait until the video plays
|
||||
while not platformtools.is_playing() and time() < time_limit:
|
||||
sleep(1)
|
||||
|
||||
while platformtools.is_playing() and time_over == False:
|
||||
try:
|
||||
Total = xbmc.Player().getTotalTime()
|
||||
Actual = xbmc.Player().getTime()
|
||||
Difference = Total - Actual
|
||||
if Total > TimeFromEnd >= Difference:
|
||||
time_over = True
|
||||
except:
|
||||
break
|
||||
|
||||
if time_over:
|
||||
if condition == 1: # hide server afther x second
|
||||
item.show_server = False
|
||||
elif condition == 2: # play next fileif exist
|
||||
|
||||
# check i next file exist
|
||||
current_filename = os.path.basename(item.strm_path)
|
||||
base_path = os.path.basename(os.path.normpath(os.path.dirname(item.strm_path)))
|
||||
path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"),base_path)
|
||||
fileList = []
|
||||
for file in os.listdir(path):
|
||||
if file.endswith('.strm'):
|
||||
fileList.append(file)
|
||||
|
||||
fileList.sort()
|
||||
|
||||
nextIndex = fileList.index(current_filename) + 1
|
||||
if nextIndex == 0 or nextIndex == len(fileList):
|
||||
next_file = None
|
||||
else:
|
||||
next_file = fileList[nextIndex]
|
||||
|
||||
# start next episode window afther x time
|
||||
if next_file:
|
||||
from core.item import Item
|
||||
season_ep = next_file.split('.')[0]
|
||||
season = season_ep.split('x')[0]
|
||||
episode = season_ep.split('x')[1]
|
||||
next_ep = '%sx%s' % (season, episode)
|
||||
item = Item(
|
||||
action= 'play_from_library',
|
||||
channel= 'videolibrary',
|
||||
contentEpisodeNumber= episode,
|
||||
contentSeason= season,
|
||||
contentTitle= next_ep,
|
||||
contentType= 'tvshow',
|
||||
infoLabels= {'episode': episode, 'mediatype': 'tvshow', 'season': season, 'title': next_ep},
|
||||
strm_path= filetools.join(base_path, next_file))
|
||||
|
||||
global ITEM
|
||||
ITEM = item
|
||||
|
||||
nextDialog = NextDialog(ND, config.get_runtime_path())
|
||||
nextDialog.show()
|
||||
while platformtools.is_playing() and not nextDialog.is_still_watching():
|
||||
xbmc.sleep(100)
|
||||
pass
|
||||
|
||||
nextDialog.close()
|
||||
logger.info('Next Episode: ' +str(nextDialog.stillwatching))
|
||||
|
||||
if nextDialog.stillwatching or nextDialog.continuewatching:
|
||||
item.next_ep = True
|
||||
xbmc.Player().stop()
|
||||
if VL:
|
||||
sleep(1)
|
||||
xbmc.executebuiltin('Action(Back)')
|
||||
sleep(0.5)
|
||||
from platformcode.launcher import play_from_library
|
||||
return play_from_library(item)
|
||||
else:
|
||||
item.show_server = False
|
||||
if VL:
|
||||
sleep(1)
|
||||
xbmc.executebuiltin('Action(Back)')
|
||||
sleep(0.5)
|
||||
return None
|
||||
|
||||
return item
|
||||
|
||||
|
||||
class NextDialog(xbmcgui.WindowXMLDialog):
|
||||
item = None
|
||||
cancel = False
|
||||
stillwatching = False
|
||||
continuewatching = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
logger.info()
|
||||
self.action_exitkeys_id = [10, 13]
|
||||
self.progress_control = None
|
||||
self.item = ITEM
|
||||
|
||||
def set_still_watching(self, stillwatching):
|
||||
self.stillwatching = stillwatching
|
||||
|
||||
def set_continue_watching(self, continuewatching):
|
||||
self.continuewatching = continuewatching
|
||||
|
||||
def is_still_watching(self):
|
||||
return self.stillwatching
|
||||
|
||||
def onFocus(self, controlId):
|
||||
pass
|
||||
|
||||
def doAction(self):
|
||||
pass
|
||||
|
||||
def closeDialog(self):
|
||||
self.close()
|
||||
|
||||
def onClick(self, controlId):
|
||||
if controlId == 3012: # Still watching
|
||||
self.set_still_watching(True)
|
||||
self.set_continue_watching(False)
|
||||
self.close()
|
||||
elif controlId == 3013: # Cancel
|
||||
self.set_continue_watching(False)
|
||||
self.close()
|
||||
|
||||
def onAction(self, action):
|
||||
logger.info()
|
||||
if action == PLAYER_STOP:
|
||||
self.set_continue_watching(False)
|
||||
self.close()
|
||||
@@ -40,7 +40,7 @@ class CipherSuiteAdapter(host_header_ssl.HostHeaderSSLAdapter):
|
||||
def __init__(self, domain, CF=False, *args, **kwargs):
|
||||
self.conn = sql.connect(db)
|
||||
self.cur = self.conn.cursor()
|
||||
self.ssl_context = CustomContext(ssl.PROTOCOL_TLS, domain)
|
||||
self.ssl_context = CustomContext(ssl.PROTOCOL_TLS if 'PROTOCOL_TLS' in ssl.__dict__ else ssl.PROTOCOL_SSLv3, domain)
|
||||
self.CF = CF # if cloudscrape is in action
|
||||
self.cipherSuite = kwargs.pop('cipherSuite', ssl._DEFAULT_CIPHERS)
|
||||
|
||||
@@ -99,7 +99,7 @@ class CipherSuiteAdapter(host_header_ssl.HostHeaderSSLAdapter):
|
||||
domain = parse.netloc
|
||||
else:
|
||||
raise requests.exceptions.URLRequired
|
||||
self.ssl_context = CustomContext(ssl.PROTOCOL_TLS, domain)
|
||||
self.ssl_context = CustomContext(ssl.PROTOCOL_TLS if 'PROTOCOL_TLS' in ssl.__dict__ else ssl.PROTOCOL_SSLv3, domain)
|
||||
if self.CF:
|
||||
self.ssl_context.options |= (ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
|
||||
self.ssl_context.set_ciphers(self.cipherSuite)
|
||||
|
||||
@@ -558,6 +558,7 @@ def findvideos(item):
|
||||
server.channel = "videolibrary"
|
||||
server.nfo = item.nfo
|
||||
server.strm_path = item.strm_path
|
||||
server.play_from = item.play_from
|
||||
|
||||
#### Compatibilidad con Kodi 18: evita que se quede la ruedecedita dando vueltas en enlaces Directos
|
||||
if server.action == 'play':
|
||||
@@ -576,7 +577,10 @@ def findvideos(item):
|
||||
|
||||
# return sorted(itemlist, key=lambda it: it.title.lower())
|
||||
autoplay.play_multi_channel(item, itemlist)
|
||||
|
||||
from inspect import stack
|
||||
from specials import nextep
|
||||
if nextep.check(item) and stack()[1][3] == 'run':
|
||||
nextep.videolibrary(item)
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||