| | |
| | | if refresh_raw is not None: |
| | | if not isinstance(refresh_raw, Mapping): |
| | | raise CollectorError("E_CONFIG", "config.refresh must be an object.") |
| | | if creator_uid is None: |
| | | raise CollectorError("E_CONFIG", "refresh requires creator.uid.", safety=True) |
| | | refresh_page = urlsplit(dynamic_url) |
| | | if ( |
| | | creator_name.strip() != "青枫浦上Q" |
| | | or creator_uid != "1420210197" |
| | | or dynamic_url != "https://space.bilibili.com/1420210197/dynamic" |
| | | refresh_page.scheme != "https" |
| | | or refresh_page.hostname != "space.bilibili.com" |
| | | or refresh_page.query |
| | | or refresh_page.fragment |
| | | or refresh_page.path.rstrip("/") != f"/{creator_uid}/dynamic" |
| | | ): |
| | | raise CollectorError("E_CONFIG", "refresh supports only the registered creator identity.", safety=True) |
| | | raise CollectorError("E_CONFIG", "refresh page URL must bind creator.uid.", safety=True) |
| | | |
| | | def bounded_int(field: str, default: int, lower: int, upper: int) -> int: |
| | | raw = refresh_raw.get(field, default) |
| | |
| | | handoff = subparsers.add_parser("handoff", help="Generate an unsent canonical Codex-native video handoff") |
| | | handoff.add_argument("--output", type=Path, help="Optional no-overwrite Markdown output path") |
| | | handoff.add_argument("--now", help="Optional offset-aware ISO-8601 clock for deterministic runs") |
| | | begin = subparsers.add_parser("refresh-begin", help="Create one durable hourly browser-refresh run") |
| | | run_refresh = subparsers.add_parser( |
| | | "refresh-run", |
| | | help="Fail closed: trusted local-unpacked extension/Host is required", |
| | | ) |
| | | run_refresh.add_argument("--now", help="Optional offset-aware ISO-8601 clock for deterministic runs") |
| | | begin = subparsers.add_parser( |
| | | "refresh-begin", help="Recover an existing refresh run (new schema3 runs require refresh-run)" |
| | | ) |
| | | begin.add_argument("--now", help="Optional offset-aware ISO-8601 clock for deterministic runs") |
| | | commit = subparsers.add_parser("refresh-commit", help="Validate and commit one local browser evidence file") |
| | | commit.add_argument("--input", required=True, type=Path, help="Final browser evidence JSON from refresh-begin") |
| | |
| | | if args.output: |
| | | output = args.output if args.output.is_absolute() else Path.cwd() / args.output |
| | | result = generate_handoff(config, output, now) |
| | | elif args.command in {"refresh-begin", "refresh-commit"}: |
| | | elif args.command in {"refresh-run", "refresh-begin", "refresh-commit"}: |
| | | from bili_dynamic_refresh import refresh_begin, refresh_commit |
| | | |
| | | if config.refresh is None: |
| | | raise CollectorError("E_CONFIG", "config.refresh is required for refresh commands.") |
| | | if args.command == "refresh-begin": |
| | | if args.command == "refresh-run": |
| | | from bili_dynamic_refresh_controller import run_product |
| | | |
| | | result = run_product(config, config_path_value, now) |
| | | elif args.command == "refresh-begin": |
| | | result = refresh_begin(config, config_path_value, now) |
| | | else: |
| | | result = refresh_commit(config, config_path_value, absolute_lexical(args.input), now) |