test
This commit is contained in:
31
lib/server/__init__.py
Normal file
31
lib/server/__init__.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
|
||||
|
||||
##########################################################3
|
||||
# all resolvers modules in this directory must have following methods:
|
||||
|
||||
# __name__ - name of the resolver module - can override module filename
|
||||
# def supports(url) - returns true iff resolver is able to resolve url to stream otherwise false
|
||||
# def resolve(url) - returns array of all hashmaps that were resolved
|
||||
# - if resolving fails, nothing is returned
|
||||
# - a hash MUST contain key 'url' - it's value is stream URL
|
||||
# - optional keys are 'subs' (link to subtitle), 'quality' (quality string like '240p' or just 'HD'
|
||||
BIN
lib/server/__pycache__/anyfilesresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/anyfilesresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/dailymotionresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/dailymotionresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/divxstageresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/divxstageresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/eserialresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/eserialresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/exashareresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/exashareresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/flashxresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/flashxresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/gosuparkresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/gosuparkresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/hqqresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/hqqresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/koukejseresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/koukejseresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/koukniresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/koukniresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/ksetresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/ksetresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/letwatch.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/letwatch.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/mixturevideoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/mixturevideoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/moevideoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/moevideoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/mojevideosk.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/mojevideosk.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/movshareresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/movshareresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/munkvideoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/munkvideoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/myviruresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/myviruresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/nahnojiresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/nahnojiresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/novamovresovler.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/novamovresovler.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/openload.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/openload.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/playedtoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/playedtoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/playmdresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/playmdresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/server/__pycache__/putlockerresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/putlockerresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/rutuberesolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/rutuberesolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/servertipczresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/servertipczresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/server/__pycache__/stagevuresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/stagevuresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/streamcloudresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/streamcloudresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/streamintoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/streamintoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/streamujtvresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/streamujtvresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/trivialresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/trivialresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videobbresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videobbresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videomailresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videomailresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videonetresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videonetresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videoweedresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videoweedresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videozerresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videozerresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/videram.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/videram.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/vimeoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/vimeoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/vkontakteresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/vkontakteresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/vuuzlaresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/vuuzlaresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/youtuberesolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/youtuberesolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/youwatch.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/youwatch.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/zideonlresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/zideonlresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
BIN
lib/server/__pycache__/zkouknitoresolver.cpython-38.opt-1.pyc
Normal file
BIN
lib/server/__pycache__/zkouknitoresolver.cpython-38.opt-1.pyc
Normal file
Binary file not shown.
104
lib/server/anyfilesresolver.py
Normal file
104
lib/server/anyfilesresolver.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# *
|
||||
# * thanks to http://code.google.com/p/sd-xbmc/
|
||||
# */
|
||||
|
||||
import re
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
import random
|
||||
import decimal
|
||||
|
||||
import util
|
||||
|
||||
__name__='anyfiles'
|
||||
|
||||
BASE_URL = 'http://video.anyfiles.pl'
|
||||
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def _gen_random_decimal(i, d):
|
||||
return decimal.Decimal('%d.%d' % (random.randint(0, i), random.randint(0, d)))
|
||||
|
||||
|
||||
def _decode(param):
|
||||
#-- define variables
|
||||
loc_3 = [0,0,0,0]
|
||||
loc_4 = [0,0,0]
|
||||
loc_2 = ''
|
||||
#-- define hash parameters for decoding
|
||||
dec = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
|
||||
hash1 = ["L", "y", "c", "X", "2", "M", "a", "l", "p", "5", "Q", "e", "R", "t", "Z", "Y", "9", "m", "d", "0", "s", "V", "b", "3", "7", "="]
|
||||
hash2 = ["i", "B", "v", "U", "H", "4", "D", "n", "k", "8", "x", "T", "u", "G", "w", "f", "N", "J", "6", "W", "1", "g", "z", "o", "I", "r"]
|
||||
hash1 = ["c", "u", "4", "V", "z", "5", "k", "m", "y", "p", "L", "J", "I", "d", "0", "M", "9", "e", "3", "8", "v", "l", "i", "7", "n", "="];
|
||||
hash2 = ["t", "Y", "T", "x", "B", "g", "G", "b", "2", "X", "1", "R", "a", "N", "w", "Q", "f", "W", "U", "D", "Z", "s", "6", "H", "o", "r"]
|
||||
|
||||
#-- decode
|
||||
for i in range(0, len(hash1)):
|
||||
re1 = hash1[i]
|
||||
re2 = hash2[i]
|
||||
|
||||
param = param.replace(re1, '___')
|
||||
param = param.replace(re2, re1)
|
||||
param = param.replace('___', re2)
|
||||
|
||||
i = 0
|
||||
while i < len(param):
|
||||
j = 0
|
||||
while j < 4 and i+j < len(param):
|
||||
loc_3[j] = dec.find(param[i+j])
|
||||
j = j + 1
|
||||
|
||||
loc_4[0] = (loc_3[0] << 2) + ((loc_3[1] & 48) >> 4);
|
||||
loc_4[1] = ((loc_3[1] & 15) << 4) + ((loc_3[2] & 60) >> 2);
|
||||
loc_4[2] = ((loc_3[2] & 3) << 6) + loc_3[3];
|
||||
|
||||
j = 0
|
||||
while j < 3:
|
||||
if loc_3[j + 1] == 64:
|
||||
break
|
||||
try:
|
||||
loc_2 += chr(loc_4[j])
|
||||
except:
|
||||
pass
|
||||
j = j + 1
|
||||
|
||||
i = i + 4;
|
||||
|
||||
return loc_2
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
resp = urllib.request.urlopen(url)
|
||||
sessc = resp.headers.get('Set-Cookie').split(';')[0]
|
||||
resp.close()
|
||||
furl = "%s/w.jsp?id=%s&width=620&height=349&pos=&skin=0" % (BASE_URL,m.group('id'))
|
||||
headers = {'Cookie':sessc, 'Referer':url}
|
||||
data = util.request(furl,headers)
|
||||
m1 = re.search('document.cookie = "([^"]+?)"',data)
|
||||
m2 = re.search('src="(\/pcsevlet\?code=[^"]+)', data)
|
||||
if m1 and m2:
|
||||
headers['Cookie'] = headers['Cookie'] + '; ' + m1.group(1)
|
||||
headers['Referer'] = BASE_URL + '/flowplayer/flowplayer.commercial-3.2.16.swf'
|
||||
data = util.request(BASE_URL + m2.group(1),headers)
|
||||
m_vurl = re.search("'url':.*?'(http[^']+?mp4)'", data, re.DOTALL)
|
||||
m_surl = re.search("'captionUrl':.*?'(http[^']+)'",data, re.DOTALL)
|
||||
if m_vurl:
|
||||
resolved = {'url':m_vurl.group(1).strip(),'quality':'???'}
|
||||
if m_surl:
|
||||
resolved['subs'] = m_surl.group(1).strip()
|
||||
return [resolved]
|
||||
else:
|
||||
return []
|
||||
def _regex(url):
|
||||
return re.search('video\.anyfiles\.pl/w\.jsp\?id=(?P<id>\d+)',url,re.IGNORECASE | re.DOTALL)
|
||||
91
lib/server/dailymotionresolver.py
Normal file
91
lib/server/dailymotionresolver.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
|
||||
import re
|
||||
from xml.etree import ElementTree
|
||||
import util
|
||||
from copy import deepcopy
|
||||
import json
|
||||
|
||||
__name__ = 'dailymotion'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'dailymotion.com/embed', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
print('The url is ::', url)
|
||||
id = re.search(r'dailymotion.com/embed/video/(.+)', url).group(1)
|
||||
print('The id is ::', id)
|
||||
headers = {'User-Agent': 'Android'}
|
||||
cookie = {'Cookie': "lang=en; ff=off"}
|
||||
r = util.request("http://www.dailymotion.com/player/metadata/video/" + id,
|
||||
headers)
|
||||
content = json.loads(r)
|
||||
cc = content['qualities']
|
||||
cc = list(cc.items())
|
||||
|
||||
cc = sorted(cc, reverse=True)
|
||||
m_url = ''
|
||||
other_playable_url = []
|
||||
|
||||
items = []
|
||||
result = []
|
||||
|
||||
for source, json_source in cc:
|
||||
source = source.split("@")[0]
|
||||
for item in json_source:
|
||||
|
||||
m_url = item.get('url', None)
|
||||
# xbmc.log("DAILYMOTION - m_url = %s" % m_url, xbmc.LOGNOTICE)
|
||||
if m_url:
|
||||
if source == "auto":
|
||||
continue
|
||||
|
||||
elif '.mnft' in m_url:
|
||||
continue
|
||||
|
||||
if 'video' in item.get('type', None):
|
||||
item = {}
|
||||
item['url'] = m_url
|
||||
item['quality'] = source
|
||||
item['title'] = 'video'
|
||||
items.append(item)
|
||||
|
||||
other_playable_url.append(m_url)
|
||||
|
||||
if items:
|
||||
for item in items:
|
||||
newitem = deepcopy(item)
|
||||
item['lang'] = '???'
|
||||
item['headers'] = headers
|
||||
result.append(newitem)
|
||||
if not result and cc[0][0]=='auto':
|
||||
json_source=cc[0][1]
|
||||
m_url=json_source[0].get('url', None)
|
||||
r = util.request(m_url)
|
||||
streams = re.compile(r'RESOLUTION=\d+x(\d+).*\n([^\s]+)').findall(r)
|
||||
for quality, url in streams:
|
||||
item = {}
|
||||
item['url'] = url
|
||||
item['quality'] = quality + 'p'
|
||||
item['title'] = 'video'
|
||||
result.append(item)
|
||||
return result
|
||||
36
lib/server/divxstageresolver.py
Normal file
36
lib/server/divxstageresolver.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,resolver
|
||||
__name__ = 'divxstage'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
if not _regex(url) == None:
|
||||
data = util.substr(util.request(url),'<embed type=\"video/divx','>')
|
||||
link = re.search('src=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL)
|
||||
if link:
|
||||
return [{'url':link.group(1)}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('embed.divxstage.eu/(.+?)',url,re.IGNORECASE | re.DOTALL)
|
||||
27
lib/server/eserialresolver.py
Normal file
27
lib/server/eserialresolver.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
__name__='eserial'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
stream = re.search('(?P<url>.+?)(\&|$)',m.group('url')).group('url')
|
||||
show = re.search('serial=(?P<url>.+?)(\&|$)',m.group('url'))
|
||||
tit = re.search('srt=(?P<url>.+?)(\&|$)',m.group('url'))
|
||||
if show and tit:
|
||||
return [{'url':stream,'subs':'http://www.eserial.cz/titulky/%s/%s.srt' % (show.group('url'),tit.group('url'))}]
|
||||
return [{'url':stream}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('eserial\.cz/video\.php\?file=(?P<url>.+?)$',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
53
lib/server/exashareresolver.py
Normal file
53
lib/server/exashareresolver.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
from demjson import demjson
|
||||
|
||||
__author__ = 'Jose Riha/Lubomir Kucera'
|
||||
__name__ = 'exashare'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'exashare\.com/embed\-[^\.]+\.html', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
realurl = re.search(r'<iframe src="([^"]+)".*', util.request(url), re.I | re.S).group(1)
|
||||
data = re.search(r'<script[^\.]+?\.setup\((.+?)\);', util.request(realurl), re.I | re.S)
|
||||
if data:
|
||||
data = data.group(1).decode('string_escape')
|
||||
data = re.sub(r'\w+\(([^\)]+?)\)', r'\1', data) # Strip JS functions
|
||||
data = re.sub(r': *([^"][a-zA-Z]+)',r':"\1"', data) # Fix incorrect JSON
|
||||
data = demjson.decode(data)
|
||||
if 'sources' in data:
|
||||
result = []
|
||||
for source in data['sources']:
|
||||
if 'tracks' in data:
|
||||
for track in data['tracks']:
|
||||
result.append({
|
||||
'url': source['file'],
|
||||
'subs': track['file'],
|
||||
'lang': ' %s subtitles' % track['label']
|
||||
})
|
||||
return result
|
||||
return None
|
||||
60
lib/server/flashxresolver.py
Normal file
60
lib/server/flashxresolver.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
|
||||
import re
|
||||
from xml.etree import ElementTree
|
||||
import util
|
||||
from copy import deepcopy
|
||||
|
||||
__name__ = 'flashx'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'flashx\.tv/embed\-[^\.]+\.html', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
data = util.extract_jwplayer_setup(util.request(url))
|
||||
if data and 'sources' in data:
|
||||
result = []
|
||||
for source in data['sources']:
|
||||
items = []
|
||||
if source['file'].endswith('.smil'):
|
||||
tree = ElementTree.fromstring(util.request(source['file']))
|
||||
base_path = tree.find('./head/meta').get('base')
|
||||
for video in tree.findall('./body/switch/video'):
|
||||
items.append({
|
||||
'url': '%s playpath=%s pageUrl=%s swfUrl=%s swfVfy=true' %
|
||||
(base_path, video.get('src'), url,
|
||||
'http://static.flashx.tv/player6/jwplayer.flash.swf'),
|
||||
'quality': video.get('height') + 'p'
|
||||
})
|
||||
else:
|
||||
items.append({'url': source['file']})
|
||||
if len(data['tracks']) > 0:
|
||||
for item in items:
|
||||
for track in data['tracks']:
|
||||
new_item = deepcopy(item)
|
||||
new_item['subs'] = track['file']
|
||||
new_item['lang'] = ' %s subtitles' % track['label']
|
||||
result.append(new_item)
|
||||
else:
|
||||
result += items
|
||||
return result
|
||||
return None
|
||||
42
lib/server/gosuparkresolver.py
Normal file
42
lib/server/gosuparkresolver.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'gosupark'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
#http://gosupark.com/embed-j3erxu8i2o30-630x320.html
|
||||
data = util.request('http://gosupark.com/'+m.group('url'))
|
||||
n = re.search('file: \"(.+?)\"',data,re.IGNORECASE | re.DOTALL)
|
||||
quality = '???'
|
||||
q = re.search('x(\d+)\.html',url)
|
||||
if q:
|
||||
quality = q.group(1)+'p'
|
||||
if not n == None:
|
||||
return [{'quality':quality,'url':n.group(1).strip()}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('gosupark\.com/(?P<url>.+?)$',url,re.IGNORECASE | re.DOTALL)
|
||||
220
lib/server/hqqresolver.py
Normal file
220
lib/server/hqqresolver.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# *
|
||||
# * original based on https://gitorious.org/iptv-pl-dla-openpli/ urlresolver
|
||||
# * update based on https://github.com/LordVenom/
|
||||
# */
|
||||
from io import StringIO
|
||||
import json
|
||||
import util
|
||||
import re
|
||||
import base64
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
__name__ = 'hqq'
|
||||
|
||||
def supports(url):
|
||||
return _regex(url) is not None
|
||||
|
||||
|
||||
def _decode(data):
|
||||
def O1l(string):
|
||||
ret = ""
|
||||
i = len(string) - 1
|
||||
while i >= 0:
|
||||
ret += string[i]
|
||||
i -= 1
|
||||
return ret
|
||||
|
||||
def l0I(string):
|
||||
enc = ""
|
||||
dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
i = 0
|
||||
while True:
|
||||
h1 = dec.find(string[i])
|
||||
i += 1
|
||||
h2 = dec.find(string[i])
|
||||
i += 1
|
||||
h3 = dec.find(string[i])
|
||||
i += 1
|
||||
h4 = dec.find(string[i])
|
||||
i += 1
|
||||
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4
|
||||
o1 = bits >> 16 & 0xff
|
||||
o2 = bits >> 8 & 0xff
|
||||
o3 = bits & 0xff
|
||||
if h3 == 64:
|
||||
enc += chr(o1)
|
||||
else:
|
||||
if h4 == 64:
|
||||
enc += chr(o1) + chr(o2)
|
||||
else:
|
||||
enc += chr(o1) + chr(o2) + chr(o3)
|
||||
if i >= len(string):
|
||||
break
|
||||
return enc
|
||||
|
||||
escape = re.search("var _escape=\'([^\']+)", l0I(O1l(data))).group(1)
|
||||
return escape.replace('%', '\\').decode('unicode-escape')
|
||||
|
||||
|
||||
def _decode2(file_url):
|
||||
def K12K(a, typ='b'):
|
||||
codec_a = ["G", "L", "M", "N", "Z", "o", "I", "t", "V", "y", "x", "p", "R", "m", "z", "u",
|
||||
"D", "7", "W", "v", "Q", "n", "e", "0", "b", "="]
|
||||
codec_b = ["2", "6", "i", "k", "8", "X", "J", "B", "a", "s", "d", "H", "w", "f", "T", "3",
|
||||
"l", "c", "5", "Y", "g", "1", "4", "9", "U", "A"]
|
||||
if 'd' == typ:
|
||||
tmp = codec_a
|
||||
codec_a = codec_b
|
||||
codec_b = tmp
|
||||
idx = 0
|
||||
while idx < len(codec_a):
|
||||
a = a.replace(codec_a[idx], "___")
|
||||
a = a.replace(codec_b[idx], codec_a[idx])
|
||||
a = a.replace("___", codec_b[idx])
|
||||
idx += 1
|
||||
return a
|
||||
|
||||
def _xc13(_arg1):
|
||||
_lg27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
_local2 = ""
|
||||
_local3 = [0, 0, 0, 0]
|
||||
_local4 = [0, 0, 0]
|
||||
_local5 = 0
|
||||
while _local5 < len(_arg1):
|
||||
_local6 = 0
|
||||
while _local6 < 4 and (_local5 + _local6) < len(_arg1):
|
||||
_local3[_local6] = _lg27.find(_arg1[_local5 + _local6])
|
||||
_local6 += 1
|
||||
_local4[0] = ((_local3[0] << 2) + ((_local3[1] & 48) >> 4))
|
||||
_local4[1] = (((_local3[1] & 15) << 4) + ((_local3[2] & 60) >> 2))
|
||||
_local4[2] = (((_local3[2] & 3) << 6) + _local3[3])
|
||||
|
||||
_local7 = 0
|
||||
while _local7 < len(_local4):
|
||||
if _local3[_local7 + 1] == 64:
|
||||
break
|
||||
_local2 += chr(_local4[_local7])
|
||||
_local7 += 1
|
||||
_local5 += 4
|
||||
return _local2
|
||||
|
||||
return _xc13(K12K(file_url, 'e'))
|
||||
|
||||
|
||||
def _decode3(w, i, s, e):
|
||||
var1 = 0
|
||||
var2 = 0
|
||||
var3 = 0
|
||||
var4 = []
|
||||
var5 = []
|
||||
while (True):
|
||||
if (var1 < 5):
|
||||
var5.append(w[var1])
|
||||
elif (var1 < len(w)):
|
||||
var4.append(w[var1])
|
||||
var1 += 1
|
||||
if (var2 < 5):
|
||||
var5.append(i[var2])
|
||||
elif (var2 < len(i)):
|
||||
var4.append(i[var2])
|
||||
var2 += 1
|
||||
if (var3 < 5):
|
||||
var5.append(s[var3])
|
||||
elif (var3 < len(s)):
|
||||
var4.append(s[var3])
|
||||
var3 += 1
|
||||
if (len(w) + len(i) + len(s) + len(e) == len(var4) + len(var5) + len(e)):
|
||||
break
|
||||
var6 = ''.join(var4)
|
||||
var7 = ''.join(var5)
|
||||
var2 = 0
|
||||
result = []
|
||||
for var1 in range(0, len(var4), 2):
|
||||
ll11 = -1
|
||||
if (ord(var7[var2]) % 2):
|
||||
ll11 = 1
|
||||
result.append(chr(int(var6[var1:var1 + 2], 36) - ll11))
|
||||
var2 += 1
|
||||
if (var2 >= len(var5)):
|
||||
var2 = 0
|
||||
return ''.join(result)
|
||||
|
||||
def _decode_data(data):
|
||||
valuesPattern = r";}\('(\w+)','(\w*)','(\w*)','(\w*)'\)\)"
|
||||
values = re.search(valuesPattern, data, re.DOTALL)
|
||||
return _decode3(values.group(1), values.group(2), values.group(3), values.group(4))
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
vid = m.group('vid')
|
||||
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Content-Type': 'text/html; charset=utf-8'}
|
||||
|
||||
player_url = "http://hqq.tv/player/embed_player.php?vid=%s&autoplay=no" % vid
|
||||
data = util.request(player_url, headers)
|
||||
|
||||
data = _decode_data(data)
|
||||
data = _decode_data(data)
|
||||
blocs = data.split(';; ')
|
||||
data = _decode_data(blocs[1])
|
||||
|
||||
jsonInfo = util.request("http://hqq.tv/player/ip.php?type=json", headers)
|
||||
jsonIp = json.loads(jsonInfo)['ip']
|
||||
at = re.search(r'at = "(\w+)";', data, re.DOTALL)
|
||||
if jsonIp and at:
|
||||
get_data = {'iss': jsonIp, 'vid': vid, 'at': at.group(1), 'autoplayed': 'yes', 'referer': 'on',
|
||||
'http_referer': '', 'pass': '', 'embed_from' : '', 'need_captcha' : '0' }
|
||||
|
||||
data = urllib.parse.unquote(util.request("http://hqq.tv/sec/player/embed_player.php?" +
|
||||
urllib.parse.urlencode(get_data), headers))
|
||||
|
||||
l = re.search(r'link_1: ([a-zA-Z]+), server_1: ([a-zA-Z]+)', data)
|
||||
vid_server = re.search(r'var ' + l.group(2) + ' = "([^"]+)"', data).group(1)
|
||||
vid_link = re.search(r'var ' + l.group(1) + ' = "([^"]+)"', data).group(1)
|
||||
|
||||
if vid_server and vid_link:
|
||||
get_data = {'server_1': vid_server, 'link_1': vid_link, 'at': at.group(1), 'adb': '0/',
|
||||
'b': '1', 'vid': vid }
|
||||
headers['x-requested-with'] = 'XMLHttpRequest'
|
||||
data = util.request("http://hqq.tv/player/get_md5.php?" + urllib.parse.urlencode(get_data), headers)
|
||||
jsonData = json.loads(data)
|
||||
encodedm3u = jsonData['file']
|
||||
decodedm3u = _decode2(encodedm3u.replace('\\', ''))
|
||||
|
||||
agent = 'User-Agent=Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X)'
|
||||
return [{'url': decodedm3u + '|' + agent, 'quality': '360p'}]
|
||||
return None
|
||||
|
||||
|
||||
def _regex(url):
|
||||
match = re.search("(hqq|netu)\.tv/watch_video\.php\?v=(?P<vid>[0-9A-Za-z]+)", url)
|
||||
if match:
|
||||
return match
|
||||
match = re.search(r'(hqq|netu)\.tv/player/embed_player\.php\?vid=(?P<vid>[0-9A-Za-z]+)', url)
|
||||
if match:
|
||||
return match
|
||||
match = re.search(r'(hqq|netu)\.tv/player/hash\.php\?hash=\d+', url)
|
||||
if match:
|
||||
match = re.search(r'var\s+vid\s*=\s*\'(?P<vid>[^\']+)\'', urllib.parse.unquote(util.request(url)))
|
||||
if match:
|
||||
return match
|
||||
b64enc = re.search(r'data:text/javascript\;charset\=utf\-8\;base64([^\"]+)', url)
|
||||
b64dec = b64enc and base64.decodestring(b64enc.group(1))
|
||||
enc = b64dec and re.search(r"\'([^']+)\'", b64dec).group(1)
|
||||
if enc:
|
||||
decoded = _decode(enc)
|
||||
match = re.search(r'<input name="vid"[^>]+? value="(?P<vid>[^"]+?)">', decoded)
|
||||
if re.search(r'<form(.+?)action="[^"]*(hqq|netu)\.tv/player/embed_player\.php"[^>]*>',
|
||||
decoded) and match:
|
||||
return match
|
||||
return None
|
||||
36
lib/server/koukejseresolver.py
Normal file
36
lib/server/koukejseresolver.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2013 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,urllib.request,urllib.error,urllib.parse,traceback
|
||||
__name__ = 'koukejse.cz'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
data = util.request(url)
|
||||
stream = re.search('_video_file = \'(?P<url>[^\']+)',data)
|
||||
if stream:
|
||||
return [{'name':__name__,'quality':'360p','url':stream.group('url'),'surl':url}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('koukejse\.cz/(.+?)',url,re.IGNORECASE | re.DOTALL)
|
||||
88
lib/server/koukniresolver.py
Normal file
88
lib/server/koukniresolver.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re, util, urllib.request, urllib.error, urllib.parse, traceback
|
||||
__name__ = 'koukni.cz'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
iframe = _iframe(url)
|
||||
if iframe:
|
||||
return iframe[0]['url']
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
try:
|
||||
iframe = _iframe(url)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return
|
||||
if iframe:
|
||||
return iframe
|
||||
# else:
|
||||
# return [{'name':__name__,'quality':'720p','url':url,'surl':url}]
|
||||
|
||||
def _furl(url):
|
||||
if url.startswith('http'):
|
||||
return url
|
||||
url = url.lstrip('./')
|
||||
return 'http://www.koukni.cz/' + url
|
||||
|
||||
def _iframe(url):
|
||||
index = url.find('&')
|
||||
if index > 0:
|
||||
url = url[:index]
|
||||
iframe = re.search('(\d+)$', url, re.IGNORECASE | re.DOTALL)
|
||||
if iframe:
|
||||
data = util.request(url)
|
||||
ress = re.search('var api = flowplayer\(\),\s+resolutions = \{([^\}]+)\}', data, re.IGNORECASE | re.DOTALL)
|
||||
valid_ress = re.compile("<span[^>]*>([^<]+)</span>", re.IGNORECASE | re.DOTALL).findall(data)
|
||||
subs = re.search('<track.+?src=\"(?P<url>[^\"]+)', data, re.IGNORECASE | re.DOTALL)
|
||||
if ress:
|
||||
ret = []
|
||||
ress = ress.group(1).strip().split(',')
|
||||
for r in ress:
|
||||
r = r.replace('"', '').split(':')
|
||||
res = r[0].strip()
|
||||
vurl = _furl(r[1].strip())
|
||||
if res in valid_ress:
|
||||
v = {'name':__name__, 'url':vurl, 'quality':res, 'surl':url,'subs':''}
|
||||
if subs:
|
||||
v['subs'] = _furl(subs.group('url'))
|
||||
ret.append(v)
|
||||
if len(ret)>0:
|
||||
return ret
|
||||
video = re.search('url\: \'(?P<url>mp4[^\']+)', data, re.IGNORECASE | re.DOTALL)
|
||||
subs = re.search('captionUrl\: \'(?P<url>[^\']+)', data, re.IGNORECASE | re.DOTALL)
|
||||
if video:
|
||||
ret = {'name':__name__, 'quality':'720p', 'surl':url}
|
||||
ret['url'] = 'rtmp://koukni.cz/mp4 playpath=%s' % video.group('url')
|
||||
if subs:
|
||||
ret['subs'] = _furl(subs.group('url'))
|
||||
return [ret]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('(www\.)?koukni.cz/(.+?)', url, re.IGNORECASE | re.DOTALL)
|
||||
54
lib/server/ksetresolver.py
Normal file
54
lib/server/ksetresolver.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2013 mx3L
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re, util, decimal, random, base64, urllib.request, urllib.parse, urllib.error
|
||||
|
||||
__name__ = 'kset'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def gen_random_decimal(i, d):
|
||||
return decimal.Decimal('%d.%d' % (random.randint(0, i), random.randint(0, d)))
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
id = int(m.group('id'))
|
||||
headers = {
|
||||
"Referer":"http://st.kset.kz/pl/pl.swf"
|
||||
}
|
||||
|
||||
params = {
|
||||
'id':id,
|
||||
'ref':'http://kset.kz/video_frame.php?id=%d' % id,
|
||||
'r':gen_random_decimal(0, 99999999999999)
|
||||
}
|
||||
quality = "480p"
|
||||
data = util.request("http://kset.kz/v.php?" + urllib.parse.urlencode(params), headers=headers)
|
||||
item = util.json.loads(base64.decodestring(data))
|
||||
return [{'quality':quality, 'url':item['file']}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
m = re.search('http://kset\.kz/video_frame\.php\?id=(?P<id>[0-9]+)', url, re.IGNORECASE | re.DOTALL)
|
||||
return m
|
||||
|
||||
43
lib/server/letwatch.py
Normal file
43
lib/server/letwatch.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
from demjson import demjson
|
||||
|
||||
__author__ = 'Lubomir Kucera'
|
||||
__name__ = 'letwatch'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'letwatch\.us/embed\-[^\.]+\.html', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
data = re.search(r'<script[^\.]+?\.setup\(([^\)]+?)\);', util.request(url), re.I | re.S)
|
||||
if data:
|
||||
data = demjson.decode(data.group(1).decode('string_escape'))
|
||||
if 'sources' in data:
|
||||
result = []
|
||||
for source in data['sources']:
|
||||
result.append({'url': source['file'], 'quality': source['label']})
|
||||
return result
|
||||
return None
|
||||
68
lib/server/mixturevideoresolver.py
Normal file
68
lib/server/mixturevideoresolver.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,urllib.request,urllib.error,urllib.parse,traceback,resolver
|
||||
|
||||
__name__ = 'mixturecloud'
|
||||
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
class MyHTTPRedirectHandler(urllib.request.HTTPRedirectHandler):
|
||||
|
||||
def http_error_302(self, req, fp, code, msg, headers):
|
||||
self.location = headers.getheader('Location')
|
||||
return urllib.request.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
defrhandler = urllib.request.HTTPRedirectHandler
|
||||
cookieprocessor = urllib.request.HTTPCookieProcessor()
|
||||
redirecthandler = MyHTTPRedirectHandler()
|
||||
opener = urllib.request.build_opener(redirecthandler, cookieprocessor)
|
||||
urllib.request.install_opener(opener)
|
||||
req = urllib.request.Request(url)
|
||||
response = urllib.request.urlopen(req)
|
||||
response.close()
|
||||
urllib.request.install_opener(urllib.request.build_opener(defrhandler,cookieprocessor))
|
||||
# mixturevideo uses REDIRECT to 'secret url' ;-)
|
||||
url = redirecthandler.location
|
||||
item = resolver.item()
|
||||
item['surl'] = url
|
||||
item['name'] = __name__
|
||||
try:
|
||||
ishd = re.search('hd\.state=([^\&]+)',url).group(1)
|
||||
streamer = re.search('streamer=([^$]+)',url).group(1)+'&start=0&'
|
||||
if ishd == 'true':
|
||||
item['url'] = streamer + 'hd.file=' +re.search('hd\.file=([^\&]+)',url).group(1)
|
||||
item['quality'] = 'hd'
|
||||
else:
|
||||
item['url'] = streamer + 'file=' +re.search('file=([^\&]+)',url).group(1)
|
||||
return [item]
|
||||
except:
|
||||
traceback.print_exc()
|
||||
pass
|
||||
|
||||
def _regex(url):
|
||||
return re.search('player\.mixturecloud\.com',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
41
lib/server/moevideoresolver.py
Normal file
41
lib/server/moevideoresolver.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,urllib.request,urllib.error,urllib.parse,urllib.parse
|
||||
__name__ = 'moevideo'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
id = m.group('id')
|
||||
post = {'r':'["tVL0gjqo5",["preview/flv_image",{"uid":"'+id+'"}],["preview/flv_link",{"uid":"'+id+'"}]]'}
|
||||
data = util.post('http://api.letitbit.net',post)
|
||||
data = data.replace('\\','')
|
||||
print(data)
|
||||
link = re.search('link\"\:\"(?P<link>[^\"]+)',data)
|
||||
if link:
|
||||
return [{'url':link.group('link')}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('moevideo.net/video\.php\?file=(?P<id>[^\&]+)',url,re.IGNORECASE | re.DOTALL)
|
||||
47
lib/server/mojevideosk.py
Normal file
47
lib/server/mojevideosk.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2016 Jose Riha
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
import time
|
||||
import pickle
|
||||
|
||||
__author__ = 'Jose Riha'
|
||||
__name__ = 'mojevideo.sk'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'mojevideo\.sk/video/\w+/.+\.html', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
cookies = {}
|
||||
util.init_urllib(cookies)
|
||||
data = util.request(url)
|
||||
view = list(pickle.loads(util._cookie_jar.dump())[
|
||||
'.mojevideo.sk']['/'].keys())[0]
|
||||
st = re.search(r'vHash=\[\'([^\']+)', data)
|
||||
if not st:
|
||||
return None
|
||||
st = st.group(1)
|
||||
tim = int(time.time())
|
||||
base = 'http://fs5.mojevideo.sk:8080/securevd/'
|
||||
return [{'url': base + view.replace('view', '') + '.mp4?st=%s&e=%s|Cookie=%s=1' % (st, tim, view)}]
|
||||
35
lib/server/movshareresolver.py
Normal file
35
lib/server/movshareresolver.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__='movshare'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
if not _regex(url) == None:
|
||||
data = util.substr(util.request(url),'<embed type=\"video/divx','>')
|
||||
stream = re.search('src=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
return [{'url':stream}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('movshare.net/(.+?)',url,re.IGNORECASE | re.DOTALL)
|
||||
45
lib/server/munkvideoresolver.py
Normal file
45
lib/server/munkvideoresolver.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
|
||||
__name__='munkvideo'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
data = util.request(url)
|
||||
streams = re.search('res0\:[^\"]*\"([^\"]+)',data,re.IGNORECASE|re.DOTALL)
|
||||
subs = re.search('sub0\:[^\"]*\".*?(http[^\"]*)',data,re.IGNORECASE|re.DOTALL)
|
||||
rn = re.search('rn\:[^\"]*\"([^\"]*)',data,re.IGNORECASE|re.DOTALL)
|
||||
if streams and subs and rn:
|
||||
streams = streams.group(1).split(',')
|
||||
subs = subs.group(1)
|
||||
rn = rn.group(1).split(',')
|
||||
index = 0
|
||||
result = []
|
||||
headers = {'Referer':'me'}
|
||||
for stream in streams:
|
||||
q = rn[index]
|
||||
if q == 'HD':
|
||||
q = '720p'
|
||||
else:
|
||||
q = '???'
|
||||
if len(subs) > 0:
|
||||
result.append({'url':stream,'quality':q,'subs':subs,'headers':headers})
|
||||
else:
|
||||
result.append({'url':stream,'quality':q,'headers':headers})
|
||||
index+=1
|
||||
return result
|
||||
|
||||
def _regex(url):
|
||||
return re.search('munkvideo\.cz/video/',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
59
lib/server/myviruresolver.py
Normal file
59
lib/server/myviruresolver.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
|
||||
import re
|
||||
import util
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import pickle
|
||||
from demjson import demjson
|
||||
|
||||
__author__ = 'Jose Riha'
|
||||
__name__ = 'myviru'
|
||||
|
||||
UA = urllib.parse.quote(util.UA)
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'http://myvi.ru/player/flash', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
cookies = {}
|
||||
result = []
|
||||
util.init_urllib(cookies)
|
||||
id = re.search(r'.*player/flash/(?P<url>.+)', url).group('url')
|
||||
r = util.request('http://myvi.ru/player/api/Video/Get/%s?sig' % id)
|
||||
jsondata = demjson.decode(r)
|
||||
playlist = jsondata['sprutoData']['playlist'][0]
|
||||
uuid = pickle.loads(util._cookie_jar.dump())[
|
||||
'.myvi.ru']['/']['UniversalUserID']
|
||||
for f in playlist['video']:
|
||||
streamurl = f['url']
|
||||
streamurl += '|Cookie=UniversalUserID%3D' + urllib.parse.quote(uuid.value)
|
||||
streamurl += '&User-Agent=' + UA
|
||||
result.append({'url': streamurl})
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
29
lib/server/nahnojiresolver.py
Normal file
29
lib/server/nahnojiresolver.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__='nahnoji'
|
||||
__priiority__=-1
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'nahnoji\.cz/.+', url) is not None
|
||||
|
||||
def resolve(url):
|
||||
# returns the stream url
|
||||
stream = []
|
||||
if url.endswith('.flv'):
|
||||
stream = [url]
|
||||
else:
|
||||
page = util.parse_html(url)
|
||||
stream = ['http://nahnoji.cz'+x['src'] for x in page.select('source[type=video/mp4]')]
|
||||
if stream:
|
||||
result=[]
|
||||
for streamurl in stream:
|
||||
result.append({'name':__name__,'quality':'360p','url':streamurl,'surl':url})
|
||||
return result
|
||||
|
||||
36
lib/server/novamovresovler.py
Normal file
36
lib/server/novamovresovler.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import util,re
|
||||
__name__ = 'novamov'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
if supports(url):
|
||||
data = util.request(url)
|
||||
m = re.search('flashvars.file=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL)
|
||||
n = re.search('flashvars.filekey=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL)
|
||||
if not m == None and not n == None:
|
||||
data = util.request('http://www.novamov.com/api/player.api.php?key=%s&file=%s&user=undefined&pass=undefined&codes=1' % (n.group(1),m.group(1)))
|
||||
stream = re.search('url=([^\&]+)',data).group(1)
|
||||
return [{'url':stream}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('novamov\.com',url,re.IGNORECASE | re.DOTALL)
|
||||
276
lib/server/openload.py
Normal file
276
lib/server/openload.py
Normal file
@@ -0,0 +1,276 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
# uses code fragments from https://github.com/LordVenom/venom-xbmc-addons
|
||||
import re
|
||||
import util
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
from aadecode import AADecoder
|
||||
|
||||
class cRequestHandler:
|
||||
REQUEST_TYPE_GET = 0
|
||||
REQUEST_TYPE_POST = 1
|
||||
|
||||
def __init__(self, sUrl):
|
||||
self.__sUrl = sUrl
|
||||
self.__sRealUrl = ''
|
||||
self.__cType = 0
|
||||
self.__aParamaters = {}
|
||||
self.__aHeaderEntries = []
|
||||
self.removeBreakLines(True)
|
||||
self.removeNewLines(True)
|
||||
self.__setDefaultHeader()
|
||||
|
||||
def removeNewLines(self, bRemoveNewLines):
|
||||
self.__bRemoveNewLines = bRemoveNewLines
|
||||
|
||||
def removeBreakLines(self, bRemoveBreakLines):
|
||||
self.__bRemoveBreakLines = bRemoveBreakLines
|
||||
|
||||
def setRequestType(self, cType):
|
||||
self.__cType = cType
|
||||
|
||||
def addHeaderEntry(self, sHeaderKey, sHeaderValue):
|
||||
aHeader = {sHeaderKey : sHeaderValue}
|
||||
self.__aHeaderEntries.append(aHeader)
|
||||
|
||||
def addParameters(self, sParameterKey, mParameterValue):
|
||||
self.__aParamaters[sParameterKey] = mParameterValue
|
||||
|
||||
def getResponseHeader(self):
|
||||
return self.__sResponseHeader
|
||||
|
||||
# url after redirects
|
||||
def getRealUrl(self):
|
||||
return self.__sRealUrl;
|
||||
|
||||
def request(self):
|
||||
self.__sUrl = self.__sUrl.replace(' ', '+')
|
||||
return self.__callRequest()
|
||||
|
||||
def getRequestUri(self):
|
||||
return self.__sUrl + '?' + urllib.parse.urlencode(self.__aParamaters)
|
||||
|
||||
def __setDefaultHeader(self):
|
||||
UA = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3'
|
||||
self.addHeaderEntry('User-Agent', UA)
|
||||
self.addHeaderEntry('Accept-Language', 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4')
|
||||
self.addHeaderEntry('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
|
||||
|
||||
def __callRequest(self):
|
||||
sParameters = urllib.parse.urlencode(self.__aParamaters)
|
||||
|
||||
if (self.__cType == cRequestHandler.REQUEST_TYPE_GET):
|
||||
if (len(sParameters) > 0):
|
||||
if (self.__sUrl.find('?') == -1):
|
||||
self.__sUrl = self.__sUrl + '?' + str(sParameters)
|
||||
sParameters = ''
|
||||
else:
|
||||
self.__sUrl = self.__sUrl + '&' + str(sParameters)
|
||||
sParameters = ''
|
||||
|
||||
if (len(sParameters) > 0):
|
||||
oRequest = urllib.request.Request(self.__sUrl, sParameters)
|
||||
else:
|
||||
oRequest = urllib.request.Request(self.__sUrl)
|
||||
|
||||
for aHeader in self.__aHeaderEntries:
|
||||
for sHeaderKey, sHeaderValue in list(aHeader.items()):
|
||||
oRequest.add_header(sHeaderKey, sHeaderValue)
|
||||
|
||||
sContent = ''
|
||||
|
||||
try:
|
||||
oResponse = urllib.request.urlopen(oRequest, timeout=30)
|
||||
sContent = oResponse.read()
|
||||
|
||||
self.__sResponseHeader = oResponse.info()
|
||||
self.__sRealUrl = oResponse.geturl()
|
||||
|
||||
oResponse.close()
|
||||
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 503:
|
||||
if cloudflare.CheckIfActive(e.headers):
|
||||
cookies = e.headers['Set-Cookie']
|
||||
cookies = cookies.split(';')[0]
|
||||
from resources.lib.cloudflare import CloudflareBypass
|
||||
sContent = CloudflareBypass().GetHtml(self.__sUrl,e.read(),cookies)
|
||||
|
||||
self.__sResponseHeader = ''
|
||||
self.__sRealUrl = ''
|
||||
|
||||
if not sContent:
|
||||
cConfig().error("%s,%s" % (cConfig().getlanguage(30205), self.__sUrl))
|
||||
return ''
|
||||
|
||||
if (self.__bRemoveNewLines == True):
|
||||
sContent = sContent.replace("\n","")
|
||||
sContent = sContent.replace("\r\t","")
|
||||
|
||||
if (self.__bRemoveBreakLines == True):
|
||||
sContent = sContent.replace(" ","")
|
||||
|
||||
return sContent
|
||||
|
||||
def getHeaderLocationUrl(self):
|
||||
opened = urllib.request.urlopen(self.__sUrl)
|
||||
return opened.geturl()
|
||||
|
||||
class cParser:
|
||||
|
||||
def parseSingleResult(self, sHtmlContent, sPattern):
|
||||
aMatches = re.compile(sPattern).findall(sHtmlContent)
|
||||
if (len(aMatches) == 1):
|
||||
aMatches[0] = self.__replaceSpecialCharacters(aMatches[0])
|
||||
return True, aMatches[0]
|
||||
return False, aMatches
|
||||
|
||||
def __replaceSpecialCharacters(self, sString):
|
||||
res=sString.replace('\\/','/').replace('&','&').replace('\xc9','E').replace('–', '-')
|
||||
res=res.replace('&', '&').replace('’','\'').replace('\r','').replace('\n','')
|
||||
res=res.replace('\t','').replace(''',"'")
|
||||
return res
|
||||
|
||||
def parse(self, sHtmlContent, sPattern, iMinFoundValue = 1):
|
||||
sHtmlContent = self.__replaceSpecialCharacters(str(sHtmlContent))
|
||||
aMatches = re.compile(sPattern, re.IGNORECASE).findall(sHtmlContent)
|
||||
if (len(aMatches) >= iMinFoundValue):
|
||||
return True, aMatches
|
||||
return False, aMatches
|
||||
|
||||
def replace(self, sPattern, sReplaceString, sValue):
|
||||
return re.sub(sPattern, sReplaceString, sValue)
|
||||
|
||||
def escape(self, sValue):
|
||||
return re.escape(sValue)
|
||||
|
||||
def getNumberFromString(self, sValue):
|
||||
sPattern = "\d+"
|
||||
aMatches = re.findall(sPattern, sValue)
|
||||
if (len(aMatches) > 0):
|
||||
return aMatches[0]
|
||||
return 0
|
||||
|
||||
|
||||
__author__ = 'Jose Riha/Lubomir Kucera'
|
||||
__name__ = 'openload'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'openload\.\w+/embed/.+', url) is not None
|
||||
|
||||
def base10toN(num, n):
|
||||
"""Change a to a base-n number.
|
||||
Up to base-36 is supported without special notation."""
|
||||
|
||||
new_num_string = ''
|
||||
current = num
|
||||
|
||||
while current != 0:
|
||||
remainder = current % n
|
||||
if 36 > remainder > 9:
|
||||
remainder_string = chr(remainder + 87)
|
||||
elif remainder >= 36:
|
||||
remainder_string = '(' + str(remainder) + ')'
|
||||
else:
|
||||
remainder_string = str(remainder)
|
||||
new_num_string = remainder_string + new_num_string
|
||||
current = current / n
|
||||
return new_num_string
|
||||
|
||||
def resolve(url):
|
||||
|
||||
oRequest = cRequestHandler(url)
|
||||
sHtmlContent = oRequest.request()
|
||||
|
||||
oParser = cParser()
|
||||
string = ''
|
||||
|
||||
sPattern = '<script type="text\/javascript">(゚ω゚.+?)<\/script>'
|
||||
aResult = oParser.parse(sHtmlContent, sPattern)
|
||||
|
||||
vid = 'XXXXXX'
|
||||
string2=[]
|
||||
|
||||
for aEntry in aResult[1]:
|
||||
s = AADecoder(aEntry).decode()
|
||||
string2.append(s)
|
||||
|
||||
if 'welikekodi_ya_rly' in s:
|
||||
c0 = re.search('welikekodi_ya_rly = ([^<>;"]+);', s)
|
||||
if c0:
|
||||
c = c0.group(1)
|
||||
c = c.replace('Math.round','int')
|
||||
cc = str(eval(c))
|
||||
vid = '[' + cc + ']'
|
||||
|
||||
for string3 in string2:
|
||||
if ('toString' in string3) and (vid in string3):
|
||||
base = int(re.findall('toString\(a\+([0-9]+)\)',string3)[0])
|
||||
table = re.findall('(\([0-9][^)]+\))',string3)
|
||||
|
||||
for str1 in table:
|
||||
val = re.findall('([0-9]+),([0-9]+)',str1)
|
||||
base2 = base + int(val[0][0])
|
||||
str2 = base10toN(int(val[0][1]), base2)
|
||||
string3 = string3.replace(str1, str2)
|
||||
|
||||
#clean up
|
||||
string3 = string3.replace('+', '')
|
||||
string3 = string3.replace('"', '')
|
||||
string3 = string3.replace('', '')
|
||||
|
||||
#a hack for not having to recode everything
|
||||
url = re.findall('(http[^<>}]+)',string3)[0]
|
||||
string = 'src="' + url + '?mime=true"'
|
||||
|
||||
if (string):
|
||||
sContent = string.replace('\\','')
|
||||
|
||||
api_call = ''
|
||||
|
||||
sPattern = 'src=\s*?"(.*?)\?'
|
||||
aResult = oParser.parse(sContent, sPattern)
|
||||
|
||||
if (aResult[0] == True):
|
||||
api_call = aResult[1][0]
|
||||
|
||||
if not api_call:
|
||||
sPattern = 'window\.vr *=["\'](.+?)["\']'
|
||||
aResult = oParser.parse(sContent, sPattern)
|
||||
if (aResult[0] == True):
|
||||
api_call = aResult[1][0]
|
||||
|
||||
if (api_call):
|
||||
|
||||
if 'openload.co/stream' in api_call:
|
||||
UA = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0'
|
||||
headers = {'User-Agent': UA }
|
||||
|
||||
req = urllib.request.Request(api_call,None,headers)
|
||||
res = urllib.request.urlopen(req)
|
||||
finalurl = res.geturl()
|
||||
api_call = finalurl
|
||||
|
||||
return [{'url': api_call}]
|
||||
|
||||
42
lib/server/playedtoresolver.py
Normal file
42
lib/server/playedtoresolver.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2013 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'played.to'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
surl = m.group('url').replace('embed','iframe')
|
||||
data = util.request('http://played.to/%s' % surl)
|
||||
n = re.search('file: \"(.+?)\"',data,re.IGNORECASE | re.DOTALL)
|
||||
quality = '???'
|
||||
q = re.search('x(\d+)\.html',url)
|
||||
if q:
|
||||
quality = q.group(1)+'p'
|
||||
if not n == None:
|
||||
return [{'quality':quality,'url':n.group(1).strip()}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('played\.to/(?P<url>(embed|iframe)-.+?)$',url,re.IGNORECASE | re.DOTALL)
|
||||
28
lib/server/playmdresolver.py
Normal file
28
lib/server/playmdresolver.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
|
||||
__name__='play.md'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
|
||||
def resolve(link):
|
||||
if _regex(link):
|
||||
data = util.request(link)
|
||||
url = re.search('base_url\: \"(?P<url>[^\"]+)',data)
|
||||
file = re.search('file_name\: \"(?P<url>[^\"]+)',data)
|
||||
res = re.search('resolutions\: \"(?P<url>[^\"]+)',data)
|
||||
if url and file and res:
|
||||
url = '%s/%s/%s' % (url.group('url'),res.group('url'),file.group('url'))
|
||||
return [{'quality':res.group('url'),'url':url}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('play\.md',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
48
lib/server/publicvideohostresolver.py
Normal file
48
lib/server/publicvideohostresolver.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2013 mx3L
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re, util, decimal, random, base64, urllib.request, urllib.parse, urllib.error
|
||||
|
||||
__name__ = 'publicvideohost'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def gen_random_decimal(i, d):
|
||||
return decimal.Decimal('%d.%d' % (random.randint(0, i), random.randint(0, d)))
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
id = int(m.group('v'))
|
||||
params = {
|
||||
'v':id,
|
||||
}
|
||||
quality = "480p"
|
||||
data = util.request("http://embed.publicvideohost.org/v.php?" + urllib.parse.urlencode(params))
|
||||
vurl = re.search('file\:(.*?)\"(?P<url>[^"]+)',data, re.IGNORECASE | re.DOTALL).group('url')
|
||||
return [{'quality':quality, 'url':vurl}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
m = re.search('http://embed\.publicvideohost\.org/v\.php\?(.+?)v=(?P<v>[0-9]+)', url, re.IGNORECASE | re.DOTALL)
|
||||
return m
|
||||
|
||||
159
lib/server/putlockerresolver.py
Normal file
159
lib/server/putlockerresolver.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# *
|
||||
# */
|
||||
|
||||
# thanks to:
|
||||
# https://github.com/Eldorados
|
||||
|
||||
import re,util,os
|
||||
__name__ = 'putlocker'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
|
||||
def get_host_and_id(url):
|
||||
r = re.search('//(.+?)/(?:file|embed)/([0-9A-Z]+)', url)
|
||||
if r:
|
||||
return r.groups()
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_host(host,media_id):
|
||||
#host,media_id=get_host_and_id(url)
|
||||
if 'putlocker' in host:
|
||||
host = 'www.putlocker.com'
|
||||
else:
|
||||
host = 'www.sockshare.com'
|
||||
return 'http://%s/file/%s' % (host, media_id)
|
||||
|
||||
|
||||
|
||||
def login_stale():
|
||||
url = 'http://www.putlocker.com/cp.php'
|
||||
if not os.path.exists(cookie_file):
|
||||
return True
|
||||
#self.net.set_cookies(cookie_file)
|
||||
source = util.request(url)
|
||||
if re.search('(?:<span class=pro_user>\( Pro \)</span>|<span class="free_user">\( Free \)</span>)', source):
|
||||
print ('Putlocker account appears to be logged in.')
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
if supports(url):
|
||||
|
||||
'''
|
||||
if self.get_setting('login') == 'true':
|
||||
if login_stale():
|
||||
login()
|
||||
#self.net.set_cookies(cookie_file)
|
||||
'''
|
||||
|
||||
host,media_id=get_host_and_id(url)
|
||||
web_url = get_host(host,media_id)
|
||||
|
||||
#find session_hash
|
||||
try:
|
||||
html = util.request(web_url)
|
||||
except urllib.error.URLError as e:
|
||||
print(('putlocker: got http error %d fetching %s' % (e.code, web_url)))
|
||||
return False
|
||||
|
||||
#Shortcut for logged in users
|
||||
pattern = '<a href="(/.+?)" class="download_file_link" style="margin:0px 0px;">Download File</a>'
|
||||
link = re.search(pattern, html)
|
||||
if link:
|
||||
print('Direct link found: %s' %link.group(1))
|
||||
return 'http://www.putlocker.com%s' %link.group(1)
|
||||
|
||||
r = re.search('value="([0-9a-f]+?)" name="hash"', html)
|
||||
if r:
|
||||
session_hash = r.group(1)
|
||||
else:
|
||||
print ('putlocker: session hash not found')
|
||||
return False
|
||||
|
||||
#post session_hash
|
||||
try:
|
||||
html = util.post(web_url, {'hash': session_hash,'confirm': 'Continue as Free User'})
|
||||
except urllib.error.URLError as e:
|
||||
print(('putlocker: got http error %d posting %s' %(e.code, web_url)))
|
||||
return False
|
||||
|
||||
#find playlist code
|
||||
r = re.search('\?stream=(.+?)\'', html)
|
||||
if r:
|
||||
playlist_code = r.group(1)
|
||||
else:
|
||||
r = re.search('key=(.+?)&',html)
|
||||
playlist_code = r.group(1)
|
||||
|
||||
#find download link
|
||||
#q = self.get_setting('quality')
|
||||
q = '1'
|
||||
|
||||
#Try to grab highest quality link available
|
||||
if q == '1':
|
||||
#download & return link.
|
||||
if 'putlocker' in host:
|
||||
Avi = "http://putlocker.com/get_file.php?stream=%s&original=1"%playlist_code
|
||||
html = util.request(Avi)
|
||||
final=re.compile('url="(.+?)"').findall(html)[0].replace('&','&')
|
||||
return [final]
|
||||
else:
|
||||
Avi = "http://sockshare.com/get_file.php?stream=%s&original=1"%playlist_code
|
||||
html = util.request(Avi)
|
||||
final=re.compile('url="(.+?)"').findall(html)[0].replace('&','&')
|
||||
return [final]
|
||||
|
||||
#Else grab standard flv link
|
||||
else:
|
||||
xml_url = re.sub('/(file|embed)/.+', '/get_file.php?stream=', web_url)
|
||||
xml_url += playlist_code
|
||||
try:
|
||||
html = util.request(xml_url)
|
||||
except urllib.error.URLError as e:
|
||||
pritn ('putlocker: got http error %d fetching %s'(e.code, xml_url))
|
||||
return False
|
||||
|
||||
r = re.search('url="(.+?)"', html)
|
||||
if r:
|
||||
flv_url = r.group(1)
|
||||
else:
|
||||
print ('putlocker: stream url not found')
|
||||
return False
|
||||
|
||||
return [flv_url.replace('&','&')]
|
||||
|
||||
|
||||
def resolve(u):
|
||||
stream = url(u)
|
||||
if stream:
|
||||
return [{'name':__name__,'quality':'360p','url':stream[0],'surl':u}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
return re.search('http://(www.)?(putlocker|sockshare).com/' + '(file|embed)/[0-9A-Z]+', url,re.IGNORECASE | re.DOTALL)
|
||||
41
lib/server/rutuberesolver.py
Normal file
41
lib/server/rutuberesolver.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'rutube'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
data = util.request('http://rutube.ru/trackinfo/'+m.group('id')+'.xml')
|
||||
n = re.search('<m3u8>([^<]+)',data,re.IGNORECASE | re.DOTALL)
|
||||
if not n == None:
|
||||
return [n.group(1).strip()]
|
||||
|
||||
def resolve(u):
|
||||
stream = url(u)
|
||||
if stream:
|
||||
return [{'name':__name__,'quality':'640p','url':stream[0],'surl':u}]
|
||||
def _regex(url):
|
||||
return re.search('rutube\.ru/(video/embed|embed)/(?P<id>[^$]+)',url,re.IGNORECASE | re.DOTALL)
|
||||
40
lib/server/servertipczresolver.py
Normal file
40
lib/server/servertipczresolver.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,urllib.request,urllib.parse,urllib.error
|
||||
__name__ = 'servertip'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
if supports(url):
|
||||
data = util.request(url)
|
||||
data = util.substr(data,'<div id=\"player_code','</div')
|
||||
try:
|
||||
video_id = re.search('flv\|\|([^\|]+)',data).group(1)
|
||||
return [{'url':'http://servertip.cz/cgi-bin/dl.cgi/%s/video.flv' % video_id}]
|
||||
except:
|
||||
pass
|
||||
|
||||
def _regex(url):
|
||||
return re.search('servertip\.cz',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
50
lib/server/sledujuserialyresolver.py
Normal file
50
lib/server/sledujuserialyresolver.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util,urllib.request,urllib.error,urllib.parse,traceback
|
||||
__name__ = 'zkouknito.cz'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
data = util.request(url)
|
||||
if data.find('jwplayer(\'mediaplayer') > 0:
|
||||
video = re.search('\'file\'\: \'(?P<url>.+?[flv|mp4])\'',data)
|
||||
if video:
|
||||
|
||||
item = {}
|
||||
item['url'] = video.group('url')
|
||||
subs = re.search('\'file\'\: \'(?P<url>.+?srt)',data)
|
||||
if subs:
|
||||
item['subs'] = _furl(subs.group('url'))
|
||||
print(item)
|
||||
return [item]
|
||||
|
||||
def _furl(url):
|
||||
if url.startswith('http'):
|
||||
return url
|
||||
url = url.lstrip('./')
|
||||
return 'http://www.sledujuserialy.cz/'+url
|
||||
|
||||
def _regex(url):
|
||||
return re.search('(www\.)?sledujuserialy.cz/(.+?)',url,re.IGNORECASE | re.DOTALL)
|
||||
36
lib/server/stagevuresolver.py
Normal file
36
lib/server/stagevuresolver.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'stagevu'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
if supports(url):
|
||||
data = util.substr(util.request(url),'<body>','</script>')
|
||||
m = re.search('url\[[\d]+\] = \'([^\']+)',data,re.IGNORECASE | re.DOTALL)
|
||||
if not m == None:
|
||||
return [{'url':m.group(1)}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('(www\.)?stagevu.com/(.+?)uid=(?P<id>(.+?))',url,re.IGNORECASE | re.DOTALL)
|
||||
61
lib/server/streamcloudresolver.py
Normal file
61
lib/server/streamcloudresolver.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'streamcloud'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
|
||||
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
|
||||
data = util.substr(util.request(url),'class=\"proform\"','</form>')
|
||||
#print data
|
||||
form_values = {}
|
||||
pattern = '<input.+?name="(?P<name>.*?)".+?value="(?P<value>.*?)"'
|
||||
for n in re.finditer(pattern,data,re.IGNORECASE | re.DOTALL ):
|
||||
form_values[n.group('name')] = n.group('value')
|
||||
#print form_values
|
||||
try:
|
||||
#time.sleep(10)
|
||||
resp = util.post(url,form_values)
|
||||
except:
|
||||
util.error('streamcloud: got http error fetching %s' % (url))
|
||||
return False
|
||||
|
||||
r = re.search('file: "(.+?)",', resp)
|
||||
if r:
|
||||
return [r.group(1)]
|
||||
|
||||
|
||||
def resolve(u):
|
||||
stream = url(u)
|
||||
if stream:
|
||||
return [{'name':__name__,'quality':'640p','url':stream[0],'surl':u}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
return re.search('http://(www.)?streamcloud.eu/[0-9A-Za-z]+',url,re.IGNORECASE | re.DOTALL)
|
||||
43
lib/server/streamintoresolver.py
Normal file
43
lib/server/streamintoresolver.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2013 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'streamin.to'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
data = util.request('http://streamin.to/'+m.group('url'))
|
||||
n = re.search('config:{file:\'(.+?)\'',data,re.IGNORECASE | re.DOTALL)
|
||||
k = re.search('streamer: \"(.+?)\"',data,re.IGNORECASE | re.DOTALL)
|
||||
quality = '???'
|
||||
q = re.search('x(\d+)\.html',url)
|
||||
if q:
|
||||
quality = q.group(1)+'p'
|
||||
if n and k:
|
||||
url = '%s playpath=%s' % (k.group(1).strip(),n.group(1).strip())
|
||||
return [{'quality':quality,'url':url}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('streamin\.to/(?P<url>.+?)$',url,re.IGNORECASE | re.DOTALL)
|
||||
78
lib/server/streamujtvresolver.py
Normal file
78
lib/server/streamujtvresolver.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
import json
|
||||
from base64 import b64decode, b64encode
|
||||
|
||||
__name__ = 'streamujtv'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return _regex(url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
util.init_urllib()
|
||||
data = util.request(url)
|
||||
if data.find('Toto video neexistuje') > 0:
|
||||
util.error('Video bylo smazano ze serveru')
|
||||
return
|
||||
player = 'http://www.streamuj.tv/new-flash-player/mplugin4.swf'
|
||||
headers = {
|
||||
'User-Agent': util.UA,
|
||||
'Referer': 'http://www.streamuj.tv/mediaplayer/player.swf',
|
||||
'Cookie': ','.join("%s=%s" % (c.name, c.value) for c in util._cookie_jar)
|
||||
}
|
||||
index = 0
|
||||
result = []
|
||||
qualities = re.search(r'rn\:[^\"]*\"([^\"]*)', data, re.IGNORECASE | re.DOTALL)
|
||||
langs = re.search(r'langs\:[^\"]*\"([^\"]+)', data, re.IGNORECASE | re.DOTALL)
|
||||
languages = [''] # pretend there is at least language so we read 1st stream info
|
||||
if langs:
|
||||
languages = langs.group(1).split(',')
|
||||
for language in languages:
|
||||
streams = re.search(r'res{index}\:[^\"]*\"([^\"]+)'.format(index=index),
|
||||
data, re.IGNORECASE | re.DOTALL)
|
||||
subs = re.search(r'sub{index}\:[^\"]*\"([^\"]+)'.format(index=index),
|
||||
data, re.IGNORECASE | re.DOTALL)
|
||||
if subs:
|
||||
subs = re.search(r'[^>]+>([^,$]+)', subs.group(1), re.IGNORECASE | re.DOTALL)
|
||||
else:
|
||||
subs = None
|
||||
if streams and qualities:
|
||||
streams = streams.group(1).split(',')
|
||||
rn = qualities.group(1).split(',')
|
||||
qindex = 0
|
||||
for stream in streams:
|
||||
q = rn[qindex]
|
||||
if q == 'HD':
|
||||
q = '720p'
|
||||
else:
|
||||
q = 'SD'
|
||||
item = {
|
||||
'url': stream,
|
||||
'quality': q,
|
||||
'headers': headers,
|
||||
'lang': language
|
||||
}
|
||||
if subs:
|
||||
link = subs.group(1)
|
||||
item['lang'] += ' + subs'
|
||||
item['subs'] = link
|
||||
result.append(item)
|
||||
qindex += 1
|
||||
index += 1
|
||||
return result
|
||||
|
||||
|
||||
def _regex(url):
|
||||
return re.search(r'streamuj\.tv/video/', url, re.IGNORECASE | re.DOTALL)
|
||||
22
lib/server/trivialresolver.py
Normal file
22
lib/server/trivialresolver.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
__name__='simple'
|
||||
__priority__ = -2
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
if supports(url):
|
||||
return [{'url':url}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('\.(flv|mp4|avi|wmv)$',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
158
lib/server/videobbresolver.py
Normal file
158
lib/server/videobbresolver.py
Normal file
@@ -0,0 +1,158 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# thanks to Lynx187 and his fix in https://github.com/t0mm0/xbmc-urlresolver
|
||||
import util,re,base64
|
||||
|
||||
from base64 import b64decode
|
||||
from binascii import unhexlify
|
||||
__name__ = 'videobb'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def _regex(url):
|
||||
return re.search('http://(www\.)?videobb.com/[\w\d]+/(?P<id>[^$]+)', url, re.IGNORECASE | re.DOTALL)
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
util.init_urllib()
|
||||
data = util.request('http://videobb.com/player_control/settings.php?v=%s&em=TRUE&fv=v1.1.67' % m.group('id'))
|
||||
json = data.replace('false','False').replace('true','True').replace('null','None')
|
||||
aData = eval('('+json+')')
|
||||
max_res = 99999
|
||||
r = re.finditer('"l".*?:.*?"(.+?)".+?"u".*?:.*?"(.+?)"', json)
|
||||
chosen_res = 0
|
||||
stream_url = False
|
||||
stream_url_part1 = False
|
||||
if r:
|
||||
|
||||
for match in r:
|
||||
print(match.groups())
|
||||
res, url = match.groups()
|
||||
res = int(res.strip('p'))
|
||||
if res > chosen_res and res <= max_res:
|
||||
stream_url_part1 = url.decode('base-64')
|
||||
chosen_res = res
|
||||
else:
|
||||
return
|
||||
|
||||
if not stream_url_part1:
|
||||
return
|
||||
# Decode the link from the json data settings
|
||||
spn_ik = unhexlify(__decrypt(aData["settings"]["login_status"]["spen"], aData["settings"]["login_status"]["salt"], 950569)).split(';')
|
||||
spn = spn_ik[0].split('&')
|
||||
ik = spn_ik[1]
|
||||
|
||||
for item in ik.split('&') :
|
||||
temp = item.split('=')
|
||||
if temp[0] == 'ik' :
|
||||
key = __get_key(temp[1])
|
||||
|
||||
sLink = ""
|
||||
for item in spn :
|
||||
item = item.split('=')
|
||||
if(int(item[1])==1):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["info"]["sece2"], aData["settings"]["config"]["rkts"], key) + '&' #decrypt32byte
|
||||
elif(int(item[1]==2)):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["banner"]["g_ads"]["url"],aData["settings"]["config"]["rkts"], key) + '&'
|
||||
elif(int(item[1])==3):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["banner"]["g_ads"]["type"],aData["settings"]["config"]["rkts"], key,26,25431,56989,93,32589,784152) + '&'
|
||||
elif(int(item[1])==4):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["banner"]["g_ads"]["time"],aData["settings"]["config"]["rkts"], key,82,84669,48779,32,65598,115498) + '&'
|
||||
elif(int(item[1])==5):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["login_status"]["euno"],aData["settings"]["login_status"]["pepper"], key,10,12254,95369,39,21544,545555) + '&'
|
||||
elif(int(item[1])==6):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["settings"]["login_status"]["sugar"],aData["settings"]["banner"]["lightbox2"]["time"], key,22,66595,17447,52,66852,400595) + '&'
|
||||
|
||||
sLink = sLink + "start=0"
|
||||
|
||||
stream_url = stream_url_part1 + '&' + sLink
|
||||
|
||||
return [{'url':stream_url}]
|
||||
|
||||
def __decrypt(str, k1, k2, p4 = 11, p5 = 77213, p6 = 81371, p7 = 17, p8 = 92717, p9 = 192811):
|
||||
tobin = hex2bin(str,len(str)*4)
|
||||
tobin_lenght = len(tobin)
|
||||
keys = []
|
||||
index = 0
|
||||
|
||||
while (index < tobin_lenght*3):
|
||||
k1 = ((int(k1) * p4) + p5) % p6
|
||||
k2 = ((int(k2) * p7) + p8) % p9
|
||||
keys.append((int(k1) + int(k2)) % tobin_lenght)
|
||||
index += 1
|
||||
|
||||
index = tobin_lenght*2
|
||||
|
||||
while (index >= 0):
|
||||
val1 = keys[index]
|
||||
mod = index%tobin_lenght
|
||||
val2 = tobin[val1]
|
||||
tobin[val1] = tobin[mod]
|
||||
tobin[mod] = val2
|
||||
index -= 1
|
||||
|
||||
index = 0
|
||||
while(index < tobin_lenght):
|
||||
tobin[index] = int(tobin[index]) ^ int(keys[index+(tobin_lenght*2)]) & 1
|
||||
index += 1
|
||||
decrypted = bin2hex(tobin)
|
||||
return decrypted
|
||||
|
||||
def hex2bin(val,fill):
|
||||
bin_array = []
|
||||
string = bin(int(val, 16))[2:].zfill(fill)
|
||||
for value in string:
|
||||
bin_array.append(value)
|
||||
return bin_array
|
||||
|
||||
def bin2hex(val):
|
||||
string = str("")
|
||||
for char in val:
|
||||
string+=str(char)
|
||||
return "%x" % int(string, 2)
|
||||
|
||||
def bin( x):
|
||||
'''
|
||||
bin(number) -> string
|
||||
Stringifies an int or long in base 2.
|
||||
'''
|
||||
if x < 0:
|
||||
return '-' + bin(-x)
|
||||
out = []
|
||||
if x == 0: out.append('0')
|
||||
while x > 0:
|
||||
out.append('01'[x & 1])
|
||||
x >>= 1
|
||||
pass
|
||||
try:
|
||||
return '0b' + ''.join(reversed(out))
|
||||
except NameError as ne2:
|
||||
out.reverse()
|
||||
return '0b' + ''.join(out)
|
||||
|
||||
def __get_key(nbr):
|
||||
if nbr == '1': return 226593
|
||||
elif nbr == '2': return 441252
|
||||
elif nbr == '3': return 301517
|
||||
elif nbr == '4': return 596338
|
||||
elif nbr == '5': return 852084
|
||||
else: return False
|
||||
56
lib/server/videomailresolver.py
Normal file
56
lib/server/videomailresolver.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2016 mx3L & lzoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re, util,urllib.request,urllib.error,urllib.parse
|
||||
__name__ = 'videomail'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
items = []
|
||||
vurl = m.group('url')
|
||||
vurl = re.sub('\&[^$]*','',vurl)
|
||||
vurl = re.sub('/embed','',vurl)
|
||||
vurl = 'http://videoapi.my.mail.ru/' + vurl + '.json'
|
||||
|
||||
util.init_urllib()
|
||||
req = urllib.request.Request(vurl)
|
||||
req.add_header('User-Agent', util.UA)
|
||||
resp = urllib.request.urlopen(req)
|
||||
data = resp.read()
|
||||
vkey = []
|
||||
for cookie in re.finditer('(video_key=[^\;]+)',resp.headers.get('Set-Cookie'),re.IGNORECASE | re.DOTALL):
|
||||
vkey.append(cookie.group(1))
|
||||
headers = {'Cookie':vkey[-1]}
|
||||
item = util.json.loads(data)
|
||||
for v in item['videos']:
|
||||
quality = v['key']
|
||||
link = v['url']
|
||||
items.append({'quality':quality, 'url':link, 'headers':headers})
|
||||
return items
|
||||
|
||||
def _regex(url):
|
||||
m1 = re.search('http://.+?mail\.ru.+?<param.+?value=\"movieSrc=(?P<url>[^\"]+)', url, re.IGNORECASE | re.DOTALL)
|
||||
m2 = re.search('://video.+?\.mail\.ru\/(?P<url>.+?)\.html', url, re.IGNORECASE | re.DOTALL)
|
||||
return m1 or m2
|
||||
67
lib/server/videonetresolver.py
Normal file
67
lib/server/videonetresolver.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = '24video'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
|
||||
def latin2text(word):
|
||||
dict_hex = {'á' : 'á',
|
||||
'č': 'č',
|
||||
'ď': 'ď',
|
||||
'é' : 'é',
|
||||
'ě': 'ě',
|
||||
'í' : 'í',
|
||||
'ñ' : 'ñ',
|
||||
'ó' : 'ó',
|
||||
'ř': 'ř',
|
||||
'š': 'š',
|
||||
'ť': 'ť',
|
||||
'ú' : 'ú',
|
||||
'ü' : 'ü',
|
||||
'ý' : 'ý',
|
||||
'ž': 'ž',
|
||||
}
|
||||
for key in list(dict_hex.keys()):
|
||||
word = word.replace(key,dict_hex[key])
|
||||
return word
|
||||
|
||||
|
||||
|
||||
# returns the steam url
|
||||
def url(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
data = latin2text(util.request('%s%s%s?mode=play' % (m.group('url') ,m.group('html'),m.group('id'))))
|
||||
f = re.search('<videos><video url=\'(.+?)[^ ] rating',data,re.IGNORECASE | re.DOTALL)
|
||||
if f:
|
||||
return [f.group(1)]
|
||||
|
||||
def resolve(u):
|
||||
stream = url(u)
|
||||
if stream:
|
||||
return [{'name':__name__,'quality':'480p','url':stream[0],'surl':u}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
return re.search('id=(?P<id>.+?)&idHtml=(?P<html>.+?)&.*rootUrl=(?P<url>.+?)&',url,re.IGNORECASE | re.DOTALL)
|
||||
40
lib/server/videoweedresolver.py
Normal file
40
lib/server/videoweedresolver.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'videoweed'
|
||||
def supports(data):
|
||||
return not _regex(data) == None
|
||||
|
||||
def resolve(url):
|
||||
if not _regex(url) == None:
|
||||
data = util.request(url.replace('&','&'))
|
||||
data = util.substr(data,'flashvars','params')
|
||||
domain = re.search('flashvars\.domain=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
file = re.search('flashvars\.file=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
key = re.search('flashvars\.filekey=\"([^\"]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
data = util.request('%s/api/player.api.php?key=%s&file=%s&user=undefined&codes=undefined&pass=undefined'% (domain,key,file))
|
||||
m = re.search('url=(?P<url>[^\&]+)',data,re.IGNORECASE | re.DOTALL)
|
||||
if not m == None:
|
||||
return [{'url':m.group('url')}]
|
||||
|
||||
def _regex(data):
|
||||
return re.search('http\://embed.videoweed.com(.+?)', data, re.IGNORECASE | re.DOTALL)
|
||||
158
lib/server/videozerresolver.py
Normal file
158
lib/server/videozerresolver.py
Normal file
@@ -0,0 +1,158 @@
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
# thanks to Lynx187 and his fix in https://github.com/t0mm0/xbmc-urlresolver
|
||||
|
||||
import re,util,base64
|
||||
|
||||
from base64 import b64decode
|
||||
from binascii import unhexlify
|
||||
__name__ = 'videozer'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def _regex(url):
|
||||
return re.search('videozer.com/embed/(?P<id>[_\-\w\d]+)',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
stream = None
|
||||
data = util.request('http://www.videozer.com/player_control/settings.php?v=%s&em=TRUE&fv=v1.1.12' % m.group('id'))
|
||||
json = data.replace('false','False').replace('true','True').replace('null','None')
|
||||
aData = eval('('+json+')')
|
||||
max_res = 99999
|
||||
r = re.finditer('"l".*?:.*?"(.+?)".+?"u".*?:.*?"(.+?)"', json)
|
||||
chosen_res = 0
|
||||
stream_url_part1 = False
|
||||
if r:
|
||||
for match in r:
|
||||
res, url = match.groups()
|
||||
if (res == 'LQ' ): res = 240
|
||||
elif (res == 'SD') : res = 480
|
||||
else:
|
||||
res = 720
|
||||
if res > chosen_res and res <= max_res:
|
||||
stream_url_part1 = url.decode('base-64')
|
||||
chosen_res = res
|
||||
else:
|
||||
return
|
||||
if not stream_url_part1:
|
||||
return
|
||||
|
||||
# Decode the link from the json data settings.
|
||||
spn_ik = unhexlify(__decrypt(aData["cfg"]["login"]["spen"], aData["cfg"]["login"]["salt"], 950569)).split(';')
|
||||
spn = spn_ik[0].split('&')
|
||||
ik = spn_ik[1]
|
||||
|
||||
for item in ik.split('&') :
|
||||
temp = item.split('=')
|
||||
if temp[0] == 'ik' :
|
||||
key = __get_key(temp[1])
|
||||
|
||||
sLink = ""
|
||||
for item in spn :
|
||||
item = item.split('=')
|
||||
if(int(item[1])==1):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["info"]["sece2"], aData["cfg"]["environment"]["rkts"], key) + '&' #decrypt32byte
|
||||
elif(int(item[1]==2)):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["ads"]["g_ads"]["url"],aData["cfg"]["environment"]["rkts"], key) + '&'
|
||||
elif(int(item[1])==3):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["ads"]["g_ads"]["type"],aData["cfg"]["environment"]["rkts"], key,26,25431,56989,93,32589,784152) + '&'
|
||||
elif(int(item[1])==4):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["ads"]["g_ads"]["time"],aData["cfg"]["environment"]["rkts"], key,82,84669,48779,32,65598,115498) + '&'
|
||||
elif(int(item[1])==5):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["login"]["euno"],aData["cfg"]["login"]["pepper"], key,10,12254,95369,39,21544,545555) + '&'
|
||||
elif(int(item[1])==6):
|
||||
sLink = sLink + item[0]+ '=' + __decrypt(aData["cfg"]["login"]["sugar"],aData["cfg"]["ads"]["lightbox2"]["time"], key,22,66595,17447,52,66852,400595) + '&'
|
||||
|
||||
sLink = sLink + "start=0"
|
||||
|
||||
sMediaLink = stream_url_part1 + '&' + sLink
|
||||
|
||||
return [{'url':sMediaLink}]
|
||||
|
||||
def __decrypt(str, k1, k2, p4 = 11, p5 = 77213, p6 = 81371, p7 = 17, p8 = 92717, p9 = 192811):
|
||||
tobin = hex2bin(str,len(str)*4)
|
||||
tobin_lenght = len(tobin)
|
||||
keys = []
|
||||
index = 0
|
||||
|
||||
while (index < tobin_lenght*3):
|
||||
k1 = ((int(k1) * p4) + p5) % p6
|
||||
k2 = ((int(k2) * p7) + p8) % p9
|
||||
keys.append((int(k1) + int(k2)) % tobin_lenght)
|
||||
index += 1
|
||||
|
||||
index = tobin_lenght*2
|
||||
|
||||
while (index >= 0):
|
||||
val1 = keys[index]
|
||||
mod = index%tobin_lenght
|
||||
val2 = tobin[val1]
|
||||
tobin[val1] = tobin[mod]
|
||||
tobin[mod] = val2
|
||||
index -= 1
|
||||
|
||||
index = 0
|
||||
while(index < tobin_lenght):
|
||||
tobin[index] = int(tobin[index]) ^ int(keys[index+(tobin_lenght*2)]) & 1
|
||||
index += 1
|
||||
decrypted = bin2hex(tobin)
|
||||
return decrypted
|
||||
|
||||
def hex2bin(val,fill):
|
||||
bin_array = []
|
||||
string = bin(int(val, 16))[2:].zfill(fill)
|
||||
for value in string:
|
||||
bin_array.append(value)
|
||||
return bin_array
|
||||
|
||||
def bin2hex(val):
|
||||
string = str("")
|
||||
for char in val:
|
||||
string+=str(char)
|
||||
return "%x" % int(string, 2)
|
||||
|
||||
def bin( x):
|
||||
'''
|
||||
bin(number) -> string
|
||||
Stringifies an int or long in base 2.
|
||||
'''
|
||||
if x < 0:
|
||||
return '-' + bin(-x)
|
||||
out = []
|
||||
if x == 0: out.append('0')
|
||||
while x > 0:
|
||||
out.append('01'[x & 1])
|
||||
x >>= 1
|
||||
pass
|
||||
try:
|
||||
return '0b' + ''.join(reversed(out))
|
||||
except NameError as ne2:
|
||||
out.reverse()
|
||||
return '0b' + ''.join(out)
|
||||
|
||||
def __get_key(nbr):
|
||||
if nbr == '1': return 215678
|
||||
elif nbr == '2': return 516929
|
||||
elif nbr == '3': return 962043
|
||||
elif nbr == '4': return 461752
|
||||
elif nbr == '5': return 141994
|
||||
else: return False
|
||||
39
lib/server/videram.py
Normal file
39
lib/server/videram.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
|
||||
__author__ = 'Jose Riha'
|
||||
__name__ = 'videram'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'play\.videram\.com', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
try:
|
||||
data=[x for x in util.request('http:'+url).splitlines() if 'file:' in x and '.mp4' in x][0]
|
||||
except:
|
||||
return None
|
||||
streamurl = re.search(r'.*file: *"([^"]+?)".*', data).group(1)
|
||||
return [{'url': streamurl}]
|
||||
53
lib/server/vimeoresolver.py
Normal file
53
lib/server/vimeoresolver.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2014 mx3L
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
|
||||
import re
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
import random
|
||||
import decimal
|
||||
|
||||
import util
|
||||
|
||||
__name__='vimeo'
|
||||
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
ret = []
|
||||
data = util.request("http://player.vimeo.com/v2/video/%s/config?type=moogaloop&referrer=&player_url=player.vimeo.com&v=1.0.0&cdn_url=http://a.vimeocdn.com"%m.group('id'))
|
||||
data = util.json.loads(data)
|
||||
h264 = data["request"]["files"]["h264"]
|
||||
for quality in h264.keys():
|
||||
item = {}
|
||||
item['title'] = data['video']['title']
|
||||
item['length'] = data['video']['duration']
|
||||
item['quality'] = quality == 'hd' and '720p' or '480p'
|
||||
item['url'] = h264[quality]['url']
|
||||
ret.append(item)
|
||||
return ret
|
||||
|
||||
def _regex(url):
|
||||
return re.search('player.vimeo.com/video/(?P<id>\d+)',url,re.IGNORECASE | re.DOTALL)
|
||||
57
lib/server/vkontakteresolver.py
Normal file
57
lib/server/vkontakteresolver.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'vkontakte'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(link):
|
||||
if not _regex(link) == None:
|
||||
data = util.request(link)
|
||||
data = util.substr(data,'div id=\"playerWrap\"','<embed>')
|
||||
if len(data) > 0:
|
||||
host = re.search('host=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
oid = re.search('oid=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
uid = re.search('uid=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
vtag = re.search('vtag=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
hd = re.search('hd_def=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
max_hd = re.search('hd=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
no_flv = re.search('no_flv=([^\&]+)',data,re.IGNORECASE | re.DOTALL).group(1)
|
||||
url = '%su%s/videos/%s' % (host,uid,vtag)
|
||||
if no_flv != '1':
|
||||
return [{'name':__name__,'quality':'???','url':url+'.flv','surl':link,'subs':''}]
|
||||
if no_flv == '1':
|
||||
res=int(hd)
|
||||
if max_hd:
|
||||
res=int(max_hd)
|
||||
if res < 0:
|
||||
return [{'name':__name__,'quality':'240p','url':url+'.flv','surl':link,'subs':''}]
|
||||
resolutions=['240','360','480','720','1080']
|
||||
ret = []
|
||||
for index,resolution in enumerate(resolutions):
|
||||
if index>res:
|
||||
return ret
|
||||
ret.append({'name':__name__,'quality':resolution+'p','url':url+'.'+resolution+'.mp4','surl':link,'subs':''})
|
||||
return ret
|
||||
|
||||
def _regex(data):
|
||||
return re.search('http\://(vkontakte.ru|vk.com)/(.+?)', data, re.IGNORECASE | re.DOTALL)
|
||||
29
lib/server/vuuzlaresolver.py
Normal file
29
lib/server/vuuzlaresolver.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
|
||||
__name__='vuuzla'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if m:
|
||||
data = util.request(url)
|
||||
sid = re.search('sid=(?P<sid>[^\&]+)',data)
|
||||
if sid:
|
||||
data = util.request('http://www.vuuzla.com/app/deliver/playlist/%s?sid=%s' % (m.group('id'),sid.group('sid')))
|
||||
link = re.search('<video.+?url=\"(?P<url>[^\"]+)',data)
|
||||
if link:
|
||||
return [{'url':link.group('url')}]
|
||||
|
||||
def _regex(url):
|
||||
return re.search('www\.vuuzla\.com.+?playerFrame/(?P<id>[^$]+)',url,re.IGNORECASE | re.DOTALL)
|
||||
|
||||
577
lib/server/youtuberesolver.py
Normal file
577
lib/server/youtuberesolver.py
Normal file
@@ -0,0 +1,577 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
import operator
|
||||
|
||||
|
||||
#source from https://github.com/rg3/youtube-dl/blob/master/youtube_dl/utils.py
|
||||
class ExtractorError(Exception):
|
||||
"""Error during info extraction."""
|
||||
|
||||
def __init__(self, msg, tb=None, expected=False, cause=None, video_id=None):
|
||||
""" tb, if given, is the original traceback (so that it can be printed out).
|
||||
If expected is set, this is a normal error message and most likely not a bug in youtube-dl.
|
||||
"""
|
||||
|
||||
if sys.exc_info()[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError):
|
||||
expected = True
|
||||
if video_id is not None:
|
||||
msg = video_id + ': ' + msg
|
||||
if cause:
|
||||
msg += ' (caused by %r)' % cause
|
||||
if not expected:
|
||||
msg += bug_reports_message()
|
||||
super(ExtractorError, self).__init__(msg)
|
||||
|
||||
self.traceback = tb
|
||||
self.exc_info = sys.exc_info() # preserve original exception
|
||||
self.cause = cause
|
||||
self.video_id = video_id
|
||||
|
||||
def format_traceback(self):
|
||||
if self.traceback is None:
|
||||
return None
|
||||
return ''.join(traceback.format_tb(self.traceback))
|
||||
|
||||
_OPERATORS = [
|
||||
('|', operator.or_),
|
||||
('^', operator.xor),
|
||||
('&', operator.and_),
|
||||
('>>', operator.rshift),
|
||||
('<<', operator.lshift),
|
||||
('-', operator.sub),
|
||||
('+', operator.add),
|
||||
('%', operator.mod),
|
||||
('/', operator.truediv),
|
||||
('*', operator.mul),
|
||||
]
|
||||
_ASSIGN_OPERATORS = [(op + '=', opfunc) for op, opfunc in _OPERATORS]
|
||||
_ASSIGN_OPERATORS.append(('=', lambda cur, right: right))
|
||||
|
||||
_NAME_RE = r'[a-zA-Z_$][a-zA-Z_$0-9]*'
|
||||
|
||||
|
||||
# source from https://github.com/rg3/youtube-dl/blob/master/youtube_dl/jsinterp.py
|
||||
class JSInterpreter(object):
|
||||
def __init__(self, code, objects=None):
|
||||
if objects is None:
|
||||
objects = {}
|
||||
self.code = code
|
||||
self._functions = {}
|
||||
self._objects = objects
|
||||
|
||||
def remove_quotes(self, s):
|
||||
if s is None or len(s) < 2:
|
||||
return s
|
||||
for quote in ('"', "'", ):
|
||||
if s[0] == quote and s[-1] == quote:
|
||||
return s[1:-1]
|
||||
return s
|
||||
|
||||
def interpret_statement(self, stmt, local_vars, allow_recursion=100):
|
||||
if allow_recursion < 0:
|
||||
raise ExtractorError('Recursion limit reached')
|
||||
|
||||
should_abort = False
|
||||
stmt = stmt.lstrip()
|
||||
stmt_m = re.match(r'var\s', stmt)
|
||||
if stmt_m:
|
||||
expr = stmt[len(stmt_m.group(0)):]
|
||||
else:
|
||||
return_m = re.match(r'return(?:\s+|$)', stmt)
|
||||
if return_m:
|
||||
expr = stmt[len(return_m.group(0)):]
|
||||
should_abort = True
|
||||
else:
|
||||
# Try interpreting it as an expression
|
||||
expr = stmt
|
||||
|
||||
v = self.interpret_expression(expr, local_vars, allow_recursion)
|
||||
return v, should_abort
|
||||
|
||||
def interpret_expression(self, expr, local_vars, allow_recursion):
|
||||
expr = expr.strip()
|
||||
if expr == '': # Empty expression
|
||||
return None
|
||||
|
||||
if expr.startswith('('):
|
||||
parens_count = 0
|
||||
for m in re.finditer(r'[()]', expr):
|
||||
if m.group(0) == '(':
|
||||
parens_count += 1
|
||||
else:
|
||||
parens_count -= 1
|
||||
if parens_count == 0:
|
||||
sub_expr = expr[1:m.start()]
|
||||
sub_result = self.interpret_expression(
|
||||
sub_expr, local_vars, allow_recursion)
|
||||
remaining_expr = expr[m.end():].strip()
|
||||
if not remaining_expr:
|
||||
return sub_result
|
||||
else:
|
||||
expr = json.dumps(sub_result) + remaining_expr
|
||||
break
|
||||
else:
|
||||
raise ExtractorError('Premature end of parens in %r' % expr)
|
||||
|
||||
for op, opfunc in _ASSIGN_OPERATORS:
|
||||
m = re.match(r'''(?x)
|
||||
(?P<out>%s)(?:\[(?P<index>[^\]]+?)\])?
|
||||
\s*%s
|
||||
(?P<expr>.*)$''' % (_NAME_RE, re.escape(op)), expr)
|
||||
if not m:
|
||||
continue
|
||||
right_val = self.interpret_expression(
|
||||
m.group('expr'), local_vars, allow_recursion - 1)
|
||||
|
||||
if m.groupdict().get('index'):
|
||||
lvar = local_vars[m.group('out')]
|
||||
idx = self.interpret_expression(
|
||||
m.group('index'), local_vars, allow_recursion)
|
||||
assert isinstance(idx, int)
|
||||
cur = lvar[idx]
|
||||
val = opfunc(cur, right_val)
|
||||
lvar[idx] = val
|
||||
return val
|
||||
else:
|
||||
cur = local_vars.get(m.group('out'))
|
||||
val = opfunc(cur, right_val)
|
||||
local_vars[m.group('out')] = val
|
||||
return val
|
||||
|
||||
if expr.isdigit():
|
||||
return int(expr)
|
||||
|
||||
var_m = re.match(
|
||||
r'(?!if|return|true|false)(?P<name>%s)$' % _NAME_RE,
|
||||
expr)
|
||||
if var_m:
|
||||
return local_vars[var_m.group('name')]
|
||||
|
||||
try:
|
||||
return json.loads(expr)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
m = re.match(
|
||||
r'(?P<in>%s)\[(?P<idx>.+)\]$' % _NAME_RE, expr)
|
||||
if m:
|
||||
val = local_vars[m.group('in')]
|
||||
idx = self.interpret_expression(
|
||||
m.group('idx'), local_vars, allow_recursion - 1)
|
||||
return val[idx]
|
||||
|
||||
m = re.match(
|
||||
r'(?P<var>%s)(?:\.(?P<member>[^(]+)|\[(?P<member2>[^]]+)\])\s*(?:\(+(?P<args>[^()]*)\))?$' % _NAME_RE,
|
||||
expr)
|
||||
if m:
|
||||
variable = m.group('var')
|
||||
member = self.remove_quotes(m.group('member') or m.group('member2'))
|
||||
arg_str = m.group('args')
|
||||
|
||||
if variable in local_vars:
|
||||
obj = local_vars[variable]
|
||||
else:
|
||||
if variable not in self._objects:
|
||||
self._objects[variable] = self.extract_object(variable)
|
||||
obj = self._objects[variable]
|
||||
|
||||
if arg_str is None:
|
||||
# Member access
|
||||
if member == 'length':
|
||||
return len(obj)
|
||||
return obj[member]
|
||||
|
||||
assert expr.endswith(')')
|
||||
# Function call
|
||||
if arg_str == '':
|
||||
argvals = tuple()
|
||||
else:
|
||||
argvals = tuple([
|
||||
self.interpret_expression(v, local_vars, allow_recursion)
|
||||
for v in arg_str.split(',')])
|
||||
|
||||
if member == 'split':
|
||||
assert argvals == ('',)
|
||||
return list(obj)
|
||||
if member == 'join':
|
||||
assert len(argvals) == 1
|
||||
return argvals[0].join(obj)
|
||||
if member == 'reverse':
|
||||
assert len(argvals) == 0
|
||||
obj.reverse()
|
||||
return obj
|
||||
if member == 'slice':
|
||||
assert len(argvals) == 1
|
||||
return obj[argvals[0]:]
|
||||
if member == 'splice':
|
||||
assert isinstance(obj, list)
|
||||
index, howMany = argvals
|
||||
res = []
|
||||
for i in range(index, min(index + howMany, len(obj))):
|
||||
res.append(obj.pop(index))
|
||||
return res
|
||||
|
||||
return obj[member](argvals)
|
||||
|
||||
for op, opfunc in _OPERATORS:
|
||||
m = re.match(r'(?P<x>.+?)%s(?P<y>.+)' % re.escape(op), expr)
|
||||
if not m:
|
||||
continue
|
||||
x, abort = self.interpret_statement(
|
||||
m.group('x'), local_vars, allow_recursion - 1)
|
||||
if abort:
|
||||
raise ExtractorError(
|
||||
'Premature left-side return of %s in %r' % (op, expr))
|
||||
y, abort = self.interpret_statement(
|
||||
m.group('y'), local_vars, allow_recursion - 1)
|
||||
if abort:
|
||||
raise ExtractorError(
|
||||
'Premature right-side return of %s in %r' % (op, expr))
|
||||
return opfunc(x, y)
|
||||
|
||||
m = re.match(
|
||||
r'^(?P<func>%s)\((?P<args>[a-zA-Z0-9_$,]*)\)$' % _NAME_RE, expr)
|
||||
if m:
|
||||
fname = m.group('func')
|
||||
argvals = tuple([
|
||||
int(v) if v.isdigit() else local_vars[v]
|
||||
for v in m.group('args').split(',')]) if len(m.group('args')) > 0 else tuple()
|
||||
if fname not in self._functions:
|
||||
self._functions[fname] = self.extract_function(fname)
|
||||
return self._functions[fname](argvals)
|
||||
|
||||
raise ExtractorError('Unsupported JS expression %r' % expr)
|
||||
|
||||
def extract_object(self, objname):
|
||||
_FUNC_NAME_RE = r'''(?:[a-zA-Z$0-9]+|"[a-zA-Z$0-9]+"|'[a-zA-Z$0-9]+')'''
|
||||
obj = {}
|
||||
obj_m = re.search(
|
||||
r'''(?x)
|
||||
(?<!this\.)%s\s*=\s*{\s*
|
||||
(?P<fields>(%s\s*:\s*function\s*\(.*?\)\s*{.*?}(?:,\s*)?)*)
|
||||
}\s*;
|
||||
''' % (re.escape(objname), _FUNC_NAME_RE),
|
||||
self.code)
|
||||
fields = obj_m.group('fields')
|
||||
# Currently, it only supports function definitions
|
||||
fields_m = re.finditer(
|
||||
r'''(?x)
|
||||
(?P<key>%s)\s*:\s*function\s*\((?P<args>[a-z,]+)\){(?P<code>[^}]+)}
|
||||
''' % _FUNC_NAME_RE,
|
||||
fields)
|
||||
for f in fields_m:
|
||||
argnames = f.group('args').split(',')
|
||||
obj[self.remove_quotes(f.group('key'))] = self.build_function(argnames, f.group('code'))
|
||||
|
||||
return obj
|
||||
|
||||
def extract_function(self, funcname):
|
||||
func_m = re.search(
|
||||
r'''(?x)
|
||||
(?:function\s+%s|[{;,]\s*%s\s*=\s*function|var\s+%s\s*=\s*function)\s*
|
||||
\((?P<args>[^)]*)\)\s*
|
||||
\{(?P<code>[^}]+)\}''' % (
|
||||
re.escape(funcname), re.escape(funcname), re.escape(funcname)),
|
||||
self.code)
|
||||
if func_m is None:
|
||||
raise ExtractorError('Could not find JS function %r' % funcname)
|
||||
argnames = func_m.group('args').split(',')
|
||||
|
||||
return self.build_function(argnames, func_m.group('code'))
|
||||
|
||||
def call_function(self, funcname, *args):
|
||||
f = self.extract_function(funcname)
|
||||
return f(args)
|
||||
|
||||
def build_function(self, argnames, code):
|
||||
def resf(args):
|
||||
local_vars = dict(list(zip(argnames, args)))
|
||||
for stmt in code.split(';'):
|
||||
res, abort = self.interpret_statement(stmt, local_vars)
|
||||
if abort:
|
||||
break
|
||||
return res
|
||||
return resf
|
||||
|
||||
|
||||
# inspired by https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/youtube.py
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
class SignatureExtractor:
|
||||
|
||||
def __init__(self):
|
||||
self.algoCache = {}
|
||||
|
||||
def decryptSignature(self, s, playerUrl):
|
||||
util.debug("decrypt_signature sign_len[%d] playerUrl[%s]" % (len(s), playerUrl))
|
||||
|
||||
if playerUrl is None:
|
||||
raise ExtractorError('Cannot decrypt signature without playerUrl')
|
||||
|
||||
if playerUrl.startswith('//'):
|
||||
playerUrl = 'https:' + playerUrl
|
||||
elif playerUrl.startswith('/'):
|
||||
playerUrl = 'https://youtube.com' + playerUrl
|
||||
|
||||
# use algoCache
|
||||
if playerUrl not in self.algoCache:
|
||||
# get player HTML 5 sript
|
||||
request = urllib.request.Request(playerUrl)
|
||||
try:
|
||||
self.playerData = urllib.request.urlopen(request).read()
|
||||
self.playerData = self.playerData.decode('utf-8', 'ignore')
|
||||
except:
|
||||
util.debug('Unable to download playerUrl webpage')
|
||||
return ''
|
||||
|
||||
patterns = [
|
||||
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'(?P<sig>[a-zA-Z0-9$]+)\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)',
|
||||
# Obsolete patterns
|
||||
r'(["\'])signature\1\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\.sig\|\|(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'yt\.akamaized\.net/\)\s*\|\|\s*.*?\s*[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?:encodeURIComponent\s*\()?\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\bc\s*&&\s*a\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\('
|
||||
]
|
||||
|
||||
match = None
|
||||
for pattern in patterns:
|
||||
match = re.search(pattern, self.playerData)
|
||||
if match is not None:
|
||||
break
|
||||
|
||||
if match:
|
||||
mainFunName = match.group('sig')
|
||||
util.debug('Main signature function name = "%s"' % mainFunName)
|
||||
else:
|
||||
util.debug('Can not get main signature function name')
|
||||
return ''
|
||||
|
||||
jsi = JSInterpreter(self.playerData)
|
||||
initial_function = jsi.extract_function(mainFunName)
|
||||
algoCodeObj = lambda s: initial_function([s])
|
||||
else:
|
||||
# get algoCodeObj from algoCache
|
||||
util.debug('Algo taken from cache')
|
||||
algoCodeObj = self.algoCache[playerUrl]
|
||||
|
||||
signature = algoCodeObj(s)
|
||||
|
||||
util.debug('Decrypted signature = [%s]' % signature)
|
||||
# if algo seems ok and not in cache, add it to cache
|
||||
if playerUrl not in self.algoCache and '' != signature:
|
||||
util.debug('Algo from player [%s] added to cache' % playerUrl)
|
||||
self.algoCache[playerUrl] = algoCodeObj
|
||||
|
||||
return signature
|
||||
|
||||
decryptor = SignatureExtractor()
|
||||
|
||||
'''
|
||||
YouTube plugin for XBMC
|
||||
Copyright (C) 2010-2012 Tobias Ussing And Henrik Mosgaard Jensen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
'''
|
||||
|
||||
import sys
|
||||
import cgi
|
||||
import json
|
||||
|
||||
class YoutubePlayer(object):
|
||||
fmt_value = {
|
||||
5: "240p",
|
||||
18: "360p",
|
||||
22: "720p",
|
||||
26: "???",
|
||||
33: "???",
|
||||
34: "360p",
|
||||
35: "480p",
|
||||
37: "1080p",
|
||||
38: "720p",
|
||||
43: "360p",
|
||||
44: "480p",
|
||||
45: "720p",
|
||||
46: "520p",
|
||||
59: "480",
|
||||
78: "400",
|
||||
82: "360p",
|
||||
83: "240p",
|
||||
84: "720p",
|
||||
85: "520p",
|
||||
100: "360p",
|
||||
101: "480p",
|
||||
102: "720p",
|
||||
120: "hd720",
|
||||
121: "hd1080"
|
||||
}
|
||||
|
||||
# YouTube Playback Feeds
|
||||
urls = {}
|
||||
urls['video_stream'] = "http://www.youtube.com/watch?v=%s&safeSearch=none"
|
||||
urls['embed_stream'] = "http://www.youtube.com/embed/%s"
|
||||
urls['video_info'] = "http://www.youtube.com/get_video_info?video_id=%s" \
|
||||
"&eurl=https://youtube.googleapis.com/v/%s&sts=%s"
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def removeAdditionalEndingDelimiter(self, data):
|
||||
pos = data.find("};")
|
||||
if pos != -1:
|
||||
data = data[:pos + 1]
|
||||
return data
|
||||
|
||||
def extractFlashVars(self, data, assets):
|
||||
flashvars = {}
|
||||
found = False
|
||||
|
||||
for line in data.split("\n"):
|
||||
if line.strip().find(";ytplayer.config = ") > 0:
|
||||
found = True
|
||||
p1 = line.find(";ytplayer.config = ") + len(";ytplayer.config = ") - 1
|
||||
p2 = line.rfind(";")
|
||||
if p1 <= 0 or p2 <= 0:
|
||||
continue
|
||||
data = line[p1 + 1:p2]
|
||||
break
|
||||
data = self.removeAdditionalEndingDelimiter(data)
|
||||
|
||||
if found:
|
||||
data = json.loads(data)
|
||||
if assets:
|
||||
flashvars = data["assets"]
|
||||
else:
|
||||
flashvars = data["args"]
|
||||
return flashvars
|
||||
|
||||
def scrapeWebPageForVideoLinks(self, result, video, video_id):
|
||||
links = {}
|
||||
if re.search(r'player-age-gate-content">', result) is not None:
|
||||
# We simulate the access to the video from www.youtube.com/v/{video_id}
|
||||
# this can be viewed without login into Youtube
|
||||
embed_webpage = util.request(self.urls["embed_stream"] % video_id)
|
||||
|
||||
sts = re.search('"sts"\s*:\s*(\d+)', embed_webpage).group().replace('"sts":', '')
|
||||
result = util.request(self.urls["video_info"] % (video_id, video_id, sts))
|
||||
|
||||
flashvars = cgi.parse_qs(result)
|
||||
flashvars["url_encoded_fmt_stream_map"] = flashvars["url_encoded_fmt_stream_map"][0]
|
||||
flashvars["title"] = flashvars["title"][0]
|
||||
else:
|
||||
flashvars = self.extractFlashVars(result, 0)
|
||||
|
||||
if "url_encoded_fmt_stream_map" not in flashvars:
|
||||
return links
|
||||
|
||||
if "ttsurl" in flashvars:
|
||||
video["ttsurl"] = flashvars["ttsurl"]
|
||||
if "title" in flashvars:
|
||||
video["title"] = flashvars["title"]
|
||||
|
||||
for url_desc in flashvars["url_encoded_fmt_stream_map"].split(","):
|
||||
url_desc_map = cgi.parse_qs(url_desc)
|
||||
if not ("url" in url_desc_map or "stream" in url_desc_map):
|
||||
continue
|
||||
|
||||
key = int(url_desc_map["itag"][0])
|
||||
url = ""
|
||||
if "url" in url_desc_map:
|
||||
url = urllib.parse.unquote(url_desc_map["url"][0])
|
||||
elif "conn" in url_desc_map and "stream" in url_desc_map:
|
||||
url = urllib.parse.unquote(url_desc_map["conn"][0])
|
||||
if url.rfind("/") < len(url) - 1:
|
||||
url = url + "/"
|
||||
url = url + urllib.parse.unquote(url_desc_map["stream"][0])
|
||||
elif "stream" in url_desc_map and "conn" not in url_desc_map:
|
||||
url = urllib.parse.unquote(url_desc_map["stream"][0])
|
||||
|
||||
if "sig" in url_desc_map:
|
||||
url = url + "&sig=" + url_desc_map["sig"][0]
|
||||
elif "s" in url_desc_map:
|
||||
sig = url_desc_map["s"][0]
|
||||
flashvars = self.extractFlashVars(result, 1)
|
||||
js = flashvars["js"]
|
||||
url = url + "&sig=" + self.decrypt_signature(sig, js)
|
||||
|
||||
links[key] = url
|
||||
|
||||
return links
|
||||
|
||||
def decrypt_signature(self, s, js):
|
||||
return decryptor.decryptSignature(s, js)
|
||||
|
||||
|
||||
def extractVideoLinksFromYoutube(self, url, videoid, video):
|
||||
result = util.request(self.urls["video_stream"] % videoid)
|
||||
links = self.scrapeWebPageForVideoLinks(result, video, videoid)
|
||||
if len(links) == 0:
|
||||
util.error("Couldn't find video url- or stream-map.")
|
||||
return links
|
||||
# /*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re, util, urllib.request, urllib.parse, urllib.error
|
||||
__name__ = 'youtube'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
player = YoutubePlayer()
|
||||
video = {'title':'žádný název'}
|
||||
index = url.find('&') # strip out everytihing after &
|
||||
if index > 0:
|
||||
url = url[:index]
|
||||
links = player.extractVideoLinksFromYoutube(url, m.group('id'), video)
|
||||
resolved = []
|
||||
for q in links:
|
||||
if q in list(player.fmt_value.keys()):
|
||||
quality = player.fmt_value[q]
|
||||
item = {}
|
||||
item['name'] = __name__
|
||||
item['url'] = links[q]
|
||||
item['quality'] = quality
|
||||
item['surl'] = url
|
||||
item['subs'] = ''
|
||||
item['title'] = video['title']
|
||||
item['fmt'] = q
|
||||
resolved.append(item)
|
||||
return resolved
|
||||
|
||||
def _regex(url):
|
||||
return re.search('(www\.youtube\.com/(watch\?v=|v/|embed/)|youtu\.be/)(?P<id>.+?)(\?|$|&)', url, re.IGNORECASE | re.DOTALL)
|
||||
41
lib/server/youwatch.py
Normal file
41
lib/server/youwatch.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# /*
|
||||
# * Copyright (C) 2015 Lubomir Kucera
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re
|
||||
import util
|
||||
|
||||
__author__ = 'Jose Riha/Lubomir Kucera'
|
||||
__name__ = 'youwatch'
|
||||
|
||||
|
||||
def supports(url):
|
||||
return re.search(r'youwatch\.org/embed\-[^\.]+\.html', url) is not None
|
||||
|
||||
|
||||
def resolve(url):
|
||||
refererurl = re.search(r'<iframe src="([^"]+)".*', util.request(url), re.I | re.S).group(1)
|
||||
try:
|
||||
data=[x for x in util.request(refererurl).splitlines() if 'file:' in x and '.mp4' in x][0]
|
||||
except:
|
||||
return None
|
||||
streamurl = re.search(r'.*file:"([^"]+?)".*', data).group(1)
|
||||
headers={'Referer': refererurl}
|
||||
return [{'url': streamurl, 'headers': headers}]
|
||||
43
lib/server/zideonlresolver.py
Normal file
43
lib/server/zideonlresolver.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
|
||||
import util,re
|
||||
__name__ = 'zideo'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
if not m == None:
|
||||
url = re.sub('.*player.swf\?','',url)
|
||||
data = util.request('http://www.zideo.nl/player/config?'+url)
|
||||
try:
|
||||
link = re.search('<file>([^<]+)',data).group(1)
|
||||
# hd = re.search('<hd\.state>([^<]+)',data).group(1)
|
||||
# if hd == 'true':
|
||||
# link = re.search('<hd\.file>([^<]+)',data).group(1)
|
||||
return [{'url':link}]
|
||||
except:
|
||||
pass
|
||||
|
||||
def _regex(url):
|
||||
return re.search('http://(www\.)?zideo.nl/player.swf', url, re.IGNORECASE | re.DOTALL)
|
||||
45
lib/server/zkouknitoresolver.py
Normal file
45
lib/server/zkouknitoresolver.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#/*
|
||||
# * Copyright (C) 2011 Libor Zoubek
|
||||
# *
|
||||
# *
|
||||
# * This Program is free software; you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation; either version 2, or (at your option)
|
||||
# * any later version.
|
||||
# *
|
||||
# * This Program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; see the file COPYING. If not, write to
|
||||
# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
# * http://www.gnu.org/copyleft/gpl.html
|
||||
# *
|
||||
# */
|
||||
import re,util
|
||||
__name__ = 'zkouknito'
|
||||
def supports(url):
|
||||
return not _regex(url) == None
|
||||
|
||||
# returns the steam url
|
||||
def resolve(url):
|
||||
m = _regex(url)
|
||||
f=None
|
||||
if not m is None:
|
||||
try:
|
||||
data = util.request('http://www.zkouknito.cz/player/scripts/videoinfo_externi.php?id=%s' % m.group('id'))
|
||||
f = re.search('<file>([^<]+)', data, re.IGNORECASE | re.DOTALL)
|
||||
except Exception:
|
||||
data = util.request(url)
|
||||
f = re.search("\'file\':.*?'([^']+)", data, re.IGNORECASE | re.DOTALL)
|
||||
if f:
|
||||
return [{'url':f.group(1)}]
|
||||
|
||||
|
||||
def _regex(url):
|
||||
m1 = re.search('(www\.)zkouknito.cz/(.+?)vid=(?P<id>[\d]+)', url, re.IGNORECASE | re.DOTALL)
|
||||
m2 = re.search('(www\.)zkouknito.cz/(.+?)', url, re.IGNORECASE | re.DOTALL)
|
||||
return m1 or m2
|
||||
Reference in New Issue
Block a user