Spaces:
Sleeping
Sleeping
| """ | |
| CLI команды для регистрации аккаунтов | |
| Поддерживает разные стратегии: | |
| - automated: DrissionPage (legacy, работает для некоторых) | |
| - webview: Реальный браузер с ручным вводом (рекомендуется) | |
| """ | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parent)) | |
| from registration.strategy_factory import StrategyFactory | |
| from registration.auth_strategy import RegistrationStrategy | |
| from typing import Optional | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| def cmd_register_strategies(args): | |
| """Показать доступные стратегии регистрации""" | |
| StrategyFactory.print_strategies() | |
| def cmd_register_webview(args): | |
| """ | |
| Регистрация через WebView (рекомендуется) | |
| Открывает реальный браузер, пользователь вручную вводит данные. | |
| Минимальный риск бана (<10%). | |
| """ | |
| email = args.email | |
| provider = args.provider or "Google" | |
| browser_path = args.browser | |
| proxy = args.proxy | |
| timeout = args.timeout or 300 | |
| print("\n" + "="*70) | |
| print("WEBVIEW REGISTRATION (Anti-Ban)") | |
| print("="*70) | |
| print(f"Email: {email}") | |
| print(f"Provider: {provider}") | |
| print(f"Strategy: webview (low ban risk)") | |
| if browser_path: | |
| print(f"Browser: {browser_path}") | |
| if proxy: | |
| print(f"Proxy: {proxy}") | |
| print("="*70 + "\n") | |
| # Создаём стратегию | |
| strategy = StrategyFactory.create( | |
| 'webview', | |
| browser_path=browser_path, | |
| proxy=proxy | |
| ) | |
| try: | |
| # Регистрация | |
| result = strategy.register( | |
| email=email, | |
| provider=provider, | |
| timeout=timeout | |
| ) | |
| # Результат | |
| print("\n" + "="*70) | |
| if result['success']: | |
| print("✅ REGISTRATION SUCCESSFUL") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Token file: {result.get('token_file', 'N/A')}") | |
| print(f"Strategy: {result['strategy']}") | |
| print(f"Ban risk: {result['ban_risk']}") | |
| print(f"\n⚠️ Quota check deferred (anti-ban measure)") | |
| print(f" Use: python -m autoreg.cli check-account --email {email}") | |
| else: | |
| print("❌ REGISTRATION FAILED") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Error: {result.get('error', 'Unknown error')}") | |
| print(f"Strategy: {result['strategy']}") | |
| print("="*70 + "\n") | |
| return 0 if result['success'] else 1 | |
| except KeyboardInterrupt: | |
| print("\n\n⚠️ Registration cancelled by user") | |
| return 1 | |
| except Exception as e: | |
| print(f"\n❌ Error: {e}") | |
| return 1 | |
| finally: | |
| strategy.cleanup() | |
| def cmd_register_automated(args): | |
| """ | |
| Регистрация через автоматизацию (legacy) | |
| Использует DrissionPage для автоматизации браузера. | |
| Работает для некоторых пользователей, но имеет высокий риск бана. | |
| """ | |
| email = args.email | |
| name = args.name | |
| password = args.password | |
| headless = args.headless | |
| check_quota = not args.no_check_quota | |
| device_flow = args.device_flow | |
| print("\n" + "="*70) | |
| print("AUTOMATED REGISTRATION (Legacy)") | |
| print("="*70) | |
| print(f"Email: {email}") | |
| if name: | |
| print(f"Name: {name}") | |
| print(f"Strategy: automated") | |
| print(f"Headless: {headless}") | |
| print(f"Check quota immediately: {check_quota}") | |
| if check_quota: | |
| print(f"⚠️ WARNING: Immediate quota check increases ban risk!") | |
| print(f" Consider using --no-check-quota flag") | |
| print("="*70 + "\n") | |
| # Создаём стратегию | |
| strategy = StrategyFactory.create( | |
| 'automated', | |
| headless=headless, | |
| check_quota_immediately=check_quota, | |
| human_delays=True | |
| ) | |
| try: | |
| # Регистрация | |
| result = strategy.register( | |
| email=email, | |
| name=name, | |
| password=password, | |
| device_flow=device_flow | |
| ) | |
| # Результат | |
| print("\n" + "="*70) | |
| if result['success']: | |
| print("✅ REGISTRATION SUCCESSFUL") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Password: {result.get('password', 'N/A')}") | |
| print(f"Token file: {result.get('token_file', 'N/A')}") | |
| print(f"Strategy: {result['strategy']}") | |
| print(f"Ban risk: {result['ban_risk']}") | |
| if not check_quota: | |
| print(f"\n⚠️ Quota check deferred (anti-ban measure)") | |
| print(f" Use: python -m autoreg.cli check-account --email {email}") | |
| else: | |
| print("❌ REGISTRATION FAILED") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Error: {result.get('error', 'Unknown error')}") | |
| print(f"Strategy: {result['strategy']}") | |
| print("="*70 + "\n") | |
| return 0 if result['success'] else 1 | |
| except KeyboardInterrupt: | |
| print("\n\n⚠️ Registration cancelled by user") | |
| return 1 | |
| except Exception as e: | |
| print(f"\n❌ Error: {e}") | |
| return 1 | |
| finally: | |
| strategy.cleanup() | |
| def cmd_register_auto(args): | |
| """ | |
| Автоматическая регистрация с email стратегией | |
| Использует настроенную email стратегию (single/plus_alias/catch_all/pool). | |
| По умолчанию использует automated стратегию, но можно указать webview. | |
| """ | |
| import os | |
| from core.email_generator import EmailGenerator | |
| count = args.count or 1 | |
| strategy_name = args.strategy or "automated" | |
| headless = args.headless | |
| check_quota = not args.no_check_quota | |
| print("\n" + "="*70) | |
| print(f"AUTO REGISTRATION ({count} accounts)") | |
| print("="*70) | |
| print(f"Strategy: {strategy_name}") | |
| print(f"Headless: {headless}") | |
| print(f"Check quota immediately: {check_quota}") | |
| print("="*70 + "\n") | |
| # Для webview стратегии - только 1 аккаунт за раз | |
| if strategy_name == "webview" and count > 1: | |
| print("⚠️ WebView strategy supports only 1 account at a time") | |
| print(" Setting count to 1") | |
| count = 1 | |
| # Получаем email стратегию из окружения | |
| email_strategy_type = os.environ.get('EMAIL_STRATEGY', 'single') | |
| imap_user = os.environ.get('IMAP_USER', '') | |
| email_domain = os.environ.get('EMAIL_DOMAIN', '') | |
| print(f"Email strategy: {email_strategy_type}") | |
| print(f"IMAP user: {imap_user}") | |
| if email_domain: | |
| print(f"Email domain: {email_domain}") | |
| # Создаём email генератор | |
| email_generator = EmailGenerator.from_env() | |
| # Генерируем email | |
| email_result = email_generator.generate() | |
| email = email_result.registration_email | |
| # Use custom login name from scheduled registration if provided | |
| custom_login_name = os.environ.get('KIRO_LOGIN_NAME', '') | |
| if custom_login_name: | |
| display_name = custom_login_name | |
| print(f"Using custom login name: {display_name}") | |
| else: | |
| display_name = email_result.display_name | |
| print(f"Generated email: {email}") | |
| print(f"Display name: {display_name}") | |
| # WebView стратегия - используем напрямую | |
| if strategy_name == "webview": | |
| strategy = StrategyFactory.create('webview') | |
| # Get OAuth provider from environment (set by VS Code extension) | |
| oauth_provider = os.environ.get('OAUTH_PROVIDER', 'Google') | |
| print(f"OAuth provider: {oauth_provider}") | |
| try: | |
| result = strategy.register( | |
| email=email, | |
| name=display_name, | |
| provider=oauth_provider, | |
| timeout=300 | |
| ) | |
| # Результат | |
| print("\n" + "="*70) | |
| if result['success']: | |
| print("[OK] SUCCESS") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Token file: {result.get('token_file', 'N/A')}") | |
| print(f"Strategy: {result['strategy']}") | |
| print(f"Ban risk: {result['ban_risk']}") | |
| print(f"\n⚠️ Quota check deferred (anti-ban measure)") | |
| else: | |
| print("[X] FAILED") | |
| print("="*70) | |
| print(f"Email: {result['email']}") | |
| print(f"Error: {result.get('error', 'Unknown error')}") | |
| print("="*70 + "\n") | |
| return 0 if result['success'] else 1 | |
| except KeyboardInterrupt: | |
| print("\n\n⚠️ Registration cancelled by user") | |
| return 1 | |
| except Exception as e: | |
| print(f"\n[X] ERROR: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return 1 | |
| finally: | |
| strategy.cleanup() | |
| # Automated стратегия - используем старый AWSRegistration | |
| from registration.register import AWSRegistration | |
| reg = AWSRegistration(headless=headless) | |
| try: | |
| results = [] | |
| for i in range(count): | |
| if i > 0: | |
| print(f"\n{'='*70}") | |
| print(f"Account {i+1}/{count}") | |
| print('='*70 + "\n") | |
| result = reg.register_auto(password=None) | |
| results.append(result) | |
| if i < count - 1: | |
| import time | |
| print(f"\n⏳ Pause 30s before next account...") | |
| time.sleep(30) | |
| # Итоги | |
| reg.print_summary(results) | |
| success_count = len([r for r in results if r.get('success')]) | |
| return 0 if success_count == count else 1 | |
| except KeyboardInterrupt: | |
| print("\n\n⚠️ Registration cancelled by user") | |
| return 1 | |
| except Exception as e: | |
| print(f"\n❌ Error: {e}") | |
| return 1 | |
| finally: | |
| reg.close() | |
| def cmd_register_batch(args): | |
| """ | |
| Пакетная регистрация с шаблоном имени и интервалом | |
| Пример: python cli_registration.py register-batch --template "Account_{N}" --count 3 --interval 5 | |
| """ | |
| import os | |
| import time | |
| from core.email_generator import EmailGenerator | |
| template = args.template or "Account_{N}" | |
| count = args.count or 2 | |
| start_num = args.start or 1 | |
| interval = args.interval or 0 # minutes, 0 = no delay | |
| provider = args.provider or "Google" | |
| strategy_name = args.strategy or "automated" | |
| headless = args.headless | |
| print("\n" + "="*70) | |
| print(f"🚀 BATCH REGISTRATION") | |
| print("="*70) | |
| print(f"Template: {template}") | |
| print(f"Count: {count}") | |
| print(f"Start #: {start_num}") | |
| print(f"Interval: {interval} min" if interval > 0 else "Interval: no delay") | |
| print(f"Strategy: {strategy_name}") | |
| print(f"Provider: {provider}") | |
| if strategy_name == "automated": | |
| print(f"Headless: {headless}") | |
| print("="*70 + "\n") | |
| results = [] | |
| # For automated strategy, create registration instance once | |
| reg = None | |
| if strategy_name == "automated": | |
| from registration.register import AWSRegistration | |
| reg = AWSRegistration(headless=headless) | |
| try: | |
| for i in range(count): | |
| current_num = start_num + i | |
| # Generate name from template | |
| login_name = template.replace('{N}', str(current_num).zfill(3)).replace('{n}', str(current_num)) | |
| print(f"\n{'='*70}") | |
| print(f"📝 Account {i+1}/{count}: {login_name}") | |
| print('='*70 + "\n") | |
| # Set environment for this registration | |
| os.environ['KIRO_LOGIN_NAME'] = login_name | |
| os.environ['OAUTH_PROVIDER'] = provider | |
| # Create email generator and generate email | |
| email_generator = EmailGenerator.from_env() | |
| email_result = email_generator.generate() | |
| email = email_result.registration_email | |
| print(f"Email: {email}") | |
| print(f"Display name: {login_name}") | |
| try: | |
| if strategy_name == "webview": | |
| # WebView strategy | |
| strategy = StrategyFactory.create('webview') | |
| try: | |
| result = strategy.register( | |
| email=email, | |
| name=login_name, | |
| provider=provider, | |
| timeout=300 | |
| ) | |
| finally: | |
| strategy.cleanup() | |
| else: | |
| # Automated strategy | |
| result = reg.register_single( | |
| email=email, | |
| name=login_name, | |
| password=None | |
| ) | |
| results.append({ | |
| 'name': login_name, | |
| 'email': email, | |
| 'success': result.get('success', False), | |
| 'token_file': result.get('token_file'), | |
| 'error': result.get('error') | |
| }) | |
| if result.get('success'): | |
| print(f"\n✅ SUCCESS: {login_name}") | |
| print(f" Token: {result.get('token_file', 'N/A')}") | |
| else: | |
| print(f"\n❌ FAILED: {login_name}") | |
| print(f" Error: {result.get('error', 'Unknown')}") | |
| except KeyboardInterrupt: | |
| print("\n\n⚠️ Registration cancelled by user") | |
| break | |
| except Exception as e: | |
| print(f"\n❌ Error: {e}") | |
| results.append({ | |
| 'name': login_name, | |
| 'email': email, | |
| 'success': False, | |
| 'error': str(e) | |
| }) | |
| finally: | |
| if 'KIRO_LOGIN_NAME' in os.environ: | |
| del os.environ['KIRO_LOGIN_NAME'] | |
| # Wait before next registration | |
| if interval > 0 and i < count - 1: | |
| wait_seconds = interval * 60 | |
| print(f"\n⏰ Next registration in {interval} minutes...") | |
| for remaining in range(wait_seconds, 0, -1): | |
| mins, secs = divmod(remaining, 60) | |
| print(f"\r ⏳ {mins:02d}:{secs:02d} remaining...", end='', flush=True) | |
| time.sleep(1) | |
| print() | |
| finally: | |
| # Cleanup automated strategy | |
| if reg: | |
| reg.close() | |
| # Summary | |
| print("\n" + "="*70) | |
| print("📊 BATCH REGISTRATION SUMMARY") | |
| print("="*70) | |
| success_count = len([r for r in results if r['success']]) | |
| failed_count = len(results) - success_count | |
| print(f"✅ Success: {success_count}") | |
| print(f"❌ Failed: {failed_count}") | |
| print() | |
| for r in results: | |
| status = "✅" if r['success'] else "❌" | |
| print(f" {status} {r['name']}: {r.get('token_file') or r.get('error', 'Unknown')}") | |
| print("="*70 + "\n") | |
| return 0 if failed_count == 0 else 1 | |
| def setup_registration_commands(subparsers): | |
| """ | |
| Настроить команды регистрации | |
| Вызывается из главного CLI для добавления команд. | |
| """ | |
| # register strategies - показать доступные стратегии | |
| parser_strategies = subparsers.add_parser( | |
| 'register-strategies', | |
| help='Show available registration strategies' | |
| ) | |
| parser_strategies.set_defaults(func=cmd_register_strategies) | |
| # register webview - WebView регистрация (рекомендуется) | |
| parser_webview = subparsers.add_parser( | |
| 'register-webview', | |
| help='Register via WebView (recommended, low ban risk)' | |
| ) | |
| parser_webview.add_argument('--email', '-e', required=True, | |
| help='Email for registration') | |
| parser_webview.add_argument('--provider', '-p', choices=['Google', 'Github'], | |
| help='OAuth provider (default: Google)') | |
| parser_webview.add_argument('--browser', '-b', | |
| help='Path to browser executable') | |
| parser_webview.add_argument('--proxy', | |
| help='Proxy in format host:port or user:pass@host:port') | |
| parser_webview.add_argument('--timeout', '-t', type=int, | |
| help='Callback timeout in seconds (default: 300)') | |
| parser_webview.set_defaults(func=cmd_register_webview) | |
| # register automated - Automated регистрация (legacy) | |
| parser_automated = subparsers.add_parser( | |
| 'register-automated', | |
| help='Register via automation (legacy, higher ban risk)' | |
| ) | |
| parser_automated.add_argument('--email', '-e', required=True, | |
| help='Email for registration') | |
| parser_automated.add_argument('--name', '-n', | |
| help='User name (generated if not specified)') | |
| parser_automated.add_argument('--password', '-p', | |
| help='Password (generated if not specified)') | |
| parser_automated.add_argument('--headless', action='store_true', | |
| help='Run browser in headless mode') | |
| parser_automated.add_argument('--no-check-quota', action='store_true', | |
| help='Do NOT check quota immediately (reduces ban risk)') | |
| parser_automated.add_argument('--device-flow', action='store_true', | |
| help='Use device flow instead of PKCE') | |
| parser_automated.set_defaults(func=cmd_register_automated) | |
| # register auto - Автоматическая регистрация с email стратегией | |
| parser_auto = subparsers.add_parser( | |
| 'register-auto', | |
| help='Auto register using email strategy from .env' | |
| ) | |
| parser_auto.add_argument('--count', '-c', type=int, | |
| help='Number of accounts to register (default: 1)') | |
| parser_auto.add_argument('--strategy', '-s', choices=['automated', 'webview'], | |
| help='Registration strategy (default: automated)') | |
| parser_auto.add_argument('--headless', action='store_true', | |
| help='Run browser in headless mode (automated only)') | |
| parser_auto.add_argument('--no-check-quota', action='store_true', | |
| help='Do NOT check quota immediately (reduces ban risk)') | |
| parser_auto.set_defaults(func=cmd_register_auto) | |
| # register batch - Пакетная регистрация с шаблоном | |
| parser_batch = subparsers.add_parser( | |
| 'register-batch', | |
| help='Batch registration with name template and interval' | |
| ) | |
| parser_batch.add_argument('--template', '-t', default='Account_{N}', | |
| help='Name template, use {N} for number (default: Account_{N})') | |
| parser_batch.add_argument('--count', '-c', type=int, default=2, | |
| help='Number of accounts to register (default: 2)') | |
| parser_batch.add_argument('--start', '-s', type=int, default=1, | |
| help='Starting number (default: 1)') | |
| parser_batch.add_argument('--interval', '-i', type=int, default=0, | |
| help='Interval between registrations in minutes (default: 0 = no delay)') | |
| parser_batch.add_argument('--provider', '-p', choices=['Google', 'Github'], default='Google', | |
| help='OAuth provider (default: Google)') | |
| parser_batch.add_argument('--strategy', choices=['automated', 'webview'], default='automated', | |
| help='Registration strategy (default: automated)') | |
| parser_batch.add_argument('--headless', action='store_true', | |
| help='Run browser in headless mode (automated only)') | |
| parser_batch.set_defaults(func=cmd_register_batch) | |
| if __name__ == '__main__': | |
| import argparse | |
| parser = argparse.ArgumentParser(description='Registration commands') | |
| subparsers = parser.add_subparsers(dest='command', help='Command to run') | |
| setup_registration_commands(subparsers) | |
| args = parser.parse_args() | |
| if not args.command: | |
| parser.print_help() | |
| sys.exit(1) | |
| sys.exit(args.func(args)) | |