mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-06-10 03:02:09 +00:00
feat(import): include cover-art attachments in --export/--import
Export URL-backed attachments per title and rebuild them on import so they ride along into the muxed output. Local font attachments are skipped (not portable).
This commit is contained in:
@@ -2829,6 +2829,9 @@ class dl:
|
|||||||
{"timestamp": chapter.timestamp, "name": chapter.name} for chapter in (title.tracks.chapters or [])
|
{"timestamp": chapter.timestamp, "name": chapter.name} for chapter in (title.tracks.chapters or [])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "attachments" not in tinfo:
|
||||||
|
tinfo["attachments"] = [a.to_dict() for a in (title.tracks.attachments or []) if a.url]
|
||||||
|
|
||||||
export.write_text(json.dumps(doc, indent=4, ensure_ascii=False), encoding="utf8")
|
export.write_text(json.dumps(doc, indent=4, ensure_ascii=False), encoding="utf8")
|
||||||
|
|
||||||
def prepare_drm(
|
def prepare_drm(
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from unshackle.core.manifests import DASH, HLS, ISM
|
|||||||
from unshackle.core.remote_service import RemoteService, _build_title, _resolve_proxy
|
from unshackle.core.remote_service import RemoteService, _build_title, _resolve_proxy
|
||||||
from unshackle.core.titles import Episode, Movies, Series, Title_T, Titles_T, remap_titles
|
from unshackle.core.titles import Episode, Movies, Series, Title_T, Titles_T, remap_titles
|
||||||
from unshackle.core.tracks import Audio, Chapter, Chapters, Tracks, Video
|
from unshackle.core.tracks import Audio, Chapter, Chapters, Tracks, Video
|
||||||
|
from unshackle.core.tracks.attachment import Attachment
|
||||||
from unshackle.core.tracks.track import Track
|
from unshackle.core.tracks.track import Track
|
||||||
|
|
||||||
log = logging.getLogger("import")
|
log = logging.getLogger("import")
|
||||||
@@ -166,6 +167,23 @@ class ImportService:
|
|||||||
track.drm = drm
|
track.drm = drm
|
||||||
tracks.add(track)
|
tracks.add(track)
|
||||||
|
|
||||||
|
for attachment in entry.get("attachments") or []:
|
||||||
|
url = attachment.get("url")
|
||||||
|
if not url:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
tracks.attachments.append(
|
||||||
|
Attachment.from_url(
|
||||||
|
url,
|
||||||
|
name=attachment.get("name"),
|
||||||
|
mime_type=attachment.get("mime_type"),
|
||||||
|
description=attachment.get("description"),
|
||||||
|
session=self.session,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.log.warning(f"Skipping attachment '{attachment.get('name')}': {e}")
|
||||||
|
|
||||||
self.tracks_by_title[title_id] = tracks
|
self.tracks_by_title[title_id] = tracks
|
||||||
return tracks
|
return tracks
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,10 @@ class Attachment:
|
|||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return " | ".join(filter(bool, ["ATT", self.name, self.mime_type, self.description]))
|
return " | ".join(filter(bool, ["ATT", self.name, self.mime_type, self.description]))
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Optional[str]]:
|
||||||
|
"""Serialise a URL-backed attachment for export/import."""
|
||||||
|
return {"url": self.url, "name": self.name, "mime_type": self.mime_type, "description": self.description}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> str:
|
def id(self) -> str:
|
||||||
"""Compute an ID from the attachment data."""
|
"""Compute an ID from the attachment data."""
|
||||||
|
|||||||
Reference in New Issue
Block a user