mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
feat: Implement Folder ID support in Audiobookshelf integration and update related documentation
This commit is contained in:
+46
-2
@@ -3088,6 +3088,42 @@ def test_audiobookshelf() -> ResponseReturnValue:
|
||||
if not matched:
|
||||
return jsonify({"error": f"Library '{library_id}' not found on Audiobookshelf."}), 400
|
||||
|
||||
folder_id = str(settings.get("folder_id") or "").strip()
|
||||
if not folder_id:
|
||||
return jsonify({"error": "Provide a folder ID before testing."}), 400
|
||||
|
||||
folder_name = folder_id
|
||||
try:
|
||||
with client._open_client() as http_client: # pylint: disable=protected-access
|
||||
library_resp = http_client.get(client._api_path(f"libraries/{library_id}"))
|
||||
library_resp.raise_for_status()
|
||||
library_payload = library_resp.json()
|
||||
except Exception as exc: # pragma: no cover - network guard
|
||||
status_code = getattr(getattr(exc, "response", None), "status_code", None)
|
||||
if status_code:
|
||||
message = f"Library lookup failed with status {status_code}."
|
||||
else:
|
||||
message = f"Library lookup failed: {exc}"
|
||||
return jsonify({"error": message}), 502
|
||||
|
||||
folders: List[Mapping[str, Any]] = []
|
||||
if isinstance(library_payload, Mapping):
|
||||
candidates = library_payload.get("libraryFolders") or library_payload.get("folders")
|
||||
if isinstance(candidates, list):
|
||||
folders = [entry for entry in candidates if isinstance(entry, Mapping)]
|
||||
|
||||
folder_matched = False
|
||||
for folder in folders:
|
||||
entry_id = str(folder.get("id") or "").strip()
|
||||
if entry_id != folder_id:
|
||||
continue
|
||||
folder_matched = True
|
||||
folder_name = folder.get("name") or folder.get("label") or folder_id
|
||||
break
|
||||
|
||||
if not folder_matched:
|
||||
return jsonify({"error": f"Folder '{folder_id}' not found in library '{library_name}'."}), 400
|
||||
|
||||
collection_id = str(settings.get("collection_id") or "").strip()
|
||||
if collection_id:
|
||||
try:
|
||||
@@ -3103,10 +3139,11 @@ def test_audiobookshelf() -> ResponseReturnValue:
|
||||
return jsonify({"error": message}), 502
|
||||
|
||||
return jsonify({
|
||||
"message": f"Connected to Audiobookshelf library '{library_name}'.",
|
||||
"message": f"Connected to Audiobookshelf library '{library_name}' (folder '{folder_name}').",
|
||||
"library_id": library_id,
|
||||
"collection_id": collection_id or None,
|
||||
"folder_id": settings.get("folder_id") or None,
|
||||
"folder_id": folder_id,
|
||||
"folder_name": folder_name,
|
||||
})
|
||||
|
||||
|
||||
@@ -4955,6 +4992,13 @@ def send_job_to_audiobookshelf(job_id: str) -> ResponseReturnValue:
|
||||
)
|
||||
service._persist_state()
|
||||
return _panel_response()
|
||||
if not config.folder_id:
|
||||
job.add_log(
|
||||
"Audiobookshelf upload skipped: configure a folder ID in the Audiobookshelf settings.",
|
||||
level="warning",
|
||||
)
|
||||
service._persist_state()
|
||||
return _panel_response()
|
||||
|
||||
audio_path = _locate_job_audio(job)
|
||||
if not audio_path or not audio_path.exists():
|
||||
|
||||
@@ -932,12 +932,19 @@ class ConversionService:
|
||||
base_url = str(integration_cfg.get("base_url") or "").strip()
|
||||
api_token = str(integration_cfg.get("api_token") or "").strip()
|
||||
library_id = str(integration_cfg.get("library_id") or "").strip()
|
||||
folder_id = str(integration_cfg.get("folder_id") or "").strip()
|
||||
if not base_url or not api_token or not library_id:
|
||||
job.add_log(
|
||||
"Audiobookshelf upload skipped: configure base URL, API token, and library ID first.",
|
||||
level="warning",
|
||||
)
|
||||
return
|
||||
if not folder_id:
|
||||
job.add_log(
|
||||
"Audiobookshelf upload skipped: configure a folder ID in the Audiobookshelf settings.",
|
||||
level="warning",
|
||||
)
|
||||
return
|
||||
|
||||
audio_ref = job.result.audio_path
|
||||
audio_path = audio_ref if isinstance(audio_ref, Path) else Path(str(audio_ref)) if audio_ref else None
|
||||
@@ -956,7 +963,7 @@ class ConversionService:
|
||||
api_token=api_token,
|
||||
library_id=library_id,
|
||||
collection_id=(str(integration_cfg.get("collection_id") or "").strip() or None),
|
||||
folder_id=(str(integration_cfg.get("folder_id") or "").strip() or None),
|
||||
folder_id=folder_id,
|
||||
verify_ssl=self._coerce_bool(integration_cfg.get("verify_ssl"), True),
|
||||
send_cover=self._coerce_bool(integration_cfg.get("send_cover"), True),
|
||||
send_chapters=self._coerce_bool(integration_cfg.get("send_chapters"), True),
|
||||
|
||||
@@ -381,8 +381,8 @@ async function testAudiobookshelf(button) {
|
||||
return;
|
||||
}
|
||||
const hasToken = Boolean(fields.api_token) || Boolean(fields.use_saved_token);
|
||||
if (!fields.base_url || !hasToken || !fields.library_id) {
|
||||
setStatus(status, 'Enter the base URL, API token, and library ID to test.', 'error');
|
||||
if (!fields.base_url || !hasToken || !fields.library_id || !fields.folder_id) {
|
||||
setStatus(status, 'Enter the base URL, API token, library ID, and folder ID to test.', 'error');
|
||||
return;
|
||||
}
|
||||
clearStatus(status);
|
||||
|
||||
@@ -445,8 +445,9 @@
|
||||
<input type="text" id="audiobookshelf_collection_id" name="audiobookshelf_collection_id" value="{{ integrations.audiobookshelf.collection_id }}">
|
||||
</div>
|
||||
<div class="field__group">
|
||||
<label for="audiobookshelf_folder_id">Folder ID (optional)</label>
|
||||
<input type="text" id="audiobookshelf_folder_id" name="audiobookshelf_folder_id" value="{{ integrations.audiobookshelf.folder_id }}">
|
||||
<label for="audiobookshelf_folder_id">Folder ID</label>
|
||||
<input type="text" id="audiobookshelf_folder_id" name="audiobookshelf_folder_id" value="{{ integrations.audiobookshelf.folder_id }}">
|
||||
<p class="hint">Open the target library in Audiobookshelf and copy the folder ID from the address bar.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field field--inline">
|
||||
|
||||
Reference in New Issue
Block a user