summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jeix <devnull@localhost> 2010-08-13 11:03:44 +0200
committerGravatar Jeix <devnull@localhost> 2010-08-13 11:03:44 +0200
commitb1cc10a0f5ea6c9cb8231c67dd016fe4a2414170 (patch)
treeaf31f7d3c6efb49a2afe905d4971001417299c03
parentirchook-xmlrpc fix (diff)
parentimprovements (diff)
downloadpyload-b1cc10a0f5ea6c9cb8231c67dd016fe4a2414170.tar.xz
Merge
-rw-r--r--module/AccountManager.py16
-rw-r--r--module/PluginManager.py12
-rw-r--r--module/PluginThread.py1
-rw-r--r--module/config/default.conf8
-rw-r--r--module/plugins/Plugin.py8
-rw-r--r--module/plugins/accounts/RapidshareCom.py51
-rw-r--r--module/plugins/accounts/UploadedTo.py35
-rw-r--r--module/plugins/crypter/YoutubeBatch.py33
-rw-r--r--module/plugins/crypter/YoutubeChannel.py52
-rw-r--r--module/plugins/hooks/IRCInterface.py6
-rw-r--r--module/plugins/hooks/UnRar.py4
-rw-r--r--module/plugins/hooks/XMPPInterface.py229
-rw-r--r--module/plugins/hoster/NetloadIn.py20
-rw-r--r--module/plugins/hoster/ShareCx.py27
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py31
-rw-r--r--module/plugins/hoster/YoutubeCom.py7
-rw-r--r--module/pyunrar.py4
-rw-r--r--module/web/pyload/views.py25
-rw-r--r--module/web/templates/default/settings.html55
-rwxr-xr-xpyLoadCli.py9
-rwxr-xr-xpyLoadCore.py17
21 files changed, 498 insertions, 152 deletions
diff --git a/module/AccountManager.py b/module/AccountManager.py
index 0122b0223..fc122e760 100644
--- a/module/AccountManager.py
+++ b/module/AccountManager.py
@@ -51,7 +51,14 @@ class AccountManager():
else:
return None
-
+ def getAccountPlugins(self):
+ """ get all account instances"""
+
+ plugins = []
+ for plugin in self.accounts.keys():
+ plugins.append(self.getAccountPlugin(plugin))
+
+ return plugins
#----------------------------------------------------------------------
def loadAccounts(self):
"""loads all accounts available"""
@@ -107,7 +114,7 @@ class AccountManager():
f = open("accounts.conf", "wb")
f.write("version: " + str(ACC_VERSION) + "\n")
-
+
for plugin, accounts in self.accounts.iteritems():
f.write("\n")
f.write(plugin+":\n")
@@ -145,11 +152,12 @@ class AccountManager():
#----------------------------------------------------------------------
def removeAccount(self, plugin, user):
"""remove account"""
+
if self.accounts.has_key(plugin):
p = self.getAccountPlugin(plugin)
p.removeAccount(user)
- if self.accounts.has_key(user):
- del self.accounts[user]
+ if self.accounts[plugin].has_key(user):
+ del self.accounts[plugin][user]
self.saveAccounts()
diff --git a/module/PluginManager.py b/module/PluginManager.py
index 44a426d31..8bb5a5ec6 100644
--- a/module/PluginManager.py
+++ b/module/PluginManager.py
@@ -132,7 +132,7 @@ class PluginManager():
config = [ [y.strip() for y in x.replace("'","").replace('"',"").replace(")","").split(",")] for x in config[0].split("(") if x.strip()]
if folder == "hooks":
- config.append( ["load", "bool", "Load on startup", True] )
+ config.append( ["load", "bool", "Load on startup", True if name not in ("XMPPInterface", "MultiHome") else False] )
for item in config:
self.core.config.addPluginConfig([name]+item)
@@ -238,8 +238,16 @@ class PluginManager():
classes.append(value["class"])
continue
- module = __import__(value["path"], globals(), locals(), [value["name"]] , -1)
+ if not self.core.config.getPlugin(name, "load"):
+ continue
+ try:
+ module = __import__(value["path"], globals(), locals(), [value["name"]] , -1)
+ except Exception, e:
+ self.log.error(_("Error importing %s: %s") % (name, str(e)))
+ self.log.error(_("You should fix dependicies or deactivate load on startup."))
+ continue
+
pluginClass = getattr(module, name)
value["class"] = pluginClass
diff --git a/module/PluginThread.py b/module/PluginThread.py
index c666e7875..f727aa7f0 100644
--- a/module/PluginThread.py
+++ b/module/PluginThread.py
@@ -70,6 +70,7 @@ class DownloadThread(PluginThread):
self.m.log.info(_("Download starts: %s" % pyfile.name))
try:
+ self.m.core.hookManager.downloadStarts(pyfile)
pyfile.plugin.preprocessing(self)
except NotImplementedError:
diff --git a/module/config/default.conf b/module/config/default.conf
index b1c0c648e..e9c7782e6 100644
--- a/module/config/default.conf
+++ b/module/config/default.conf
@@ -21,17 +21,15 @@ log - "Log":
str log_folder : "Folder" = Logs
int log_count : "Count" = 5
general - "General":
- en;de;fr;nl;pl language : "Language" = de
+ en;de;fr;nl;pl language : "Language" = en
str download_folder : "Download Folder" = Downloads
int max_downloads : "Max Parallel Downloads" = 3
- str link_file : "File For Links" = links.txt
- str failed_file : "File For Failed Links" = failed_links.txt
bool debug_mode : "Debug Mode" = False
int max_download_time : "Max Download Time" = 5
int download_speed_limit : "Download Speed Limit" = 0
- bool checksum : "Use Checksum" = True
+ bool checksum : "Use Checksum" = False
int min_free_space : "Min Free Space (MB)" = 200
- bool folder_per_package : "Create folder for each package" = False
+ bool folder_per_package : "Create folder for each package" = True
ip download_interface : "Outgoing IP address for downloads" = None
updates - "Updates":
bool search_updates : "Search" = True
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 04a5adb91..02a15dfbc 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -34,6 +34,14 @@ from os import makedirs
from tempfile import NamedTemporaryFile
from mimetypes import guess_type
+from itertools import islice
+
+def chunks(iterable, size):
+ it = iter(iterable)
+ item = list(islice(it, size))
+ while item:
+ yield item
+ item = list(islice(it, size))
def dec(func):
def new(*args):
diff --git a/module/plugins/accounts/RapidshareCom.py b/module/plugins/accounts/RapidshareCom.py
index 052470ada..7f5fff84d 100644
--- a/module/plugins/accounts/RapidshareCom.py
+++ b/module/plugins/accounts/RapidshareCom.py
@@ -28,31 +28,34 @@ class RapidshareCom(Account):
__author_mail__ = ("mkaay@mkaay.de")
def getAccountInfo(self, user):
- data = None
- for account in self.accounts.items():
- if account[0] == user:
- data = account[1]
- if not data:
- return
- req = self.core.requestFactory.getRequest(self.__name__, user)
- api_url_base = "http://api.rapidshare.com/cgi-bin/rsapi.cgi"
- api_param_prem = {"sub": "getaccountdetails_v1", "type": "prem", "login": user, "password": data["password"], "withcookie": 1}
- src = req.load(api_url_base, cookies=False, get=api_param_prem)
- if src.startswith("ERROR"):
- return
- fields = src.split("\n")
- info = {}
- for t in fields:
- if not t.strip():
- continue
- k, v = t.split("=")
- info[k] = v
+ try:
+ data = None
+ for account in self.accounts.items():
+ if account[0] == user:
+ data = account[1]
+ if not data:
+ return
+ req = self.core.requestFactory.getRequest(self.__name__, user)
+ api_url_base = "http://api.rapidshare.com/cgi-bin/rsapi.cgi"
+ api_param_prem = {"sub": "getaccountdetails_v1", "type": "prem", "login": user, "password": data["password"], "withcookie": 1}
+ src = req.load(api_url_base, cookies=False, get=api_param_prem)
+ if src.startswith("ERROR"):
+ return
+ fields = src.split("\n")
+ info = {}
+ for t in fields:
+ if not t.strip():
+ continue
+ k, v = t.split("=")
+ info[k] = v
+
+ out = Account.getAccountInfo(self, user)
+ tmp = {"validuntil":None, "login":str(info["accountid"]), "trafficleft":int(info["tskb"]), "type":self.__name__}
+ out.update(tmp)
- out = Account.getAccountInfo(self, user)
- tmp = {"validuntil":None, "login":str(info["accountid"]), "trafficleft":int(info["tskb"]), "type":self.__name__}
- out.update(tmp)
-
- return out
+ return out
+ except:
+ return Account.getAccountInfo(self, user)
def login(self, user, data):
req = self.core.requestFactory.getRequest(self.__name__, user)
diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py
index d2aa22b22..926f91255 100644
--- a/module/plugins/accounts/UploadedTo.py
+++ b/module/plugins/accounts/UploadedTo.py
@@ -30,22 +30,25 @@ class UploadedTo(Account):
__author_mail__ = ("mkaay@mkaay.de")
def getAccountInfo(self, user):
- data = None
- for account in self.accounts.items():
- if account[0] == user:
- data = account[1]
- if not data:
- return
- req = self.core.requestFactory.getRequest(self.__name__, user)
- html = req.load("http://uploaded.to/", cookies=True)
- raw_traffic = re.search(r"Traffic left: </span><span class=.*?>(.*?)</span>", html).group(1)
- raw_valid = re.search(r"Valid until: </span> <span class=.*?>(.*?)</span>", html).group(1)
- traffic = int(self.parseTraffic(raw_traffic))
- validuntil = int(mktime(strptime(raw_valid.strip(), "%d-%m-%Y %H:%M")))
- out = Account.getAccountInfo(self, user)
- tmp = {"login":user, "validuntil":validuntil, "trafficleft":traffic, "type":self.__name__}
- out.update(tmp)
- return out
+ try:
+ data = None
+ for account in self.accounts.items():
+ if account[0] == user:
+ data = account[1]
+ if not data:
+ return
+ req = self.core.requestFactory.getRequest(self.__name__, user)
+ html = req.load("http://uploaded.to/", cookies=True)
+ raw_traffic = re.search(r"Traffic left: </span><span class=.*?>(.*?)</span>", html).group(1)
+ raw_valid = re.search(r"Valid until: </span> <span class=.*?>(.*?)</span>", html).group(1)
+ traffic = int(self.parseTraffic(raw_traffic))
+ validuntil = int(mktime(strptime(raw_valid.strip(), "%d-%m-%Y %H:%M")))
+ out = Account.getAccountInfo(self, user)
+ tmp = {"login":user, "validuntil":validuntil, "trafficleft":traffic, "type":self.__name__}
+ out.update(tmp)
+ return out
+ except:
+ return Account.getAccountInfo(self, user)
def login(self, user, data):
req = self.core.requestFactory.getRequest(self.__name__, user)
diff --git a/module/plugins/crypter/YoutubeBatch.py b/module/plugins/crypter/YoutubeBatch.py
new file mode 100644
index 000000000..091c8558a
--- /dev/null
+++ b/module/plugins/crypter/YoutubeBatch.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.Crypter import Crypter
+
+class YoutubeBatch(Crypter):
+ __name__ = "YoutubeBatch"
+ __type__ = "container"
+ __pattern__ = r"http://(www\.)?(de\.)?\youtube\.com/user/*"
+ __version__ = "0.9"
+ __description__ = """Youtube.com Channel Download Plugin"""
+ __author_name__ = ("RaNaN", "Spoob")
+ __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org")
+
+ def setup(self):
+ self.user = re.search(r"/user/(.+)", self.pyfile.url).group(1).split("#")[0]
+ self.playlist = re.search(r"/user/%s.*?/user/(.{16})" % self.user, self.pyfile.url).group(1)
+
+ def file_exists(self):
+ if "User not found" in self.req.load("http://gdata.youtube.com/feeds/api/playlists/%s?v=2" % self.playlist):
+ return False
+ return True
+
+ def decrypt(self, pyfile):
+ if not self.file_exists():
+ self.offline()
+ url = "http://gdata.youtube.com/feeds/api/playlists/%s?v=2" % self.playlist
+ rep = self.load(url)
+ new_links = []
+ new_links.extend(re.findall(r"href\='(http:\/\/www.youtube.com\/watch\?v\=[^']+)&", rep))
+ self.packages.append((self.pyfile.package().name, new_links, self.pyfile.package().name))
diff --git a/module/plugins/crypter/YoutubeChannel.py b/module/plugins/crypter/YoutubeChannel.py
deleted file mode 100644
index 292be06af..000000000
--- a/module/plugins/crypter/YoutubeChannel.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-
-from module.plugins.Crypter import Crypter
-
-class YoutubeChannel(Crypter):
- __name__ = "YoutubeChannel"
- __type__ = "container"
- __pattern__ = r"http://(www\.)?(de\.)?\youtube\.com/user/*"
- __version__ = "0.9"
- __description__ = """Youtube.com Channel Download Plugin"""
- __author_name__ = ("RaNaN", "Spoob")
- __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org")
-
- def __init__(self, parent):
- Crypter.__init__(self, parent)
- self.parent = parent
- self.html = None
- self.read_config()
- self.user = re.search(r"/user/(.+)", self.parent.url).group(1).split("#")[0]
-
- def file_exists(self):
- if "User not found" in self.req.load("http://gdata.youtube.com/feeds/api/users/%s" % self.user):
- return False
- return True
-
- def proceed(self, url, location):
- max_videos = self.config['max_videos']
- if not max_videos:
- max_videos = 1000 #max video a user can upload
- page = 0
- temp_links = []
- if "," in self.config['video_groups']:
- video_groups = self.config['video_groups'].split(",")
- else:
- video_groups = [self.config['video_groups']]
- for group in video_groups:
- for start_index in range(1, int(max_videos), 50):
- max_results = max_videos - page * 50
- if max_results > 50:
- max_results = 50
- url = "http://gdata.youtube.com/feeds/api/users/%s/%s?max-results=%i&start-index=%i" % (self.user, group, max_results, start_index)
- rep = self.req.load(url)
- new_links = re.findall(r"href\='(http:\/\/www.youtube.com\/watch\?v\=[^']+)&", rep)
- if new_links != []:
- temp_links.extend(new_links)
- else:
- break
- page += 1
- self.links = temp_links
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index 2ede56685..8d50647e3 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -86,8 +86,8 @@ class IRCInterface(Thread, Hook):
for t in self.getConfig("owner").split():
if t.strip().startswith("#"):
self.sock.send("JOIN %s\r\n" % t.strip())
- self.log.info("pyLoadIRC: Connected to %s!" % host)
- self.log.info("pyLoadIRC: Switching to listening mode!")
+ self.log.info("pyLoad IRC: Connected to %s!" % host)
+ self.log.info("pyLoad IRC: Switching to listening mode!")
try:
self.main_loop()
@@ -173,7 +173,7 @@ class IRCInterface(Thread, Hook):
for line in res:
self.response(line, msg["origin"])
except Exception, e:
- self.log.error("pyLoadIRC: "+ repr(e))
+ self.log.error("pyLoad IRC: "+ repr(e))
def response(self, msg, origin=""):
diff --git a/module/plugins/hooks/UnRar.py b/module/plugins/hooks/UnRar.py
index 82c99a575..30cda62af 100644
--- a/module/plugins/hooks/UnRar.py
+++ b/module/plugins/hooks/UnRar.py
@@ -30,7 +30,7 @@ class UnRar(Hook):
__name__ = "UnRar"
__version__ = "0.1"
__description__ = """unrar"""
- __config__ = [ ("activated", "bool", "Activated", True),
+ __config__ = [ ("activated", "bool", "Activated", False),
("fullpath", "bool", "extract full path", True),
("overwrite", "bool", "overwrite files", True),
("passwordfile", "str", "unrar passoword file", "unrar_passwords.txt"),
@@ -109,7 +109,7 @@ class UnRar(Hook):
u.crackPassword(passwords=self.passwords, statusFunction=s, overwrite=True, destination=folder)
except WrongPasswordError:
continue
- except CommandError as e:
+ except CommandError , e:
if re.search("Cannot find volume", e.stderr):
continue
try:
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
new file mode 100644
index 000000000..67a7f1b77
--- /dev/null
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -0,0 +1,229 @@
+# -*- 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: RaNaN
+ @interface-version: 0.2
+"""
+
+import socket
+import sys
+from threading import Thread
+import time
+from time import sleep
+from traceback import print_exc
+
+from pyxmpp.all import JID,Iq,Presence,Message,StreamError
+from pyxmpp.jabber.client import JabberClient
+from pyxmpp.interface import implements
+from pyxmpp.interfaces import *
+from pyxmpp.streamtls import TLSSettings
+
+from module.plugins.Hook import Hook
+from module.plugins.hooks.IRCInterface import IRCInterface
+
+class XMPPInterface(IRCInterface, JabberClient):
+ __name__ = "XMPPInterface"
+ __version__ = "0.1"
+ __description__ = """connect to jabber and let owner perform different tasks"""
+ __config__ = [("activated", "bool", "Activated", "False"),
+ ("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"),
+ ("pw", "str", "Password", ""),
+ ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"),
+ ("info_file", "bool", "Inform about every file finished", "False"),
+ ("info_pack", "bool", "Inform about every package finished", "True")]
+ __author_name__ = ("RaNaN")
+ __author_mail__ = ("RaNaN@pyload.org")
+
+ implements(IMessageHandlersProvider)
+
+ def __init__(self, core):
+ IRCInterface.__init__(self, core)
+
+ self.jid = JID(self.getConfig("jid"))
+ password = self.getConfig("pw")
+
+ # if bare JID is provided add a resource -- it is required
+ if not self.jid.resource:
+ self.jid=JID(self.jid.node, self.jid.domain, "pyLoad")
+
+ tls_settings = None
+
+ # setup client with provided connection information
+ # and identity data
+ JabberClient.__init__(self, self.jid, password,
+ disco_name="pyLoad XMPP Client", disco_type="bot",
+ tls_settings = tls_settings)
+
+ self.interface_providers = [
+ VersionHandler(self),
+ self,
+ ]
+
+ def coreReady(self):
+ self.new_package = {}
+
+ self.start()
+
+ def packageFinished(self, pypack):
+
+ try:
+ if self.getConfig("info_pack"):
+ self.announce(_("Package finished: %s") % pypack.name)
+ except:
+ pass
+
+ def downloadFinished(self, pyfile):
+ try:
+ if self.getConfig("info_file"):
+ self.announce(_("Download finished: %s @ %s") % (pyfile.name, pyfile.pluginname) )
+ except:
+ pass
+
+ def run(self):
+ # connect to IRC etc.
+ self.connect()
+ try:
+ self.loop(1)
+ except Exception, ex:
+ self.core.log.error("pyLoad XMPP: %s" % str(ex))
+
+ def stream_state_changed(self,state,arg):
+ """This one is called when the state of stream connecting the component
+ to a server changes. This will usually be used to let the user
+ know what is going on."""
+ self.log.debug("pyLoad XMPP: *** State changed: %s %r ***" % (state,arg) )
+
+ def get_message_handlers(self):
+ """Return list of (message_type, message_handler) tuples.
+
+ The handlers returned will be called when matching message is received
+ in a client session."""
+ return [
+ ("normal", self.message),
+ ]
+
+ def message(self,stanza):
+ """Message handler for the component."""
+ subject=stanza.get_subject()
+ body=stanza.get_body()
+ t=stanza.get_type()
+ self.log.debug(_(u'pyLoad XMPP: Message from %s received.') % (unicode(stanza.get_from(),)))
+ self.log.debug(_(u'pyLoad XMPP: Body: %s') % body)
+
+ if stanza.get_type()=="headline":
+ # 'headline' messages should never be replied to
+ return True
+ if subject:
+ subject=u"Re: "+subject
+
+ to_jid = stanza.get_from()
+ from_jid = stanza.get_to()
+
+ #j = JID()
+ to_name = to_jid.as_utf8()
+ from_name = from_jid.as_utf8()
+
+ names = self.getConfig("owners").split(";")
+
+ if to_name in names or to_jid.node+"@"+to_jid.domain in names:
+
+ messages = []
+
+ trigger = "pass"
+ args = None
+
+ temp = body.split()
+ trigger = temp[0]
+ if len(temp) > 1:
+ args = temp[1:]
+
+ handler = getattr(self, "event_%s" % trigger, self.event_pass)
+ try:
+ res = handler(args)
+ for line in res:
+ m=Message(
+ to_jid=to_jid,
+ from_jid=from_jid,
+ stanza_type=stanza.get_type(),
+ subject=subject,
+ body=line)
+
+ messages.append(m)
+ except Exception, e:
+ self.log.error("pyLoad XMPP: "+ repr(e))
+
+ return messages
+
+ else:
+ return True
+
+
+ def announce(self, message):
+ """ send message to all owners"""
+ for user in self.getConfig("owners").split(";"):
+
+ self.log.debug(_("pyLoad XMPP: Send message to %s") % user)
+
+ to_jid = JID(user)
+
+ m = Message(from_jid=self.jid,
+ to_jid=to_jid,
+ stanza_type="chat",
+ body=message)
+
+ self.stream.send(m)
+
+
+class VersionHandler(object):
+ """Provides handler for a version query.
+
+ This class will answer version query and announce 'jabber:iq:version' namespace
+ in the client's disco#info results."""
+
+ implements(IIqHandlersProvider, IFeaturesProvider)
+
+ def __init__(self, client):
+ """Just remember who created this."""
+ self.client = client
+
+ def get_features(self):
+ """Return namespace which should the client include in its reply to a
+ disco#info query."""
+ return ["jabber:iq:version"]
+
+ def get_iq_get_handlers(self):
+ """Return list of tuples (element_name, namespace, handler) describing
+ handlers of <iq type='get'/> stanzas"""
+ return [
+ ("query", "jabber:iq:version", self.get_version),
+ ]
+
+ def get_iq_set_handlers(self):
+ """Return empty list, as this class provides no <iq type='set'/> stanza handler."""
+ return []
+
+ def get_version(self,iq):
+ """Handler for jabber:iq:version queries.
+
+ jabber:iq:version queries are not supported directly by PyXMPP, so the
+ XML node is accessed directly through the libxml2 API. This should be
+ used very carefully!"""
+ iq=iq.make_result_response()
+ q=iq.new_query("jabber:iq:version")
+ q.newTextChild(q.ns(),"name","Echo component")
+ q.newTextChild(q.ns(),"version","1.0")
+ return iq
+ \ No newline at end of file
diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py
index 9e117fa14..6f0cb9461 100644
--- a/module/plugins/hoster/NetloadIn.py
+++ b/module/plugins/hoster/NetloadIn.py
@@ -4,8 +4,12 @@
import re
from time import sleep
+
from module.plugins.Hoster import Hoster
from module.network.Request import getURL
+from module.plugins.Plugin import chunks
+
+
def getInfo(urls):
## returns list of tupels (name, size (in bytes), status (see FileDatabase), url)
@@ -14,14 +18,10 @@ def getInfo(urls):
apiurl = "http://api.netload.in/info.php?auth=Zf9SnQh9WiReEsb18akjvQGqT0I830e8&bz=1&md5=1&file_id="
id_regex = re.compile("http://.*netload\.in/(?:datei(.*?)(?:\.htm|/)|index.php?id=10&file_id=)")
urls_per_query = 80
-
- iterations = len(urls)/urls_per_query
- if len(urls)%urls_per_query > 0:
- iterations = iterations +1
-
- for i in range(iterations):
+
+ for chunk in chunks(urls, urls_per_query):
ids = ""
- for url in urls[i*urls_per_query:(i+1)*urls_per_query]:
+ for url in chunk:
match = id_regex.search(url)
if match:
ids = ids + match.group(1) +";"
@@ -37,19 +37,17 @@ def getInfo(urls):
result = []
- counter = 0
- for r in api.split():
+ for i, r in enumerate(api.split()):
try:
tmp = r.split(";")
try:
size = int(tmp[2])
except:
size = 0
- result.append( (tmp[1], size, 2 if tmp[3] == "online" else 1, urls[(i*80)+counter]) )
+ result.append( (tmp[1], size, 2 if tmp[3] == "online" else 1, chunk[i] ) )
except:
print "Netload prefetch: Error while processing response: "
print r
- counter = counter +1
yield result
diff --git a/module/plugins/hoster/ShareCx.py b/module/plugins/hoster/ShareCx.py
index feee30cd3..e64459754 100644
--- a/module/plugins/hoster/ShareCx.py
+++ b/module/plugins/hoster/ShareCx.py
@@ -3,8 +3,35 @@
import re
from module.plugins.Hoster import Hoster
+from module.plugins.Plugin import chunks
+from module.network.Request import getURL
#from module.BeautifulSoup import BeautifulSoup
+def getInfo(urls):
+ api_url = "http://www.share.cx/uapi?do=check&links="
+
+ for chunk in chunks(urls, 90):
+ get = ""
+ for url in chunk:
+ get += ";"+url
+
+ api = getURL(api_url+get[1:])
+ result = []
+
+ for i, link in enumerate(api.split()):
+ url,name,size = link.split(";")
+ if name and size:
+ status = 2
+ else:
+ status = 1
+
+ if not name: name = chunk[i]
+ if not size: size = 0
+
+ result.append( (name, size, status, chunk[i]) )
+
+ yield result
+
class ShareCx(Hoster):
__name__ = "ShareCx"
__type__ = "hoster"
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 8646fcc88..42a2bc560 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -13,19 +13,30 @@ from time import sleep
from module.plugins.Hoster import Hoster
from module.network.Request import getURL
+from module.plugins.Plugin import chunks
+
def getInfo(urls):
api_url_base = "http://www.share-online.biz/linkcheck/linkcheck.php"
- api_param_file = {"links": "\n".join(x.replace("http://www.share-online.biz/dl/","") for x in urls)} #api only supports old style links
- src = getURL(api_url_base, post=api_param_file)
- result = []
- for i, res in enumerate(src.split("\n")):
- if not res:
- continue
- fields = res.split(";")
- status = 2 if fields[1] == "OK" else 3
- result.append((fields[2], int(fields[3]), status, urls[i]))
- yield result
+
+ for chunk in chunks(urls, 90):
+ api_param_file = {"links": "\n".join(x.replace("http://www.share-online.biz/dl/","") for x in chunk)} #api only supports old style links
+ src = getURL(api_url_base, post=api_param_file)
+ result = []
+ for i, res in enumerate(src.split("\n")):
+ if not res:
+ continue
+ fields = res.split(";")
+
+ if fields[1] == "OK":
+ status = 2
+ elif fields[1] in ("DELETED", "NOT FOUND"):
+ status = 1
+ else:
+ status = 3
+
+ result.append((fields[2], int(fields[3]), status, chunk[i]))
+ yield result
class ShareonlineBiz(Hoster):
__name__ = "ShareonlineBiz"
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index e40b0c9ad..d92d8d128 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -32,9 +32,8 @@ class YoutubeCom(Hoster):
if self.getConf("quality") == "hd" or self.getConf("quality") == "hq":
file_suffix = ".mp4"
- name = re.search(file_name_pattern, html).group(1).replace("/", "") + file_suffix
-
- pyfile.name = name.replace("&amp;", "&").replace("ö", "oe").replace("ä", "ae").replace("ü", "ue")
+ name = (re.search(file_name_pattern, html).group(1).replace("/", "") + file_suffix).decode("utf8")
+ pyfile.name = name #.replace("&amp;", "&").replace("ö", "oe").replace("ä", "ae").replace("ü", "ue")
if self.getConf("quality") == "sd":
quality = "&fmt=6"
@@ -45,4 +44,4 @@ class YoutubeCom(Hoster):
file_url = 'http://youtube.com/get_video?video_id=' + videoId + '&t=' + videoHash + quality + "&asv=2"
- self.download(file_url) \ No newline at end of file
+ self.download(file_url)
diff --git a/module/pyunrar.py b/module/pyunrar.py
index 4db3c3a19..6bb240965 100644
--- a/module/pyunrar.py
+++ b/module/pyunrar.py
@@ -270,7 +270,7 @@ class Unrar():
if overwrite:
try:
remove(abspath(join(destination, sf[0])))
- except OSError as e:
+ except OSError, e:
if not e.errno == 2:
raise e
f = sf[0]
@@ -278,7 +278,7 @@ class Unrar():
if fullPath:
try:
makedirs(dirname(join(abspath(destination), sf[0])))
- except OSError as e:
+ except OSError, e:
if not e.errno == 17:
raise e
d = join(destination, dirname(f))
diff --git a/module/web/pyload/views.py b/module/web/pyload/views.py
index b8cbacf30..880ec7843 100644
--- a/module/web/pyload/views.py
+++ b/module/web/pyload/views.py
@@ -300,6 +300,7 @@ def collector(request):
def config(request):
conf = settings.PYLOAD.get_config()
plugin = settings.PYLOAD.get_plugin_config()
+ accs = settings.PYLOAD.get_accounts()
messages = []
for section in chain(conf.itervalues(), plugin.itervalues()):
@@ -343,6 +344,26 @@ def config(request):
continue
else:
continue
+
+ elif sec == "Accounts":
+ if ";" in okey:
+ action, name = okey.split(";")
+
+ if action == "delete":
+ settings.PYLOAD.remove_account(skey, name)
+ elif action == "password":
+
+ for acc in accs[skey]:
+ if acc["login"] == name and acc["password"] != value:
+ settings.PYLOAD.update_account(skey, name, value)
+
+ elif okey == "newacc" and value:
+ # add account
+
+ pw = request.POST.get("Accounts|%s|newpw" % skey)
+
+ settings.PYLOAD.update_account(skey, value, pw)
+
if errors:
messages.append(_("Error occured when setting the following options:"))
@@ -351,4 +372,6 @@ def config(request):
else:
messages.append(_("All options were set correctly."))
- return render_to_response(join(settings.TEMPLATE, 'settings.html'), RequestContext(request, {'conf': {'Plugin':plugin, 'General':conf}, 'errors': messages}, [status_proc]))
+ accs = settings.PYLOAD.get_accounts()
+
+ return render_to_response(join(settings.TEMPLATE, 'settings.html'), RequestContext(request, {'conf': {'Plugin':plugin, 'General':conf, 'Accounts': accs}, 'errors': messages}, [status_proc]))
diff --git a/module/web/templates/default/settings.html b/module/web/templates/default/settings.html
index 208549813..e9a40ff3a 100644
--- a/module/web/templates/default/settings.html
+++ b/module/web/templates/default/settings.html
@@ -77,17 +77,23 @@
<ul id="tabs" class="tabs">
{% for configname, config in conf.iteritems %}
<span id="g_{{configname}}">
- {% for skey, section in config.iteritems %}
- <li><a href="#{{configname}}{{skey}}">{{section.desc}}</a></li>
- {% endfor %}
+ {% ifnotequal configname "Accounts" %}
+ {% for skey, section in config.iteritems %}
+ <li><a href="#{{configname}}{{skey}}">{{section.desc}}</a></li>
+ {% endfor %}
+ {% else %}
+ {% for skey, section in config.iteritems %}
+ <li><a href="#{{configname}}{{skey}}">{{skey}}</a></li>
+ {% endfor %}
+ {% endifnotequal %}
</span>
{% endfor %}
</ul>
</div>
<form id="horizontalForm" action="" method="POST">
{% for configname, config in conf.iteritems %}
+ {% ifnotequal configname "Accounts" %}
{% for skey, section in config.iteritems %}
-
<div class="tabContent" id="{{configname}}{{skey}}">
<table class="settable">
{% for okey, option in section.items %}
@@ -118,6 +124,47 @@
</table>
</div>
{% endfor %}
+ {% else %}
+ <!-- Accounts -->
+ {% for plugin, accounts in config.iteritems %}
+ <div class="tabContent" id="{{configname}}{{plugin}}">
+ <table class="settable">
+ {% for account in accounts %}
+ <tr>
+ <td><label for="{{configname}}|{{plugin}}|password;{{account.login}}" style="color:#424242;">{{account.login}}:</label></td>
+ <td>
+ <input id="{{plugin}}|delete;{{account.login}}" name="{{configname}}|{{plugin}}|password;{{account.login}}" type="password" value="{{account.password}}"/>
+ </td>
+ <td>
+ {% trans "Delete? " %}
+ <input id="{{plugin}}|delete;{{account.login}}" name="{{configname}}|{{plugin}}|delete;{{account.login}}" type="checkbox" value="True"/>
+
+ </td>
+ </tr>
+
+ {% endfor %}
+ <tr><td>&nbsp;</td></tr>
+
+ <tr>
+ <td><label for="{{configname}}|{{plugin}}|{{account.login}}" style="color:#424242;">{% trans "New account:" %}</label></td>
+
+ <td>
+ <input id="{{plugin}}|newacc" name="{{configname}}|{{plugin}}|newacc" type="text"/>
+ </td>
+ </tr>
+ <tr>
+ <td><label for="{{configname}}|{{plugin}}|{{account.name}}" style="color:#424242;">{% trans "New password:" %}</label></td>
+
+ <td>
+ <input id="{{config}}|{{plugin}}" name="{{configname}}|{{plugin}}|newpw" type="password"/>
+ </td>
+ </tr>
+
+ </table>
+ </div>
+ {% endfor %}
+
+ {% endifnotequal %}
{% endfor %}
{% if conf %}
<input class="submit" type="submit" value="{% trans "Submit" %}" />
diff --git a/pyLoadCli.py b/pyLoadCli.py
index 36ab0c4f7..4e97489c8 100755
--- a/pyLoadCli.py
+++ b/pyLoadCli.py
@@ -30,10 +30,15 @@ import threading
import time
from time import sleep
import xmlrpclib
+from traceback import print_exc
from module import InitHomeDir
from module.ConfigParser import ConfigParser
+import codecs
+
+sys.stdout = codecs.getwriter("utf8")(sys.stdout, errors = "replace")
+
if sys.stdout.encoding.lower().startswith("utf"):
conv = unicode
else:
@@ -109,7 +114,7 @@ class pyLoadCli:
return conv(size / 1024 ** 2) + " MiB"
def println(self, line, content):
- print "\033[" + conv(line) + ";0H\033[2K" + conv(content) + "\033[" + conv((self.inputline if self.inputline > 0 else self.inputline + 1) - 1) + ";0H"
+ print "\033[" + conv(line) + ";0H\033[2K" + content + "\033[" + conv((self.inputline if self.inputline > 0 else self.inputline + 1) - 1) + ";0H"
def print_input(self):
self.println(self.inputline, white(" Input: ") + self.input)
@@ -336,7 +341,7 @@ class RefreshThread(threading.Thread):
self.cli.println(2, red(conv(e)))
self.cli.pos[1] = 0
self.cli.pos[2] = 0
-
+ print_exc()
diff --git a/pyLoadCore.py b/pyLoadCore.py
index 8dc725ca7..cc9480dee 100755
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -64,6 +64,7 @@ import module.remote.SecureXMLRPCServer as Server
from module.web.ServerThread import WebServer
from module.FileDatabase import PyFile
+
class Core(object):
""" pyLoad Core """
@@ -71,7 +72,6 @@ class Core(object):
self.doDebug = False
self.arg_links = []
-
if len(argv) > 1:
try:
options, args = getopt(argv[1:], 'vca:hdus:', ["version", "clear", "add=", "help", "debug", "user", "setup", "configdir="])
@@ -156,7 +156,6 @@ class Core(object):
s.start()
exit()
-
self.config = ConfigParser()
translation = gettext.translation("pyLoad", self.path("locale"), languages=["en", self.config['general']['language']])
@@ -214,7 +213,7 @@ class Core(object):
self.init_server()
self.init_webserver()
- linkFile = self.config['general']['link_file']
+ #linkFile = self.config['general']['link_file']
freeSpace = self.freeSpace()
if freeSpace > 5 * 1024:
@@ -613,20 +612,18 @@ class ServerMethods():
return self.core.pullManager.getEvents(uuid)
def get_accounts(self):
- plugins = self.core.pluginManager.getAccountPlugins()
- data = []
+ plugins = self.core.accountManager.getAccountPlugins()
+ data = {}
for p in plugins:
- data.extend(p.getAllAccounts())
+ data[p.__name__] = p.getAllAccounts()
return data
def update_account(self, plugin, account, password, options=[]):
""" create and update account """
- plugins = self.core.pluginManager.getAccountPlugins()
- self.core.pluginManager.updateAccount(plugin, account, password, options)
+ self.core.accountManager.updateAccount(plugin, account, password, options)
def remove_account(self, plugin, account):
- plugins = self.core.pluginManager.getAccountPlugins()
- self.core.pluginManager.removeAccount(plugin, account)
+ self.core.accountManager.removeAccount(plugin, account)
def set_priority(self, id, priority):
p = self.core.files.getPackage(id)