This commit is contained in:
Pavel Suha
2025-04-25 16:31:48 +02:00
commit 7b54ba45a1
132 changed files with 6984 additions and 0 deletions

0
lib/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

209
lib/aadecode.py Normal file
View File

@@ -0,0 +1,209 @@
#-*- coding: utf-8 -*-
#
# author : Djeman
# Updated by Shani-08 (https://github.com/Shani-08/ShaniXBMCWork2)
import re
class AADecoder(object):
def __init__(self, aa_encoded_data):
self.encoded_str = aa_encoded_data.replace('/*´∇`*/','')
self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)",
"(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))",
"((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ",
"(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"]
def is_aaencoded(self):
idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ")
if idx == -1:
return False
if self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) == -1:
return False
return True
def base_repr(self, number, base=2, padding=0):
digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
if base > len(digits):
base = len(digits)
num = abs(number)
res = []
while num:
res.append(digits[num % base])
num //= base
if padding:
res.append('0' * padding)
if number < 0:
res.append('-')
return ''.join(reversed(res or '0'))
def decode_char(self, enc_char, radix):
end_char = "+ "
str_char = ""
while enc_char != '':
found = False
if not found:
for i in range(len(self.b)):
enc_char=enc_char.replace(self.b[i], str(i))
startpos=0
findClose=True
balance=1
result=[]
if enc_char.startswith('('):
l=0
for t in enc_char[1:]:
l+=1
if findClose and t==')':
balance-=1;
if balance==0:
result+=[enc_char[startpos:l+1]]
findClose=False
continue
elif not findClose and t=='(':
startpos=l
findClose=True
balance=1
continue
elif t=='(':
balance+=1
if result is None or len(result)==0:
return ""
else:
for r in result:
value = self.decode_digit(r, radix)
if value == "":
return ""
else:
str_char += value
return str_char
enc_char = enc_char[len(end_char):]
return str_char
def decode_digit(self, enc_int, radix):
rr = '(\(.+?\)\))\+'
rerr=enc_int.split('))+')
v = ''
#new mode
for c in rerr:
if len(c)>0:
if c.strip().endswith('+'):
c=c.strip()[:-1]
startbrackets=len(c)-len(c.replace('(',''))
endbrackets=len(c)-len(c.replace(')',''))
if startbrackets>endbrackets:
c+=')'*startbrackets-endbrackets
c = c.replace('!+[]','1')
c = c.replace('-~','1+')
c = c.replace('[]','0')
v+=str(eval(c))
return v
mode = 0
value = 0
while enc_int != '':
found = False
for i in range(len(self.b)):
if enc_int.find(self.b[i]) == 0:
if mode == 0:
value += i
else:
value -= i
enc_int = enc_int[len(self.b[i]):]
found = True
break
if not found:
return ""
enc_int = re.sub('^\s+|\s+$', '', enc_int)
if enc_int.find("+") == 0:
mode = 0
else:
mode = 1
enc_int = enc_int[1:]
enc_int = re.sub('^\s+|\s+$', '', enc_int)
return self.base_repr(value, radix)
def decode(self):
self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str)
# get data
pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)")
result = re.search(pattern, self.encoded_str, re.DOTALL)
if result is None:
print("AADecoder: data not found")
return False
data = result.group(1)
# hex decode string
begin_char = "(゚Д゚)[゚ε゚]+"
alt_char = "(o゚ー゚o)+ "
out = ''
while data != '':
# Check new char
if data.find(begin_char) != 0:
print("AADecoder: data not found")
return False
data = data[len(begin_char):]
# Find encoded char
enc_char = ""
if data.find(begin_char) == -1:
enc_char = data
data = ""
else:
enc_char = data[:data.find(begin_char)]
data = data[len(enc_char):]
radix = 8
# Detect radix 16 for utf8 char
if enc_char.find(alt_char) == 0:
enc_char = enc_char[len(alt_char):]
radix = 16
str_char = self.decode_char(enc_char, radix)
if str_char == "":
print("no match : ")
print(data + "\nout = " + out + "\n")
return False
out += chr(int(str_char, radix))
if out == "":
print("no match : " + data)
return False
return out

189
lib/cloudflare.py Normal file
View File

