| 54 | |
| 55 | |
| 56 | class AnyAutoRegistrationEngine: |
| 57 | def __init__( |
| 58 | self, |
| 59 | email_service, |
| 60 | proxy_url: Optional[str] = None, |
| 61 | callback_logger: Optional[Callable[[str], None]] = None, |
| 62 | max_retries: int = 3, |
| 63 | browser_mode: str = "protocol", |
| 64 | extra_config: Optional[Dict[str, Any]] = None, |
| 65 | ): |
| 66 | self.email_service = email_service |
| 67 | self.proxy_url = proxy_url |
| 68 | self.callback_logger = callback_logger or (lambda _msg: None) |
| 69 | self.max_retries = max(1, int(max_retries or 1)) |
| 70 | self.browser_mode = browser_mode or "protocol" |
| 71 | self.extra_config = dict(extra_config or {}) |
| 72 | |
| 73 | self.email: Optional[str] = None |
| 74 | self.inbox_email: Optional[str] = None |
| 75 | self.email_info: Optional[Dict[str, Any]] = None |
| 76 | self.password: Optional[str] = None |
| 77 | self.session = None |
| 78 | self.device_id: Optional[str] = None |
| 79 | |
| 80 | def _log(self, message: str): |
| 81 | if self.callback_logger: |
| 82 | self.callback_logger(message) |
| 83 | |
| 84 | @staticmethod |
| 85 | def _build_password(length: int) -> str: |
| 86 | length = max(8, int(length or DEFAULT_PASSWORD_LENGTH)) |
| 87 | password_chars = [ |
| 88 | secrets.choice(string.ascii_lowercase), |
| 89 | secrets.choice(string.ascii_uppercase), |
| 90 | secrets.choice(string.digits), |
| 91 | secrets.choice(PASSWORD_SPECIAL_CHARSET), |
| 92 | ] |
| 93 | password_chars.extend(secrets.choice(PASSWORD_CHARSET) for _ in range(length - len(password_chars))) |
| 94 | secrets.SystemRandom().shuffle(password_chars) |
| 95 | return "".join(password_chars) |
| 96 | |
| 97 | @staticmethod |
| 98 | def _should_retry(message: str) -> bool: |
| 99 | text = str(message or "").lower() |
| 100 | retriable_markers = [ |
| 101 | "tls", |
| 102 | "ssl", |
| 103 | "curl: (35)", |
| 104 | "预授权被拦截", |
| 105 | "authorize", |
| 106 | "registration_disallowed", |
| 107 | "http 400", |
| 108 | "创建账号失败", |
| 109 | "未获取到 authorization code", |
| 110 | "consent", |
| 111 | "workspace", |
| 112 | "organization", |
| 113 | "otp", |
no outgoing calls
no test coverage detected