From 181ab47c5f775b8b48569361da6b88a801784a30 Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Thu, 26 Mar 2015 18:15:41 +0100 Subject: Cleanup --- module/plugins/accounts/Keep2ShareCc.py | 73 ---- module/plugins/accounts/MegaRapidoNet.py | 57 --- module/plugins/captcha/OCR.py | 319 --------------- module/plugins/crypter/DailymotionComFolder.py | 106 ----- module/plugins/crypter/YoutubeComFolder.py | 148 ------- module/plugins/hooks/AntiVirus.py | 95 ----- module/plugins/hooks/MegaRapidoNet.py | 81 ---- module/plugins/hoster/MegaRapidoNet.py | 54 --- module/plugins/internal/CaptchaService.py | 526 ------------------------- pyload/plugin/Addon.py | 4 +- pyload/plugin/Captcha.py | 2 +- pyload/plugin/account/Keep2ShareCc.py | 58 +-- pyload/plugin/account/MegaRapidoNet.py | 57 +++ pyload/plugin/addon/AndroidPhoneNotify.py | 4 +- pyload/plugin/addon/AntiVirus.py | 88 +++++ pyload/plugin/addon/Checksum.py | 2 - pyload/plugin/addon/ClickAndLoad.py | 5 +- pyload/plugin/addon/DeleteFinished.py | 2 +- pyload/plugin/addon/DownloadScheduler.py | 8 - pyload/plugin/addon/ExternalScripts.py | 21 +- pyload/plugin/addon/ExtractArchive.py | 2 - pyload/plugin/addon/IRCInterface.py | 3 - pyload/plugin/addon/JustPremium.py | 5 - pyload/plugin/addon/MergeFiles.py | 6 - pyload/plugin/addon/MultiHome.py | 4 - pyload/plugin/addon/RestartFailed.py | 1 + pyload/plugin/addon/RestartSlow.py | 7 +- pyload/plugin/addon/SkipRev.py | 17 +- pyload/plugin/addon/UnSkipOnFail.py | 3 - pyload/plugin/addon/UpdateManager.py | 25 +- pyload/plugin/addon/WindowsPhoneNotify.py | 10 +- pyload/plugin/captcha/AdYouLike.py | 1 + pyload/plugin/captcha/AdsCaptcha.py | 1 + pyload/plugin/captcha/ReCaptcha.py | 1 + pyload/plugin/captcha/SolveMedia.py | 1 + pyload/plugin/crypter/DailymotionComFolder.py | 106 +++++ pyload/plugin/crypter/FilecryptCc.py | 2 +- pyload/plugin/crypter/YoutubeComFolder.py | 148 +++++++ pyload/plugin/extractor/UnRar.py | 6 +- pyload/plugin/hook/BypassCaptcha.py | 2 - pyload/plugin/hook/Captcha9Kw.py | 2 - pyload/plugin/hook/CaptchaBrotherhood.py | 7 +- pyload/plugin/hook/DeathByCaptcha.py | 7 +- pyload/plugin/hook/ExpertDecoders.py | 7 +- pyload/plugin/hook/ImageTyperz.py | 2 - pyload/plugin/hook/MegaRapidoNet.py | 81 ++++ pyload/plugin/hook/XFileSharingPro.py | 3 +- pyload/plugin/hoster/ExtabitCom.py | 2 +- pyload/plugin/hoster/FileserveCom.py | 2 +- pyload/plugin/hoster/FreakshareCom.py | 2 +- pyload/plugin/hoster/Keep2ShareCc.py | 2 +- pyload/plugin/hoster/LetitbitNet.py | 2 +- pyload/plugin/hoster/MediafireCom.py | 7 +- pyload/plugin/hoster/MegaRapidoNet.py | 54 +++ pyload/plugin/hoster/NitroflareCom.py | 2 +- pyload/plugin/hoster/RapidgatorNet.py | 6 +- pyload/plugin/hoster/SoundcloudCom.py | 7 +- pyload/plugin/hoster/UploadedTo.py | 2 +- pyload/plugin/hoster/ZippyshareCom.py | 2 +- pyload/plugin/internal/BasePlugin.py | 5 +- pyload/plugin/internal/MultiHook.py | 30 +- pyload/plugin/internal/MultiHoster.py | 2 +- 62 files changed, 655 insertions(+), 1642 deletions(-) delete mode 100644 module/plugins/accounts/Keep2ShareCc.py delete mode 100644 module/plugins/accounts/MegaRapidoNet.py delete mode 100644 module/plugins/captcha/OCR.py delete mode 100644 module/plugins/crypter/DailymotionComFolder.py delete mode 100644 module/plugins/crypter/YoutubeComFolder.py delete mode 100644 module/plugins/hooks/AntiVirus.py delete mode 100644 module/plugins/hooks/MegaRapidoNet.py delete mode 100644 module/plugins/hoster/MegaRapidoNet.py delete mode 100644 module/plugins/internal/CaptchaService.py create mode 100644 pyload/plugin/account/MegaRapidoNet.py create mode 100644 pyload/plugin/addon/AntiVirus.py create mode 100644 pyload/plugin/crypter/DailymotionComFolder.py create mode 100644 pyload/plugin/crypter/YoutubeComFolder.py create mode 100644 pyload/plugin/hook/MegaRapidoNet.py create mode 100644 pyload/plugin/hoster/MegaRapidoNet.py diff --git a/module/plugins/accounts/Keep2ShareCc.py b/module/plugins/accounts/Keep2ShareCc.py deleted file mode 100644 index d2ba1d237..000000000 --- a/module/plugins/accounts/Keep2ShareCc.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from module.plugins.Account import Account - - -class Keep2ShareCc(Account): - __name__ = "Keep2ShareCc" - __type__ = "account" - __version__ = "0.05" - - __description__ = """Keep2Share.cc account plugin""" - __license__ = "GPLv3" - __authors__ = [("aeronaut", "aeronaut@pianoguy.de"), - ("Walter Purcaro", "vuolter@gmail.com")] - - - VALID_UNTIL_PATTERN = r'Premium expires:\s*(.+?)<' - TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*(.+?)<' - - LOGIN_FAIL_PATTERN = r'Please fix the following input errors' - - - def loadAccountInfo(self, user, req): - validuntil = None - trafficleft = -1 - premium = False - - html = req.load("http://keep2share.cc/site/profile.html", decode=True) - - m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: - expiredate = m.group(1).strip() - self.logDebug("Expire date: " + expiredate) - - if expiredate == "LifeTime": - premium = True - validuntil = -1 - else: - try: - validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d")) - - except Exception, e: - self.logError(e) - - else: - premium = True if validuntil > time.mktime(time.gmtime()) else False - - m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: - try: - trafficleft = self.parseTraffic(m.group(1)) - - except Exception, e: - self.logError(e) - - return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} - - - def login(self, user, data, req): - req.cj.setCookie("keep2share.cc", "lang", "en") - - html = req.load("http://keep2share.cc/login.html", - post={'LoginForm[username]' : user, - 'LoginForm[password]' : data['password'], - 'LoginForm[rememberMe]': 1, - 'yt0' : ""}, - decode=True) - - if re.search(self.LOGIN_FAIL_PATTERN, html): - self.wrongPassword() diff --git a/module/plugins/accounts/MegaRapidoNet.py b/module/plugins/accounts/MegaRapidoNet.py deleted file mode 100644 index 80e066244..000000000 --- a/module/plugins/accounts/MegaRapidoNet.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from module.plugins.Account import Account - - -class MegaRapidoNet(Account): - __name__ = "MegaRapidoNet" - __type__ = "account" - __version__ = "0.02" - - __description__ = """MegaRapido.net account plugin""" - __license__ = "GPLv3" - __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] - - - VALID_UNTIL_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?[\'"]premium_index[\'"][^>]*>[^<]*?<[^>]*?b[^>]*>\s*?TEMPO\s*?PREMIUM[^<]*<[^>]*?/b[^>]*>\s*?(\d*)[^\d]*?DIAS[^\d]*?(\d*)[^\d]*?HORAS[^\d]*?(\d*)[^\d]*?MINUTOS[^\d]*?(\d*)[^\d]*?SEGUNDOS' - USER_ID_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']checkbox_compartilhar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']usar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']user["\'][^>]*?value\s*?=\s*?["\'](.*?)\s*?["\']' - - - def loadAccountInfo(self, user, req): - validuntil = None - trafficleft = None - premium = False - - html = req.load("http://megarapido.net/gerador", decode=True) - - validuntil = re.search(self.VALID_UNTIL_PATTERN, html) - if validuntil: - #hier weitermachen!!! (müssen umbedingt die zeit richtig machen damit! (sollte aber möglich)) - validuntil = time.time() + int(validuntil.group(1)) * 24 * 3600 + int(validuntil.group(2)) * 3600 + int(validuntil.group(3)) * 60 + int(validuntil.group(4)) - trafficleft = -1 - premium = True - - return {'validuntil' : validuntil, - 'trafficleft': trafficleft, - 'premium' : premium} - - - def login(self, user, data, req): - req.load("http://megarapido.net/login") - req.load("http://megarapido.net/painel_user/ajax/logar.php", - post={'login': user, 'senha': data['password']}, - decode=True) - - html = req.load("http://megarapido.net/gerador") - - if "sair" not in html.lower(): - self.wrongPassword() - else: - m = re.search(self.USER_ID_PATTERN, html) - if m: - data['uid'] = m.group(1) - else: - self.fail("Couldn't find the user ID") diff --git a/module/plugins/captcha/OCR.py b/module/plugins/captcha/OCR.py deleted file mode 100644 index 1874ba07d..000000000 --- a/module/plugins/captcha/OCR.py +++ /dev/null @@ -1,319 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -try: - from PIL import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin - -except ImportError: - import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin - -import logging -import os -import subprocess -#import tempfile - -from module.utils import save_join - - -class OCR(object): - __name__ = "OCR" - __type__ = "ocr" - __version__ = "0.11" - - __description__ = """OCR base plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - def __init__(self): - self.logger = logging.getLogger("log") - - - def load_image(self, image): - self.image = Image.open(image) - self.pixels = self.image.load() - self.result_captcha = '' - - - def unload(self): - """delete all tmp images""" - pass - - - def threshold(self, value): - self.image = self.image.point(lambda a: a * value + 10) - - - def run(self, command): - """Run a command""" - - popen = subprocess.Popen(command, bufsize = -1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - popen.wait() - output = popen.stdout.read() +" | "+ popen.stderr.read() - popen.stdout.close() - popen.stderr.close() - self.logger.debug("Tesseract ReturnCode %s Output: %s" % (popen.returncode, output)) - - - def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True): - #tmpTif = tempfile.NamedTemporaryFile(suffix=".tif") - try: - tmpTif = open(save_join("tmp", "tmpTif_%s.tif" % self.__name__), "wb") - tmpTif.close() - - #tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt") - tmpTxt = open(save_join("tmp", "tmpTxt_%s.txt" % self.__name__), "wb") - tmpTxt.close() - - except IOError, e: - self.logError(e) - return - - self.logger.debug("save tiff") - self.image.save(tmpTif.name, 'TIFF') - - if os.name == "nt": - tessparams = [os.path.join(pypath, "tesseract", "tesseract.exe")] - else: - tessparams = ["tesseract"] - - tessparams.extend( [os.path.abspath(tmpTif.name), os.path.abspath(tmpTxt.name).replace(".txt", "")] ) - - if subset and (digits or lowercase or uppercase): - #tmpSub = tempfile.NamedTemporaryFile(suffix=".subset") - with open(save_join("tmp", "tmpSub_%s.subset" % self.__name__), "wb") as tmpSub: - tmpSub.write("tessedit_char_whitelist ") - - if digits: - tmpSub.write("0123456789") - if lowercase: - tmpSub.write("abcdefghijklmnopqrstuvwxyz") - if uppercase: - tmpSub.write("ABCDEFGHIJKLMNOPQRSTUVWXYZ") - - tmpSub.write("\n") - tessparams.append("nobatch") - tessparams.append(os.path.abspath(tmpSub.name)) - - self.logger.debug("run tesseract") - self.run(tessparams) - self.logger.debug("read txt") - - try: - with open(tmpTxt.name, 'r') as f: - self.result_captcha = f.read().replace("\n", "") - except Exception: - self.result_captcha = "" - - self.logger.debug(self.result_captcha) - try: - os.remove(tmpTif.name) - os.remove(tmpTxt.name) - if subset and (digits or lowercase or uppercase): - os.remove(tmpSub.name) - except Exception: - pass - - - def get_captcha(self, name): - raise NotImplementedError - - - def to_greyscale(self): - if self.image.mode != 'L': - self.image = self.image.convert('L') - - self.pixels = self.image.load() - - - def eval_black_white(self, limit): - self.pixels = self.image.load() - w, h = self.image.size - for x in xrange(w): - for y in xrange(h): - if self.pixels[x, y] > limit: - self.pixels[x, y] = 255 - else: - self.pixels[x, y] = 0 - - - def clean(self, allowed): - pixels = self.pixels - - w, h = self.image.size - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 255: - continue - # No point in processing white pixels since we only want to remove black pixel - count = 0 - - try: - if pixels[x-1, y-1] != 255: - count += 1 - if pixels[x-1, y] != 255: - count += 1 - if pixels[x-1, y + 1] != 255: - count += 1 - if pixels[x, y + 1] != 255: - count += 1 - if pixels[x + 1, y + 1] != 255: - count += 1 - if pixels[x + 1, y] != 255: - count += 1 - if pixels[x + 1, y-1] != 255: - count += 1 - if pixels[x, y-1] != 255: - count += 1 - except Exception: - pass - - # not enough neighbors are dark pixels so mark this pixel - # to be changed to white - if count < allowed: - pixels[x, y] = 1 - - # second pass: this time set all 1's to 255 (white) - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 1: - pixels[x, y] = 255 - - self.pixels = pixels - - - def derotate_by_average(self): - """rotate by checking each angle and guess most suitable""" - - w, h = self.image.size - pixels = self.pixels - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 155 - - highest = {} - counts = {} - - for angle in xrange(-45, 45): - - tmpimage = self.image.rotate(angle) - - pixels = tmpimage.load() - - w, h = self.image.size - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 255 - - - count = {} - - for x in xrange(w): - count[x] = 0 - for y in xrange(h): - if pixels[x, y] == 155: - count[x] += 1 - - sum = 0 - cnt = 0 - - for x in count.values(): - if x != 0: - sum += x - cnt += 1 - - avg = sum / cnt - counts[angle] = cnt - highest[angle] = 0 - for x in count.values(): - if x > highest[angle]: - highest[angle] = x - - highest[angle] = highest[angle] - avg - - hkey = 0 - hvalue = 0 - - for key, value in highest.iteritems(): - if value > hvalue: - hkey = key - hvalue = value - - self.image = self.image.rotate(hkey) - pixels = self.image.load() - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 255 - - if pixels[x, y] == 155: - pixels[x, y] = 0 - - self.pixels = pixels - - - def split_captcha_letters(self): - captcha = self.image - started = False - letters = [] - width, height = captcha.size - bottomY, topY = 0, height - pixels = captcha.load() - - for x in xrange(width): - black_pixel_in_col = False - for y in xrange(height): - if pixels[x, y] != 255: - if not started: - started = True - firstX = x - lastX = x - - if y > bottomY: - bottomY = y - if y < topY: - topY = y - if x > lastX: - lastX = x - - black_pixel_in_col = True - - if black_pixel_in_col is False and started is True: - rect = (firstX, topY, lastX, bottomY) - new_captcha = captcha.crop(rect) - - w, h = new_captcha.size - if w > 5 and h > 5: - letters.append(new_captcha) - - started = False - bottomY, topY = 0, height - - return letters - - - def correct(self, values, var=None): - if var: - result = var - else: - result = self.result_captcha - - for key, item in values.iteritems(): - - if key.__class__ == str: - result = result.replace(key, item) - else: - for expr in key: - result = result.replace(expr, item) - - if var: - return result - else: - self.result_captcha = result diff --git a/module/plugins/crypter/DailymotionComFolder.py b/module/plugins/crypter/DailymotionComFolder.py deleted file mode 100644 index 5c078000a..000000000 --- a/module/plugins/crypter/DailymotionComFolder.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from urlparse import urljoin - -from module.common.json_layer import json_loads -from module.plugins.Crypter import Crypter -from module.utils import save_join - - -class DailymotionComFolder(Crypter): - __name__ = "DailymotionComFolder" - __type__ = "crypter" - __version__ = "0.01" - - __pattern__ = r'https?://(?:www\.)?dailymotion\.com/((playlists/)?(?Pplaylist|user)/)?(?P[\w^_]+)(?(TYPE)|#)' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), - ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] - - __description__ = """Dailymotion.com channel & playlist decrypter""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - def api_response(self, ref, req=None): - url = urljoin("https://api.dailymotion.com/", ref) - html = self.load(url, get=req) - return json_loads(html) - - - def getPlaylistInfo(self, id): - ref = "playlist/" + id - req = {"fields": "name,owner.screenname"} - playlist = self.api_response(ref, req) - - if "error" in playlist: - return - - name = playlist['name'] - owner = playlist['owner.screenname'] - return name, owner - - - def _getPlaylists(self, user_id, page=1): - ref = "user/%s/playlists" % user_id - req = {"fields": "id", "page": page, "limit": 100} - user = self.api_response(ref, req) - - if "error" in user: - return - - for playlist in user['list']: - yield playlist['id'] - - if user['has_more']: - for item in self._getPlaylists(user_id, page + 1): - yield item - - - def getPlaylists(self, user_id): - return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)] - - - def _getVideos(self, id, page=1): - ref = "playlist/%s/videos" % id - req = {"fields": "url", "page": page, "limit": 100} - playlist = self.api_response(ref, req) - - if "error" in playlist: - return - - for video in playlist['list']: - yield video['url'] - - if playlist['has_more']: - for item in self._getVideos(id, page + 1): - yield item - - - def getVideos(self, playlist_id): - return list(self._getVideos(playlist_id))[::-1] - - - def decrypt(self, pyfile): - m = re.match(self.__pattern__, pyfile.url) - m_id = m.group('ID') - m_type = m.group('TYPE') - - if m_type == "playlist": - self.logDebug("Url recognized as Playlist") - p_info = self.getPlaylistInfo(m_id) - playlists = [(m_id,) + p_info] if p_info else None - else: - self.logDebug("Url recognized as Channel") - playlists = self.getPlaylists(m_id) - self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id)) - - if not playlists: - self.fail(_("No playlist available")) - - for p_id, p_name, p_owner in playlists: - p_videos = self.getVideos(p_id) - p_folder = save_join(self.config['general']['download_folder'], p_owner, p_name) - self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) - self.packages.append((p_name, p_videos, p_folder)) #: folder is NOT recognized by pyload 0.4.9! diff --git a/module/plugins/crypter/YoutubeComFolder.py b/module/plugins/crypter/YoutubeComFolder.py deleted file mode 100644 index d7ca494fa..000000000 --- a/module/plugins/crypter/YoutubeComFolder.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from urlparse import urljoin - -from module.common.json_layer import json_loads -from module.plugins.Crypter import Crypter -from module.utils import save_join - - -class YoutubeComFolder(Crypter): - __name__ = "YoutubeComFolder" - __type__ = "crypter" - __version__ = "1.01" - - __pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?Puser|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P[\w-]+)' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ), - ("subfolder_per_pack", "bool", "Create a subfolder for each package", True ), - ("likes" , "bool", "Grab user (channel) liked videos" , False), - ("favorites" , "bool", "Grab user (channel) favorite videos", False), - ("uploads" , "bool", "Grab channel unplaylisted videos" , True )] - - __description__ = """Youtube.com channel & playlist decrypter plugin""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0" - - - def api_response(self, ref, req): - req.update({"key": self.API_KEY}) - url = urljoin("https://www.googleapis.com/youtube/v3/", ref) - html = self.load(url, get=req) - return json_loads(html) - - - def getChannel(self, user): - channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"}) - if channels['items']: - channel = channels['items'][0] - return {"id": channel['id'], - "title": channel['snippet']['title'], - "relatedPlaylists": channel['contentDetails']['relatedPlaylists'], - "user": user} # One lone channel for user? - - - def getPlaylist(self, p_id): - playlists = self.api_response("playlists", {"part": "snippet", "id": p_id}) - if playlists['items']: - playlist = playlists['items'][0] - return {"id": p_id, - "title": playlist['snippet']['title'], - "channelId": playlist['snippet']['channelId'], - "channelTitle": playlist['snippet']['channelTitle']} - - - def _getPlaylists(self, id, token=None): - req = {"part": "id", "maxResults": "50", "channelId": id} - if token: - req.update({"pageToken": token}) - - playlists = self.api_response("playlists", req) - - for playlist in playlists['items']: - yield playlist['id'] - - if "nextPageToken" in playlists: - for item in self._getPlaylists(id, playlists['nextPageToken']): - yield item - - - def getPlaylists(self, ch_id): - return map(self.getPlaylist, self._getPlaylists(ch_id)) - - - def _getVideosId(self, id, token=None): - req = {"part": "contentDetails", "maxResults": "50", "playlistId": id} - if token: - req.update({"pageToken": token}) - - playlist = self.api_response("playlistItems", req) - - for item in playlist['items']: - yield item['contentDetails']['videoId'] - - if "nextPageToken" in playlist: - for item in self._getVideosId(id, playlist['nextPageToken']): - yield item - - - def getVideosId(self, p_id): - return list(self._getVideosId(p_id)) - - - def decrypt(self, pyfile): - m = re.match(self.__pattern__, pyfile.url) - m_id = m.group('ID') - m_type = m.group('TYPE') - - if m_type == "user": - self.logDebug("Url recognized as Channel") - user = m_id - channel = self.getChannel(user) - - if channel: - playlists = self.getPlaylists(channel['id']) - self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title'])) - - relatedplaylist = {p_name: self.getPlaylist(p_id) for p_name, p_id in channel['relatedPlaylists'].iteritems()} - self.logDebug("Channel's related playlists found = %s" % relatedplaylist.keys()) - - relatedplaylist['uploads']['title'] = "Unplaylisted videos" - relatedplaylist['uploads']['checkDups'] = True #: checkDups flag - - for p_name, p_data in relatedplaylist.iteritems(): - if self.getConfig(p_name): - p_data['title'] += " of " + user - playlists.append(p_data) - else: - playlists = [] - else: - self.logDebug("Url recognized as Playlist") - playlists = [self.getPlaylist(m_id)] - - if not playlists: - self.fail(_("No playlist available")) - - addedvideos = [] - urlize = lambda x: "https://www.youtube.com/watch?v=" + x - for p in playlists: - p_name = p['title'] - p_videos = self.getVideosId(p['id']) - p_folder = save_join(self.config['general']['download_folder'], p['channelTitle'], p_name) - self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) - - if not p_videos: - continue - elif "checkDups" in p: - p_urls = [urlize(v_id) for v_id in p_videos if v_id not in addedvideos] - self.logDebug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name)) - else: - p_urls = map(urlize, p_videos) - - self.packages.append((p_name, p_urls, p_folder)) #: folder is NOT recognized by pyload 0.4.9! - - addedvideos.extend(p_videos) diff --git a/module/plugins/hooks/AntiVirus.py b/module/plugins/hooks/AntiVirus.py deleted file mode 100644 index cc3c5c754..000000000 --- a/module/plugins/hooks/AntiVirus.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import shutil -import subprocess - -from module.plugins.Hook import Hook, Expose, threaded -from module.utils import fs_encode, save_join - - -class AntiVirus(Hook): - __name__ = "AntiVirus" - __type__ = "hook" - __version__ = "0.05" - - #@TODO: add trash option (use Send2Trash lib) - __config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"), - ("quardir" , "folder" , "Quarantine folder" , "" ), - ("scanfailed", "bool" , "Scan incompleted files (failed downloads)", False ), - ("cmdfile" , "file" , "Antivirus executable" , "" ), - ("cmdargs" , "str" , "Scan options" , "" ), - ("ignore-err", "bool" , "Ignore scan errors" , False )] - - __description__ = """Scan downloaded files with antivirus program""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - - @Expose - @threaded - def scan(self, pyfile, thread): - file = fs_encode(pyfile.plugin.lastDownload) - filename = os.path.basename(pyfile.plugin.lastDownload) - cmdfile = fs_encode(self.getConfig('cmdfile')) - cmdargs = fs_encode(self.getConfig('cmdargs').strip()) - - if not os.path.isfile(file) or not os.path.isfile(cmdfile): - return - - thread.addActive(pyfile) - pyfile.setCustomStatus(_("virus scanning")) - - try: - p = subprocess.Popen([cmdfile, cmdargs, file], bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - out, err = map(str.strip, p.communicate()) - - if out: - self.logInfo(filename, out) - - if err: - self.logWarning(filename, err) - if not self.getConfig('ignore-err'): - self.logDebug("Delete/Quarantine task is aborted") - return - - if p.returncode: - pyfile.error = _("infected file") - action = self.getConfig('action') - try: - if action == "Delete": - os.remove(file) - - elif action == "Quarantine": - pyfile.setCustomStatus(_("file moving")) - pyfile.setProgress(0) - shutil.move(file, self.getConfig('quardir')) - - except (IOError, shutil.Error), e: - self.logError(filename, action + " action failed!", e) - - elif not out and not err: - self.logDebug(filename, "No infected file found") - - finally: - pyfile.setProgress(100) - thread.finishFile(pyfile) - - - def downloadFinished(self, pyfile): - return self.scan(pyfile) - - - def downloadFailed(self, pyfile): - #: Check if pyfile is still "failed", - # maybe might has been restarted in meantime - if pyfile.status == 8 and self.getConfig('scanfailed'): - return self.scan(pyfile) diff --git a/module/plugins/hooks/MegaRapidoNet.py b/module/plugins/hooks/MegaRapidoNet.py deleted file mode 100644 index fb5e77994..000000000 --- a/module/plugins/hooks/MegaRapidoNet.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- - -import re - -from module.plugins.internal.MultiHook import MultiHook - - -class MegaRapidoNet(MultiHook): - __name__ = "MegaRapidoNet" - __type__ = "hook" - __version__ = "0.02" - - __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), - ("pluginlist" , "str" , "Plugin list (comma separated)", "" ), - ("reload" , "bool" , "Reload plugin list" , True ), - ("reloadinterval", "int" , "Reload interval in hours" , 12 )] - - __description__ = """MegaRapido.net hook plugin""" - __license__ = "GPLv3" - __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] - - - def getHosters(self): - hosters = {'1fichier' : [],#leave it there are so many possible addresses? - '1st-files' : ['1st-files.com'], - '2shared' : ['2shared.com'], - '4shared' : ['4shared.com', '4shared-china.com'], - 'asfile' : ['http://asfile.com/'], - 'bitshare' : ['bitshare.com'], - 'brupload' : ['brupload.net'], - 'crocko' : ['crocko.com','easy-share.com'], - 'dailymotion' : ['dailymotion.com'], - 'depfile' : ['depfile.com'], - 'depositfiles': ['depositfiles.com', 'dfiles.eu'], - 'dizzcloud' : ['dizzcloud.com'], - 'dl.dropbox' : [], - 'extabit' : ['extabit.com'], - 'extmatrix' : ['extmatrix.com'], - 'facebook' : [], - 'file4go' : ['file4go.com'], - 'filecloud' : ['filecloud.io','ifile.it','mihd.net'], - 'filefactory' : ['filefactory.com'], - 'fileom' : ['fileom.com'], - 'fileparadox' : ['fileparadox.in'], - 'filepost' : ['filepost.com', 'fp.io'], - 'filerio' : ['filerio.in','filerio.com','filekeen.com'], - 'filesflash' : ['filesflash.com'], - 'firedrive' : ['firedrive.com', 'putlocker.com'], - 'flashx' : [], - 'freakshare' : ['freakshare.net', 'freakshare.com'], - 'gigasize' : ['gigasize.com'], - 'hipfile' : ['hipfile.com'], - 'junocloud' : ['junocloud.me'], - 'letitbit' : ['letitbit.net','shareflare.net'], - 'mediafire' : ['mediafire.com'], - 'mega' : ['mega.co.nz'], - 'megashares' : ['megashares.com'], - 'metacafe' : ['metacafe.com'], - 'netload' : ['netload.in'], - 'oboom' : ['oboom.com'], - 'rapidgator' : ['rapidgator.net'], - 'rapidshare' : ['rapidshare.com'], - 'rarefile' : ['rarefile.net'], - 'ryushare' : ['ryushare.com'], - 'sendspace' : ['sendspace.com'], - 'turbobit' : ['turbobit.net', 'unextfiles.com'], - 'uploadable' : ['uploadable.ch'], - 'uploadbaz' : ['uploadbaz.com'], - 'uploaded' : ['uploaded.to', 'uploaded.net', 'ul.to'], - 'uploadhero' : ['uploadhero.com'], - 'uploading' : ['uploading.com'], - 'uptobox' : ['uptobox.com'], - 'xvideos' : ['xvideos.com'], - 'youtube' : ['youtube.com']} - - hoster_list = [] - - for item in hosters.itervalues(): - hoster_list.extend(item) - - return hoster_list diff --git a/module/plugins/hoster/MegaRapidoNet.py b/module/plugins/hoster/MegaRapidoNet.py deleted file mode 100644 index b38374646..000000000 --- a/module/plugins/hoster/MegaRapidoNet.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -from random import randint - -from module.plugins.internal.MultiHoster import MultiHoster - - -def random_with_N_digits(n): - rand = "0." - not_zero = 0 - for i in range(1,n+1): - r = randint(0,9) - if(r > 0): - not_zero += 1 - rand += str(r) - - if not_zero > 0: - return rand - else: - return random_with_N_digits(n) - - -class MegaRapidoNet(MultiHoster): - __name__ = "MegaRapidoNet" - __type__ = "hoster" - __version__ = "0.02" - - __pattern__ = r'http://(?:www\.)?\w+\.megarapido\.net/\?file=\w+' - __config__ = [("use_premium", "bool", "Use premium account if available", True)] - - __description__ = """MegaRapido.net multi-hoster plugin""" - __license__ = "GPLv3" - __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] - - - LINK_PREMIUM_PATTERN = r'<\s*?a[^>]*?title\s*?=\s*?["\'][^"\']*?download["\'][^>]*?href=["\']([^"\']*)' - - ERROR_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']?alert-message error[^>]*>([^<]*)' - - - def handlePremium(self, pyfile): - self.html = self.load("http://megarapido.net/gerar.php", - post={'rand' :random_with_N_digits(16), - 'urllist' : pyfile.url, - 'links' : pyfile.url, - 'exibir' : "normal", - 'usar' : "premium", - 'user' : self.account.getAccountInfo(self.user).get('sid', None), - 'autoreset': ""}) - - if "desloga e loga novamente para gerar seus links" in self.html.lower(): - self.error("You have logged in at another place") - - return super(MegaRapidoNet, self).handlePremium(pyfile) diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py deleted file mode 100644 index fcb8f0095..000000000 --- a/module/plugins/internal/CaptchaService.py +++ /dev/null @@ -1,526 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from base64 import b64encode -from random import random, randint -from urlparse import urljoin, urlparse - -from module.common.json_layer import json_loads -from module.plugins.Plugin import Base - - -#@TODO: Extend (new) Plugin class; remove all `html` args -class CaptchaService(Base): - __name__ = "CaptchaService" - __type__ = "captcha" - __version__ = "0.25" - - __description__ = """Base captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - key = None #: last key detected - - - def __init__(self, plugin): - self.plugin = plugin - super(CaptchaService, self).__init__(plugin.core) - - - def detect_key(self, html=None): - raise NotImplementedError - - - def challenge(self, key=None, html=None): - raise NotImplementedError - - - def result(self, server, challenge): - raise NotImplementedError - - -class ReCaptcha(CaptchaService): - __name__ = "ReCaptcha" - __type__ = "captcha" - __version__ = "0.14" - - __description__ = """ReCaptcha captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org"), - ("Walter Purcaro", "vuolter@gmail.com"), - ("zapp-brannigan", "fuerst.reinje@web.de")] - - - KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)' - KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("ReCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html) - if m: - self.key = m.group(1).strip() - self.logDebug("Key: %s" % self.key) - return self.key - else: - self.logDebug("Key not found") - return None - - - def challenge(self, key=None, html=None, version=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("ReCaptcha key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - if version in (1, 2): - return getattr(self, "_challenge_v%s" % version)(key) - - elif not html and hasattr(self.plugin, "html") and self.plugin.html: - version = 2 if re.search(self.KEY_V2_PATTERN, self.plugin.html) else 1 - return self.challenge(key, self.plugin.html, version) - - else: - errmsg = _("ReCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - - def _challenge_v1(self, key): - html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", - get={'k': key}) - try: - challenge = re.search("challenge : '(.+?)',", html).group(1) - server = re.search("server : '(.+?)',", html).group(1) - - except AttributeError: - errmsg = _("ReCaptcha challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(server, challenge), challenge - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha("%simage" % server, - get={'c': challenge}, - cookies=True, - forceUser=True, - imgtype="jpg") - - self.logDebug("Result: %s" % result) - - return result - - - def _collectApiInfo(self): - html = self.plugin.req.load("http://www.google.com/recaptcha/api.js") - a = re.search(r'po.src = \'(.*?)\';', html).group(1) - vers = a.split("/")[5] - - self.logDebug("API version: %s" %vers) - - language = a.split("__")[1].split(".")[0] - - self.logDebug("API language: %s" % language) - - html = self.plugin.req.load("https://apis.google.com/js/api.js") - b = re.search(r'"h":"(.*?)","', html).group(1) - jsh = b.decode('unicode-escape') - - self.logDebug("API jsh-string: %s" % jsh) - - return vers, language, jsh - - - def _prepareTimeAndRpc(self): - self.plugin.req.load("http://www.google.com/recaptcha/api2/demo") - - millis = int(round(time.time() * 1000)) - - self.logDebug("Time: %s" % millis) - - rand = randint(1, 99999999) - a = "0.%s" % str(rand * 2147483647) - rpc = int(100000000 * float(a)) - - self.logDebug("Rpc-token: %s" % rpc) - - return millis, rpc - - - def _challenge_v2(self, key, parent=None): - if parent is None: - try: - parent = urljoin("http://", urlparse(self.plugin.pyfile.url).netloc) - - except Exception: - parent = "" - - botguardstring = "!A" - vers, language, jsh = self._collectApiInfo() - millis, rpc = self._prepareTimeAndRpc() - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor", - get={'k' : key, - 'hl' : language, - 'v' : vers, - 'usegapi' : "1", - 'jsh' : "%s#id=IO_%s" % (jsh, millis), - 'parent' : parent, - 'pfname' : "", - 'rpctoken': rpc}) - - token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html) - self.logDebug("Token #1: %s" % token1.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", - get={'c' : token1.group(1), - 'hl' : language, - 'v' : vers, - 'bg' : botguardstring, - 'k' : key, - 'usegapi': "1", - 'jsh' : jsh}).decode('unicode-escape') - - token2 = re.search(r'"finput","(.*?)",', html) - self.logDebug("Token #2: %s" % token2.group(1)) - - token3 = re.search(r'."asconf".\s,".*?".\s,"(.*?)".', html) - self.logDebug("Token #3: %s" % token3.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload", - post={'k' : key, - 'c' : token2.group(1), - 'reason': "fi", - 'fbg' : token3.group(1)}) - - token4 = re.search(r'"rresp","(.*?)",', html) - self.logDebug("Token #4: %s" % token4.group(1)) - - millis_captcha_loading = int(round(time.time() * 1000)) - captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", - get={'c':token4.group(1), 'k':key}, - cookies=True, - forceUser=True) - response = b64encode('{"response":"%s"}' % captcha_response) - - self.logDebug("Result: %s" % response) - - timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading - timeToSolveMore = timeToSolve + int(float("0." + str(randint(1, 99999999))) * 500) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", - post={'k' : key, - 'c' : token4.group(1), - 'response': response, - 't' : timeToSolve, - 'ct' : timeToSolveMore, - 'bg' : botguardstring}) - - token5 = re.search(r'"uvresp","(.*?)",', html) - self.logDebug("Token #5: %s" % token5.group(1)) - - result = token5.group(1) - - return result, None - - -class AdsCaptcha(CaptchaService): - __name__ = "AdsCaptcha" - __type__ = "captcha" - __version__ = "0.08" - - __description__ = """AdsCaptcha captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - CAPTCHAID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*CaptchaId=(\d+)' - PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*PublicKey=([\w-]+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("AdsCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.PUBLICKEY_PATTERN, html) - n = re.search(self.CAPTCHAID_PATTERN, html) - if m and n: - self.key = (m.group(1).strip(), n.group(1).strip()) #: key is the tuple(PublicKey, CaptchaId) - self.logDebug("Key|id: %s | %s" % self.key) - return self.key - else: - self.logDebug("Key or id not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("AdsCaptcha key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - PublicKey, CaptchaId = key - - html = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", - get={'CaptchaId': CaptchaId, - 'PublicKey': PublicKey}) - try: - challenge = re.search("challenge: '(.+?)',", html).group(1) - server = re.search("server: '(.+?)',", html).group(1) - - except AttributeError: - errmsg = _("AdsCaptcha challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(server, challenge), challenge - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server, - get={'cid': challenge, 'dummy': random()}, - cookies=True, - imgtype="jpg") - - self.logDebug("Result: %s" % result) - - return result - - -class SolveMedia(CaptchaService): - __name__ = "SolveMedia" - __type__ = "captcha" - __version__ = "0.12" - - __description__ = """SolveMedia captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("SolveMedia html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.KEY_PATTERN, html) - if m: - self.key = m.group(1).strip() - self.logDebug("Key: %s" % self.key) - return self.key - else: - self.logDebug("Key not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("SolveMedia key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript", - get={'k': key}) - try: - challenge = re.search(r'', - html).group(1) - server = "http://api.solvemedia.com/papi/media" - - except AttributeError: - errmsg = _("SolveMedia challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - result = self.result(server, challenge) - - try: - magic = re.search(r'name="magic" value="(.+?)"', html).group(1) - - except AttributeError: - self.logDebug("Magic code not found") - - else: - if not self._verify(key, magic, result, challenge): - self.logDebug("Captcha code was invalid") - - return result, challenge - - - def _verify(self, key, magic, result, challenge, ref=None): #@TODO: Clean up - if ref is None: - try: - ref = self.plugin.pyfile.url - - except Exception: - ref = "" - - html = self.plugin.req.load("http://api.solvemedia.com/papi/verify.noscript", - post={'adcopy_response' : result, - 'k' : key, - 'l' : "en", - 't' : "img", - 's' : "standard", - 'magic' : magic, - 'adcopy_challenge' : challenge, - 'ref' : ref}) - try: - html = self.plugin.req.load(re.search(r'URL=(.+?)">', html).group(1)) - gibberish = re.search(r'id=gibberish>(.+?)', html).group(1) - - except Exception: - return False - - else: - return True - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha(server, - get={'c': challenge}, - cookies=True, - imgtype="gif") - - self.logDebug("Result: %s" % result) - - return result - - -class AdYouLike(CaptchaService): - __name__ = "AdYouLike" - __type__ = "captcha" - __version__ = "0.05" - - __description__ = """AdYouLike captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - AYL_PATTERN = r'Adyoulike\.create\s*\((.+?)\)' - CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("AdYouLike html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.AYL_PATTERN, html) - n = re.search(self.CALLBACK_PATTERN, html) - if m and n: - self.key = (m.group(1).strip(), n.group(1).strip()) - self.logDebug("Ayl|callback: %s | %s" % self.key) - return self.key #: key is the tuple(ayl, callback) - else: - self.logDebug("Ayl or callback not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("AdYouLike key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - ayl, callback = key - - # {"adyoulike":{"key":"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"}, - # "all":{"element_id":"ayl_private_cap_92300","lang":"fr","env":"prod"}} - ayl = json_loads(ayl) - - html = self.plugin.req.load("http://api-ayl.appspot.com/challenge", - get={'key' : ayl['adyoulike']['key'], - 'env' : ayl['all']['env'], - 'callback': callback}) - try: - challenge = json_loads(re.search(callback + r'\s*\((.+?)\)', html).group(1)) - - except AttributeError: - errmsg = _("AdYouLike challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(ayl, challenge), challenge - - - def result(self, server, challenge): - # Adyoulike.g._jsonp_5579316662423138 - # ({"translations":{"fr":{"instructions_visual":"Recopiez « Soonnight » ci-dessous :"}}, - # "site_under":true,"clickable":true,"pixels":{"VIDEO_050":[],"DISPLAY":[],"VIDEO_000":[],"VIDEO_100":[], - # "VIDEO_025":[],"VIDEO_075":[]},"medium_type":"image/adyoulike", - # "iframes":{"big":""},"shares":{},"id":256, - # "token":"e6QuI4aRSnbIZJg02IsV6cp4JQ9~MjA1","formats":{"small":{"y":300,"x":0,"w":300,"h":60}, - # "big":{"y":0,"x":0,"w":300,"h":250},"hover":{"y":440,"x":0,"w":300,"h":60}}, - # "tid":"SqwuAdxT1EZoi4B5q0T63LN2AkiCJBg5"}) - - if isinstance(server, basestring): - server = json_loads(server) - - if isinstance(challenge, basestring): - challenge = json_loads(challenge) - - try: - instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] - result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() - - except AttributeError: - errmsg = _("AdYouLike result not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - result = {'_ayl_captcha_engine' : "adyoulike", - '_ayl_env' : server['all']['env'], - '_ayl_tid' : challenge['tid'], - '_ayl_token_challenge': challenge['token'], - '_ayl_response' : response} - - self.logDebug("Result: %s" % result) - - return result diff --git a/pyload/plugin/Addon.py b/pyload/plugin/Addon.py index dc07a2513..14b5ee2a5 100644 --- a/pyload/plugin/Addon.py +++ b/pyload/plugin/Addon.py @@ -76,11 +76,9 @@ class Addon(Base): self.setup() - # self.initPeriodical() - def initPeriodical(self, delay=0, threaded=False): - self.cb = self.core.scheduler.addJob(delay, self._periodical, args=[threaded], threaded=threaded) + self.cb = self.core.scheduler.addJob(max(0, delay), self._periodical, args=[threaded], threaded=threaded) def _periodical(self, threaded): diff --git a/pyload/plugin/Captcha.py b/pyload/plugin/Captcha.py index 383eedac8..d7a506979 100644 --- a/pyload/plugin/Captcha.py +++ b/pyload/plugin/Captcha.py @@ -19,7 +19,7 @@ class Captcha(Base): def __init__(self, plugin): self.plugin = plugin self.key = None #: last key detected - super(CaptchaService, self).__init__(plugin.core) + super(Captcha, self).__init__(plugin.core) def detect_key(self, html=None): diff --git a/pyload/plugin/account/Keep2ShareCc.py b/pyload/plugin/account/Keep2ShareCc.py index 7ed15dc62..a3cc2c40d 100644 --- a/pyload/plugin/account/Keep2ShareCc.py +++ b/pyload/plugin/account/Keep2ShareCc.py @@ -1,32 +1,32 @@ # -*- coding: utf-8 -*- import re - -from time import gmtime, mktime, strptime +import time from pyload.plugin.Account import Account -class Keep2shareCc(Account): - __name__ = "Keep2shareCc" +class Keep2ShareCc(Account): + __name__ = "Keep2ShareCc" __type__ = "account" - __version__ = "0.02" + __version__ = "0.05" - __description__ = """Keep2share.cc account plugin""" + __description__ = """Keep2Share.cc account plugin""" __license__ = "GPLv3" - __authors__ = [("aeronaut", "aeronaut@pianoguy.de")] + __authors__ = [("aeronaut", "aeronaut@pianoguy.de"), + ("Walter Purcaro", "vuolter@gmail.com")] - VALID_UNTIL_PATTERN = r'Premium expires: (.+?)' - TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):(.+?)' + VALID_UNTIL_PATTERN = r'Premium expires:\s*(.+?)<' + TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*(.+?)<' LOGIN_FAIL_PATTERN = r'Please fix the following input errors' def loadAccountInfo(self, user, req): validuntil = None - trafficleft = None - premium = None + trafficleft = -1 + premium = False html = req.load("http://keep2share.cc/site/profile.html", decode=True) @@ -35,26 +35,26 @@ class Keep2shareCc(Account): expiredate = m.group(1).strip() self.logDebug("Expire date: " + expiredate) - try: - validuntil = mktime(strptime(expiredate, "%Y.%m.%d")) + if expiredate == "LifeTime": + premium = True + validuntil = -1 + else: + try: + validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d")) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) - else: - if validuntil > mktime(gmtime()): - premium = True else: - premium = False - validuntil = None + premium = True if validuntil > time.mktime(time.gmtime()) else False - m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: - try: - trafficleft = self.parseTraffic(m.group(1)) + m = re.search(self.TRAFFIC_LEFT_PATTERN, html) + if m: + try: + trafficleft = self.parseTraffic(m.group(1)) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} @@ -63,7 +63,11 @@ class Keep2shareCc(Account): req.cj.setCookie("keep2share.cc", "lang", "en") html = req.load("http://keep2share.cc/login.html", - post={'LoginForm[username]': user, 'LoginForm[password]': data['password']}) + post={'LoginForm[username]' : user, + 'LoginForm[password]' : data['password'], + 'LoginForm[rememberMe]': 1, + 'yt0' : ""}, + decode=True) if re.search(self.LOGIN_FAIL_PATTERN, html): self.wrongPassword() diff --git a/pyload/plugin/account/MegaRapidoNet.py b/pyload/plugin/account/MegaRapidoNet.py new file mode 100644 index 000000000..22979a09a --- /dev/null +++ b/pyload/plugin/account/MegaRapidoNet.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +import re +import time + +from pyload.plugin.Account import Account + + +class MegaRapidoNet(Account): + __name__ = "MegaRapidoNet" + __type__ = "account" + __version__ = "0.02" + + __description__ = """MegaRapido.net account plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + VALID_UNTIL_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?[\'"]premium_index[\'"][^>]*>[^<]*?<[^>]*?b[^>]*>\s*?TEMPO\s*?PREMIUM[^<]*<[^>]*?/b[^>]*>\s*?(\d*)[^\d]*?DIAS[^\d]*?(\d*)[^\d]*?HORAS[^\d]*?(\d*)[^\d]*?MINUTOS[^\d]*?(\d*)[^\d]*?SEGUNDOS' + USER_ID_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']checkbox_compartilhar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']usar["\'][^>]*>[^<]*<\s*?input[^>]*?name\s*?=\s*?["\']user["\'][^>]*?value\s*?=\s*?["\'](.*?)\s*?["\']' + + + def loadAccountInfo(self, user, req): + validuntil = None + trafficleft = None + premium = False + + html = req.load("http://megarapido.net/gerador", decode=True) + + validuntil = re.search(self.VALID_UNTIL_PATTERN, html) + if validuntil: + #hier weitermachen!!! (müssen umbedingt die zeit richtig machen damit! (sollte aber möglich)) + validuntil = time.time() + int(validuntil.group(1)) * 24 * 3600 + int(validuntil.group(2)) * 3600 + int(validuntil.group(3)) * 60 + int(validuntil.group(4)) + trafficleft = -1 + premium = True + + return {'validuntil' : validuntil, + 'trafficleft': trafficleft, + 'premium' : premium} + + + def login(self, user, data, req): + req.load("http://megarapido.net/login") + req.load("http://megarapido.net/painel_user/ajax/logar.php", + post={'login': user, 'senha': data['password']}, + decode=True) + + html = req.load("http://megarapido.net/gerador") + + if "sair" not in html.lower(): + self.wrongPassword() + else: + m = re.search(self.USER_ID_PATTERN, html) + if m: + data['uid'] = m.group(1) + else: + self.fail("Couldn't find the user ID") diff --git a/pyload/plugin/addon/AndroidPhoneNotify.py b/pyload/plugin/addon/AndroidPhoneNotify.py index 53af8aa1c..d3b390e6e 100644 --- a/pyload/plugin/addon/AndroidPhoneNotify.py +++ b/pyload/plugin/addon/AndroidPhoneNotify.py @@ -28,11 +28,9 @@ class AndroidPhoneNotify(Addon): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -44,7 +42,7 @@ class AndroidPhoneNotify(Addon): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/pyload/plugin/addon/AntiVirus.py b/pyload/plugin/addon/AntiVirus.py new file mode 100644 index 000000000..619893735 --- /dev/null +++ b/pyload/plugin/addon/AntiVirus.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +import os +import shutil +import subprocess + +from pyload.plugin.Addon import Addon, Expose, threaded +from pyload.utils import fs_encode, fs_join + + +class AntiVirus(Addon): + __name__ = "AntiVirus" + __type__ = "addon" + __version__ = "0.05" + + #@TODO: add trash option (use Send2Trash lib) + __config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"), + ("quardir" , "folder" , "Quarantine folder" , "" ), + ("scanfailed", "bool" , "Scan incompleted files (failed downloads)", False ), + ("cmdfile" , "file" , "Antivirus executable" , "" ), + ("cmdargs" , "str" , "Scan options" , "" ), + ("ignore-err", "bool" , "Ignore scan errors" , False )] + + __description__ = """Scan downloaded files with antivirus program""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + @Expose + @threaded + def scan(self, pyfile, thread): + file = fs_encode(pyfile.plugin.lastDownload) + filename = os.path.basename(pyfile.plugin.lastDownload) + cmdfile = fs_encode(self.getConfig('cmdfile')) + cmdargs = fs_encode(self.getConfig('cmdargs').strip()) + + if not os.path.isfile(file) or not os.path.isfile(cmdfile): + return + + thread.addActive(pyfile) + pyfile.setCustomStatus(_("virus scanning")) + + try: + p = subprocess.Popen([cmdfile, cmdargs, file], bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + out, err = map(str.strip, p.communicate()) + + if out: + self.logInfo(filename, out) + + if err: + self.logWarning(filename, err) + if not self.getConfig('ignore-err'): + self.logDebug("Delete/Quarantine task is aborted") + return + + if p.returncode: + pyfile.error = _("infected file") + action = self.getConfig('action') + try: + if action == "Delete": + os.remove(file) + + elif action == "Quarantine": + pyfile.setCustomStatus(_("file moving")) + pyfile.setProgress(0) + shutil.move(file, self.getConfig('quardir')) + + except (IOError, shutil.Error), e: + self.logError(filename, action + " action failed!", e) + + elif not out and not err: + self.logDebug(filename, "No infected file found") + + finally: + pyfile.setProgress(100) + thread.finishFile(pyfile) + + + def downloadFinished(self, pyfile): + return self.scan(pyfile) + + + def downloadFailed(self, pyfile): + #: Check if pyfile is still "failed", + # maybe might has been restarted in meantime + if pyfile.status == 8 and self.getConfig('scanfailed'): + return self.scan(pyfile) diff --git a/pyload/plugin/addon/Checksum.py b/pyload/plugin/addon/Checksum.py index 7ba5d7ab6..4b1380506 100644 --- a/pyload/plugin/addon/Checksum.py +++ b/pyload/plugin/addon/Checksum.py @@ -56,7 +56,6 @@ class Checksum(Addon): ("stickell" , "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 methods = {'sfv' : 'crc32', 'crc' : 'crc32', 'hash': 'md5'} @@ -72,7 +71,6 @@ class Checksum(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.algorithms = sorted( getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True) diff --git a/pyload/plugin/addon/ClickAndLoad.py b/pyload/plugin/addon/ClickAndLoad.py index 63647e30a..df8d09806 100644 --- a/pyload/plugin/addon/ClickAndLoad.py +++ b/pyload/plugin/addon/ClickAndLoad.py @@ -30,15 +30,12 @@ class ClickAndLoad(Addon): ("port" , "int" , "Port" , 9666), ("extern" , "bool", "Listen on the public network interface", True)] - __description__ = """Click'n'Load hook plugin""" + __description__ = """Click'n'Load addon plugin""" __license__ = "GPLv3" __authors__ = [("RaNaN" , "RaNaN@pyload.de" ), ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def activate(self): if not self.config['webinterface']['activated']: return diff --git a/pyload/plugin/addon/DeleteFinished.py b/pyload/plugin/addon/DeleteFinished.py index aad05891e..989271fa8 100644 --- a/pyload/plugin/addon/DeleteFinished.py +++ b/pyload/plugin/addon/DeleteFinished.py @@ -25,7 +25,6 @@ class DeleteFinished(Addon): ## overwritten methods ## def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.interval = self.MIN_CHECK_INTERVAL @@ -56,6 +55,7 @@ class DeleteFinished(Addon): # self.pluginConfigChanged(self.__name__, 'interval', interval) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60 * 60) self.addEvent('packageFinished', self.wakeup) + self.initPeriodical() ## own methods ## diff --git a/pyload/plugin/addon/DownloadScheduler.py b/pyload/plugin/addon/DownloadScheduler.py index ff65a478d..de961cc1f 100644 --- a/pyload/plugin/addon/DownloadScheduler.py +++ b/pyload/plugin/addon/DownloadScheduler.py @@ -20,14 +20,6 @@ class DownloadScheduler(Addon): ("stickell", "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded - - def activate(self): self.updateSchedule() diff --git a/pyload/plugin/addon/ExternalScripts.py b/pyload/plugin/addon/ExternalScripts.py index 139be1299..502a6dc7b 100644 --- a/pyload/plugin/addon/ExternalScripts.py +++ b/pyload/plugin/addon/ExternalScripts.py @@ -28,7 +28,6 @@ class ExternalScripts(Addon): "all_archives_extracted", "all_archives_processed", "allDownloadsFinished" , "allDownloadsProcessed" , "packageDeleted"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): @@ -65,7 +64,7 @@ class ExternalScripts(Addon): return for filename in os.listdir(dir): - file = save_join(dir, filename) + file = fs_join(dir, filename) if not os.path.isfile(file): continue @@ -102,7 +101,7 @@ class ExternalScripts(Addon): self.callScript(script) - def coreExiting(self): + def exit(self): for script in self.scripts['pyload_restart' if self.core.do_restart else 'pyload_stop']: self.callScript(script) @@ -125,23 +124,23 @@ class ExternalScripts(Addon): def downloadFailed(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_failed']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) def downloadFinished(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_finished']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) @@ -157,7 +156,7 @@ class ExternalScripts(Addon): def packageFinished(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -169,7 +168,7 @@ class ExternalScripts(Addon): pack = self.core.api.getPackageInfo(pid) if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pack.folder) else: download_folder = self.config['general']['download_folder'] @@ -179,7 +178,7 @@ class ExternalScripts(Addon): def package_extract_failed(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -189,7 +188,7 @@ class ExternalScripts(Addon): def package_extracted(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] diff --git a/pyload/plugin/addon/ExtractArchive.py b/pyload/plugin/addon/ExtractArchive.py index 3c71e7e1a..419ca609e 100644 --- a/pyload/plugin/addon/ExtractArchive.py +++ b/pyload/plugin/addon/ExtractArchive.py @@ -137,8 +137,6 @@ class ExtractArchive(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.queue = ArchiveQueue(self, "Queue") self.failed = ArchiveQueue(self, "Failed") diff --git a/pyload/plugin/addon/IRCInterface.py b/pyload/plugin/addon/IRCInterface.py index 9038ce993..6d85a5681 100644 --- a/pyload/plugin/addon/IRCInterface.py +++ b/pyload/plugin/addon/IRCInterface.py @@ -37,9 +37,6 @@ class IRCInterface(Thread, Addon): __authors__ = [("Jeix", "Jeix@hasnomail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def __init__(self, core, manager): Thread.__init__(self) Addon.__init__(self, core, manager) diff --git a/pyload/plugin/addon/JustPremium.py b/pyload/plugin/addon/JustPremium.py index e69bc24f6..b878f302d 100644 --- a/pyload/plugin/addon/JustPremium.py +++ b/pyload/plugin/addon/JustPremium.py @@ -21,11 +21,6 @@ class JustPremium(Addon): event_list = ["linksAdded"] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 def linksAdded(self, links, pid): diff --git a/pyload/plugin/addon/MergeFiles.py b/pyload/plugin/addon/MergeFiles.py index 374604d82..e0233af10 100644 --- a/pyload/plugin/addon/MergeFiles.py +++ b/pyload/plugin/addon/MergeFiles.py @@ -23,15 +23,9 @@ class MergeFiles(Addon): __authors__ = [("and9000", "me@has-no-mail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - BUFFER_SIZE = 4096 - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @threaded def packageFinished(self, pack): files = {} diff --git a/pyload/plugin/addon/MultiHome.py b/pyload/plugin/addon/MultiHome.py index 0cebf35b8..03974d6c6 100644 --- a/pyload/plugin/addon/MultiHome.py +++ b/pyload/plugin/addon/MultiHome.py @@ -17,11 +17,7 @@ class MultiHome(Addon): __authors__ = [("mkaay", "mkaay@mkaay.de")] - interval = 0 #@TODO: Remove in 0.4.10 - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.register = {} self.interfaces = [] diff --git a/pyload/plugin/addon/RestartFailed.py b/pyload/plugin/addon/RestartFailed.py index e34424a8c..c568bfb0a 100644 --- a/pyload/plugin/addon/RestartFailed.py +++ b/pyload/plugin/addon/RestartFailed.py @@ -40,3 +40,4 @@ class RestartFailed(Addon): def activate(self): # self.pluginConfigChanged(self.__name__, "interval", self.getConfig('interval')) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60) + self.initPeriodical() diff --git a/pyload/plugin/addon/RestartSlow.py b/pyload/plugin/addon/RestartSlow.py index cd503518d..34416e79a 100644 --- a/pyload/plugin/addon/RestartSlow.py +++ b/pyload/plugin/addon/RestartSlow.py @@ -22,11 +22,12 @@ class RestartSlow(Addon): event_list = ["downloadStarts"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): self.info = {'chunk': {}} + + def periodical(self): if not self.pyfile.plugin.req.dl: return @@ -36,8 +37,8 @@ class RestartSlow(Addon): limit = 5 else: type = "premium" if self.pyfile.plugin.premium else "free" - time = max(30, self.getConfig("%s_time" % type) * 60) - limit = max(5, self.getConfig("%s_limit" % type) * 1024) + time = max(30, self.getConfig('%s_time' % type) * 60) + limit = max(5, self.getConfig('%s_limit' % type) * 1024) chunks = [chunk for chunk in self.pyfile.plugin.req.dl.chunks \ if chunk.id not in self.info['chunk'] or self.info['chunk'][chunk.id] is not (time, limit)] diff --git a/pyload/plugin/addon/SkipRev.py b/pyload/plugin/addon/SkipRev.py index 157b55bbd..1c42ddfd8 100644 --- a/pyload/plugin/addon/SkipRev.py +++ b/pyload/plugin/addon/SkipRev.py @@ -6,14 +6,14 @@ from types import MethodType from urllib import unquote from urlparse import urlparse -from module.PyFile import PyFile -from module.plugins.Hook import Hook -from module.plugins.Plugin import SkipDownload +from pyload.datatype.File import PyFile +from pyload.plugin.Addon import Addon +from pyload.plugin.Plugin import SkipDownload -class SkipRev(Hook): +class SkipRev(Addon): __name__ = "SkipRev" - __type__ = "hook" + __type__ = "addon" __version__ = "0.29" __config__ = [("mode" , "Auto;Manual", "Choose recovery archives to skip" , "Auto"), @@ -24,13 +24,6 @@ class SkipRev(Hook): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @staticmethod def _setup(self): self.pyfile.plugin._setup() diff --git a/pyload/plugin/addon/UnSkipOnFail.py b/pyload/plugin/addon/UnSkipOnFail.py index 55de85082..f81066daa 100644 --- a/pyload/plugin/addon/UnSkipOnFail.py +++ b/pyload/plugin/addon/UnSkipOnFail.py @@ -16,9 +16,6 @@ class UnSkipOnFail(Addon): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def downloadFailed(self, pyfile): #: Check if pyfile is still "failed", # maybe might has been restarted in meantime diff --git a/pyload/plugin/addon/UpdateManager.py b/pyload/plugin/addon/UpdateManager.py index 643b5c2d1..cd8dc9a03 100644 --- a/pyload/plugin/addon/UpdateManager.py +++ b/pyload/plugin/addon/UpdateManager.py @@ -9,9 +9,9 @@ import time from operator import itemgetter -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join +from pyload.network.RequestFactory import getURL +from pyload.plugin.Addon import Expose, Addon, threaded +from pyload.utils import fs_join # Case-sensitive os.path.exists @@ -26,9 +26,9 @@ def exists(path): return False -class UpdateManager(Hook): +class UpdateManager(Addon): __name__ = "UpdateManager" - __type__ = "hook" + __type__ = "addon" __version__ = "0.50" __config__ = [("activated" , "bool", "Activated" , True ), @@ -43,14 +43,11 @@ class UpdateManager(Hook): __license__ = "GPLv3" __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - interval = 0 - SERVER_URL = "http://updatemanager.pyload.org" MIN_CHECK_INTERVAL = 3 * 60 * 60 #: 3 hours - def coreReady(self): + def activate(self): if self.checkonstart: self.update() @@ -189,7 +186,7 @@ class UpdateManager(Hook): # Protect UpdateManager from self-removing try: - type_plugins.remove(("hook", "UpdateManager")) + type_plugins.remove(("addon", "UpdateManager")) except ValueError: pass @@ -242,7 +239,7 @@ class UpdateManager(Hook): m = VERSION.search(content) if m and m.group(2) == version: - with open(save_join("userplugins", prefix, filename), "wb") as f: + with open(fs_join("userplugins", prefix, filename), "wb") as f: f.write(content) updated.append((prefix, name)) @@ -288,12 +285,12 @@ class UpdateManager(Hook): rootplugins = os.path.join(pypath, "module", "plugins") for dir in ("userplugins", rootplugins): - py_filename = save_join(dir, type, name + ".py") + py_filename = fs_join(dir, type, name + ".py") pyc_filename = py_filename + "c" - if type == "hook": + if type == "addon": try: - self.manager.deactivateHook(name) + self.manager.deactivateAddon(name) except Exception, e: self.logDebug(e) diff --git a/pyload/plugin/addon/WindowsPhoneNotify.py b/pyload/plugin/addon/WindowsPhoneNotify.py index e61057f9f..341e682b2 100644 --- a/pyload/plugin/addon/WindowsPhoneNotify.py +++ b/pyload/plugin/addon/WindowsPhoneNotify.py @@ -3,12 +3,12 @@ import httplib import time -from module.plugins.Hook import Hook, Expose +from pyload.plugin.Addon import Addon, Expose -class WindowsPhoneNotify(Hook): +class WindowsPhoneNotify(Addon): __name__ = "WindowsPhoneNotify" - __type__ = "hook" + __type__ = "addon" __version__ = "0.09" __config__ = [("id" , "str" , "Push ID" , "" ), @@ -29,11 +29,9 @@ class WindowsPhoneNotify(Hook): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -45,7 +43,7 @@ class WindowsPhoneNotify(Hook): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/pyload/plugin/captcha/AdYouLike.py b/pyload/plugin/captcha/AdYouLike.py index 0ff1a799b..d656acb09 100644 --- a/pyload/plugin/captcha/AdYouLike.py +++ b/pyload/plugin/captcha/AdYouLike.py @@ -8,6 +8,7 @@ from pyload.utils import json_loads class AdYouLike(Captcha): __name__ = "AdYouLike" + __type__ = "captcha" __version__ = "0.05" __description__ = """AdYouLike captcha service plugin""" diff --git a/pyload/plugin/captcha/AdsCaptcha.py b/pyload/plugin/captcha/AdsCaptcha.py index 75852e36d..5b23247c0 100644 --- a/pyload/plugin/captcha/AdsCaptcha.py +++ b/pyload/plugin/captcha/AdsCaptcha.py @@ -9,6 +9,7 @@ from pyload.plugin.Captcha import Captcha class AdsCaptcha(Captcha): __name__ = "AdsCaptcha" + __type__ = "captcha" __version__ = "0.08" __description__ = """AdsCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/ReCaptcha.py b/pyload/plugin/captcha/ReCaptcha.py index 295491bd8..62b82d1d5 100644 --- a/pyload/plugin/captcha/ReCaptcha.py +++ b/pyload/plugin/captcha/ReCaptcha.py @@ -12,6 +12,7 @@ from pyload.plugin.Captcha import Captcha class ReCaptcha(Captcha): __name__ = "ReCaptcha" + __type__ = "captcha" __version__ = "0.14" __description__ = """ReCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/SolveMedia.py b/pyload/plugin/captcha/SolveMedia.py index af45101b4..7f421f490 100644 --- a/pyload/plugin/captcha/SolveMedia.py +++ b/pyload/plugin/captcha/SolveMedia.py @@ -7,6 +7,7 @@ from pyload.plugin.Captcha import Captcha class SolveMedia(Captcha): __name__ = "SolveMedia" + __type__ = "captcha" __version__ = "0.12" __description__ = """SolveMedia captcha service plugin""" diff --git a/pyload/plugin/crypter/DailymotionComFolder.py b/pyload/plugin/crypter/DailymotionComFolder.py new file mode 100644 index 000000000..3c5000515 --- /dev/null +++ b/pyload/plugin/crypter/DailymotionComFolder.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join + + +class DailymotionComFolder(Crypter): + __name__ = "DailymotionComFolder" + __type__ = "crypter" + __version__ = "0.01" + + __pattern__ = r'https?://(?:www\.)?dailymotion\.com/((playlists/)?(?Pplaylist|user)/)?(?P[\w^_]+)(?(TYPE)|#)' + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), + ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] + + __description__ = """Dailymotion.com channel & playlist decrypter""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + def api_response(self, ref, req=None): + url = urljoin("https://api.dailymotion.com/", ref) + html = self.load(url, get=req) + return json_loads(html) + + + def getPlaylistInfo(self, id): + ref = "playlist/" + id + req = {"fields": "name,owner.screenname"} + playlist = self.api_response(ref, req) + + if "error" in playlist: + return + + name = playlist['name'] + owner = playlist['owner.screenname'] + return name, owner + + + def _getPlaylists(self, user_id, page=1): + ref = "user/%s/playlists" % user_id + req = {"fields": "id", "page": page, "limit": 100} + user = self.api_response(ref, req) + + if "error" in user: + return + + for playlist in user['list']: + yield playlist['id'] + + if user['has_more']: + for item in self._getPlaylists(user_id, page + 1): + yield item + + + def getPlaylists(self, user_id): + return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)] + + + def _getVideos(self, id, page=1): + ref = "playlist/%s/videos" % id + req = {"fields": "url", "page": page, "limit": 100} + playlist = self.api_response(ref, req) + + if "error" in playlist: + return + + for video in playlist['list']: + yield video['url'] + + if playlist['has_more']: + for item in self._getVideos(id, page + 1): + yield item + + + def getVideos(self, playlist_id): + return list(self._getVideos(playlist_id))[::-1] + + + def decrypt(self, pyfile): + m = re.match(self.__pattern__, pyfile.url) + m_id = m.group('ID') + m_type = m.group('TYPE') + + if m_type == "playlist": + self.logDebug("Url recognized as Playlist") + p_info = self.getPlaylistInfo(m_id) + playlists = [(m_id,) + p_info] if p_info else None + else: + self.logDebug("Url recognized as Channel") + playlists = self.getPlaylists(m_id) + self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id)) + + if not playlists: + self.fail(_("No playlist available")) + + for p_id, p_name, p_owner in playlists: + p_videos = self.getVideos(p_id) + p_folder = fs_join(self.config['general']['download_folder'], p_owner, p_name) + self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) + self.packages.append((p_name, p_videos, p_folder)) #: folder is NOT recognized by pyload 0.4.9! diff --git a/pyload/plugin/crypter/FilecryptCc.py b/pyload/plugin/crypter/FilecryptCc.py index c052573e1..1d8388dcd 100644 --- a/pyload/plugin/crypter/FilecryptCc.py +++ b/pyload/plugin/crypter/FilecryptCc.py @@ -10,7 +10,7 @@ from Crypto.Cipher import AES from urlparse import urljoin from pyload.plugin.Crypter import Crypter -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha class FilecryptCc(Crypter): diff --git a/pyload/plugin/crypter/YoutubeComFolder.py b/pyload/plugin/crypter/YoutubeComFolder.py new file mode 100644 index 000000000..e42615af0 --- /dev/null +++ b/pyload/plugin/crypter/YoutubeComFolder.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join + + +class YoutubeComFolder(Crypter): + __name__ = "YoutubeComFolder" + __type__ = "crypter" + __version__ = "1.01" + + __pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?Puser|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P[\w-]+)' + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ), + ("subfolder_per_pack", "bool", "Create a subfolder for each package", True ), + ("likes" , "bool", "Grab user (channel) liked videos" , False), + ("favorites" , "bool", "Grab user (channel) favorite videos", False), + ("uploads" , "bool", "Grab channel unplaylisted videos" , True )] + + __description__ = """Youtube.com channel & playlist decrypter plugin""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0" + + + def api_response(self, ref, req): + req.update({"key": self.API_KEY}) + url = urljoin("https://www.googleapis.com/youtube/v3/", ref) + html = self.load(url, get=req) + return json_loads(html) + + + def getChannel(self, user): + channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"}) + if channels['items']: + channel = channels['items'][0] + return {"id": channel['id'], + "title": channel['snippet']['title'], + "relatedPlaylists": channel['contentDetails']['relatedPlaylists'], + "user": user} # One lone channel for user? + + + def getPlaylist(self, p_id): + playlists = self.api_response("playlists", {"part": "snippet", "id": p_id}) + if playlists['items']: + playlist = playlists['items'][0] + return {"id": p_id, + "title": playlist['snippet']['title'], + "channelId": playlist['snippet']['channelId'], + "channelTitle": playlist['snippet']['channelTitle']} + + + def _getPlaylists(self, id, token=None): + req = {"part": "id", "maxResults": "50", "channelId": id} + if token: + req.update({"pageToken": token}) + + playlists = self.api_response("playlists", req) + + for playlist in playlists['items']: + yield playlist['id'] + + if "nextPageToken" in playlists: + for item in self._getPlaylists(id, playlists['nextPageToken']): + yield item + + + def getPlaylists(self, ch_id): + return map(self.getPlaylist, self._getPlaylists(ch_id)) + + + def _getVideosId(self, id, token=None): + req = {"part": "contentDetails", "maxResults": "50", "playlistId": id} + if token: + req.update({"pageToken": token}) + + playlist = self.api_response("playlistItems", req) + + for item in playlist['items']: + yield item['contentDetails']['videoId'] + + if "nextPageToken" in playlist: + for item in self._getVideosId(id, playlist['nextPageToken']): + yield item + + + def getVideosId(self, p_id): + return list(self._getVideosId(p_id)) + + + def decrypt(self, pyfile): + m = re.match(self.__pattern__, pyfile.url) + m_id = m.group('ID') + m_type = m.group('TYPE') + + if m_type == "user": + self.logDebug("Url recognized as Channel") + user = m_id + channel = self.getChannel(user) + + if channel: + playlists = self.getPlaylists(channel['id']) + self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title'])) + + relatedplaylist = {p_name: self.getPlaylist(p_id) for p_name, p_id in channel['relatedPlaylists'].iteritems()} + self.logDebug("Channel's related playlists found = %s" % relatedplaylist.keys()) + + relatedplaylist['uploads']['title'] = "Unplaylisted videos" + relatedplaylist['uploads']['checkDups'] = True #: checkDups flag + + for p_name, p_data in relatedplaylist.iteritems(): + if self.getConfig(p_name): + p_data['title'] += " of " + user + playlists.append(p_data) + else: + playlists = [] + else: + self.logDebug("Url recognized as Playlist") + playlists = [self.getPlaylist(m_id)] + + if not playlists: + self.fail(_("No playlist available")) + + addedvideos = [] + urlize = lambda x: "https://www.youtube.com/watch?v=" + x + for p in playlists: + p_name = p['title'] + p_videos = self.getVideosId(p['id']) + p_folder = fs_join(self.config['general']['download_folder'], p['channelTitle'], p_name) + self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) + + if not p_videos: + continue + elif "checkDups" in p: + p_urls = [urlize(v_id) for v_id in p_videos if v_id not in addedvideos] + self.logDebug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name)) + else: + p_urls = map(urlize, p_videos) + + self.packages.append((p_name, p_urls, p_folder)) #: folder is NOT recognized by pyload 0.4.9! + + addedvideos.extend(p_videos) diff --git a/pyload/plugin/extractor/UnRar.py b/pyload/plugin/extractor/UnRar.py index 5b9052bff..3bc4f3464 100644 --- a/pyload/plugin/extractor/UnRar.py +++ b/pyload/plugin/extractor/UnRar.py @@ -198,13 +198,13 @@ class UnRar(Extractor): if not self.fullpath and self.VERSION.startswith('5'): # NOTE: Unrar 5 always list full path for f in fs_decode(out).splitlines(): - f = save_join(self.out, os.path.basename(f.strip())) + f = fs_join(self.out, os.path.basename(f.strip())) if os.path.isfile(f): - result.add(save_join(self.out, os.path.basename(f))) + result.add(fs_join(self.out, os.path.basename(f))) else: for f in fs_decode(out).splitlines(): f = f.strip() - result.add(save_join(self.out, f)) + result.add(fs_join(self.out, f)) return list(result) diff --git a/pyload/plugin/hook/BypassCaptcha.py b/pyload/plugin/hook/BypassCaptcha.py index 786f5dff3..4579d17c5 100644 --- a/pyload/plugin/hook/BypassCaptcha.py +++ b/pyload/plugin/hook/BypassCaptcha.py @@ -40,8 +40,6 @@ class BypassCaptcha(Hook): ("zoidberg" , "zoidberg@mujmail.cz" )] - interval = 0 #@TODO: Remove in 0.4.10 - PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" SUBMIT_URL = "http://bypasscaptcha.com/upload.php" diff --git a/pyload/plugin/hook/Captcha9Kw.py b/pyload/plugin/hook/Captcha9Kw.py index 38cbb5a21..012266739 100644 --- a/pyload/plugin/hook/Captcha9Kw.py +++ b/pyload/plugin/hook/Captcha9Kw.py @@ -36,8 +36,6 @@ class Captcha9kw(Hook): ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.9kw.eu/index.cgi" diff --git a/pyload/plugin/hook/CaptchaBrotherhood.py b/pyload/plugin/hook/CaptchaBrotherhood.py index fbf2e2e29..3cbdb27d7 100644 --- a/pyload/plugin/hook/CaptchaBrotherhood.py +++ b/pyload/plugin/hook/CaptchaBrotherhood.py @@ -50,11 +50,14 @@ class CaptchaBrotherhood(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.captchabrotherhood.com/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL + "askCredits.aspx", get={"username": self.getConfig('username'), "password": self.getConfig('passkey')}) diff --git a/pyload/plugin/hook/DeathByCaptcha.py b/pyload/plugin/hook/DeathByCaptcha.py index 41d4d300b..0f0e66ea2 100644 --- a/pyload/plugin/hook/DeathByCaptcha.py +++ b/pyload/plugin/hook/DeathByCaptcha.py @@ -63,11 +63,14 @@ class DeathByCaptcha(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://api.dbcapi.me/api/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def api_response(self, api="captcha", post=False, multipart=False): req = getRequest() req.c.setopt(HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version]) diff --git a/pyload/plugin/hook/ExpertDecoders.py b/pyload/plugin/hook/ExpertDecoders.py index f1096b8ed..0f86baa17 100644 --- a/pyload/plugin/hook/ExpertDecoders.py +++ b/pyload/plugin/hook/ExpertDecoders.py @@ -25,11 +25,14 @@ class ExpertDecoders(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.fasttypers.org/imagepost.ashx" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL, post={"key": self.getConfig('passkey'), "action": "balance"}) diff --git a/pyload/plugin/hook/ImageTyperz.py b/pyload/plugin/hook/ImageTyperz.py index a556b109a..a7c3389c1 100644 --- a/pyload/plugin/hook/ImageTyperz.py +++ b/pyload/plugin/hook/ImageTyperz.py @@ -44,8 +44,6 @@ class ImageTyperz(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" diff --git a/pyload/plugin/hook/MegaRapidoNet.py b/pyload/plugin/hook/MegaRapidoNet.py new file mode 100644 index 000000000..2f660c939 --- /dev/null +++ b/pyload/plugin/hook/MegaRapidoNet.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.MultiHook import MultiHook + + +class MegaRapidoNet(MultiHook): + __name__ = "MegaRapidoNet" + __type__ = "hook" + __version__ = "0.02" + + __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), + ("pluginlist" , "str" , "Plugin list (comma separated)", "" ), + ("reload" , "bool" , "Reload plugin list" , True ), + ("reloadinterval", "int" , "Reload interval in hours" , 12 )] + + __description__ = """MegaRapido.net hook plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + def getHosters(self): + hosters = {'1fichier' : [],#leave it there are so many possible addresses? + '1st-files' : ['1st-files.com'], + '2shared' : ['2shared.com'], + '4shared' : ['4shared.com', '4shared-china.com'], + 'asfile' : ['http://asfile.com/'], + 'bitshare' : ['bitshare.com'], + 'brupload' : ['brupload.net'], + 'crocko' : ['crocko.com','easy-share.com'], + 'dailymotion' : ['dailymotion.com'], + 'depfile' : ['depfile.com'], + 'depositfiles': ['depositfiles.com', 'dfiles.eu'], + 'dizzcloud' : ['dizzcloud.com'], + 'dl.dropbox' : [], + 'extabit' : ['extabit.com'], + 'extmatrix' : ['extmatrix.com'], + 'facebook' : [], + 'file4go' : ['file4go.com'], + 'filecloud' : ['filecloud.io','ifile.it','mihd.net'], + 'filefactory' : ['filefactory.com'], + 'fileom' : ['fileom.com'], + 'fileparadox' : ['fileparadox.in'], + 'filepost' : ['filepost.com', 'fp.io'], + 'filerio' : ['filerio.in','filerio.com','filekeen.com'], + 'filesflash' : ['filesflash.com'], + 'firedrive' : ['firedrive.com', 'putlocker.com'], + 'flashx' : [], + 'freakshare' : ['freakshare.net', 'freakshare.com'], + 'gigasize' : ['gigasize.com'], + 'hipfile' : ['hipfile.com'], + 'junocloud' : ['junocloud.me'], + 'letitbit' : ['letitbit.net','shareflare.net'], + 'mediafire' : ['mediafire.com'], + 'mega' : ['mega.co.nz'], + 'megashares' : ['megashares.com'], + 'metacafe' : ['metacafe.com'], + 'netload' : ['netload.in'], + 'oboom' : ['oboom.com'], + 'rapidgator' : ['rapidgator.net'], + 'rapidshare' : ['rapidshare.com'], + 'rarefile' : ['rarefile.net'], + 'ryushare' : ['ryushare.com'], + 'sendspace' : ['sendspace.com'], + 'turbobit' : ['turbobit.net', 'unextfiles.com'], + 'uploadable' : ['uploadable.ch'], + 'uploadbaz' : ['uploadbaz.com'], + 'uploaded' : ['uploaded.to', 'uploaded.net', 'ul.to'], + 'uploadhero' : ['uploadhero.com'], + 'uploading' : ['uploading.com'], + 'uptobox' : ['uptobox.com'], + 'xvideos' : ['xvideos.com'], + 'youtube' : ['youtube.com']} + + hoster_list = [] + + for item in hosters.itervalues(): + hoster_list.extend(item) + + return hoster_list diff --git a/pyload/plugin/hook/XFileSharingPro.py b/pyload/plugin/hook/XFileSharingPro.py index 9599c8180..9560cbd08 100644 --- a/pyload/plugin/hook/XFileSharingPro.py +++ b/pyload/plugin/hook/XFileSharingPro.py @@ -23,7 +23,6 @@ class XFileSharingPro(Hook): # event_list = ["pluginConfigChanged"] - interval = 0 #@TODO: Remove in 0.4.10 regexp = {'hoster' : (r'https?://(?:www\.)?(?P[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', r'https?://(?:[^/]+\.)?(?P%s)/(?:embed-)?\w+'), 'crypter': (r'https?://(?:www\.)?(?P[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:user|folder)s?/\w+', @@ -54,7 +53,7 @@ class XFileSharingPro(Hook): use_builtin_list = self.getConfig('use_builtin_list') for type in ("hoster", "crypter"): - every_plugin = not self.getConfig("use_%s_list" % type) + every_plugin = not self.getConfig('use_%s_list' % type) if every_plugin: self.logInfo(_("Handling any %s I can!") % type) diff --git a/pyload/plugin/hoster/ExtabitCom.py b/pyload/plugin/hoster/ExtabitCom.py index dfd37b0a0..c0fa782fa 100644 --- a/pyload/plugin/hoster/ExtabitCom.py +++ b/pyload/plugin/hoster/ExtabitCom.py @@ -4,7 +4,7 @@ import re from pyload.utils import json_loads -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/FileserveCom.py b/pyload/plugin/hoster/FileserveCom.py index 18322fa00..eb80889b1 100644 --- a/pyload/plugin/hoster/FileserveCom.py +++ b/pyload/plugin/hoster/FileserveCom.py @@ -6,7 +6,7 @@ from pyload.utils import json_loads from pyload.network.RequestFactory import getURL from pyload.plugin.Hoster import Hoster from pyload.plugin.Plugin import chunks -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight from pyload.utils import parseFileSize diff --git a/pyload/plugin/hoster/FreakshareCom.py b/pyload/plugin/hoster/FreakshareCom.py index 331d7f2a3..53eb10e55 100644 --- a/pyload/plugin/hoster/FreakshareCom.py +++ b/pyload/plugin/hoster/FreakshareCom.py @@ -3,7 +3,7 @@ import re from pyload.plugin.Hoster import Hoster -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight diff --git a/pyload/plugin/hoster/Keep2ShareCc.py b/pyload/plugin/hoster/Keep2ShareCc.py index 3c2b6c570..67af087b7 100644 --- a/pyload/plugin/hoster/Keep2ShareCc.py +++ b/pyload/plugin/hoster/Keep2ShareCc.py @@ -4,7 +4,7 @@ import re from urlparse import urljoin -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/LetitbitNet.py b/pyload/plugin/hoster/LetitbitNet.py index 01767cabf..545cde27c 100644 --- a/pyload/plugin/hoster/LetitbitNet.py +++ b/pyload/plugin/hoster/LetitbitNet.py @@ -12,7 +12,7 @@ from urlparse import urljoin from pyload.utils import json_loads, json_dumps from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/MediafireCom.py b/pyload/plugin/hoster/MediafireCom.py index 3b39e2420..8b05a95ec 100644 --- a/pyload/plugin/hoster/MediafireCom.py +++ b/pyload/plugin/hoster/MediafireCom.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.CaptchaService import SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster class MediafireCom(SimpleHoster): @@ -58,6 +58,3 @@ class MediafireCom(SimpleHoster): self.fail(_("Incorrect password")) return super(MediafireCom, self).handleFree(pyfile) - - -getInfo = create_getInfo(MediafireCom) diff --git a/pyload/plugin/hoster/MegaRapidoNet.py b/pyload/plugin/hoster/MegaRapidoNet.py new file mode 100644 index 000000000..938b201d5 --- /dev/null +++ b/pyload/plugin/hoster/MegaRapidoNet.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +from random import randint + +from pyload.plugin.internal.MultiHoster import MultiHoster + + +def random_with_N_digits(n): + rand = "0." + not_zero = 0 + for i in range(1,n+1): + r = randint(0,9) + if(r > 0): + not_zero += 1 + rand += str(r) + + if not_zero > 0: + return rand + else: + return random_with_N_digits(n) + + +class MegaRapidoNet(MultiHoster): + __name__ = "MegaRapidoNet" + __type__ = "hoster" + __version__ = "0.02" + + __pattern__ = r'http://(?:www\.)?\w+\.megarapido\.net/\?file=\w+' + __config__ = [("use_premium", "bool", "Use premium account if available", True)] + + __description__ = """MegaRapido.net multi-hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")] + + + LINK_PREMIUM_PATTERN = r'<\s*?a[^>]*?title\s*?=\s*?["\'][^"\']*?download["\'][^>]*?href=["\']([^"\']*)' + + ERROR_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']?alert-message error[^>]*>([^<]*)' + + + def handlePremium(self, pyfile): + self.html = self.load("http://megarapido.net/gerar.php", + post={'rand' :random_with_N_digits(16), + 'urllist' : pyfile.url, + 'links' : pyfile.url, + 'exibir' : "normal", + 'usar' : "premium", + 'user' : self.account.getAccountInfo(self.user).get('sid', None), + 'autoreset': ""}) + + if "desloga e loga novamente para gerar seus links" in self.html.lower(): + self.error("You have logged in at another place") + + return super(MegaRapidoNet, self).handlePremium(pyfile) diff --git a/pyload/plugin/hoster/NitroflareCom.py b/pyload/plugin/hoster/NitroflareCom.py index dfe33e59c..d2bcd871d 100644 --- a/pyload/plugin/hoster/NitroflareCom.py +++ b/pyload/plugin/hoster/NitroflareCom.py @@ -2,7 +2,7 @@ import re -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/RapidgatorNet.py b/pyload/plugin/hoster/RapidgatorNet.py index 2af0001df..98a8b97c9 100644 --- a/pyload/plugin/hoster/RapidgatorNet.py +++ b/pyload/plugin/hoster/RapidgatorNet.py @@ -6,8 +6,10 @@ from pycurl import HTTPHEADER from pyload.utils import json_loads from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.CaptchaService import AdsCaptcha, ReCaptcha, SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight +from pyload.plugin.captcha.AdsCaptcha import AdsCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight class RapidgatorNet(SimpleHoster): diff --git a/pyload/plugin/hoster/SoundcloudCom.py b/pyload/plugin/hoster/SoundcloudCom.py index 31aa7ba3c..524fb6e13 100644 --- a/pyload/plugin/hoster/SoundcloudCom.py +++ b/pyload/plugin/hoster/SoundcloudCom.py @@ -2,8 +2,8 @@ import re -from module.plugin.internal.SimpleHoster import SimpleHoster -from module.common.json_layer import json_loads +from pyload.plugin.internal.SimpleHoster import SimpleHoster +from pyload.utils import json_loads class SoundcloudCom(SimpleHoster): @@ -51,6 +51,3 @@ class SoundcloudCom(SimpleHoster): if http_streams: stream_name, self.link = http_streams[0 if self.getConfig('quality') == "Higher" else -1] pyfile.name += '.' + stream_name.split('_')[1].lower() - - -getInfo = create_getInfo(SoundcloudCom) diff --git a/pyload/plugin/hoster/UploadedTo.py b/pyload/plugin/hoster/UploadedTo.py index 165b29c7a..207817122 100644 --- a/pyload/plugin/hoster/UploadedTo.py +++ b/pyload/plugin/hoster/UploadedTo.py @@ -4,7 +4,7 @@ import re import time from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/ZippyshareCom.py b/pyload/plugin/hoster/ZippyshareCom.py index 784eccb68..9b1d432cc 100644 --- a/pyload/plugin/hoster/ZippyshareCom.py +++ b/pyload/plugin/hoster/ZippyshareCom.py @@ -4,7 +4,7 @@ import re from BeautifulSoup import BeautifulSoup -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/internal/BasePlugin.py b/pyload/plugin/internal/BasePlugin.py index ed4da72a1..0b6e8f102 100644 --- a/pyload/plugin/internal/BasePlugin.py +++ b/pyload/plugin/internal/BasePlugin.py @@ -6,7 +6,7 @@ from urllib import unquote from urlparse import urljoin, urlparse from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.SimpleHoster import create_getInfo, getFileURL +from pyload.plugin.internal.SimpleHoster import getFileURL from pyload.plugin.Hoster import Hoster @@ -99,6 +99,3 @@ class BasePlugin(Hoster): self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry") self.retry(3, 60, errmsg) - - -getInfo = create_getInfo(BasePlugin) diff --git a/pyload/plugin/internal/MultiHook.py b/pyload/plugin/internal/MultiHook.py index d43956691..ab96d30ca 100644 --- a/pyload/plugin/internal/MultiHook.py +++ b/pyload/plugin/internal/MultiHook.py @@ -54,8 +54,6 @@ class MultiHook(Hook): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.plugins = [] self.supported = [] self.new_supported = [] @@ -82,7 +80,7 @@ class MultiHook(Hook): self.pluginclass = getattr(self.pluginmodule, self.__name__) - def _loadAccount(self): + def loadAccount(self): self.account = self.core.accountManager.getAccountPlugin(self.pluginname) if self.account and not self.account.canUse(): @@ -94,7 +92,7 @@ class MultiHook(Hook): def activate(self): - self._loadAccount() + self.initPeriodical(threaded=True) def getURL(self, *args, **kwargs): #@TODO: Remove in 0.4.10 @@ -137,9 +135,9 @@ class MultiHook(Hook): return list() try: - configmode = self.getConfig("pluginmode", 'all') + configmode = self.getConfig('pluginmode', 'all') if configmode in ("listed", "unlisted"): - pluginlist = self.getConfig("pluginlist", '').replace('|', ',').replace(';', ',').split(',') + pluginlist = self.getConfig('pluginlist', '').replace('|', ',').replace(';', ',').split(',') configset = self._pluginSet(pluginlist) if configmode == "listed": @@ -183,24 +181,12 @@ class MultiHook(Hook): raise NotImplementedError - #: Threaded _periodical, remove in 0.4.10 and use built-in flag for that - def _periodical(self): - try: - if self.isActivated(): - self.periodical() - - except Exception, e: - self.core.log.error(_("Error executing hooks: %s") % str(e)) - if self.core.debug: - print_exc() - - self.cb = self.core.scheduler.addJob(self.interval, self._periodical) - - def periodical(self): """reload plugin list periodically""" - if self.getConfig("reload", True): - self.interval = max(self.getConfig("reloadinterval", 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) + self.loadAccount() + + if self.getConfig('reload', True): + self.interval = max(self.getConfig('reloadinterval', 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) else: self.core.scheduler.removeJob(self.cb) self.cb = None diff --git a/pyload/plugin/internal/MultiHoster.py b/pyload/plugin/internal/MultiHoster.py index 036570805..e9bb483da 100644 --- a/pyload/plugin/internal/MultiHoster.py +++ b/pyload/plugin/internal/MultiHoster.py @@ -85,7 +85,7 @@ class MultiHoster(SimpleHoster): self.logWarning(_("Premium download failed")) self.retryFree() - elif self.getConfig("revertfailed", True) \ + elif self.getConfig('revertfailed', True) \ and "new_module" in self.core.pluginManager.hosterPlugins[self.__name__]: hdict = self.core.pluginManager.hosterPlugins[self.__name__] -- cgit v1.2.3