@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 tknorris (Derived from Mikey1234's & Lambda's)
#
# 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 XBMC; 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
#
# This code is a derivative of the YouTube plugin for XBMC and associated works
# released under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3
import re
import urllib.request, urllib.parse, urllib.error
import urllib.parse
import util
import xbmc
MAX_TRIES = 3
COMPONENT = __name__
class NoRedirection(urllib.request.HTTPErrorProcessor):
def http_response(self, request, response):
util.info('[CF] Stopping Redirect')
return response
https_response = http_response
def solve_equation(equation):
try:
offset = (1 if equation[0] == '+' else 0)
ev = equation.replace('!+[]', '1').replace('!![]',
'1').replace('[]', '0').replace('(', 'str(')[offset:]
ev = re.sub(r'^str', 'float', re.sub(r'\/(.)str', r'/\1float', ev))
# util.debug('[CF] eval: {0}'.format(ev))
return float(eval(ev))
except:
pass
def solve(url, cj, user_agent=None, wait=True):
if user_agent is None:
user_agent = util.UA
headers = {'User-Agent': user_agent, 'Referer': url}
if cj is not None:
try:
cj.load(ignore_discard=True)
except:
pass
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
urllib.request.install_opener(opener)
scheme = urllib.parse.urlparse(url).scheme
domain = urllib.parse.urlparse(url).hostname
request = urllib.request.Request(url)
for key in headers:
request.add_header(key, headers[key])
try:
response = urllib.request.urlopen(request)
html = response.read()
except urllib.error.HTTPError as e:
html = e.read()
tries = 0
while tries < MAX_TRIES:
solver_pattern = \
'var (?:s,t,o,p,b,r,e,a,k,i,n,g|t,r,a),f,\s*([^=]+)'
solver_pattern += \
'={"([^"]+)":([^}]+)};.+challenge-form\'\);'
vc_pattern = \
'input type="hidden" name="jschl_vc" value="([^"]+)'
pass_pattern = 'input type="hidden" name="pass" value="([^"]+)'
s_pattern = 'input type="hidden" name="s" value="([^"]+)'
init_match = re.search(solver_pattern, html, re.DOTALL)
vc_match = re.search(vc_pattern, html)
pass_match = re.search(pass_pattern, html)
s_match = re.search(s_pattern, html)
if not init_match or not vc_match or not pass_match or not s_match:
msg = \
"[CF] Couldn't find attribute: init: |%s| vc: |%s| pass: |%s| No cloudflare check?"
util.info(msg % (init_match, vc_match, pass_match))
return False
(init_dict, init_var, init_equation) = \
init_match.groups()
vc = vc_match.group(1)
password = pass_match.group(1)
s = s_match.group(1)
equations = re.compile(r"challenge-form\'\);\s*(.*)a.v").findall(html)[0]
# util.info("[CF] VC is: %s" % (vc))
varname = (init_dict, init_var)
# util.info('[CF] init: [{0}]'.format((init_equation.rstrip())))
result = float(solve_equation(init_equation.rstrip()))
util.info('[CF] Initial value: [ {0} ] Result: [ {1} ]'.format(init_equation,
result))
for equation in equations.split(';'):
equation = equation.rstrip()
if len(equation) > len('.'.join(varname)):
# util.debug('[CF] varname {0} line {1}'.format('.'.join(varname), equation))
if equation[:len('.'.join(varname))] != '.'.join(varname):
util.info('[CF] Equation does not start with varname |%s|'
% equation)
else:
equation = equation[len('.'.join(varname)):]
expression = equation[2:]
operator = equation[0]
if operator not in ['+', '-', '*', '/']:
util.info('[CF] Unknown operator: |%s|' % equation)
continue
result = float(str(eval(str(result) + operator + str(solve_equation(
expression)))))
#util.info('[CF] intermediate: %s = %s' % (equation, result))
#util.debug('[CF] POCET: {0} {1}'.format(result, len(domain)))
result = '{0:.10f}'.format(eval('float({0} + {1})'.format(result, len(domain))))
util.info('[CF] Final Result: |%s|' % result)
if wait:
util.info('[CF] Sleeping for 5 Seconds')
xbmc.sleep(5000)
url = \
'%s://%s/cdn-cgi/l/chk_jschl?s=%s&jschl_vc=%s&pass=%s&jschl_answer=%s' \
% (scheme, domain, urllib.parse.quote(s), urllib.parse.quote(vc), urllib.parse.quote(password), urllib.parse.quote(result))
# util.info('[CF] url: %s' % url)
# util.debug('[CF] headers: {0}'.format(headers))
request = urllib.request.Request(url)
for key in headers:
request.add_header(key, headers[key])
try:
opener = urllib.request.build_opener(NoRedirection)
urllib.request.install_opener(opener)
response = urllib.request.urlopen(request)
# util.info('[CF] code: {}'.format(response.getcode()))
while response.getcode() in [301, 302, 303, 307]:
if cj is not None:
cj.extract_cookies(response, request)
redir_url = response.info().getheader('location')
if not redir_url.startswith('http'):
base_url = '%s://%s' % (scheme, domain)
redir_url = urllib.parse.urljoin(base_url, redir_url)
request = urllib.request.Request(redir_url)
for key in headers:
request.add_header(key, headers[key])
if cj is not None:
cj.add_cookie_header(request)
response = urllib.request.urlopen(request)
final = response.read()
if 'cf-browser-verification' in final:
util.info('[CF] Failure: html: %s url: %s' % (html, url))
tries += 1
html = final
else:
break
except urllib.error.HTTPError as e:
util.info('[CF] HTTP Error: %s on url: %s' % (e.code,
url))
return False
except urllib.error.URLError as e:
util.info('[CF] URLError Error: %s on url: %s' % (e,
url))
return False
if cj is not None:
util.cache_cookies()
return final

View File

