Commit 624a2c39 authored by David Trattnig's avatar David Trattnig
Browse files

Improved model. #50

parent 718a29a4
......@@ -117,7 +117,7 @@ class FallbackManager:
fallback_type = None
if self.validate_playlist(timeslot, "playlist"):
planned_playlist = timeslot.get_playlist()
planned_playlist = timeslot.playlist
fallback_type = FallbackType.NONE
else:
(fallback_type, planned_playlist) = self.get_fallback_playlist(timeslot)
......@@ -134,16 +134,16 @@ class FallbackManager:
timeslot (Timeslot)
Returns:
(Playlist)
(Playlist)
"""
playlist = None
fallback_type = FallbackType.STATION
if self.validate_playlist(timeslot, "schedule_fallback"):
playlist = timeslot.schedule_fallback[0]
playlist = timeslot.schedule_fallback
fallback_type = FallbackType.SCHEDULE
elif self.validate_playlist(timeslot, "show_fallback"):
playlist = timeslot.show_fallback[0]
playlist = timeslot.show_fallback
fallback_type = FallbackType.SHOW
return (fallback_type, playlist)
......@@ -168,18 +168,17 @@ class FallbackManager:
"""
playlist = getattr(timeslot, playlist_type)
if playlist \
and isinstance(playlist, list) \
and playlist[0].entries \
and len(playlist[0].entries) > 0:
and playlist.entries \
and len(playlist.entries) > 0:
# Default playlist
if playlist_type == "playlist":
return True
# Fallback playlist
elif playlist[0].entries:
elif playlist.entries:
is_fs_only = True
for entry in playlist[0].entries:
for entry in playlist.entries:
if entry.get_content_type() not in ResourceClass.FILE.types:
self.logger.error(SU.red("Fallback playlist of type '%s' contains not only file-system entries! \
Skipping fallback level..." % playlist_type))
......
......@@ -24,9 +24,9 @@ import datetime
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import BigInteger, Boolean, Column, DateTime, Integer, String, ForeignKey, ColumnDefault
from sqlalchemy import orm
from sqlalchemy import BigInteger, Boolean, Column, DateTime, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.ext.hybrid import hybrid_property
......@@ -103,18 +103,9 @@ class AuraDatabaseModel():
def recreate_db(systemexit = False):
"""
Re-creates the database for developments purposes.
"""
manualtimeslot = Timeslot()
manualtimeslot.timeslot_id = 0
manualtimeslot.show_name = "Manual Show"
"""
Base.metadata.drop_all()
Base.metadata.create_all()
# self.logger.debug("inserting manual scheduling possibility and fallback trackservice timeslot")
# DB.session.add(manualtimeslot)
# db.session.add(fallback_trackservice_timeslot)
# self.logger.debug("all created. commiting...")
DB.session.commit()
if systemexit:
......@@ -123,20 +114,43 @@ class AuraDatabaseModel():
#
# SCHEDULES & PLAYLISTS
# TIMESLOT
#
class Timeslot(DB.Model, AuraDatabaseModel):
"""
One specific Timeslot for a show on a timeslot.
Holding references to playlists and fallback-playlists.
One specific timeslot for a show.
"""
__tablename__ = 'timeslot'
# Primary keys
id = Column(Integer, primary_key=True, autoincrement=True)
# Relationships
playlist = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, \
Timeslot.playlist_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
uselist=False, back_populates="timeslot")
schedule_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, \
Timeslot.schedule_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
uselist=False, back_populates="timeslot")
show_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, \
Timeslot.show_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
uselist=False, back_populates="timeslot")
station_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, \
Timeslot.station_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
uselist=False, back_populates="timeslot")
playlist_id = Column(Integer)
schedule_fallback_id = Column(Integer)
show_fallback_id = Column(Integer)
station_fallback_id = Column(Integer)
# Data
timeslot_start = Column(DateTime, unique=True, index=True)
timeslot_end = Column(DateTime, unique=True, index=True)
timeslot_id = Column(Integer, unique=True)
......@@ -151,29 +165,10 @@ class Timeslot(DB.Model, AuraDatabaseModel):
category = Column(String(256))
topic = Column(String(256))
musicfocus = Column(String(256))
is_repetition = Column(Boolean())
playlist_id = Column(Integer) #, ForeignKey("playlist.playlist_id"))
schedule_fallback_id = Column(Integer)
show_fallback_id = Column(Integer)
station_fallback_id = Column(Integer)
fadeouttimer = None # Used to fade-out the timeslot, even when entries are longer
playlist = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, Timeslot.playlist_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
back_populates="timeslot")
schedule_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, Timeslot.schedule_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
back_populates="timeslot")
show_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, Timeslot.show_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
back_populates="timeslot")
station_fallback = relationship("Playlist",
primaryjoin="and_(Timeslot.timeslot_start==Playlist.timeslot_start, Timeslot.station_fallback_id==Playlist.playlist_id, Timeslot.show_name==Playlist.show_name)",
back_populates="timeslot")
@staticmethod
def select_show_on_datetime(date_time):
......@@ -213,16 +208,6 @@ class Timeslot(DB.Model, AuraDatabaseModel):
return timeslots
def get_playlist(self):
"""
Returns the assigned playlist.
"""
# TODO Refactor to avoid storing array of playlists.
if self.playlist and self.playlist[0]:
return self.playlist[0]
return None
def has_queued_entries(self):
"""
Checks if entries of this timeslot have been queued at the engine.
......@@ -291,6 +276,9 @@ class Timeslot(DB.Model, AuraDatabaseModel):
return "ID#%s [Show: %s, ShowID: %s | %s - %s ]" % (str(self.timeslot_id), self.show_name, str(self.show_id), time_start, time_end)
#
# PLAYLIST
#
class Playlist(DB.Model, AuraDatabaseModel):
"""
......@@ -298,14 +286,16 @@ class Playlist(DB.Model, AuraDatabaseModel):
"""
__tablename__ = 'playlist'
# pk,fk
# Primary and Foreign Key
artificial_id = Column(Integer, primary_key=True)
timeslot_start = Column(DateTime, ForeignKey("timeslot.timeslot_start"))
# relationships
# Relationships
timeslot = relationship("Timeslot", uselist=False, back_populates="playlist")
entries = relationship("PlaylistEntry", back_populates="playlist")
# data
playlist_id = Column(Integer, autoincrement=False) # , ForeignKey("timeslot.playlist_id"))
# Data
playlist_id = Column(Integer, autoincrement=False)
show_name = Column(String(256))
entry_count = Column(Integer)
......@@ -434,6 +424,9 @@ class Playlist(DB.Model, AuraDatabaseModel):
return "ID#%s [items: %s | %s - %s]" % (str(self.playlist_id), str(self.entry_count), str(time_start), str(time_end))
#
# PLAYLIST ENTRY
#
class PlaylistEntry(DB.Model, AuraDatabaseModel):
"""
......@@ -441,29 +434,30 @@ class PlaylistEntry(DB.Model, AuraDatabaseModel):
"""
__tablename__ = 'playlist_entry'
# primary keys
# Primary and Foreign Keys
artificial_id = Column(Integer, primary_key=True)
# foreign keys
artificial_playlist_id = Column(Integer, ForeignKey("playlist.artificial_id"))
entry_num = Column(Integer) # , primary_key=True)
# Relationships
playlist = relationship("Playlist", uselist=False, back_populates="entries")
meta_data = relationship("PlaylistEntryMetaData", uselist=False, back_populates="entry")
# Data
entry_num = Column(Integer)
uri = Column(String(1024))
duration = Column(BigInteger)
volume = Column(Integer, ColumnDefault(100))
source = Column(String(1024))
entry_start = Column(DateTime)
entry_start_actual = None # Assigned when the entry is actually played
channel = None # Assigned when entry is actually played
queue_state = None # Assigned when entry is about to be queued
status = None # Assigned when state changes
switchtimer = None
loadtimer = None
fadeouttimer = None
# relationships
playlist = relationship("Playlist", uselist=False, back_populates="entries")
meta_data = relationship("PlaylistEntryMetaData", uselist=False, back_populates="entry")
@staticmethod
def select_playlistentry_for_playlist(artificial_playlist_id, entry_num):
......@@ -503,9 +497,6 @@ class PlaylistEntry(DB.Model, AuraDatabaseModel):
def end_unix(self):
return time.mktime(self.entry_end.timetuple())
@hybrid_property
def volume(self):
return 100 # FIXME Make DB Column
def get_content_type(self):
return ResourceUtil.get_content_type(self.uri)
......@@ -572,22 +563,29 @@ class PlaylistEntry(DB.Model, AuraDatabaseModel):
#
# PLAYLIST ENTRY METADATA
#
class PlaylistEntryMetaData(DB.Model, AuraDatabaseModel):
"""
Metadata for a playlist entry such as the artist and track name.
Metadata for a playlist entry such as the artist, album and track name.
"""
__tablename__ = "playlist_entry_metadata"
# Primary and Foreign Keys
artificial_id = Column(Integer, primary_key=True)
artificial_entry_id = Column(Integer, ForeignKey("playlist_entry.artificial_id"))
# Relationships
entry = relationship("PlaylistEntry", uselist=False, back_populates="meta_data")
# Data
artist = Column(String(256))
title = Column(String(256))
album = Column(String(256))
entry = relationship("PlaylistEntry", uselist=False, back_populates="meta_data")
@staticmethod
def select_metadata_for_entry(artificial_playlistentry_id):
return DB.session.query(PlaylistEntryMetaData).filter(PlaylistEntryMetaData.artificial_entry_id == artificial_playlistentry_id).first()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment