python-rucaptcha 5.1.5__py3-none-any.whl → 5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- __version__ = "5.1.5"
1
+ __version__ = "5.2"
@@ -5,7 +5,6 @@ from .core.enums import AmazonWAFCaptchaEnm
5
5
  class AmazonWAF(BaseCaptcha):
6
6
  def __init__(
7
7
  self,
8
- rucaptcha_key: str,
9
8
  pageurl: str,
10
9
  sitekey: str,
11
10
  iv: str,
@@ -56,7 +55,7 @@ class AmazonWAF(BaseCaptcha):
56
55
  Notes:
57
56
  https://rucaptcha.com/api-rucaptcha#amazon-waf
58
57
  """
59
- super().__init__(rucaptcha_key=rucaptcha_key, method=method, *args, **kwargs)
58
+ super().__init__(method=method, *args, **kwargs)
60
59
 
61
60
  self.post_payload.update({"sitekey": sitekey, "pageurl": pageurl, "iv": iv, "context": context})
62
61
 
@@ -0,0 +1,208 @@
1
+ import base64
2
+ import shutil
3
+ from typing import Optional
4
+
5
+ from .core.base import BaseCaptcha
6
+ from .core.enums import SaveFormatsEnm, AudioCaptchaEnm
7
+
8
+
9
+ class AudioCaptcha(BaseCaptcha):
10
+ def __init__(
11
+ self,
12
+ save_format: str = SaveFormatsEnm.TEMP.value,
13
+ img_clearing: bool = True,
14
+ img_path: str = "PythonRuCaptchaAudio",
15
+ lang: str = "en",
16
+ *args,
17
+ **kwargs,
18
+ ):
19
+ """
20
+ The class is used to work with Text Captcha.
21
+
22
+ Args:
23
+ rucaptcha_key: User API key
24
+ save_format: The format in which the file will be saved, or as a temporary file - 'temp',
25
+ or as a regular file to a folder created by the library - 'const'.
26
+ img_clearing: True - delete file after solution, False - don't delete file after solution
27
+ img_path: Folder to save captcha audio
28
+ lang: Captcha audio lang: `en`, `fr`, `de`, `el`, `pt`, `ru`
29
+
30
+ Examples:
31
+ >>> AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
32
+ ... lang='en'
33
+ ... ).captcha_handler(captcha_file='examples/mediacaptcha_audio/recaptcha_55914.mp3')
34
+ {
35
+ 'captchaSolve': 'five five nine one four',
36
+ 'taskId': 73243152973,
37
+ 'error': False,
38
+ 'errorBody': None
39
+ }
40
+
41
+ >>> await AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
42
+ ... lang='en'
43
+ ... ).aio_captcha_handler(captcha_file='examples/mediacaptcha_audio/recaptcha_55914.mp3')
44
+ {
45
+ 'captchaSolve': 'five five nine one four',
46
+ 'taskId': 73243152973,
47
+ 'error': False,
48
+ 'errorBody': None
49
+ }
50
+
51
+ Returns:
52
+ Dict with full server response
53
+
54
+ Notes:
55
+ https://rucaptcha.com/api-rucaptcha#audio
56
+ """
57
+
58
+ super().__init__(method=AudioCaptchaEnm.AUDIO.value, *args, **kwargs)
59
+ self.save_format = save_format
60
+ self.img_clearing = img_clearing
61
+ self.img_path = img_path
62
+
63
+ self.post_payload.update({"lang": lang})
64
+
65
+ def captcha_handler(
66
+ self,
67
+ captcha_link: Optional[str] = None,
68
+ captcha_file: Optional[str] = None,
69
+ captcha_base64: Optional[bytes] = None,
70
+ **kwargs,
71
+ ) -> dict:
72
+ """
73
+ Synchronous method for captcha solving
74
+
75
+ Args:
76
+ captcha_link: Captcha file URL
77
+ captcha_file: Captcha file path
78
+ captcha_base64: Captcha file BASE64 info
79
+ kwargs: additional params for `requests` library
80
+
81
+ Examples:
82
+ >>> AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
83
+ ... lang='en'
84
+ ... ).captcha_handler(captcha_file='examples/mediacaptcha_audio/recaptcha_55914.mp3')
85
+ {
86
+ 'captchaSolve': 'five five nine one four',
87
+ 'taskId': 73243152973,
88
+ 'error': False,
89
+ 'errorBody': None
90
+ }
91
+
92
+ >>> AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
93
+ ... lang='en'
94
+ ... ).captcha_handler(captcha_link='http://some/link/address/recaptcha_55914.mp3')
95
+ {
96
+ 'captchaSolve': 'five five nine one four',
97
+ 'taskId': 73243152973,
98
+ 'error': False,
99
+ 'errorBody': None
100
+ }
101
+
102
+ Returns:
103
+ Dict with full server response
104
+
105
+ Notes:
106
+ Check class docstirng for more info
107
+ """
108
+ # if a local file link is passed
109
+ if captcha_file:
110
+ self.post_payload.update({"body": base64.b64encode(self._local_file_captcha(captcha_file)).decode("utf-8")})
111
+ # if the file is transferred in base64 encoding
112
+ elif captcha_base64:
113
+ self.post_payload.update({"body": base64.b64encode(captcha_base64).decode("utf-8")})
114
+ # if a URL is passed
115
+ elif captcha_link:
116
+ try:
117
+ content = self.url_open(url=captcha_link, **kwargs).content
118
+ except Exception as error:
119
+ self.result.error = True
120
+ self.result.errorBody = str(error)
121
+ return self.result.dict()
122
+
123
+ # according to the value of the passed parameter, select the function to save the file
124
+ if self.save_format == SaveFormatsEnm.CONST.value:
125
+ self._file_const_saver(content, self.img_path, file_extension="mp3")
126
+ self.post_payload.update({"body": base64.b64encode(content).decode("utf-8")})
127
+
128
+ else:
129
+ # if none of the parameters are passed
130
+ self.result.error = True
131
+ self.result.errorBody = self.NO_CAPTCHA_ERR
132
+ return self.result.dict()
133
+
134
+ return self._processing_response(**kwargs)
135
+
136
+ async def aio_captcha_handler(
137
+ self,
138
+ captcha_link: Optional[str] = None,
139
+ captcha_file: Optional[str] = None,
140
+ captcha_base64: Optional[bytes] = None,
141
+ **kwargs,
142
+ ) -> dict:
143
+ """
144
+ Asynchronous method for captcha solving
145
+
146
+ Args:
147
+ captcha_link: Captcha file URL
148
+ captcha_file: Captcha file path
149
+ captcha_base64: Captcha file BASE64
150
+ kwargs: additional params for `aiohttp` library
151
+
152
+ Examples:
153
+ >>> await AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
154
+ ... lang='en'
155
+ ... ).aio_captcha_handler(captcha_file='examples/mediacaptcha_audio/recaptcha_55914.mp3')
156
+ {
157
+ 'captchaSolve': 'five five nine one four',
158
+ 'taskId': 73243152973,
159
+ 'error': False,
160
+ 'errorBody': None
161
+ }
162
+ >>> await AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
163
+ ... lang='en'
164
+ ... ).aio_captcha_handler(captcha_link='http://some/link/address/recaptcha_55914.mp3')
165
+ {
166
+ 'captchaSolve': 'five five nine one four',
167
+ 'taskId': 73243152973,
168
+ 'error': False,
169
+ 'errorBody': None
170
+ }
171
+
172
+ Returns:
173
+ Dict with full server response
174
+
175
+ Notes:
176
+ Check class docstirng for more info
177
+ """
178
+ # if a local file link is passed
179
+ if captcha_file:
180
+ self.post_payload.update({"body": base64.b64encode(self._local_file_captcha(captcha_file)).decode("utf-8")})
181
+ # if the file is transferred in base64 encoding
182
+ elif captcha_base64:
183
+ self.post_payload.update({"body": base64.b64encode(captcha_base64).decode("utf-8")})
184
+ # if a URL is passed
185
+ elif captcha_link:
186
+ try:
187
+ content = await self.aio_url_read(url=captcha_link, **kwargs)
188
+ except Exception as error:
189
+ self.result.error = True
190
+ self.result.errorBody = str(error)
191
+ return self.result.dict()
192
+
193
+ # according to the value of the passed parameter, select the function to save the file
194
+ if self.save_format == SaveFormatsEnm.CONST.value:
195
+ self._file_const_saver(content, self.img_path)
196
+ self.post_payload.update({"body": base64.b64encode(content).decode("utf-8")})
197
+
198
+ else:
199
+ # if none of the parameters are passed
200
+ self.result.error = True
201
+ self.result.errorBody = self.NO_CAPTCHA_ERR
202
+ return self.result.dict()
203
+
204
+ return await self._aio_processing_response()
205
+
206
+ def __del__(self):
207
+ if self.save_format == SaveFormatsEnm.CONST.value and self.img_clearing:
208
+ shutil.rmtree(self.img_path)
@@ -37,6 +37,31 @@ class Control(BaseCaptcha):
37
37
  'errorBody': None
38
38
  }
39
39
 
40
+ Death By Captcha example:
41
+
42
+ >>> Control(rucaptcha_key="service_username:service_password",
43
+ ... service_type="other-captcha-services",
44
+ ... action=ControlEnm.GETBALANCE.value).additional_methods()
45
+ {
46
+ 'captchaSolve': '0.00',
47
+ 'taskId': None,
48
+ 'error': False,
49
+ 'errorBody': None
50
+ }
51
+
52
+ Death By Captcha example:
53
+
54
+ >>> from python_rucaptcha.core.enums import ControlEnm, ServiceEnm
55
+ >>> Control(rucaptcha_key="service_username:service_password",
56
+ ... service_type=ServiceEnm.DEATHBYCAPTCHA,
57
+ ... action=ControlEnm.GETBALANCE.value).additional_methods()
58
+ {
59
+ 'captchaSolve': '0.00',
60
+ 'taskId': None,
61
+ 'error': False,
62
+ 'errorBody': None
63
+ }
64
+
40
65
  Returns:
41
66
  Dict with full server response
42
67
 
@@ -46,7 +71,7 @@ class Control(BaseCaptcha):
46
71
  https://rucaptcha.com/api-rucaptcha#additional
47
72
  """
