Skip to content

Enhances metadata, notifications, and service management - #23

Merged
H2OKing89 merged 9 commits into
mainfrom
fect/mam_api
Jul 21, 2026
Merged

Enhances metadata, notifications, and service management#23
H2OKing89 merged 9 commits into
mainfrom
fect/mam_api

Conversation

@H2OKing89

@H2OKing89 H2OKing89 commented Jul 21, 2026

Copy link
Copy Markdown
Owner

This pull request introduces significant enhancements to metadata processing, notification content, and system management capabilities.

  • Richer MAM Metadata Integration: Integrates a comprehensive set of metadata from MyAnonaMouse (MAM) torrents, including detailed audio properties (codec, bitrate, channels, sampling rate), torrent health (seeders, leechers, completion count), uploader information, freeleech status, and more. This data is now leveraged to provide more informative notifications across Discord, Gotify, NTFY, and Pushover, and displayed prominently in the web approval interface.
  • Dedicated Service Management Script: Adds a new service.sh script to streamline systemd service operations, allowing users to easily start, stop, restart, check status, view logs, and manage the service without manual systemctl commands.
  • Improved Error Handling: Enhances robustness by refining the handling of qBittorrent API responses across different versions and ensuring that MyAnonaMouse API errors are gracefully logged, allowing the system to continue searching for metadata from alternative sources.
  • Extended Reply Token TTL: Increases the default reply token validity period from 1 hour to 48 hours, providing more flexibility for users to approve requests.
  • Dependency and CI Updates: Updates qbittorrent-api to a newer version and refines CI workflows for improved stability and maintenance.

Summary by CodeRabbit

  • New Features
    • Added a service.sh control script for managing audiobook-style services and viewing logs.
    • Approval page now shows expanded tech specs (audio/torrent health, tags, uploader, identifiers) and displays MAM upload notes when available.
    • Discord, Gotify, ntfy, and Pushover notifications now include additional audio/torrent details when present.
  • Improvements
    • Reply-token TTL increased to 48 hours (including example configurations).
    • Metadata enrichment now drives more displayed/notification fields.
    • qBittorrent “add torrent” success detection is more consistent across response types.
  • Bug Fixes
    • Improved MAM error handling so auth/lookup issues fall back instead of interrupting the workflow.
  • Chores
    • CI security audit setup hardened; dependency pinning and config examples updated.

H2OKing89 added 4 commits May 22, 2026 21:51
- Added audio summary, torrent health, access labels, added date, and identifiers (ASIN/ISBN) to Discord, Gotify, NTFY, and Pushover notifications.
- Improved the handling of metadata in the `get_notification_fields` function to include MAM enrichment details such as audio properties, torrent health, and uploader information.
- Updated the web UI to display additional metadata fields including audio summary, torrent health, uploader, access labels, and added date.
- Enhanced tests to cover new MAM enrichment fields and ensure proper formatting in notifications and web UI.
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds MAM enrichment normalization and propagation, expands notification and approval-page metadata, standardizes qBittorrent add-result handling, introduces a systemd service script, extends reply-token TTL defaults, updates dependencies, and revises related tests.

Changes

Runtime operations and defaults

Layer / File(s) Summary
Runtime operations and defaults
.github/workflows/ci.yml, config/..., docs/vendor/audible/..., requirements.txt, service.sh, src/db.py
CI security setup, dependency constraints, reply-token TTL defaults, and systemd service management are updated.

MAM normalization and coordinator flow

