From 3fa56cf42410c413636395571c95795ff61ddcec Mon Sep 17 00:00:00 2001 From: John Howe <89397553+timerring@users.noreply.github.com> Date: Sun, 21 Dec 2025 13:11:23 +0800 Subject: [PATCH] feat: enable local test --- .env.test | 0 .gitignore | 3 ++- README-en.md | 15 +++++++++++++++ README.md | 15 +++++++++++++++ nodeseek/nodeseek.py | 20 +++++++------------- onepoint3acres/onepoint3acres.py | 7 +++++-- requirements.txt | 3 ++- telegram/notify.py | 7 +++++-- v2ex/v2ex.py | 7 +++++-- 9 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 .env.test diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore index b02bfee..2213367 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ */__pycache__ -node_modules/ \ No newline at end of file +node_modules/ +.env \ No newline at end of file diff --git a/README-en.md b/README-en.md index 948c0c5..e2bac99 100644 --- a/README-en.md +++ b/README-en.md @@ -106,6 +106,21 @@ https://github.com/timerring/CloudCheckin/blob/0b719258ab4f5f746b067798eb2a4185a After configuring all content, please manually execute the `Setup CircleCI Context and Secrets` and `Deploy Cloudflare Worker` workflows once to ensure that configuration secrets are correctly synchronized to CircleCI contexts secrets through CircleCI CLI, and that the Cloudflare Worker is properly deployed. (Actions -> `Setup CircleCI Context and Secrets` -> `Run workflow` and Actions -> `Deploy Cloudflare Worker` -> `Run workflow`) +## Local Development + +```bash +# Install dependencies +pip install -r requirements.txt + +# Copy env template and fill in your config +cp .env.test .env + +# Run check-in scripts +python -m nodeseek.nodeseek +python -m v2ex.v2ex +python -m onepoint3acres.onepoint3acres +``` + ## FAQ 1. **Why use CircleCI instead of GitHub Actions directly?** diff --git a/README.md b/README.md index a11c9c3..e7843bf 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,21 @@ https://github.com/timerring/CloudCheckin/blob/0b719258ab4f5f746b067798eb2a4185a > [!IMPORTANT] > 有时 cookie 会过期导致签到失败,如果遇到失败情况,请考虑重新获取 cookie 填入 Secrets,再手动执行 `Setup CircleCI Context and Secrets` workflow 同步 cookie 到 CircleCI。 +## 本地调试 + +```bash +# 安装依赖 +pip install -r requirements.txt + +# 复制环境变量模板并填入你的配置 +cp .env.test .env + +# 运行签到脚本 +python -m nodeseek.nodeseek +python -m v2ex.v2ex +python -m onepoint3acres.onepoint3acres +``` + ## 常见问题 1. 为什么要采用 CircleCI,不直接用 Github Actions? diff --git a/nodeseek/nodeseek.py b/nodeseek/nodeseek.py index 2282834..01e95d2 100644 --- a/nodeseek/nodeseek.py +++ b/nodeseek/nodeseek.py @@ -3,10 +3,13 @@ from curl_cffi import requests import random import time +from dotenv import load_dotenv from telegram.notify import send_tg_notification +load_dotenv() + # Get COOKIE from environment variable, multiple cookies separated by & -cookies = os.environ.get('NODESEEK_COOKIE').strip() +cookies = os.environ.get('NODESEEK_COOKIE', '').strip() if not cookies: raise ValueError("Environment variable NODESEEK_COOKIE is not set") @@ -17,19 +20,10 @@ # Request headers headers = { - 'Accept': '*/*', - 'Accept-Encoding': 'gzip, deflate, br, zstd', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', - 'Content-Length': '0', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0', 'Origin': 'https://www.nodeseek.com', 'Referer': 'https://www.nodeseek.com/board', - 'Sec-CH-UA': '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"', - 'Sec-CH-UA-Mobile': '?0', - 'Sec-CH-UA-Platform': '"Windows"', - 'Sec-Fetch-Dest': 'empty', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-origin', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36', + 'Content-Type': 'application/json', } # Iterate over multiple account cookies for check-in @@ -47,7 +41,7 @@ try: # random=true means get a random bonus url = 'https://www.nodeseek.com/api/attendance?random=true' - response = requests.post(url, headers=headers, impersonate="chrome110") + response = requests.post(url, headers=headers, impersonate="chrome124") # Output the status code and response content print(f"The {idx+1} account's Status Code: {response.status_code}", flush=True) diff --git a/onepoint3acres/onepoint3acres.py b/onepoint3acres/onepoint3acres.py index a814756..f74176c 100644 --- a/onepoint3acres/onepoint3acres.py +++ b/onepoint3acres/onepoint3acres.py @@ -6,9 +6,12 @@ import requests import http.cookies import time +from dotenv import load_dotenv from .questions import questions from telegram.notify import send_tg_notification +load_dotenv() + class OnePointThreeAcres: def __init__(self, cookie: str, solver: TwoCaptcha): self.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" @@ -209,8 +212,8 @@ def answer_daily_question(self, question: int, answer: int) -> bool: if __name__ == "__main__": - cookie = os.environ.get('ONEPOINT3ACRES_COOKIE').strip() - TwoCaptcha_apikey = os.environ.get('TWOCAPTCHA_APIKEY').strip() + cookie = os.environ.get('ONEPOINT3ACRES_COOKIE', '').strip() + TwoCaptcha_apikey = os.environ.get('TWOCAPTCHA_APIKEY', '').strip() try: if not cookie: diff --git a/requirements.txt b/requirements.txt index 79ecc54..e6829f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ requests 2captcha-python -curl_cffi \ No newline at end of file +curl_cffi +python-dotenv \ No newline at end of file diff --git a/telegram/notify.py b/telegram/notify.py index ac42870..0e2e5c0 100644 --- a/telegram/notify.py +++ b/telegram/notify.py @@ -3,12 +3,15 @@ import json import os import sys +from dotenv import load_dotenv + +load_dotenv() # follow the instructions from https://core.telegram.org/bots/features#botfather and get the bot token -TELEGRAM_TOKEN = os.environ.get('TELEGRAM_TOKEN').strip() +TELEGRAM_TOKEN = os.environ.get('TELEGRAM_TOKEN', '').strip() # add the bot to your contact and send a message to it # then check the url https://api.telegram.org/bot{TELEGRAM_TOKEN}/getUpdates to get the chat id -TELEGRAM_CHAT_ID = os.environ.get('TELEGRAM_CHAT_ID').strip() +TELEGRAM_CHAT_ID = os.environ.get('TELEGRAM_CHAT_ID', '').strip() def send_tg_notification(message): """Send Telegram notification diff --git a/v2ex/v2ex.py b/v2ex/v2ex.py index 921112e..1093e7f 100644 --- a/v2ex/v2ex.py +++ b/v2ex/v2ex.py @@ -3,9 +3,12 @@ import os from datetime import datetime, timedelta import sys +from dotenv import load_dotenv from telegram.notify import send_tg_notification -cookie = os.environ.get('V2EX_COOKIE').strip() +load_dotenv() + +cookie = os.environ.get('V2EX_COOKIE', '').strip() # Initial the message time time = datetime.now() + timedelta(hours=8) message = time.strftime("%Y/%m/%d %H:%M:%S") + " from V2EX \n" @@ -24,7 +27,7 @@ "sec-fetch-user": "?1", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", - "cookie": f"'{cookie}'", + "cookie": cookie, } def get_once() -> tuple[str, bool]: