broadcasts.py 12.4 KB
Newer Older
1
__author__ = 'gg'
2
3
# -*- coding: utf-8 -*-

4
import sys
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
5
import time
6
7
import logging
import datetime
8

9
from sqlalchemy import orm, func, Boolean, Column, DateTime, Integer, String, ForeignKey, ForeignKeyConstraint
10
from sqlalchemy.orm import relationship
11
from sqlalchemy.sql.expression import false, true
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
12
from libraries.database.database import DB
13
from libraries.enum.scheduleentrytype import ScheduleEntryType
14

15

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
16
class AuraDatabaseModel:
17
18
19
20
21
    logger = None

    def __init__(self):
        self.logger = logging.getLogger("AuraEngine")

22
23
    def store(self, add=False, commit=False):
        if add:
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
24
            DB.session.add(self)
25
        if commit:
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
26
            DB.session.commit()
27
28

    def delete(self, commit=False):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
29
        DB.session.delete(self)
30
31
32
33
#        current_db_sessions = DB.session.object_session(self)
#        current_db_sessions.delete(self)
#        return
#        DB.session.delete(self)
34
        if commit:
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
35
            DB.session.commit()
36

37
38
    def _asdict(self):
        return self.__dict__
39

40
41
    @staticmethod
    def recreate_db(systemexit = False):
42
43
        manualschedule = Schedule()
        manualschedule.schedule_id = 0
44
        manualschedule.show_name = "Manual Show"
45

46
#        self.logger.debug("Recreating Database...")
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
47
        DB.drop_all()
48
#        self.logger.debug("all dropped. creating...")
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
49
        DB.create_all()
50
#        self.logger.debug("inserting manual scheduling possibility and fallback trackservice schedule")
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
51
        DB.session.add(manualschedule)
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
52
#        db.session.add(fallback_trackservice_schedule)
53
#        self.logger.debug("all created. commiting...")
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
54
        DB.session.commit()
55
#        self.logger.debug("Database recreated!")
56

57
58
        if systemexit:
            sys.exit(0)
59

60

61
# ------------------------------------------------------------------------------------------ #
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
62
class Schedule(DB.Model, AuraDatabaseModel):
63
    """
64
    One specific Schedule for a show on a timeslot
65
    """
66
    __tablename__ = 'schedule'
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
67
68

    # primary and foreign keys
69
    schedule_id = Column(Integer, primary_key=True, autoincrement=False)
70
    show_id = Column(Integer) # well, in fact not needed..
71

72
73
    schedule_start = Column(DateTime) # can be null due to manual entries
    schedule_end = Column(DateTime) # can be null due to manual entries
74
75
    show_name = Column(String(256))
    show_hosts = Column(String(256))
76
    funding_category = Column(String(256))
77
78
79
80
81
82
    comment = Column(String(512))
    languages = Column(String(256))
    type = Column(String(256))
    category = Column(String(256))
    topic = Column(String(256))
    musicfocus = Column(String(256))
83
84
85

    is_repetition = Column(Boolean())

86
87
88
89
90
    playlist_id = Column(Integer)
    timeslot_fallback_id = Column(Integer)
    show_fallback_id = Column(Integer)
    station_fallback_id = Column(Integer)

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
91
92
93
94
95
96
97
98
99
100
101
    @staticmethod
    def select_all():
        # fetching all entries
        all_entries = DB.session.query(Schedule).filter().order_by(Schedule.schedule_start).all()
        return all_entries

    @staticmethod
    def select_by_id(id):
        entry = DB.session.query(Schedule).filter(Schedule.schedule_id == id).first()
        return entry

102
103
104
105
106
107
    def get_length(self):
        sec1 = int(datetime.datetime.strptime(self.start[0:16].replace(" ", "T"), "%Y-%m-%dT%H:%M").strftime("%s"))
        sec2 = int(datetime.datetime.strptime(self.end[0:16].replace(" ", "T"), "%Y-%m-%dT%H:%M").strftime("%s"))
        len = sec2 - sec1
        return len

108

109
# ------------------------------------------------------------------------------------------ #
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
110
class ScheduleEntry(DB.Model, AuraDatabaseModel):
111
    """
112
    One schedule can have multiple entries
113
    """
114
115
    __tablename__ = 'schedule_entry'

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
116
    # primary and foreign keys
117
118
119
    playlist_id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
    entry_num = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
    schedule_id = Column(Integer, ForeignKey("schedule.schedule_id"))
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
120

121
    entry_start = Column(DateTime)