Layer / File(s) Summary
MAM normalization and coordinator flow
src/mam_api/*, src/metadata_coordinator.py, tests/test_mam_api.py, tests/test_metadata_coordinator.py, tests/test_metadata_extended.py, tests/conftest.py
MAM audio and uploader data is normalized into mam_enrichment; the coordinator propagates it and falls back to Audible after MAM errors or missing ASINs.

Enriched notification and approval rendering

Layer / File(s) Summary
Enriched notification and approval rendering
src/utils.py, src/notify/*, src/webui.py, templates/approval.html, tests/test_notify_formatting.py, tests/test_utils_extra.py, tests/test_webui_extended.py
Enriched audio, torrent, freeleech, identifier, uploader, and upload-note fields are derived and rendered across notifications and the approval page.

qBittorrent result classification

Layer / File(s) Summary
qBittorrent result classification
src/qbittorrent.py, tests/test_qbittorrent.py, tests/test_qbittorrent_coverage.py
Torrent-add success detection is centralized across supported response shapes and covered by metadata success, failure, and unrecognized-response tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Webhook
  participant MetadataCoordinator
  participant MAMApiAdapter
  participant Audnex
  participant Audible
  Webhook->>MetadataCoordinator: submit MAM URL
  MetadataCoordinator->>MAMApiAdapter: get_full_metadata(url)
  MAMApiAdapter-->>MetadataCoordinator: return asin and mam_enrichment
  MetadataCoordinator->>Audnex: request metadata using asin
  MetadataCoordinator->>Audible: fallback after missing MAM or Audnex metadata
Loading

Possibly related PRs

Suggested labels: enhancement, logging

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main changes to metadata, notifications, and service management.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fect/mam_api

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Jul 21, 2026

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f25a90598b

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread src/utils.py
Comment thread src/utils.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/metadata_coordinator.py (1)

74-94: 🧹 Nitpick | 🔵 Trivial

MAM auth failures now silently fall back instead of surfacing.

MamApiError (including auth errors that get_torrent_data deliberately re-raises) is caught and swallowed here, degrading gracefully to Audible fallback with only a log entry. An expired/invalid MAM_ID will now silently degrade metadata quality indefinitely instead of being surfaced to the operator.

Recommend adding a metric/alert on the coordinator.step1.mam_api_error log event (or a periodic health check) so a persistent auth misconfiguration doesn't go unnoticed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/metadata_coordinator.py` around lines 74 - 94, Update the MamApiError
handling in the coordinator flow around mam_adapter.get_full_metadata so
authentication-related failures are surfaced to operators instead of only being
logged and swallowed. Add a metric or alert tied to the
coordinator.step1.mam_api_error event, preserving graceful fallback while
enabling detection of persistent MAM_ID/auth misconfiguration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mam_api/models.py`:
- Around line 118-120: Add a concise comment immediately above the BitRate and
Bitrate fields explaining that they intentionally map to distinct raw
MAM/MediaInfo key casings and are both used by bitrate_value()'s fallback chain.
Do not rename, remove, or otherwise alter either field.

In `@src/qbittorrent.py`:
- Around line 220-276: Update add_torrent_by_url to route every non-string
torrents_add result through _torrent_add_result_succeeded(result) instead of
treating it as successful, while preserving the existing conflict and error
handling. Add coverage for metadata with success_count=0, empty
added_torrent_ids, and failure_count>0, asserting the URL add returns False.

In `@src/utils.py`:
- Around line 183-216: Update `_format_sampling_rate` so its numeric `<1000`
branch appends the appropriate `" Hz"` fallback unit, matching
`_format_bitrate`’s labeled output while preserving existing kHz formatting and
nonnumeric handling; add a direct test covering a sub-1000 sampling-rate value.

In `@src/webui.py`:
- Around line 102-109: Update the template context construction around the
context dictionary so the explicit "token": token assignment occurs after the
payload, metadata, and fields spreads. Preserve the existing narrator
assignment, and add coverage for payload or metadata containing a token to
verify the rendered approval link still uses the URL-path token.

---

Outside diff comments:
In `@src/metadata_coordinator.py`:
- Around line 74-94: Update the MamApiError handling in the coordinator flow
around mam_adapter.get_full_metadata so authentication-related failures are
surfaced to operators instead of only being logged and swallowed. Add a metric
or alert tied to the coordinator.step1.mam_api_error event, preserving graceful
fallback while enabling detection of persistent MAM_ID/auth misconfiguration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3ae5c1c3-2005-46fc-8534-4cf923734412

📥 Commits

Reviewing files that changed from the base of the PR and between 3dd590a and f25a905.

📒 Files selected for processing (25)
  • .github/workflows/ci.yml
  • config/config.yaml.example
  • docs/vendor/audible/config/config.yaml.example
  • requirements.txt
  • service.sh
  • src/db.py
  • src/mam_api/adapter.py
  • src/mam_api/models.py
  • src/metadata_coordinator.py
  • src/notify/discord.py
  • src/notify/gotify.py
  • src/notify/ntfy.py
  • src/notify/pushover.py
  • src/qbittorrent.py
  • src/utils.py
  • src/webui.py
  • templates/approval.html
  • tests/conftest.py
  • tests/test_mam_api.py
  • tests/test_metadata_coordinator.py
  • tests/test_metadata_extended.py
  • tests/test_notify_formatting.py
  • tests/test_qbittorrent.py
  • tests/test_utils_extra.py
  • tests/test_webui_extended.py

Comment thread src/mam_api/models.py
Comment thread src/qbittorrent.py
Comment thread src/utils.py Outdated
Comment thread src/webui.py
coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/test_metadata_coordinator.py (2)

273-287: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the MAM_ID not configured authentication branch.

  • Issue: The new test exercises MAM_AUTH_ERROR_MESSAGE but not the alternate marker checked on src/metadata_coordinator.py Line 88.
  • Impact: Missing MAM configuration could regress to non-alert logging without failing the suite.
  • Fix: Add a parameterized case or test using MamApiError("MAM_ID not configured") and assert alert=True plus the auth-alert log.
  • Test: Verify the Audible fallback still occurs.

As per path instructions, **/tests/** requires pytest best practices, proper mocking of external services, and adequate coverage of edge cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_metadata_coordinator.py` around lines 273 - 287, Add coverage for
the alternate MAM authentication marker by parameterizing or adding a test
alongside test_webhook_mam_auth_error_falls_back_to_audible using
MamApiError("MAM_ID not configured"). Assert the Audible fallback succeeds and
verify both the exception log with alert=True and the auth-alert log containing
the marker.

Source: Path instructions


188-198: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exercise MAM enrichment propagation in both webhook outcomes.

  • Issue: The MAM mocks return only asin or None; neither path asserts that mam_enrichment is copied to the Audnex or Audible result.
  • Impact: A regression in src/metadata_coordinator.py Lines 120 or 146 could silently remove metadata used by notifications and the approval page.
  • Fix: Return a small mam_enrichment mapping and assert exact propagation in both tests.
  • Test: Cover both the Audnex-success and Audible-fallback paths.

As per path instructions, **/tests/** requires pytest best practices, proper mocking of external services, and adequate coverage of edge cases.

Also applies to: 206-214

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_metadata_coordinator.py` around lines 188 - 198, Update the
webhook metadata tests around get_metadata_from_webhook to have the MAM mock
return a small mam_enrichment mapping alongside the existing ASIN or None
values, then assert exact mam_enrichment propagation in both the Audnex-success
and Audible-fallback cases. Preserve the existing source, ASIN, and mock-call
assertions while covering both outcomes.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/qbittorrent.py`:
- Line 522: Update the string-response branch in add_torrent_by_url to route the
complete qBittorrent response through _torrent_add_result_succeeded, or
explicitly return False for unrecognized strings such as "Unexpected.". Add a
pytest case using the existing mock to verify add_torrent_by_url returns False
for that response.

---

Outside diff comments:
In `@tests/test_metadata_coordinator.py`:
- Around line 273-287: Add coverage for the alternate MAM authentication marker
by parameterizing or adding a test alongside
test_webhook_mam_auth_error_falls_back_to_audible using MamApiError("MAM_ID not
configured"). Assert the Audible fallback succeeds and verify both the exception
log with alert=True and the auth-alert log containing the marker.
- Around line 188-198: Update the webhook metadata tests around
get_metadata_from_webhook to have the MAM mock return a small mam_enrichment
mapping alongside the existing ASIN or None values, then assert exact
mam_enrichment propagation in both the Audnex-success and Audible-fallback
cases. Preserve the existing source, ASIN, and mock-call assertions while
covering both outcomes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6d7ed7bd-6349-4a04-93c8-158875f3af71

📥 Commits

Reviewing files that changed from the base of the PR and between f25a905 and 8bd7c97.

📒 Files selected for processing (9)
  • src/mam_api/models.py
  • src/metadata_coordinator.py
  • src/qbittorrent.py
  • src/utils.py
  • src/webui.py
  • tests/test_metadata_coordinator.py
  • tests/test_qbittorrent.py
  • tests/test_utils_extra.py
  • tests/test_webui_extended.py

Comment thread src/qbittorrent.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
tests/test_metadata_coordinator.py (2)

297-309: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert that non-auth errors do not emit an auth alert.

  • Issue: The test checks alert=False but never asserts that coordinator.step1.mam_auth_alert is absent.
  • Impact: A regression could emit an auth-specific alert for every MAM API error while this test still passes.
  • Fix/Test: Add a negative assertion for the auth-alert log event.

As per path instructions, tests should cover the relevant edge-case distinction between authenticated and non-authenticated failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_metadata_coordinator.py` around lines 297 - 309, Extend
test_webhook_mam_api_error_falls_back_to_audible to assert mock_log does not
emit the coordinator.step1.mam_auth_alert event, while preserving the existing
assertion that the generic mam_api_error event uses alert=False.

Source: Path instructions


245-249: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Prove that the new MAM mock is exercised.

  • Issue: These fallback/error tests configure get_full_metadata but do not assert it was called.
  • Impact: They can pass if the coordinator skips MAM or regresses to another method; injected MAM failures would never be exercised.
  • Fix/Test: Add assert_called_once_with(sample_webhook_payload["url"]) to the affected MAM-path tests, and assert Audnex was called where its failure path is under test.
Suggested assertion
 result = await coordinator.get_metadata_from_webhook(sample_webhook_payload)
+coordinator.mam_adapter.get_full_metadata.assert_called_once_with(
+    sample_webhook_payload["url"]
+)

As per path instructions, tests must verify proper mocking of external services and adequate edge-case coverage.

Also applies to: 259-260, 269-270, 314-316, 326-328, 338-340, 350-351, 359-360, 368-369, 400-401, 411-412, 422-423, 980-982

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_metadata_coordinator.py` around lines 245 - 249, Add interaction
assertions to each affected MAM-path test around the configured
coordinator.mam_adapter.get_full_metadata mock, verifying it was called exactly
once with sample_webhook_payload["url"]. In tests covering Audnex failure, also
assert coordinator.audnex.get_book_by_asin was called with the expected ASIN,
while preserving the existing fallback assertions.

Source: Path instructions

src/qbittorrent.py (1)

505-518: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Log count-based metadata successes consistently.

  • Issue: URL adds log success only when result.hash exists. Metadata responses recognized through counts, IDs, or pending state return True without emitting the success event.
  • Impact: Successful URL additions can be missing from operational telemetry, unlike file and data additions.
  • Fix: Compute success once, then emit the generic success log for every successful result; include hash only when available.
  • Test: Add a metadata-success fixture without hash and assert the success log is emitted.

As per path instructions, maintain logging consistency for Python API-call paths.

Suggested adjustment
             else:
+                success = _torrent_add_result_succeeded(result)
                 torrent_hash = getattr(result, "hash", None)
-                if torrent_hash:
-                    log.info("qbittorrent.torrent.add.success", hash=torrent_hash)
-                return _torrent_add_result_succeeded(result)
+                if success:
+                    if torrent_hash:
+                        log.info("qbittorrent.torrent.add.success", hash=torrent_hash)
+                    else:
+                        log.info("qbittorrent.torrent.add.success")
+                return success
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/qbittorrent.py` around lines 505 - 518, Update the metadata branch of the
torrent-add handling around _torrent_add_result_succeeded to compute success
once, then emit qbittorrent.torrent.add.success for every successful result,
including metadata recognized by counts, IDs, or pending state. Include the hash
field only when available, preserve rejection handling for string responses, and
add coverage for a successful metadata result without hash.

Source: Path instructions

tests/test_qbittorrent_coverage.py (1)

241-258: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the remaining qBittorrent metadata branches

  • Issue: this test only hits the unrecognised-object fallback.
  • Impact: add_torrent_by_url() can still drift on success_count, added_torrent_ids, or pending_count/failure_count responses without a direct guard here.
  • Fix: add a few parametrized cases for positive success count, non-empty IDs, pending with zero failures, and failure/empty boundaries; use realistic metadata objects instead of a generic mock where possible.
  • Test: keep the current hash and fallback assertions, and add the remaining shapes in this file or the nearest qBittorrent coverage test.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_qbittorrent_coverage.py` around lines 241 - 258, Expand
test_unrecognised_metadata_response_returns_false into parametrized coverage for
add_torrent_by_url metadata handling, retaining the existing hash and
unrecognised-object fallback assertions. Add realistic metadata cases for
positive success_count, non-empty added_torrent_ids, pending_count with zero
failure_count, and failure/empty boundary values, asserting each expected result
directly.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/qbittorrent.py`:
- Around line 505-518: Update the metadata branch of the torrent-add handling
around _torrent_add_result_succeeded to compute success once, then emit
qbittorrent.torrent.add.success for every successful result, including metadata
recognized by counts, IDs, or pending state. Include the hash field only when
available, preserve rejection handling for string responses, and add coverage
for a successful metadata result without hash.

In `@tests/test_metadata_coordinator.py`:
- Around line 297-309: Extend test_webhook_mam_api_error_falls_back_to_audible
to assert mock_log does not emit the coordinator.step1.mam_auth_alert event,
while preserving the existing assertion that the generic mam_api_error event
uses alert=False.
- Around line 245-249: Add interaction assertions to each affected MAM-path test
around the configured coordinator.mam_adapter.get_full_metadata mock, verifying
it was called exactly once with sample_webhook_payload["url"]. In tests covering
Audnex failure, also assert coordinator.audnex.get_book_by_asin was called with
the expected ASIN, while preserving the existing fallback assertions.

In `@tests/test_qbittorrent_coverage.py`:
- Around line 241-258: Expand test_unrecognised_metadata_response_returns_false
into parametrized coverage for add_torrent_by_url metadata handling, retaining
the existing hash and unrecognised-object fallback assertions. Add realistic
metadata cases for positive success_count, non-empty added_torrent_ids,
pending_count with zero failure_count, and failure/empty boundary values,
asserting each expected result directly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2d34aeb9-6c03-4c14-9af7-b19a5ebdb634

📥 Commits

Reviewing files that changed from the base of the PR and between eb15ac5 and 54843d4.

📒 Files selected for processing (3)
  • src/qbittorrent.py
  • tests/test_metadata_coordinator.py
  • tests/test_qbittorrent_coverage.py

@H2OKing89
H2OKing89 merged commit 59e7914 into main Jul 21, 2026
12 checks passed
@H2OKing89
H2OKing89 deleted the fect/mam_api branch July 21, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request logging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant