emmental/curds/tags.py

83 lines
2.8 KiB
Python

# Copyright 2019 (c) Anna Schumaker.
from . import data
from . import notify
import mutagen
import os
import re
discno_map = { "one" : "1", "two" : "2", "three" : "3", "four" : "4", "five" : "5" }
tag_map = dict()
class Tag:
def extract(info, key, default):
return info.get(key, [ default ])[0]
def lookup(tag, cb):
ret = tag_map.setdefault(hash(tag), tag)
if ret == tag:
notify.Notify.notify(cb, ret)
return ret
class Album(Tag):
def __init__(self, info):
self.album = Tag.extract(info, "album", "Unknown Album")
self.genre = Tag.extract(info, "genre", "Unknown")
self.date = int(Tag.extract(info, "date", 0))
self.tracktotal = int(Tag.extract(info, "tracktotal", 0))
self.albumartist = Tag.extract(info, "albumartist",
Tag.extract(info, "album artist",
Tag.extract(info, "artist", "Unknown Artist")))
# Try to detect album names that have a discnumber embedded in them
match = re.search("(cd|dis[c|k])(\s)*(([0-9]+)|one|two|three|four|five)", self.album.lower())
if match and match.start() > 0:
self.album = self.album[:match.start()].strip(" ;({[-")
def __hash__(self):
return hash((self.album, self.albumartist, self.date))
def lookup(info):
return Tag.lookup(Album(info), "new-album")
class Track(Tag):
def __init__(self, path):
info = mutagen.File(path)
self.path = path
self.title = Tag.extract(info, "title", os.path.basename(path))
self.artist = Tag.extract(info, "artist", "Unknown Artist")
self.tracknumber = int(Tag.extract(info, "tracknumber", 0))
self.discnumber = int(Tag.extract(info, "discnumber", 1))
self.length = info.info.length
self.album = Album.lookup(info)
# Try to detect discnumbers that are embedded in the album name
discno = Tag.extract(info, "album", "Unknown Album")[len(self.album.album):]
match = re.search("([1-9][0-9]*)|one|two|three|four|five", discno.lower())
if match:
self.discnumber = int(discno_map.get(match.group(), match.group()))
def __getitem__(self, key):
item = vars(self).get(key)
if not item or item == self.album:
item = vars(self.album).get(key)
return item
def __hash__(self):
return hash((hash(self.album), self.title, self.artist,
self.tracknumber, self.discnumber))
def lookup(path):
return Tag.lookup(Track(path), "new-track")
def save():
with data.DataFile("tags.pickle", data.WRITE) as f:
f.pickle(tag_map)
def load():
with data.DataFile("tags.pickle", data.READ) as f:
tag_map.update(f.unpickle())