@@ -0,0 +1,230 @@
# * Copyright (C) 2012 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
# *
# */
from collections import defaultdict
import util
import resolver
try:
import StorageServer
except ImportError:
print('Using dummy storage server')
import storageserverdummy as StorageServer
class ResolveException(Exception):
pass
class ContentProvider(object):
"""
ContentProvider class provides an internet content. It should NOT have any xbmc-related imports
and must be testable without XBMC runtime. This is a basic/dummy implementation.
"""
def __init__(self, name='dummy', base_url='/', username=None, password=None, filter=None, tmp_dir='.'):
"""
ContentProvider constructor
Args:
name (str): name of provider
base_url (str): base url of site being accessed
username (str): login username
password (str): login password
filter (func{item}): function to filter results returned by search or list methods
tmp_dir (str): temporary dir where provider can store/cache files
"""
self.name = name
self.username = username
self.password = password
if not base_url[-1] == '/':
base_url += '/'
self.base_url = base_url
self.filter = filter
self.tmp_dir = tmp_dir
self.cache = StorageServer.StorageServer(self.name, 24)
self.lang = 'cs' # initialize, current language could be set by XBMContentProvider
def __str__(self):
return 'ContentProvider' + self.name
def on_init(self):
"""
This function gets called by XbmcContentProvider after it initializes itself
and sets eveything up (especially 'lang' property of ContentProvider which gets detected
from kodi)
"""
pass
def capabilities(self):
"""
This way class defines which capabilities it provides ['login','search','resolve','categories']
It may also contain '!download' when provider does not support downloading
"""
return []
def video_item(self, url='', img='', quality='???'):
"""
Returns empty video item - contains all required fields
"""
return {'type': 'video', 'title': '', 'rating': 0, 'year': 0, 'size': '0MB', 'url': url, 'img': img,
'length': '', 'quality': quality, 'subs': '', 'surl': '', 'lang': ''}
def dir_item(self, title='', url='', type='dir'):
"""
Returns empty directory item
"""
return {'type': type, 'title': title, 'size': '0', 'url': url}
def login(self):
"""
A login method returns True on successfull login, False otherwise
"""
return False
def search(self, keyword):
"""
Search for a keyword on a site
Args:
keyword (str)
returns:
array of video or directory items
"""
return []
def list(self, url):
"""
Lists content on given url
Args:
url (str): either relative or absolute provider URL
Returns:
array of video or directory items
"""
return []
def categories(self):
"""
Lists categories on provided site
Returns:
array of video or directory items
"""
return []
def findstreams(self, data, regexes=None):
"""
Finds streams in given data (see resovler.findstreams for more details)
:param data: A string (piece of HTML, for example) or an array of URLs
:param regexes: An array of regexes to be used for extracting URLs from
'data' of type 'string'
:returns: An array of video items
"""
resolved = resolver.findstreams(data, regexes)
if resolved is None:
raise ResolveException(
'Nelze ziskat video link [CR]zkontrolujte jestli video nebylo odstraneno')
elif isinstance(resolved, list) and not resolved:
raise ResolveException('Video je na serveru, ktery neni podporovan')
elif not resolved:
raise ResolveException(
'Nebyl nalezen zadny video embed [CR]zkontrolujte stranku pripadne nahlaste chybu pluginu')
result = []
for j in resolved:
i = defaultdict(lambda: '', j)
item = self.video_item()
item['title'] = i['name']
item['url'] = i['url']
item['quality'] = i['quality']
item['surl'] = i['surl']
item['subs'] = i['subs']
item['headers'] = i['headers']
item['lang'] = i['lang']
item['info'] = i['info']
result.append(item)
return result
def resolve(self, item, captcha_cb=None, select_cb=None, wait_cb=None):
"""
Resolves given video item to a downloable/playable file/stream URL
Args:
url (str): relative or absolute URL to be resolved
captcha_cb(func{obj}): callback function when user input is required (captcha, one-time passwords etc).
function implementation must be Provider-specific
select_cb(func{array}): callback function for cases when given url resolves to multiple streams,
provider class may call this function and require user interaction
wait_cb(func{obj}): callback function for cases when url resolves to stream which becomes available
somewhere in future (typically in several seconds). Provider may call this and require waiting.
Returns:
None - if ``url`` was not resolved. Video item with 'url' key pointing to resolved target
"""
return None
def _url(self, url):
"""
Transforms relative to absolute url based on ``base_url`` class property
"""
if url.startswith('http'):
return url
return self.base_url + url.lstrip('./')
def _filter(self, result, item):
"""
Applies filter, if filter passes `item` is appended to `result`
Args:
result (array) : target array
item (obj) : item that is being applied filter on
"""
if self.filter:
if self.filter(item):
result.append(item)
else:
result.append(item)
def info(self, msg):
util.info('[%s] %s' % (self.name, msg))
def error(self, msg):
util.error('[%s] %s' % (self.name, msg))
class cached(object):
"""
A method decorator that can be used on any ContentProvider method
Having this decorator means that results of such method are going
to be cached for 24hours by default. You can pass number argument
to decorator, for example @cached(1) would cache for 1 hour.
"""
def __init__(self, ttl=24):
self.ttl = ttl
def __call__(self, f):
def wrap(*args):
provider = args[0]
cache = StorageServer.StorageServer(provider.name + str(self.ttl), self.ttl)
return cache.cacheFunction(f, *args)
return wrap

View File

