Skip to content

Refactor collector into modular package; add source health, validation, exporter, tests, and CI - #13

Open
MahanKenway wants to merge 2 commits into
mainfrom
codex/find-issues-in-the-code-yfhd5l
Open

Refactor collector into modular package; add source health, validation, exporter, tests, and CI#13
MahanKenway wants to merge 2 commits into
mainfrom
codex/find-issues-in-the-code-yfhd5l

Conversation

@MahanKenway

Copy link
Copy Markdown
Owner

Motivation

  • Restructure the one-file scripts/collector.py into a maintainable package to improve testability and safety.
  • Add robust source health tracking and static validation to avoid noisy or private endpoints.
  • Provide clear export, notification, and parsing layers so reachability testing and I/O are isolated.
  • Document operational guidance, add license and abuse/security policies, and enable CI to run the collector and persist changes.

Description

  • Introduce a new src/ package with modules: core (collector, parser, tester, exporter, notifier, deduplicate, source_health, static_validator), models, config, utils, and main to drive the pipeline.
  • Replace the legacy scripts/collector.py runner to call src.main, and add config/sources.yaml, src/config/settings.py, and a .env.example for runtime configuration.
  • Add deterministic deduplication, base64 decoding helpers, structured logging, JSON schema (schemas/config.schema.json), and prioritized source quarantine/health management.
  • Add documentation and governance files (ABUSE.md, SECURITY.md, CONTRIBUTING.md, docs/*), a project LICENSE, .gitignore, test configuration (pytest.ini), and a GitHub Actions workflow that runs python -m src.main, commits generated configs/, and uploads logs on failure.

Testing

  • Added unit tests under tests/ covering parser, deduplication, tester, source health, and static validation and ran pytest to execute the suite.
  • Ran pytest (13 tests) and all tests completed successfully.
  • No additional automated linting or packaging steps were executed as part of this PR.

Codex Task

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa9ae01a30

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/parser.py
if not payload:
return None
data = json.loads(payload)
host = data.get("add")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip non-object VMess payloads

When a fetched VMess line decodes to valid JSON that is not an object, for example vmess://W10= ([]), data.get raises AttributeError, which is not caught by parse. Since ConfigCollector.collect() parses every untrusted source line before testing, one malformed VMess entry aborts the whole update instead of being skipped; check that data is a dict or catch this case before reading fields.

Useful? React with 👍 / 👎.

Comment thread src/core/parser.py
return None
data = decoded
data = data.split("?", 1)[0]
match = re.search(r"@([^:/]+):(\d+)$", data)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept Shadowsocks plugin URLs with a slash

Shadowsocks/SIP002 plugin URLs commonly include the optional slash before the query, e.g. ss://cipher:password@example.com:443/?plugin=...; after the query is stripped this leaves ...:443/, so the end-anchored regex does not match and the config is silently dropped before reachability testing. This removes otherwise valid SS plugin configs from both ss.txt and mix.txt; allow the optional trailing slash/path when extracting host and port.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c29841f39

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/core/tester.py
host, port, type=socket.SOCK_STREAM
)
]
except socket.gaierror:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Catch IDNA errors during DNS resolution

When a feed includes a syntactically parseable config with an invalid IDNA hostname, such as a single 300-character label, socket.getaddrinfo raises UnicodeEncodeError rather than socket.gaierror. Since ConfigCollector.collect() consumes executor.map() directly, that worker exception aborts the whole scheduled update instead of skipping the bad config; catch UnicodeError here or validate hostname length before resolving.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant