Store playlist in db
This commit is contained in:
parent
ddce8f2391
commit
af895ef577
94
app/model.py
94
app/model.py
@ -3,10 +3,19 @@
|
||||
import os
|
||||
import sqlalchemy
|
||||
|
||||
from datetime import datetime
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Float, DateTime, Integer, String
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
DateTime,
|
||||
Float,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
String,
|
||||
Table
|
||||
)
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm import relationship, sessionmaker
|
||||
|
||||
from config import Config
|
||||
|
||||
@ -60,6 +69,63 @@ class Settings(Base):
|
||||
session.commit()
|
||||
|
||||
|
||||
playlist_tracks = Table(
|
||||
'playlistracks',
|
||||
Base.metadata,
|
||||
Column('playlist_id', Integer, ForeignKey('playlists.id')),
|
||||
Column('track_id', Integer, ForeignKey('tracks.id'))
|
||||
)
|
||||
|
||||
|
||||
class Playlists(Base):
|
||||
"""
|
||||
Usage:
|
||||
|
||||
In [3]: pl = session.query(Playlists).filter(Playlists.id == 1).one()
|
||||
|
||||
In [4]: pl
|
||||
Out[4]: <Playlist(id=1, name=Default>
|
||||
|
||||
In [5]: tr = session.query(Tracks).filter(Tracks.id == 3837).one()
|
||||
|
||||
In [6]: tr
|
||||
Out[6]: <Track(id=3837, title=Babe, artist=Various, path=/home/[...]
|
||||
|
||||
In [7]: pl.tracks.append(tr)
|
||||
...: session.commit()
|
||||
|
||||
In [8]: tr.playlists
|
||||
Out[8]: [<Playlist(id=1, name=Default>]
|
||||
|
||||
In [9]: pl.tracks
|
||||
Out[9]: [<Track(id=3837, title=Babe, artist=Various, path=/home/[...]
|
||||
"""
|
||||
|
||||
__tablename__ = "playlists"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(32), nullable=False, unique=True)
|
||||
tracks = relationship(
|
||||
"Tracks",
|
||||
secondary=playlist_tracks,
|
||||
back_populates="playlists")
|
||||
|
||||
def __repr__(self):
|
||||
return (f"<Playlist(id={self.id}, name={self.name}>")
|
||||
|
||||
# Currently we only support one playlist, so make that obvious from
|
||||
# function name
|
||||
@classmethod
|
||||
def get_only_playlist(cls):
|
||||
return session.query(Playlists).filter(Playlists.id == 1).one()
|
||||
|
||||
def add_track(self, track):
|
||||
self.tracks.append(track)
|
||||
|
||||
def get_tracks(self):
|
||||
return self.tracks
|
||||
|
||||
|
||||
class Tracks(Base):
|
||||
__tablename__ = 'tracks'
|
||||
|
||||
@ -71,9 +137,14 @@ class Tracks(Base):
|
||||
fade_at = Column(Integer, index=False)
|
||||
silence_at = Column(Integer, index=False)
|
||||
path = Column(String(2048), index=False, nullable=False)
|
||||
|
||||
mtime = Column(Float, index=True)
|
||||
lastplayed = Column(DateTime, index=True, default=None)
|
||||
playlists = relationship(
|
||||
"Playlists",
|
||||
secondary=playlist_tracks,
|
||||
back_populates="tracks")
|
||||
playdates_id = Column(Integer, ForeignKey('playdates.id'))
|
||||
playdates = relationship("Playdates", back_populates="tracks")
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
@ -123,3 +194,20 @@ class Tracks(Base):
|
||||
def track_from_id(id):
|
||||
return session.query(Tracks).filter(
|
||||
Tracks.id == id).one()
|
||||
|
||||
|
||||
class Playdates(Base):
|
||||
__tablename__ = 'playdates'
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
lastplayed = Column(DateTime, index=True, default=None)
|
||||
tracks = relationship("Tracks", back_populates="playdates")
|
||||
|
||||
@staticmethod
|
||||
def add_playdate(track):
|
||||
DEBUG(f"add_playdate({track})")
|
||||
pd = Playdates()
|
||||
pd.lastplayed = datetime.now()
|
||||
pd.tracks.append(track)
|
||||
session.add(pd)
|
||||
session.commit()
|
||||
|
||||
@ -14,7 +14,7 @@ from ui.main_window_ui import Ui_MainWindow
|
||||
from ui.dlg_search_database_ui import Ui_Dialog
|
||||
|
||||
from config import Config
|
||||
from model import Settings, Tracks
|
||||
from model import Playdates, Playlists, Settings, Tracks
|
||||
|
||||
|
||||
class Music:
|
||||
@ -106,6 +106,7 @@ class Music:
|
||||
self.previous_track = self.current_track
|
||||
self.current_track = self.next_track
|
||||
self.current_track['player'].play()
|
||||
Playdates.add_playdate(self.current_track['meta'])
|
||||
|
||||
# Tidy up
|
||||
self.next_track = {
|
||||
@ -158,6 +159,11 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
if record.f_int is not None:
|
||||
self.playlist.setColumnWidth(column, record.f_int)
|
||||
|
||||
# Load playlist
|
||||
db_playlist = Playlists.get_only_playlist()
|
||||
for track in db_playlist.get_tracks():
|
||||
self.add_to_playlist(track)
|
||||
|
||||
self.timer.start(Config.TIMER_MS)
|
||||
|
||||
def __del__(self):
|
||||
@ -369,6 +375,12 @@ class DbDialog(QDialog):
|
||||
def listdclick(self, entry):
|
||||
track_id = entry.data(Qt.UserRole)
|
||||
track = Tracks.track_from_id(track_id)
|
||||
|
||||
# Store in current playlist in database
|
||||
db_playlist = Playlists.get_only_playlist()
|
||||
db_playlist.add_track(track)
|
||||
|
||||
# Add to on-screen playlist
|
||||
self.parent().add_to_playlist(track)
|
||||
|
||||
|
||||
@ -384,8 +396,8 @@ def ms_to_mmss(ms, decimals=0, negative=False):
|
||||
|
||||
minutes, remainder = divmod(ms, 60 * 1000)
|
||||
seconds = remainder / 1000
|
||||
if seconds == 60:
|
||||
print(f"ms_to_mmss({ms}) gave 60 seconds")
|
||||
if int(seconds) == 60:
|
||||
DEBUG(f"ms_to_mmss({ms}) gave 60 seconds")
|
||||
|
||||
return f"{sign}{minutes:.0f}:{seconds:02.{decimals}f}"
|
||||
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
"""Add playlist and playtimes
|
||||
|
||||
Revision ID: f07b96a5e60f
|
||||
Revises: b0983648595e
|
||||
Create Date: 2021-03-27 19:53:09.524989
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f07b96a5e60f'
|
||||
down_revision = 'b0983648595e'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('playdates',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('lastplayed', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_playdates_lastplayed'), 'playdates', ['lastplayed'], unique=False)
|
||||
op.create_table('playlists',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('name', sa.String(length=32), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('name')
|
||||
)
|
||||
op.create_table('playlistracks',
|
||||
sa.Column('playlist_id', sa.Integer(), nullable=True),
|
||||
sa.Column('track_id', sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['playlist_id'], ['playlists.id'], ),
|
||||
sa.ForeignKeyConstraint(['track_id'], ['tracks.id'], )
|
||||
)
|
||||
op.add_column('tracks', sa.Column('playdates_id', sa.Integer(), nullable=True))
|
||||
op.create_foreign_key(None, 'tracks', 'playdates', ['playdates_id'], ['id'])
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'tracks', type_='foreignkey')
|
||||
op.drop_column('tracks', 'playdates_id')
|
||||
op.drop_table('playlistracks')
|
||||
op.drop_table('playlists')
|
||||
op.drop_index(op.f('ix_playdates_lastplayed'), table_name='playdates')
|
||||
op.drop_table('playdates')
|
||||
# ### end Alembic commands ###
|
||||
Loading…
Reference in New Issue
Block a user