@@ -0,0 +1,464 @@
# * Copyright (C) 2012 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 sys
import os
import re
import traceback
import util
import xbmcutil
import resolver
import time
import xbmcplugin
import xbmc
import xbmcvfs
import xbmcgui
import urllib.parse
import urllib.request, urllib.parse, urllib.error
from collections import defaultdict
from provider import ResolveException
class XBMContentProvider(object):
'''
ContentProvider class provides an internet content. It should NOT have any xbmc-related imports
and must be testable without XBMC runtime. This is a basic/dummy implementation.
'''
def __init__(self, provider, settings, addon):
'''
XBMContentProvider constructor
Args:
name (str): name of provider
'''
self.provider = provider
# inject current user language
try: # not fully supported on Frodo
provider.lang = xbmc.getLanguage(xbmc.ISO_639_1)
except:
provider.lang = None
pass
self.settings = settings
# lang setting is optional for plugins
if not 'lang' in self.settings:
self.settings['lang'] = '0'
util.info('Initializing provider %s with settings %s' % (provider.name, settings))
self.addon = addon
self.addon_id = addon.getAddonInfo('id')
if '!download' not in self.provider.capabilities():
self.check_setting_keys(['downloads'])
self.cache = provider.cache
provider.on_init()
def check_setting_keys(self, keys):
for key in keys:
if not key in list(self.settings.keys()):
raise Exception('Invalid settings passed - [' + key + '] setting is required')
def params(self):
return {'cp': self.provider.name}
def run(self, params):
if params == {} or params == self.params():
return self.root()
if 'list' in list(params.keys()):
self.list(self.provider.list(params['list']))
return xbmcplugin.endOfDirectory(int(sys.argv[1]))
if 'down' in list(params.keys()):
return self.download({'url': params['down'], 'title': params['title']})
if 'play' in list(params.keys()):
return self.play({'url': params['play'], 'info': params})
if 'search-list' in list(params.keys()):
return self.search_list()
if 'search' in list(params.keys()):
return self.do_search(params['search'])
if 'search-remove' in list(params.keys()):
return self.search_remove(params['search-remove'])
if 'search-edit' in list(params.keys()):
return self.search_edit(params['search-edit'])
if self.run_custom:
return self.run_custom(params)
def search_list(self):
params = self.params()
params.update({'search': '#'})
menu1 = self.params()
menu2 = self.params()
xbmcutil.add_dir(xbmcutil.__lang__(30004), params, xbmcutil.icon('search.png'))
for what in xbmcutil.search_list(self.cache):
params['search'] = what
menu1['search-remove'] = what
menu2['search-edit'] = what
xbmcutil.add_dir(what, params, menuItems={xbmcutil.__lang__(
30016): menu2, xbmc.getLocalizedString(117): menu1})
xbmcplugin.endOfDirectory(int(sys.argv[1]))
def search_remove(self, what):
xbmcutil.search_remove(self.cache, what)
xbmc.executebuiltin('Container.Refresh')
def search_edit(self, what):
kb = xbmc.Keyboard(what, xbmcutil.__lang__(30003), False)
kb.doModal()
if kb.isConfirmed():
replacement = kb.getText()
xbmcutil.search_replace(self.cache, what, replacement)
params = self.params()
params.update({'search': replacement})
action = xbmcutil._create_plugin_url(params)
xbmc.executebuiltin('Container.Update(%s)' % action)
def do_search(self, what):
if what == '' or what == '#':
kb = xbmc.Keyboard('', xbmcutil.__lang__(30003), False)
kb.doModal()
if kb.isConfirmed():
what = kb.getText()
if not what == '':
maximum = 20
try:
maximum = int(self.settings['keep-searches'])
except:
util.error('Unable to parse convert addon setting to number')
pass
xbmcutil.search_add(self.cache, what, maximum)
self.search(what)
def root(self):
searches = xbmcutil.get_searches(self.addon, self.provider.name)
if len(searches) > 0:
self.provider.info('Upgrading to new saved search storage...')
for s in searches:
self.provider.info('Moving item %s' % s)
xbmcutil.search_add(self.cache, s, 9999999)
xbmcutil.delete_search_history(self.addon, self.provider.name)
if 'search' in self.provider.capabilities():
params = self.params()
params.update({'search-list': '#'})
xbmcutil.add_dir(xbmcutil.__lang__(30003), params, xbmcutil.icon('search.png'))
if not '!download' in self.provider.capabilities():
xbmcutil.add_local_dir(xbmcutil.__lang__(30006), self.settings[
'downloads'], xbmcutil.icon('download.png'))
self.list(self.provider.categories())
return xbmcplugin.endOfDirectory(int(sys.argv[1]))
def download(self, item):
downloads = self.settings['downloads']
if '' == downloads:
xbmcgui.Dialog().ok(self.provider.name, xbmcutil.__lang__(30009))
return
stream = self.resolve(item['url'])
if stream:
if not 'headers' in list(stream.keys()):
stream['headers'] = {}
xbmcutil.reportUsage(self.addon_id, self.addon_id + '/download')
# clean up \ and /
name = item['title'].replace('/', '_').replace('\\', '_')
if not stream['subs'] == '':
xbmcutil.save_to_file(stream['subs'], os.path.join(
downloads, name + '.srt'), stream['headers'])
dot = name.find('.')
if dot <= 0:
# name does not contain extension, append some
name += '.mp4'
xbmcutil.download(self.addon, name, self.provider._url(
stream['url']), os.path.join(downloads, name), headers=stream['headers'])
def play(self, item):
stream = self.resolve(item['url'])
if stream:
xbmcutil.reportUsage(self.addon_id, self.addon_id + '/play')
if 'headers' in list(stream.keys()):
headerStr = '|' + urllib.parse.urlencode(stream['headers'])
if len(headerStr) > 1:
stream['url'] += headerStr.encode('utf-8')
print('Sending %s to player' % stream['url'])
li = xbmcgui.ListItem(path=stream['url'])
li.setArt({'icon': 'DefaulVideo.png'})
il = self._extract_infolabels(item['info'])
if len(il) > 0: # only set when something was extracted
li.setInfo('video', il)
try:
local_subs = xbmcutil.set_subtitles(li, stream['subs'], stream.get('headers'))
except:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
xbmcutil.load_subtitles(stream['subs'], stream.get('headers'))
else:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
def _handle_exc(self, e):
msg = e.message
if msg.find('$') == 0:
try:
msg = self.addon.getLocalizedString(int(msg[1:]))
except:
try:
msg = xbmcutil.__lang__(int(msg[1:]))
except:
pass
xbmcgui.Dialog().ok(self.provider.name, msg)
def resolve(self, url):
item = self.provider.video_item()
item.update({'url': url})
try:
return self.provider.resolve(item)
except ResolveException as e:
self._handle_exc(e)
def search(self, keyword):
self.list(self.provider.search(keyword))
return xbmcplugin.endOfDirectory(int(sys.argv[1]))
def list(self, items):
params = self.params()
for item in items:
if item['type'] == 'dir':
self.render_dir(item)
elif item['type'] == 'next':
params.update({'list': item['url']})
xbmcutil.add_dir(xbmcutil.__lang__(30007), params, xbmcutil.icon('next.png'))
elif item['type'] == 'prev':
params.update({'list': item['url']})
xbmcutil.add_dir(xbmcutil.__lang__(30008), params, xbmcutil.icon('prev.png'))
elif item['type'] == 'new':
params.update({'list': item['url']})
xbmcutil.add_dir(xbmcutil.__lang__(30012), params, xbmcutil.icon('new.png'))
elif item['type'] == 'top':
params.update({'list': item['url']})
xbmcutil.add_dir(xbmcutil.__lang__(30013), params, xbmcutil.icon('top.png'))
elif item['type'] == 'video':
self.render_video(item)
else:
self.render_default(item)
def render_default(self, item):
raise Exception("Unable to render item " + str(item))
def render_dir(self, item):
params = self.params()
params.update({'list': item['url']})
title = item['title']
img = None
if 'img' in list(item.keys()):
img = item['img']
if title.find('$') == 0:
try:
title = self.addon.getLocalizedString(int(title[1:]))
except:
pass
menuItems = {}
if 'menu' in list(item.keys()):
for ctxtitle, value in item['menu'].items():
if ctxtitle.find('$') == 0:
try:
ctxtitle = self.addon.getLocalizedString(int(ctxtitle[1:]))
except:
pass
menuItems[ctxtitle] = value
xbmcutil.add_dir(title, params, img, infoLabels=self._extract_infolabels(
item), menuItems=menuItems)
def _extract_infolabels(self, item):
infoLabels = {}
for label in ['title', 'plot', 'year', 'genre', 'rating', 'director',
'votes', 'cast', 'trailer', 'tvshowtitle', 'season',
'episode', 'duration']:
if label in list(item.keys()):
infoLabels[label] = util.decode_html(item[label])
return infoLabels
def render_video(self, item):
params = self.params()
params.update({'play': item['url']})
downparams = self.params()
downparams.update({'title': item['title'], 'down': item['url']})
def_item = self.provider.video_item()
if item['size'] == def_item['size']:
item['size'] = ''
else:
item['size'] = ' (%s)' % item['size']
title = '%s%s' % (item['title'], item['size'])
menuItems = {}
if "!download" not in self.provider.capabilities():
menuItems[xbmc.getLocalizedString(33003)] = downparams
if 'menu' in list(item.keys()):
for ctxtitle, value in item['menu'].items():
if ctxtitle.find('$') == 0:
try:
ctxtitle = self.addon.getLocalizedString(int(ctxtitle[1:]))
except:
pass
menuItems[ctxtitle] = value
xbmcutil.add_video(title,
params,
item['img'],
infoLabels=self._extract_infolabels(item),
menuItems=menuItems
)
def categories(self):
self.list(self.provider.categories(keyword))
return xbmcplugin.endOfDirectory(int(sys.argv[1]))
class XBMCMultiResolverContentProvider(XBMContentProvider):
def __init__(self, provider, settings, addon):
XBMContentProvider.__init__(self, provider, settings, addon)
self.check_setting_keys(['quality'])
def resolve(self, url):
item = self.provider.video_item()
item.update({'url': url})
def select_cb(resolved):
quality = self.settings['quality'] or '0'
filtered = resolver.filter_by_quality(resolved, quality)
lang = self.settings['lang'] or '0'
filtered = resolver.filter_by_language(filtered, lang)
# if user requested something but 'ask me' or filtered result is exactly 1
if len(filtered) == 1 or (int(quality) > 0 and int(lang) == 0):
return filtered[0]
# if user requested particular language and we have it
if len(filtered) > 0 and int(lang) > 0:
return filtered[0]
dialog = xbmcgui.Dialog()
opts = []
for r in resolved:
d = defaultdict(lambda: '', r)
opts.append('%s [%s] %s' % (d['title'], d['quality'], d['lang']))
ret = dialog.select(xbmcutil.__lang__(30005), opts)
if ret >= 0:
return resolved[ret]
try:
return self.provider.resolve(item, select_cb=select_cb)
except ResolveException as e:
self._handle_exc(e)
class XBMCLoginRequiredContentProvider(XBMContentProvider):
def root(self):
if not self.provider.login():
xbmcgui.Dialog().ok(self.provider.name, xbmcutil.__lang__(30011))
else:
return XBMContentProvider.root(self)
class XBMCLoginOptionalContentProvider(XBMContentProvider):
def __init__(self, provider, settings, addon):
XBMContentProvider.__init__(self, provider, settings, addon)
self.check_setting_keys(['vip'])
def ask_for_captcha(self, params):
img = os.path.join(str(xbmcvfs.translatePath(
self.addon.getAddonInfo('profile'))), 'captcha.png')
util.save_to_file(params['img'], img)
cd = CaptchaDialog('captcha-dialog.xml',
xbmcutil.__addon__.getAddonInfo('path'), 'default', '0')
cd.image = img
xbmc.sleep(3000)
cd.doModal()
del cd
kb = xbmc.Keyboard('', self.addon.getLocalizedString(200), False)
kb.doModal()
if kb.isConfirmed():
print('got code ' + kb.getText())
return kb.getText()
def ask_for_account_type(self):
if len(self.provider.username) == 0:
util.info('Username is not set, NOT using VIP account')
return False
if self.settings['vip'] == '0':
util.info('Asking user whether to use VIP account')
ret = xbmcgui.Dialog().yesno(self.provider.name, xbmcutil.__lang__(30010))
return ret == 1
return self.settings['vip'] == '1'
def resolve(self, url):
item = self.provider.video_item()
item.update({'url': url})
if not self.ask_for_account_type():
# set user/pass to null - user does not want to use VIP at this time
self.provider.username = None
self.provider.password = None
else:
if not self.provider.login():
xbmcgui.Dialog().ok(self.provider.name, xbmcutil.__lang__(30011))
return
try:
return self.provider.resolve(item, captcha_cb=self.ask_for_captcha)
except ResolveException as e:
self._handle_exc(e)
class XBMCLoginOptionalDelayedContentProvider(XBMCLoginOptionalContentProvider):
def wait_cb(self, wait):
left = wait
msg = xbmcutil.__lang__(30014).encode('utf-8')
while left > 0:
xbmc.executebuiltin("XBMC.Notification(%s,%s,1000,%s)" %
(self.provider.name, msg % str(left), ''))
left -= 1
time.sleep(1)
def resolve(self, url):
item = self.video_item()
item.update({'url': url})
if not self.ask_for_account_type():
# set user/pass to null - user does not want to use VIP at this time
self.provider.username = None
self.provider.password = None
else:
if not self.provider.login():
xbmcgui.Dialog().ok(self.provider.name, xbmcutil.__lang__(30011))
return
try:
return self.provider.resolve(item, captcha_cb=self.ask_for_captcha, wait_cb=self.wait_cb)
except ResolveException as e:
self._handle_exc(e)
class CaptchaDialog (xbmcgui.WindowXMLDialog):
def __init__(self, *args, **kwargs):
super(xbmcgui.WindowXMLDialog, self).__init__(args, kwargs)
self.image = None
def onFocus(self, controlId):
self.controlId = controlId
def onInit(self):
self.getControl(101).setImage(self.image)
def onAction(self, action):
if action.getId() in [9, 10]:
self.close()
def onClick(self, controlId):
if controlId == 102:
self.close()

