Files

239 lines
9.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Calibre-Web Automated fork of Calibre-Web
# Copyright (C) 2018-2026 Calibre-Web contributors
# Copyright (C) 2024-2026 Calibre-Web Automated contributors
# SPDX-License-Identifier: GPL-3.0-or-later
# See CONTRIBUTORS for full list of authors.
# This file is is mostly taken from audio.py from Ozzieisaacs at calibre-web
import base64
import os
from collections import namedtuple
import mutagen
try:
from wand.image import Image
use_IM = True
except (ImportError, RuntimeError) as e:
use_IM = False
BookMeta = namedtuple(
"BookMeta",
"file_path, extension, title, author, cover, description, tags, series, "
"series_id, languages, publisher, pubdate, identifiers",
)
NO_JPEG_EXTENSIONS = [".png", ".webp", ".bmp"]
COVER_EXTENSIONS = [".png", ".webp", ".bmp", ".jpg", ".jpeg"]
def cover_processing(tmp_file_path, img, extension):
# tmp_cover_name = os.path.join(os.path.dirname(tmp_file_name), 'cover.jpg')
tmp_cover_name = tmp_file_path + ".jpg"
if extension in NO_JPEG_EXTENSIONS:
if use_IM:
with Image(blob=img) as imgc:
imgc.format = "jpeg"
imgc.transform_colorspace("srgb")
imgc.save(filename=tmp_cover_name)
return tmp_cover_name
else:
return None
if img:
with open(tmp_cover_name, "wb") as f:
f.write(img)
return tmp_cover_name
else:
return None
def get_audio_file_info(
tmp_file_path, original_file_extension, original_file_name, no_cover_processing
):
tmp_cover_name = None
audio_file = mutagen.File(tmp_file_path)
comments = None
if original_file_extension in [".mp3", ".wav", ".aiff"]:
cover_data = list()
for key, val in audio_file.tags.items():
if key.startswith("APIC:"):
cover_data.append(val)
if key.startswith("COMM:"):
comments = val.text[0]
title = (
audio_file.tags.get("TIT2").text[0] if "TIT2" in audio_file.tags else None
)
author = (
audio_file.tags.get("TPE1").text[0] if "TPE1" in audio_file.tags else None
)
if author is None:
author = (
audio_file.tags.get("TPE2").text[0]
if "TPE2" in audio_file.tags
else None
)
tags = (
audio_file.tags.get("TCON").text[0] if "TCON" in audio_file.tags else None
) # Genre
series = (
audio_file.tags.get("TALB").text[0] if "TALB" in audio_file.tags else None
) # Album
series_id = (
audio_file.tags.get("TRCK").text[0] if "TRCK" in audio_file.tags else None
) # track no.
publisher = (
audio_file.tags.get("TPUB").text[0] if "TPUB" in audio_file.tags else None
)
pubdate = (
str(audio_file.tags.get("TDRL").text[0])
if "TDRL" in audio_file.tags
else None
)
if not pubdate:
pubdate = (
str(audio_file.tags.get("TDRC").text[0])
if "TDRC" in audio_file.tags
else None
)
if not pubdate:
pubdate = (
str(audio_file.tags.get("TDOR").text[0])
if "TDOR" in audio_file.tags
else None
)
if cover_data and not no_cover_processing:
cover_info = cover_data[0]
for dat in cover_data:
if dat.type == mutagen.id3.PictureType.COVER_FRONT:
cover_info = dat
break
tmp_cover_name = cover_processing(
tmp_file_path, cover_info.data, "." + cover_info.mime[-3:]
)
elif original_file_extension in [".ogg", ".flac", ".opus", ".ogv"]:
title = audio_file.tags.get("TITLE")[0] if "TITLE" in audio_file else None
author = audio_file.tags.get("ARTIST")[0] if "ARTIST" in audio_file else None
comments = (
audio_file.tags.get("COMMENTS")[0] if "COMMENTS" in audio_file else None
)
tags = (
audio_file.tags.get("GENRE")[0] if "GENRE" in audio_file else None
) # Genre
series = audio_file.tags.get("ALBUM")[0] if "ALBUM" in audio_file else None
series_id = (
audio_file.tags.get("TRACKNUMBER")[0]
if "TRACKNUMBER" in audio_file
else None
)
publisher = audio_file.tags.get("LABEL")[0] if "LABEL" in audio_file else None
pubdate = audio_file.tags.get("DATE")[0] if "DATE" in audio_file else None
cover_data = audio_file.tags.get("METADATA_BLOCK_PICTURE")
if not no_cover_processing:
if cover_data:
cover_info = mutagen.flac.Picture(base64.b64decode(cover_data[0]))
tmp_cover_name = cover_processing(
tmp_file_path, cover_info.data, "." + cover_info.mime[-3:]
)
if hasattr(audio_file, "pictures"):
cover_info = audio_file.pictures[0]
for dat in audio_file.pictures:
if dat.type == mutagen.id3.PictureType.COVER_FRONT:
cover_info = dat
break
tmp_cover_name = cover_processing(
tmp_file_path, cover_info.data, "." + cover_info.mime[-3:]
)
elif original_file_extension in [".aac"]:
title = audio_file.tags.get("Title").value if "Title" in audio_file else None
author = audio_file.tags.get("Artist").value if "Artist" in audio_file else None
comments = (
audio_file.tags.get("Comment").value if "Comment" in audio_file else None
)
tags = audio_file.tags.get("Genre").value if "Genre" in audio_file else None
series = audio_file.tags.get("Album").value if "Album" in audio_file else None
series_id = (
audio_file.tags.get("Track").value if "Track" in audio_file else None
)
publisher = (
audio_file.tags.get("Label").value if "Label" in audio_file else None
)
pubdate = audio_file.tags.get("Year").value if "Year" in audio_file else None
cover_data = audio_file.tags["Cover Art (Front)"]
if cover_data and not no_cover_processing:
tmp_cover_name = tmp_file_path + ".jpg"
with open(tmp_cover_name, "wb") as cover_file:
cover_file.write(cover_data.value.split(b"\x00", 1)[1])
elif original_file_extension in [".asf"]:
title = audio_file.tags.get("Title")[0].value if "Title" in audio_file else None
author = (
audio_file.tags.get("Artist")[0].value if "Artist" in audio_file else None
)
comments = (
audio_file.tags.get("Comments")[0].value
if "Comments" in audio_file
else None
)
tags = audio_file.tags.get("Genre")[0].value if "Genre" in audio_file else None
series = (
audio_file.tags.get("Album")[0].value if "Album" in audio_file else None
)
series_id = (
audio_file.tags.get("Track")[0].value if "Track" in audio_file else None
)
publisher = (
audio_file.tags.get("Label")[0].value if "Label" in audio_file else None
)
pubdate = audio_file.tags.get("Year")[0].value if "Year" in audio_file else None
cover_data = audio_file.tags.get("WM/Picture", None)
if cover_data and not no_cover_processing:
tmp_cover_name = tmp_file_path + ".jpg"
with open(tmp_cover_name, "wb") as cover_file:
cover_file.write(cover_data[0].value)
elif original_file_extension in [".mp4", ".m4a", ".m4b"]:
title = audio_file.tags.get("©nam")[0] if "©nam" in audio_file.tags else None
author = audio_file.tags.get("©ART")[0] if "©ART" in audio_file.tags else None
comments = audio_file.tags.get("©cmt")[0] if "©cmt" in audio_file.tags else None
tags = audio_file.tags.get("©gen")[0] if "©gen" in audio_file.tags else None
series = audio_file.tags.get("©alb")[0] if "©alb" in audio_file.tags else None
series_id = (
str(audio_file.tags.get("trkn")[0][0])
if "trkn" in audio_file.tags
else None
)
publisher = ""
pubdate = audio_file.tags.get("©day")[0] if "©day" in audio_file.tags else None
cover_data = audio_file.tags.get("covr", None)
if cover_data and not no_cover_processing:
cover_type = None
for c in cover_data:
if c.imageformat == mutagen.mp4.AtomDataType.JPEG:
cover_type = ".jpg"
cover_bin = c
break
elif c.imageformat == mutagen.mp4.AtomDataType.PNG:
cover_type = ".png"
cover_bin = c
break
if cover_type:
tmp_cover_name = cover_processing(tmp_file_path, cover_bin, cover_type)
# else:
# logger.error("Unknown covertype in file {} ".format(original_file_name))
return BookMeta(
file_path=tmp_file_path,
extension=original_file_extension,
title=title or original_file_name,
author="Unknown" if author is None else author,
cover=tmp_cover_name,
description="" if comments is None else comments,
tags="" if tags is None else tags,
series="" if series is None else series,
series_id="1" if series_id is None else series_id.split("/")[0],
languages="",
publisher="" if publisher is None else publisher,
pubdate="" if pubdate is None else pubdate,
identifiers=[],
)