diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2010-07-29 12:09:42 +0200 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2010-07-29 12:09:42 +0200 |
commit | 2ba07aa53d2af572af2c5a43e77725abd46e1b13 (patch) | |
tree | 89ff915a3a476dd9431d38c6e2b39b9de1aeb0f5 /module/plugins | |
parent | Added tag working for changeset 3cca18acfe7d (diff) | |
download | pyload-2ba07aa53d2af572af2c5a43e77725abd46e1b13.tar.xz |
many new stuff, some things already working
Diffstat (limited to 'module/plugins')
-rw-r--r-- | module/plugins/Plugin.py | 229 | ||||
-rw-r--r-- | module/plugins/hooks/ContainerDownload.py | 40 | ||||
-rw-r--r-- | module/plugins/hooks/LinuxFileEvents.py | 75 | ||||
-rw-r--r-- | module/plugins/hoster/BasePlugin.py | 25 | ||||
-rw-r--r-- | module/plugins/hoster/YoutubeCom.py | 2 |
5 files changed, 147 insertions, 224 deletions
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py index 0e04a86e6..51cd78f2d 100644 --- a/module/plugins/Plugin.py +++ b/module/plugins/Plugin.py @@ -22,15 +22,35 @@ import re from os.path import exists from os.path import join +from time import time from time import sleep + import sys from os.path import exists from os import makedirs -from module.DownloadThread import CaptchaError -class Plugin(): +def dec(func): + def new(*args): + if args[0].pyfile.abort: + raise Abort + return func(*args) + return new + +class Abort(Exception): + """ raised when aborted """ + +class Fail(Exception): + """ raised when failed """ + +class Reconnect(Exception): + """ raised when reconnected """ + +class Retry(Exception): + """ raised when start again from beginning """ + +class Plugin(object): __name__ = "Plugin" __version__ = "0.4" __pattern__ = None @@ -39,107 +59,55 @@ class Plugin(): __author_name__ = ("RaNaN", "spoob", "mkaay") __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org", "mkaay@mkaay.de") - def __init__(self, parent): - self.configparser = parent.core.parser_plugins - self.config = {} - self.parent = parent - self.req = parent.core.requestFactory.getRequest(self.__name__) - self.html = 0 - self.time_plus_wait = 0 #time() + wait in seconds - self.want_reconnect = False - self.multi_dl = True - self.ocr = None #captcha reader instance - self.logger = logging.getLogger("log") - self.decryptNow = True - self.pyfile = self.parent - - def prepare(self, thread): - self.want_reconnect = False - self.pyfile.status.exists = self.file_exists() - - if not self.pyfile.status.exists: - return False - - self.pyfile.status.filename = self.get_file_name() - self.pyfile.status.waituntil = self.time_plus_wait - self.pyfile.status.url = self.get_file_url() - self.pyfile.status.want_reconnect = self.want_reconnect - thread.wait(self.parent) - - return True - - def set_parent_status(self): - """ sets all available Statusinfos about a File in self.parent.status - """ - pass - - def download_html(self): - """ gets the url from self.parent.url saves html in self.html and parses - """ - self.html = "" - - def file_exists(self): - """ returns True or False - """ - if re.search(r"(?!http://).*\.(dlc|ccf|rsdf|txt)", self.parent.url): - return exists(self.parent.url) - header = self.load(self.parent.url, just_header=True) - try: - if re.search(r"HTTP/1.1 404 Not Found", header): - return False - except: - pass - return True - - def get_file_url(self): - """ returns the absolute downloadable filepath - """ - return self.parent.url - - def get_file_name(self): - try: - return re.findall("([^\/=]+)", self.parent.url)[-1] - except: - return self.parent.url[:20] - - def wait_until(self): - if self.html != None: - self.download_html() - return self.time_plus_wait - - def proceed(self, url, location): - self.download(url, location) - - def set_config(self): - for k, v in self.config.items(): - self.configparser.set(self.__name__, {"option": k}, v) - - def remove_config(self, option): - self.configparser.remove(self.__name__, option) - - def get_config(self, value, default=None): - self.configparser.loadData() - return self.configparser.get(self.__name__, value, default=default) - - def read_config(self): - self.configparser.loadData() - try: - self.verify_config() - self.config = self.configparser.getConfig()[self.__name__] - except: - pass - - def verify_config(self): - pass - - def init_ocr(self): - captchaClass = self.parent.core.pluginManager.getCaptchaPlugin(self.__name__) - self.ocr = captchaClass() + def __new__(cls, *args, **kws): + for f in dir(cls): + if not f.startswith("_") and f not in ("checksum"): + setattr(cls, f, dec(getattr(cls, f)) ) + + o = super(cls.__class__, cls).__new__(cls) + #wrap decorator around every method + return o + + def __init__(self, pyfile): + self.config = pyfile.m.core.config + + self.req = pyfile.m.core.requestFactory.getRequest(self.__name__) + + self.wantReconnect = False + self.multiDL = True + + self.waitUntil = 0 # time() + wait in seconds + self.premium = False + + self.ocr = None # captcha reader instance + self.account = pyfile.m.core.accountManager.getAccount(self.__name__) # account handler instance + self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, self.account) + + self.log = logging.getLogger("log") + + self.pyfile = pyfile + self.thread = None # holds thread in future + def __call__(self): + return self.__name__ + + def preprocessing(self, thread): + """ handles important things to do before starting """ + self.thread = thread + + if not self.account: + self.req.clearCookies() + + return self.process(self.pyfile) + + #---------------------------------------------------------------------- + def process(self, pyfile): + """the 'main' method of every plugin""" raise NotImplementedError - def check_file(self, local_file): + + def checksum(self, local_file=None): """ return codes: 0 - checksum ok @@ -148,8 +116,48 @@ class Plugin(): 10 - not implemented 20 - unknown error """ + #@TODO checksum check hook + return (True, 10) + + def setConf(self, option, value): + """ sets a config value """ + self.config.setPlugin(self.__name__, option, value) + + def removeConf(self, option): + """ removes a config value """ + raise NotImplementedError + + def getConf(self, option): + """ gets a config value """ + return self.config.getPlugin(self.__name__, option) + + + def setWait(self, seconds): + """ set the wait time to specified seconds """ + self.waitUntil = time() + int(seconds) + + def wait(): + """ waits the time previously set """ + pass + + def fail(self, reason): + """ fail and give reason """ + raise Fail(reason) + + def offline(self): + """ fail and indicate file is offline """ + raise Fail("offline") + + def retry(self): + """ begin again from the beginning """ + raise Retry + + def askCaptcha(self, url): + """ loads the catpcha and decrypt it or ask the user for input """ + pass + def waitForCaptcha(self, captchaData, imgType): captchaManager = self.parent.core.captchaManager task = captchaManager.newTask(self) @@ -165,16 +173,19 @@ class Plugin(): return result def load(self, url, get={}, post={}, ref=True, cookies=True, just_header=False): + """ returns the content loaded """ return self.req.load(url, get, post, ref, cookies, just_header) - def download(self, url, file_name, get={}, post={}, ref=True, cookies=True): - download_folder = self.parent.core.config['general']['download_folder'] - if self.pyfile.package.data["package_name"] != (self.parent.core.config['general']['link_file']) and self.parent.core.xmlconfig.get("general", "folder_per_package", False): - self.pyfile.folder = self.pyfile.package.data["package_name"] - location = join(download_folder, self.pyfile.folder.decode(sys.getfilesystemencoding())) - if not exists(location): makedirs(location) - file_path = join(location.decode(sys.getfilesystemencoding()), self.pyfile.status.filename.decode(sys.getfilesystemencoding())) - else: - file_path = join(download_folder, self.pyfile.status.filename.decode(sys.getfilesystemencoding())) + def download(self, url, get={}, post={}, ref=True, cookies=True): + """ downloads the url content to disk """ + download_folder = self.config['general']['download_folder'] + + location = join(download_folder, self.pyfile.package().folder.decode(sys.getfilesystemencoding())) + + if not exists(location): + makedirs(location) + + newname = self.req.download(url, self.pyfile.name, location, get, post, ref, cookies) - self.pyfile.status.filename = self.req.download(url, file_path, get, post, ref, cookies) + if newname: + self.pyfile.name = newname diff --git a/module/plugins/hooks/ContainerDownload.py b/module/plugins/hooks/ContainerDownload.py deleted file mode 100644 index 673931391..000000000 --- a/module/plugins/hooks/ContainerDownload.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay - @interface-version: 0.1 -""" - -from module.plugins.Hook import Hook - -from os.path import join, abspath - -class ContainerDownload(Hook): - __name__ = "ContainerDownload" - __version__ = "0.1" - __description__ = """add the downloaded container to current package""" - __author_name__ = ("mkaay") - __author_mail__ = ("mkaay@mkaay.de") - - def downloadFinished(self, pyfile): - filename = pyfile.status.filename - if not pyfile.url.startswith("http"): - return - if filename.endswith(".dlc") or filename.endswith(".ccf") or filename.endswith(".rsdf"): - self.logger.info("ContainerDownload: adding container file") - location = abspath(join(pyfile.folder, filename)) - newFile = self.core.file_list.collector.addLink(location) - self.core.file_list.packager.addFileToPackage(pyfile.package.data["id"], self.core.file_list.collector.popFile(newFile)) diff --git a/module/plugins/hooks/LinuxFileEvents.py b/module/plugins/hooks/LinuxFileEvents.py deleted file mode 100644 index f4fe12de4..000000000 --- a/module/plugins/hooks/LinuxFileEvents.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - @author: mkaay - @interface-version: 0.1 -""" - -from module.plugins.Hook import Hook -import os - -class LinuxFileEvents(Hook): - __name__ = "LinuxFileEvents" - __version__ = "0.1" - __description__ = """monitors files and directories for changes""" - __author_name__ = ("mkaay") - __author_mail__ = ("mkaay@mkaay.de") - - def __init__(self, core): - Hook.__init__(self, core) - - return #@TODO remove when working correctly - - if not os.name == "posix": - return - - self.core.check_file(self.core.make_path("container"), _("folder for container"), True) - self.core.check_install("pyinotify", _("pyinotify for LinuxFileEvents")) - - try: - import pyinotify - except: - return - wm = pyinotify.WatchManager() - - class FileChangeHandler(pyinotify.ProcessEvent): - def __init__(self, hook): - self.hook = hook - - def process_default(self, event): - self.hook.fileChangeEvent(event.path) - - notifier = pyinotify.ThreadedNotifier(wm, FileChangeHandler(self)) - notifier.start() - mask = pyinotify.IN_MODIFY | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_MOVED_TO - wm.add_watch(os.path.join(self.core.path, "links.txt"), mask) - wm.add_watch(os.path.join(self.core.path, "container"), mask, rec=True, auto_add=True) - - def fileChangeEvent(self, path): - path = os.path.abspath(path) - if self.isValidContainer(path): - self.addNewFile(path) - - def isValidContainer(self, path): - ext = [".txt", ".dlc", ".ccf", ".rsdf"] - for e in ext: - if path.endswith(e): - return True - return False - - def addNewFile(self, path): - self.core.server_methods.add_package("Container", [path]) - diff --git a/module/plugins/hoster/BasePlugin.py b/module/plugins/hoster/BasePlugin.py new file mode 100644 index 000000000..09545d493 --- /dev/null +++ b/module/plugins/hoster/BasePlugin.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.Hoster import Hoster + +class BasePlugin(Hoster): + __name__ = "BasePlugin" + __type__ = "hoster" + __pattern__ = r"^unmatchable$" + __version__ = "0.1" + __description__ = """Base Plugin when any other didnt fit""" + __author_name__ = ("RaNaN") + __author_mail__ = ("RaNaN@pyload.org") + + def process(self, pyfile): + """main function""" + + if pyfile.url.startswith("http://"): + + pyfile.name = re.findall("([^\/=]+)", pyfile.url)[-1] + self.download(pyfile.url) + + else: + self.fail("No Plugin matched and not a downloadable url.")
\ No newline at end of file diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 6c952e2ba..978d89a37 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -9,6 +9,8 @@ class YoutubeCom(Hoster): __type__ = "hoster" __pattern__ = r"http://(www\.)?(de\.)?\youtube\.com/watch\?v=.*" __version__ = "0.2" + __config__ = [ ("int", "quality" , "Quality Setting", "hd;lq"), + ("int", "config", "Config Settings" , "default" ) ] __description__ = """Youtube.com Video Download Hoster""" __author_name__ = ("spoob") __author_mail__ = ("spoob@pyload.org") |