0
lib/crypto/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

75
lib/crypto/md5crypt.py Normal file
View File

@@ -0,0 +1,75 @@
import hashlib
MAGIC = '$1$'
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def to64(v, n):
ret = ''
while n > 0:
ret += ITOA64[v & 0x3f]
v >>= 6
n -= 1
return ret
def apache_md5_crypt(pw, salt):
return unix_md5_crypt(pw, salt, '$apr1$')
def unix_md5_crypt(pw, salt, magic=None):
if magic is None:
magic = MAGIC
if salt.startswith(magic):
salt = salt[len(magic):]
salt = salt.split('$', 1)[0][:8]
pw_bytes = pw.encode('utf-8')
salt_bytes = salt.encode('utf-8')
magic_bytes = magic.encode('utf-8')
ctx = pw_bytes + magic_bytes + salt_bytes
final = hashlib.md5(pw_bytes + salt_bytes + pw_bytes).digest()
for pl in range(len(pw_bytes), 0, -16):
ctx += final[:min(16, pl)]
i = len(pw_bytes)
while i:
if i & 1:
ctx += b'\x00'
else:
ctx += pw_bytes[:1]
i >>= 1
final = hashlib.md5(ctx).digest()
for i in range(1000):
ctx1 = b''
if i & 1:
ctx1 += pw_bytes
else:
ctx1 += final
if i % 3:
ctx1 += salt_bytes
if i % 7:
ctx1 += pw_bytes
if i & 1:
ctx1 += final
else:
ctx1 += pw_bytes
final = hashlib.md5(ctx1).digest()
passwd = ''
passwd += to64((final[0] << 16) | (final[6] << 8) | final[12], 4)
passwd += to64((final[1] << 16) | (final[7] << 8) | final[13], 4)
passwd += to64((final[2] << 16) | (final[8] << 8) | final[14], 4)
passwd += to64((final[3] << 16) | (final[9] << 8) | final[15], 4)
passwd += to64((final[4] << 16) | (final[10] << 8) | final[5], 4)
passwd += to64(final[11], 2)
return magic + salt + '$' + passwd
md5crypt = unix_md5_crypt
if __name__ == "__main__":
print(unix_md5_crypt("cat", "hat"))

