summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/CaptchaManager.py134
-rw-r--r--module/HookManager.py7
-rw-r--r--module/config/default.conf7
-rw-r--r--module/lib/captchatrader.py123
-rw-r--r--module/network/HTTPRequest.py16
-rw-r--r--module/network/RequestFactory.py8
-rw-r--r--module/plugins/Hook.py14
-rw-r--r--module/plugins/Plugin.py75
-rw-r--r--module/plugins/hooks/CaptchaTrader.py131
-rw-r--r--module/web/pyload_app.py1
-rw-r--r--module/web/templates/jinja/default/settings.html3
-rw-r--r--module/web/webinterface.py2
-rwxr-xr-xpyLoadCore.py4
13 files changed, 274 insertions, 251 deletions
diff --git a/module/CaptchaManager.py b/module/CaptchaManager.py
index d9e3748d7..99d29f37d 100644
--- a/module/CaptchaManager.py
+++ b/module/CaptchaManager.py
@@ -14,74 +14,91 @@
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
+ @author: mkaay, RaNaN
"""
-from uuid import uuid4 as uuid
+from time import time
+from traceback import print_exc
from threading import Lock
class CaptchaManager():
def __init__(self, core):
self.lock = Lock()
self.core = core
- self.tasks = []
-
- def newTask(self, plugin):
- task = CaptchaTask(plugin, self)
- self.lock.acquire()
- self.tasks.append(task)
- self.lock.release()
+ self.tasks = [] #task store, for outgoing tasks only
+
+ self.ids = 0 #only for internal purpose
+
+ def newTask(self, img, type, temp):
+ task = CaptchaTask(self.ids, img, type, temp)
+ self.ids += 1
return task
-
+
def removeTask(self, task):
self.lock.acquire()
- self.tasks.remove(task)
+ if task in self.tasks:
+ self.tasks.remove(task)
self.lock.release()
-
+
def getTask(self):
self.lock.acquire()
for task in self.tasks:
- status = task.getStatus()
- if status == "waiting" or status == "shared-user":
+ if task.status in ("waiting", "shared-user"):
self.lock.release()
return task
self.lock.release()
return None
-
+
def getTaskFromID(self, tid):
self.lock.acquire()
for task in self.tasks:
- if task.getID() == tid:
+ if task.id == tid:
self.lock.release()
return task
self.lock.release()
return None
+ def handleCaptcha(self, task):
+ if self.core.isClientConnected: #client connected -> should solve the captcha
+ self.tasks.append(task)
+ task.setWaiting(40) #wait 40 sec for response
+ return True
+
+ for plugin in self.core.hookManager.activePlugins():
+ try:
+ plugin.newCaptchaTask(task)
+ except:
+ if self.core.debug:
+ print_exc()
+
+ if task.handler: # a plugin handles the captcha
+ return True
+
+ task.error = _("No Client connected for captcha decrypting")
+
+ return False
+
+
class CaptchaTask():
- def __init__(self, plugin, manager):
- self.lock = Lock()
- self.plugin = plugin
- self.manager = manager
- self.captchaImg = None
- self.captchaType = None
- self.result = None
- self.status = "preparing"
- self.id = uuid().hex
-
- def setCaptcha(self, img, imgType):
- self.lock.acquire()
+ def __init__(self, id, img, type, temp):
+ self.id = str(id)
self.captchaImg = img
- self.captchaType = imgType
- self.lock.release()
-
+ self.captchaType = type
+ self.captchaFile = temp
+ self.handler = None #the hook plugin that will take care of the solution
+ self.result = None
+ self.waitUntil = None
+ self.error = None #error message
+
+ self.status = "init"
+ self.data = {} #handler can store data here
+
def getCaptcha(self):
return self.captchaImg, self.captchaType
-
+
def setResult(self, result):
- self.lock.acquire()
self.result = result
- self.lock.release()
-
+
def getResult(self):
try:
res = self.result.encode("utf8", "replace")
@@ -89,33 +106,38 @@ class CaptchaTask():
res = self.result
return res
-
- def getID(self):
- return self.id
-
+
def getStatus(self):
return self.status
-
- def setDone(self):
- self.lock.acquire()
- self.status = "done"
- self.lock.release()
-
- def setWaiting(self):
- self.lock.acquire()
+
+ def setWaiting(self, sec):
+ """ let the captcha wait secs for the solution """
+ self.waitUntil = time() + sec
self.status = "waiting"
- self.lock.release()
-
+
+ def isWaiting(self):
+ if self.result or self.error or time() > self.waitUntil:
+ return False
+
+ return True
+
def setWatingForUser(self, exclusive):
- self.lock.acquire()
if exclusive:
self.status = "user"
else:
self.status = "shared-user"
- self.lock.release()
-
- def removeTask(self):
- self.manager.removeTask(self)
-
+
+ def timedOut(self):
+ return self.waitUntil >= time()
+
+ def invalid(self):
+ """ indicates the captcha was not correct """
+ if self.handler:
+ self.handler.captchaInvalid()
+
+ def correct(self):
+ if self.handler:
+ self.handler.captchaCorrect()
+
def __str__(self):
- return "<CaptchaTask '%s'>" % (self.getID(),)
+ return "<CaptchaTask '%s'>" % self.id
diff --git a/module/HookManager.py b/module/HookManager.py
index bc79b3c1c..6c6c0170f 100644
--- a/module/HookManager.py
+++ b/module/HookManager.py
@@ -20,6 +20,7 @@
import traceback
from threading import RLock
+from operator import methodcaller
from module.PluginThread import HookThread
from time import time
@@ -75,7 +76,7 @@ class HookManager():
def wrapPeriodical(plugin):
plugin.lastCall = time()
try:
- plugin.periodical()
+ if plugin.isActivated(): plugin.periodical()
except Exception, e:
self.core.log.error(_("Error executing hooks: %s") % str(e))
if self.core.debug:
@@ -143,3 +144,7 @@ class HookManager():
def startThread(self, function, pyfile):
t = HookThread(self.core.threadManager, function, pyfile)
+
+ def activePlugins(self):
+ """ returns all active plugins """
+ return filter(methodcaller("isActivated"), self.plugins)
diff --git a/module/config/default.conf b/module/config/default.conf
index dfa58608b..18edd5a77 100644
--- a/module/config/default.conf
+++ b/module/config/default.conf
@@ -4,7 +4,7 @@ remote - "Remote":
int port : "Port" = 7227
ip listenaddr : "Adress" = 0.0.0.0
str username : "Username" = admin
- str password : "Password" = pwhere
+ password password : "Password" = pwhere
ssl - "SSL":
bool activated : "Activated"= False
file cert : "SSL Certificate" = ssl.crt
@@ -58,7 +58,4 @@ proxy - "Proxy":
int port : "Port" = 7070
http;socks4;socks5 type : "Protocol" = http
str username : "Username" = None
- str password : "Password" = None
-captchatrader - "CaptchaTrader":
- str username : "Username" =
- str password : "Password" =
+ password password : "Password" = None \ No newline at end of file
diff --git a/module/lib/captchatrader.py b/module/lib/captchatrader.py
deleted file mode 100644
index 50a2acbea..000000000
--- a/module/lib/captchatrader.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-# -*- 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
-"""
-
-try:
- from json import loads
-except ImportError:
- from simplejson import loads
-
-from urllib2 import build_opener
-from MultipartPostHandler import MultipartPostHandler
-
-PYLOAD_KEY = "9f65e7f381c3af2b076ea680ae96b0b7"
-
-opener = build_opener(MultipartPostHandler)
-
-class CaptchaTraderException(Exception):
- def __init__(self, err):
- self.err = err
-
- def getCode(self):
- return self.err
-
- def __str__(self):
- return "<CaptchaTraderException %s>" % self.err
-
- def __repr__(self):
- return "<CaptchaTraderException %s>" % self.err
-
-class CaptchaTrader():
- SUBMIT_URL = "http://captchatrader.com/api/submit"
- RESPOND_URL = "http://captchatrader.com/api/respond"
- GETCREDITS_URL = "http://captchatrader.com/api/get_credits/username:%(user)s/password:%(password)s/"
-
- def __init__(self, user, password, api_key=PYLOAD_KEY):
- self.api_key = api_key
- self.user = user
- self.password = password
-
- def getCredits(self):
- json = opener.open(CaptchaTrader.GETCREDITS_URL % {"user":self.user, "password":self.password}).read()
- response = loads(json)
- if response[0] < 0:
- raise CaptchaTraderException(response[1])
- else:
- return response[1]
-
- def submit(self, captcha, captchaType="file", match=None):
- if not self.api_key:
- raise CaptchaTraderException("No API Key Specified!")
- if type(captcha) == str and captchaType == "file":
- raise CaptchaTraderException("Invalid Type")
- assert captchaType in ("file", "url-jpg", "url-jpeg", "url-png", "url-bmp")
- json = opener.open(CaptchaTrader.SUBMIT_URL, data={"api_key":self.api_key,
- "username":self.user,
- "password":self.password,
- "value":captcha,
- "type":captchaType}).read()
- response = loads(json)
- if response[0] < 0:
- raise CaptchaTraderException(response[1])
-
- class Result():
- def __init__(self, api, ticket, result):
- self.api = api
- self.ticket = ticket
- self.result = result
-
- def getTicketID(self):
- return self.ticket
-
- def getResult(self):
- return self.result
-
- def success(self):
- self.sendResponse(True)
-
- def fail(self):
- self.sendResponse(False)
-
- def sendResponse(self, success):
- self.api.respond(self.ticket, success)
-
- return Result(self, response[0], response[1])
-
- def respond(self, ticket, success):
- json = opener.open(CaptchaTrader.RESPOND_URL, data={"is_correct":1 if success else 0,
- "username":self.user,
- "password":self.password,
- "ticket":ticket}).read()
- response = loads(json)
- if response[0] < 0:
- raise CaptchaTraderException(response[1])
-
-if __name__ == "__main__":
- ct = CaptchaTrader("<user>", "<password>")
- print "credits", ct.getCredits()
-
- print "testing..."
-
- result = ct.submit(open("test_captcha.jpg", "rb"))
- print "result", result.getResult()
- if result.getResult() == "bettand trifting":
- result.success()
- print "captcha recognized"
- else:
- result.fail()
- print "captcha not recognized"
diff --git a/module/network/HTTPRequest.py b/module/network/HTTPRequest.py
index 13e76d5a2..bcd2c696c 100644
--- a/module/network/HTTPRequest.py
+++ b/module/network/HTTPRequest.py
@@ -111,7 +111,7 @@ class HTTPRequest():
def clearCookies(self):
self.c.setopt(pycurl.COOKIELIST, "")
- def setRequestContext(self, url, get, post, referer, cookies):
+ def setRequestContext(self, url, get, post, referer, cookies, multipart=False):
""" sets everything needed for the request """
url = myquote(str(url))
@@ -124,9 +124,13 @@ class HTTPRequest():
self.c.lastUrl = url
if post:
- post = urlencode(post)
- self.c.setopt(pycurl.POSTFIELDS, post)
-
+ if not multipart:
+ post = urlencode(post)
+ self.c.setopt(pycurl.POSTFIELDS, post)
+ else:
+ post = [(x, str(quote(y)) if type(y) in (str, unicode) else y ) for x,y in post.iteritems()]
+ self.c.setopt(pycurl.HTTPPOST, post)
+
if referer and self.lastURL:
self.c.setopt(pycurl.REFERER, self.lastURL)
@@ -136,10 +140,10 @@ class HTTPRequest():
self.getCookies()
- def load(self, url, get={}, post={}, referer=True, cookies=True, just_header=False):
+ def load(self, url, get={}, post={}, referer=True, cookies=True, just_header=False, multipart=False):
""" load and returns a given page """
- self.setRequestContext(url, get, post, referer, cookies)
+ self.setRequestContext(url, get, post, referer, cookies, multipart)
self.header = ""
diff --git a/module/network/RequestFactory.py b/module/network/RequestFactory.py
index ec9ce4350..8340d06f7 100644
--- a/module/network/RequestFactory.py
+++ b/module/network/RequestFactory.py
@@ -49,9 +49,9 @@ class RequestFactory():
self.lock.release()
return req
- def getURL(self, url, get={}, post={}):
+ def getURL(self, url, get={}, post={}, multipart=False):
h = HTTPRequest(None, self.iface(), self.getProxies())
- rep = h.load(url, get, post)
+ rep = h.load(url, get, post, multipart=multipart)
h.close()
return rep
@@ -97,5 +97,5 @@ class RequestFactory():
self.bucket.setRate(self.core.config["download"]["max_speed"] * 1024)
# needs pyreq in global namespace
-def getURL(url, get={}, post={}):
- return pyreq.getURL(url, get, post) \ No newline at end of file
+def getURL(*args, **kwargs):
+ return pyreq.getURL(*args, **kwargs) \ No newline at end of file
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
index 1b3c05ba1..4bbf6e33a 100644
--- a/module/plugins/Hook.py
+++ b/module/plugins/Hook.py
@@ -19,7 +19,6 @@
"""
-
class Hook():
__name__ = "Hook"
__version__ = "0.2"
@@ -38,6 +37,9 @@ class Hook():
self.interval = 60
self.setup()
+
+ def __repr__(self):
+ return self.__name__
def setup(self):
""" more init stuff if needed"""
@@ -84,3 +86,13 @@ class Hook():
def unrarFinished(self, folder, fname):
pass
+
+ def newCaptchaTask(self, task):
+ """ new captcha task for the plugin, it MUST set the handler and timeout or will be ignored """
+ pass
+
+ def captchaCorrect(self, task):
+ pass
+
+ def captchaWrong(self, task):
+ pass \ No newline at end of file
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 617e2e20a..3891cba94 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -29,7 +29,6 @@ from os import chmod
from os import stat
from os.path import exists
from os.path import join
-from os.path import basename
if os.name != "nt":
from os import chown
@@ -38,8 +37,6 @@ if os.name != "nt":
from itertools import islice
-from thread import start_new_thread
-
from module.utils import save_join
def chunks(iterable, size):
@@ -110,7 +107,7 @@ class Plugin(object):
self.lastDownload = "" # location where the last call to download was saved
self.lastCheck = None #re match of last checked matched
self.js = self.core.js # js engine
- self.ctresult = None
+ self.cTask = None #captcha task
self.html = None #some plugins store html code here
@@ -221,17 +218,15 @@ class Plugin(object):
def retry(self):
""" begin again from the beginning """
- if self.ctresult:
- self.ctresult.fail()
raise Retry
def invalidCaptcha(self):
- if self.ctresult:
- self.ctresult.fail()
+ if self.cTask:
+ self.cTask.invalid()
def correctCaptcha(self):
- if self.ctresult:
- self.ctresult.success()
+ if self.cTask:
+ self.cTask.success()
def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype="jpg"):
""" loads the catpcha and decrypt it or ask the user for input """
@@ -260,52 +255,28 @@ class Plugin(object):
else:
captchaManager = self.core.captchaManager
- task = captchaManager.newTask(self)
- task.setCaptcha(content, imgtype)
- task.setWaiting()
-
- ct = None
- if self.core.config["captchatrader"]["username"] and self.core.config["captchatrader"]["password"]:
- task.setWatingForUser(exclusive=True)
- from module.lib.captchatrader import CaptchaTrader
- ct = CaptchaTrader(self.core.config["captchatrader"]["username"], self.core.config["captchatrader"]["password"])
- if ct.getCredits < 10:
- self.log.info("Not enough credits for CaptchaTrader")
- task.setWaiting()
- else:
- self.log.info("Submitting to CaptchaTrader")
- def threaded(ct):
- cf = open(join("tmp","tmpCaptcha_%s_%s.%s" % (self.__name__, id, imgtype)), "rb")
- try:
- result = ct.submit(cf)
- except:
- self.log.warning("CaptchaTrader error!")
- if self.core.debug:
- from traceback import print_exc
- print_exc()
- ct = None
- task.setWaiting()
- else:
- self.ctresult = result
- task.setResult(result.getResult())
- self.log.debug("CaptchaTrader response: %s" % result.getResult())
- task.setDone()
- start_new_thread(threaded, (ct, ))
+ task = captchaManager.newTask(content, imgtype, temp.name)
+ self.cTask = task
+ captchaManager.handleCaptcha(task)
- while not task.getStatus() == "done":
- if not self.core.isClientConnected():
- task.removeTask()
- #temp.unlink(temp.name)
- if has_plugin and not ct:
- self.fail(_("Pil and tesseract not installed and no Client connected for captcha decrypting"))
- elif not ct:
- self.fail(_("No Client connected for captcha decrypting"))
+ while task.isWaiting():
if self.pyfile.abort:
- task.removeTask()
+ captchaManager.removeTask(task)
raise Abort
sleep(1)
- result = task.getResult()
- task.removeTask()
+
+ captchaManager.removeTask(task)
+
+ if task.error and has_plugin: #ignore default error message since the user could use OCR
+ self.fail(_("Pil and tesseract not installed and no Client connected for captcha decrypting"))
+ elif task.error:
+ self.fail(task.error)
+ elif not task.result:
+ self.fail(_("No captcha result obtained in appropiate time by any of the plugins."))
+
+
+ result = task.result
+ self.log.debug("Received captcha result: %s" % result)
if not self.core.debug:
try:
diff --git a/module/plugins/hooks/CaptchaTrader.py b/module/plugins/hooks/CaptchaTrader.py
new file mode 100644
index 000000000..9bb8dd2f0
--- /dev/null
+++ b/module/plugins/hooks/CaptchaTrader.py
@@ -0,0 +1,131 @@
+# -*- 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, RaNaN
+"""
+
+try:
+ from json import loads
+except ImportError:
+ from simplejson import loads
+
+from thread import start_new_thread
+from pycurl import FORM_FILE
+
+from module.network.RequestFactory import getURL
+
+from module.plugins.Hook import Hook
+
+PYLOAD_KEY = "9f65e7f381c3af2b076ea680ae96b0b7"
+
+class CaptchaTraderException(Exception):
+ def __init__(self, err):
+ self.err = err
+
+ def getCode(self):
+ return self.err
+
+ def __str__(self):
+ return "<CaptchaTraderException %s>" % self.err
+
+ def __repr__(self):
+ return "<CaptchaTraderException %s>" % self.err
+
+class CaptchaTrader(Hook):
+ __name__ = "CaptchaTrader"
+ __version__ = "0.1"
+ __description__ = """send captchas to captchatrader.com"""
+ __config__ = [("activated", "bool", "Activated", "True"),
+ ("username", "str", "Username", ""),
+ ("passkey", "password", "Password", "")]
+ __author_name__ = ("RaNaN")
+ __author_mail__ = ("RaNaN@pyload.org")
+
+ SUBMIT_URL = "http://captchatrader.com/api/submit"
+ RESPOND_URL = "http://captchatrader.com/api/respond"
+ GETCREDITS_URL = "http://captchatrader.com/api/get_credits/username:%(user)s/password:%(password)s/"
+
+
+ def getCredits(self):
+ json = getURL(CaptchaTrader.GETCREDITS_URL % {"user": self.getConfig("username"),
+ "password": self.getConfig("passkey")})
+ response = loads(json)
+ if response[0] < 0:
+ raise CaptchaTraderException(response[1])
+ else:
+ self.log.debug("CaptchaTrader: %s credits left" % response[1])
+ return response[1]
+
+ def submit(self, captcha, captchaType="file", match=None):
+ if not PYLOAD_KEY:
+ raise CaptchaTraderException("No API Key Specified!")
+
+ #if type(captcha) == str and captchaType == "file":
+ # raise CaptchaTraderException("Invalid Type")
+ assert captchaType in ("file", "url-jpg", "url-jpeg", "url-png", "url-bmp")
+ json = getURL(CaptchaTrader.SUBMIT_URL, post={"api_key": PYLOAD_KEY,
+ "username": self.getConfig("username"),
+ "password": self.getConfig("passkey"),
+ "value": (FORM_FILE, captcha),
+ "type": captchaType}, multipart=True)
+ response = loads(json)
+ if response[0] < 0:
+ raise CaptchaTraderException(response[1])
+
+ ticket = response[0]
+ result = response[1]
+ self.log.debug("CaptchaTrader result %s : %s" % (ticket,result))
+
+ return ticket, result
+
+ def respond(self, ticket, success):
+ json = getURL(CaptchaTrader.RESPOND_URL, post={"is_correct": 1 if success else 0,
+ "username": self.getConfig("username"),
+ "password": self.getConfig("passkey"),
+ "ticket": ticket})
+ response = loads(json)
+ if response[0] < 0:
+ raise CaptchaTraderException(response[1])
+
+ def newCaptchaTask(self, task):
+ if not self.getConfig("username") or not self.getConfig("passkey"):
+ return False
+
+ if self.getCredits() > 10:
+
+ task.handler = self
+ task.setWaiting(40)
+ start_new_thread(self.processCaptcha, (task,))
+
+ else:
+ self.log.info(_("Your CaptchaTrader Account has not enough credits"))
+
+ def captchaCorrect(self, task):
+ ticket = task.data["ticket"]
+ self.respond(ticket, True)
+
+ def captchaWrong(self, task):
+ ticket = task.data["ticket"]
+ self.respond(ticket, True)
+
+ def processCaptcha(self, task):
+ c = task.captchaFile
+ try:
+ ticket, result = self.submit(c)
+ except CaptchaTraderException, e:
+ task.error = e.getCode()
+
+ task.data["ticket"] = ticket
+ task.setResult(result)
diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py
index 70686532c..2778566e1 100644
--- a/module/web/pyload_app.py
+++ b/module/web/pyload_app.py
@@ -400,6 +400,7 @@ def path(file="", path=""):
return render_to_response('pathchooser.html', {'cwd': cwd, 'files': files, 'parentdir': parentdir, 'type': type, 'oldfile': oldfile, 'absolute': abs}, [])
@route("/logs")
+@route("/logs", method="POST")
@route("/logs/:item")
@route("/logs/:item", method="POST")
@login_required('can_see_logs')
diff --git a/module/web/templates/jinja/default/settings.html b/module/web/templates/jinja/default/settings.html
index 18bc78e30..68c480ec2 100644
--- a/module/web/templates/jinja/default/settings.html
+++ b/module/web/templates/jinja/default/settings.html
@@ -127,6 +127,9 @@
<input name="browsebutton" type="button"
onclick="ifield = document.getElementById('{{skey}}|{{okey}}'); filechooser = window.open('{% if option.value %}{{ "/filechooser/" + option.value|quotepath }}{% else %}{{ fileroot }}{% endif %}', 'filechooser', 'scrollbars=yes,toolbar=no,menubar=no,statusbar=no,width=650,height=300'); filechooser.ifield = ifield; window.ifield = ifield;"
value="{{_("Browse")}}"/>
+ {% elif option.type == "password" %}
+ <input id="{{skey}}|{{okey}}" name="{{configname}}|{{skey}}|{{okey}}"
+ type="password" value="{{option.value}}"/>
{% else %}
<input id="{{skey}}|{{okey}}" name="{{configname}}|{{skey}}|{{okey}}"
type="text" value="{{option.value}}"/>
diff --git a/module/web/webinterface.py b/module/web/webinterface.py
index fe59c57b1..15948666e 100644
--- a/module/web/webinterface.py
+++ b/module/web/webinterface.py
@@ -113,7 +113,7 @@ from beaker.middleware import SessionMiddleware
session_opts = {
'session.type': 'file',
- 'session.cookie_expires': -1,
+ # 'session.cookie_expires': -1,
'session.data_dir': './tmp',
'session.auto': False
}
diff --git a/pyLoadCore.py b/pyLoadCore.py
index f207bf2e5..ec22a82b6 100755
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -770,7 +770,7 @@ class ServerMethods():
if task:
task.setWatingForUser(exclusive=exclusive)
c = task.getCaptcha()
- return str(task.getID()), Binary(c[0]), str(c[1])
+ return str(task.id), Binary(c[0]), str(c[1])
else:
return None, None, None
@@ -785,7 +785,7 @@ class ServerMethods():
task = self.core.captchaManager.getTaskFromID(tid)
if task:
task.setResult(result)
- task.setDone()
+ self.core.captchaManager.removeTask(task)
return True
else:
return False