48
73
 
49
- super().__init__(action=action, *args, **kwargs)
74
+ super().__init__(method=ControlEnm.CONTROL.value, action=action, *args, **kwargs)
50
75
 
51
76
  # check user params
52
77
  if action not in ControlEnm.list_values():
@@ -20,10 +20,10 @@ class BaseCaptcha:
20
20
  def __init__(
21
21
  self,
22
22
  rucaptcha_key: str,
23
- method: str = "",
23
+ method: str,
24
24
  action: str = "get",
25
25
  sleep_time: int = 15,
26
- service_type: str = enums.ServicesEnm.TWOCAPTCHA.value,
26
+ service_type: str = enums.ServiceEnm.TWOCAPTCHA.value,
27
27
  **kwargs,
28
28
  ):
29
29
  """
@@ -36,7 +36,7 @@ class BaseCaptcha:
36
36
  :param kwargs: Designed to pass OPTIONAL parameters to the payload for a request to RuCaptcha
37
37
  """
38
38
  # assign args to validator
39
- self.params = CaptchaOptionsSer(**locals())
39
+ self.params = CaptchaOptionsSer(**locals(), **kwargs)
40
40
 
41
41
  # prepare POST payload
42
42
  self.post_payload = PostRequestSer(key=self.params.rucaptcha_key, method=method).dict(by_alias=True)
