-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.py
160 lines (132 loc) · 5.05 KB
/
controller.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import signal
import logging
import os
from PyQt4 import QtCore
import log
# TODO: read settings from a logging.ini, where, basing on classname, level,
# style (colored,format), propagate and stream (that is, file/output) can be
# changed on a fine-grained level
logger = log.ColoredLogger(__name__)
from player import QtPlayer
from bobina import Bobina, get_libraries, find_libraries
from event import EventMonitor
from command import TCPCommandSocket, HTTPCommandSocket, short_command
from config_manager import get_config
class Controller(QtCore.QObject):
'''all the main logic, without those boring details'''
# when a Event rings
event_occurred = QtCore.pyqtSignal()
song_finished = QtCore.pyqtSignal()
# just before exiting, to do some cleaning
closing = QtCore.pyqtSignal()
@log.cls_logger
def __init__(self):
QtCore.QObject.__init__(self)
self.log.debug("%s instantiating" % self.__class__.__name__)
self.player = QtPlayer()
self.audio_source = EventAggregator()
if get_config()['SOCKET_TCP']:
self.tcp_socket = TCPCommandSocket(
self, get_config()['SOCKET_TCP'])
if get_config()['SOCKET_HTTP']:
self.http_socket = HTTPCommandSocket(
self, get_config()['SOCKET_HTTP'])
self.player.empty.connect(self.on_empty)
def start(self):
self.on_empty()
def on_empty(self):
self.log.debug("Playlist empty, need to fill")
next_audio = self.audio_source.get_next()
# This keeps the reference to the current playing Bell;
# it's very important not to mess with this, because the __del__ method
# is used to automatically remove files from cache
self.current = next_audio
assert type(next_audio) is list
self.player.now_play_sequence(next_audio)
class EventAggregator(QtCore.QObject):
'''
EventManager knows what need to be played; it handles Bobina, listen to
events.
More abstractly, it's an Audio source that aggregates different Audio
sources
'''
@log.cls_logger
def __init__(self):
QtCore.QObject.__init__(self)
self.bobina = Bobina()
self.event_monitor = EventMonitor()
self.event_monitor.bell_now.connect(self.on_event)
self.last_event = None
self.paused = False
def on_event(self, ev):
self.log.info("Bell rang " + str(ev))
if not self.paused:
self.last_event = ev
else:
self.log.debug("Ignoring bell: we're in pause mode")
def get_next(self):
last = self.last_event
self.last_event = None
if last is None:
next_audio = [self.bobina.get_next()]
self.log.info("Next audio is %s, from Bobina" % next_audio[0])
else:
next_audio = last.audio
self.log.info("Next audio is %s, from Event %s" %
(next_audio, last))
return next_audio
def pause_events(self, value=None):
if value is None:
value = not self.paused
self.paused = value
@short_command("last_event")
def cmd_lastevent(controller, args):
return str(controller.audio_source.last_event)
@short_command("pause_events")
def cmd_pause_events(controller, args):
controller.audio_source.pause_events()
return str(controller.audio_source.paused)
class Tamarradio(QtCore.QCoreApplication):
started = QtCore.pyqtSignal()
@log.cls_logger
def __init__(self, *args):
self.args = args
QtCore.QCoreApplication.__init__(self, *args)
self.setApplicationName('tamarradio')
self.aboutToQuit.connect(self.pre_quit)
QtCore.QTimer.singleShot(1000, self, QtCore.SIGNAL('really_run()'))
QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL('start_app()'))
def pre_quit(self):
self.log.info("About to quit, cleaning up...")
for name in os.listdir(get_config()['CACHE_DIR']):
if name.endswith('.wav'):
os.unlink(os.path.join(get_config()['CACHE_DIR'], name))
_c = None
def main():
global _c
_c = Controller()
app.connect(app, QtCore.SIGNAL('really_run()'), _c.start)
def parse_options(args):
# TODO: move to argparse
opts = {'config': []}
if len(args) > 1:
opts['config'].append(args[1])
return opts
if __name__ == '__main__':
import sys
#logging.basicConfig(filename=None, level=logging.DEBUG)
opts = parse_options(sys.argv)
log.ColoredLogger.default_level = logging.DEBUG
logger.info('start')
app = Tamarradio(sys.argv)
app.connect(app, QtCore.SIGNAL('start_app()'), main)
get_config().from_pyfile("default_config.py")
get_config().from_pyfile("/etc/tamarradio/player.cfg", silent=True)
for configfile in opts['config']:
get_config().from_pyfile(configfile)
for d in get_config()['LIBRARIES_PATH']:
get_libraries().update(find_libraries(d))
signal.signal(signal.SIGINT, lambda *args: app.quit())
ret = app.exec_()
logger.info('end %d' % ret)
sys.exit(ret)