122
    source = Column(String(256))
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
123
    volume = Column(Integer, default=100)
124
    fallback_type = Column(Integer, default=0)
125
    cleansource = ""
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
126
    entry_start_unix = 0
127
    programme_index = -1
128
    type = None
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
129

130
    schedule = relationship("Schedule", foreign_keys=[schedule_id], lazy="joined")
131

132
    # normal constructor
133
134
    def __init__(self, **kwargs):
        super(ScheduleEntry, self).__init__(**kwargs)
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
135
        self.calc_unix_times()
136

137
    # constructor like - called from sqlalchemy
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
138
    @orm.reconstructor
139
140
141
142
    def reconstructor(self):
        self.calc_unix_times()
        self.set_entry_type()

143
144
145
146
147
148
149
150
    def define_clean_source(self):
        if self.source.startswith("http") or self.source.startswith("live") or self.source.startswith("linein"):
            self.cleansource = self.source
        if self.source.startswith("pool") or self.source.startswith("file"):
            self.cleansource = self.source[7:]
        if self.source.startswith("playlist"):
            self.cleansource = self.source[11:]

151
    def calc_unix_times(self):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
152
153
        if self.entry_start is not None:
            self.entry_start_unix = time.mktime(self.entry_start.timetuple())
154

155
156
    def set_entry_type(self):
        if self.source.startswith("http"):
157
158
159
160
161
            self.type = ScheduleEntryType.STREAM
        if self.source.startswith("pool") or self.source.startswith("playlist") or self.source.startswith("file"):
            self.type = ScheduleEntryType.FILESYSTEM
        if self.source.startswith("live") or self.source.startswith("linein"):
            self.type = ScheduleEntryType.LIVE
162

163
164
165
    # ------------------------------------------------------------------------------------------ #
    @staticmethod
    def select_all():
166
        # fetching all entries
167
        all_entries = DB.session.query(ScheduleEntry).filter(ScheduleEntry.fallback_type == 0).order_by(ScheduleEntry.entry_start).all()
168
169
170
171
172
173
174
175

        cnt = 0
        for entry in all_entries:
            entry.programme_index = cnt
            cnt = cnt + 1

        return all_entries

176
177
178
179
180
181
182
183
184
185
    # ------------------------------------------------------------------------------------------ #
    @staticmethod
    def truncate():
        all_entries = DB.session.query(ScheduleEntry).filter().order_by(ScheduleEntry.entry_start).all()

        for a in all_entries:
            a.delete()
        DB.session.commit()

    # ------------------------------------------------------------------------------------------ #
186
187
188
    @staticmethod
    def select_next_manual_entry_num():

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
189
        max_manual_entry_num = DB.session.query(func.max(ScheduleEntry.entry_num)).filter(ScheduleEntry.schedule_id == 0).first()
190
191
192
193
194
195
196
197
198

        if max_manual_entry_num[0] is None:
            return 0
        else:
            return int(max_manual_entry_num[0])+1

    # ------------------------------------------------------------------------------------------ #
    @staticmethod
    def upcoming(datefrom=datetime.datetime.now()):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
199
        upcomingtracks = DB.session.query(ScheduleEntry).filter(ScheduleEntry.start > datefrom).all()
200
201
202
203
204
        return upcomingtracks

    # ------------------------------------------------------------------------------------------ #
    @staticmethod
    def select_one(playlist_id, entry_num):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
205
        return DB.session.query(ScheduleEntry).filter(ScheduleEntry.playlist_id == playlist_id, ScheduleEntry.entry_num == entry_num).first()
206

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
207
208
209
210
211
    # ------------------------------------------------------------------------------------------ #
    @staticmethod
    def select_playlist(playlist_id):
        return DB.session.query(ScheduleEntry).filter(ScheduleEntry.playlist_id == playlist_id).all()

212
213
    # ------------------------------------------------------------------------------------------ #
    def __str__(self):
214
        return "ScheduleID: #" + str(self.schedule_id) + " Showname: " + self.schedule.show_name + " starts @ " + str(self.entry_start) + " and plays " + self.source
215

216

217
# ------------------------------------------------------------------------------------------ #
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
218
class TrackService(DB.Model, AuraDatabaseModel):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
219
    __tablename__ = 'trackservice'
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
220

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
221
222
223
    trackservice_id = Column(Integer, primary_key=True, autoincrement=True)
    playlist_id = Column(Integer, nullable=False)
    entry_num = Column(Integer, nullable=False)
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
224

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
225
    source = Column(String(255), nullable=False)
226
    start = Column(DateTime, nullable=False, default=func.now())
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
227

228
229
230
    __table_args__ = (
        ForeignKeyConstraint(['playlist_id', 'entry_num'], ['schedule_entry.playlist_id', 'schedule_entry.entry_num']),
    )
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
231

232
    #schedule = relationship("Schedule", foreign_keys=[schedule_id], lazy="joined")
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
233
234
    # trackservice_entry = relationship("ScheduleEntry", foreign_keys=[playlist_id, entry_num], lazy="joined")
    schedule_entry = relationship("ScheduleEntry", primaryjoin="and_(TrackService.playlist_id==ScheduleEntry.playlist_id, TrackService.entry_num==ScheduleEntry.entry_num)", lazy="joined")
235

236
    @staticmethod
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
237
    # ------------------------------------------------------------------------------------------ #
238
    def select_one(trackservice_id):
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
239
        return DB.session.query(TrackService).filter(TrackService.trackservice_id == trackservice_id).first()
240

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
241
242
243
244
245
246
247
    @staticmethod
    # ------------------------------------------------------------------------------------------ #
    def select_by_day(day):
        day_plus_one = day + datetime.timedelta(days=1)
        tracks = DB.session.query(TrackService).filter(TrackService.start >= str(day), TrackService.start < str(day_plus_one)).all()
        return tracks

248
249
250
251
252
253
254
    @staticmethod
    # ------------------------------------------------------------------------------------------ #
    def select_by_range(from_day, to_day):
        tracks = DB.session.query(TrackService).filter(TrackService.start >= str(from_day),
                                                       TrackService.start < str(to_day)).all()
        return tracks

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
255
256
257
258
    # ------------------------------------------------------------------------------------------ #
    def __str__(self):
        return "TrackServiceID: #" + str(self.trackservice_id) + " playlist_id: " + str(self.playlist_id) + " started @ " + str(self.start) + " and played " + self.source

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# ------------------------------------------------------------------------------------------ #
# class TrackServiceSchedule(db.Model, AuraDatabaseModel):
#     """
#     Trackservice is tracking every schedule.
#     """
#     __tablename__ = 'trackservice_schedule'
#
#     # primary and foreign keys
#     ts_schedule_id = Column(Integer, primary_key=True, autoincrement=True)
#     schedule_id = Column(Integer, ForeignKey("schedule.schedule_id"))
#
#     schedule = relationship("Schedule", foreign_keys=[schedule_id], lazy="joined")
#
#     # ------------------------------------------------------------------------------------------ #
#     @staticmethod
#     def select_one(schedule_id):
#         # damn BAND-AID
#         # db.session.commit()
#
#         return db.session.query(ScheduleEntry).filter(TrackServiceSchedule.schedule_id == schedule_id).first()
#
# # ------------------------------------------------------------------------------------------ #
# class TrackServiceScheduleEntry(db.Model, AuraDatabaseModel):
#     """
#     And a schedule can have multiple entries
#     """
#     __tablename__ = 'trackservice_entry'
#
#     # primary and foreign keys. the foreign keys here can be null, because of fallback stuff
#     ts_entry_id = Column(Integer, primary_key=True, autoincrement=True)
#     ts_schedule_id = Column(Integer, ForeignKey("trackservice_schedule.ts_schedule_id"), nullable=True)
#     playlist_id = Column(Integer, nullable=True)
#     entry_num = Column(Integer, nullable=True)
#
#     fallback = Column(Boolean, default=False)
#     fallback_start = Column(DateTime, nullable=True, default=None)
#     source = Column(String(256), nullable=True, default=None)
#
#     # foreign key definitions
#     __table_args__ = (
#         ForeignKeyConstraint(['playlist_id', 'entry_num'], ['schedule_entry.playlist_id', 'schedule_entry.entry_num']),
#     )
#
#     trackservice_schedule = relationship("TrackServiceSchedule", foreign_keys=[ts_schedule_id], lazy="joined")
#     #trackservice_entry = relationship("ScheduleEntry", foreign_keys=[playlist_id, entry_num], lazy="joined")
#     trackservice_entry = relationship("ScheduleEntry", primaryjoin="and_(TrackServiceScheduleEntry.playlist_id==ScheduleEntry.playlist_id, TrackServiceScheduleEntry.entry_num==ScheduleEntry.entry_num)" , lazy="joined")
#
#     @staticmethod
#     def select_all():
#         return db.session.query(TrackServiceScheduleEntry).filter().all()

310
#AuraDatabaseModel.recreate_db(systemexit=True)