boostgh / cc.py
victoirefinal7vi's picture
Create cc.py
49979e8 verified
import asyncio
import aiohttp
import json
import time
import random
from typing import Dict, Optional, List, Any
from urllib.parse import urljoin
from faker import Faker
from concurrent.futures import ThreadPoolExecutor
from asyncio import Semaphore
from tqdm.asyncio import tqdm as tqdm_asyncio
import logging
from dataclasses import dataclass
from aiohttp import ClientTimeout
from contextlib import asynccontextmanager
# Configuration du logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
@dataclass
class AccountData:
username: str
password: str
province_id: int
ville_id: int
registration_date: str = None
class RateLimiter:
def __init__(self, rate_limit: int, time_window: float = 1.0):
self.rate_limit = rate_limit
self.time_window = time_window
self.tokens = rate_limit
self.last_update = time.time()
self._lock = asyncio.Lock()
async def acquire(self):
async with self._lock:
now = time.time()
time_passed = now - self.last_update
self.tokens = min(self.rate_limit,
self.tokens + time_passed * (self.rate_limit / self.time_window))
self.last_update = now
if self.tokens < 1:
wait_time = (1 - self.tokens) * (self.time_window / self.rate_limit)
await asyncio.sleep(wait_time)
self.tokens = 0
else:
self.tokens -= 1
class AccountGenerator:
def __init__(self):
self.faker = Faker(['fr_FR'])
self.locations = {
1: [1, 2, 3, 4, 5, 6], # Estuaire
2: [7, 8, 9, 10, 11], # Haut-Ogooué
3: [12, 13], # Moyen-Ogooué
4: [14, 15, 16, 17, 18],# Ngounié
5: [19, 20, 21], # Nyanga
6: [22, 23, 24], # Ogooué-Ivindo
7: [25, 26], # Ogooué-Lolo
8: [27, 28, 29], # Ogooué-Maritime
9: [30, 31, 32, 33, 34] # Woleu-Ntem
}
self._username_cache = set()
self._lock = asyncio.Lock()
async def generate_unique_username(self, min_length=10, max_length=20) -> str:
async with self._lock:
while True:
username = self._generate_username(min_length, max_length)
if username not in self._username_cache:
self._username_cache.add(username)
return username
def _generate_username(self, min_length=10, max_length=20) -> str:
patterns = [
lambda: self.faker.user_name()[:12],
lambda: f"{self.faker.first_name().lower()}{random.randint(1, 999)}",
lambda: f"{self.faker.last_name().lower()}{random.randint(1, 99)}",
lambda: f"{self.faker.word()}{random.randint(1, 999)}"
]
username = random.choice(patterns)()
username = ''.join(c for c in username if c.isalnum())
if len(username) < min_length:
username += str(random.randint(1000, 9999))
elif len(username) > max_length:
username = username[:max_length]
return username
def generate_password(self, min_length=8, max_length=12) -> str:
patterns = [
lambda: self.faker.password(length=random.randint(min_length, max_length)),
lambda: f"{self.faker.word().capitalize()}{random.randint(100, 999)}!",
lambda: f"{self.faker.color_name().capitalize()}{random.randint(100, 999)}@"
]
return random.choice(patterns)()
def generate_location(self) -> tuple:
province_id = random.choice(list(self.locations.keys()))
ville_id = random.choice(self.locations[province_id])
return province_id, ville_id
async def generate_account_data(self) -> AccountData:
province_id, ville_id = self.generate_location()
return AccountData(
username=await self.generate_unique_username(),
password=self.generate_password(),
province_id=province_id,
ville_id=ville_id
)
class AsyncGabaoHubAPI:
def __init__(self, base_url: str, session: aiohttp.ClientSession, rate_limiter: RateLimiter):
self.base_url = base_url.rstrip('/')
self.session = session
self.rate_limiter = rate_limiter
self.timeout = ClientTimeout(total=30)
self.headers = {
'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',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3'
}
async def _make_request(self, endpoint: str, method: str = 'POST', data: Dict = None) -> Dict:
await self.rate_limiter.acquire()
url = urljoin(self.base_url, endpoint)
try:
async with self.session.request(method, url, data=data, timeout=self.timeout, headers=self.headers) as response:
text = await response.text()
return {
'success': response.status == 200,
'status_code': response.status,
'data': text
}
except asyncio.TimeoutError:
logger.error(f"Timeout lors de la requête vers {endpoint}")
return {'success': False, 'error': 'Timeout'}
except Exception as e:
logger.error(f"Erreur lors de la requête vers {endpoint}: {str(e)}")
return {'success': False, 'error': str(e)}
async def check_username_availability(self, username: str) -> bool:
result = await self._make_request(
'/assets/functions.php',
data={'ajaxCall': 'isUsernameTaken', 'u': username}
)
if not result['success']:
raise ConnectionError(f"Erreur lors de la vérification du username: {result.get('error')}")
return result['data'].strip() == "0"
async def register_user(self, account_data: AccountData) -> Dict:
if not 3 <= len(account_data.username) <= 32:
return {'success': False, 'error': "Username length invalid"}
if not account_data.username.isalnum():
return {'success': False, 'error': "Username must be alphanumeric"}
if not 4 <= len(account_data.password) <= 32:
return {'success': False, 'error': "Password length invalid"}
init_result = await self._make_request('/register/index.php', method='GET')
if not init_result['success']:
return {'success': False, 'error': "Cannot access registration page"}
if not await self.check_username_availability(account_data.username):
return {'success': False, 'error': "Username already taken"}
register_data = {
'username': account_data.username,
'password': account_data.password,
'password2': account_data.password,
'province': str(account_data.province_id),
'ville': str(account_data.ville_id),
'submit': "S'incrire"
}
result = await self._make_request('/register/register.php', data=register_data)
if not result['success']:
return {'success': False, 'error': f"Registration error: {result.get('error')}"}
if "erreur" in result['data'].lower() or "error" in result['data'].lower():
return {'success': False, 'error': "Registration failed, check provided data"}
return {
'success': True,
'message': "Registration successful",
'data': result['data']
}
class AsyncAccountCreator:
def __init__(self, base_url: str, max_concurrent: int = 3, rate_limit: int = 10):
self.base_url = base_url
self.generator = AccountGenerator()
self.max_concurrent = max_concurrent
self.rate_limiter = RateLimiter(rate_limit)
self.successful_accounts: List[AccountData] = []
self.failed_accounts: List[Dict] = []
self._semaphore = Semaphore(max_concurrent)
@asynccontextmanager
async def _get_session(self):
conn = aiohttp.TCPConnector(limit=self.max_concurrent)
async with aiohttp.ClientSession(connector=conn) as session:
yield session
async def create_account(self, session: aiohttp.ClientSession) -> Dict:
async with self._semaphore:
api = AsyncGabaoHubAPI(self.base_url, session, self.rate_limiter)
max_retries = 3
retry_count = 0
while retry_count < max_retries:
try:
account_data = await self.generator.generate_account_data()
result = await api.register_user(account_data)
if result['success']:
account_data.registration_date = time.strftime('%Y-%m-%d %H:%M:%S')
self.successful_accounts.append(account_data)
return {'success': True, 'account': account_data}
retry_count += 1
await asyncio.sleep(random.uniform(1, 3))
except Exception as e:
logger.error(f"Error creating account: {str(e)}")
retry_count += 1
await asyncio.sleep(random.uniform(1, 3))
self.failed_accounts.append({
'error': f"Failed after {max_retries} attempts",
'last_attempt': account_data
})
return {'success': False, 'error': f"Failed after {max_retries} attempts"}
async def create_multiple_accounts(self, count: int) -> Dict:
start_time = time.time()
results = {'success': [], 'failed': []}
async with self._get_session() as session:
tasks = [self.create_account(session) for _ in range(count)]
for result in tqdm_asyncio(
asyncio.as_completed(tasks),
total=count,
desc="Creating accounts"
):
try:
completed_result = await result
if completed_result['success']:
results['success'].append(completed_result['account'])
else:
results['failed'].append(completed_result['error'])
except Exception as e:
logger.error(f"Task error: {str(e)}")
results['failed'].append(str(e))
end_time = time.time()
return {
'duration': end_time - start_time,
'total_attempts': count,
'successful': len(results['success']),
'failed': len(results['failed']),
'accounts': results['success'],
'errors': results['failed']
}
async def save_accounts(accounts: List[AccountData], filename: str):
with open(filename, 'w', encoding='utf-8') as f:
json.dump([vars(account) for account in accounts], f, ensure_ascii=False, indent=2)
async def main():
try:
creator = AsyncAccountCreator(
'https://gabaohub.alwaysdata.net',
max_concurrent=10,
rate_limit=20
)
num_accounts = 20000
logger.info(f"Creating {num_accounts} accounts...")
results = await creator.create_multiple_accounts(num_accounts)
logger.info(f"\nResults after {results['duration']:.2f} seconds:")
logger.info(f"✅ Successfully created accounts: {results['successful']}")
logger.info(f"❌ Failed attempts: {results['failed']}")
if results['accounts']:
filename = f"accounts_{time.strftime('%Y%m%d_%H%M%S')}.json"
await save_accounts(results['accounts'], filename)
logger.info(f"\nAccounts saved to {filename}")
except Exception as e:
logger.error(f"Main error: {str(e)}")
raise
if __name__ == "__main__":
asyncio.run(main())