├── .gitignore ├── README.md ├── addon.xml ├── changelog.txt ├── icon.png ├── lib ├── __init__.py ├── default.py └── lambdascrapers │ ├── __init__.py │ ├── modules │ ├── __init__.py │ ├── cache.py │ ├── cfdecoder.py │ ├── cfscrape.py │ ├── cleandate.py │ ├── cleantitle.py │ ├── client.py │ ├── control.py │ ├── debrid.py │ ├── directstream.py │ ├── dom_parser.py │ ├── dom_parser2.py │ ├── js2py │ │ ├── __init__.py │ │ ├── base.py │ │ ├── constructors │ │ │ ├── __init__.py │ │ │ ├── jsarray.py │ │ │ ├── jsboolean.py │ │ │ ├── jsdate.py │ │ │ ├── jsfunction.py │ │ │ ├── jsmath.py │ │ │ ├── jsnumber.py │ │ │ ├── jsobject.py │ │ │ ├── jsregexp.py │ │ │ ├── jsstring.py │ │ │ ├── six.py │ │ │ └── time_helpers.py │ │ ├── evaljs.py │ │ ├── host │ │ │ ├── __init__.py │ │ │ ├── console.py │ │ │ ├── dom │ │ │ │ ├── __init__.py │ │ │ │ ├── constants.py │ │ │ │ └── interface.py │ │ │ ├── jseval.py │ │ │ └── jsfunctions.py │ │ ├── legecy_translators │ │ │ ├── __init__.py │ │ │ ├── constants.py │ │ │ ├── exps.py │ │ │ ├── flow.py │ │ │ ├── functions.py │ │ │ ├── jsparser.py │ │ │ ├── nodevisitor.py │ │ │ ├── nparser.py │ │ │ ├── objects.py │ │ │ ├── tokenize.py │ │ │ ├── translator.py │ │ │ └── utils.py │ │ ├── prototypes │ │ │ ├── __init__.py │ │ │ ├── jsarray.py │ │ │ ├── jsboolean.py │ │ │ ├── jserror.py │ │ │ ├── jsfunction.py │ │ │ ├── jsjson.py │ │ │ ├── jsnumber.py │ │ │ ├── jsobject.py │ │ │ ├── jsregexp.py │ │ │ ├── jsstring.py │ │ │ └── six.py │ │ ├── pyjs.py │ │ ├── six.py │ │ ├── todo │ │ ├── translators │ │ │ ├── __init__.py │ │ │ ├── friendly_nodes.py │ │ │ ├── jsregexps.py │ │ │ ├── markdown.js │ │ │ ├── pyjsparser.py │ │ │ ├── pyjsparserdata.py │ │ │ ├── six.py │ │ │ ├── std_nodes.py │ │ │ ├── translating_nodes.py │ │ │ └── translator.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── definitions.py │ │ │ ├── injector.py │ │ │ └── six.py │ ├── jsunfuck.py │ ├── jsunpack.py │ ├── log_utils.py │ ├── proxy.py │ ├── pyaes │ │ ├── __init__.py │ │ ├── aes.py │ │ ├── blockfeeder.py │ │ └── util.py │ ├── regex.py │ ├── source_utils.py │ ├── trakt.py │ ├── tvmaze.py │ ├── utils.py │ └── workers.py │ └── sources_ lambdascrapers │ ├── __init__.py │ ├── de │ ├── allucde.py │ ├── animebase.py │ ├── animeloads.py │ ├── bs.py │ ├── cine.py │ ├── cinenator.py │ ├── ddl.py │ ├── filmpalast.py │ ├── foxx.py │ ├── hdfilme.py │ ├── hdstreams.py │ ├── horrorkino.py │ ├── iload.py │ ├── kinodogs.py │ ├── kinoking.py │ ├── kinow.py │ ├── kinox.py │ ├── lichtspielhaus.py │ ├── movie2k-ac.py │ ├── movie2k-ag.py │ ├── movie2z.py │ ├── movie4k.py │ ├── moviesever.py │ ├── movietown.py │ ├── netzkino.py │ ├── proxer.py │ ├── pureanime.py │ ├── serienstream.py │ ├── seriesever.py │ ├── stream-to.py │ ├── streamdream.py │ ├── streamflix.py │ ├── streamit.py │ ├── tata.py │ ├── video4k.py │ └── view4u.py │ ├── en │ ├── 0123putlocker.py │ ├── 123fox.py │ ├── 123hbo.py │ ├── 123hulu.py │ ├── 123movieshubz.py │ ├── 300mbdownload.py │ ├── 4kmovieto.py │ ├── Hdmto.py │ ├── animetoon.py │ ├── azmovie.py │ ├── bnwmovies.py │ ├── cartoonhd.py │ ├── cmovieshd.py │ ├── cmovieshdbz.py │ ├── coolmoviezone.py │ ├── downflix.py │ ├── extramovies.py │ ├── filmxy.py │ ├── fmovies.py │ ├── freefmovies.py │ ├── freeputlockers.py │ ├── furk.py │ ├── gostream.py │ ├── gowatchseries.py │ ├── hdpopcorns.py │ ├── iwaatch.py │ ├── kattv.py │ ├── l23movies.py │ ├── library.py │ ├── moviesonline.py │ ├── movietoken.py │ ├── myprojectfreetv.py │ ├── odb.py │ ├── openloadmovie.py │ ├── ororo.py │ ├── plocker.py │ ├── primewire.py │ ├── putlocker.py │ ├── reddit.py │ ├── seehd.py │ ├── series9.py │ ├── seriesfree.py │ ├── seriesonline.py │ ├── sezonlukdizi.py │ ├── solarmoviez.py │ ├── tvbox.py │ ├── vdonip.py │ ├── videoscraper.py │ ├── vidics.py │ ├── watchseries.py │ ├── xwatchseries.py │ └── ymovies.py │ ├── en_DebridOnly │ ├── 300mbfilms.py │ ├── bestmoviez.py │ ├── ddlspot.py │ ├── ddlvalley.py │ ├── directdl.py │ ├── invictus.py │ ├── iwantmyshow.py │ ├── moviesleak.py │ ├── myvideolink.py │ ├── playmovies.py │ ├── rlsbb.py │ ├── scenerls.py │ ├── scnsrc.py │ ├── ultrahdindir.py │ └── wrzcraft.py │ ├── en_Torrent │ ├── bitlord.py │ ├── eztv.py │ ├── glodls.py │ ├── kickass2.py │ ├── limetorrents.py │ ├── piratebay.py │ ├── torrentapi.py │ ├── torrentdownloads.py │ ├── yify.py │ └── zoogle.py │ ├── es │ ├── megapelistv.py │ ├── peliculasdk.py │ ├── pelisplustv.py │ ├── pepecine.py │ └── seriespapaya.py │ ├── gr │ ├── gamatotv.py │ ├── liomenoi.py │ ├── tainiesonline.py │ ├── tainiomania.py │ └── xrysoi.py │ └── pl │ ├── alltube.py │ ├── boxfilm.py │ ├── cdahd.py │ ├── cdax.py │ ├── ekinomaniak.py │ ├── ekinotv.py │ ├── filiser.py │ ├── filmwebbooster.py │ ├── iitv.py │ ├── movieneo.py │ ├── openkatalog.py │ ├── paczamy.py │ ├── segos.py │ ├── szukajkatv.py │ └── trt.py └── resources └── settings.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # file: ~/.gitignore 2 | *.pyo 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LambdaScrapers 2 | ## **Scraper Module for Exodus based add ons.** 3 | -------------------------------------------------------------------------------- /addon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | executable 10 | 11 | 12 | all 13 | Lambdascrapers Module 14 | Scrape common video host for URL's to be playable in XBMC/Kodi, simplifying addon development of video plugins requiring multi video hosts. 15 | The author is not responsible for the use of this addon. The author is not responsible for the content found using this addon. The author does not host or own any content found within this addon.[CR]The author is in no way affiliated with Kodi, Team Kodi, or the XBMC Foundation.[CR]This is a Non-profit resource, organized solely for educational purposes which is protected under the Fair-Use doctrine of the Copyright Act, Specifically section 107, which does promote freedom of expression, by permitting the unlicensed use of copyright-protected works. 16 | all 17 | GNU GENERAL PUBLIC LICENSE. Version 3, 29 June 2007 18 | 19 | icon.png 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Lambdascrapers Module Changelog: 2 | 2.0.0 3 | - CivitasScrapers-0.0.5.8 base 4 | - Initial commit 5 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-A-C/script.module.lambdascrapers/74de3e5fa79f815031805fa7813efb68a087bd05/icon.png -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-A-C/script.module.lambdascrapers/74de3e5fa79f815031805fa7813efb68a087bd05/lib/__init__.py -------------------------------------------------------------------------------- /lib/default.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import urlparse 4 | from lambdascrapers.modules import control 5 | from lambdascrapers import providerSources, providerNames 6 | 7 | params = dict(urlparse.parse_qsl(sys.argv[2].replace('?', ''))) 8 | mode = params.get('mode') 9 | 10 | def ScraperChoice(): 11 | from lambdascrapers import providerSources 12 | sourceList = sorted(providerSources()) 13 | control.idle() 14 | select = control.selectDialog([i for i in sourceList]) 15 | if select == -1: return 16 | module_choice = sourceList[select] 17 | control.setSetting('module.provider', module_choice) 18 | control.openSettings('0.1') 19 | 20 | def ToggleProviderAll(enable): 21 | from lambdascrapers import providerNames 22 | sourceList = providerNames() 23 | (setting, open_id) = ('true', '0.3') if enable else ('false', '0.2') 24 | for i in sourceList: 25 | source_setting = 'provider.' + i 26 | control.setSetting(source_setting, setting) 27 | control.openSettings(open_id) 28 | 29 | def toggleAll(setting, open_id=None, sourceList=None): 30 | from lambdascrapers import getAllHosters 31 | sourceList = getAllHosters() if not sourceList else sourceList 32 | for i in sourceList: 33 | source_setting = 'provider.' + i 34 | control.setSetting(source_setting, setting) 35 | control.openSettings(open_id) 36 | 37 | 38 | 39 | if mode == "LambdaSettings": 40 | control.openSettings('0.0', 'script.module.lambdascrapers') 41 | 42 | if mode == "ScraperChoice": 43 | ScraperChoice() 44 | 45 | if mode == "ToggleProviderAll": 46 | ToggleProviderAll(False if params['action'] == "DisableModuleAll" else True) 47 | 48 | if mode == "toggleAll": 49 | open_id = params['open_id'] if 'open_id' in params else '0.0' 50 | sourcelist = params['sourcelist'] if 'sourcelist' in params else None 51 | toggleAll(params['setting'], open_id, sourceList=sourcelist) 52 | 53 | if mode == "toggleAllDebrid": 54 | sourcelist = ['300mbfilms','bestmoviez','ddlvalley','ddlspot','directdl','invictus','myvideolink', 55 | 'playmovies','scenerls','ultrahdindir','wrzcraft','iwantmyshow','moviesleak'] 56 | toggleAll(params['setting'], params['open_id'], sourcelist) 57 | 58 | if mode == "toggleAllGerman": 59 | sourcelist = ['gamatotv','liomenoi','tainiesonline','tainiomania','xrysoi'] 60 | toggleAll(params['setting'], params['open_id'], sourcelist) 61 | 62 | if mode == "toggleAllPolish": 63 | sourcelist = ['alltube','boxfilm','cdahd','cdax','ekinomaniak','ekinotv','filiser', 64 | 'filmwebbooster','iitv','movieneo','openkatalog','paczamy','segos','szukajkatv','trt'] 65 | toggleAll(params['setting'], params['open_id'], sourcelist) 66 | 67 | if mode == "toggleAllSpanish": 68 | sourcelist = ['megapelistv','peliculasdk','pelisplustv','pepecine','seriespapaya'] 69 | toggleAll(params['setting'], params['open_id'], sourcelist) 70 | 71 | if mode == "toggleAllForeign": 72 | sourcelist = ['gamatotv','liomenoi','tainiesonline','tainiomania','xrysoi', 73 | 'alltube','boxfilm','cdahd','cdax','ekinomaniak','ekinotv','filiser', 74 | 'filmwebbooster','iitv','movieneo','openkatalog','paczamy','segos', 75 | 'szukajkatv','trt','megapelistv','peliculasdk','pelisplustv','pepecine','seriespapaya'] 76 | toggleAll(params['setting'], params['open_id'], sourcelist) 77 | 78 | if mode == "toggleAllTorrent": 79 | sourcelist = ['bitlord','torrentapi','yify','piratebay','eztv','zoogle','glodls','limetorrents','torrentdownloads'] 80 | toggleAll(params['setting'], params['open_id'], sourcelist) 81 | 82 | if mode == "Defaults": 83 | sourcelist = ['123fox','123hbo','123movieshubz','animetoon','azmovies','bnwmovies','cartoonhd', 84 | 'extramovies','fmovies','freefmovies','freeputlockers','gostream','Hdmto','hdpopcorns', 85 | 'kattv','l23movies','iwaatch','openloadmovie','primewire','putlocker','reddit','rlsbb','scenerls', 86 | 'seehd','series9','seriesfree','seriesonline','solarmoviez','tvbox','vidics','watchseries', 87 | 'xwatchseries','vdonip','odb','downflix','ymovies','ddlspot','filmxy','kickass2','sezonlukdizi'] 88 | toggleAll(params['setting'], params['open_id'], sourcelist) 89 | -------------------------------------------------------------------------------- /lib/lambdascrapers/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | import pkgutil 4 | import os.path 5 | 6 | import xbmcaddon 7 | 8 | __addon__ = xbmcaddon.Addon(id='script.module.lambdascrapers') 9 | 10 | def sources(): 11 | try: 12 | sourceDict = [] 13 | provider = __addon__.getSetting('module.provider') 14 | sourceFolder = getScraperFolder(provider) 15 | sourceFolderLocation = os.path.join(os.path.dirname(__file__), sourceFolder) 16 | sourceSubFolders = [x[1] for x in os.walk(sourceFolderLocation)][0] 17 | for i in sourceSubFolders: 18 | for loader, module_name, is_pkg in pkgutil.walk_packages([os.path.join(sourceFolderLocation, i)]): 19 | if is_pkg: 20 | continue 21 | try: 22 | module = loader.find_module(module_name).load_module(module_name) 23 | sourceDict.append((module_name, module.source())) 24 | except: pass 25 | return enabledHosters(sourceDict) 26 | except: 27 | return [] 28 | 29 | def enabledHosters(sourceDict, function=False): 30 | enabledHosts = [i[0] for i in sourceDict if __addon__.getSetting('provider.' + i[0].split('_')[0]) == 'true'] 31 | returnedHosts = [i for i in sourceDict if i[0] in enabledHosts] 32 | return returnedHosts 33 | 34 | def providerSources(): 35 | sourceSubFolders = [x[1] for x in os.walk(os.path.dirname(__file__))][0] 36 | return getModuleName(sourceSubFolders) 37 | 38 | def providerNames(): 39 | providerList = [] 40 | provider = __addon__.getSetting('module.provider') 41 | sourceFolder = getScraperFolder(provider) 42 | sourceFolderLocation = os.path.join(os.path.dirname(__file__), sourceFolder) 43 | sourceSubFolders = [x[1] for x in os.walk(sourceFolderLocation)][0] 44 | for i in sourceSubFolders: 45 | for loader, module_name, is_pkg in pkgutil.walk_packages([os.path.join(sourceFolderLocation, i)]): 46 | if is_pkg: 47 | continue 48 | correctName = module_name.split('_')[0] 49 | providerList.append(correctName) 50 | return providerList 51 | 52 | def getAllHosters(): 53 | def _sources(sourceFolder, appendList): 54 | sourceFolderLocation = os.path.join(os.path.dirname(__file__), sourceFolder) 55 | sourceSubFolders = [x[1] for x in os.walk(sourceFolderLocation)][0] 56 | for i in sourceSubFolders: 57 | for loader, module_name, is_pkg in pkgutil.walk_packages([os.path.join(sourceFolderLocation, i)]): 58 | if is_pkg: 59 | continue 60 | try: mn = str(module_name).split('_')[0] 61 | except: mn = str(module_name) 62 | appendList.append(mn) 63 | sourceSubFolders = [x[1] for x in os.walk(os.path.dirname(__file__))][0] 64 | appendList = [] 65 | for item in sourceSubFolders: 66 | if item != 'modules': 67 | _sources(item, appendList) 68 | return list(set(appendList)) 69 | 70 | def getScraperFolder(scraper_source): 71 | sourceSubFolders = [x[1] for x in os.walk(os.path.dirname(__file__))][0] 72 | return [i for i in sourceSubFolders if scraper_source.lower() in i.lower()][0] 73 | 74 | def getModuleName(scraper_folders): 75 | nameList = [] 76 | for s in scraper_folders: 77 | try: nameList.append(s.split('_')[1].lower().title()) 78 | except: pass 79 | return nameList 80 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/cleandate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | LambdaScrapers Module 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | # Addon Name: LambdaScrapers Module 20 | # Addon id: script.module.lambdascrapers 21 | 22 | 23 | import time,datetime 24 | 25 | 26 | def iso_2_utc(iso_ts): 27 | if not iso_ts or iso_ts is None: return 0 28 | delim = -1 29 | if not iso_ts.endswith('Z'): 30 | delim = iso_ts.rfind('+') 31 | if delim == -1: delim = iso_ts.rfind('-') 32 | 33 | if delim > -1: 34 | ts = iso_ts[:delim] 35 | sign = iso_ts[delim] 36 | tz = iso_ts[delim + 1:] 37 | else: 38 | ts = iso_ts 39 | tz = None 40 | 41 | if ts.find('.') > -1: 42 | ts = ts[:ts.find('.')] 43 | 44 | try: d = datetime.datetime.strptime(ts, '%Y-%m-%dT%H:%M:%S') 45 | except TypeError: d = datetime.datetime(*(time.strptime(ts, '%Y-%m-%dT%H:%M:%S')[0:6])) 46 | 47 | dif = datetime.timedelta() 48 | if tz: 49 | hours, minutes = tz.split(':') 50 | hours = int(hours) 51 | minutes = int(minutes) 52 | if sign == '-': 53 | hours = -hours 54 | minutes = -minutes 55 | dif = datetime.timedelta(minutes=minutes, hours=hours) 56 | utc_dt = d - dif 57 | epoch = datetime.datetime.utcfromtimestamp(0) 58 | delta = utc_dt - epoch 59 | try: seconds = delta.total_seconds() # works only on 2.7 60 | except: seconds = delta.seconds + delta.days * 24 * 3600 # close enough 61 | return seconds 62 | 63 | 64 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/cleantitle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | LambdaScrapers Module 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | # Addon Name: LambdaScrapers Module 20 | # Addon id: script.module.lambdascrapers 21 | 22 | import re 23 | import unicodedata 24 | 25 | 26 | def get(title): 27 | if title is None: return 28 | try: 29 | title = title.encode('utf-8') 30 | except: 31 | pass 32 | title = str(title) 33 | title = re.sub('&#(\d);', '', title) 34 | title = re.sub('(&#[0-9]+)([^;^0-9]+)', '\\1;\\2', title) 35 | title = title.replace('"', '\"').replace('&', '&') 36 | title = re.sub('\n|([[].+?[]])|([(].+?[)])|\s(vs|v[.])\s|(:|;|-|"|,|\'|\_|\.|\?)|\s', '', title) 37 | return title.lower() 38 | 39 | def geturl(title): 40 | if title is None: return 41 | title = title.lower() 42 | title = title.translate(None, ':*?"\'\.<>|&!,') 43 | title = title.replace('/', '-') 44 | title = title.replace(' ', '-') 45 | title = title.replace('--', '-') 46 | return title 47 | 48 | 49 | def get_simple(title): 50 | if title is None: return 51 | title = title.lower() 52 | title = re.sub('(\d{4})', '', title) 53 | title = re.sub('&#(\d+);', '', title) 54 | title = re.sub('(&#[0-9]+)([^;^0-9]+)', '\\1;\\2', title) 55 | title = title.replace('"', '\"').replace('&', '&') 56 | title = re.sub('\n|\(|\)|\[|\]|\{|\}|\s(vs|v[.])\s|(:|;|-|–|"|,|\'|\_|\.|\?)|\s', '', title).lower() 57 | return title 58 | 59 | 60 | def getsearch(title): 61 | if title is None: return 62 | title = title.lower() 63 | title = re.sub('&#(\d+);', '', title) 64 | title = re.sub('(&#[0-9]+)([^;^0-9]+)', '\\1;\\2', title) 65 | title = title.replace('"', '\"').replace('&', '&') 66 | title = re.sub('\\\|/|-|–|:|;|\*|\?|"|\'|<|>|\|', '', title).lower() 67 | return title 68 | 69 | 70 | def query(title): 71 | if title is None: return 72 | title = title.replace('\'', '').rsplit(':', 1)[0].rsplit(' -', 1)[0].replace('-', ' ') 73 | return title 74 | 75 | 76 | def normalize(title): 77 | 78 | try: 79 | try: return title.decode('ascii').encode("utf-8") 80 | except: pass 81 | 82 | return str(''.join(c for c in unicodedata.normalize('NFKD', unicode(title.decode('utf-8'))) if unicodedata.category(c) != 'Mn')) 83 | except: 84 | return title 85 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/debrid.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | LambdaScrapers Module 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | # Addon Name: LambdaScrapers Module 20 | # Addon id: script.module.lambdascrapers 21 | 22 | from lambdascrapers.modules import log_utils 23 | 24 | try: 25 | import resolveurl 26 | 27 | debrid_resolvers = [resolver() for resolver in resolveurl.relevant_resolvers(order_matters=True) if resolver.isUniversal()] 28 | 29 | if len(debrid_resolvers) == 0: 30 | # Support Rapidgator accounts! Unfortunately, `sources.py` assumes that rapidgator.net is only ever 31 | # accessed via a debrid service, so we add rapidgator as a debrid resolver and everything just works. 32 | # As a bonus(?), rapidgator links will be highlighted just like actual debrid links 33 | debrid_resolvers = [resolver() for resolver in resolveurl.relevant_resolvers(order_matters=True,include_universal=False) if 'rapidgator.net' in resolver.domains] 34 | 35 | except: 36 | debrid_resolvers = [] 37 | 38 | 39 | def status(torrent=False): 40 | debrid_check = debrid_resolvers != [] 41 | if debrid_check is True: 42 | if torrent: 43 | enabled = control.setting('torrent.enabled') 44 | if enabled == '' or enabled.lower() == 'true': 45 | return True 46 | else: 47 | return False 48 | return debrid_check 49 | 50 | def resolver(url, debrid): 51 | try: 52 | debrid_resolver = [resolver for resolver in debrid_resolvers if resolver.name == debrid][0] 53 | 54 | debrid_resolver.login() 55 | _host, _media_id = debrid_resolver.get_host_and_id(url) 56 | stream_url = debrid_resolver.get_media_url(_host, _media_id) 57 | 58 | return stream_url 59 | except Exception as e: 60 | log_utils.log('%s Resolve Failure: %s' % (debrid, e), log_utils.LOGWARNING) 61 | return None 62 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/__init__.py: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright 2014, 2015 Piotr Dabkowski 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining 6 | # a copy of this software and associated documentation files (the 'Software'), 7 | # to deal in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | # the Software, and to permit persons to whom the Software is furnished to do so, subject 10 | # to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all copies or 13 | # substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 16 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 20 | 21 | """ This module allows you to translate and execute Javascript in pure python. 22 | Basically its implementation of ECMAScript 5.1 in pure python. 23 | 24 | Use eval_js method to execute javascript code and get resulting python object (builtin if possible). 25 | 26 | EXAMPLE: 27 | >>> import js2py 28 | >>> add = js2py.eval_js('function add(a, b) {return a + b}') 29 | >>> add(1, 2) + 3 30 | 6 31 | >>> add('1', 2, 3) 32 | u'12' 33 | >>> add.constructor 34 | function Function() { [python code] } 35 | 36 | 37 | Or use EvalJs to execute many javascript code fragments under same context - you would be able to get any 38 | variable from the context! 39 | 40 | >>> js = js2py.EvalJs() 41 | >>> js.execute('var a = 10; function f(x) {return x*x};') 42 | >>> js.f(9) 43 | 81 44 | >>> js.a 45 | 10 46 | 47 | Also you can use its console method to play with interactive javascript console. 48 | 49 | 50 | Use parse_js to parse (syntax tree is just like in esprima.js) and translate_js to trasnlate JavaScript. 51 | 52 | Finally, you can use pyimport statement from inside JS code to import and use python libraries. 53 | 54 | >>> js2py.eval_js('pyimport urllib; urllib.urlopen("https://www.google.com")') 55 | 56 | NOTE: This module is still not fully finished: 57 | 58 | Date and JSON builtin objects are not implemented 59 | Array prototype is not fully finished (will be soon) 60 | 61 | Other than that everything should work fine. 62 | 63 | """ 64 | 65 | __author__ = 'Piotr Dabkowski' 66 | __all__ = ['EvalJs', 'translate_js', 'import_js', 'eval_js', 'parse_js', 'translate_file', 'run_file'] 67 | from .evaljs import * 68 | from .translators import parse as parse_js 69 | 70 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Piotr Dabkowski' -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsarray.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | 3 | @Js 4 | def Array(): 5 | if len(arguments)==0 or len(arguments)>1: 6 | return arguments.to_list() 7 | a = arguments[0] 8 | if isinstance(a, PyJsNumber): 9 | length = a.to_uint32() 10 | if length!=a.value: 11 | raise MakeError('RangeError', 'Invalid array length') 12 | temp = Js([]) 13 | temp.put('length', a) 14 | return temp 15 | return [a] 16 | 17 | Array.create = Array 18 | Array.own['length']['value'] = Js(1) 19 | 20 | @Js 21 | def isArray(arg): 22 | return arg.Class=='Array' 23 | 24 | 25 | Array.define_own_property('isArray', {'value': isArray, 26 | 'enumerable': False, 27 | 'writable': True, 28 | 'configurable': True}) 29 | 30 | Array.define_own_property('prototype', {'value': ArrayPrototype, 31 | 'enumerable': False, 32 | 'writable': False, 33 | 'configurable': False}) 34 | 35 | ArrayPrototype.define_own_property('constructor', {'value': Array, 36 | 'enumerable': False, 37 | 'writable': True, 38 | 'configurable': True}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsboolean.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | 3 | BooleanPrototype.define_own_property('constructor', {'value': Boolean, 4 | 'enumerable': False, 5 | 'writable': True, 6 | 'configurable': True}) 7 | 8 | Boolean.define_own_property('prototype', {'value': BooleanPrototype, 9 | 'enumerable': False, 10 | 'writable': False, 11 | 'configurable': False}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsfunction.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | try: 3 | from ..translators.translator import translate_js 4 | except: 5 | pass 6 | 7 | 8 | @Js 9 | def Function(): 10 | # convert arguments to python list of strings 11 | a = [e.to_string().value for e in arguments.to_list()] 12 | body = ';' 13 | args = () 14 | if len(a): 15 | body = '%s;' % a[-1] 16 | args = a[:-1] 17 | # translate this function to js inline function 18 | js_func = '(function (%s) {%s})' % (','.join(args), body) 19 | # now translate js inline to python function 20 | py_func = translate_js(js_func, '') 21 | # add set func scope to global scope 22 | # a but messy solution but works :) 23 | globals()['var'] = PyJs.GlobalObject 24 | # define py function and return it 25 | temp = executor(py_func, globals()) 26 | temp.source = '{%s}'%body 27 | temp.func_name = 'anonymous' 28 | return temp 29 | 30 | def executor(f, glob): 31 | exec(f, globals()) 32 | return globals()['PyJs_anonymous_0_'] 33 | 34 | 35 | #new statement simply calls Function 36 | Function.create = Function 37 | 38 | #set constructor property inside FunctionPrototype 39 | 40 | fill_in_props(FunctionPrototype, {'constructor':Function}, default_attrs) 41 | 42 | #attach prototype to Function constructor 43 | Function.define_own_property('prototype', {'value': FunctionPrototype, 44 | 'enumerable': False, 45 | 'writable': False, 46 | 'configurable': False}) 47 | #Fix Function length (its 0 and should be 1) 48 | Function.own['length']['value'] = Js(1) 49 | 50 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsmath.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | import math 3 | import random 4 | 5 | Math = PyJsObject(prototype=ObjectPrototype) 6 | Math.Class = 'Math' 7 | 8 | CONSTANTS = {'E': 2.7182818284590452354, 9 | 'LN10': 2.302585092994046, 10 | 'LN2': 0.6931471805599453, 11 | 'LOG2E': 1.4426950408889634, 12 | 'LOG10E': 0.4342944819032518, 13 | 'PI': 3.1415926535897932, 14 | 'SQRT1_2': 0.7071067811865476, 15 | 'SQRT2': 1.4142135623730951} 16 | 17 | for constant, value in CONSTANTS.items(): 18 | Math.define_own_property(constant, {'value': Js(value), 19 | 'writable': False, 20 | 'enumerable': False, 21 | 'configurable': False}) 22 | 23 | class MathFunctions: 24 | def abs(x): 25 | a = x.to_number().value 26 | if a!=a: # it must be a nan 27 | return NaN 28 | return abs(a) 29 | 30 | def acos(x): 31 | a = x.to_number().value 32 | if a!=a: # it must be a nan 33 | return NaN 34 | try: 35 | return math.acos(a) 36 | except: 37 | return NaN 38 | 39 | def asin(x): 40 | a = x.to_number().value 41 | if a!=a: # it must be a nan 42 | return NaN 43 | try: 44 | return math.asin(a) 45 | except: 46 | return NaN 47 | 48 | def atan(x): 49 | a = x.to_number().value 50 | if a!=a: # it must be a nan 51 | return NaN 52 | return math.atan(a) 53 | 54 | def atan2(y, x): 55 | a = x.to_number().value 56 | b = y.to_number().value 57 | if a!=a or b!=b: # it must be a nan 58 | return NaN 59 | return math.atan2(b, a) 60 | 61 | def ceil(x): 62 | a = x.to_number().value 63 | if a!=a: # it must be a nan 64 | return NaN 65 | return math.ceil(a) 66 | 67 | def floor(x): 68 | a = x.to_number().value 69 | if a!=a: # it must be a nan 70 | return NaN 71 | return math.floor(a) 72 | 73 | def round(x): 74 | a = x.to_number().value 75 | if a!=a: # it must be a nan 76 | return NaN 77 | return round(a) 78 | 79 | def sin(x): 80 | a = x.to_number().value 81 | if a!=a: # it must be a nan 82 | return NaN 83 | return math.sin(a) 84 | 85 | def cos(x): 86 | a = x.to_number().value 87 | if a!=a: # it must be a nan 88 | return NaN 89 | return math.cos(a) 90 | 91 | def tan(x): 92 | a = x.to_number().value 93 | if a!=a: # it must be a nan 94 | return NaN 95 | return math.tan(a) 96 | 97 | def log(x): 98 | a = x.to_number().value 99 | if a!=a: # it must be a nan 100 | return NaN 101 | try: 102 | return math.log(a) 103 | except: 104 | return NaN 105 | 106 | def exp(x): 107 | a = x.to_number().value 108 | if a!=a: # it must be a nan 109 | return NaN 110 | return math.exp(a) 111 | 112 | def pow(x, y): 113 | a = x.to_number().value 114 | b = y.to_number().value 115 | if a!=a or b!=b: # it must be a nan 116 | return NaN 117 | try: 118 | return a**b 119 | except: 120 | return NaN 121 | 122 | def sqrt(x): 123 | a = x.to_number().value 124 | if a!=a: # it must be a nan 125 | return NaN 126 | try: 127 | return a**0.5 128 | except: 129 | return NaN 130 | 131 | def min(): 132 | if not len(arguments): 133 | return -Infinity 134 | lis = tuple(e.to_number().value for e in arguments.to_list()) 135 | if any(e!=e for e in lis): # we dont want NaNs 136 | return NaN 137 | return min(*lis) 138 | 139 | def max(): 140 | if not len(arguments): 141 | return -Infinity 142 | lis = tuple(e.to_number().value for e in arguments.to_list()) 143 | if any(e!=e for e in lis): # we dont want NaNs 144 | return NaN 145 | return max(*lis) 146 | 147 | def random(): 148 | return random.random() 149 | 150 | 151 | fill_prototype(Math, MathFunctions, default_attrs) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsnumber.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | 3 | 4 | CONSTS = {'prototype': NumberPrototype, 5 | 'MAX_VALUE':1.7976931348623157e308, 6 | 'MIN_VALUE': 5.0e-324, 7 | 'NaN': NaN, 8 | 'NEGATIVE_INFINITY': float('-inf'), 9 | 'POSITIVE_INFINITY': float('inf')} 10 | 11 | fill_in_props(Number, CONSTS, {'enumerable': False, 12 | 'writable': False, 13 | 'configurable': False}) 14 | 15 | NumberPrototype.define_own_property('constructor', {'value': Number, 16 | 'enumerable': False, 17 | 'writable': True, 18 | 'configurable': True}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsregexp.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | 3 | RegExpPrototype.define_own_property('constructor', {'value': RegExp, 4 | 'enumerable': False, 5 | 'writable': True, 6 | 'configurable': True}) 7 | 8 | RegExp.define_own_property('prototype', {'value': RegExpPrototype, 9 | 'enumerable': False, 10 | 'writable': False, 11 | 'configurable': False}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/constructors/jsstring.py: -------------------------------------------------------------------------------- 1 | from ..base import * 2 | # python 3 support 3 | import six 4 | if six.PY3: 5 | unichr = chr 6 | 7 | @Js 8 | def fromCharCode(): 9 | args = arguments.to_list() 10 | res = u'' 11 | for e in args: 12 | res +=unichr(e.to_uint16()) 13 | return this.Js(res) 14 | 15 | fromCharCode.own['length']['value'] = Js(1) 16 | 17 | String.define_own_property('fromCharCode', {'value': fromCharCode, 18 | 'enumerable': False, 19 | 'writable': True, 20 | 'configurable': True}) 21 | 22 | String.define_own_property('prototype', {'value': StringPrototype, 23 | 'enumerable': False, 24 | 'writable': False, 25 | 'configurable': False}) 26 | 27 | StringPrototype.define_own_property('constructor', {'value': String, 28 | 'enumerable': False, 29 | 'writable': True, 30 | 'configurable': True}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/host/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-A-C/script.module.lambdascrapers/74de3e5fa79f815031805fa7813efb68a087bd05/lib/lambdascrapers/modules/js2py/host/__init__.py -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/host/console.py: -------------------------------------------------------------------------------- 1 | from js2py.base import * 2 | 3 | @Js 4 | def console(): 5 | pass 6 | 7 | @Js 8 | def log(): 9 | print(arguments[0]) 10 | 11 | console.put('log', log) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/host/dom/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-A-C/script.module.lambdascrapers/74de3e5fa79f815031805fa7813efb68a087bd05/lib/lambdascrapers/modules/js2py/host/dom/__init__.py -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/host/dom/constants.py: -------------------------------------------------------------------------------- 1 | from js2py.base import * 2 | 3 | def _get_conts(idl): 4 | def is_valid(c): 5 | try: 6 | exec(c) 7 | return 1 8 | except: 9 | pass 10 | return '\n'.join(filter(is_valid, (' '.join(e.strip(' ;').split()[-3:]) for e in idl.splitlines()))) 11 | 12 | 13 | default_attrs = {'writable':True, 'enumerable':True, 'configurable':True} 14 | 15 | 16 | def compose_prototype(Class, attrs=default_attrs): 17 | prototype = Class() 18 | for i in dir(Class): 19 | e = getattr(Class, i) 20 | if hasattr(e, '__func__'): 21 | temp = PyJsFunction(e.__func__, FunctionPrototype) 22 | attrs = {k:v for k,v in attrs.iteritems()} 23 | attrs['value'] = temp 24 | prototype.define_own_property(i, attrs) 25 | return prototype 26 | 27 | 28 | # Error codes 29 | 30 | INDEX_SIZE_ERR = 1 31 | DOMSTRING_SIZE_ERR = 2 32 | HIERARCHY_REQUEST_ERR = 3 33 | WRONG_DOCUMENT_ERR = 4 34 | INVALID_CHARACTER_ERR = 5 35 | NO_DATA_ALLOWED_ERR = 6 36 | NO_MODIFICATION_ALLOWED_ERR = 7 37 | NOT_FOUND_ERR = 8 38 | NOT_SUPPORTED_ERR = 9 39 | INUSE_ATTRIBUTE_ERR = 10 40 | INVALID_STATE_ERR = 11 41 | SYNTAX_ERR = 12 42 | INVALID_MODIFICATION_ERR = 13 43 | NAMESPACE_ERR = 14 44 | INVALID_ACCESS_ERR = 15 45 | VALIDATION_ERR = 16 46 | TYPE_MISMATCH_ERR = 17 47 | 48 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/host/dom/interface.py: -------------------------------------------------------------------------------- 1 | from StringIO import StringIO 2 | from constants import * 3 | from bs4 import BeautifulSoup 4 | from js2py.base import * 5 | try: 6 | import lxml 7 | def parse(source): 8 | return BeautifulSoup(source, 'lxml') 9 | except: 10 | def parse(source): 11 | return BeautifulSoup(source) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | x = ''' 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
Shady GroveAeolian
Over the River, CharlieDorian
''' 31 | 32 | 33 | 34 | class DOM(PyJs): 35 | prototype = ObjectPrototype 36 | def __init__(self): 37 | self.own = {} 38 | 39 | def readonly(self, name, val): 40 | self.define_own_property(name, {'writable':False, 'enumerable':False, 'configurable':False, 'value': Js(val)}) 41 | 42 | 43 | 44 | # DOMStringList 45 | 46 | class DOMStringListPrototype(DOM): 47 | Class = 'DOMStringListPrototype' 48 | 49 | def contains(element): 50 | return element.to_string().value in this._string_list 51 | 52 | def item(index): 53 | return this._string_list[index.to_int()] if 0<=index.to_int()36: 21 | return NaN 22 | if r!=16: 23 | strip_prefix = False 24 | else: 25 | r = 10 26 | if strip_prefix: 27 | if len(string)>=2 and string[:2] in ['0x', '0X']: 28 | string = string[2:] 29 | r = 16 30 | n = 0 31 | num = 0 32 | while n4: # cant be a number anymore 62 | break 63 | length += 1 64 | if num is None: 65 | return NaN 66 | return sign*float(string[:max_len]) 67 | 68 | @Js 69 | def isNaN(number): 70 | if number.to_number().is_nan(): 71 | return true 72 | return false 73 | 74 | @Js 75 | def isFinite(number): 76 | num = number.to_number() 77 | if num.is_nan() or num.is_infinity(): 78 | return false 79 | return true 80 | 81 | 82 | #todo URI handling! 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/legecy_translators/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Piotrek' 2 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/legecy_translators/exps.py: -------------------------------------------------------------------------------- 1 | """ 2 | exp_translate routine: 3 | It takes a single line of JS code and returns a SINGLE line of Python code. 4 | Note var is not present here because it was removed in previous stages. Also remove this useless void keyword 5 | If case of parsing errors it must return a pos of error. 6 | 1. Convert all assignment operations to put operations, this may be hard :( DONE, wasn't that bad 7 | 2. Convert all gets and calls to get and callprop. 8 | 3. Convert unary operators like typeof, new, !, delete, ++, -- 9 | Delete can be handled by replacing last get method with delete. 10 | 4. Convert remaining operators that are not handled by python: 11 | &&, || <= these should be easy simply replace && by and and || by or 12 | === and !== 13 | comma operator , in, instanceof and finally :? 14 | 15 | 16 | NOTES: 17 | Strings and other literals are not present so each = means assignment 18 | """ 19 | from utils import * 20 | from jsparser import * 21 | 22 | def exps_translator(js): 23 | #Check () {} and [] nums 24 | ass = assignment_translator(js) 25 | 26 | 27 | # Step 1 28 | def assignment_translator(js): 29 | sep = js.split(',') 30 | res = sep[:] 31 | for i, e in enumerate(sep): 32 | if '=' not in e: # no need to convert 33 | continue 34 | res[i] = bass_translator(e) 35 | return ','.join(res) 36 | 37 | 38 | def bass_translator(s): 39 | # I hope that I will not have to fix any bugs here because it will be terrible 40 | if '(' in s or '[' in s: 41 | converted = '' 42 | for e in bracket_split(s, ['()','[]'], strip=False): 43 | if e[0]=='(': 44 | converted += '(' + bass_translator(e[1:-1])+')' 45 | elif e[0]=='[': 46 | converted += '[' + bass_translator(e[1:-1])+']' 47 | else: 48 | converted += e 49 | s = converted 50 | if '=' not in s: 51 | return s 52 | ass = reversed(s.split('=')) 53 | last = ass.next() 54 | res = last 55 | for e in ass: 56 | op = '' 57 | if e[-1] in OP_METHODS: #increment assign like += 58 | op = ', "'+e[-1]+'"' 59 | e = e[:-1] 60 | cand = e.strip('() ') # (a) = 40 is valid so we need to transform '(a) ' to 'a' 61 | if not is_property_accessor(cand): # it is not a property assignment 62 | if not is_lval(cand) or is_internal(cand): 63 | raise SyntaxError('Invalid left-hand side in assignment') 64 | res = 'var.put(%s, %s%s)'%(cand.__repr__(), res, op) 65 | elif cand[-1]==']': # property assignment via [] 66 | c = list(bracket_split(cand, ['[]'], strip=False)) 67 | meth, prop = ''.join(c[:-1]).strip(), c[-1][1:-1].strip() #this does not have to be a string so dont remove 68 | #() because it can be a call 69 | res = '%s.put(%s, %s%s)'%(meth, prop, res, op) 70 | else: # Prop set via '.' 71 | c = cand.rfind('.') 72 | meth, prop = cand[:c].strip(), cand[c+1:].strip('() ') 73 | if not is_lval(prop): 74 | raise SyntaxError('Invalid left-hand side in assignment') 75 | res = '%s.put(%s, %s%s)'%(meth, prop.__repr__(), res, op) 76 | return res 77 | 78 | if __name__=='__main__': 79 | print bass_translator('3.ddsd = 40') -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/legecy_translators/functions.py: -------------------------------------------------------------------------------- 1 | """This module removes JS functions from source code""" 2 | from jsparser import * 3 | from utils import * 4 | 5 | 6 | INLINE_NAME = 'PyJsLvalInline%d_' 7 | INLINE_COUNT = 0 8 | PRE_EXP_STARTS = {'return', 'new', 'void', 'throw', 'typeof', 'in', 'instanceof'} 9 | PRE_ALLOWED = IDENTIFIER_PART.union({';', '{', '}', ']', ')', ':'}) 10 | INCREMENTS = {'++', '--'} 11 | 12 | def reset_inline_count(): 13 | global INLINE_COUNT 14 | INLINE_COUNT = 0 15 | 16 | def remove_functions(source, all_inline=False): 17 | """removes functions and returns new source, and 2 dicts. 18 | first dict with removed hoisted(global) functions and second with replaced inline functions""" 19 | global INLINE_COUNT 20 | inline = {} 21 | hoisted = {} 22 | n = 0 23 | limit = len(source) - 9 # 8 is length of 'function' 24 | res = '' 25 | last = 0 26 | while n < limit: 27 | if n and source[n-1] in IDENTIFIER_PART: 28 | n+=1 29 | continue 30 | if source[n:n+8] == 'function' and source[n+8] not in IDENTIFIER_PART: 31 | if source[:n].rstrip().endswith('.'): # allow function as a property name :) 32 | n+=1 33 | continue 34 | if source[n+8:].lstrip().startswith(':'): # allow functions inside objects... 35 | n+=1 36 | continue 37 | entered = n 38 | res += source[last:n] 39 | name = '' 40 | n = pass_white(source, n+8) 41 | if source[n] in IDENTIFIER_START: # hoisted function 42 | name, n= parse_identifier(source, n) 43 | args, n = pass_bracket(source, n, '()') 44 | if not args: 45 | raise SyntaxError('Function misses bracket with argnames ()') 46 | args = args.strip('() \n') 47 | args = tuple(parse_identifier(e, 0)[0] for e in argsplit(args)) if args else () 48 | if len(args) - len(set(args)): 49 | # I know its legal in JS but python does not allow duplicate argnames 50 | # I will not work around it 51 | raise SyntaxError('Function has duplicate argument names. Its not legal in this implementation. Sorry.') 52 | block, n = pass_bracket(source, n, '{}') 53 | if not block: 54 | raise SyntaxError('Function does not have any code block to execute') 55 | mixed = False # named function expression flag 56 | if name and not all_inline: 57 | # Here I will distinguish between named function expression (mixed) and a function statement 58 | before = source[:entered].rstrip() 59 | if any(endswith_keyword(before, e) for e in PRE_EXP_STARTS): 60 | #print 'Ended ith keyword' 61 | mixed = True 62 | elif before and before[-1] not in PRE_ALLOWED and not before[-2:] in INCREMENTS: 63 | #print 'Ended with'+repr(before[-1]), before[-1]=='}' 64 | mixed = True 65 | else: 66 | #print 'FUNCTION STATEMENT' 67 | #its a function statement. 68 | # todo remove fucking label if present! 69 | hoisted[name] = block, args 70 | if not name or mixed or all_inline: # its a function expression (can be both named and not named) 71 | #print 'FUNCTION EXPRESSION' 72 | INLINE_COUNT += 1 73 | iname = INLINE_NAME%INLINE_COUNT # inline name 74 | res += ' '+ iname 75 | inline['%s@%s' %(iname, name)] = block, args #here added real name at the end because it has to be added to the func scope 76 | last = n 77 | else: 78 | n+=1 79 | res += source[last:] 80 | return res, hoisted, inline 81 | 82 | 83 | if __name__=='__main__': 84 | print remove_functions('5+5 function n (functiona ,functionaj) {dsd s, dsdd}') -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/legecy_translators/tokenize.py: -------------------------------------------------------------------------------- 1 | from jsparser import * 2 | from utils import * 3 | # maybe I will try rewriting my parser in the future... Tokenizer makes things much easier and faster, unfortunately I 4 | # did not know anything about parsers when I was starting this project so I invented my own. 5 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/legecy_translators/utils.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unicodedata 3 | from collections import defaultdict 4 | 5 | def is_lval(t): 6 | """Does not chceck whether t is not resticted or internal""" 7 | if not t: 8 | return False 9 | i = iter(t) 10 | if i.next() not in IDENTIFIER_START: 11 | return False 12 | return all(e in IDENTIFIER_PART for e in i) 13 | 14 | def is_valid_lval(t): 15 | """Checks whether t is valid JS identifier name (no keyword like var, function, if etc) 16 | Also returns false on internal""" 17 | if not is_internal(t) and is_lval(t) and t not in RESERVED_NAMES: 18 | return True 19 | return False 20 | 21 | 22 | def is_plval(t): 23 | return t.startswith('PyJsLval') 24 | 25 | def is_marker(t): 26 | return t.startswith('PyJsMarker') or t.startswith('PyJsConstant') 27 | 28 | def is_internal(t): 29 | return is_plval(t) or is_marker(t) or t=='var' # var is a scope var 30 | 31 | def is_property_accessor(t): 32 | return '[' in t or '.' in t 33 | 34 | def is_reserved(t): 35 | return t in RESERVED_NAMES 36 | 37 | 38 | 39 | 40 | #http://stackoverflow.com/questions/14245893/efficiently-list-all-characters-in-a-given-unicode-category 41 | BOM = u'\uFEFF' 42 | ZWJ = u'\u200D' 43 | ZWNJ = u'\u200C' 44 | TAB = u'\u0009' 45 | VT = u'\u000B' 46 | FF = u'\u000C' 47 | SP = u'\u0020' 48 | NBSP = u'\u00A0' 49 | LF = u'\u000A' 50 | CR = u'\u000D' 51 | LS = u'\u2028' 52 | PS = u'\u2029' 53 | 54 | U_CATEGORIES = defaultdict(list) # Thank you Martijn Pieters! 55 | for c in map(unichr, range(sys.maxunicode + 1)): 56 | U_CATEGORIES[unicodedata.category(c)].append(c) 57 | 58 | UNICODE_LETTER = set(U_CATEGORIES['Lu']+U_CATEGORIES['Ll']+ 59 | U_CATEGORIES['Lt']+U_CATEGORIES['Lm']+ 60 | U_CATEGORIES['Lo']+U_CATEGORIES['Nl']) 61 | UNICODE_COMBINING_MARK = set(U_CATEGORIES['Mn']+U_CATEGORIES['Mc']) 62 | UNICODE_DIGIT = set(U_CATEGORIES['Nd']) 63 | UNICODE_CONNECTOR_PUNCTUATION = set(U_CATEGORIES['Pc']) 64 | IDENTIFIER_START = UNICODE_LETTER.union({'$','_'}) # and some fucking unicode escape sequence 65 | IDENTIFIER_PART = IDENTIFIER_START.union(UNICODE_COMBINING_MARK).union(UNICODE_DIGIT).union(UNICODE_CONNECTOR_PUNCTUATION).union({ZWJ, ZWNJ}) 66 | USP = U_CATEGORIES['Zs'] 67 | KEYWORD = {'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 68 | 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 69 | 'switch', 'while', 'debugger', 'function', 'this', 'with', 'default', 70 | 'if', 'throw', 'delete', 'in', 'try'} 71 | 72 | FUTURE_RESERVED_WORD = {'class', 'enum', 'extends', 'super', 'const', 'export', 'import'} 73 | RESERVED_NAMES = KEYWORD.union(FUTURE_RESERVED_WORD).union({'null', 'false', 'true'}) 74 | 75 | WHITE = {TAB, VT, FF, SP, NBSP, BOM}.union(USP) 76 | LINE_TERMINATOR = {LF, CR, LS, PS} 77 | LLINE_TERMINATOR = list(LINE_TERMINATOR) 78 | x = ''.join(WHITE)+''.join(LINE_TERMINATOR) 79 | SPACE = WHITE.union(LINE_TERMINATOR) 80 | LINE_TERMINATOR_SEQUENCE = LINE_TERMINATOR.union({CR+LF}) -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Piotr Dabkowski' 2 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jsboolean.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class BooleanPrototype: 4 | def toString(): 5 | if this.Class!='Boolean': 6 | raise this.Js(TypeError)('this must be a boolean') 7 | return 'true' if this.value else 'false' 8 | 9 | def valueOf(): 10 | if this.Class!='Boolean': 11 | raise this.Js(TypeError)('this must be a boolean') 12 | return this.value 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jserror.py: -------------------------------------------------------------------------------- 1 | 2 | class ErrorPrototype: 3 | def toString(): 4 | if this.TYPE!='Object': 5 | raise this.MakeError('TypeError', 'Error.prototype.toString called on non-object') 6 | name = this.get('name') 7 | name = 'Error' if name.is_undefined() else name.to_string().value 8 | msg = this.get('message') 9 | msg = '' if msg.is_undefined() else msg.to_string().value 10 | return name + (name and msg and ': ') + msg -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jsfunction.py: -------------------------------------------------------------------------------- 1 | # python 3 support 2 | import six 3 | if six.PY3: 4 | basestring = str 5 | long = int 6 | xrange = range 7 | unicode = str 8 | 9 | 10 | # todo fix apply and bind 11 | 12 | class FunctionPrototype: 13 | def toString(): 14 | if not this.is_callable(): 15 | raise TypeError('toString is not generic!') 16 | args = ', '.join(this.code.__code__.co_varnames[:this.argcount]) 17 | return 'function %s(%s) '%(this.func_name, args)+this.source 18 | 19 | def call(): 20 | arguments_ = arguments 21 | if not len(arguments): 22 | obj = this.Js(None) 23 | else: 24 | obj = arguments[0] 25 | if len(arguments)<=1: 26 | args = () 27 | else: 28 | args = tuple([arguments_[e] for e in xrange(1, len(arguments_))]) 29 | return this.call(obj, args) 30 | 31 | def apply(): 32 | if not len(arguments): 33 | obj = this.Js(None) 34 | else: 35 | obj = arguments[0] 36 | if len(arguments)<=1: 37 | args = () 38 | else: 39 | appl = arguments[1] 40 | args = tuple([appl[e] for e in xrange(len(appl))]) 41 | return this.call(obj, args) 42 | 43 | def bind(thisArg): 44 | target = this 45 | if not target.is_callable(): 46 | raise this.MakeError('Object must be callable in order to be used with bind method') 47 | if len(arguments) <= 1: 48 | args = () 49 | else: 50 | args = tuple([arguments[e] for e in xrange(1, len(arguments))]) 51 | return this.PyJsBoundFunction(target, thisArg, args) 52 | 53 | 54 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jsnumber.py: -------------------------------------------------------------------------------- 1 | import six 2 | if six.PY3: 3 | basestring = str 4 | long = int 5 | xrange = range 6 | unicode = str 7 | 8 | 9 | RADIX_SYMBOLS = {0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10 | 10: 'a', 11: 'b', 12: 'c', 13: 'd', 14: 'e', 15: 'f', 16: 'g', 17: 'h', 18: 'i', 19: 'j', 20: 'k', 11 | 21: 'l', 22: 'm', 23: 'n', 24: 'o', 25: 'p', 26: 'q', 27: 'r', 28: 's', 29: 't', 30: 'u', 31: 'v', 12 | 32: 'w', 33: 'x', 34: 'y', 35: 'z'} 13 | 14 | 15 | def to_str_rep(num): 16 | if num.is_nan(): 17 | return num.Js('NaN') 18 | elif num.is_infinity(): 19 | sign = '-' if num.value<0 else '' 20 | return num.Js(sign+'Infinity') 21 | elif isinstance(num.value, (long, int)) or num.value.is_integer(): # dont print .0 22 | return num.Js(unicode(int(num.value))) 23 | return num.Js(unicode(num.value)) # accurate enough 24 | 25 | 26 | class NumberPrototype: 27 | def toString(radix): 28 | if this.Class!='Number': 29 | raise this.MakeError('TypeError', 'Number.prototype.valueOf is not generic') 30 | if radix.is_undefined(): 31 | return to_str_rep(this) 32 | r = radix.to_int() 33 | if r==10: 34 | return to_str_rep(this) 35 | if r not in xrange(2, 37): 36 | raise this.MakeError('RangeError', 'Number.prototype.toString() radix argument must be between 2 and 36') 37 | num = this.to_int() 38 | if num < 0: 39 | num = -num 40 | sign = '-' 41 | else: 42 | sign = '' 43 | res = '' 44 | while num: 45 | s = RADIX_SYMBOLS[num % r] 46 | num = num // r 47 | res = s + res 48 | return sign + (res if res else '0') 49 | 50 | def valueOf(): 51 | if this.Class!='Number': 52 | raise this.MakeError('TypeError', 'Number.prototype.valueOf is not generic') 53 | return this.value 54 | 55 | def toLocaleString(): 56 | return this.to_string() 57 | 58 | def toFixed (fractionDigits): 59 | if this.Class!='Number': 60 | raise this.MakeError('TypeError', 'Number.prototype.toFixed called on incompatible receiver') 61 | digs = fractionDigits.to_int() 62 | if digs<0 or digs>20: 63 | raise this.MakeError('RangeError', 'toFixed() digits argument must be between 0 and 20') 64 | elif this.is_infinity(): 65 | return 'Infinity' if this.value>0 else '-Infinity' 66 | elif this.is_nan(): 67 | return 'NaN' 68 | return format(this.value, '-.%df'%digs) 69 | 70 | 71 | def toExponential (fractionDigits): 72 | if this.Class!='Number': 73 | raise this.MakeError('TypeError', 'Number.prototype.toExponential called on incompatible receiver') 74 | digs = fractionDigits.to_int() 75 | if digs<0 or digs>20: 76 | raise this.MakeError('RangeError', 'toFixed() digits argument must be between 0 and 20') 77 | elif this.is_infinity(): 78 | return 'Infinity' if this.value>0 else '-Infinity' 79 | elif this.is_nan(): 80 | return 'NaN' 81 | return format(this.value, '-.%de'%digs) 82 | 83 | def toPrecision (precision): 84 | if this.Class!='Number': 85 | raise this.MakeError('TypeError', 'Number.prototype.toPrecision called on incompatible receiver') 86 | if precision.is_undefined(): 87 | return this.to_String() 88 | prec = precision.to_int() 89 | if this.is_nan(): 90 | return 'NaN' 91 | elif this.is_infinity(): 92 | return 'Infinity' if this.value>0 else '-Infinity' 93 | digs = prec - len(str(int(this.value))) 94 | if digs>=0: 95 | return format(this.value, '-.%df'%digs) 96 | else: 97 | return format(this.value, '-.%df'%(prec-1)) 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jsobject.py: -------------------------------------------------------------------------------- 1 | 2 | class ObjectPrototype: 3 | def toString(): 4 | return '[object %s]'%this.Class 5 | 6 | def valueOf(): 7 | return this.to_object() 8 | 9 | 10 | def toLocaleString(): 11 | return this.callprop('toString') 12 | 13 | def hasOwnProperty(prop): 14 | return this.get_own_property(prop.to_string().value) is not None 15 | 16 | def isPrototypeOf(obj): 17 | #a bit stupid specification but well 18 | # for example Object.prototype.isPrototypeOf.call((5).__proto__, 5) gives false 19 | if not obj.is_object(): 20 | return False 21 | while 1: 22 | obj = obj.prototype 23 | if obj is None or obj.is_null(): 24 | return False 25 | if obj is this: 26 | return True 27 | 28 | def propertyIsEnumerable(prop): 29 | cand = this.own.get(prop.to_string().value) 30 | return cand is not None and cand.get('enumerable') 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/prototypes/jsregexp.py: -------------------------------------------------------------------------------- 1 | 2 | class RegExpPrototype: 3 | def toString(): 4 | flags = u'' 5 | if this.glob: 6 | flags += u'g' 7 | if this.ignore_case: 8 | flags += u'i' 9 | if this.multiline: 10 | flags += u'm' 11 | v = this.value if this.value else '(?:)' 12 | return u'/%s/'%v + flags 13 | 14 | def test(string): 15 | return Exec(this, string) is not this.null 16 | 17 | def exec2(string): # will be changed to exec in base.py. cant name it exec here 18 | return Exec(this, string) 19 | 20 | 21 | 22 | 23 | def Exec(this, string): 24 | if this.Class!='RegExp': 25 | raise this.MakeError('TypeError', 'RegExp.prototype.exec is not generic!') 26 | string = string.to_string() 27 | length = len(string) 28 | i = this.get('lastIndex').to_int() if this.glob else 0 29 | matched = False 30 | while not matched: 31 | if i < 0 or i > length: 32 | this.put('lastIndex', this.Js(0)) 33 | return this.null 34 | matched = this.match(string.value, i) 35 | i += 1 36 | start, end = matched.span()#[0]+i-1, matched.span()[1]+i-1 37 | if this.glob: 38 | this.put('lastIndex', this.Js(end)) 39 | arr = this.Js([this.Js(e) for e in [matched.group()]+list(matched.groups())]) 40 | arr.put('index', this.Js(start)) 41 | arr.put('input', string) 42 | return arr 43 | 44 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/pyjs.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | from .constructors.jsmath import Math 3 | from .constructors.jsdate import Date 4 | from .constructors.jsobject import Object 5 | from .constructors.jsfunction import Function 6 | from .constructors.jsstring import String 7 | from .constructors.jsnumber import Number 8 | from .constructors.jsboolean import Boolean 9 | from .constructors.jsregexp import RegExp 10 | from .constructors.jsarray import Array 11 | from .prototypes.jsjson import JSON 12 | from .host.console import console 13 | from .host.jseval import Eval 14 | from .host.jsfunctions import parseFloat, parseInt, isFinite, isNaN 15 | 16 | # Now we have all the necessary items to create global environment for script 17 | __all__ = ['Js', 'PyJsComma', 'PyJsStrictEq', 'PyJsStrictNeq', 18 | 'PyJsException', 'PyJsBshift', 'Scope', 'PyExceptionToJs', 19 | 'JsToPyException', 'JS_BUILTINS', 'appengine', 'set_global_object', 20 | 'JsRegExp', 'PyJsException', 'PyExceptionToJs', 'JsToPyException', 'PyJsSwitchException'] 21 | 22 | 23 | # these were defined in base.py 24 | builtins = ('true','false','null','undefined','Infinity', 25 | 'NaN', 'console', 'String', 'Number', 'Boolean', 'RegExp', 26 | 'Math', 'Date', 'Object', 'Function', 'Array', 27 | 'parseFloat', 'parseInt', 'isFinite', 'isNaN') 28 | #Array, Function, JSON, Error is done later :) 29 | # also some built in functions like eval... 30 | 31 | def set_global_object(obj): 32 | obj.IS_CHILD_SCOPE = False 33 | this = This({}) 34 | this.own = obj.own 35 | this.prototype = obj.prototype 36 | PyJs.GlobalObject = this 37 | # make this available 38 | obj.register('this') 39 | obj.put('this', this) 40 | 41 | 42 | 43 | scope = dict(zip(builtins, [globals()[e] for e in builtins])) 44 | # Now add errors: 45 | for name, error in ERRORS.items(): 46 | scope[name] = error 47 | #add eval 48 | scope['eval'] = Eval 49 | scope['JSON'] = JSON 50 | JS_BUILTINS = {} 51 | for k,v in scope.iteritems(): 52 | JS_BUILTINS[k]=v 53 | 54 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/todo: -------------------------------------------------------------------------------- 1 | # TODO 2 | Check Object Constructor 3 | Complete list prototype 4 | Fix function bind... 5 | Fix regexp compile ??? 6 | Check prototypes: 7 | String: replace, split 8 | fix recursion error in special case in to_dict and to_list 9 | 10 | Array constructor 11 | 12 | 13 | escape, URL... etc 14 | 15 | Check primitive.to_object() 16 | var obj = new Number(0); var x = new Array(obj); x 17 | 18 | Smarter import... 19 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/translators/__init__.py: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright 2014, 2015 Piotr Dabkowski 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining 6 | # a copy of this software and associated documentation files (the 'Software'), 7 | # to deal in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | # the Software, and to permit persons to whom the Software is furnished to do so, subject 10 | # to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all copies or 13 | # substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 16 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 20 | 21 | __all__ = ['PyJsParser', 'Node', 'WrappingNode', 'node_to_dict', 'parse', 'translate_js', 'translate', 'syntax_tree_translate', 22 | 'DEFAULT_HEADER'] 23 | __author__ = 'Piotr Dabkowski' 24 | __version__ = '2.2.0' 25 | from .pyjsparser import PyJsParser, Node, WrappingNode, node_to_dict 26 | from .translator import translate_js, trasnlate, syntax_tree_translate, DEFAULT_HEADER 27 | 28 | 29 | def parse(javascript_code): 30 | """Returns syntax tree of javascript_code. 31 | 32 | Syntax tree has the same structure as syntax tree produced by esprima.js 33 | 34 | Same as PyJsParser().parse For your convenience :) """ 35 | p = PyJsParser() 36 | return p.parse(javascript_code) 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-A-C/script.module.lambdascrapers/74de3e5fa79f815031805fa7813efb68a087bd05/lib/lambdascrapers/modules/js2py/utils/__init__.py -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/js2py/utils/definitions.py: -------------------------------------------------------------------------------- 1 | from pyparsing import * 2 | IdentifierStart = oneOf(['$', '_']+list(alphas)) 3 | Identifier = Combine(IdentifierStart + Optional(Word(alphas+nums+'$_'))) 4 | 5 | _keywords = ['break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 6 | 'return', 'void', 'continue', 'for', 'switch', 'while', 'debugger', 'function', 'this', 7 | 'with', 'default', 'if', 'throw', 'delete', 'in', 'try'] 8 | 9 | Keyword = oneOf(_keywords) 10 | 11 | 12 | #Literals 13 | 14 | #Bool 15 | BooleanLiteral = oneOf(('true', 'false')) 16 | 17 | #Null 18 | 19 | NullLiteral = Literal('null') 20 | 21 | #Undefined 22 | 23 | UndefinedLiteral = Literal('undefined') 24 | 25 | #NaN 26 | 27 | NaNLiteral = Literal('NaN') 28 | 29 | #Number 30 | NonZeroDigit = oneOf(['1','2','3','4','5','6','7','8','9']) 31 | DecimalDigit = oneOf(['0', '1','2','3','4','5','6','7','8','9']) 32 | HexDigit = oneOf(list('0123456789abcdefABCDEF')) 33 | DecimalDigits = Word(nums) 34 | DecimalIntegerLiteral = Combine(NonZeroDigit+Optional(DecimalDigits)) | '0' 35 | SignedInteger = Combine('-'+DecimalDigits) | Combine('+'+DecimalDigits) | DecimalDigits 36 | ExponentPart = Combine(oneOf('e', 'E')+SignedInteger) 37 | _DecimalLiteral = (Combine(DecimalIntegerLiteral('int')+'.'+Optional(DecimalDigits('float'))+Optional(ExponentPart('exp'))) | 38 | Combine('.'+DecimalDigits('float')+Optional(ExponentPart('exp'))) | 39 | DecimalIntegerLiteral('int')+Optional(ExponentPart('exp'))) 40 | DecimalLiteral = Combine(_DecimalLiteral+NotAny(IdentifierStart)) 41 | HexIntegerLiteral = Combine(oneOf(('0x','0X'))+Word('0123456789abcdefABCDEF')('hex')) 42 | NumericLiteral = Group(DecimalLiteral)('decimal') ^ Group(HexIntegerLiteral)('hex') 43 | 44 | def js_num(num): 45 | res = NumericLiteral.parseString(num) 46 | if res.decimal: 47 | res = res.decimal 48 | cand = int(res.int if res.int else 0)+ float('0.'+res.float if res.float else 0) 49 | if res.exp: 50 | cand*= 10**int(res.exp) 51 | return cand 52 | elif res.hex: 53 | return int(res.hex.hex, 16) 54 | 55 | #String 56 | LineTerminator = White('\n', 1,1,1) | White('\r', 1,1,1) 57 | LineTerminatorSequence = Combine(White('\r', 1,1,1)+White('\n', 1,1,1)) | White('\n', 1,1,1) | White('\r', 1,1,1) 58 | LineContinuation = Combine('\\'+LineTerminatorSequence) 59 | 60 | UnicodeEscapeSequence = Combine('u'+HexDigit+HexDigit+HexDigit+HexDigit) 61 | HexEscapeSequence = Combine('x'+HexDigit+HexDigit) 62 | SingleEscapeCharacter = oneOf(["'", '"', '\\', 'b', 'f', 'n', 'r', 't', 'v']) 63 | EscapeCharacter = SingleEscapeCharacter | '0' | 'x' | 'u' # Changed DecimalDigit to 0 since it would match for example "\3" To verify.. 64 | NonEscapeCharacter = CharsNotIn([EscapeCharacter |LineTerminator]) 65 | CharacterEscapeSequence = SingleEscapeCharacter | NonEscapeCharacter 66 | EscapeSequence = CharacterEscapeSequence | Combine('0'+NotAny(DecimalDigit)) | HexEscapeSequence | UnicodeEscapeSequence 67 | 68 | SingleStringCharacter = CharsNotIn([LineTerminator | '\\' | "'"]) | Combine('\\'+EscapeSequence) | LineContinuation 69 | DoubleStringCharacter = CharsNotIn([LineTerminator | '\\' | '"']) | Combine('\\'+EscapeSequence) | LineContinuation 70 | StringLiteral = Combine('"'+ZeroOrMore(DoubleStringCharacter)+'"') ^ Combine("'"+ZeroOrMore(SingleStringCharacter)+"'") 71 | 72 | #Array 73 | 74 | 75 | #Dict 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/log_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | # Addon Name: LambdaScrapers Module 5 | # Addon id: script.module.lambdascrapers 6 | 7 | import os, time, cProfile, StringIO, pstats, json, xbmc 8 | 9 | from xbmc import LOGDEBUG, LOGERROR, LOGFATAL, LOGINFO, LOGNONE, LOGNOTICE, LOGSEVERE, LOGWARNING # @UnusedImport 10 | from datetime import date, datetime, timedelta 11 | from lambdascrapers.modules import control 12 | 13 | name = control.addonInfo('name') 14 | DEBUGPREFIX = '[COLOR red][ PLACENTA DEBUG ][/COLOR]' # Using color coding, for color formatted log viewers like Assassin's Tools 15 | LOGPATH = xbmc.translatePath('special://logpath/') 16 | 17 | def log(msg, level=LOGNOTICE): 18 | debug_enabled = control.setting('addon_debug') 19 | debug_log = control.setting('debug.location') 20 | 21 | print DEBUGPREFIX + ' Debug Enabled?: ' + str(debug_enabled) 22 | print DEBUGPREFIX + ' Debug Log?: ' + str(debug_log) 23 | 24 | if not control.setting('addon_debug') == 'true': 25 | return 26 | 27 | try: 28 | if isinstance(msg, unicode): 29 | msg = '%s (ENCODED)' % (msg.encode('utf-8')) 30 | 31 | if not control.setting('debug.location') == '0': 32 | log_file = os.path.join(LOGPATH, 'placenta.log') 33 | if not os.path.exists(log_file): f = open(log_file, 'w'); f.close() 34 | with open(log_file, 'a') as f: 35 | line = '[%s %s] %s: %s' % (datetime.now().date(), str(datetime.now().time())[:8], DEBUGPREFIX, msg) 36 | f.write(line.rstrip('\r\n')+'\n') 37 | else: 38 | print '%s: %s' % (DEBUGPREFIX, msg) 39 | except Exception as e: 40 | try: 41 | xbmc.log('Logging Failure: %s' % (e), level) 42 | except: 43 | pass 44 | 45 | class Profiler(object): 46 | def __init__(self, file_path, sort_by='time', builtins=False): 47 | self._profiler = cProfile.Profile(builtins=builtins) 48 | self.file_path = file_path 49 | self.sort_by = sort_by 50 | 51 | def profile(self, f): 52 | def method_profile_on(*args, **kwargs): 53 | try: 54 | self._profiler.enable() 55 | result = self._profiler.runcall(f, *args, **kwargs) 56 | self._profiler.disable() 57 | return result 58 | except Exception as e: 59 | log('Profiler Error: %s' % (e), LOGWARNING) 60 | return f(*args, **kwargs) 61 | 62 | def method_profile_off(*args, **kwargs): 63 | return f(*args, **kwargs) 64 | 65 | if _is_debugging(): 66 | return method_profile_on 67 | else: 68 | return method_profile_off 69 | 70 | def __del__(self): 71 | self.dump_stats() 72 | 73 | def dump_stats(self): 74 | if self._profiler is not None: 75 | s = StringIO.StringIO() 76 | params = (self.sort_by,) if isinstance(self.sort_by, basestring) else self.sort_by 77 | ps = pstats.Stats(self._profiler, stream=s).sort_stats(*params) 78 | ps.print_stats() 79 | if self.file_path is not None: 80 | with open(self.file_path, 'w') as f: 81 | f.write(s.getvalue()) 82 | 83 | 84 | def trace(method): 85 | def method_trace_on(*args, **kwargs): 86 | start = time.time() 87 | result = method(*args, **kwargs) 88 | end = time.time() 89 | log('{name!r} time: {time:2.4f}s args: |{args!r}| kwargs: |{kwargs!r}|'.format(name=method.__name__, time=end - start, args=args, kwargs=kwargs), LOGDEBUG) 90 | return result 91 | 92 | def method_trace_off(*args, **kwargs): 93 | return method(*args, **kwargs) 94 | 95 | if _is_debugging(): 96 | return method_trace_on 97 | else: 98 | return method_trace_off 99 | 100 | 101 | def _is_debugging(): 102 | command = {'jsonrpc': '2.0', 'id': 1, 'method': 'Settings.getSettings', 'params': {'filter': {'section': 'system', 'category': 'logging'}}} 103 | js_data = execute_jsonrpc(command) 104 | for item in js_data.get('result', {}).get('settings', {}): 105 | if item['id'] == 'debug.showloginfo': 106 | return item['value'] 107 | 108 | return False 109 | 110 | 111 | def execute_jsonrpc(command): 112 | if not isinstance(command, basestring): 113 | command = json.dumps(command) 114 | response = control.jsonrpc(command) 115 | return json.loads(response) 116 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/pyaes/__init__.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Richard Moore 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | # This is a pure-Python implementation of the AES algorithm and AES common 24 | # modes of operation. 25 | 26 | # See: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard 27 | # See: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation 28 | 29 | 30 | # Supported key sizes: 31 | # 128-bit 32 | # 192-bit 33 | # 256-bit 34 | 35 | 36 | # Supported modes of operation: 37 | # ECB - Electronic Codebook 38 | # CBC - Cipher-Block Chaining 39 | # CFB - Cipher Feedback 40 | # OFB - Output Feedback 41 | # CTR - Counter 42 | 43 | # See the README.md for API details and general information. 44 | 45 | # Also useful, PyCrypto, a crypto library implemented in C with Python bindings: 46 | # https://www.dlitz.net/software/pycrypto/ 47 | 48 | 49 | VERSION = [1, 3, 0] 50 | 51 | from .aes import AES, AESModeOfOperationCTR, AESModeOfOperationCBC, AESModeOfOperationCFB, AESModeOfOperationECB, AESModeOfOperationOFB, AESModesOfOperation, Counter 52 | from .blockfeeder import decrypt_stream, Decrypter, encrypt_stream, Encrypter 53 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/pyaes/util.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Richard Moore 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | # Why to_bufferable? 24 | # Python 3 is very different from Python 2.x when it comes to strings of text 25 | # and strings of bytes; in Python 3, strings of bytes do not exist, instead to 26 | # represent arbitrary binary data, we must use the "bytes" object. This method 27 | # ensures the object behaves as we need it to. 28 | 29 | def to_bufferable(binary): 30 | return binary 31 | 32 | def _get_byte(c): 33 | return ord(c) 34 | 35 | try: 36 | xrange 37 | except: 38 | 39 | def to_bufferable(binary): 40 | if isinstance(binary, bytes): 41 | return binary 42 | return bytes(ord(b) for b in binary) 43 | 44 | def _get_byte(c): 45 | return c 46 | 47 | def append_PKCS7_padding(data): 48 | pad = 16 - (len(data) % 16) 49 | return data + to_bufferable(chr(pad) * pad) 50 | 51 | def strip_PKCS7_padding(data): 52 | if len(data) % 16 != 0: 53 | raise ValueError("invalid length") 54 | 55 | pad = _get_byte(data[-1]) 56 | 57 | if not pad or pad > 16: 58 | return data 59 | 60 | return data[:-pad] 61 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | LambdaScrapers Module 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | # Addon Name: LambdaScrapers Module 20 | # Addon id: script.module.lambdascrapers 21 | 22 | import json, re 23 | 24 | 25 | def json_load_as_str(file_handle): 26 | return byteify(json.load(file_handle, object_hook=byteify), ignore_dicts=True) 27 | 28 | 29 | def json_loads_as_str(json_text): 30 | return byteify(json.loads(json_text, object_hook=byteify), ignore_dicts=True) 31 | 32 | 33 | def byteify(data, ignore_dicts=False): 34 | if isinstance(data, unicode): 35 | return data.encode('utf-8') 36 | if isinstance(data, list): 37 | return [byteify(item, ignore_dicts=True) for item in data] 38 | if isinstance(data, dict) and not ignore_dicts: 39 | return dict([(byteify(key, ignore_dicts=True), byteify(value, ignore_dicts=True)) for key, value in data.iteritems()]) 40 | return data 41 | 42 | def title_key(title): 43 | try: 44 | if title is None: title = '' 45 | articles_en = ['the', 'a', 'an'] 46 | articles_de = ['der', 'die', 'das'] 47 | articles = articles_en + articles_de 48 | 49 | match = re.match('^((\w+)\s+)', title.lower()) 50 | if match and match.group(2) in articles: 51 | offset = len(match.group(1)) 52 | else: 53 | offset = 0 54 | 55 | return title[offset:] 56 | except: 57 | return title 58 | -------------------------------------------------------------------------------- /lib/lambdascrapers/modules/workers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | LambdaScrapers Module 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | # Addon Name: LambdaScrapers Module 20 | # Addon id: script.module.lambdascrapers 21 | 22 | import threading 23 | 24 | 25 | class Thread(threading.Thread): 26 | def __init__(self, target, *args): 27 | self._target = target 28 | self._args = args 29 | threading.Thread.__init__(self) 30 | def run(self): 31 | self._target(*self._args) 32 | 33 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/cine.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import json 16 | import re 17 | import urllib 18 | import urlparse 19 | 20 | from resources.lib.modules import client 21 | from resources.lib.modules import source_utils 22 | 23 | 24 | class source: 25 | def __init__(self): 26 | self.priority = 1 27 | self.language = ['de'] 28 | self.domains = ['cine.to'] 29 | self.base_link = 'https://cine.to' 30 | self.request_link = '/request/links' 31 | self.out_link = '/out/%s' 32 | 33 | def movie(self, imdb, title, localtitle, aliases, year): 34 | try: 35 | return urllib.urlencode({'imdb': imdb}) 36 | except: 37 | return 38 | 39 | def sources(self, url, hostDict, hostprDict): 40 | sources = [] 41 | 42 | try: 43 | if url == None: 44 | return sources 45 | 46 | data = urlparse.parse_qs(url) 47 | data = dict([(i, data[i][0]) if data[i] else (i, '') for i in data]) 48 | data = urllib.urlencode({'ID': re.sub('[^0-9]', '', str(data['imdb'])), 'lang': 'de'}) 49 | 50 | data = client.request(urlparse.urljoin(self.base_link, self.request_link), post=data, XHR=True) 51 | data = json.loads(data) 52 | data = [(i, data['links'][i]) for i in data['links'] if 'links' in data] 53 | data = [(i[0], i[1][0], (i[1][1:])) for i in data] 54 | 55 | for hoster, quli, links in data: 56 | valid, hoster = source_utils.is_host_valid(hoster, hostDict) 57 | if not valid: continue 58 | 59 | for link in links: 60 | try: sources.append({'source': hoster, 'quality': 'SD', 'language': 'de', 'url': self.out_link % link, 'direct': False, 'debridonly': False}) 61 | except: pass 62 | 63 | return sources 64 | except: 65 | return sources 66 | 67 | def resolve(self, url): 68 | try: 69 | url = urlparse.urljoin(self.base_link, url) 70 | url = client.request(url, output='geturl') 71 | if self.out_link not in url: 72 | return url 73 | except: 74 | return 75 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/ddl.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import json 16 | import re 17 | import urllib 18 | import urlparse 19 | 20 | from resources.lib.modules import client 21 | from resources.lib.modules import source_utils 22 | 23 | 24 | class source: 25 | def __init__(self): 26 | self.priority = 1 27 | self.language = ['de'] 28 | self.domains = ['de.ddl.me'] 29 | self.base_link = 'http://de.ddl.me' 30 | self.search_link = '/search_99/?q=%s' 31 | 32 | def movie(self, imdb, title, localtitle, aliases, year): 33 | try: 34 | url = self.__get_direct_url(imdb) 35 | if not url: return 36 | return urllib.urlencode({'url': url}) 37 | except: 38 | return 39 | 40 | def tvshow(self, imdb, tvdb, tvshowtitle, localtvshowtitle, aliases, year): 41 | try: 42 | return self.__get_direct_url(imdb) 43 | except: 44 | return 45 | 46 | def episode(self, url, imdb, tvdb, title, premiered, season, episode): 47 | try: 48 | if url == None: return 49 | 50 | j = self.__get_json(url) 51 | 52 | if not j: return 53 | 54 | j = [v['info'] for k, v in j.items()] 55 | j = [(i['nr'], i['staffel'], i['sid']) for i in j] 56 | j = [(i[2]) for i in j if int(i[0]) == int(episode) and int(i[1]) == int(season)][0] 57 | return urllib.urlencode({'url': url, 'sid': j}) 58 | except: 59 | return 60 | 61 | def sources(self, url, hostDict, hostprDict): 62 | sources = [] 63 | 64 | try: 65 | if url == None: 66 | return sources 67 | 68 | data = urlparse.parse_qs(url) 69 | data = dict([(i, data[i][0]) if data[i] else (i, '') for i in data]) 70 | 71 | j = self.__get_json(data['url']) 72 | 73 | if not j: return 74 | 75 | sid = data['sid'] if 'sid' in data else j.keys()[0] 76 | pcnt = int(j[sid]['1']) if '1' in j[sid] else 1 77 | 78 | for jHoster in j[sid]['links']: 79 | jLinks = [i[3] for i in j[sid]['links'][jHoster] if i[5] == 'stream'] 80 | if len(jLinks) < pcnt: continue 81 | 82 | h_url = jLinks[0] 83 | valid, hoster = source_utils.is_host_valid(h_url, hostDict) 84 | if not valid: continue 85 | 86 | h_url = h_url if pcnt == 1 else 'stack://' + ' , '.join(jLinks) 87 | 88 | try: sources.append({'source': hoster, 'quality': 'SD', 'language': 'de', 'info' : '' if pcnt == 1 else 'multi-part', 'url': h_url, 'direct': False, 'debridonly': False}) 89 | except: pass 90 | 91 | return sources 92 | except: 93 | return sources 94 | 95 | def resolve(self, url): 96 | return url 97 | 98 | def __get_direct_url(self, imdb): 99 | try: 100 | query = urlparse.urljoin(self.base_link, self.search_link % imdb) 101 | r = client.request(query, output='geturl') 102 | 103 | if self.search_link in r: return 104 | return r 105 | except: 106 | return 107 | 108 | def __get_json(self, url): 109 | try: 110 | result = client.request(url) 111 | result = re.compile('var\s+subcats\s+=\s*(.*?);').findall(result)[0] 112 | return json.loads(result) 113 | except: 114 | return 115 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/horrorkino.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import re 16 | import urlparse 17 | 18 | from resources.lib.modules import cleantitle 19 | from resources.lib.modules import client 20 | from resources.lib.modules import dom_parser 21 | from resources.lib.modules import source_utils 22 | 23 | 24 | class source: 25 | def __init__(self): 26 | self.priority = 1 27 | self.language = ['de'] 28 | self.genre_filter = ['horror'] 29 | self.domains = ['horrorkino.do.am'] 30 | self.base_link = 'http://horrorkino.do.am/' 31 | self.search_link = 'video/shv' 32 | 33 | def movie(self, imdb, title, localtitle, aliases, year): 34 | try: 35 | url = self.__search([localtitle] + source_utils.aliases_to_array(aliases), year) 36 | if not url and title != localtitle: url = self.__search([title] + source_utils.aliases_to_array(aliases), year) 37 | return url 38 | except: 39 | return 40 | 41 | def sources(self, url, hostDict, hostprDict): 42 | sources = [] 43 | 44 | try: 45 | if not url: 46 | return sources 47 | 48 | r = client.request(urlparse.urljoin(self.base_link, url)) 49 | r = re.findall('''vicode\s*=\s*["'](.*?)["'];''', r)[0].decode('string_escape') 50 | r = dom_parser.parse_dom(r, 'iframe', req='src') 51 | r = [i.attrs['src'] for i in r] 52 | 53 | for i in r: 54 | valid, host = source_utils.is_host_valid(i, hostDict) 55 | if not valid: continue 56 | 57 | sources.append({'source': host, 'quality': 'SD', 'language': 'de', 'url': i, 'direct': False, 'debridonly': False, 'checkquality': True}) 58 | 59 | return sources 60 | except: 61 | return sources 62 | 63 | def resolve(self, url): 64 | return url 65 | 66 | def __search(self, titles, year): 67 | try: 68 | t = [cleantitle.get(i) for i in set(titles) if i] 69 | y = ['%s' % str(year), '%s' % str(int(year) + 1), '%s' % str(int(year) - 1), '0'] 70 | 71 | r = client.request(urlparse.urljoin(self.base_link, self.search_link), post={'query': cleantitle.query(titles[0])}) 72 | 73 | r = dom_parser.parse_dom(r, 'li', attrs={'class': 'entTd'}) 74 | r = dom_parser.parse_dom(r, 'div', attrs={'class': 've-screen'}, req='title') 75 | r = [(dom_parser.parse_dom(i, 'a', req='href'), i.attrs['title'].split(' - ')[0]) for i in r] 76 | r = [(i[0][0].attrs['href'], i[1], re.findall('(.+?) \(*(\d{4})', i[1])) for i in r] 77 | r = [(i[0], i[2][0][0] if len(i[2]) > 0 else i[1], i[2][0][1] if len(i[2]) > 0 else '0') for i in r] 78 | r = sorted(r, key=lambda i: int(i[2]), reverse=True) # with year > no year 79 | r = [i[0] for i in r if cleantitle.get(i[1]) in t and i[2] in y][0] 80 | 81 | return source_utils.strip_domain(r) 82 | except: 83 | return 84 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/movie2k-ac.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import re 16 | import urllib 17 | import urlparse 18 | 19 | from resources.lib.modules import cleantitle 20 | from resources.lib.modules import client 21 | from resources.lib.modules import source_utils 22 | from resources.lib.modules import dom_parser 23 | 24 | 25 | class source: 26 | def __init__(self): 27 | self.priority = 1 28 | self.language = ['de'] 29 | self.domains = ['movie2k.ac'] 30 | self.base_link = 'http://www.movie2k.ac' 31 | self.search_link = '/search/%s' 32 | 33 | def movie(self, imdb, title, localtitle, aliases, year): 34 | try: 35 | url = self.__search([localtitle] + source_utils.aliases_to_array(aliases)) 36 | if not url and title != localtitle: url = self.__search([title] + source_utils.aliases_to_array(aliases)) 37 | return url 38 | except: 39 | return 40 | 41 | def sources(self, url, hostDict, hostprDict): 42 | sources = [] 43 | 44 | try: 45 | if not url: 46 | return sources 47 | 48 | query = urlparse.urljoin(self.base_link, url) 49 | r = client.request(query) 50 | 51 | r = dom_parser.parse_dom(r, 'div', attrs={'id': 'tab-plot_german'}) 52 | r = dom_parser.parse_dom(r, 'tbody') 53 | r = dom_parser.parse_dom(r, 'tr') 54 | 55 | for i in r: 56 | if re.search('(?<=">)(\n.*?)(?=<\/a>)', i[1]).group().strip(): 57 | hoster = re.search('(?<=">)(\n.*?)(?=<\/a>)', i[1]).group().strip() 58 | link = re.search('(?<=href=\")(.*?)(?=\")', i[1]).group() 59 | rel = re.search('(?<=oddCell qualityCell">)(\n.*?)(?=<\/td>)', i[1]).group().strip() 60 | quality, info = source_utils.get_release_quality(rel) 61 | if not quality: 62 | quality = 'SD' 63 | 64 | valid, hoster = source_utils.is_host_valid(hoster, hostDict) 65 | if not valid: continue 66 | 67 | sources.append({'source': hoster, 'quality': quality, 'language': 'de', 'url': link, 'direct': False, 'debridonly': False}) 68 | 69 | return sources 70 | except: 71 | return sources 72 | 73 | def resolve(self, url): 74 | return url 75 | 76 | def __search(self, titles): 77 | try: 78 | query = self.search_link % (urllib.quote_plus(urllib.quote_plus(cleantitle.query(titles[0])))) 79 | query = urlparse.urljoin(self.base_link, query) 80 | 81 | t = [cleantitle.get(i) for i in set(titles) if i] 82 | 83 | r = client.request(query) 84 | 85 | r = dom_parser.parse_dom(r, 'ul', attrs={'class': 'coverBox'}) 86 | r = dom_parser.parse_dom(r, 'li') 87 | r = dom_parser.parse_dom(r, 'span', attrs={'class': 'name'}) 88 | r = dom_parser.parse_dom(r, 'a') 89 | 90 | title = r[0][1] 91 | title = cleantitle.get(title) 92 | 93 | if title in t: 94 | return source_utils.strip_domain(r[0][0]['href']) 95 | else: 96 | return 97 | except: 98 | return 99 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/movie2k-ag.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import re 16 | import urllib 17 | import urlparse 18 | 19 | from resources.lib.modules import cleantitle 20 | from resources.lib.modules import client 21 | from resources.lib.modules import source_utils 22 | from resources.lib.modules import dom_parser 23 | 24 | 25 | class source: 26 | def __init__(self): 27 | self.priority = 1 28 | self.language = ['de'] 29 | self.domains = ['movie2k.ag'] 30 | self.base_link = 'https://www.movie2k.ag' 31 | self.search_link = '?c=movie&m=filter&keyword=%s' 32 | self.get_link = 'http://www.vodlocker.to/embed/movieStreams?lang=2&e=&id=%s&links=%s&cat=movie' 33 | 34 | def movie(self, imdb, title, localtitle, aliases, year): 35 | try: 36 | url = self.__search([localtitle] + source_utils.aliases_to_array(aliases)) 37 | if not url and title != localtitle: url = self.__search([title] + source_utils.aliases_to_array(aliases)) 38 | return url 39 | except: 40 | return 41 | 42 | def sources(self, url, hostDict, hostprDict): 43 | sources = [] 44 | 45 | try: 46 | if not url: 47 | return sources 48 | 49 | query = urlparse.urljoin(self.base_link, url) 50 | r = client.request(query) 51 | r = dom_parser.parse_dom(r, 'div', attrs={'id': 'player'}) 52 | r = dom_parser.parse_dom(r, 'iframe', req='src') 53 | r = client.request(r[0][0]['src']) 54 | r = dom_parser.parse_dom(r, 'a', attrs={'class': 'play_container'}, req='href') 55 | r = client.request(r[0][0]['href']) 56 | url = self.get_link % (re.search('(?<=var id = \")(.*?)(?=\")', r).group(), re.search('(?<=var links = \")(.*?)(?=\")', r).group()) 57 | r = client.request(url) 58 | r = dom_parser.parse_dom(r, 'ul', attrs={'id': 'articleList'}) 59 | r = dom_parser.parse_dom(r, 'a') 60 | 61 | for i in r: 62 | if 'http' in i[0]['href']: 63 | link = i[0]['href'] 64 | elif 'http' in i[0]['onclick']: 65 | link = re.search('http(.*?)(?=\")', i[0]['onclick']).group() 66 | else: 67 | return sources 68 | 69 | valid, hoster = source_utils.is_host_valid(link, hostDict) 70 | if not valid: continue 71 | 72 | sources.append({'source': hoster, 'quality': 'SD', 'language': 'de', 'url': link, 'direct': False, 'debridonly': False}) 73 | 74 | return sources 75 | except: 76 | return sources 77 | 78 | def resolve(self, url): 79 | return url 80 | 81 | def __search(self, titles): 82 | try: 83 | query = self.search_link % (urllib.quote_plus(cleantitle.query(titles[0]))) 84 | query = urlparse.urljoin(self.base_link, query) 85 | 86 | t = [cleantitle.get(i) for i in set(titles) if i] 87 | 88 | r = client.request(query) 89 | 90 | r = dom_parser.parse_dom(r, 'div', attrs={'class': 'nag'}) 91 | r = dom_parser.parse_dom(r, 'div', attrs={'class': 'item-video'}) 92 | r = dom_parser.parse_dom(r, 'h2', attrs={'class': 'entry-title'}) 93 | r = dom_parser.parse_dom(r, 'a', req='href') 94 | 95 | 96 | 97 | 98 | for i in r: 99 | title = i[1] 100 | if re.search('\*(?:.*?)\*', title) is not None: 101 | title = re.sub('\*(?:.*?)\*', '', title) 102 | title = cleantitle.get(title) 103 | if title in t: 104 | return source_utils.strip_domain(i[0]['href']) 105 | else: 106 | return 107 | except: 108 | return 109 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/netzkino.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import json 16 | import re 17 | import urllib 18 | import urlparse 19 | 20 | from resources.lib.modules import cleantitle 21 | from resources.lib.modules import client 22 | from resources.lib.modules import source_utils 23 | 24 | 25 | class source: 26 | def __init__(self): 27 | self.priority = 1 28 | self.language = ['de'] 29 | self.domains = ['netzkino.de'] 30 | self.base_link = 'http://netzkino.de' 31 | self.conf_link = '/adconf/android-new.php' 32 | self.search_link = 'http://api.netzkino.de.simplecache.net/capi-2.0a/search?q=%s&d=www&l=de-DE&v=unknown-debugBuild' 33 | 34 | def movie(self, imdb, title, localtitle, aliases, year): 35 | try: 36 | url = self.__search([localtitle] + source_utils.aliases_to_array(aliases), imdb, year) 37 | if not url and title != localtitle: url = self.__search([title] + source_utils.aliases_to_array(aliases), imdb, year) 38 | return url 39 | except: 40 | return 41 | 42 | def sources(self, url, hostDict, hostprDict): 43 | sources = [] 44 | 45 | try: 46 | if not url: 47 | return sources 48 | 49 | r = client.request(urlparse.urljoin(self.base_link, self.conf_link), XHR=True) 50 | r = json.loads(r).get('streamer') 51 | r = client.request(r + '%s.mp4/master.m3u8' % url, XHR=True) 52 | 53 | r = re.findall('RESOLUTION\s*=\s*\d+x(\d+).*?\n(http.*?)(?:\n|$)', r, re.IGNORECASE) 54 | r = [(source_utils.label_to_quality(i[0]), i[1]) for i in r] 55 | 56 | for quality, link in r: 57 | sources.append({'source': 'CDN', 'quality': quality, 'language': 'de', 'url': link, 'direct': True, 'debridonly': False}) 58 | 59 | return sources 60 | except: 61 | return sources 62 | 63 | def resolve(self, url): 64 | return url 65 | 66 | def __search(self, titles, imdb, year): 67 | try: 68 | query = self.search_link % (urllib.quote_plus(cleantitle.query(titles[0]))) 69 | query = urlparse.urljoin(self.base_link, query) 70 | 71 | t = [cleantitle.get(i) for i in set(titles) if i] 72 | y = ['%s' % str(year), '%s' % str(int(year) + 1), '%s' % str(int(year) - 1), '0'] 73 | 74 | r = client.request(query, XHR=True) 75 | r = json.loads(r) 76 | 77 | r = [(i.get('title'), i.get('custom_fields', {})) for i in r.get('posts', [])] 78 | r = [(i[0], i[1]) for i in r if i[0] and i[1]] 79 | r = [(i[0], i[1].get('Streaming', ['']), i[1].get('Jahr', ['0']), i[1].get('IMDb-Link', [''])) for i in r if i] 80 | r = [(i[0], i[1][0], i[2][0], re.findall('.+?(tt\d+).*?', i[3][0])) for i in r if i[0] and i[1] and i[2] and i[3]] 81 | r = [i[1] for i in r if imdb in i[3] or (cleantitle.get(i[0]) in t and i[2] in y)][0] 82 | 83 | return source_utils.strip_domain(r) 84 | except: 85 | return 86 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/de/video4k.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ####################################################################### 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # @Daddy_Blamo wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return. - Muad'Dib 8 | # ---------------------------------------------------------------------------- 9 | ####################################################################### 10 | 11 | # Addon Name: Placenta 12 | # Addon id: plugin.video.placenta 13 | # Addon Provider: Mr.Blamo 14 | 15 | import json 16 | import re 17 | import urllib 18 | import urlparse 19 | 20 | from resources.lib.modules import client 21 | from resources.lib.modules import source_utils 22 | 23 | 24 | class source: 25 | def __init__(self): 26 | self.priority = 1 27 | self.language = ['de'] 28 | self.domains = ['video4k.to'] 29 | self.base_link = 'http://video4k.to' 30 | self.request_link = '/request' 31 | 32 | def movie(self, imdb, title, localtitle, aliases, year): 33 | try: 34 | return urllib.urlencode({'mID': re.sub('[^0-9]', '', imdb)}) 35 | except: 36 | return 37 | 38 | def tvshow(self, imdb, tvdb, tvshowtitle, localtvshowtitle, aliases, year): 39 | try: 40 | return urllib.urlencode({'mID': re.sub('[^0-9]', '', imdb)}) 41 | except: 42 | return 43 | 44 | def episode(self, url, imdb, tvdb, title, premiered, season, episode): 45 | try: 46 | if url == None: 47 | return 48 | 49 | return urllib.urlencode({'mID': re.sub('[^0-9]', '', imdb), 'season': season, 'episode': episode}) 50 | except: 51 | return 52 | 53 | def sources(self, url, hostDict, hostprDict): 54 | sources = [] 55 | 56 | try: 57 | if url == None: 58 | return sources 59 | 60 | data = urlparse.parse_qs(url) 61 | data = dict([(i, data[i][0]) if data[i] else (i, '') for i in data]) 62 | data.update({'raw': 'true', 'language': 'de'}) 63 | data = urllib.urlencode(data) 64 | data = client.request(urlparse.urljoin(self.base_link, self.request_link), post=data) 65 | data = json.loads(data) 66 | data = [i[1] for i in data[1].items()] 67 | data = [(i['name'].lower(), i['links']) for i in data] 68 | 69 | for host, links in data: 70 | valid, host = source_utils.is_host_valid(host, hostDict) 71 | if not valid: continue 72 | 73 | for link in links: 74 | try:sources.append({'source': host, 'quality': 'SD', 'language': 'de', 'url': link['URL'], 'direct': False, 'debridonly': False}) 75 | except: pass 76 | 77 | return sources 78 | except: 79 | return sources 80 | 81 | def resolve(self, url): 82 | return url 83 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/en/0123putlocker.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # -Cleaned and Checked on 12-03-2018 by JewBMX in Scrubs. 3 | 4 | import re,urllib,urlparse,base64 5 | from resources.lib.modules import cleantitle,client,proxy,cfscrape 6 | 7 | 8 | class source: 9 | def __init__(self): 10 | self.priority = 1 11 | self.language = ['en'] 12 | self.domains = ['0123putlocker.com'] 13 | self.base_link = 'http://0123putlocker.com' 14 | self.search_link = '/search-movies/%s.html' 15 | self.scraper = cfscrape.create_scraper() 16 | 17 | 18 | def tvshow(self, imdb, tvdb, tvshowtitle, localtvshowtitle, aliases, year): 19 | try: 20 | url = cleantitle.geturl(tvshowtitle) 21 | url = url.replace('-','+') 22 | return url 23 | except: 24 | return 25 | 26 | 27 | def episode(self, url, imdb, tvdb, title, premiered, season, episode): 28 | try: 29 | if not url: return 30 | query = url + '+season+' + season 31 | find = query.replace('+','-') 32 | url = self.base_link + self.search_link % query 33 | r = self.scraper.get(url).content 34 | match = re.compile('' + episode + '').findall(r) 39 | for url in match: 40 | return url 41 | except: 42 | return 43 | 44 | 45 | def sources(self, url, hostDict, hostprDict): 46 | try: 47 | sources = [] 48 | r = self.scraper.get(url).content 49 | try: 50 | match = re.compile('

