From aa7e8ab9c17306ad8f11a5165b65f93d824f40e8 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 13:53:45 +0200 Subject: implemented click captchas --- pyload/interaction/InteractionTask.py | 36 +++++++++--------- pyload/web/app/scripts/views/input/clickInput.js | 43 ++++++++++++++++++++++ pyload/web/app/scripts/views/input/inputLoader.js | 7 +++- pyload/web/app/scripts/views/input/inputView.js | 5 +++ pyload/web/app/scripts/views/queryModal.js | 16 +++++++- .../templates/default/dialogs/interactionTask.html | 2 +- 6 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 pyload/web/app/scripts/views/input/clickInput.js diff --git a/pyload/interaction/InteractionTask.py b/pyload/interaction/InteractionTask.py index b404aa6ce..498d807c0 100644 --- a/pyload/interaction/InteractionTask.py +++ b/pyload/interaction/InteractionTask.py @@ -1,27 +1,25 @@ # -*- 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 . - - @author: RaNaN -""" +############################################################################### +# Copyright(c) 2008-2014 pyLoad Team +# http://www.pyload.org +# +# This file is part of pyLoad. +# pyLoad is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# Subjected to the terms and conditions in LICENSE +# +# @author: RaNaN +############################################################################### from time import time from pyload.Api import InteractionTask as BaseInteractionTask from pyload.Api import Interaction, InputType, Input -#noinspection PyUnresolvedReferences +# noinspection PyUnresolvedReferences class InteractionTask(BaseInteractionTask): """ General Interaction Task extends ITask defined by api with additional fields and methods. @@ -61,6 +59,10 @@ class InteractionTask(BaseInteractionTask): self.wait_until = 0 def convertResult(self, value): + if self.input.type == InputType.Click: + parts = value.split(',') + return int(parts[0]), int(parts[1]) + #TODO: convert based on input/output return value diff --git a/pyload/web/app/scripts/views/input/clickInput.js b/pyload/web/app/scripts/views/input/clickInput.js new file mode 100644 index 000000000..873c81ce7 --- /dev/null +++ b/pyload/web/app/scripts/views/input/clickInput.js @@ -0,0 +1,43 @@ +define(['jquery', 'backbone', 'underscore', 'helpers/gettext', './inputView'], function($, Backbone, _, gettext, inputView) { + 'use strict'; + + return inputView.extend({ + + tagName: 'input', + events: { + 'keyup': 'onChange', + 'focus': 'showTooltip', + 'focusout': 'hideTooltip' + }, + + renderInput: function() { + this.$el.attr('disabled', 'on'); + this.$el.attr('type', 'text'); + this.$el.attr('name', 'textInput'); + + if (this.default_value) + this.$el.attr('placeholder', this.default_value); + else + this.$el.attr('placeholder', gettext('Please click on the right position in the captcha.')); + + if (this.value) + this.$el.val(this.value); + + return this; + }, + + onClick: function(x,y) { + this.$el.val(x + "," + y); + this.onChange(); + }, + + clear: function() { + this.$el.val(''); + }, + + onChange: function(e) { + this.setVal(this.$el.val()); + } + + }); +}); \ No newline at end of file diff --git a/pyload/web/app/scripts/views/input/inputLoader.js b/pyload/web/app/scripts/views/input/inputLoader.js index 04d591d30..c28572c6c 100644 --- a/pyload/web/app/scripts/views/input/inputLoader.js +++ b/pyload/web/app/scripts/views/input/inputLoader.js @@ -1,8 +1,13 @@ -define(['./textInput'], function(textInput) { +define(['utils/apitypes', './textInput', './clickInput'], function(Api, textInput, clickInput) { 'use strict'; // selects appropriate input element return function(input) { + console.log('Select input', input); + + if (input.type == Api.InputType.Click) + return clickInput; + return textInput; }; }); \ No newline at end of file diff --git a/pyload/web/app/scripts/views/input/inputView.js b/pyload/web/app/scripts/views/input/inputView.js index 1860fcaf1..394e33aef 100644 --- a/pyload/web/app/scripts/views/input/inputView.js +++ b/pyload/web/app/scripts/views/input/inputView.js @@ -38,6 +38,11 @@ define(['jquery', 'backbone', 'underscore'], function($, Backbone, _) { return this; }, + // triggered by captcha clicks + onClick: function(x,y) { + + }, + renderInput: function() { // Overwrite this }, diff --git a/pyload/web/app/scripts/views/queryModal.js b/pyload/web/app/scripts/views/queryModal.js index ce624814a..be66a47b4 100644 --- a/pyload/web/app/scripts/views/queryModal.js +++ b/pyload/web/app/scripts/views/queryModal.js @@ -1,9 +1,10 @@ -define(['jquery', 'underscore', 'app', 'views/abstract/modalView', './input/inputLoader', 'hbs!tpl/dialogs/interactionTask'], - function($, _, App, modalView, load_input, template) { +define(['jquery', 'underscore', 'app', 'utils/apitypes', 'views/abstract/modalView', './input/inputLoader', 'hbs!tpl/dialogs/interactionTask'], + function($, _, App, Api, modalView, load_input, template) { 'use strict'; return modalView.extend({ events: { + 'click #captchaImage': 'onClick', 'click .btn-success': 'submit', 'submit form': 'submit' }, @@ -31,6 +32,9 @@ define(['jquery', 'underscore', 'app', 'views/abstract/modalView', './input/inpu if (this.model.isCaptcha()) { data.captcha = input[0]; data.type = input[1]; + + if (input.type == Api.InputType.Click) + data.click = true; } return data; }, @@ -44,6 +48,14 @@ define(['jquery', 'underscore', 'app', 'views/abstract/modalView', './input/inpu this.$('#inputField').append(this.input.render().el); }, + onClick: function(e) { + var el = $(e.target); + var posX = el.offset().left, + posY = el.offset().top; + + this.input.onClick(Math.round(e.pageX - posX), Math.round(e.pageY - posY)); + }, + submit: function(e) { e.stopPropagation(); // TODO: load next task diff --git a/pyload/web/app/templates/default/dialogs/interactionTask.html b/pyload/web/app/templates/default/dialogs/interactionTask.html index 722d43365..e1d649d1a 100755 --- a/pyload/web/app/templates/default/dialogs/interactionTask.html +++ b/pyload/web/app/templates/default/dialogs/interactionTask.html @@ -17,7 +17,7 @@
- +
-- cgit v1.2.3 From 9aa62273c897f67f0fd12b8d6e3bb3ea78e3be7a Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 14:18:09 +0200 Subject: fixed js hint --- pyload/web/app/scripts/views/input/clickInput.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyload/web/app/scripts/views/input/clickInput.js b/pyload/web/app/scripts/views/input/clickInput.js index 873c81ce7..ca8a954b8 100644 --- a/pyload/web/app/scripts/views/input/clickInput.js +++ b/pyload/web/app/scripts/views/input/clickInput.js @@ -27,7 +27,7 @@ define(['jquery', 'backbone', 'underscore', 'helpers/gettext', './inputView'], f }, onClick: function(x,y) { - this.$el.val(x + "," + y); + this.$el.val(x + ',' + y); this.onChange(); }, @@ -40,4 +40,4 @@ define(['jquery', 'backbone', 'underscore', 'helpers/gettext', './inputView'], f } }); -}); \ No newline at end of file +}); -- cgit v1.2.3 From 9b8d4a5db97489bfbb5116b081dbdc8de706e502 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 15:18:47 +0200 Subject: fixed click captcha size --- pyload/web/app/scripts/views/queryModal.js | 9 ++++++--- pyload/web/app/styles/default/style.less | 6 ++++++ pyload/web/app/templates/default/dialogs/interactionTask.html | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pyload/web/app/scripts/views/queryModal.js b/pyload/web/app/scripts/views/queryModal.js index be66a47b4..6877687b3 100644 --- a/pyload/web/app/scripts/views/queryModal.js +++ b/pyload/web/app/scripts/views/queryModal.js @@ -3,6 +3,8 @@ define(['jquery', 'underscore', 'app', 'utils/apitypes', 'views/abstract/modalVi 'use strict'; return modalView.extend({ + className: 'query-modal', + events: { 'click #captchaImage': 'onClick', 'click .btn-success': 'submit', @@ -32,9 +34,6 @@ define(['jquery', 'underscore', 'app', 'utils/apitypes', 'views/abstract/modalVi if (this.model.isCaptcha()) { data.captcha = input[0]; data.type = input[1]; - - if (input.type == Api.InputType.Click) - data.click = true; } return data; }, @@ -44,6 +43,9 @@ define(['jquery', 'underscore', 'app', 'utils/apitypes', 'views/abstract/modalVi var input = this.model.get('input'); var InputView = load_input(input); this.input = new InputView({input: input}); + if (input.type == Api.InputType.Click) + this.$('#captchaImage').css('cursor', 'crosshair'); + // only renders after wards this.$('#inputField').append(this.input.render().el); }, @@ -53,6 +55,7 @@ define(['jquery', 'underscore', 'app', 'utils/apitypes', 'views/abstract/modalVi var posX = el.offset().left, posY = el.offset().top; + // TODO: calculate image size, scale positions to displayed / real image size this.input.onClick(Math.round(e.pageX - posX), Math.round(e.pageY - posY)); }, diff --git a/pyload/web/app/styles/default/style.less b/pyload/web/app/styles/default/style.less index ad60e5b59..fb441b882 100644 --- a/pyload/web/app/styles/default/style.less +++ b/pyload/web/app/styles/default/style.less @@ -222,6 +222,12 @@ header { // background-color: @greyDark; } +.query-modal { + img { + max-width: none; + } +} + /* Actionbar */ diff --git a/pyload/web/app/templates/default/dialogs/interactionTask.html b/pyload/web/app/templates/default/dialogs/interactionTask.html index e1d649d1a..722d43365 100755 --- a/pyload/web/app/templates/default/dialogs/interactionTask.html +++ b/pyload/web/app/templates/default/dialogs/interactionTask.html @@ -17,7 +17,7 @@
- +
-- cgit v1.2.3 From a6097f1fad3a8d8193dab5f4d531246e5103d64c Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 16:57:53 +0200 Subject: small fix for info fetching --- pyload/threads/InfoThread.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyload/threads/InfoThread.py b/pyload/threads/InfoThread.py index 1ff68fb45..1c95d9aca 100644 --- a/pyload/threads/InfoThread.py +++ b/pyload/threads/InfoThread.py @@ -31,6 +31,9 @@ class InfoThread(DecrypterThread): plugins = accumulate(self.data) crypter = {} + # db or info result + cb = self.updateDB if self.pid > 1 else self.updateResult + # filter out crypter plugins for name in self.m.core.pluginManager.getPlugins("crypter"): if name in plugins: @@ -41,22 +44,19 @@ class InfoThread(DecrypterThread): # decrypt them links, packages = self.decrypt(crypter, err=True) # push these as initial result and save package names - self.updateResult(links) + cb(links) for pack in packages: for url in pack.getURLs(): self.names[url] = pack.name links.extend(pack.links) - self.updateResult(pack.links) + cb(pack.links) # TODO: no plugin information pushed to GUI # parse links and merge hoster, crypter = self.m.core.pluginManager.parseUrls([l.url for l in links]) accumulate(hoster + crypter, plugins) - # db or info result - cb = self.updateDB if self.pid > 1 else self.updateResult - self.progress = ProgressInfo("BasePlugin", "", _("online check"), 0, 0, sum(len(urls) for urls in plugins.itervalues()), self.owner, ProgressType.LinkCheck) @@ -102,6 +102,7 @@ class InfoThread(DecrypterThread): # merge in packages that already have a name data = accumulate(tmp.iteritems(), data) + # TODO: self.oc is None ?! self.m.setInfoResults(self.oc, data) def fetchForPlugin(self, plugin, urls, cb): -- cgit v1.2.3 From 81d50016d902df49208ee606ada7d69325a7ea15 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 18:46:15 +0200 Subject: implemented deprecated method for some crypter --- pyload/plugins/Crypter.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyload/plugins/Crypter.py b/pyload/plugins/Crypter.py index b6bdb1edd..d2a9482d1 100644 --- a/pyload/plugins/Crypter.py +++ b/pyload/plugins/Crypter.py @@ -286,6 +286,11 @@ class Crypter(Base): """ Retry decrypting, will only work once. Somewhat deprecated method, should be avoided. """ raise Retry() + def getPassword(): + """ Deprecated """ + self.logDebug("Deprecated method .getPassword(), use self.password instead.") + return self.password + def convertPackages(self): """ Deprecated """ self.logDebug("Deprecated method .convertPackages()") @@ -300,4 +305,4 @@ class Crypter(Base): def clean(self): if hasattr(self, "req"): self.req.close() - del self.req \ No newline at end of file + del self.req -- cgit v1.2.3 From 33f2bd9970a6c03c8ba8924277b39b06bba011db Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 1 Jun 2014 19:22:27 +0200 Subject: added missing argument --- pyload/plugins/Crypter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyload/plugins/Crypter.py b/pyload/plugins/Crypter.py index d2a9482d1..e3b373dbb 100644 --- a/pyload/plugins/Crypter.py +++ b/pyload/plugins/Crypter.py @@ -286,7 +286,7 @@ class Crypter(Base): """ Retry decrypting, will only work once. Somewhat deprecated method, should be avoided. """ raise Retry() - def getPassword(): + def getPassword(self): """ Deprecated """ self.logDebug("Deprecated method .getPassword(), use self.password instead.") return self.password -- cgit v1.2.3