Files
spotify-downloader/spotdl/metadata/embedder_base.py
2020-04-12 14:13:21 +05:30

95 lines
3.0 KiB
Python

import os
from abc import ABC
from abc import abstractmethod
import urllib.request
class EmbedderBase(ABC):
"""
The subclass must define the supported media file encoding
formats here using a static variable - such as:
>>> supported_formats = ("mp3", "m4a", "flac")
"""
supported_formats = ()
@abstractmethod
def __init__(self):
"""
For every supported format, there must be a corresponding
method that applies metadata on this format.
Such as if mp3 is supported, there must exist a method named
`as_mp3` on this class that applies metadata on mp3 files.
"""
# self.targets = { fmt: eval(str("self.as_" + fmt))
# for fmt in self.supported_formats }
#
# TODO: The above code seems to fail for some reason
# I do not know.
self.targets = {}
for fmt in self.supported_formats:
# FIXME: Calling `eval` is dangerous here!
self.targets[fmt] = eval("self.as_" + fmt)
def get_encoding(self, path):
"""
This method must determine the encoding for a local
audio file. Such as "mp3", "wav", "m4a", etc.
"""
_, extension = os.path.splitext(path)
# Ignore the initial dot from file extension
return extension[1:]
def apply_metadata(self, path, metadata, cached_albumart=None, encoding=None):
"""
This method must automatically detect the media encoding
format from file path and embed the corresponding metadata
on the given file by calling an appropriate submethod.
"""
if cached_albumart is None:
cached_albumart = urllib.request.urlopen(
metadata["album"]["images"][0]["url"],
).read()
if encoding is None:
encoding = self.get_encoding(path)
if encoding not in self.supported_formats:
raise TypeError(
'The input format ("{}") is not supported.'.format(
encoding,
))
embed_on_given_format = self.targets[encoding]
embed_on_given_format(path, metadata, cached_albumart=cached_albumart)
def as_mp3(self, path, metadata, cached_albumart=None):
"""
Method for mp3 support. This method might be defined in
a subclass.
Other methods for additional supported formats must also
be declared here.
"""
raise NotImplementedError
def as_m4a(self, path, metadata, cached_albumart=None):
"""
Method for m4a support. This method might be defined in
a subclass.
Other methods for additional supported formats must also
be declared here.
"""
raise NotImplementedError
def as_flac(self, path, metadata, cached_albumart=None):
"""
Method for flac support. This method might be defined in
a subclass.
Other methods for additional supported formats must also
be declared here.
"""
raise NotImplementedError