').findall(r) 51 | for host, url in match: 52 | if host == 'internet': pass 53 | else: sources.append({'source': host,'quality': 'SD','language': 'en','url': url,'direct': False,'debridonly': False}) 54 | except: 55 | return 56 | except Exception: 57 | return 58 | return sources 59 | 60 | 61 | def resolve(self, url): 62 | r = self.scraper.get(url).content 63 | match = re.compile('decode\("(.+?)"').findall(r) 64 | for info in match: 65 | info = base64.b64decode(info) 66 | match = re.compile('src="(.+?)"').findall(info) 67 | for url in match: 68 | return url 69 | 70 | -------------------------------------------------------------------------------- /lib/lambdascrapers/sources_ lambdascrapers/en/Hdmto.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | ''' 3 | hdmto scraper for Exodus forks. 4 | Nov 9 2018 - Checked 5 | 6 | Updated and refactored by someone. 7 | Originally created by others. 8 | ''' 9 | import re 10 | import urllib 11 | import urlparse 12 | from resources.lib.modules import cleantitle 13 | from resources.lib.modules import client 14 | from resources.lib.modules import proxy 15 | from resources.lib.modules import cfscrape 16 | 17 | class source: 18 | def __init__(self): 19 | self.priority = 1 20 | self.language = ['en'] 21 | self.domains = ['hdm.to'] 22 | self.base_link = 'https://hdm.to' 23 | self.scraper = cfscrape.create_scraper() 24 | 25 | def movie(self, imdb, title, localtitle, aliases, year): 26 | try: 27 | url = cleantitle.geturl(title) 28 | return url 29 | except: 30 | return 31 | 32 | def sources(self, url, hostDict, hostprDict): 33 | try: 34 | sources = [] 35 | url = '%s/%s/' % (self.base_link,url) 36 | r = self.scraper.get(url).content 37 | try: 38 | match = re.compile('