| 
					
				 | 
			
			
				@@ -1,39 +1,44 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #!./bin/python3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import os 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import yaml 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import pygame # type: ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from typing import Dict 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import random 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Color constants 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-BLACK = (0, 0, 0)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-GREEN = (0, 255, 0)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+BLACK = (0, 0, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GREEN = (0, 255, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+WHITE = (255, 255, 255) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Display: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Display object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, config, pydsp): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Set config values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._dx = config.get("dimx", 128) # Drawing dimensions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._dy = config.get("dimy", 160) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._playlistFile = config.get("playlist", "music.yml") # Playlist data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._pydsp = pydsp # Pygame display object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._fontsize = config.get("fontsize", 12) # Fontsize to use 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self._drawlines = int(self._dy / 12) - 1 # Max number of drawn lines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._drawlines = int(self._dy / 12) - 5 # Max number of drawn lines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Set initialisation values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._selection_pointer = 0 # Current selected value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._line_offset = 0 # Drawing offset in playlist 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._current_item = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._bgImg = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    def loadPlaylist(self) -> Dict: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def getPlaylist(self) -> Dict: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Load the playlist. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Return the playlist for this display. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return yaml.safe_load(open(self._playlistFile)).get("playlist", []) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -43,7 +48,7 @@ class Display: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Load the data from the given playlist file and draw it according to the current state. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._pydsp.fill((0,0,0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        playlist = self.loadPlaylist() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        playlist = self.getPlaylist() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Correct offset and selection pointer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -55,7 +60,7 @@ class Display: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self._selection_pointer = self._drawlines # Move the line offset up if possible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if self._line_offset < len(playlist) - self._drawlines - 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self._line_offset+=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Draw lines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         font = pygame.font.Font('freesansbold.ttf', self._fontsize) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -72,18 +77,57 @@ class Display: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if drawline == self._selection_pointer: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 text = font.render(item["name"], True, BLACK, GREEN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pygame.draw.rect(self._pydsp, BLACK, (0,0,self._dx,50)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.drawArt(item) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                except Exception as e: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    print("Error while drawing art:", e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self._current_item = item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 text = font.render(item["name"], True, GREEN, BLACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self._pydsp.blit(text, (0, drawline * self._fontsize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self._pydsp.blit(text, (0, drawline * self._fontsize+50)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # Increase number of drawn lines - stop when the maximum is reached 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             drawline += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if drawline > self._drawlines: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def drawArt(self, item): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Beautify the display. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font = pygame.font.Font('freesansbold.ttf', self._fontsize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Draw a background image 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self._bgImg is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bg = os.listdir("web/background") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bg = bg[random.randint(0, len(bg)-1)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self._bgImg = pygame.image.load(os.path.join("web/background", bg)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pygame.transform.scale(self._bgImg, (self._dx, 50)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._pydsp.blit(self._bgImg, (0,0), (0, 0, self._dx, 50)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        path = item.get("path") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        title = item.get("name", "") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        artist = item.get("artist", "") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Try to extract meta data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if path is not None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        s = title 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if artist != "": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            s = "%s (%s)" % (s, artist) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        text = font.render(s, True, WHITE, BLACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._pydsp.blit(text, (0, 38)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def currentItem(self) -> Dict: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ''' 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -100,5 +144,5 @@ class Display: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self._selection_pointer-=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         elif action == "down": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self._selection_pointer+=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.update() 
			 |