@@ -154,24 +154,24 @@ class BaseCaptcha:
154
154
  # Working with images methods
155
155
 
156
156
  @staticmethod
157
- def _local_image_captcha(captcha_file: str):
157
+ def _local_file_captcha(captcha_file: str):
158
158
  """
159
- Method get local image, read it and prepare for sending to Captcha solving service
159
+ Method get local file, read it and prepare for sending to Captcha solving service
160
160
  """
161
161
  with open(captcha_file, "rb") as file:
162
162
  return file.read()
163
163
 
164
- def _image_const_saver(self, content: bytes, img_path: str):
164
+ def _file_const_saver(self, content: bytes, file_path: str, file_extension: str = "png"):
165
165
  """
166
166
  Method create and save file in folder
167
167
  """
168
- Path(img_path).mkdir(parents=True, exist_ok=True)
168
+ Path(file_path).mkdir(parents=True, exist_ok=True)
169
169
 
170
170
  # generate image name
171
- self._image_name = f"im-{uuid.uuid4()}.png"
171
+ self._file_name = f"file-{uuid.uuid4()}.{file_extension}"
172
172
 
173
173
  # save image to folder
174
- with open(os.path.join(img_path, self._image_name), "wb") as out_image:
174
+ with open(os.path.join(file_path, self._file_name), "wb") as out_image:
175
175
  out_image.write(content)
