feat(cli): package project as installable command
This commit is contained in:
2
src/__init__.py
Normal file
2
src/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
"""gptplus_auto package."""
|
||||
|
||||
5
src/__main__.py
Normal file
5
src/__main__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .main import main
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,7 +1,12 @@
|
||||
"""ChatGPT Plus payment flow."""
|
||||
import uuid
|
||||
from http_client import HTTPClient
|
||||
from captcha_solver import CaptchaSolver
|
||||
|
||||
try:
|
||||
from .http_client import HTTPClient
|
||||
from .captcha_solver import CaptchaSolver
|
||||
except ImportError: # pragma: no cover - allow direct script execution from source tree
|
||||
from http_client import HTTPClient
|
||||
from captcha_solver import CaptchaSolver
|
||||
|
||||
|
||||
class ChatGPTPayment:
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
"""Pure HTTP registration experiment with detailed auth-state diagnostics."""
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from urllib.parse import unquote, urlencode, urljoin, urlparse
|
||||
|
||||
from http_client import HTTPClient
|
||||
from vmail_client import get_mail_client
|
||||
from config import settings
|
||||
try:
|
||||
from .http_client import HTTPClient
|
||||
from .vmail_client import BaseMailClient
|
||||
except ImportError: # pragma: no cover - allow direct script execution from source tree
|
||||
from http_client import HTTPClient
|
||||
from vmail_client import BaseMailClient
|
||||
|
||||
|
||||
class ChatGPTRegisterHTTPReverse:
|
||||
def __init__(self, http: HTTPClient, mail: MailClient):
|
||||
def __init__(self, http: HTTPClient, mail: BaseMailClient):
|
||||
self.http = http
|
||||
self.mail = mail
|
||||
self.base = "https://chatgpt.com"
|
||||
self.auth_base = "https://auth.openai.com"
|
||||
self.root_dir = os.path.dirname(os.path.dirname(__file__))
|
||||
self.module_dir = Path(__file__).resolve().parent
|
||||
|
||||
def _cookie_rows(self) -> list[tuple[str, str, str]]:
|
||||
rows = []
|
||||
@@ -74,11 +80,19 @@ class ChatGPTRegisterHTTPReverse:
|
||||
return None
|
||||
|
||||
def _load_captured_sentinel(self, flow_name: str) -> str:
|
||||
path = os.path.join(self.root_dir, "nodatadog.js")
|
||||
try:
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
content = handle.read()
|
||||
except FileNotFoundError:
|
||||
candidates = [
|
||||
self.module_dir / "nodatadog.js",
|
||||
self.module_dir.parent / "nodatadog.js",
|
||||
Path.cwd() / "nodatadog.js",
|
||||
]
|
||||
content = ""
|
||||
for path in candidates:
|
||||
try:
|
||||
content = path.read_text(encoding="utf-8")
|
||||
break
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
if not content:
|
||||
return ""
|
||||
pattern = re.compile(r'"openai-sentinel-token": "((?:[^"\\]|\\.)*flow\\"\\"%s(?:[^"\\]|\\.)*)"' % re.escape(flow_name))
|
||||
match = pattern.search(content)
|
||||
|
||||
@@ -9,7 +9,12 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.parse import urljoin, urlparse
|
||||
|
||||
from http_client import HTTPClient
|
||||
try:
|
||||
from .config import settings
|
||||
from .http_client import HTTPClient
|
||||
except ImportError: # pragma: no cover - allow direct script execution from source tree
|
||||
from config import settings
|
||||
from http_client import HTTPClient
|
||||
|
||||
try:
|
||||
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
|
||||
@@ -170,23 +175,10 @@ class BrowserSentinelHelper:
|
||||
|
||||
|
||||
def load_proxy() -> str:
|
||||
proxy = os.getenv("SOCKS5_PROXY", "").strip()
|
||||
proxy = settings.socks5_proxy.strip()
|
||||
if proxy:
|
||||
return proxy
|
||||
|
||||
env_path = Path(__file__).resolve().parent.parent / ".env"
|
||||
if not env_path.exists():
|
||||
return ""
|
||||
|
||||
for raw_line in env_path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
if key.strip() != "SOCKS5_PROXY":
|
||||
continue
|
||||
return value.strip().strip("\"'")
|
||||
return ""
|
||||
return os.getenv("SOCKS5_PROXY", "").strip()
|
||||
|
||||
|
||||
class CodexOAuthHTTPFlow:
|
||||
@@ -314,7 +306,10 @@ class CodexOAuthHTTPFlow:
|
||||
return ""
|
||||
mail = self.mail_client
|
||||
if not mail:
|
||||
from vmail_client import get_mail_client
|
||||
try:
|
||||
from .vmail_client import get_mail_client
|
||||
except ImportError: # pragma: no cover - allow direct script execution from source tree
|
||||
from vmail_client import get_mail_client
|
||||
mail = get_mail_client()
|
||||
print("[otp] auto-fetching OTP from mailbox...")
|
||||
try:
|
||||
|
||||
25
src/main.py
25
src/main.py
@@ -5,13 +5,22 @@ import random
|
||||
import string
|
||||
import sys
|
||||
|
||||
from config import settings
|
||||
from vmail_client import get_mail_client
|
||||
from captcha_solver import CaptchaSolver
|
||||
from http_client import HTTPClient
|
||||
from chatgpt_register_http_reverse import ChatGPTRegisterHTTPReverse
|
||||
from chatgpt_payment import ChatGPTPayment
|
||||
from codex_oauth_http_flow import CodexOAuthHTTPFlow, DEFAULT_AUTHORIZE_URL
|
||||
try:
|
||||
from .config import settings
|
||||
from .vmail_client import get_mail_client
|
||||
from .captcha_solver import CaptchaSolver
|
||||
from .http_client import HTTPClient
|
||||
from .chatgpt_register_http_reverse import ChatGPTRegisterHTTPReverse
|
||||
from .chatgpt_payment import ChatGPTPayment
|
||||
from .codex_oauth_http_flow import CodexOAuthHTTPFlow, DEFAULT_AUTHORIZE_URL
|
||||
except ImportError: # pragma: no cover - allow direct script execution from source tree
|
||||
from config import settings
|
||||
from vmail_client import get_mail_client
|
||||
from captcha_solver import CaptchaSolver
|
||||
from http_client import HTTPClient
|
||||
from chatgpt_register_http_reverse import ChatGPTRegisterHTTPReverse
|
||||
from chatgpt_payment import ChatGPTPayment
|
||||
from codex_oauth_http_flow import CodexOAuthHTTPFlow, DEFAULT_AUTHORIZE_URL
|
||||
|
||||
|
||||
def generate_password(length=16):
|
||||
@@ -144,7 +153,7 @@ def cmd_codex_login(args):
|
||||
|
||||
def build_parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="main.py",
|
||||
prog="gptplus-auto",
|
||||
description="ChatGPT account tools",
|
||||
)
|
||||
sub = parser.add_subparsers(dest="command")
|
||||
|
||||
49618
src/nodatadog.js
Normal file
49618
src/nodatadog.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user