amjadyt 0.0.1__tar.gz

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.
amjadyt-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: amjadyt
3
+ Version: 0.0.1
4
+ Summary: Kumpulan fungsi untuk scriping
5
+ Author-email: Solihul Amjad <amjadyt348@anda.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Requires-Python: >=3.7
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Functions Untuk Scripting
12
+ # Fitur
13
+ - class Requests
14
+ - class Functions
15
+ - class Display
16
+ - class Baypas captcha Multibot & xevil
17
+ - Baypas Icon Captcha
18
+ - html scrap (menggunakan BeautifulSoup)
19
+
20
+ # Example
21
+ #### Cara Import
22
+ ```from class import*```
23
+ #### Requests
24
+ ```response = Requests.curl('https://example.com')```
25
+ #### Functions
26
+ ```Functions.setConfig('nama_data')```
27
+ #### Baypas Captcha
28
+ panggil function menu api dulu sebelum memanggil class Baypas Captch
29
+ ###### Example
30
+ function menu api
31
+ ```HOST_CAP,API_CAP = Functions.menu_api()`
32
+ lalu panggil function Baypas Captcha nya
33
+ cap = Captcha.Recaptchav2(sitekey,pageurl)```
34
+ #### Baypass Icon Captcha
35
+ ###### Example
36
+ ```baypas = IconBypass(host, headers)```
37
+ ```icon = baypas.icon_bypass(iconToken)```
38
+
39
+
40
+
@@ -0,0 +1,30 @@
1
+ # Functions Untuk Scripting
2
+ # Fitur
3
+ - class Requests
4
+ - class Functions
5
+ - class Display
6
+ - class Baypas captcha Multibot & xevil
7
+ - Baypas Icon Captcha
8
+ - html scrap (menggunakan BeautifulSoup)
9
+
10
+ # Example
11
+ #### Cara Import
12
+ ```from class import*```
13
+ #### Requests
14
+ ```response = Requests.curl('https://example.com')```
15
+ #### Functions
16
+ ```Functions.setConfig('nama_data')```
17
+ #### Baypas Captcha
18
+ panggil function menu api dulu sebelum memanggil class Baypas Captch
19
+ ###### Example
20
+ function menu api
21
+ ```HOST_CAP,API_CAP = Functions.menu_api()`
22
+ lalu panggil function Baypas Captcha nya
23
+ cap = Captcha.Recaptchav2(sitekey,pageurl)```
24
+ #### Baypass Icon Captcha
25
+ ###### Example
26
+ ```baypas = IconBypass(host, headers)```
27
+ ```icon = baypas.icon_bypass(iconToken)```
28
+
29
+
30
+
@@ -0,0 +1,17 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "amjadyt"
7
+ version = "0.0.1"
8
+ authors = [
9
+ { name="Solihul Amjad", email="amjadyt348@anda.com" },
10
+ ]
11
+ description = "Kumpulan fungsi untuk scriping"
12
+ readme = "README.md"
13
+ requires-python = ">=3.7"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,460 @@
1
+ # module python
2
+ import requests
3
+ import os
4
+ import sys
5
+ import time
6
+ import json
7
+ import re
8
+ import base64
9
+ import random
10
+ from urllib.parse import urlparse
11
+ from typing import Dict, Union, List, Optional, Tuple
12
+ from bs4 import BeautifulSoup
13
+
14
+ class Colors:
15
+ DASAR = '\x1b[0m'
16
+ TEBAL = '\x1b[1m'
17
+ GARIS = '\x1b[4m'
18
+ GERAK = '\x1b[5m'
19
+ # Warna Teks
20
+ MERAH = '\x1b[31;1m'
21
+ HIJAU = '\x1b[32;1m'
22
+ KUNING = '\x1b[33;1m'
23
+ BIRU = '\x1b[34;1m'
24
+ UNGU = '\x1b[35;1m'
25
+ CYAN = '\x1b[36;1m'
26
+ PUTIH = '\x1b[37;1m'
27
+ # Warna Background
28
+ BG_M = '\x1b[41;1m'
29
+ BG_H = '\x1b[42;1m'
30
+ BG_K = '\x1b[43;1m'
31
+ BG_B = '\x1b[44;1m'
32
+ BG_U = '\x1b[45;1m'
33
+ BG_C = '\x1b[46;1m'
34
+ BG_P = '\x1b[47;1m'
35
+
36
+ DATA_FILE = 'data.json'
37
+
38
+ class Requests:
39
+ @staticmethod
40
+ def curl(url, method='GET', data=None, headers=None, cookies_file='cookie.txt'):
41
+ while True:
42
+ session = requests.Session()
43
+ try:
44
+ with open(cookies_file, 'r') as f:
45
+ cookies = {}
46
+ for line in f.readlines():
47
+ name, value = line.strip().split('=')
48
+ cookies[name] = value
49
+ session.cookies.update(cookies)
50
+ except FileNotFoundError:
51
+ pass
52
+ try:
53
+ if method.upper() == 'GET':
54
+ response = session.get(url, headers=headers)
55
+ elif method.upper() == 'POST':
56
+ response = session.post(url, data=data, headers=headers)
57
+ else:
58
+ raise ValueError('Metode tidak didukung')
59
+ response.raise_for_status()
60
+ except requests.exceptions.RequestException as e:
61
+ print(f"Koneksi terputus Mencoba lagi...")
62
+ time.sleep(5)
63
+ continue
64
+ with open(cookies_file, 'w') as f:
65
+ for cookie in session.cookies.items():
66
+ f.write(f"{cookie[0]}={cookie[1]}\n")
67
+ return response.text
68
+ class Display:
69
+ @staticmethod
70
+ def menu(no: Union[int, str], name: str) -> None:
71
+ print(f'{Colors.PUTIH}[{Colors.KUNING}{no}{Colors.PUTIH}] {Colors.PUTIH}{name}')
72
+ @staticmethod
73
+ def succes(msg: str) -> None:
74
+ print(f'{Colors.PUTIH}[{Colors.HIJAU}✓{Colors.PUTIH}] {Colors.HIJAU}{msg}{Colors.DASAR}')
75
+ @staticmethod
76
+ def error(msg: str) -> None:
77
+ print(f'{Colors.PUTIH}[{Colors.MERAH}!{Colors.PUTIH}] {Colors.MERAH}{msg}{Colors.DASAR}')
78
+ @staticmethod
79
+ def title(name: str, length: int = 44, pad_char: str = " ") -> None:
80
+ padded_name = name.center(length, pad_char)
81
+ print(f'{Colors.BG_B}{Colors.PUTIH}{padded_name}{Colors.DASAR}')
82
+ @staticmethod
83
+ def line(length: int = 44) -> None:
84
+ print(f'{Colors.CYAN}-'*length)
85
+ class Functions:
86
+ @staticmethod
87
+ def setConfig(key: str, value: Optional[str] = None) -> str:
88
+ config = {}
89
+ if os.path.exists(DATA_FILE):
90
+ try:
91
+ with open(DATA_FILE, 'r') as f:
92
+ config = json.load(f)
93
+ except (json.JSONDecodeError, IOError):
94
+ config = {}
95
+ if value is None:
96
+ if key in config:
97
+ return config[key]
98
+ value = input(f'--[>] Input {key}: ')
99
+ config[key] = value
100
+ try:
101
+ with open(DATA_FILE, 'w') as f:
102
+ json.dump(config, f, indent=4)
103
+ except IOError as e:
104
+ Display.error(f"Gagal menyimpan konfigurasi: {e}")
105
+ return value
106
+ @staticmethod
107
+ def menu_api() -> Tuple[str, str]:
108
+ Display.menu(1, 'Multibot')
109
+ Display.menu(2, 'Xevil')
110
+ Display.line()
111
+ options = {
112
+ 1: {"host": "api.multibot.in", "apikey": "apikey-multibot"},
113
+ 2: {"host": "api.sctg.xyz", "apikey": "apikey-xevil"}
114
+ }
115
+ while True:
116
+ try:
117
+ cap = int(input(f'{Colors.HIJAU}--Input Number: {Colors.PUTIH}'))
118
+ if cap in options:
119
+ break
120
+ Display.error('Pilihan tidak valid. Silakan coba lagi.')
121
+ except ValueError:
122
+ Display.error('Input harus angka. Silakan coba lagi.')
123
+ host = options[cap]["host"]
124
+ api_key = Functions.setConfig(options[cap]["apikey"])
125
+ return host, api_key
126
+ @staticmethod
127
+ def Tmr(tmr: int) -> None:
128
+ while tmr > 0:
129
+ mins, secs = divmod(tmr, 60)
130
+ timeformat = f'\033[1;97m\033[1;93m•\033[1;97m Wait \033[1;92m{mins:02d}:{secs:02d}'
131
+ print(f"{timeformat}", end='\r')
132
+ time.sleep(1)
133
+ tmr -= 1
134
+ print(" " * 30, end='\r') # Clear line
135
+ @staticmethod
136
+ def prosesBypasIcon(icontoken,host,h):
137
+ if icontoken:
138
+ while True:
139
+ amjad = IconBypass(host,h)
140
+ icon = amjad.icon_bypass(icontoken)
141
+ if not icon:
142
+ print(f'\r{Colors.PUTIH}--[{Colors.MERAH}!{Colors.PUTIH}] Bypas Gagal !\r',end='')
143
+ time.sleep(2)
144
+ continue
145
+ print(f'\r{Colors.PUTIH}--[{Colors.HIJAU}✓{Colors.PUTIH}] Bypas Succes\r',end='')
146
+ time.sleep(2)
147
+ return icon
148
+ class Captcha:
149
+ @staticmethod
150
+ def get_in(data: Dict) -> str:
151
+ url = f'http://{HOST_CAP}/in.php?'
152
+ params = {'key': API_CAP}
153
+ params.update(data)
154
+ try:
155
+ res = requests.get(url, params=params, timeout=30).json()
156
+ return res.get('request', '')
157
+ except (requests.RequestException, json.JSONDecodeError) as e:
158
+ Display.error(f"Gagal mendapatkan captcha ID: {e}")
159
+ raise
160
+
161
+ @staticmethod
162
+ def get_res(api_id: str) -> Dict:
163
+ url = f'http://{HOST_CAP}/res.php?key={API_CAP}&json=1&id={api_id}'
164
+ try:
165
+ res = requests.get(url, timeout=30)
166
+ return res.json()
167
+ except (requests.RequestException, json.JSONDecodeError) as e:
168
+ Display.error(f"Gagal mendapatkan hasil captcha: {e}")
169
+ return {'request': 'ERROR', 'error': str(e)}
170
+
171
+ @staticmethod
172
+ def Filter(method: str) -> str:
173
+ method_map = {
174
+ 'userrecaptcha': 'RecaptchaV2',
175
+ 'hcaptcha': 'Hcaptcha',
176
+ 'turnstile': 'Turnstile'
177
+ }
178
+ return method_map.get(method, method)
179
+
180
+ @staticmethod
181
+ def getResult(data: Dict) -> str:
182
+ method_value = data.get('method', '')
183
+ cap_type = Captcha.Filter(method_value)
184
+ max_attempts = 60
185
+ try:
186
+ captcha_id = Captcha.get_in(data)
187
+ for _ in range(max_attempts):
188
+ res = Captcha.get_res(captcha_id)
189
+ if res.get('request') == 'CAPCHA_NOT_READY':
190
+ print(f"\rBaypas {cap_type}", end='')
191
+ time.sleep(1)
192
+ continue
193
+ if res.get('request') == 'ERROR':
194
+ raise Exception(res.get('error', 'Unknown error'))
195
+ Display.succes(f'Baypas {cap_type} sukses')
196
+ time.sleep(2)
197
+ print(" " * 30, end='\r') # Clear line
198
+ return res.get('request', '')
199
+ raise Exception("Captcha tidak selesai dalam waktu yang ditentukan")
200
+ except Exception as e:
201
+ Display.error(f"Gagal bypass captcha: {e}")
202
+ raise
203
+
204
+ @staticmethod
205
+ def Recaptchav2(sitekey: str, pageurl: str) -> str:
206
+ data = {
207
+ 'method': 'userrecaptcha',
208
+ 'sitekey': sitekey,
209
+ 'pageurl': pageurl,
210
+ 'json': 1
211
+ }
212
+ return Captcha.getResult(data)
213
+
214
+ @staticmethod
215
+ def Hcaptcha(sitekey: str, pageurl: str) -> str:
216
+ data = {
217
+ 'method': 'hcaptcha',
218
+ 'sitekey': sitekey,
219
+ 'pageurl': pageurl,
220
+ 'json': 1
221
+ }
222
+ return Captcha.getResult(data)
223
+
224
+ @staticmethod
225
+ def Turnstile(sitekey: str, pageurl: str) -> str:
226
+ data = {
227
+ 'method': 'turnstile',
228
+ 'sitekey': sitekey,
229
+ 'pageurl': pageurl,
230
+ 'json': 1
231
+ }
232
+ return Captcha.getResult(data)
233
+ class HtmlScrap:
234
+ def __init__(self):
235
+ self._captcha_pattern = re.compile(r'class=["\']([^"\']+)["\'][^>]*data-sitekey=["\']([^"\']+)["\'][^>]*>')
236
+ self._input_pattern = re.compile(r'<input[^>]*name=["\'](.*?)["\'][^>]*value=["\'](.*?)["\'][^>]*>')
237
+ self._limit_pattern = re.compile(r'(\d{1,})\/(\d{1,})')
238
+ self._security_patterns = {
239
+ 'cloudflare': re.compile(r'Just a moment...'),
240
+ 'firewall': re.compile(r'Firewall'),
241
+ 'locked': re.compile(r'Locked')
242
+ }
243
+
244
+ def _scrap(self, pattern: re.Pattern, html: str) -> List[Tuple[str, ...]]:
245
+ return pattern.findall(html)
246
+
247
+ def get_captcha(self, html: str) -> Dict[str, str]:
248
+ matches = self._scrap(self._captcha_pattern, html)
249
+ return {match[0]: match[1] for match in matches}
250
+
251
+ def get_inputs(self, html: str, form_index: int = 1) -> Dict[str, str]:
252
+ forms = html.split('<form')
253
+ if len(forms) <= form_index:
254
+ return {}
255
+ form_content = forms[form_index]
256
+ matches = self._scrap(self._input_pattern, form_content)
257
+ return {name: value for name, value in matches}
258
+
259
+ def get_limits(self, html: str) -> List[Tuple[str, str]]:
260
+ return self._scrap(self._limit_pattern, html)
261
+
262
+ def check_security(self, html: str) -> Dict[str, bool]:
263
+ return {name: bool(pattern.search(html)) for name, pattern in self._security_patterns.items()}
264
+
265
+ def parse_responses(self, html: str) -> Dict[str, Union[str, bool, None]]:
266
+ result = {
267
+ 'success': None,
268
+ 'warning': None,
269
+ 'unset': False,
270
+ 'exit': False
271
+ }
272
+ if 'icon: \'success\',' in html:
273
+ success_part = html.split("icon: 'success',")[1]
274
+ if "html: '" in success_part:
275
+ success_msg = success_part.split("html: '")[1].split("'")[0]
276
+ result['success'] = re.sub('<[^<]+?>', '', success_msg)
277
+ return result
278
+ warning_msg = None
279
+ if 'html: \'' in html:
280
+ warning_msg = html.split("html: '")[1].split("'")[0]
281
+ error_conditions = [
282
+ ('<div class="alert text-center alert-danger"><i class="fas fa-exclamation-circle"></i> Your account',
283
+ lambda: html.split('Your account')[1].split('</div>')[0], True),
284
+ ('invalid amount', "You are sending an invalid amount", True),
285
+ ('Shortlink in order to claim from the faucet!', warning_msg, True),
286
+ ('sufficient funds', "Sufficient funds", True)
287
+ ]
288
+ for condition, message, exit_flag in error_conditions:
289
+ if condition in html:
290
+ result['warning'] = message() if callable(message) else message
291
+ result['exit'] = exit_flag
292
+ return result
293
+ result['warning'] = warning_msg or "Not Found"
294
+ return result
295
+
296
+ def get_title(self, html: str) -> str:
297
+ title_parts = html.split('<title>')
298
+ if len(title_parts) > 1:
299
+ return title_parts[1].split('</title>')[0]
300
+ return ""
301
+
302
+ def scrape_all(self, html: str, form_index: int = 1) -> Dict[str, Union[str, bool, Dict, List]]:
303
+ return {
304
+ 'title': self.get_title(html),
305
+ **self.check_security(html),
306
+ 'captcha': self.get_captcha(html),
307
+ 'input': self.get_inputs(html, form_index) or self.get_inputs(html, 2),
308
+ 'faucet': self.get_limits(html),
309
+ 'response': self.parse_responses(html)
310
+ }
311
+
312
+ @staticmethod
313
+ def bs_get_forms(html: str) -> List[Dict[str, Union[str, Dict[str, str]]]]:
314
+ soup = BeautifulSoup(html, 'html.parser')
315
+ forms = []
316
+ for form in soup.find_all('form'):
317
+ form_data = {
318
+ 'action': form.get('action', ''),
319
+ 'method': form.get('method', 'get').upper(),
320
+ 'inputs': {}
321
+ }
322
+ for input_tag in form.find_all('input'):
323
+ name = input_tag.get('name')
324
+ if name:
325
+ form_data['inputs'][name] = input_tag.get('value', '')
326
+ forms.append(form_data)
327
+ return forms
328
+
329
+ @staticmethod
330
+ def bs_get_links(html: str, base_url: str = '') -> List[Dict[str, str]]:
331
+ soup = BeautifulSoup(html, 'html.parser')
332
+ links = []
333
+ for a in soup.find_all('a', href=True):
334
+ href = a['href']
335
+ if base_url and not href.startswith(('http://', 'https://')):
336
+ href = base_url + href
337
+ links.append({
338
+ 'text': a.get_text(strip=True),
339
+ 'href': href
340
+ })
341
+ return links
342
+ class IconBypass:
343
+ def __init__(self, host, headers):
344
+ self.host = host
345
+ self.headers = headers
346
+ def widget_id(self):
347
+ import uuid
348
+ return str(uuid.uuid4())
349
+ def msg(self, text, j=10):
350
+ symbols = ['-', '/', '|', '\\']
351
+ for i in range(j, 0, -1):
352
+ for n, s in enumerate(symbols):
353
+ print(f" [{s}] {text} {'➤' * n}", end='\r')
354
+ time.sleep(0.1)
355
+ print(" " * 30, end='\r')
356
+ def icon_bypass(self, token):
357
+ try:
358
+ # Persiapan header
359
+ icon_header = self.headers.copy()
360
+ icon_header.update({
361
+ 'origin': self.host,
362
+ 'x-iconcaptcha-token': token,
363
+ 'x-requested-with': 'XMLHttpRequest',
364
+ 'content-type': 'application/x-www-form-urlencoded'
365
+ })
366
+
367
+ # --- STEP 1: LOAD CAPTCHA ---
368
+ self.msg("Loading captcha", 3)
369
+ timestamp = int(time.time() * 1000)
370
+ widget_id = self.widget_id()
371
+ payload = {
372
+ "widgetId": widget_id,
373
+ "action": "LOAD",
374
+ "theme": "light",
375
+ "token": token,
376
+ "timestamp": timestamp,
377
+ "initTimestamp": timestamp - 2000
378
+ }
379
+
380
+ # Encode payload
381
+ data = {
382
+ "payload": base64.b64encode(
383
+ json.dumps(payload).encode('utf-8')
384
+ ).decode('utf-8')
385
+ }
386
+
387
+ # Kirim request
388
+ response = Requests.curl(
389
+ self.host + "icaptcha/req",
390
+ method='POST',
391
+ headers=icon_header,
392
+ data=data
393
+ )
394
+
395
+ # Handle response
396
+ try:
397
+ decoded = base64.b64decode(response).decode('utf-8')
398
+ response_data = json.loads(decoded)
399
+ except:
400
+ print("Invalid response format:", response.text[:200])
401
+ return None
402
+
403
+ if 'identifier' not in response_data:
404
+ print("No identifier in response")
405
+ return None
406
+
407
+ challenge_id = response_data['identifier']
408
+
409
+ # --- STEP 2: SEND SELECTION ---
410
+ self.msg("Solving captcha", 3)
411
+ timestamp = int(time.time() * 1000)
412
+ payload = {
413
+ "widgetId": widget_id,
414
+ "challengeId": challenge_id,
415
+ "action": "SELECTION",
416
+ "x": random.randint(150, 170), # Koordinat acak di area tengah
417
+ "y": random.randint(20, 30),
418
+ "width": 320,
419
+ "token": token,
420
+ "timestamp": timestamp,
421
+ "initTimestamp": timestamp - 2000
422
+ }
423
+
424
+ data = {
425
+ "payload": base64.b64encode(
426
+ json.dumps(payload).encode('utf-8')
427
+ ).decode('utf-8')
428
+ }
429
+
430
+ response = Requests.curl(
431
+ self.host + "icaptcha/req",
432
+ method='POST',
433
+ headers=icon_header,
434
+ data=data
435
+ )
436
+
437
+ try:
438
+ decoded = base64.b64decode(response).decode('utf-8')
439
+ response_data = json.loads(decoded)
440
+ except:
441
+ print("Invalid response format:", response.text[:200])
442
+ return None
443
+
444
+ if not response_data.get('completed', False):
445
+ return None
446
+
447
+ # --- STEP 3: RETURN RESULT ---
448
+ return {
449
+ "captcha": "icaptcha",
450
+ "_iconcaptcha-token": token,
451
+ "ic-rq": 1,
452
+ "ic-wid": payload["widgetId"],
453
+ "ic-cid": challenge_id,
454
+ "ic-hp": '',
455
+ "human_move": 1
456
+ }
457
+
458
+ except Exception as e:
459
+ print(f"Error in bypass: {str(e)}")
460
+ return None
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: amjadyt
3
+ Version: 0.0.1
4
+ Summary: Kumpulan fungsi untuk scriping
5
+ Author-email: Solihul Amjad <amjadyt348@anda.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Requires-Python: >=3.7
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Functions Untuk Scripting
12
+ # Fitur
13
+ - class Requests
14
+ - class Functions
15
+ - class Display
16
+ - class Baypas captcha Multibot & xevil
17
+ - Baypas Icon Captcha
18
+ - html scrap (menggunakan BeautifulSoup)
19
+
20
+ # Example
21
+ #### Cara Import
22
+ ```from class import*```
23
+ #### Requests
24
+ ```response = Requests.curl('https://example.com')```
25
+ #### Functions
26
+ ```Functions.setConfig('nama_data')```
27
+ #### Baypas Captcha
28
+ panggil function menu api dulu sebelum memanggil class Baypas Captch
29
+ ###### Example
30
+ function menu api
31
+ ```HOST_CAP,API_CAP = Functions.menu_api()`
32
+ lalu panggil function Baypas Captcha nya
33
+ cap = Captcha.Recaptchav2(sitekey,pageurl)```
34
+ #### Baypass Icon Captcha
35
+ ###### Example
36
+ ```baypas = IconBypass(host, headers)```
37
+ ```icon = baypas.icon_bypass(iconToken)```
38
+
39
+
40
+
@@ -0,0 +1,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/amjadyt/__init__.py
4
+ src/amjadyt/func.py
5
+ src/amjadyt.egg-info/PKG-INFO
6
+ src/amjadyt.egg-info/SOURCES.txt
7
+ src/amjadyt.egg-info/dependency_links.txt
8
+ src/amjadyt.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ amjadyt