289
lib/resolver.py Normal file
View File

@@ -0,0 +1,289 @@
# -*- 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 sys
import os
import re
import traceback
import util
sys.path.append(os.path.join(os.path.dirname(__file__), 'server'))
RESOLVERS = []
util.debug('%s searching for modules' % __name__)
for module in os.listdir(os.path.join(os.path.dirname(__file__), 'server')):
if module == '__init__.py' or module[-3:] != '.py':
continue
module = module[:-3]
exec('import %s' % module)
resolver = eval(module)
util.debug('found %s %s' % (resolver, dir(resolver)))
if not hasattr(resolver, '__priority__'):
resolver.__priority__ = 0
RESOLVERS.append(resolver)
del module
RESOLVERS = sorted(RESOLVERS, key=lambda m: -m.__priority__)
util.debug('done')
def item():
return {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {}}
def resolve(url):
"""
resolves given url by asking all resolvers
returns None if no resolver advised to be able to resolve this url
returns False if resolver did his job, but did not return any value (thus failed)
returns Array of resolved objects in positive usecase
"""
url = util.decode_html(url)
util.info('Resolving ' + url)
resolver = _get_resolver(url)
value = None
if resolver is None:
return None
util.info('Using resolver \'%s\'' % str(resolver.__name__));
try:
value = resolver.resolve(url)
except:
traceback.print_exc()
if value is None:
return False
default = item()
def fix_stream(i, url, resolver, default):
""" fix missing but required values """
if 'name' not in list(i.keys()):
i['name'] = resolver.__name__
if 'surl' not in list(i.keys()):
i['surl'] = url
for key in list(default.keys()):
if key not in list(i.keys()):
i[key] = default[key]
[fix_stream(i, url, resolver, default) for i in value]
return sorted(value, key=lambda i: i['quality'])
def _get_resolver(url):
util.debug('Get resolver for ' + url)
for r in RESOLVERS:
util.debug('querying %s' % r)
if r.supports(url):
return r
def can_resolve(url):
""" Returns true if we are able to resolve stream by given URL """
return _get_resolver(url) is not None
def filter_resolvable(url):
if url.find('facebook') > 0 or url.find('yield') > 0:
return
return url.strip('\'\"')
def findstreams(data, regexes=None):
"""
Finds streams in given data. Respects caller add-on settings about
quality and asks user if necessary.
:param data: A string (piece of text / HTML code), an array of URLs or an
array of dictionaries, where 'url' key stores actual URL and
all other keys not present in item() are being copied to the
resolved stream dictionary
:param regexes: An array of strings - regular expressions, each MUST define
named group called 'url', which retrieves resolvable URL
(that one is passed to resolve operation); only used
with 'data' of type 'string'
:returns: An array of resolved objects, None if at least 1 resolver failed
to resolve and nothing else was found, an empty array if no
resolvers for URLs has been found or False if none of regexes
found anything
"""
def get_url(obj):
return obj['url'] if isinstance(obj, dict) else obj
urls = []
resolvables = []
resolved = []
not_found = False
if isinstance(data, str) and regexes:
for regex in regexes:
for match in re.finditer(regex, data, re.IGNORECASE | re.DOTALL):
urls.append(match.group('url'))
elif isinstance(data, list):
urls = data
else:
raise TypeError
for url in urls:
if isinstance(url, dict):
url['url'] = filter_resolvable(url['url'])
else:
url = filter_resolvable(url)
if url and url not in resolvables:
util.info('Found resolvable ' + get_url(url))
resolvables.append(url)
if len(resolvables) == 0:
util.info('No resolvables found!')
return False
for url in resolvables:
streams = resolve(get_url(url))
if streams is None:
util.info('No resolver found for ' + get_url(url))
not_found = True
elif not streams:
util.info('There was an error resolving ' + get_url(url))
elif len(streams) > 0:
for stream in streams:
if isinstance(url, dict):
for key in list(url.keys()):
if key not in stream:
stream[key] = url[key]
elif key not in item():
if isinstance(stream[key], str) and \
isinstance(url[key], str):
stream[key] = url[key] + ' +' + stream[key]
elif isinstance(stream[key], list) and \
isinstance(url[key], list):
stream[key] = url[key] + stream[key]
elif isinstance(stream[key], dict) and \
isinstance(url[key], dict):
stream[key].update(url[key])
resolved.append(stream)
if len(resolved) == 0:
if not_found:
return []
return None
resolved = sorted(resolved, key=lambda i: i['quality'])
resolved = sorted(resolved, key=lambda i: len(i['quality']))
resolved.reverse()
return resolved
q_map = {'3': '720p', '4': '480p', '5': '360p'}
def filter_by_quality(resolved, q):
util.info('filtering by quality setting ' + q)
if q == '0':
return resolved
sources = {}
ret = []
# first group streams by source url
for item in resolved:
if item['surl'] in list(sources.keys()):
sources[item['surl']].append(item)
else:
sources[item['surl']] = [item]
if q == '1':
# always return best quality from each source
for key in list(sources.keys()):
ret.append(sources[key][0])
elif q == '2':
# always return worse quality from each source
for key in list(sources.keys()):
ret.append(sources[key][-1])
else:
# we try to select sources of desired qualities
quality = q_map[q]
# 3,4,5 are 720,480,360
for key in list(sources.keys()):
added = False
for item in sources[key]:
if quality == item['quality']:
ret.append(item)
added = True
if not added:
util.debug('Desired quality %s not found, adding best found' % quality)
ret.append(sources[key][-1])
# sort results again, so best quality streams appear first
ret = sorted(ret, key=lambda i: i['quality'])
if not q == '2':
ret.reverse()
return ret
def filter_by_language(resolved, lang):
util.info('filtering by language setting ' + lang)
if lang == '0':
return resolved
ret = []
# first group streams by source url
for item in resolved:
if 'lang' in item and item['lang'] != '':
util.info(item)
if lang == '1' and re.match('en', item['lang'], re.IGNORECASE):
ret.append(item)
if lang == '2' and re.match('cs|cz|čeština', item['lang'], re.IGNORECASE):
ret.append(item)
return ret
def findstreams_multi(data, regexes):
"""
Finds streams in given data according to given regexes
respects caller addon's setting about desired quality, asks user if needed
assumes, that all resolvables need to be returned, but in particular quality
@param data piece of text (HTML code) to search in
@param regexes - array of strings - regular expressions, each MUST define named group called 'url'
which retrieves resolvable URL (that one is passsed to resolve operation)
@return array of dictionaries with keys: name,url,quality,surl
@return None if at least 1 resoler failed to resolve and nothing else has been found
@return [] if no resolvable URLs or no resolvers for URL has been found
"""
resolved = []
# keep list of found urls to aviod having duplicates
urls = []
error = False
for regex in regexes:
for match in re.finditer(regex, data, re.IGNORECASE | re.DOTALL):
print('Found resolvable %s ' % match.group('url'))
streams = resolve(match.group('url'))
if isinstance(streams, list) and streams:
util.debug('There was an error resolving ' + match.group('url'))
error = True
if streams is not None:
if len(streams) > 0:
for stream in streams:
resolved.append(stream)
if error and len(resolved) == 0:
return None
if len(resolved) == 0:
return []
resolved = sorted(resolved, key=lambda i: i['quality'])
resolved = sorted(resolved, key=lambda i: len(i['quality']))
resolved2 = resolved
resolved2.reverse()
qualities = {}
for item in resolved2:
if item['quality'] in list(qualities.keys()):
qualities[item['quality']].append(item)
else:
qualities[item['quality']] = [item]
# now .. we must sort items to be in same order as they were found on page
for q in list(qualities.keys()):
qualities[q] = sorted(qualities[q], key=lambda i: resolved.index(i))
return qualities