176
176
 
177
177
  def __enter__(self):
@@ -20,9 +20,10 @@ class MyEnum(Enum):
20
20
  return list(map(lambda c: c.name, cls))
21
21
 
22
22
 
23
- class ServicesEnm(str, MyEnum):
23
+ class ServiceEnm(str, MyEnum):
24
24
  TWOCAPTCHA = "2captcha"
25
25
  RUCAPTCHA = "rucaptcha"
26
+ DEATHBYCAPTCHA = "other-captcha-services"
26
27
 
27
28
 
28
29
  class SaveFormatsEnm(str, MyEnum):
@@ -72,6 +73,9 @@ class TikTokCaptchaEnm(str, MyEnum):
72
73
 
73
74
 
74
75
  class ControlEnm(str, MyEnum):
76
+ # control method
77
+ CONTROL = "control"
78
+
75
79
  # default
76
80
  GET = "get"
77
81
  # https://rucaptcha.com/api-rucaptcha#manage_pingback
@@ -98,3 +102,11 @@ class TurnstileCaptchaEnm(str, MyEnum):
98
102
 
99
103
  class AmazonWAFCaptchaEnm(str, MyEnum):
100
104
  AMAZON_WAF = "amazon_waf"
105
+
106
+
107
+ class TextCaptchaEnm(str, MyEnum):
108
+ TEXT = "text"
109
+
110
+
111
+ class AudioCaptchaEnm(str, MyEnum):
112
+ AUDIO = "audio"
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  from uuid import uuid4
2
3
  from typing import Union, Optional
3
4
 
@@ -94,34 +95,53 @@ class GetRequestSer(BaseModel):
94
95
 
95
96
 
96
97
  class CaptchaOptionsSer(BaseModel):
97
- rucaptcha_key: constr(min_length=32, max_length=32)
98
98
  method: str
99
99
  action: str
100
100
  sleep_time: conint(gt=5) = 10
101
- service_type: str = enums.ServicesEnm.TWOCAPTCHA.value
101
+ service_type: str = enums.ServiceEnm.TWOCAPTCHA.value
102
+ rucaptcha_key: constr(min_length=1)
102
103
 
103
- # CaptchaImage
104
- # save_format: str = enums.SaveFormatsEnm.TEMP.value
105
- # img_clearing: bool = True
106
- # img_path: str = "PythonRuCaptchaImages"
104
+ url_request: Optional[str] = None # /in.php
105
+ url_response: Optional[str] = None # /res.php
107
106
 
108
- url_request: str = ""
109
- url_response: str = ""
107
+ @validator("rucaptcha_key")
108
+ def rucaptcha_key_check(cls, value, values, **kwargs):
109
+ service_type = values.get("service_type")
110
+ if service_type in (enums.ServiceEnm.RUCAPTCHA, enums.ServiceEnm.TWOCAPTCHA):
111
+ if len(value) != 32:
112
+ raise ValueError(f"Invalid `rucaptcha_key` len, it must be - 32, u send - {len(value)}")
113
+ return value
110
114
 
111
115
  @validator("service_type")
112
116
  def service_type_check(cls, value):
