Compare commits
4 Commits
0e4de857d4
...
89d49f3e34
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89d49f3e34 | ||
|
|
e813a01e14 | ||
|
|
72e3ef69ff | ||
|
|
94e7508a24 |
@ -36,7 +36,7 @@ class Config(object):
|
||||
ROOT = os.environ.get('ROOT') or "/home/kae/music"
|
||||
TESTMODE = True
|
||||
TIMER_MS = 500
|
||||
VOLUME_VLC_DEFAULT = 81
|
||||
VOLUME_VLC_DEFAULT = 75
|
||||
|
||||
|
||||
config = Config
|
||||
|
||||
68
app/model.py
68
app/model.py
@ -2,7 +2,7 @@
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, time
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
@ -119,6 +119,35 @@ class Playdates(Base):
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def remove_track(session, track_id):
|
||||
"""
|
||||
Remove all records of track_id
|
||||
"""
|
||||
|
||||
session.query(Playdates).filter(
|
||||
Playdates.track_id == track_id,
|
||||
).delete()
|
||||
session.commit()
|
||||
|
||||
@staticmethod
|
||||
def last_show(session, track):
|
||||
"""
|
||||
Return datetime track last played during show time or None
|
||||
|
||||
FIXME: hard coded times in here
|
||||
"""
|
||||
|
||||
# dayofweek: 1 = Sunday, 2 = Monday, ..., 7 = Saturday.
|
||||
friday = 6
|
||||
after = time(20, 0)
|
||||
|
||||
return session.query(Playdates).filter(
|
||||
(Playdates.track_id == track.id),
|
||||
(func.dayofweek(Playdates.lastplayed) == friday),
|
||||
(func.time(Playdates.lastplayed) > after),
|
||||
).order_by(Playdates.lastplayed.desc()).first()
|
||||
|
||||
|
||||
class Playlists(Base):
|
||||
"""
|
||||
@ -293,18 +322,11 @@ class PlaylistTracks(Base):
|
||||
session.commit()
|
||||
|
||||
@staticmethod
|
||||
def get_playlists_containing_track_id(session, track_id):
|
||||
def get_track_playlists(session, track_id):
|
||||
"Return all PlaylistTracks objects with this track_id"
|
||||
|
||||
playlists = []
|
||||
playlist_ids = session.query(PlaylistTracks.playlist_id).filter(
|
||||
return session.query(PlaylistTracks).filter(
|
||||
PlaylistTracks.track_id == track_id).all()
|
||||
for p in playlist_ids:
|
||||
playlist = session.query(Playlists).filter(
|
||||
Playlists.id == p[0]).first()
|
||||
if playlist:
|
||||
playlists.append(playlist)
|
||||
|
||||
return playlists
|
||||
|
||||
@staticmethod
|
||||
def move_track(session, from_playlist_id, row, to_playlist_id):
|
||||
@ -492,6 +514,29 @@ class Tracks(Base):
|
||||
ERROR(f"get_track({id}): not found")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def search(session, title=None, artist=None, duration=None):
|
||||
"""
|
||||
Return any tracks matching passed criteria
|
||||
"""
|
||||
|
||||
DEBUG(
|
||||
f"Tracks.search({title=}, {artist=}), {duration=})"
|
||||
)
|
||||
|
||||
if not title and not artist and not duration:
|
||||
return None
|
||||
|
||||
q = session.query(Tracks).filter(False)
|
||||
if title:
|
||||
q = q.filter(Tracks.title == title)
|
||||
if artist:
|
||||
q = q.filter(Tracks.artist == artist)
|
||||
if duration:
|
||||
q = q.filter(Tracks.duration == duration)
|
||||
|
||||
return q.all()
|
||||
|
||||
@staticmethod
|
||||
def get_track_from_filename(session, filename):
|
||||
"""
|
||||
@ -527,6 +572,7 @@ class Tracks(Base):
|
||||
|
||||
try:
|
||||
session.query(Tracks).filter(Tracks.path == path).delete()
|
||||
session.commit()
|
||||
except IntegrityError as exception:
|
||||
ERROR(f"Can't remove track with {path=} ({exception=})")
|
||||
|
||||
|
||||
@ -530,6 +530,11 @@ class PlaylistTab(QTableWidget):
|
||||
duration = Tracks.get_duration(session, self._get_row_id(row))
|
||||
return start + timedelta(milliseconds=duration)
|
||||
|
||||
def _can_read_track(self, track):
|
||||
"Check track file is readable"
|
||||
|
||||
return os.access(track.path, os.R_OK)
|
||||
|
||||
def _context_menu(self, pos):
|
||||
|
||||
self.menu.exec_(self.mapToGlobal(pos))
|
||||
@ -617,12 +622,12 @@ class PlaylistTab(QTableWidget):
|
||||
if not track:
|
||||
txt = f"Track not found (track.id={id})"
|
||||
else:
|
||||
txt = f"""
|
||||
Title: {track.title}
|
||||
Artist: {track.artist}
|
||||
Path: {track.path}
|
||||
Track ID: {track.id}
|
||||
"""
|
||||
txt = (
|
||||
f"Title: {track.title}\n"
|
||||
f"Artist: {track.artist}\n"
|
||||
f"Path: {track.path}\n"
|
||||
f"Track ID: {track.id}"
|
||||
)
|
||||
info = QMessageBox(self)
|
||||
info.setIcon(QMessageBox.Information)
|
||||
info.setText(txt)
|
||||
|
||||
@ -7,7 +7,7 @@ import tempfile
|
||||
|
||||
from config import Config
|
||||
from log import DEBUG, INFO
|
||||
from model import Tracks, Playdates, PlaylistTracks, Session
|
||||
from model import Notes, Playdates, PlaylistTracks, Session, Tracks
|
||||
from mutagen.flac import FLAC
|
||||
from mutagen.mp3 import MP3
|
||||
from pydub import AudioSegment, effects
|
||||
@ -255,23 +255,26 @@ def update_db(session):
|
||||
db_paths = set(Tracks.get_all_paths(session))
|
||||
# Remote any tracks from database whose paths don't exist
|
||||
for path in list(db_paths - os_paths):
|
||||
# Manage tracks listed in database but where path is invalid
|
||||
track = Tracks.get_track_from_path(session, path)
|
||||
DEBUG(f"songdb.update_db(): remove from database: {path=} {track=}")
|
||||
played = Playdates.last_played(session, track)
|
||||
playlists = PlaylistTracks.get_playlists_containing_track_id(
|
||||
session, track.id)
|
||||
if played:
|
||||
INFO(
|
||||
f"songdb.update_db: Can't remove {track.id=} ({track.path=}) "
|
||||
f"as it's in playdates.id={played.id}"
|
||||
)
|
||||
elif playlists:
|
||||
INFO(
|
||||
f"songdb.update_db: Can't remove {track.id=} ({track.path=} "
|
||||
f"as it's in playlists {[p.name for p in playlists]}"
|
||||
)
|
||||
else:
|
||||
Tracks.remove_path(session, path)
|
||||
|
||||
# Remove references from Playdates
|
||||
Playdates.remove_track(session, track.id)
|
||||
|
||||
# Replace playlist entries with a note
|
||||
note_txt = (
|
||||
f"File removed: {track.title=}, {track.artist=}, "
|
||||
f"{track.path=}"
|
||||
)
|
||||
for pt in PlaylistTracks.get_track_playlists(session, track.id):
|
||||
# Create note
|
||||
Notes.add_note(session, pt.playlist_id, pt.row, note_txt)
|
||||
# Remove playlist entry
|
||||
PlaylistTracks.remove_track(session, pt.playlist_id, pt.row)
|
||||
|
||||
# Remove Track entry pointing to invalid path
|
||||
Tracks.remove_path(session, path)
|
||||
|
||||
|
||||
if __name__ == '__main__' and '__file__' in globals():
|
||||
|
||||
Loading…
Reference in New Issue
Block a user