#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Collect scripts from a fixed seed repository list into this Qinglong archive.""" from __future__ import annotations import os import re import urllib.parse from typing import Dict, List import collector as c SEEDS = [ ("zy库", "https://gitee.com/jdqlscript/zy"), ("QLScriptPublic", "https://github.com/smallfawn/QLScriptPublic"), ("艾默库", "https://github.com/imoki/sign_script"), ("i茅台", "https://github.com/AkenClub/ken-iMoutai-Script"), ("偷撸库", "https://gitee.com/jdqlscript/toulu"), ("滑稽库", "https://github.com/huaji8/huajiScript"), ("其他签到库1", "https://github.com/xzxxn777/Surge"), ("其他签到库2", "https://gitee.com/jdqlscript/zyqinglong"), ("其他签到库3", "https://github.com/NaroisCool/naro-scripts"), ("其他签到库4", "https://github.com/Sitoi/dailycheckin"), ("其他签到库5", "https://github.com/sudojia/AutoTaskScript"), ("其他签到库6", "https://github.com/985Ming/qlk"), ("哔哩哔哩", "https://github.com/RayWangQvQ/BiliBiliToolPro"), ("自用青龙", "https://github.com/linbailo/zyqinglong"), ("zero205", "https://github.com/zero205/JD_tencent_scf"), ("yangro", "https://gitee.com/yangro/ql"), ("sync", "https://github.com/Aaron-lv/sync"), ("JD-Script", "https://github.com/curtinlv/JD-Script"), ("什么值得买", "https://gitee.com/jdqlscript/smzdm_script"), ("营业厅库", "https://gitee.com/jdqlscript/yyt"), ("其他签到库7", "https://github.com/xfmeng970526/ql"), ("feverrun", "https://github.com/feverrun/my_scripts"), ("WX协议本", "https://github.com/LinYuanovo/AutoTaskScripts"), ("WX协议本1", "https://github.com/3ixi/CodeScripts"), ] MAX_PER_REPO = int(os.getenv("SEED_MAX_FILES_PER_REPO", "160")) def parse_repo(url: str): u = urllib.parse.urlparse(url.rstrip("/")) parts = [p for p in u.path.split("/") if p] if len(parts) < 2: return None full = "/".join(parts[:2]) if "github.com" in u.netloc.lower(): return "GitHub", full if "gitee.com" in u.netloc.lower(): return "Gitee", full return None def get_github_repo(full: str) -> Dict: r = c.github_get(f"https://api.github.com/repos/{full}") if r: return r.json() return {"full_name": full, "default_branch": "main", "pushed_at": ""} def get_gitee_repo(full: str) -> Dict: encoded = urllib.parse.quote(full, safe="") params = {} if c.GITEE_TOKEN: params["access_token"] = c.GITEE_TOKEN r = c.generic_get( f"https://gitee.com/api/v5/repos/{encoded}", params=params, headers={"Authorization": f"token {c.GITEE_TOKEN}"} if c.GITEE_TOKEN else {}, ) if r: try: data = r.json() if isinstance(data, dict): data.setdefault("full_name", full) return data except Exception: pass return {"full_name": full, "path_with_namespace": full, "default_branch": "master", "pushed_at": ""} def sort_candidates(items: List[dict]) -> List[dict]: candidates = [x for x in items if x.get("type") in ("blob", "file") and c.is_candidate_path(x.get("path", ""))] candidates.sort(key=lambda x: ( 0 if re.search(r"(?i)(script|scripts|ql|青龙|wx_|applet|env|bili|smzdm|yyt|moutai|茅台|营业厅|值得买)", x.get("path", "")) else 1, 1 if re.search(r"(?i)(jd_|jingdong|京东|京喜)", x.get("path", "")) else 0, len(x.get("path", "")), )) return candidates def collect_seed(label: str, url: str, records: List[c.Record], seen: set, files_done: int) -> int: parsed = parse_repo(url) if not parsed: print(f"[SEED_SKIP] invalid_url label={label} url={url}", flush=True) return files_done platform, full = parsed print(f"\n[SEED] {label} | {platform} | {full}", flush=True) added_before = len(records) if platform == "GitHub": repo = get_github_repo(full) branch = str(repo.get("default_branch") or "main") tree = c.list_github_tree(repo) candidates = sort_candidates(tree) print(f" [TREE] branch={branch} candidates={len(candidates)}", flush=True) for item in candidates[:MAX_PER_REPO]: path = item.get("path", "") content, raw_url, html_url = c.get_file_content(full, path, branch) uploaded_at = c.get_file_uploaded_at(full, path, repo.get("pushed_at", "")) if content else "" if c.add_content_record(records, seen, content or "", platform, full, path, html_url, raw_url, uploaded_at): files_done += 1 else: repo = get_gitee_repo(full) branch = str(repo.get("default_branch") or "master") tree = c.list_gitee_tree(repo) branch = str(repo.get("default_branch") or branch) candidates = sort_candidates(tree) print(f" [TREE] branch={branch} candidates={len(candidates)}", flush=True) for item in candidates[:MAX_PER_REPO]: path = item.get("path", "") content, raw_url, html_url = c.get_gitee_file_content(full, path, branch) uploaded_at = c.get_gitee_file_uploaded_at(full, path, repo.get("pushed_at", "")) if content else "" if c.add_content_record(records, seen, content or "", platform, full, path, html_url, raw_url, uploaded_at): files_done += 1 print(f" [SEED_DONE] added={len(records) - added_before}", flush=True) return files_done def main(): c.OUT_DIR.mkdir(parents=True, exist_ok=True) c.META_DIR.mkdir(parents=True, exist_ok=True) seen = c.load_seen_hashes() records: List[c.Record] = [] files_done = 0 for label, url in SEEDS: try: files_done = collect_seed(label, url, records, seen, files_done) except RuntimeError as e: if str(e) == "github_rate_limited": print("[WARN] GitHub rate limited; continuing with later non-GitHub seeds where possible", flush=True) continue raise except Exception as e: print(f"[SEED_ERROR] {label} {url}: {type(e).__name__}: {e}", flush=True) continue if records: c.save_indexes(records) c.update_readme() else: c.rebuild_index_from_files() print(f"\n[DONE] seed_added={len(records)} files_done={files_done}", flush=True) if __name__ == "__main__": main()