deemix-py/deemix/tagger.py
RemixDev f530a4e89f Merge refactoring (#4)
Removed saveDownloadQueue and tagsLanguage from lib settings

Revert embedded cover change

Fixed bitrate fallback check

Use overwriteFile setting when downloading embedded covers

Fixed bitrate fallback not working

Fixed some issues to make the lib work

Implemented spotify plugin back

Better handling of albums upcs

Fixed queue item not cancelling correctly

Code parity with deemix-js

Code cleanup with pylint

Even more rework on the library

More work on the library (WIP)

Total rework of the library (WIP)

Some rework done on types

Added start queue function

Made nextitem work on a thread

Removed dz as first parameter

Started queuemanager refactoring

Removed eventlet

Co-authored-by: RemixDev <RemixDev64@gmail.com>
Reviewed-on: https://git.freezer.life/RemixDev/deemix-py/pulls/4
Co-Authored-By: RemixDev <remixdev@noreply.localhost>
Co-Committed-By: RemixDev <remixdev@noreply.localhost>
2021-06-27 16:29:41 -04:00

213 lines
8 KiB
Python

from mutagen.flac import FLAC, Picture
from mutagen.id3 import ID3, ID3NoHeaderError, \
TXXX, TIT2, TPE1, TALB, TPE2, TRCK, TPOS, TCON, TYER, TDAT, TLEN, TBPM, \
TPUB, TSRC, USLT, SYLT, APIC, IPLS, TCOM, TCOP, TCMP, Encoding, PictureType
# Adds tags to a MP3 file
def tagID3(path, track, save):
# Delete exsisting tags
try:
tag = ID3(path)
tag.delete()
except ID3NoHeaderError:
tag = ID3()
if save['title']:
tag.add(TIT2(text=track.title))
if save['artist'] and len(track.artists):
if save['multiArtistSeparator'] == "default":
tag.add(TPE1(text=track.artists))
else:
if save['multiArtistSeparator'] == "nothing":
tag.add(TPE1(text=track.mainArtist.name))
else:
tag.add(TPE1(text=track.artistsString))
# Tag ARTISTS is added to keep the multiartist support when using a non standard tagging method
# https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#artists
tag.add(TXXX(desc="ARTISTS", text=track.artists))
if save['album']:
tag.add(TALB(text=track.album.title))
if save['albumArtist'] and len(track.album.artists):
if save['singleAlbumArtist'] and track.album.mainArtist.save:
tag.add(TPE2(text=track.album.mainArtist.name))
else:
tag.add(TPE2(text=track.album.artists))
if save['trackNumber']:
trackNumber = str(track.trackNumber)
if save['trackTotal']:
trackNumber += "/" + str(track.album.trackTotal)
tag.add(TRCK(text=trackNumber))
if save['discNumber']:
discNumber = str(track.discNumber)
if save['discTotal']:
discNumber += "/" + str(track.album.discTotal)
tag.add(TPOS(text=discNumber))
if save['genre']:
tag.add(TCON(text=track.album.genre))
if save['year']:
tag.add(TYER(text=str(track.date.year)))
if save['date']:
# Referencing ID3 standard
# https://id3.org/id3v2.3.0#TDAT
# The 'Date' frame is a numeric string in the DDMM format.
tag.add(TDAT(text=str(track.date.day) + str(track.date.month)))
if save['length']:
tag.add(TLEN(text=str(int(track.duration)*1000)))
if save['bpm']:
tag.add(TBPM(text=str(track.bpm)))
if save['label']:
tag.add(TPUB(text=track.album.label))
if save['isrc']:
tag.add(TSRC(text=track.ISRC))
if save['barcode']:
tag.add(TXXX(desc="BARCODE", text=track.album.barcode))
if save['explicit']:
tag.add(TXXX(desc="ITUNESADVISORY", text= "1" if track.explicit else "0" ))
if save['replayGain']:
tag.add(TXXX(desc="REPLAYGAIN_TRACK_GAIN", text=track.replayGain))
if track.lyrics.unsync and save['lyrics']:
tag.add(USLT(text=track.lyrics.unsync))
if track.lyrics.syncID3 and save['syncedLyrics']:
# Referencing ID3 standard
# https://id3.org/id3v2.3.0#sec4.10
# Type: 1 => is lyrics
# Format: 2 => Absolute time, 32 bit sized, using milliseconds as unit
tag.add(SYLT(Encoding.UTF8, type=1, format=2, text=track.lyrics.syncID3))
involved_people = []
for role in track.contributors:
if role in ['author', 'engineer', 'mixer', 'producer', 'writer']:
for person in track.contributors[role]:
involved_people.append([role, person])
elif role == 'composer' and save['composer']:
tag.add(TCOM(text=track.contributors['composer']))
if len(involved_people) > 0 and save['involvedPeople']:
tag.add(IPLS(people=involved_people))
if save['copyright']:
tag.add(TCOP(text=track.copyright))
if save['savePlaylistAsCompilation'] and track.playlist or track.album.recordType == "compile":
tag.add(TCMP(text="1"))
if save['source']:
tag.add(TXXX(desc="SOURCE", text='Deezer'))
tag.add(TXXX(desc="SOURCEID", text=str(track.id)))
if save['cover'] and track.album.embeddedCoverPath:
descEncoding = Encoding.LATIN1
if save['coverDescriptionUTF8']:
descEncoding = Encoding.UTF8
mimeType = 'image/jpeg'
if str(track.album.embeddedCoverPath).endswith('png'):
mimeType = 'image/png'
with open(track.album.embeddedCoverPath, 'rb') as f:
tag.add(APIC(descEncoding, mimeType, PictureType.COVER_FRONT, desc='cover', data=f.read()))
tag.save( path,
v1=2 if save['saveID3v1'] else 0,
v2_version=3,
v23_sep=None if save['useNullSeparator'] else '/' )
# Adds tags to a FLAC file
def tagFLAC(path, track, save):
# Delete exsisting tags
tag = FLAC(path)
tag.delete()
tag.clear_pictures()
if save['title']:
tag["TITLE"] = track.title
if save['artist'] and len(track.artists):
if save['multiArtistSeparator'] == "default":
tag["ARTIST"] = track.artists
else:
if save['multiArtistSeparator'] == "nothing":
tag["ARTIST"] = track.mainArtist.name
else:
tag["ARTIST"] = track.artistsString
# Tag ARTISTS is added to keep the multiartist support when using a non standard tagging method
# https://picard-docs.musicbrainz.org/en/technical/tag_mapping.html#artists
tag["ARTISTS"] = track.artists
if save['album']:
tag["ALBUM"] = track.album.title
if save['albumArtist'] and len(track.album.artists):
if save['singleAlbumArtist'] and track.album.mainArtist.save:
tag["ALBUMARTIST"] = track.album.mainArtist.name
else:
tag["ALBUMARTIST"] = track.album.artists
if save['trackNumber']:
tag["TRACKNUMBER"] = str(track.trackNumber)
if save['trackTotal']:
tag["TRACKTOTAL"] = str(track.album.trackTotal)
if save['discNumber']:
tag["DISCNUMBER"] = str(track.discNumber)
if save['discTotal']:
tag["DISCTOTAL"] = str(track.album.discTotal)
if save['genre']:
tag["GENRE"] = track.album.genre
# YEAR tag is not suggested as a standard tag
# Being YEAR already contained in DATE will only use DATE instead
# Reference: https://www.xiph.org/vorbis/doc/v-comment.html#fieldnames
if save['date']:
tag["DATE"] = track.dateString
elif save['year']:
tag["DATE"] = str(track.date.year)
if save['length']:
tag["LENGTH"] = str(int(track.duration)*1000)
if save['bpm']:
tag["BPM"] = str(track.bpm)
if save['label']:
tag["PUBLISHER"] = track.album.label
if save['isrc']:
tag["ISRC"] = track.ISRC
if save['barcode']:
tag["BARCODE"] = track.album.barcode
if save['explicit']:
tag["ITUNESADVISORY"] = "1" if track.explicit else "0"
if save['replayGain']:
tag["REPLAYGAIN_TRACK_GAIN"] = track.replayGain
if track.lyrics.unsync and save['lyrics']:
tag["LYRICS"] = track.lyrics.unsync
for role in track.contributors:
if role in ['author', 'engineer', 'mixer', 'producer', 'writer', 'composer']:
if save['involvedPeople'] and role != 'composer' or save['composer'] and role == 'composer':
tag[role] = track.contributors[role]
elif role == 'musicpublisher' and save['involvedPeople']:
tag["ORGANIZATION"] = track.contributors['musicpublisher']
if save['copyright']:
tag["COPYRIGHT"] = track.copyright
if save['savePlaylistAsCompilation'] and track.playlist or track.album.recordType == "compile":
tag["COMPILATION"] = "1"
if save['source']:
tag["SOURCE"] = 'Deezer'
tag["SOURCEID"] = str(track.id)
if save['cover'] and track.album.embeddedCoverPath:
image = Picture()
image.type = PictureType.COVER_FRONT
image.mime = 'image/jpeg'
if str(track.album.embeddedCoverPath).endswith('png'):
image.mime = 'image/png'
with open(track.album.embeddedCoverPath, 'rb') as f:
image.data = f.read()
tag.add_picture(image)
tag.save(deleteid3=True)