source: titan/mediathek/localhoster/lib/recaptcha_v2.py @ 39020

Last change on this file since 39020 was 38962, checked in by obi, 8 years ago

localhoster add needed libs

File size: 7.5 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3    urlresolver XBMC Addon
4    Copyright (C) 2016 tknorris
5    Derived from Shani's LPro Code (https://github.com/Shani-08/ShaniXBMCWork2/blob/master/plugin.video.live.streamspro/unCaptcha.py)
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20    reusable captcha methods
21"""
22import re
23import urllib
24import urllib2
25import os
26import xbmcgui
27from urlresolver import common
28
29class cInputWindow(xbmcgui.WindowDialog):
30
31    def __init__(self, *args, **kwargs):
32        bg_image = os.path.join(common.addon_path, 'resources', 'images', 'DialogBack2.png')
33        check_image = os.path.join(common.addon_path, 'resources', 'images', 'checked.png')
34        self.cancelled = False
35        self.chk = [0] * 9
36        self.chkbutton = [0] * 9
37        self.chkstate = [False] * 9
38
39        imgX, imgY, imgw, imgh = 436, 210, 408, 300
40        ph, pw = imgh / 3, imgw / 3
41        x_gap = 70
42        y_gap = 70
43        button_gap = 40
44        button_h = 40
45        button_y = imgY + imgh + button_gap
46        middle = imgX + (imgw / 2)
47        win_x = imgX - x_gap
48        win_y = imgY - y_gap
49        win_h = imgh + 2 * y_gap + button_h + button_gap
50        win_w = imgw + 2 * x_gap
51
52        ctrlBackgound = xbmcgui.ControlImage(win_x, win_y, win_w, win_h, bg_image)
53        self.addControl(ctrlBackgound)
54        self.msg = '[COLOR red]%s[/COLOR]' % (kwargs.get('msg'))
55        self.strActionInfo = xbmcgui.ControlLabel(imgX, imgY - 30, imgw, 20, self.msg, 'font13')
56        self.addControl(self.strActionInfo)
57        img = xbmcgui.ControlImage(imgX, imgY, imgw, imgh, kwargs.get('captcha'))
58        self.addControl(img)
59        self.iteration = kwargs.get('iteration')
60        self.strActionInfo = xbmcgui.ControlLabel(imgX, imgY + imgh, imgw, 20, 'Captcha Round: %s [I](2 Rounds is typical)[/I]' % (str(self.iteration)), 'font40')
61        self.addControl(self.strActionInfo)
62        self.cancelbutton = xbmcgui.ControlButton(middle - 110, button_y, 100, button_h, 'Cancel', alignment=2)
63        self.okbutton = xbmcgui.ControlButton(middle + 10, button_y, 100, button_h, 'OK', alignment=2)
64        self.addControl(self.okbutton)
65        self.addControl(self.cancelbutton)
66
67        for i in xrange(9):
68            row = i / 3
69            col = i % 3
70            x_pos = imgX + (pw * col)
71            y_pos = imgY + (ph * row)
72            self.chk[i] = xbmcgui.ControlImage(x_pos, y_pos, pw, ph, check_image)
73            self.addControl(self.chk[i])
74            self.chk[i].setVisible(False)
75            self.chkbutton[i] = xbmcgui.ControlButton(x_pos, y_pos, pw, ph, str(i + 1), font='font1')
76            self.addControl(self.chkbutton[i])
77
78        for i in xrange(9):
79            row_start = (i / 3) * 3
80            right = row_start + (i + 1) % 3
81            left = row_start + (i - 1) % 3
82            up = (i - 3) % 9
83            down = (i + 3) % 9
84            self.chkbutton[i].controlRight(self.chkbutton[right])
85            self.chkbutton[i].controlLeft(self.chkbutton[left])
86            if i <= 2:
87                self.chkbutton[i].controlUp(self.okbutton)
88            else:
89                self.chkbutton[i].controlUp(self.chkbutton[up])
90
91            if i >= 6:
92                self.chkbutton[i].controlDown(self.okbutton)
93            else:
94                self.chkbutton[i].controlDown(self.chkbutton[down])
95
96        self.okbutton.controlLeft(self.cancelbutton)
97        self.okbutton.controlRight(self.cancelbutton)
98        self.cancelbutton.controlLeft(self.okbutton)
99        self.cancelbutton.controlRight(self.okbutton)
100        self.okbutton.controlDown(self.chkbutton[2])
101        self.okbutton.controlUp(self.chkbutton[8])
102        self.cancelbutton.controlDown(self.chkbutton[0])
103        self.cancelbutton.controlUp(self.chkbutton[6])
104        self.setFocus(self.okbutton)
105
106    def get(self):
107        self.doModal()
108        self.close()
109        if not self.cancelled:
110            return [i for i in xrange(9) if self.chkstate[i]]
111
112    def onControl(self, control):
113        if control == self.okbutton and any(self.chkstate):
114            self.close()
115
116        elif control == self.cancelbutton:
117            self.cancelled = True
118            self.close()
119        else:
120            label = control.getLabel()
121            if label.isnumeric():
122                index = int(label) - 1
123                self.chkstate[index] = not self.chkstate[index]
124                self.chk[index].setVisible(self.chkstate[index])
125
126    def onAction(self, action):
127        if action == 10:
128            self.cancelled = True
129            self.close()
130
131class UnCaptchaReCaptcha:
132
133    def processCaptcha(self, key, lang):
134        headers = {'Referer': 'https://www.google.com/recaptcha/api2/demo', 'Accept-Language': lang}
135        html = get_url('http://www.google.com/recaptcha/api/fallback?k=%s' % (key), headers=headers)
136        token = ''
137        iteration = 0
138        while True:
139            payload = re.findall('"(/recaptcha/api2/payload[^"]+)', html)
140            iteration += 1
141            message = re.findall('<label[^>]+class="fbc-imageselect-message-text"[^>]*>(.*?)</label>', html)
142            if not message:
143                message = re.findall('<div[^>]+class="fbc-imageselect-message-error">(.*?)</div>', html)
144            if not message:
145                token = re.findall('"this\.select\(\)">(.*?)</textarea>', html)[0]
146                if token:
147                    common.log_utils.log_debug('Captcha Success: %s' % (token))
148                else:
149                    common.log_utils.log_debug('Captcha Failed: %s')
150                break
151            else:
152                message = message[0]
153                payload = payload[0]
154
155            cval = re.findall('name="c"\s+value="([^"]+)', html)[0]
156            captcha_imgurl = 'https://www.google.com%s' % (payload.replace('&amp;', '&'))
157            message = re.sub('</?strong>', '', message)
158            oSolver = cInputWindow(captcha=captcha_imgurl, msg=message, iteration=iteration)
159            captcha_response = oSolver.get()
160            if not captcha_response:
161                break
162
163            data = {'c': cval, 'response': captcha_response}
164            html = get_url("http://www.google.com/recaptcha/api/fallback?k=%s" % (key), data=data, headers=headers)
165        return token
166
167# TODO: Replace with common.Net() when urlencode is fixed in _fetch
168def get_url(url, data=None, timeout=20, headers=None):
169    if headers is None: headers = {}
170    if data is None: data = {}
171    post_data = urllib.urlencode(data, doseq=True)
172    if 'User-Agent' not in headers:
173        headers['User-Agent'] = common.FF_USER_AGENT
174    common.log_utils.log_debug('URL: |%s| Data: |%s| Headers: |%s|' % (url, post_data, headers))
175
176    req = urllib2.Request(url)
177    for key in headers:
178        req.add_header(key, headers[key])
179
180    response = urllib2.urlopen(req, data=post_data, timeout=timeout)
181    result = response.read()
182    response.close()
183    return result
Note: See TracBrowser for help on using the repository browser.