113
- if value not in enums.ServicesEnm.list_values():
114
- raise ValueError(
115
- f"Invalid `service_type`, valid params - {','.join(enums.ServicesEnm.list_values())}, send - {value}"
117
+ if value not in enums.ServiceEnm.list_values():
118
+ logging.warning(
119
+ f"We support only this list of services - '{', '.join(enums.ServiceEnm.list_values())}', u send - '{value}'. "
120
+ f"All other services you use at your own risk"
116
121
  )
117
122
  return value
118
123
 
119
124
  @root_validator
120
125
  def urls_set(cls, values):
121
- service_type = values.get("service_type")
122
- values.update(
123
- {"url_request": f"http://{service_type}.com/in.php", "url_response": f"http://{service_type}.com/res.php"}
124
- )
126
+ """
127
+ Set request \ response URLs if they not set previously
128
+ """
129
+ if not values.get("url_request") and not values.get("url_response"):
130
+ service_type = values.get("service_type")
131
+ if service_type == enums.ServiceEnm.DEATHBYCAPTCHA:
132
+ values.update(
133
+ {
134
+ "url_request": f"http://api.{service_type}.com/2captcha/in.php",
135
+ "url_response": f"http://api.{service_type}.com/2captcha/res.php",
136
+ }
137
+ )
138
+ else:
139
+ values.update(
140
+ {
141
+ "url_request": f"http://{service_type}.com/in.php",
142
+ "url_response": f"http://{service_type}.com/res.php",
143
+ }
144
+ )
125
145
  return values
126
146
 
127
147
 
@@ -112,13 +112,11 @@ class ImageCaptcha(BaseCaptcha):
112
112
  Dict with full server response
113
113
 
114
114
  Notes:
115
- https://rucaptcha.com/api-rucaptcha#solving_funcaptcha_new
115
+ Check class docstirng for more info
116
116
  """
117
117
  # if a local file link is passed
118
118
  if captcha_file:
119
- self.post_payload.update(
120
- {"body": base64.b64encode(self._local_image_captcha(captcha_file)).decode("utf-8")}
121
- )
119
+ self.post_payload.update({"body": base64.b64encode(self._local_file_captcha(captcha_file)).decode("utf-8")})
122
120
  # if the file is transferred in base64 encoding
123
121
  elif captcha_base64:
124
122
  self.post_payload.update({"body": base64.b64encode(captcha_base64).decode("utf-8")})
@@ -133,7 +131,7 @@ class ImageCaptcha(BaseCaptcha):
133
131
 
134
132
  # according to the value of the passed parameter, select the function to save the image
135
133
  if self.save_format == SaveFormatsEnm.CONST.value:
136
- self._image_const_saver(content, self.img_path)
134
+ self._file_const_saver(content, self.img_path)
137
135
  self.post_payload.update({"body": base64.b64encode(content).decode("utf-8")})
138
136
 
139
137
  else:
@@ -183,13 +181,11 @@ class ImageCaptcha(BaseCaptcha):
183
181
  Dict with full server response
184
182
 
185
183
  Notes:
186
- https://rucaptcha.com/api-rucaptcha#solving_funcaptcha_new
184
+ Check class docstirng for more info
187
185
  """
188
186
  # if a local file link is passed
189
187
  if captcha_file:
190
- self.post_payload.update(
191
- {"body": base64.b64encode(self._local_image_captcha(captcha_file)).decode("utf-8")}
192
- )
188
+ self.post_payload.update({"body": base64.b64encode(self._local_file_captcha(captcha_file)).decode("utf-8")})
193
189
  # if the file is transferred in base64 encoding
194
190
  elif captcha_base64:
195
191
  self.post_payload.update({"body": base64.b64encode(captcha_base64).decode("utf-8")})
@@ -204,7 +200,7 @@ class ImageCaptcha(BaseCaptcha):
204
200
 
205
201
  # according to the value of the passed parameter, select the function to save the image
206
202
  if self.save_format == SaveFormatsEnm.CONST.value:
207
- self._image_const_saver(content, self.img_path)
203
+ self._file_const_saver(content, self.img_path)
208
204
  self.post_payload.update({"body": base64.b64encode(content).decode("utf-8")})
209
205
 
210
206
  else:
@@ -1,10 +1,10 @@
1
1
  from .core.base import BaseCaptcha
2
+ from .core.enums import TextCaptchaEnm
2
3
 
3
4
 
4
5
  class TextCaptcha(BaseCaptcha):
5
6
  def __init__(
6
7
  self,
7
- rucaptcha_key: str,
8
8
  language: int = 0,
9
9
  *args,
10
10
  **kwargs,
@@ -45,7 +45,7 @@ class TextCaptcha(BaseCaptcha):
45
45
  https://rucaptcha.com/api-rucaptcha#solving_text_captcha
46
46
  """
47
47
 
48
- super().__init__(rucaptcha_key=rucaptcha_key, *args, **kwargs)
48
+ super().__init__(method=TextCaptchaEnm.TEXT.value, *args, **kwargs)
49
49
 
50
50
  self.post_payload.update({"language": language})
51
51
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-rucaptcha
3
- Version: 5.1.5
3
+ Version: 5.2
4
4
  Summary: Python 3.7+ RuCaptcha library with AIO module.
5
5
  Home-page: https://andreidrang.github.io/python-rucaptcha/
6
6
  Author: AndreiDrang, redV0ID
@@ -13,6 +13,7 @@ Project-URL: Issue tracker, https://github.com/AndreiDrang/python-rucaptcha/issu
13
13
  Keywords: captcha
14
14
  rucaptcha
15
15
  2captcha
16
+ deathbycaptcha
16
17
  recaptcha
17
18
  geetest
18
19
  hcaptcha
@@ -114,6 +115,8 @@ Is described in the [documentation-website](https://andreidrang.github.io/python
114
115
 
115
116
  ### Changelog
116
117
 
118
+ - v.5.3 - Added support for [Death By Captcha](https://deathbycaptcha.com/) and other services by changing `service_type` and `url_request` \ `url_response` parameters.
119
+ - v.5.2 - Added Audio captcha method.
117
120
  - v.5.1 - Check [releases page](https://github.com/AndreiDrang/python-rucaptcha/releases).
118
121
  - v.5.0 - Added AmazonWAF captcha method.
119
122
  - v.4.2 - Added [Yandex Smart Captcha](https://rucaptcha.com/api-rucaptcha#yandex).
@@ -1,28 +1,29 @@
1
1
  python_rucaptcha/SocketAPI.py,sha256=W_ZmEaNTMx--lvaYiLJyckWGt3P-gxoZf0qdxK-onb0,4291
2
2
  python_rucaptcha/TikTokCaptcha.py,sha256=PF1ZeV3tb1e2ig3w6kfqqHQzAMOhmGxKjiAyizBRzks,2122
3
3
  python_rucaptcha/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_rucaptcha/__version__.py,sha256=iuyP95EWNF1uITAbMAYesfeNd_xgRbn4iq1J3kpldnA,22
5
- python_rucaptcha/amazon_waf.py,sha256=ef1YhPb0Q2BoQSFY1XsLWk-bmeG5ISHu85EOUTGbeYE,4442
4
+ python_rucaptcha/__version__.py,sha256=w-7iTykPeImrjtpuwfo7ztWT6laCATvHs7mwCtvIvZs,20
5
+ python_rucaptcha/amazon_waf.py,sha256=On5PdMYuyWp0DLdmnCs04CuYALEx-aKo0P-USsk-dgk,4385
6
+ python_rucaptcha/audio_captcha.py,sha256=HFAzvEMwgqmjx3mu8_6az4T4YCqqcIzEB5pRc4V0Ojo,7879
6
7
  python_rucaptcha/capy_puzzle.py,sha256=wgofttv2qp-7_xHClKE8E6jlV1ca0H4m9fw0ZVnq7RU,7077
7
- python_rucaptcha/control.py,sha256=kGKX1DtFGRCoooGJ5lW5U0Xb7w6hjACU9RLOF7qjLOk,12513
8
+ python_rucaptcha/control.py,sha256=xOLHFrXh2OCb-UFYI9Kxcxkj_B4CX2FsLqMHCWjoMHI,13476
8
9
  python_rucaptcha/fun_captcha.py,sha256=0IdsCe_4HxSgtdhBb3B6w_LaSel89IUEQYL7_m2D2i4,3859
9
10
  python_rucaptcha/gee_test.py,sha256=-mHV8w717UhsmjQUknZgl1elNEXRz-h5GC6S3QtEM6U,10436
10
11
  python_rucaptcha/hcaptcha.py,sha256=lvBpIqlZnELEu6aXcAn0hGWybtYvXn0Gmzq4KXO9hPg,3844
11
- python_rucaptcha/image_captcha.py,sha256=TXmJmlBHoqeepVu0NxLrBYj1FoyIdNwAXLPqpwCUT-k,9391
12
+ python_rucaptcha/image_captcha.py,sha256=hSLEHV6w-ekthZfdIsIzIM5Wm4QYd3XsDiewb6FRoAM,9281
12
13
  python_rucaptcha/key_captcha.py,sha256=qdWlHdLg2RzBGtkBDdGwyfpsLu821Iy2Pk2tIe1p7WI,5022
13
14
  python_rucaptcha/lemin_cropped_captcha.py,sha256=m51lbpFk_QHAXUIlaBS7YEkTetZmyKDz0tzHeufz-mU,5209
14
15
  python_rucaptcha/re_captcha.py,sha256=9k9_ErZkSge-IrjMAYMbrmkScDD9XAMnny0ko3gNx5I,5437
15
16
  python_rucaptcha/rotate_captcha.py,sha256=P5eNM-fLGnW1TVoF2OxlF-Kou-jVPY7yjAvTw5V_Gfc,6187
16
- python_rucaptcha/text_captcha.py,sha256=HUnhPbN7zvgRAzcXUn88YER-dyXW3UOcM27VV8ZVark,3102
17
+ python_rucaptcha/text_captcha.py,sha256=Qj32p71KNj02laARIbpAzSszBeuUGTLrSyRoesvubf0,3118
17
18
  python_rucaptcha/turnstile.py,sha256=O2Q10oei6pSt47Wdq3lJjCagH_1x2U_h-LcPu0gXaDM,3790
18
19
  python_rucaptcha/yandex_smart_captcha.py,sha256=YGBhflfTxWJ603o3COvYAYHSFvbXBb5KrsduBI25YKQ,4695
19
20
  python_rucaptcha/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- python_rucaptcha/core/base.py,sha256=DV6bUrvx7rgd1isqT7rGosal-yycIQdLYlGYtTmYxm8,6620
21
+ python_rucaptcha/core/base.py,sha256=UzbJYseQX4nGjGKcjWgAAmXqo9defTd4CURTV1xyrn4,6666
21
22
  python_rucaptcha/core/config.py,sha256=SRbH3ENNpVLwqCkXU_cqVILkSqtorUlkYBs-_XMXYzQ,552
22
- python_rucaptcha/core/enums.py,sha256=qGGbYmg7jBryunJOOK1NNAaOI3ZkVU3p-KHDy4pF-R4,1905
23
+ python_rucaptcha/core/enums.py,sha256=QYdnxgALuplSD5dWkW16OP5dMcRCT3BHXPWBKIBFHag,2109
23
24
  python_rucaptcha/core/result_handler.py,sha256=OPCpfaItugyUMLJsrNaUZhZAHjb3wzHUOGO02av5KoE,3390
24
- python_rucaptcha/core/serializer.py,sha256=CfSGnVhraeVigUXmZz9S7E6ak1qSKs-5mdiphSi0aZA,3652
25
- python_rucaptcha-5.1.5.dist-info/METADATA,sha256=fojexCO9paFDH6GVT5ClJsMANb2cOBVtJUWydfuYecA,5434
26
- python_rucaptcha-5.1.5.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
27
- python_rucaptcha-5.1.5.dist-info/top_level.txt,sha256=Eu_atEB79Y7jCsfXPcXF5N8OLt6kKVbvhuRsI1BmSWM,17
28
- python_rucaptcha-5.1.5.dist-info/RECORD,,
25
+ python_rucaptcha/core/serializer.py,sha256=2C-qTZIDNtH-ENqGORpguOQBnkSbkC1Ka1Ig5aT8Hd8,4617
26
+ python_rucaptcha-5.2.dist-info/METADATA,sha256=Cl_toq1iSuzrVQWU3UIDBR48wQvTR1n7bUm3ug0qddM,5658
27
+ python_rucaptcha-5.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
28
+ python_rucaptcha-5.2.dist-info/top_level.txt,sha256=Eu_atEB79Y7jCsfXPcXF5N8OLt6kKVbvhuRsI1BmSWM,17
29
+ python_rucaptcha-5.2.dist-info/RECORD,,