76
lib/search.py Normal file
View File

@@ -0,0 +1,76 @@
# -*- 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 os,re,sys
import xbmcplugin,xbmcaddon,xbmc
import xbmcutil,util
def _list(addon,history,key,value):
params = {}
menuItems = {}
if key:
params[key] = value
menuItems[key] = value
params['search'] = '#'
xbmcutil.add_dir(xbmcutil.__lang__(30004),params,xbmcutil.icon('search.png'))
for what in xbmcutil.get_searches(addon,history):
params['search'] = what
menuItems['search-remove'] = what
xbmcutil.add_dir(what,params,menuItems={xbmc.getLocalizedString(117):menuItems})
xbmcplugin.endOfDirectory(int(sys.argv[1]))
def _remove(addon,history,search):
xbmcutil.remove_search(addon,history,search)
xbmc.executebuiltin('Container.Refresh')
def _search(addon,history,what,update_history,callback):
if what == '' or what == '#':
kb = xbmc.Keyboard('',xbmcutil.__lang__(30003),False)
kb.doModal()
if kb.isConfirmed():
what = kb.getText()
if not what == '':
maximum = 20
try:
maximum = int(addon.getSetting('keep-searches'))
except:
util.error('Unable to parse convert addon setting to number')
pass
if update_history:
xbmcutil.add_search(addon,history,what,maximum)
callback(what)
def item(items={},label=xbmcutil.__lang__(30003)):
items['search-list'] = '#'
xbmcutil.add_dir(label,items,xbmcutil.icon('search.png'))
def main(addon,history,p,callback,key=None,value=None):
if (key==None) or (key in p and p[key] == value):
if 'search-list' in list(p.keys()):
_list(addon,history,key,value)
if 'search' in list(p.keys()):
update_history=True
if 'search-no-history' in list(p.keys()):
update_history=False
_search(addon,history,p['search'],update_history,callback)
if 'search-remove' in list(p.keys()):
_remove(addon,history,p['search-remove'])

31
lib/server/__init__.py Normal file
View 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'

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

View 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

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

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

View 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

View 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

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

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

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

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

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

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

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

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

View 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

View 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

View 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
View 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("&nbsp;","")
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('&amp;','&').replace('\xc9','E').replace('&#8211;', '-')
res=res.replace('&#038;', '&').replace('&rsquo;','\'').replace('\r','').replace('\n','')
res=res.replace('\t','').replace('&#039;',"'")
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}]

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

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

View 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

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

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

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

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

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

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

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

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

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

View 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

Some files were not shown because too many files have changed in this diff Show More