chore: migrate remaining address tool assets
This commit is contained in:
@@ -7,6 +7,8 @@ A small Python standard-library HTTP service with a static web UI for address/pr
|
|||||||
- `server.py` — HTTP server and API proxy/fallback logic.
|
- `server.py` — HTTP server and API proxy/fallback logic.
|
||||||
- `index.html` — browser UI; calls the local `/api/v1/dz` endpoint.
|
- `index.html` — browser UI; calls the local `/api/v1/dz` endpoint.
|
||||||
- `.env.example` — documented optional runtime environment variables.
|
- `.env.example` — documented optional runtime environment variables.
|
||||||
|
- `scripts/gen.py` — existing standalone helper for querying the fallback provider.
|
||||||
|
- `docs/migration-inventory.md` — migrated content and cutover notes.
|
||||||
- `deploy/address-tool.service.example` — example systemd unit for this repository layout.
|
- `deploy/address-tool.service.example` — example systemd unit for this repository layout.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Existing service content migration inventory
|
||||||
|
|
||||||
|
Source service directory: `/root/.openclaw/workspace/address_tool`
|
||||||
|
Active systemd unit: `address-tool.service`
|
||||||
|
|
||||||
|
## Migrated into this repository
|
||||||
|
|
||||||
|
- `server.py`: API server, request throttling, FakeNameGenerator integration and fallback provider logic. Repository copy uses a directory-relative web root and environment-only API key configuration.
|
||||||
|
- `index.html`: active browser UI served by the API server.
|
||||||
|
- `scripts/gen.py`: existing standalone CLI helper that calls the fallback address API.
|
||||||
|
- `.env.example`: names and defaults for runtime configuration; contains no credentials.
|
||||||
|
- `deploy/address-tool.service.example`: example unit for a future migration.
|
||||||
|
|
||||||
|
## Intentionally not copied into Git
|
||||||
|
|
||||||
|
- `server.py.bak-*`, `index.html.bak-*`: historical snapshots, not runtime inputs. The full source directory was preserved in a separate backup before extraction.
|
||||||
|
- `__pycache__/`: generated Python bytecode.
|
||||||
|
- Runtime credentials: kept only in an ignored local `.env` file (mode 600) when available from the existing source. Never commit it.
|
||||||
|
|
||||||
|
## Current deployment status
|
||||||
|
|
||||||
|
The existing systemd unit still runs `/root/.openclaw/workspace/address_tool/server.py` on port 18990. This migration does not stop, restart, or repoint that service. A later cutover must first test the repository copy and configure its environment file and service account.
|
||||||
|
|
||||||
|
## External runtime dependencies
|
||||||
|
|
||||||
|
- Optional FakeNameGenerator API, configured with `FNG_API_KEY`.
|
||||||
|
- Fallback API `https://www.meiguodizhi.com/api/v1/dz`.
|
||||||
|
- Cap.js widget/CDN and CAPTCHA endpoint referenced by `index.html`.
|
||||||
Executable
+88
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
API_URL = "https://www.meiguodizhi.com/api/v1/dz"
|
||||||
|
|
||||||
|
WORD_POOL = [
|
||||||
|
"sunshine", "ocean", "river", "mountain", "shadow", "forest", "galaxy",
|
||||||
|
"silver", "breeze", "whisper", "crystal", "journey", "falcon", "amber",
|
||||||
|
"meadow", "harbor", "sunset", "thunder", "frost", "velvet", "aurora",
|
||||||
|
"beacon", "canyon", "echo", "flame", "horizon", "island", "lunar",
|
||||||
|
"mystic", "nebula", "phoenix", "radiant", "stellar", "summit", "vortex",
|
||||||
|
"winter", "spring", "summer", "timber", "willow", "valley"
|
||||||
|
]
|
||||||
|
|
||||||
|
def generate_password_hint():
|
||||||
|
# 随机 2~3 个英文单词直接拼接为纯英文字符串(无符号)
|
||||||
|
count = 3 if random.random() > 0.5 else 2
|
||||||
|
chosen = random.sample(WORD_POOL, count)
|
||||||
|
return "".join(w.capitalize() for w in chosen)
|
||||||
|
|
||||||
|
def generate_birthday_18_to_19():
|
||||||
|
# 年龄大于 18 且小于 20(即 18 岁 ~ 19 岁之间)
|
||||||
|
# 格式:dd/mm/yyyy
|
||||||
|
today = datetime.date.today()
|
||||||
|
# 满 18 岁但未满 20 岁
|
||||||
|
max_birth = today - datetime.timedelta(days=int(18.01 * 365.25))
|
||||||
|
min_birth = today - datetime.timedelta(days=int(19.99 * 365.25))
|
||||||
|
|
||||||
|
total_days = (max_birth - min_birth).days
|
||||||
|
random_days = random.randint(0, max_days if (max_days := total_days) > 0 else 0)
|
||||||
|
bdate = min_birth + datetime.timedelta(days=random_days)
|
||||||
|
return bdate.strftime("%d/%m/%Y")
|
||||||
|
|
||||||
|
def get_address(city="Virginia Beach"):
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Referer": "https://www.meiguodizhi.com/",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
|
||||||
|
}
|
||||||
|
payload = json.dumps({
|
||||||
|
"city": city,
|
||||||
|
"path": "/",
|
||||||
|
"method": "refresh"
|
||||||
|
}).encode("utf-8")
|
||||||
|
|
||||||
|
try:
|
||||||
|
req = urllib.request.Request(API_URL, data=payload, headers=headers)
|
||||||
|
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||||
|
data = json.loads(resp.read().decode("utf-8"))
|
||||||
|
if data.get("status") == "ok":
|
||||||
|
return data.get("address", {})
|
||||||
|
except Exception as e:
|
||||||
|
sys.stderr.write(f"请求失败: {e}\n")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
city = sys.argv[1] if len(sys.argv) > 1 else "Virginia Beach"
|
||||||
|
addr = get_address(city)
|
||||||
|
|
||||||
|
if not addr:
|
||||||
|
print("获取失败,请重试。")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
name = addr.get("Full_Name", "").strip()
|
||||||
|
street = re.sub(r"\s+", " ", addr.get("Address", "").strip())
|
||||||
|
city_name = addr.get("City", "").strip()
|
||||||
|
state = addr.get("State", "").strip()
|
||||||
|
zip_code = addr.get("Zip_Code", "").strip()
|
||||||
|
phone = addr.get("Telephone", "").strip()
|
||||||
|
|
||||||
|
full_addr = f"{street}, {city_name}, {state} {zip_code}"
|
||||||
|
pwd_hint = generate_password_hint()
|
||||||
|
birthday = generate_birthday_18_to_19()
|
||||||
|
|
||||||
|
print(f"全名:{name}")
|
||||||
|
print(f"完整地址:{full_addr}")
|
||||||
|
print(f"电话号码:{phone}")
|
||||||
|
print(f"密码提示:{pwd_hint}")
|
||||||
|
print(f"生日:{birthday}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user