victoirefinal7vi commited on
Commit
49979e8
·
verified ·
1 Parent(s): e45ce37

Create cc.py

Browse files
Files changed (1) hide show
  1. cc.py +313 -0
cc.py ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import aiohttp
3
+ import json
4
+ import time
5
+ import random
6
+ from typing import Dict, Optional, List, Any
7
+ from urllib.parse import urljoin
8
+ from faker import Faker
9
+ from concurrent.futures import ThreadPoolExecutor
10
+ from asyncio import Semaphore
11
+ from tqdm.asyncio import tqdm as tqdm_asyncio
12
+ import logging
13
+ from dataclasses import dataclass
14
+ from aiohttp import ClientTimeout
15
+ from contextlib import asynccontextmanager
16
+
17
+ # Configuration du logging
18
+ logging.basicConfig(
19
+ level=logging.INFO,
20
+ format='%(asctime)s - %(levelname)s - %(message)s'
21
+ )
22
+ logger = logging.getLogger(__name__)
23
+
24
+ @dataclass
25
+ class AccountData:
26
+ username: str
27
+ password: str
28
+ province_id: int
29
+ ville_id: int
30
+ registration_date: str = None
31
+
32
+ class RateLimiter:
33
+ def __init__(self, rate_limit: int, time_window: float = 1.0):
34
+ self.rate_limit = rate_limit
35
+ self.time_window = time_window
36
+ self.tokens = rate_limit
37
+ self.last_update = time.time()
38
+ self._lock = asyncio.Lock()
39
+
40
+ async def acquire(self):
41
+ async with self._lock:
42
+ now = time.time()
43
+ time_passed = now - self.last_update
44
+ self.tokens = min(self.rate_limit,
45
+ self.tokens + time_passed * (self.rate_limit / self.time_window))
46
+ self.last_update = now
47
+
48
+ if self.tokens < 1:
49
+ wait_time = (1 - self.tokens) * (self.time_window / self.rate_limit)
50
+ await asyncio.sleep(wait_time)
51
+ self.tokens = 0
52
+ else:
53
+ self.tokens -= 1
54
+
55
+ class AccountGenerator:
56
+ def __init__(self):
57
+ self.faker = Faker(['fr_FR'])
58
+ self.locations = {
59
+ 1: [1, 2, 3, 4, 5, 6], # Estuaire
60
+ 2: [7, 8, 9, 10, 11], # Haut-Ogooué
61
+ 3: [12, 13], # Moyen-Ogooué
62
+ 4: [14, 15, 16, 17, 18],# Ngounié
63
+ 5: [19, 20, 21], # Nyanga
64
+ 6: [22, 23, 24], # Ogooué-Ivindo
65
+ 7: [25, 26], # Ogooué-Lolo
66
+ 8: [27, 28, 29], # Ogooué-Maritime
67
+ 9: [30, 31, 32, 33, 34] # Woleu-Ntem
68
+ }
69
+ self._username_cache = set()
70
+ self._lock = asyncio.Lock()
71
+
72
+ async def generate_unique_username(self, min_length=10, max_length=20) -> str:
73
+ async with self._lock:
74
+ while True:
75
+ username = self._generate_username(min_length, max_length)
76
+ if username not in self._username_cache:
77
+ self._username_cache.add(username)
78
+ return username
79
+
80
+ def _generate_username(self, min_length=10, max_length=20) -> str:
81
+ patterns = [
82
+ lambda: self.faker.user_name()[:12],
83
+ lambda: f"{self.faker.first_name().lower()}{random.randint(1, 999)}",
84
+ lambda: f"{self.faker.last_name().lower()}{random.randint(1, 99)}",
85
+ lambda: f"{self.faker.word()}{random.randint(1, 999)}"
86
+ ]
87
+
88
+ username = random.choice(patterns)()
89
+ username = ''.join(c for c in username if c.isalnum())
90
+
91
+ if len(username) < min_length:
92
+ username += str(random.randint(1000, 9999))
93
+ elif len(username) > max_length:
94
+ username = username[:max_length]
95
+
96
+ return username
97
+
98
+ def generate_password(self, min_length=8, max_length=12) -> str:
99
+ patterns = [
100
+ lambda: self.faker.password(length=random.randint(min_length, max_length)),
101
+ lambda: f"{self.faker.word().capitalize()}{random.randint(100, 999)}!",
102
+ lambda: f"{self.faker.color_name().capitalize()}{random.randint(100, 999)}@"
103
+ ]
104
+ return random.choice(patterns)()
105
+
106
+ def generate_location(self) -> tuple:
107
+ province_id = random.choice(list(self.locations.keys()))
108
+ ville_id = random.choice(self.locations[province_id])
109
+ return province_id, ville_id
110
+
111
+ async def generate_account_data(self) -> AccountData:
112
+ province_id, ville_id = self.generate_location()
113
+ return AccountData(
114
+ username=await self.generate_unique_username(),
115
+ password=self.generate_password(),
116
+ province_id=province_id,
117
+ ville_id=ville_id
118
+ )
119
+
120
+ class AsyncGabaoHubAPI:
121
+ def __init__(self, base_url: str, session: aiohttp.ClientSession, rate_limiter: RateLimiter):
122
+ self.base_url = base_url.rstrip('/')
123
+ self.session = session
124
+ self.rate_limiter = rate_limiter
125
+ self.timeout = ClientTimeout(total=30)
126
+ self.headers = {
127
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
128
+ 'Content-Type': 'application/x-www-form-urlencoded',
129
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
130
+ 'Accept-Language': 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3'
131
+ }
132
+
133
+ async def _make_request(self, endpoint: str, method: str = 'POST', data: Dict = None) -> Dict:
134
+ await self.rate_limiter.acquire()
135
+ url = urljoin(self.base_url, endpoint)
136
+
137
+ try:
138
+ async with self.session.request(method, url, data=data, timeout=self.timeout, headers=self.headers) as response:
139
+ text = await response.text()
140
+ return {
141
+ 'success': response.status == 200,
142
+ 'status_code': response.status,
143
+ 'data': text
144
+ }
145
+ except asyncio.TimeoutError:
146
+ logger.error(f"Timeout lors de la requête vers {endpoint}")
147
+ return {'success': False, 'error': 'Timeout'}
148
+ except Exception as e:
149
+ logger.error(f"Erreur lors de la requête vers {endpoint}: {str(e)}")
150
+ return {'success': False, 'error': str(e)}
151
+
152
+ async def check_username_availability(self, username: str) -> bool:
153
+ result = await self._make_request(
154
+ '/assets/functions.php',
155
+ data={'ajaxCall': 'isUsernameTaken', 'u': username}
156
+ )
157
+
158
+ if not result['success']:
159
+ raise ConnectionError(f"Erreur lors de la vérification du username: {result.get('error')}")
160
+
161
+ return result['data'].strip() == "0"
162
+
163
+ async def register_user(self, account_data: AccountData) -> Dict:
164
+ if not 3 <= len(account_data.username) <= 32:
165
+ return {'success': False, 'error': "Username length invalid"}
166
+
167
+ if not account_data.username.isalnum():
168
+ return {'success': False, 'error': "Username must be alphanumeric"}
169
+
170
+ if not 4 <= len(account_data.password) <= 32:
171
+ return {'success': False, 'error': "Password length invalid"}
172
+
173
+ init_result = await self._make_request('/register/index.php', method='GET')
174
+ if not init_result['success']:
175
+ return {'success': False, 'error': "Cannot access registration page"}
176
+
177
+ if not await self.check_username_availability(account_data.username):
178
+ return {'success': False, 'error': "Username already taken"}
179
+
180
+ register_data = {
181
+ 'username': account_data.username,
182
+ 'password': account_data.password,
183
+ 'password2': account_data.password,
184
+ 'province': str(account_data.province_id),
185
+ 'ville': str(account_data.ville_id),
186
+ 'submit': "S'incrire"
187
+ }
188
+
189
+ result = await self._make_request('/register/register.php', data=register_data)
190
+
191
+ if not result['success']:
192
+ return {'success': False, 'error': f"Registration error: {result.get('error')}"}
193
+
194
+ if "erreur" in result['data'].lower() or "error" in result['data'].lower():
195
+ return {'success': False, 'error': "Registration failed, check provided data"}
196
+
197
+ return {
198
+ 'success': True,
199
+ 'message': "Registration successful",
200
+ 'data': result['data']
201
+ }
202
+
203
+ class AsyncAccountCreator:
204
+ def __init__(self, base_url: str, max_concurrent: int = 3, rate_limit: int = 10):
205
+ self.base_url = base_url
206
+ self.generator = AccountGenerator()
207
+ self.max_concurrent = max_concurrent
208
+ self.rate_limiter = RateLimiter(rate_limit)
209
+ self.successful_accounts: List[AccountData] = []
210
+ self.failed_accounts: List[Dict] = []
211
+ self._semaphore = Semaphore(max_concurrent)
212
+
213
+ @asynccontextmanager
214
+ async def _get_session(self):
215
+ conn = aiohttp.TCPConnector(limit=self.max_concurrent)
216
+ async with aiohttp.ClientSession(connector=conn) as session:
217
+ yield session
218
+
219
+ async def create_account(self, session: aiohttp.ClientSession) -> Dict:
220
+ async with self._semaphore:
221
+ api = AsyncGabaoHubAPI(self.base_url, session, self.rate_limiter)
222
+ max_retries = 3
223
+ retry_count = 0
224
+
225
+ while retry_count < max_retries:
226
+ try:
227
+ account_data = await self.generator.generate_account_data()
228
+ result = await api.register_user(account_data)
229
+
230
+ if result['success']:
231
+ account_data.registration_date = time.strftime('%Y-%m-%d %H:%M:%S')
232
+ self.successful_accounts.append(account_data)
233
+ return {'success': True, 'account': account_data}
234
+
235
+ retry_count += 1
236
+ await asyncio.sleep(random.uniform(1, 3))
237
+
238
+ except Exception as e:
239
+ logger.error(f"Error creating account: {str(e)}")
240
+ retry_count += 1
241
+ await asyncio.sleep(random.uniform(1, 3))
242
+
243
+ self.failed_accounts.append({
244
+ 'error': f"Failed after {max_retries} attempts",
245
+ 'last_attempt': account_data
246
+ })
247
+ return {'success': False, 'error': f"Failed after {max_retries} attempts"}
248
+
249
+ async def create_multiple_accounts(self, count: int) -> Dict:
250
+ start_time = time.time()
251
+ results = {'success': [], 'failed': []}
252
+
253
+ async with self._get_session() as session:
254
+ tasks = [self.create_account(session) for _ in range(count)]
255
+
256
+ for result in tqdm_asyncio(
257
+ asyncio.as_completed(tasks),
258
+ total=count,
259
+ desc="Creating accounts"
260
+ ):
261
+ try:
262
+ completed_result = await result
263
+ if completed_result['success']:
264
+ results['success'].append(completed_result['account'])
265
+ else:
266
+ results['failed'].append(completed_result['error'])
267
+ except Exception as e:
268
+ logger.error(f"Task error: {str(e)}")
269
+ results['failed'].append(str(e))
270
+
271
+ end_time = time.time()
272
+
273
+ return {
274
+ 'duration': end_time - start_time,
275
+ 'total_attempts': count,
276
+ 'successful': len(results['success']),
277
+ 'failed': len(results['failed']),
278
+ 'accounts': results['success'],
279
+ 'errors': results['failed']
280
+ }
281
+
282
+ async def save_accounts(accounts: List[AccountData], filename: str):
283
+ with open(filename, 'w', encoding='utf-8') as f:
284
+ json.dump([vars(account) for account in accounts], f, ensure_ascii=False, indent=2)
285
+
286
+ async def main():
287
+ try:
288
+ creator = AsyncAccountCreator(
289
+ 'https://gabaohub.alwaysdata.net',
290
+ max_concurrent=10,
291
+ rate_limit=20
292
+ )
293
+
294
+ num_accounts = 20000
295
+ logger.info(f"Creating {num_accounts} accounts...")
296
+
297
+ results = await creator.create_multiple_accounts(num_accounts)
298
+
299
+ logger.info(f"\nResults after {results['duration']:.2f} seconds:")
300
+ logger.info(f"✅ Successfully created accounts: {results['successful']}")
301
+ logger.info(f"❌ Failed attempts: {results['failed']}")
302
+
303
+ if results['accounts']:
304
+ filename = f"accounts_{time.strftime('%Y%m%d_%H%M%S')}.json"
305
+ await save_accounts(results['accounts'], filename)
306
+ logger.info(f"\nAccounts saved to {filename}")
307
+
308
+ except Exception as e:
309
+ logger.error(f"Main error: {str(e)}")
310
+ raise
311
+
312
+ if __name__ == "__main__":
313
+ asyncio.run(main())