mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-07-09 12:41:05 +02:00
8e70d0411d989d851d6343ecadec2e38ea8cf698
1012 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8e70d0411d |
refactor: decompose WebScrapingMixin (static helpers, diagnostics, exception annotations) (#1174)
## ℹ️ Description Decompose `WebScrapingMixin` — incremental internal refactors to reduce class size and improve separation of concerns. ## 📋 Changes Summary ### Static method extraction - Extract 5 `@staticmethod` members from `WebScrapingMixin` to module-level private functions in `web_scraping_mixin.py` - Update internal call sites and test call sites (no compatibility aliases) ### Browser diagnostics extraction - Create `src/kleinanzeigen_bot/utils/browser_diagnostics.py` with module-level diagnostic functions - `WebScrapingMixin.diagnose_browser_issues()` → thin delegator (resolves `self` attrs, calls extracted logic) - Replace `self`-coupled logic with explicit parameter dependencies - Migrate translations to new module section in `translations.de.yaml` ### Exception annotations - Add `# noqa: BLE001` + justification comments to 4 bare `except Exception:` blocks (no behavior changes) ### ⚙️ Type of Change - [x] 🔧 Refactor (internal code improvements, no behavior changes) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`) — 1287 passed, 4 skipped - [x] I have formatted the code (`pdm run format`) - [x] I have verified that linting passes (`pdm run lint`) — ruff, mypy, pyright clean - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added enhanced browser troubleshooting with remote-debugging connectivity checks, running-process inspection, and Chrome/Edge compatibility validation including recommended configuration updates. * **Refactor** * Reorganized browser/session diagnostics and remote-debugging argument handling into dedicated utilities; introduced a shared browser runtime configuration container. * **Chores** * Suppressed linter warnings for intentionally broad exception handling. * **Tests** * Updated unit and integration tests to match the new diagnostics flow and remote-debugging probing behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b2dce90ef1 |
refactor: remove dead wrapper methods from KleinanzeigenBot (#1172)
## ℹ️ Description Remove four private wrapper methods on `KleinanzeigenBot` in `app.py` that wrap public module-level functions but have zero production call sites. This is a cleanup-only change with no behavioral impact. ## 📋 Changes Summary - **Remove** `_has_logged_in_marker` — delegates to `login_flow.has_logged_in_marker` - **Remove** `_check_publishing_result` — delegates to `publishing_workflow.check_publishing_result` - **Remove** `_delete_old_ad_if_needed` — delegates to `publishing_workflow.delete_old_ad_if_needed` - **Remove** `_capture_login_detection_diagnostics_if_enabled` — delegates to `login_flow.capture_login_detection_diagnostics_if_enabled` - **Remove** unused `Literal` import - **Retarget** 4 helper-detail tests that called the deleted wrapper directly to the real `login_flow.capture_login_detection_diagnostics_if_enabled` function ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized login detection diagnostics functionality for improved accessibility * Simplified login status verification logic within the authentication system <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
dedf4cb4f0 |
refactor: extract template name renderer from AdExtractor (#1171)
## ℹ️ Description Extract the priority-based template rendering algorithm from `_render_download_name_with_budget` into a module-level pure function `_render_name_with_budget`. The method becomes a thin wrapper that delegates rendering and handles truncation warnings. ## 📋 Changes Summary - Added `_render_name_with_budget(template, ad_id, title, max_length) -> tuple[str, bool, bool]` as a module-level pure function with no AdExtractor dependency - Rewrote `_render_download_name_with_budget` as a thin wrapper that calls the pure function and handles logging - Removed `_reserved_for_pending_placeholders` static method (logic inlined in the pure function) ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved download name handling with enhanced truncation logic for improved filename generation. * Added warnings when download names are automatically shortened due to length constraints. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e15c57f131 |
ci(deps): bump actions/checkout from 6.0.3 to 7.0.0 in the all-actions group (#1170)
Bumps the all-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 6.0.3 to 7.0.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
1f142f8339 |
refactor: extract selector and filter helpers from load_ads (#1169)
## ℹ️ Description Extract three private helpers from `load_ads()` to remove the last remaining `# noqa: PLR0915` annotation in main source. `load_ads` goes from ~100 statements to ~35 — a clean orchestration function. ## 📋 Changes Summary - **`_parse_ad_selector`**: parse `ads_selector` string into numeric IDs list or frozenset of tokens - **`_should_include_ad`**: token-based ad filtering ("changed"/"new"/"due"/"all") — preserves exact ordering, side effects, and "changed"/price-reduction-for-update logic - **`_prepare_selected_ad_entry`**: description validation, category resolution, image resolution — called only after filtering to avoid validating skipped ads - Translation keys moved to match new caller function names (`_should_include_ad:`, `_prepare_selected_ad_entry:`) - Added regression test: inactive ad with unresolvable images is skipped without error ### ⚙️ Type of Change - [x] ✨ New feature (adds new functionality without breaking existing usage) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized ad loading process with improved selector parsing and filtering logic for better code maintainability. * Optimized validation workflow: inactive and non-selected ads now skip description and image validation, improving overall efficiency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
388d0fb3c8 |
refactor: separate download ad persistence concerns (#1168)
## ℹ️ Description Separate downloaded-ad persistence concerns from `download_ad()` in `extract.py`. The original method mixed browser extraction, local-settings preservation, and a filesystem transaction — three independently meaningful and operationally sensitive concerns. ## 📋 Changes Summary - **Extracted `_preserve_local_settings_from_existing_ad()`** — preserves local-only settings (repost_count, republication_interval, auto_price_reduction, price_reduction_count) from an existing ad YAML into the new config. No-op unless `preserve_local_settings` is enabled. - **Extracted `_commit_staged_download()`** — owns the full filesystem transaction: YAML save, backup collision check, rename final→backup→staging→final, backup cleanup, and rollback on failure. - **Simplified `download_ad()`** — now a clean 3-step orchestrator: extract → preserve → commit. - **Restructured translation keys** in `translations.de.yaml` to follow the new caller function names. No behavior changes to preservation, rollback, YAML handling, or exception propagation. ### ⚙️ Type of Change - [ ] 🐞 Bug fix - [ ] ✨ New feature - [ ] 💥 Breaking change ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Enhanced ad download process with improved backup and rollback mechanisms for better reliability * Refined handling of local settings preservation during re-downloads to maintain data integrity <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
eeeae6ea5e |
refactor: extract shipping helpers from set_shipping (#1167)
## ℹ️ Description Refactor `set_shipping` in `publishing_form.py` by extracting four distinct concerns into focused private helpers. Simplifies a ~55-statement function into a ~20-statement orchestrator with a flat if-return chain. ## 📋 Changes Summary - Extract `_select_shipping_combobox_if_present` — PRO/commercial combobox handling - Extract `_set_pickup_shipping` — PICKUP radio + fieldset fallback - Extract `_set_configured_shipping_options` — shipping options dialog + MODIFY nav - Extract `_enable_platform_default_shipping` — enable shipping toggle - Keep legacy `shipping_costs` guard inline in `set_shipping` (per review) - Re-key translation entries under new caller-function names (duplicate "Failed to set shipping..." under both combobox and pickup helpers) - `set_shipping` slimmed from ~55 → ~20 ruff-counted statements ### ⚙️ Type of Change - [ ] 🐞 Bug fix - [ ] ✨ New feature - [ ] 💥 Breaking change ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Refactor * **Shipping configuration**: Refactored the shipping configuration logic to improve internal code structure and maintainability, enabling more reliable handling of shipping options across different scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
780743aee2 |
refactor: separate download_ads workflow modes (#1166)
## ℹ️ Description Extract four private async helpers from `download_ads()` to separate per-mode workflow logic. - Motivation: Reduce function complexity, enable tighter pylint thresholds ## 📋 Changes Summary - Extracted `_fetch_published_ads_by_id` — fetch and build published ads lookup dict - Extracted `_download_all_ads` — download all ads from overview page - Extracted `_download_new_ads` — download only unsaved ads (preserving URL dedup behavior) - Extracted `_download_ads_by_ids` — download specific ads by numeric ID (preserving distinct warning semantics) - Slimmed `download_ads()` to ~48-line orchestrator (was ~124 lines) - Restructured `translations.de.yaml` — messages moved to per-function sections - Ratcheted pylint thresholds: max-statements 90→76, max-branches 35→31 ### ⚙️ Type of Change - [ ] 🐞 Bug fix - [ ] ✨ New feature - [ ] 💥 Breaking change Internal refactor, no user-visible behavior change. ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`): 1286 passed, 4 skipped - [x] I have formatted the code (`pdm run format`) - [x] I have verified that linting passes (`pdm run lint`) - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Strengthened code quality standards and refactored internal ad downloading logic for improved maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
eaa646874d |
refactor: replace get_message_template match with dict lookup (#1165)
## ℹ️ Description Replace the ~115-arm match/case in `__get_message_template` with a module-level `_MESSAGE_TEMPLATES` dict of raw English strings plus a 3-line lazy `_(template)` lookup function. - **Motivation**: Eliminate 5 complexity `noqa` annotations (C901, PLR0911, PLR0912, PLR0915, E701) by removing the real architectural complexity — a pure flat error-code → message mapping that has zero branching or logic. - **Approach**: A `dict[str, str]` of raw English strings (no `_()` calls at import time) with lazy translation inside `__get_message_template`. `"custom_error"` intentionally omitted — handled by `.get()` default. - **Translation**: Caller function name unchanged → translation keys under `__get_message_template` preserved. AST-based translation test extractor updated to recognize `_MESSAGE_TEMPLATES` dict values. ## 📋 Changes Summary - `src/kleinanzeigen_bot/utils/pydantics.py`: Replaced ~115 match arms with `_MESSAGE_TEMPLATES` dict + 3-line function; removed all 5 noqa annotations - `tests/unit/test_translations.py`: Added AST extraction for `_MESSAGE_TEMPLATES` dict values to maintain translation coverage checks ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved error message handling system to support better internationalization and translation workflows * **Tests** * Updated test suite to extract and verify translatable message strings <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
32c6d3985f |
refactor: split published ads pagination (#1164)
## ℹ️ Description Extract content-decoding and paging-navigation logic from `fetch_published_ads` into focused module-level helpers, reducing function complexity while preserving all behavior. ## 📋 Changes Summary - **`published_ads.py`**: Extracted `_parse_published_ads_page()` (content decode, JSON parse, payload validation, ad filtering) and `_determine_next_page()` (paging metadata resolution, last-page/empty-ads guards). Main `fetch_published_ads` is now a clean orchestration loop: request → response check → parse → extend → paginate. - **`translations.de.yaml`**: Split the single `fetch_published_ads:` translation section into three sections (`fetch_published_ads:`, `_parse_published_ads_page:`, `_determine_next_page:`) matching the new caller function names. Added missing translation for "No paging dict found on page %s". - **`pyproject.toml`**: Lowered `max-statements` from 115 to 90. - **`pydantics.py`**: Added `PLR0915` noqa for `__get_message_template` (already an approved exception for the generated pydantic error-code mapping). ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved published-ads fetching by separating response decoding and pagination handling into dedicated helpers, while preserving existing behavior. * Reworked strict-mode validation and stopping conditions for clearer control flow and more consistent error handling. * **Chores** * Updated linting limits to enforce stricter code quality. * Added targeted lint suppression for an overly complex section. * **Tests** * Expanded unit test coverage for published-ads content decoding and strict-mode failure cases across multiple malformed/edge responses. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c6843a49c0 |
fix: avoid TypeError abort when web_request gets a non-dict response (#1162)
## ℹ️ Description When publishing a batch of ads, a single transient page-load failure could crash the **entire** run with an unhandled `TypeError`. During the pre-publish delete step, `delete_flow.delete_ad` calls `web_request`, which runs a `fetch(...)` via `web_execute`. When the page context is torn down mid-navigation (the same condition that surfaces as *"Page did not finish loading within 30.0 seconds"*), `web_execute` returns a CDP `ExceptionDetails` object (or `None`) instead of the expected response dict. `web_request` then does `response["statusCode"]`, raising: ``` TypeError: [ExceptionDetails] object is not subscriptable File ".../utils/web_scraping_mixin.py", line 1537, in web_request response["statusCode"] in valid_response_codes, ``` This `TypeError` is **not** caught by the publish retry loop (which handles `TimeoutError` / `ProtocolException`), so it propagates all the way up and aborts the whole batch — every remaining ad goes unpublished. Observed live while publishing ~25 ads: 9 published successfully, two hit transient load timeouts, and the next `delete_ad` request crashed the process. - Link to the related issue(s): Issue # ## 📋 Changes Summary - `web_request`: guard the response — if it is not a `dict` containing `statusCode`, raise a `ProtocolException` (already imported) instead of blindly subscripting it. - `ProtocolException` is already handled by the publish retry/skip logic, so a single transient failure now retries and then skips that one ad, letting the rest of the batch continue. - Add a parametrized regression test in `test_web_scraping_mixin.py` covering `None` / non-dict / missing-`statusCode` responses. ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured the affected tests pass (`pytest tests/unit/test_web_scraping_mixin.py -k web_request` → 7 passed). - [ ] I have formatted the code (`pdm run format`). - [ ] I have verified that linting passes (`pdm run lint`). - [ ] I have updated documentation where necessary (n/a). By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Enhanced validation for network operation responses with improved error messaging for unexpected situations, preventing hidden failures and providing clearer diagnostics when issues occur. * **Tests** * Extended test coverage to comprehensively validate error handling across various edge cases and unexpected response scenarios in network operations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0c75eea071 |
chore: Update Python dependencies (#1163)
✔ Update wrapt 2.2.1 -> 2.2.2 successful ✔ Update coverage 7.14.1 -> 7.14.2 successful Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
b5e2769f2d |
refactor: extract special attribute helpers from publishing form (#1161)
## ℹ️ Description Extract three module-level helpers from `set_special_attributes()` in `publishing_form.py` to reduce local variable count and improve readability. `set_special_attributes` had 27 locals — after extraction it has 10. - Behavior-preserving: no change to exception propagation, logging, or control flow. - `condition_s` probe stays in main to avoid translation-key churn. ## 📋 Changes Summary - Extract `_build_special_attribute_xpath()` — Pure XPath construction (fix comment: five → six patterns) - Extract `_resolve_special_attribute_element()` — Wraps `web_find_all` + candidate pick, propagates exceptions uncaught - Extract `_set_special_attribute_input()` — 6-branch input-type dispatch; hidden-input returns without logging, caller logs once - Rewire `set_special_attributes` to call the three helpers - Ratchet `pyproject.toml`: PLR0914 max-locals 27 → 20 - Update `translations.de.yaml`: move 4 debug messages + add `Failed to set attribute` under `_set_special_attribute_input` ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] ♻️ Refactor (non-breaking restructuring of existing code) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). → 1268 passed, 4 skipped - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. → Translation file updated <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Chores** * Tightened linting rules by lowering the allowed maximum number of local variables. * **Refactor** * Reworked special-attribute DOM handling to use clearer selection and value-setting paths for different field types, including improved fallback behavior. * **Tests** * Added async unit test coverage for `set_special_attributes`, including input fallback behavior and error cases for unsupported checkbox values and missing hidden input metadata. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d542f1ea92 |
feat: use configured --remote-debugging-host for browser diagnostics probes (#1160)
## ℹ️ Description `diagnose_browser_issues()` previously hardcoded `127.0.0.1` for port-open and `/json/version` API probes. When Chrome's remote debugging is exposed on a different host (Docker, LAN, CI), the diagnostics miss the running browser entirely. This PR makes diagnostics host-aware by parsing `--remote-debugging-host` from `browser_config.arguments` and using the configured host instead of the hardcoded `127.0.0.1`. All diagnostics probes (port, API, Chrome version) now respect the configured host. ## 📋 Changes Summary - Added `_diagnostic_remote_debugging_endpoint()` — private diagnostics parser with first-wins semantics for both host and port, defaults to `127.0.0.1:0` - Added `_format_url_host()` — IPv6-safe URL bracketing helper - Threaded configured host into `net.is_port_open()`, `_remote_debugging_api_browser()`, and `_diagnose_chrome_version_issues()` - Emit `LOG.warning` before probing a non-loopback configured host (security/documentation guard) - Updated German translations for changed log message strings - Added tests: configured host `10.0.0.5` and `192.168.1.100`, host-after-port ordering, IPv6 URL formatting, Chrome-version host propagation - Default behavior (no `--remote-debugging-host` argument) unchanged — probes remain `127.0.0.1` ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [x] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved remote browser debugging diagnostics to work with non-local hosts, including correct IPv6-safe URL formatting. * Added host-aware reachability checks and clearer warnings when the configured remote host may not be loopback. * Enhanced diagnostic messaging to report the configured host and port during remote debugging checks. * **Tests** * Expanded unit test coverage for configured remote-debugging hosts (including IPv6) and updated expectations for host-specific diagnostic outputs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d384f172b8 |
fix: remove individual shipping publishing (#1159)
## ℹ️ Description - Link to the related issue(s): Issue #1157 - Kleinanzeigen no longer offers individual/custom shipping. This updates publishing, validation, docs, schemas, translations, and tests so existing `shipping_costs` configs are handled gracefully instead of failing against removed DOM controls. ## 📋 Changes Summary - Keep `shipping_costs` for legacy configs/downloaded ads, but mark it deprecated in schema/docs and ignore it during publishing. - Remove publishing interaction with removed individual-shipping DOM controls. - Require predefined non-empty `shipping_options` for `sell_directly`. - Update docs, generated schemas/config artifacts, German translations, and unit tests. - Verified live DOM for `sell_directly: true` + `shipping_type: SHIPPING` + predefined `shipping_options` via local ignored script; no ad submission performed. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated shipping guides to deprecate custom individual shipping costs and make publishing depend on per-ad predefined `shipping_options` (DHL/Hermes; selectable options must come from a single size group). * Added migration guidance replacing `shipping_costs` with the correct `shipping_options`. * Clarified “Sell directly” requires `shipping_type: SHIPPING`, non-empty `shipping_options`, and `FIXED`/`NEGOTIABLE` pricing. * **Bug Fixes** * Publishing is blocked when `shipping_costs` is provided without `shipping_options`. * Removed unsupported individual-shipping handling and tightened “Sell directly” eligibility rules. * **Tests** * Expanded unit coverage for deprecation behavior, content handling, and direct-buy validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5ab4015251 |
refactor: simplify browser diagnostics (#1158)
## ℹ️ Description - Link to the related issue(s): Issue # - Refactor browser diagnostics to reduce the complexity of the diagnostics orchestration while preserving the generated diagnostics report and browser workflow behavior. ## 📋 Changes Summary - Extract factual browser diagnostic checks into focused helpers for binary detection, remote debugging port parsing, remote API probing, target browser name detection, and process discovery. - Keep translated diagnostics logging as direct literal log calls in `diagnose_browser_issues`. - Add regression coverage for remote debugging host handling, invalid ports, first-port precedence, and port `0` pass-through behavior. - No dependencies, configuration changes, or additional requirements introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] ♻️ Refactor (no user-facing behavior change) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved browser diagnostics by breaking down remote debugging checks into clearer steps, enhancing resilience when probing the browser and inspecting running processes, and refining success vs failure logging. * **Tests** * Expanded unit coverage to ensure remote debugging probing always targets `http://127.0.0.1:<port>`, validates `--remote-debugging-port` parsing (including invalid and multi-argument cases), and skips remote debugging when the port is `0` while continuing Chrome version diagnostics. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0b4b9eb397 |
refactor: split browser session setup (#1156)
## ℹ️ Description - Link to the related issue(s): N/A - Split browser session setup into smaller, behavior-preserving helpers so browser startup orchestration is easier to review and maintain. ## 📋 Changes Summary - Extract remote debugging connection handling from browser session creation. - Extract launch argument, user-data-dir, Nodriver config, profile preparation, and extension setup helpers. - Add matching German translation entries for log messages moved into helper functions. - Leave lint thresholds unchanged because the diagnostics follow-up remains separate. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Refactor** * Improved browser session setup by separating remote-debugging connections from fresh browser startup. * Hardened launch argument construction and user data directory resolution for more consistent configuration. * Improved browser startup failure cleanup to ensure resources are released reliably. * Kept troubleshooting output behavior, including better guidance for debugging scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c8fb72ae9e |
refactor: split command orchestration handlers (#1155)
## ℹ️ Description - Link to the related issue(s): Issue # - Refactors the CLI command orchestration boundary so command dispatch remains visible while command execution lives in focused handlers. ## 📋 Changes Summary - Split command execution paths in `KleinanzeigenBot.run()` into named handlers for configuration, verification, update checks, content hashing, and ad workflows. - Preserved literal command dispatch cases and command-specific behavior for update checks, download validation, browser login, and cleanup. - Moved German translation keys to the new handler caller names for existing runtime messages. - Added focused tests for update-check behavior, download validation ordering, workspace state usage, and translation key placement. - Lowered the configured branch and cyclomatic complexity limits now that the command orchestration boundary is simpler. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Strengthened code quality standards by implementing stricter complexity thresholds in the development configuration. * **Refactor** * Reorganized command handler architecture to improve internal code structure and maintainability. * **Tests** * Significantly expanded test coverage to validate command execution, argument handling, and translation data integrity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
75f34775e2 |
refactor: reduce return-count complexity (#1154)
## ℹ️ Description - Link to the related issue(s): Issue # - Reduces return-count complexity in the update checker while preserving existing update-check behavior. ## 📋 Changes Summary - Extracted GitHub release selection and commit-ish validation from `check_for_updates` into a private helper. - Moved German translation keys for logger calls that now originate from the helper. - Ratcheted Ruff/Pylint `max-returns` from 10 to 8. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * The update checker now correctly handles the latest update channel by excluding pre-release versions and recommending only stable releases. * **Chores** * Code quality configuration settings were adjusted. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
66cab91898 |
refactor: reduce return-count complexity (#1153)
## ℹ️ Description This refactor reduces return-count complexity for the next PLR0911 ratchet while preserving existing behavior. No related issue. ## 📋 Changes Summary - Extract German and English pluralization helpers while keeping translation and prefix handling in `pluralize()`. - Remove one early return from `check_for_updates()` by sharing the existing final state update/save path. - Ratchet Ruff `PLR0911` `max-returns` from 12 to 10. - Document the one-lower discovery result: `check_for_updates()` is the next limiter at 10 returns for `max-returns = 9`. - No dependencies, configuration requirements, documentation updates, or generated artifacts are introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. No documentation changes were needed. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized pluralization logic and simplified update-checking control flow for improved code maintainability. * **Tests** * Expanded test coverage for pluralization with additional German and English language variations. * **Chores** * Updated code quality configuration standards. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8b0e4f468d |
chore: Update Python dependencies (#1151)
✔ Update pytest 9.1.0 -> 9.1.1 successful ✔ Update msgpack 1.2.0 -> 1.2.1 successful ✔ Update ruff 0.15.17 -> 0.15.18 successful Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
e8752ce10e |
refactor: reduce price reduction complexity (#1152)
## ℹ️ Description - Link to the related issue(s): Issue # - Extracts the first complexity hotspot in the ratcheting sequence by separating the final auto price-reduction application flow from `apply_auto_price_reduction`. - This keeps behavior unchanged while allowing the Ruff `max-returns` transitional limit to move from 13 to 12. ## 📋 Changes Summary - Extracted `_apply_price_reduction_decision` for the final price-reduction mutation/logging phase. - Moved German translations for the relocated `LOG.info` calls to the new helper function key. - Lowered `tool.ruff.lint.pylint.max-returns` from 13 to 12. - No dependency or runtime configuration changes introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) Refactor-only change; none of the listed user-facing change types apply. ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated linting configuration thresholds for code quality standards. * **Refactor** * Improved internal code organization for better maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
801ed0e223 |
refactor: remove KleinanzeigenBot re-export from package root (#1150)
## ℹ️ Description - Link to the related issue(s): N/A - Removes the unsupported package-root `KleinanzeigenBot` re-export after tests were moved to their owning modules. - Updates remaining tests and `conftest.py` to import `KleinanzeigenBot` from `kleinanzeigen_bot.app` directly. - Re-enables Ruff's mccabe complexity checks and tightens high Pylint complexity thresholds left over from the old package-root monolith. ## 📋 Changes Summary - Removed `KleinanzeigenBot` from `src/kleinanzeigen_bot/__init__.py`. - Updated all remaining test imports to use `from kleinanzeigen_bot.app import KleinanzeigenBot`. - Enabled `C90`/mccabe complexity linting with an explicit `max-complexity`. - Lowered the broad Pylint limits for branches, locals, returns, statements, and public methods. - Kept the generated/static pydantic error-code mapping explicitly exempted from complexity checks. - No runtime behavior, CLI, config, translations, or ad YAML changes. - No new dependencies. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [x] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized internal module import structure for consistency across the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3c17f3c8dd |
refactor: move cross-drive fallback test (#1149)
## ℹ️ Description - Link to the related issue(s): Issue # - Move the Windows cross-drive fallback coverage from the package-init test module into the publishing workflow test suite. - This is a behavior-neutral test organization cleanup. ## 📋 Changes Summary - Moved the cross-drive auto-price-reduction path fallback test into `TestAutoPriceReductionDispatch`. - Deleted the now-empty `tests/unit/test_init.py` and its unused local helpers. - No runtime code, CLI behavior, config, translations, or ad YAML changed. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Reorganized test structure for Windows cross-drive path handling validation to improve maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
48e88fccd3 |
refactor: create app test file and move shell tests (#1148)
## ℹ️ Description - Link to the related issue(s): Issue # - Move app-shell unit tests into a dedicated test module matching `src/kleinanzeigen_bot/app.py`. ## 📋 Changes Summary - Added `tests/unit/test_app.py` for the app-shell test classes and shared fixture. - Kept the cross-drive path fallback coverage in `tests/unit/test_init.py`. - Updated the moved test module to import `KleinanzeigenBot` from `kleinanzeigen_bot.app`. - No runtime, CLI, config, translation, or ad YAML changes. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - Test organization refactor only. ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive unit tests covering command-line subcommands (including defaulting/fallback behavior for ad selector options) and unknown-command handling. * Added assertions for expected initialization behavior and invalid selector validation (including SystemExit code 2). * Refined the unit test modules to simplify imports and improve maintainability, while retaining key cross-drive publish fallback verification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d0d8e5461b |
refactor: move shipping form tests (#1147)
## ℹ️ Description - Link to the related issue(s): Issue # - Move the shipping option mapping test to the publishing form test module, where the browser-level shipping form behavior is owned. ## 📋 Changes Summary - Moved `test_shipping_options_mapping` from `tests/unit/test_init.py` to `tests/unit/test_publishing_form.py`. - Kept the existing assertions and patch targets intact. - Renamed the remaining `test_init.py` class to describe its cross-drive path fallback coverage. - No runtime behavior, CLI, config, translation, or ad YAML changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Reorganized test coverage for publishing and shipping functionality * Added tests for Windows cross-drive path fallback behavior * Added tests for shipping options mapping verification <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
824ff70e43 |
refactor: move publishing result tests (#1146)
## ℹ️ Description - Link to the related issue(s): N/A - Moves a focused set of publish-ad orchestration/result tests out of the package initialization test module and into the publishing workflow test module. ## 📋 Changes Summary - Move pre-submit timeout retry coverage into `tests/unit/test_publishing_workflow.py`. - Move WANTED shipping delegation coverage into the publishing workflow tests. - Move auto price reduction dispatch coverage into the publishing workflow tests. - Remove now-unused local fixture/imports from `tests/unit/test_init.py`. - No runtime, CLI, config, translation, or ad YAML changes. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] Refactor / test organization only ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Adjusted test coverage for internal functionality validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
01e764a477 |
refactor: move publish uncertainty tests (#1145)
## ℹ️ Description - Link to the related issue(s): Issue # - Moves publish-ad post-submit uncertainty tests into the publishing workflow test module so `test_init.py` keeps shrinking toward initializer-focused coverage. ## 📋 Changes Summary - Moved the post-submit uncertainty `publish_ad()` test slice into `tests/unit/test_publishing_workflow.py`. - Kept the pre-submit retryability test and unrelated initializer/CLI/login/shipping/ad-management tests in `tests/unit/test_init.py`. - Adjusted test imports only; no runtime behavior, configuration, translation, or YAML changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Reorganized test coverage for publishing workflows, expanding validation of post-submit error handling and confirmation fallback mechanisms to ensure robust publication behavior under various scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f54521b8e6 |
refactor: move publishing diagnostics tests (#1144)
## ℹ️ Description - Link to the related issue(s): N/A - Move the publish failure diagnostics tests out of the initializer-focused unit test module and into the publishing workflow unit test module. - This is a behavior-neutral test organization change. ## 📋 Changes Summary - Moved `TestKleinanzeigenBotDiagnostics` from `tests/unit/test_init.py` to `tests/unit/test_publishing_workflow.py`. - Kept existing assertions and publishing workflow patch targets unchanged. - Removed stale imports from `tests/unit/test_init.py`. - No runtime, CLI, config, translation, or ad YAML changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Enhanced test coverage for diagnostics capture during publishing failures, including verification of log file handling and behavior when diagnostics are disabled. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2332682d07 |
refactor: move publishing orchestration tests (#1143)
## ℹ️ Description - Link to the related issue(s): Issue #977 - Move another focused set of publishing/update orchestration tests out of `tests/unit/test_init.py` and into `tests/unit/test_publishing_workflow.py`. - This is a behavior-neutral test organization change; no runtime, CLI, config, translation, or ad YAML behavior changes are intended. ## 📋 Changes Summary - Moved display counter progression coverage into the publishing workflow test module. - Moved publish-ads orchestration coverage into a dedicated publishing workflow test class. - Cleaned up imports left behind in `tests/unit/test_init.py`. - Dependencies/configuration/additional requirements: none. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) Test-only refactor; none of the listed runtime change categories apply. ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. Not applicable; test-only relocation. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Improved the ad publishing workflow test coverage by reorganizing publish/cleanup, retry behavior, and “no-retry” scenarios. * Added new async testing utilities (including a reusable mocked page) to better simulate browser interactions. * Expanded regression coverage for processing/counter progression across publishing and updating, including paused ads and “not found” cases. * Removed several redundant or replaced counter/retry/skip tests from the prior initialization test module. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
29aed68706 |
refactor: move publishing workflow tests (#1142)
## ℹ️ Description - Link to the related issue(s): Follow-up to #1141 - Move a publishing/update orchestration test slice into the publishing workflow test module. - Share duplicated test fixtures/helpers that are now used by the relocated publishing workflow tests and existing related tests. - This remains behavior-neutral test organization only. ## 📋 Changes Summary - Added `tests/unit/test_publishing_workflow.py` for publishing workflow orchestration tests. - Moved `TestKleinanzeigenBotUpdateAdsResilience` out of `tests/unit/test_init.py`. - Updated the relocated tests to import `KleinanzeigenBot` directly from `kleinanzeigen_bot.app`. - Moved the duplicated `base_ad_config` fixture into `tests/conftest.py`. - Extracted shared `build_update_ad` and `build_published_ads` test helpers into `tests/conftest.py`. - Removed duplicate fixture/helper definitions from affected unit test files. - No runtime behavior, CLI output, config parsing, translations, or ad YAML handling changes. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] Maintenance/refactor (tests only, no runtime behavior change) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive tests for ad publishing resilience and orchestration, covering retry mechanisms, error handling, timeout scenarios, and failure propagation across different ad states * Reorganized and consolidated test utilities, shared fixtures, and builder helpers across test modules <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ee581e383f |
refactor: clean up source hygiene (#1141)
## ℹ️ Description - Link to the related issue(s): Issue # - Clean up minor post-extraction source hygiene without changing runtime behavior. ## 📋 Changes Summary - Import `KleinanzeigenBot` from its concrete `app` module in the CLI. - Update stale source comments/docstrings that referenced the previous package structure. - No dependencies, configuration changes, CLI output changes, translation changes, or ad YAML handling changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Refactored internal code organization by adjusting module imports and updating code documentation references to enhance maintainability and clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f5f3399a66 |
refactor: move app shell out of package init (#1140)
## ℹ️ Description Move the `KleinanzeigenBot` application class out of `__init__.py` into a dedicated `app.py` module. This continues the maintainability-focused refactoring of the package initializer that was started in prior PRs (login flow extraction, publishing workflow extraction, etc.). - Link to the related issue(s): N/A ## 📋 Changes Summary - **New `src/kleinanzeigen_bot/app.py`** (525 lines): contains the full `KleinanzeigenBot` class with all imports, constructor, `run()` command dispatch, `load_ads()`, and delegator methods - **`src/kleinanzeigen_bot/__init__.py`**: reduced from 545 lines to 27 lines — thin package initializer with `colorama` init, `LOG` setup, `KleinanzeigenBot` re-export from `app.py`, `main()` delegator, and `__name__` guard - **Translations**: split `__init__.py` section header in `translations.de.yaml`; class-owned translations moved to new `kleinanzeigen_bot/app.py:` section - **Tests**: updated patch targets from package-root paths to concrete module paths (`kleinanzeigen_bot.UpdateChecker` → `kleinanzeigen_bot.update_checker.UpdateChecker`) ### ⚙️ Type of Change - [ ] 🐞 Bug fix - [ ] ✨ New feature - [ ] 💥 Breaking change - [x] 🔧 Refactoring (no user-facing behavior changes) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Centralized runtime command handling in a new application entrypoint class while keeping the same CLI-style command set. * Slimmed the package initializer to re-export the main bot class and delegate CLI execution through `main(args)`. * **Bug Fixes** * Improved Windows console compatibility during startup. * **Tests** * Updated unit tests and mocks to reflect the new location of command-handling logic and related wiring. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d3507c0ff5 |
chore: Update Python dependencies (#1138)
✔ Update certifi 2026.5.20 -> 2026.6.17 successful ✔ Update cyclonedx-python-lib 11.10.0 -> 11.11.0 successful Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
35bd393dc4 |
refactor: extract login/auth flow into login_flow.py (#1139)
## ℹ️ Description Extract all login, Auth0 form-fill, captcha, SMS/email verification, GDPR, login-state detection, and diagnostics-capture logic from `__init__.py` into a new `login_flow.py` module. ## 📋 Changes Summary - Create `login_flow.py` (~634 lines) with module-level async functions accepting explicit `web: WebScrapingMixin` + keyword arguments - Thin delegators in `__init__.py` bind `KleinanzeigenBot` instance attributes to module calls - Remove 12 dead delegator methods; tests call module functions directly - Move `LoginDetectionResult`/`LoginDetectionReason` types to `login_flow` - Move `TestKleinanzeigenBotAuthentication` to `tests/unit/test_login_flow.py`, update patch targets - Move login translations to `login_flow.py` section in `translations.de.yaml` - Fix diagnostics guard reset per login attempt - Remove `is_logged_in_web()`; pass username explicitly - Make cross-module functions public: `login_flow` internal helpers and `WebScrapingMixin` helpers (`dismiss_consent_banner`, `effective_timeout`, `extract_visible_text`) ### ⚙️ Type of Change - [x] ✨ New feature (adds new functionality without breaking existing usage) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Reworked the authentication/login process to use a dedicated login flow, improving handling of multi-step sign-in and related verification prompts. * Standardized login-status detection and diagnostics behavior when login state can’t be determined. * Updated text-extraction and timeout behavior for DOM-based fallbacks, and aligned consent-banner dismissal to the public API. * **Tests** * Added extensive unit tests for the login flow and login-state detection. * Updated existing tests to reflect the refactored helpers and consent-banner method naming. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ecd3ea35cf |
refactor: extract publishing workflow (#1137)
## ℹ️ Description - Link to the related issue(s): N/A - Extracts publish/update orchestration from the monolithic bot class into `publishing_workflow.py` as Step 21 of the monolith breakdown. ## 📋 Changes Summary - Added `src/kleinanzeigen_bot/publishing_workflow.py` for publish/update orchestration, retry/uncertainty handling, result checks, and delete-before/after-publish wiring. - Kept `KleinanzeigenBot` publish/update methods as narrow delegation seams with explicit dependencies. - Moved WANTED ad type selection into `publishing_form.fill_ad_form()` so form details stay in the form module. - Updated German translations and unit tests to patch concrete workflow module paths. - No dependency or configuration changes. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] Refactor (no user-facing behavior change) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved form rendering for WANTED ad type by ensuring the ad type is pre-selected before populating other form fields. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
eae9dc9fc1 |
refactor: extract publishing form orchestrator (#1136)
## ℹ️ Description Move the last form-filling remnant out of `__init__.py` into `publishing_form.py`, where all individual form section functions already live. - `_fill_ad_form()` only delegated to the already-extracted section functions (`set_category`, `set_special_attributes`, `set_shipping_form`, `set_pricing_fields`, `set_contact_fields`, `fill_image_section`). - Replaced with a public module-level `publishing_form.fill_ad_form()` that accepts explicit `web`, `root_url`, `ad_defaults`, `ad_file`, `ad_cfg`, and `mode` parameters. - `publish_ad()` now calls `_publishing_form.fill_ad_form(self, ...)` instead of `self._fill_ad_form(...)`. ## 📋 Changes Summary - Extracted `fill_ad_form()` into `publishing_form.py` as a public module-level async function - Removed `_fill_ad_form()` method from `KleinanzeigenBot` class - Updated call site in `publish_ad()` to pass explicit parameters - Updated test patch target in `test_publishing_persistence.py` and docstring in `test_init.py` ### ⚙️ Type of Change - [ ] 🐞 Bug fix - [ ] ✨ New feature - [ ] 💥 Breaking change ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized ad form-filling logic for improved maintainability and code structure. * **Tests** * Updated unit tests to reflect internal code reorganization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
154c37b26e |
refactor: extract special-attributes/condition form section (#1135)
## ℹ️ Description Extracts special-attribute and condition form logic from `__init__.py` into `publishing_form.py` to continue module decomposition. ## 📋 Changes Summary - **`publishing_form.py`**: Added `set_special_attributes`, `_set_condition`, and helpers (`_pick_special_attribute_candidate`, `_special_attribute_candidate_priority`, `_describe_special_attribute_candidate`) adapted as module-level functions taking `web: WebScrapingMixin` - **`__init__.py`**: Removed the moved functions, cleaned up stale imports (`re`, `_ad_form_helpers`, `_select_button_combobox`, `ensure`, `Element`), updated `_fill_ad_form` to delegate via `_publishing_form.set_special_attributes()` - **`translations.de.yaml`**: Moved `_set_condition` and `set_special_attributes` sections from `__init__.py:` → `publishing_form.py:` block - **`test_init.py`**: Moved special-attribute and condition tests to `test_publishing_form.py`, updated orchestration patch targets - **`test_publishing_form.py`**: Added `TestSpecialAttributes`, `TestConditionSelector`, and `TestConditionFallbackToGenericHandler` classes with adapted imports and patches ### ⚙️ Type of Change - [x] Refactor — no behavior changes, internal module reorganization only ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. |
||
|
|
875b8b063a |
refactor: extract publishing shipping form section (#1134)
## ℹ️ Description - Extracts the publishing shipping form workflow from `KleinanzeigenBot` into `publishing_form.py`. - Keeps runtime behavior, selectors, waits, messages, and browser interactions unchanged while moving translation ownership. ## 📋 Changes Summary - Move WANTED shipping handling, shipping radio/dialog handling, shipping option toggling, and the private React-fiber button-combobox helper into `publishing_form.py`. - Update `__init__.py` to delegate shipping form work and keep only orchestration/seam responsibilities. - Move direct shipping behavior tests to `tests/unit/test_publishing_form.py`; keep a shipping orchestration seam test in `tests/unit/test_init.py`. - Move German translation entries for shipping messages to the `publishing_form.py` translation section. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary of changes * **Refactor** * Improved publishing ad shipping form handling by routing wanted vs non-wanted ads to the correct UI flow. * Enhanced Versand (shipping) combobox selection for wanted ads to ensure the right option is chosen. * Strengthened the shipping dialog flow for pickup vs shipping-with-options, including more reliable shipping price confirmation and retry behavior. * **Tests** * Expanded unit tests covering shipping dialog interactions, carrier/option selection, wanted-shipping combobox behavior, and timeout/error scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e9ed698dce |
refactor: extract publishing pricing form section (#1133)
## ℹ️ Description - Link to the related issue(s): Issue # - Extracts the publishing pricing/direct-buy/description form section from the main bot class as the next monolith-breakdown step. ## 📋 Changes Summary - Added publishing_form.set_pricing_fields() for price type/amount, sell-directly/direct-buy radios, and description filling. - Replaced the inline _fill_ad_form() pricing block with the new publishing form section call. - Moved direct unit coverage for pricing/direct-buy/description behavior into test_publishing_form.py and kept orchestration seam tests in test_init.py. - Moved existing German translation ownership entries to the new function path without wording changes. - No dependencies, configuration changes, CLI changes, schema changes, or generated artifacts. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (pdm run test). - [x] I have formatted the code (pdm run format). - [x] I have verified that linting passes (pdm run lint). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Centralized pricing-related ad form filling (price type, price amount, ad description with affixes, and direct-buy/buy-now controls) into a shared publishing helper for more consistent behavior. * **Bug Fixes** * Improved handling of pricing/buy-now selection failures by surfacing clearer, localized timeout errors. * **Tests** * Added dedicated coverage for pricing field interactions, including dropdown skipping when not applicable, correct amount input behavior, and description generation usage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
137a7691a7 |
refactor: extract publishing image form section (#1132)
## ℹ️ Description - Link to the related issue(s): N/A - Extracts the publishing image cleanup and upload section from the bot monolith into `publishing_form.py` as Step 16 of the monolith breakdown plan. ## 📋 Changes Summary - Move image cleanup/upload behavior into `fill_image_section()` and `upload_images()`. - Replace the monolith image block with a publishing form seam call. - Move direct image behavior tests from `test_init.py` to `test_publishing_form.py`. - Update German translation ownership paths without changing translated text. - No dependency, configuration, CLI, schema, or generated artifact changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] ♻️ Refactor (no intended behavior change) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Image upload handling has been reorganized and consolidated in the publishing module for improved code organization. The image processing workflow now includes enhanced timeout management and marker-based completion detection to ensure all images are reliably processed during ad publication. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9d146c2b96 |
refactor: extract publishing contact form section (#1131)
## ℹ️ Description - Link to the related issue(s): Issue # - Refactors the publishing form code by moving the contact/location form section out of the package initializer into the publishing form module. ## 📋 Changes Summary - Move contact field handling, contact location handling, and city combobox helpers into publishing_form.py. - Keep the publishing form orchestration delegating through an explicit web/contact boundary. - Update unit tests to patch and call the new publishing form functions. - Move German translation ownership paths for the relocated messages without changing translated text. - No dependencies, configuration changes, or additional requirements introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (pdm run test). - [x] I have formatted the code (pdm run format). - [x] I have verified that linting passes (pdm run lint). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Updated ad publishing to populate contact and location fields via dedicated public publishing-form helpers, with revised import wiring for ad model types. * Removed older internal city/contact handling logic and replaced it with clearer helper-driven flow. * **Bug Fixes** * Improved city/location hardening: safer city extraction, combobox-style selection with ambiguity checks, timeout-based fallbacks, and correct handling for read-only city inputs. * More resilient contact field population (zipcode/location, street, name, phone), with graceful handling when optional elements are missing. * **Tests** * Added/updated unit tests to cover city/contact hardening and category probe/picker selection behaviors, asserting helper calls rather than private methods. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f02816cb06 |
refactor: extract publishing category form section (#1130)
## ℹ️ Description - Link to the related issue(s): N/A - Extracts the publishing category form section from the monolithic bot class into a focused publishing form module while preserving category selection and suggestion fallback behavior. ## 📋 Changes Summary - Move category selection and category suggestion fallback into `src/kleinanzeigen_bot/publishing_form.py`. - Update publish form orchestration to call the extracted category function through a narrow web/root_url boundary. - Update unit tests and German translation ownership for the new module path. - No dependencies, configuration changes, or additional requirements introduced. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Restructured category selection logic for improved maintainability and code organization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
dd6a1955ef |
refactor: extract publishing form helpers (#1129)
## ℹ️ Description - Extract browser-independent publishing form helpers from the monolith into `ad_form_helpers.py`. - Prepares later publishing form extraction without changing browser behavior. ## 📋 Changes Summary - Move the Versand combobox selector constant to `ad_form_helpers.py`. - Move location matching logic to `ad_form_helpers.py`. - Update production call sites and helper ownership tests. - Keep form sections and browser-dependent logic in `__init__.py`. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved internal code organization by consolidating shared helpers for form-related utilities and location matching logic. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fda56b109c |
refactor: prepare web helpers for publishing form extraction (#1128)
## ℹ️ Description - Link to the related issue(s): Issue #930 - Moves a shared consent-banner browser helper onto the generic web scraping mixin so later publishing form refactors can use it without depending on the main bot class. ## 📋 Changes Summary - Move `_dismiss_consent_banner()` from `KleinanzeigenBot` to `WebScrapingMixin` without changing selector, timeout, click, or sleep behavior. - Move the helper's focused unit tests from `test_init.py` to `test_web_scraping_mixin.py`. - No dependencies, configuration changes, or additional requirements introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) None of the listed categories apply; this is an internal behavior-equivalent refactor. ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Moved consent-banner dismissal logic into a shared web-scraping helper, and updated the bot flow to proceed directly after SMS verification. * **Tests** * Removed unit tests that covered the old bot-level consent-banner handling. * Added new async unit tests to verify the shared helper clicks the consent accept button when present and does nothing when absent. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
816cf3ed9e |
refactor: rename publishing persistence module (#1127)
## ℹ️ Description - Link to the related issue(s): Issue # - Rename the persistence-only publishing module so the module name matches its current responsibility. ## 📋 Changes Summary - Rename `publishing_flow.py` to `publishing_persistence.py`. - Update production imports/calls and test patch paths. - Move persistence tests to `test_publishing_persistence.py` and keep submission tests under `test_publishing_submission.py`. - Update the German translation section header for the renamed module. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved the way published ad changes are saved after submitting or updating, ensuring related fields (such as image updates and pricing adjustments) are correctly retained. * **Bug Fixes** * Publishing now continues even if the follow-up save step fails, preventing unnecessary interruptions. * **Tests** * Updated existing tests to match the revised persistence behavior. * Added new unit tests covering persistence outcomes, logging, rollback behavior, and image/price update handling. * Simplified the publishing submission test suite setup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5c22795728 |
fix: handle shipping select for pro accounts (#1126)
## ℹ️ Description - Link to the related issue(s): Issue #1125 - Fixes PRO/commercial account publishing where the Versand field is rendered as a custom `button[role="combobox"]` dropdown by the PostListingForm Astro island, not as a native `versand_s` `<select>` and not as the private-account radio-button UI. - Uses the confirmed PRO DOM model from the issue comments/screenshots: category-prefixed IDs such as `kunst.versand` / `uhren.versand`, placeholder `Bitte wählen`, and options `Versand möglich` (`ja`) / `Nur Abholung` (`nein`). ## 📋 Changes Summary - Detect the custom Versand combobox before falling back to the private radio/dialog shipping flow. - Locate the combobox by the confirmed category-prefixed id shape and by the selected-option label relationship (`aria-labelledby$="versand-selected-option"`) so the lookup is not tied to one category prefix. - Select `Versand möglich` for `shipping_type: SHIPPING` and `Nur Abholung` for `shipping_type: PICKUP` by visible option text via `web_select_button_combobox()`. - Apply the same safer Versand combobox selector to the existing WANTED-ad shipping combobox path. - Keep the private/non-commercial radio-button and shipping-options-dialog path as the fallback when the custom combobox is absent. - Add regression coverage for the PRO combobox path and relax existing shipping-flow assertions so they check behavior instead of exact probe ordering/timeout plumbing. - Add the German translation for the combobox error message. ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved the WANTED shipping flow to detect and use native “Versand” dropdown controls when available, selecting the correct shipping option directly. * **Bug Fixes** * Added clearer errors for unsupported shipping types and standardized timeout behavior when native selection fails; continues to fall back to the existing radio/dialog approach when the control is missing. * **Tests** * Expanded unit tests to cover the native Versand combobox route, including selector coverage and updated probe/call-order expectations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
021b887d08 |
chore: Update Python dependencies (#1124)
✔ Update filelock 3.29.3 -> 3.29.4 successful ✔ Update pytest 9.0.3 -> 9.1.0 successful ✔ Update pyinstaller 6.20.0 -> 6.21.0 successful ✔ Update basedpyright 1.39.7 -> 1.39.8 successful Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
f94567a983 |
fix: use canonical title for owned ad downloads (#1123)
## ℹ️ Description - Link to the related issue(s): Issue #1119 - Fixes owned-ad downloads where the public/detail page title may include UI status decoration that makes the title exceed the semantic 65-character title limit. ## 📋 Changes Summary - Resolve download titles once via manage-ads metadata when available. - Reuse the resolved title for folder naming, file stems, and persisted ad config data. - Keep manual page title extraction as the fallback without stripping or truncation. - Add regression coverage for canonical metadata titles and fallback extraction. ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (pdm run test). - [x] I have formatted the code (pdm run format). - [x] I have verified that linting passes (pdm run lint). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Enhanced ad title resolution to prioritize cached published metadata when available, with fallback to page extraction for improved reliability. * Improved directory handling to consistently use the resolved ad title for naming and saved info templates. * **Bug Fixes** * Corrected title/metadata extraction flow to avoid redundant title reads and ensure creation dates are reliably sourced from the expected page elements. * **Tests** * Updated and added unit test coverage for title resolution, directory behaviors, and extraction call ordering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
439c36e851 |
fix: click Auth0 Weiter after captcha (#1120) (#1122)
## ℹ️ Description Fixes issue #1120 by handling the Auth0 captcha branch after email submit. When captcha appears, the bot now probes for a visible/clickable "Weiter" button and clicks it before waiting for the password page. The normal no-captcha login flow remains unchanged. - Link to the related issue(s): Issue #1120 - Describe the motivation and context for this change. ## 📋 Changes Summary - Added a captcha-only Auth0 identifier handler that waits for captcha completion, probes for "Weiter" with `web_probe`, and clicks it if present. - Kept the existing no-captcha login path unchanged. - Updated German translations for the new log messages. - Adjusted unit tests for the new login helper. ### ⚙️ Type of Change - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. No additional docs changes were needed beyond translations. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved login robustness to detect optional reCAPTCHA on the email/identifier step; users are notified when a captcha appears, can provide input, and the login resumes once advanced. * **Tests** * Updated unit tests to cover and control the captcha-handling behavior during the login flow, including the missing-password-step scenario. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |