diff --git a/software/webradio.py b/software/webradio.py index fa43917..e04e45c 100755 --- a/software/webradio.py +++ b/software/webradio.py @@ -6,6 +6,8 @@ from mpd import MPDClient import spidev import math import traceback +from aiohttp import web +import datetime IO_DELAY = (1.0 / 18.0) MPD_DELAY = 0.5 @@ -15,6 +17,8 @@ IO_SPEED = 50000 LIVE_SELECT = 160 LIVE_VOLUME = 40 +LIKE_FILE = "/var/db/wr_likes" + class display(object): def __init__(self): self.fg = 1 @@ -210,6 +214,34 @@ class display_manager(object): # TODO: Consider also animating inactive screens... Might resolve some glitches when updating text while a screen is in the background (or pass `tick` to update funcs) class radioserv: + def load_liked(self): + try: + f = open(LIKE_FILE, "r") + text = f.read() + if text != "": + self.liked = text.split("\n"); + else: + self.liked = [] + f.close(); + except: + self.liked = [] + + def like_song(self): + self.liked.append("[{}] {}".format(datetime.datetime.now(), self.get_formatted_title())) + self.disp_info.update_text("♥", True) + self.disp_info.update_info("Liked song.") + self.disp_mgr.set_display(self.disp_info, LIVE_VOLUME) + self.sync_liked() + + def unlike_song(self, id): + self.liked.pop(id) + self.sync_liked() + + def sync_liked(self): + f = open(LIKE_FILE, "w") + f.write("\n".join(self.liked)) + f.close() + def handle_volume(self, rotary_delta, bat): if (rotary_delta != 0): nvol = int(self.status['volume']) + (rotary_delta * 4) @@ -243,6 +275,20 @@ class radioserv: self.disp_select.set_entries(entries, True) self.disp_mgr.set_display(self.disp_select, LIVE_SELECT) + def get_formatted_title(self): + try: + title = self.currentsong['title'] + try: + title += " by " + self.currentsong['artist'] + except: + pass + except: + try: + title = self.currentsong['file'] + except: + title = " " + return title + def handle_rx(self, rdata): # Handle battery voltage bat = int((int(rdata[2]) - 175) / 45 * 100) @@ -266,8 +312,7 @@ class radioserv: if (self.disp_mgr.current_display == self.disp_playback): if (key_press_short): if (key_id == 0): # Tune- - print(self.status) # TODO: Only for testing purposes. This key is still free! - print(self.currentsong) + self.like_song() elif (key_id == 1): # Tune+ self.mpd.previous() elif (key_id == 2): # Power @@ -369,17 +414,7 @@ class radioserv: self.currentsong = currentsong # Song title - try: - title = currentsong['title'] - try: - title += " by " + currentsong['artist'] - except: - pass - except: - try: - title = currentsong['file']; - except: - title = " " + title = self.get_formatted_title() if (title != last_title): self.disp_playback.update_text(title) last_title = title @@ -410,6 +445,48 @@ class radioserv: # Sadly I can't use mpd.idle() here await asyncio.sleep(MPD_DELAY) + async def webserver_main(self): + print("ws main") + routes = web.RouteTableDef() + @routes.get('/') + @routes.post('/') + async def hello(request): + data = await request.post() + if (len(data) > 0): + for key in data: + print(key[4:]) + self.unlike_song(int(key[4:])) + slist = "" + i = 0 + for entry in self.liked: + slist += '
  • {}
  • '.format(entry, i) + i += 1 + if slist == "": + slist = "There are no liked songs. Push the like-button to add them to the list." + text = """ + + + Web Radio: Liked Songs + + +

    Web Radio: Liked Songs

    +

    +

    + {} +
    +

    +

    + Refresh +

    + + + """.format(slist); + return web.Response(text=text, headers=({'CONTENT-TYPE': "text/html"})) + + app = web.Application() + app.add_routes(routes) + await web._run_app(app, host="*", port=80) + async def main(self): # Connect to SPI self.spi = spidev.SpiDev() @@ -457,6 +534,7 @@ class radioserv: io_task = asyncio.create_task(self.io_main()) io_timer_task = asyncio.create_task(self.io_timer_main()) mpd_task = asyncio.create_task(self.mpd_main()) + ws_task = asyncio.create_task(self.webserver_main()) await self.kill_event.wait() self.kill_event.clear() @@ -475,13 +553,14 @@ class radioserv: self.mpd.disconnect() def __init__(self): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + self.load_liked() try: - loop.run_until_complete(self.main()) + self.loop.run_until_complete(self.main()) finally: - loop.run_until_complete(loop.shutdown_asyncgens()) - loop.close() + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + self.loop.close() r = radioserv()