First pass of songdb
This commit is contained in:
parent
a285765b24
commit
8177e2bd07
129
songdb.py
Executable file
129
songdb.py
Executable file
@ -0,0 +1,129 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import sqlalchemy
|
||||
|
||||
import pytiger.logging.config
|
||||
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Float, DateTime, Integer, String
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from tinytag import TinyTag
|
||||
|
||||
# "Constants"
|
||||
ROOT = "/home/kae/music"
|
||||
DISPLAY_SQL = False
|
||||
MYSQL_CONNECT = "mysql+mysqldb://songdb:songdb@localhost/songdb"
|
||||
|
||||
# Instantiate logging
|
||||
pytiger.logging.config.basic_config(stderr=False, level=logging.INFO)
|
||||
log = logging.getLogger(__name__)
|
||||
log.info("Starting")
|
||||
|
||||
# Declare mapping
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
# Database classes
|
||||
class Tracks(Base):
|
||||
__tablename__ = 'tracks'
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
title = Column(String(256), index=True)
|
||||
artist = Column(String(256), index=True)
|
||||
length = Column(Integer, index=True)
|
||||
path = Column(String(2048), index=False, nullable=False)
|
||||
mtime = Column(Float, index=True)
|
||||
lastplayed = Column(DateTime, index=True, default=None)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<Track(id={self.id}, title={self.title}, "
|
||||
f"artist={self.artist}, path={self.path}>"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_or_create(cls, session, path):
|
||||
try:
|
||||
track = session.query(cls).filter(cls.path == path).one()
|
||||
except NoResultFound:
|
||||
track = Tracks()
|
||||
track.path = path
|
||||
session.add(track)
|
||||
return track
|
||||
|
||||
|
||||
def main():
|
||||
"Main loop"
|
||||
|
||||
# Set up database connection
|
||||
log.info("Connect to database")
|
||||
engine = sqlalchemy.create_engine(f"{MYSQL_CONNECT}?charset=utf8",
|
||||
encoding='utf-8',
|
||||
echo=DISPLAY_SQL)
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
# Create a Session
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
# Parse command line
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('-u', '--update',
|
||||
action="store_true", dest="update",
|
||||
default=True, help="Update database")
|
||||
args = p.parse_args()
|
||||
|
||||
# Run as required
|
||||
if args.update:
|
||||
log.info("Updating database")
|
||||
update_db(session)
|
||||
|
||||
log.info("Finished")
|
||||
|
||||
|
||||
def update_db(session):
|
||||
"""
|
||||
Repopulate database
|
||||
|
||||
TODO: remove missing files
|
||||
"""
|
||||
|
||||
count = 0
|
||||
for root, dirs, files in os.walk(ROOT):
|
||||
for f in files:
|
||||
count += 1
|
||||
path = os.path.join(root, f)
|
||||
ext = os.path.splitext(f)[1]
|
||||
if ext in [".flac", ".mp3"]:
|
||||
track = Tracks.get_or_create(session,
|
||||
os.path.relpath(path, ROOT))
|
||||
tag = TinyTag.get(path)
|
||||
track.title = tag.title
|
||||
track.artist = tag.artist
|
||||
track.length = tag.duration * 1000
|
||||
track.mtime = os.path.getmtime(path)
|
||||
elif ext not in [".jpg"]:
|
||||
print(f"Unrecognised file type: {path}")
|
||||
|
||||
session.commit()
|
||||
print(f"{count} files processed")
|
||||
|
||||
|
||||
def md5(path):
|
||||
"https://stackoverflow.com/questions/3431825/"
|
||||
"generating-an-md5-checksum-of-a-file"
|
||||
|
||||
hash_md5 = hashlib.md5()
|
||||
with open(path, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(4096), b""):
|
||||
hash_md5.update(chunk)
|
||||
return hash_md5.hexdigest()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user