class WebApp: def __init__(self, logger, exc_cb): self.logger = logger self.comm = Comm(5009, "web_app", {}, self.logger, exc_cb) self.loop = asyncio.get_event_loop() app = web.Application() app.add_routes([web.get('/', self.main_menu), web.get('/stop', self.stop), web.get('/search', self.search), web.get('/get_search_result', self.get_search_result), web.get('/play', self.play), web.get('/radio', self.radio), web.get('/music', self.music_menu), web.get('/assets/apple-touch-icon.png', self.png)]) handler = app.make_handler() self.server = self.loop.create_server(handler, port=8080) self.loop.run_until_complete(self.server) async def png(self, request): headers = {'content-type': 'image/png'} return web.FileResponse('./web_app/assets/apple-touch-icon.png') async def main_menu(self, request): content = "" content += link("/music", "Music") content += button("radio", "'p1'", "P1") content += button("radio", "'p2'", "P2") content += button("radio", "'p3'", "P3") content += button("radio", "'24syv'", "24Syv") content += button("stop", "", "Stop") scripts = """ function radio(channel_name) { $.get("/radio", {channel:channel_name}); } function stop() { $.get("/stop"); } """ head = tag("head", minimal_head) script = tag("script", scripts) body = tag("body", content + script) html = tag("html", head + body) text = "<!DOCTYPE html>" + html peername = request.transport.get_extra_info('peername') print("peername:", peername) headers = {'content-type': 'text/html'} return web.Response(headers=headers, text=text) async def music_menu(self, request): peername = request.transport.get_extra_info('peername') content = "" content += link("/", "Main Menu") if peername[0] == '192.168.0.11': content += "<h2>Welcome rolf</h2><br>" content += button("play_list", "'metal'", "Rolf") elif peername[0] == '192.168.0.13': content += "<h2>Velkommen Karen</h2><br>" content += button("play_list", "'svensk'", "Ulf Lundell & Bo Kasper") content += button("stop", "", "Stop") content += "<input name=\"title\" id=\"filter\" />\n" content += button("play", "", "Play") content += "<ol id=\"fruits\"></ol>\n" scripts = "session_id ={session_id};".format(session_id = '"' + str(uuid.uuid4()) +'"') scripts += """ function play_list(playlist_name) { $.get("/play", {source:"list", query:playlist_name}); } function stop() { $.get("/stop"); } function play() { var title = document.getElementById('filter').value $.get("/play", {source:"collection", title:title}); } polling = 0 $('#filter').keyup(function() { var query = document.getElementById('filter').value; $.get("/search", {title:query, session_id:session_id}, function(data0, status){ //var n_res = JSON.parse(data0); if (!polling) { polling = 1; setTimeout(poll, 50); } }); }); function poll() { $.get("/get_search_result", {session_id:session_id}, function(data, status){ polling = 0; document.getElementById("fruits").innerHTML = ""; try { var songs = JSON.parse(data); } catch(e) { console.log("bad json"); console.log(data) return; } if (songs.status == "available") { for (var key in songs.result) { var linode = document.createElement("LI"); var divnode = document.createElement("DIV"); var textnode = document.createTextNode(songs.result[key]["artist"] + " - " + songs.result[key]["title"]); linode.appendChild(divnode); divnode.appendChild(textnode); divnode.setAttribute("title", key); document.getElementById("fruits").appendChild(linode); } } else if (songs.status == "in_progress") { polling = 1; setTimeout(poll, 50); } }).fail(function(jq){ console.log("failure"); console.log(jq.responseText); console.log(jq.status); }); }; """ head = tag("head", minimal_head) script = tag("script", scripts) body = tag("body", content + script) html = tag("html", head + body) text = "<!DOCTYPE html>" + html headers = {'content-type': 'text/html'} return web.Response(headers=headers, text=text) async def stop(self, request): res = self.comm.call("music_server", "stop", {}) res = self.comm.call("stream_receiver", "off", {}) res = self.comm.call("led", "set", {"anim": ["off"]}) headers = {'content-type': 'text/html'} return web.Response(headers=headers, status=res[0], text=res[1]) async def radio(self, request): print("calling radio!") args = multi_dict_to_dict_of_lists(request.rel_url.query) res = self.comm.call("music_server", "stop", {}) res = self.comm.call("stream_receiver", "radio", args) res = self.comm.call("led", "set", {"anim": ["tu"]}) headers = {'content-type': 'text/html'} return web.Response(headers=headers, status=res[0], text=res[1]) async def play(self, request): args = multi_dict_to_dict_of_lists(request.rel_url.query) res = self.comm.call("music_server", "play", args) res = self.comm.call("stream_receiver", "multicast", {}) res = self.comm.call("led", "set", {"anim": ["mp"]}) headers = {'content-type': 'text/html'} return web.Response(headers=headers, status=res[0], text=res[1]) async def search(self, request): args = multi_dict_to_dict_of_lists(request.rel_url.query) res = self.comm.call("music_server", "search", args) headers = {'content-type': 'text/html'} return web.Response(headers=headers, status=res[0], text=res[1]) async def get_search_result(self, request): args = multi_dict_to_dict_of_lists(request.rel_url.query) res = self.comm.call("music_server", "get_search_result", args) headers = {'content-type': 'text/html'} return web.Response(headers=headers, status=res[0], text=res[1]) def shut_down(self): print("begin stopping") self.comm.shut_down() print("done stopping")
class PingServer(): def __init__(self, logger, exc_cb): self.logger = logger ip_list = self.load_obj("ip_list") alarms = self.load_obj("alarms") self.comm = Comm(5002, "ping_server", { "status": self.status, "log": self.log, "reset": self.reset }, self.logger, exc_cb) self.ping_thread = PingThread(60, None) for ip in ip_list: self.ping_thread.add_ip(ip["name"], ip["ip"]) for a in alarms: if a["type"] == "timeofday": self.ping_thread.add_alarm_timeofday( a["user"], lambda alarm: self.alarm_received(alarm, a["to"]), a["start"], a["end"], a["weekdays"]) elif a["type"] == "dayamount": self.ping_thread.add_alarm_dayamount( a["user"], lambda alarm: self.alarm_received(alarm, a["to"]), a["amount"], a["weekdays"]) elif a["type"] == "onoffline": self.ping_thread.add_alarm_onoffline( a["user"], lambda alarm: self.alarm_received(alarm, a["to"]), a["onoff"], a["weekdays"]) def alarm_received(self, alarm, to): res = self.comm.call("sms_portal", "send_sms", { "text": [alarm], "to": [to] }) print("send sms results: '%s'" % (res, )) print("PingServer::alarm_received: %s " % alarm) def load_obj(self, name): with open(os.path.join(home_server_config, name + '.json'), 'rb') as f: return json.load(f) #http://127.0.0.1:5002/status def status(self, params): status = self.ping_thread.get_status() return (200, status) def log(self, params): if "user" not in params: return (404, "function 'log' requires 'user'") user = params["user"][0] log = self.ping_thread.m_get_log(user) return (200, log) def reset(self, params): self.ping_thread.reset_alarms() return (200, "reset ok") def shut_down(self): self.ping_thread.shut_down() self.comm.shut_down()
class Radio(): def __init__(self, logger, exc_cb, inputter): self.logger = logger self.comm = Comm(5000, "buttons", {}, self.logger, exc_cb) self.inputter = inputter self.menu_linger_time = 5.0 self.main_menu = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.go_to_playlist_menu()), KeyPress.compile(".B.b<match>", match=lambda: self.multicast_play({ "artist": ["bryan adams"], "title": ["summer of 69"] })), KeyPress.compile(".C.c<match>", match=lambda: self.go_to_radio_menu()), KeyPress.compile(".D.d<match>", match=lambda: self.multicast_play({ "artist": ["volbeat"], "title": ["for evigt"] })), KeyPress.compile(".E.e<match>", match=lambda: self.apple_dock()), KeyPress.compile(".F.f<match>", match=lambda: self.go_to_podcast_menu()), KeyPress.compile(".H.h<match>", match=lambda: self.go_to_flow_menu()), ]) self.radio_menu = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.radio_channel("p1")), KeyPress.compile(".B.b<match>", match=lambda: self.radio_channel("p2")), KeyPress.compile(".C.c<match>", match=lambda: self.radio_channel("p3")), KeyPress.compile(".D.d<match>", match=lambda: self.radio_channel("24syv")), ]) self.podcast_menu = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.start_podcast("baelte")), KeyPress.compile(".B.b<match>", match=lambda: self.start_podcast("orientering")), KeyPress.compile(".C.c<match>", match=lambda: self.start_podcast("mads")), KeyPress.compile(".D.d<match>", match=lambda: self.start_podcast("d6m")), ]) self.flow_menu = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.flow({"to": ["0"]})), KeyPress.compile(".B.b<match>", match=lambda: self.flow({"prev": [1]})), KeyPress.compile(".C.c<match>", match=lambda: self.flow({"to": ["random"]})), KeyPress.compile(".D.d<match>", match=lambda: self.flow({"next": ["1"]})), KeyPress.compile(".E.e<match>", match=lambda: self.flow({"to": ["last"]})), KeyPress.compile(".H.h<match>", match=lambda: self.stop()), ]) self.playlist_menu = KeyPress.mkUnion([ KeyPress.compile( ".A.a<match>", match=lambda: self.go_to_users_playlist_menu("user_k")), KeyPress.compile( ".B.b<match>", match=lambda: self.go_to_users_playlist_menu("user_r")), KeyPress.compile( ".C.c<match>", match=lambda: self.go_to_users_playlist_menu("user_c")), KeyPress.compile( ".D.d<match>", match=lambda: self.go_to_users_playlist_menu("user_h")), KeyPress.compile( ".E.e<match>", match=lambda: self.go_to_users_playlist_menu("user_a")), KeyPress.compile( ".F.f<match>", match=lambda: self.go_to_users_playlist_menu("user_s")), ]) self.user_playlist_menu = {} self.user_playlist_menu["user_k"] = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.multicast_play({ "source": ["list"], "query": ["svensk"] })), ]) self.user_playlist_menu["user_r"] = KeyPress.mkUnion([ KeyPress.compile(".A.a<match>", match=lambda: self.multicast_play({ "source": ["list"], "query": ["metal"] })), KeyPress.compile( ".B.b<match>", match=lambda: self.multicast_play({"artist": ["metallica"]})), ]) self.user_playlist_menu["user_c"] = KeyPress.mkUnion([]) self.user_playlist_menu["user_h"] = KeyPress.mkUnion([]) self.user_playlist_menu["user_a"] = KeyPress.mkUnion([]) self.user_playlist_menu["user_s"] = KeyPress.mkUnion([]) print("==== press 'A' for playlists") print("==== press 'B' for youtube play") print("==== press 'C' for radio") print("==== press 'D' for Volbeat - For Evigt") print("==== press 'E' for Knight Rider") print("==== press 'F' for Pod cast") print("==== press 'H' for Flow control") print("==== press 'q' to quit") self.go_to_main_menu() self.inputter.click_NAD_button(3) def go_to_main_menu(self): print("going to main menu...") self.inputter.set_key_press(KeyPress(self.main_menu)) self.startup_timer = None def go_to_playlist_menu(self): res = self.comm.call("led", "set", {"anim": ["playlist_menu"]}) res = self.comm.call("stream_receiver", "multicast", {}) self.inputter.set_key_press(KeyPress(self.playlist_menu)) self.startup_timer = threading.Timer(self.menu_linger_time, self.leave_submenu) self.startup_timer.start() def go_to_radio_menu(self): res = self.comm.call("led", "set", {"anim": ["tu"]}) res = self.comm.call("led", "set", {"anim": ["radio_menu"]}) res = self.comm.call("stream_receiver", "radio", {}) self.inputter.set_key_press(KeyPress(self.radio_menu)) self.startup_timer = threading.Timer(self.menu_linger_time, self.leave_submenu) self.startup_timer.start() def go_to_podcast_menu(self): res = self.comm.call("led", "set", {"anim": ["podcast_menu"]}) res = self.comm.call("music_server", "podcast", {}) res = self.comm.call("stream_receiver", "multicast", {}) self.inputter.set_key_press(KeyPress(self.podcast_menu)) self.startup_timer = threading.Timer(self.menu_linger_time, self.leave_submenu) self.startup_timer.start() def go_to_flow_menu(self): res = self.comm.call("led", "set", {"anim": ["flow_menu"]}) self.inputter.set_key_press(KeyPress(self.flow_menu)) self.startup_timer = threading.Timer(self.menu_linger_time, self.leave_submenu) self.startup_timer.start() #--- def go_to_users_playlist_menu(self, user): res = self.comm.call("led", "set", {"anim": [user + "_menu"]}) self.inputter.set_key_press(KeyPress(self.user_playlist_menu[user])) if self.startup_timer != None: self.startup_timer.cancel() self.startup_timer = threading.Timer(self.menu_linger_time, self.leave_submenu) self.startup_timer.start() #--- def leave_submenu(self): if self.startup_timer != None: self.startup_timer.cancel() self.startup_timer = None res = self.comm.call("led", "set", {"anim": ["clear_submenu"]}) self.go_to_main_menu() def multicast_play(self, query): self.inputter.click_NAD_button(3) print("requesting '%s'" % query) res = self.comm.call("music_server", "play", query) print("res = %d %s" % res) res = self.comm.call("stream_receiver", "multicast", {}) res = self.comm.call("led", "set", {"anim": ["mp"]}) self.leave_submenu() def radio_channel(self, channel): self.inputter.click_NAD_button(3) res = self.comm.call("stream_receiver", "radio", {"channel": [channel]}) res = self.comm.call("led", "set", {"anim": ["tu"]}) self.leave_submenu() def start_podcast(self, program): self.inputter.click_NAD_button(3) res = self.comm.call("led", "set", {"anim": ["vi_wait"]}) print("requesting program '%s'" % program) res = self.comm.call("music_server", "podcast", {"program": [program]}) print("res = %d %s" % res) res = self.comm.call("stream_receiver", "multicast", {}) res = self.comm.call("led", "set", {"anim": ["vi"]}) self.leave_submenu() def flow(self, skip): res = self.comm.call("music_server", "skip", skip) self.leave_submenu() def stop(self): res = self.comm.call("music_server", "stop", {}) res = self.comm.call("stream_receiver", "off", {}) res = self.comm.call("led", "set", {"anim": ["off"]}) self.leave_submenu() def apple_dock(self): print("apple_dock") self.inputter.click_NAD_button(6) res = self.comm.call("led", "set", {"anim": ["au"]}) def knightrider(self): print("knightrider!") res = self.comm.call("led", "set", {"anim": ["knightrider"]}) def shut_down(self): if self.startup_timer != None: self.startup_timer.cancel() self.comm.shut_down() self.inputter.shut_down()