fix: replace Playwright post() with httpx legacy API, fix session_file Path coercion and comment URL check
smoke test confirmed: post via /api/submit + comment via /api/comment both working with modhash + session cookies
This commit is contained in:
parent
6cf61663a5
commit
01e5990f58
2 changed files with 30 additions and 37 deletions
|
|
@ -134,8 +134,8 @@ class RedditCommentStrategy(PostingStrategy):
|
||||||
client = RedditClient(session_file=session_file)
|
client = RedditClient(session_file=session_file)
|
||||||
comment_url = client.comment(thread_id=thread_id, body=body)
|
comment_url = client.comment(thread_id=thread_id, body=body)
|
||||||
|
|
||||||
# Reddit comment() may return empty URL; reconstruct from thread_id
|
# Reddit comment() may return bare domain or empty; reconstruct from thread_id
|
||||||
if not comment_url:
|
if not comment_url or comment_url.rstrip("/") in ("https://reddit.com", "https://www.reddit.com"):
|
||||||
comment_url = f"https://www.reddit.com/r/{target}/comments/{thread_id}/"
|
comment_url = f"https://www.reddit.com/r/{target}/comments/{thread_id}/"
|
||||||
|
|
||||||
return PostResult(url=comment_url, metadata={"thread_id": thread_id})
|
return PostResult(url=comment_url, metadata={"thread_id": thread_id})
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) Chrome/124.0.0.0"
|
||||||
class RedditClient:
|
class RedditClient:
|
||||||
def __init__(self, session_file: Path | None = None) -> None:
|
def __init__(self, session_file: Path | None = None) -> None:
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
self._session_file = session_file or Path(settings.reddit_session_file)
|
self._session_file = Path(session_file) if session_file else Path(settings.reddit_session_file)
|
||||||
ensure_valid_session(self._session_file)
|
ensure_valid_session(self._session_file)
|
||||||
self.cookies = load_cookies(self._session_file)
|
self.cookies = load_cookies(self._session_file)
|
||||||
self.headers = {"User-Agent": USER_AGENT}
|
self.headers = {"User-Agent": USER_AGENT}
|
||||||
|
|
@ -43,43 +43,36 @@ class RedditClient:
|
||||||
return self._modhash
|
return self._modhash
|
||||||
|
|
||||||
def post(self, sub: str, title: str, body: str, flair: str | None = None) -> str:
|
def post(self, sub: str, title: str, body: str, flair: str | None = None) -> str:
|
||||||
"""Submit a text post via Playwright (xvfb-run). Returns the permalink."""
|
"""Submit a text post via Reddit legacy API (httpx). Returns the permalink."""
|
||||||
settings = get_settings()
|
data = {
|
||||||
cmd = [
|
"api_type": "json",
|
||||||
"xvfb-run", "--auto-servernum",
|
"kind": "self",
|
||||||
sys.executable, str(_POST_SCRIPT),
|
"sr": sub,
|
||||||
"--sub", sub,
|
"title": title,
|
||||||
"--title", title,
|
"text": body,
|
||||||
"--body", body,
|
"uh": self.modhash,
|
||||||
"--yes",
|
"sendreplies": "true",
|
||||||
]
|
"nsfw": "false",
|
||||||
if flair:
|
"spoiler": "false",
|
||||||
cmd += ["--flair", flair]
|
}
|
||||||
|
resp = httpx.post(
|
||||||
result = subprocess.run(
|
"https://www.reddit.com/api/submit",
|
||||||
cmd,
|
cookies=self.cookies,
|
||||||
capture_output=True,
|
headers=self.headers,
|
||||||
text=True,
|
data=data,
|
||||||
timeout=180,
|
timeout=30,
|
||||||
env={
|
|
||||||
**__import__("os").environ,
|
|
||||||
"REDDIT_SESSION_FILE": str(self._session_file),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
resp.raise_for_status()
|
||||||
|
result = resp.json()
|
||||||
|
errors = result.get("json", {}).get("errors", [])
|
||||||
|
if errors:
|
||||||
|
raise RuntimeError(f"Post to r/{sub} failed: {errors}")
|
||||||
|
url = result.get("json", {}).get("data", {}).get("url", "")
|
||||||
|
if not url:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"Post to r/{sub} failed (exit {result.returncode}):\n"
|
f"Post to r/{sub} may have failed — no URL in response:\n{result}"
|
||||||
f"STDOUT:\n{result.stdout}\n"
|
|
||||||
f"STDERR:\n{result.stderr}"
|
|
||||||
)
|
)
|
||||||
for line in result.stdout.splitlines():
|
|
||||||
if line.startswith("Posted:"):
|
|
||||||
url = line.split("Posted:", 1)[-1].strip()
|
|
||||||
return url
|
return url
|
||||||
raise RuntimeError(
|
|
||||||
f"Post to r/{sub} may have failed — no 'Posted:' line in output.\n"
|
|
||||||
f"Full stdout:\n{result.stdout}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def comment(self, thread_id: str, body: str) -> str:
|
def comment(self, thread_id: str, body: str) -> str:
|
||||||
"""Post a top-level comment to a thread. Returns the permalink."""
|
"""Post a top-level comment to a thread. Returns the permalink."""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue