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
This commit is contained in:
marco
2020-01-20 18:31:32 +01:00
parent 1b63ed4046
commit d585b0e042
81 changed files with 1447 additions and 990 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 &amp; STREAMING</strong>', url=item.url)[0]
match = support.match(item, patron=r'href="(?P<url>[^"]+)"[^>]+><strong>DOWNLOAD &amp; 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
View 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
View 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)

View File

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

View File

@@ -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+(?:&#215;|×)?\d+\-\d+|\d+(?:&#215;|×)\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)

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,5 @@
"thumbnail": "dreamsub.png",
"banner": "dreamsub.png",
"categories": ["anime", "vos"],
"not_active": ["include_in_newest"],
"settings": []
}

View File

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

View File

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

View File

@@ -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>.*?)(?:&nbsp;|<strong>|<div class="addtoany)'
patron = r'(?:/>|p>)\s*(?P<season>\d+)(?:&#215;|×|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)

View File

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

View File

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

View File

@@ -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
View 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
View 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="([^"]+)"[^>]+>&raquo;'
return locals()
@support.scrape
def episodios(item):
patron = r'<div class="episode-box">[^>]+>[^>]+>[^>]+>\D+Streaming\s(?P<lang>[^"]+)">[^>]+>[^>]+>(?P<quality>[^<]+)<[^>]+>[^>]+>[^>]+>\s*<img src="(?P<thumb>[^"]+)"[^[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*<a href="(?P<url>[^"]+)"[^>]+>[^>]+>(?P<title>[^<]+)<[^>]+>[^>]+>[^>]+>\D*(?P<season>\d+)[^>]+>\D*(?P<episode>\d+)'
return locals()
def findvideos(item):
support.log()
# match = support.match(item, patron='wstream', debug=True)
return support.server(item)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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