| 
									
										
										
										
											2025-02-21 14:11:39 -05:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  | import json | 
					
						
							|  |  |  | import random | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  | from typing import Any, Optional, Annotated | 
					
						
							| 
									
										
										
										
											2025-07-01 11:38:38 -04:00
										 |  |  | from fastapi import FastAPI, Request, UploadFile, Response, HTTPException, Form, Depends | 
					
						
							|  |  |  | from fastapi_throttle import RateLimiter | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  | from fastapi.responses import JSONResponse | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  | import redis | 
					
						
							|  |  |  | from rq import Queue | 
					
						
							|  |  |  | from rq.registry import ( | 
					
						
							|  |  |  |     StartedJobRegistry, | 
					
						
							|  |  |  |     FinishedJobRegistry, | 
					
						
							|  |  |  |     FailedJobRegistry, | 
					
						
							| 
									
										
										
										
											2025-09-09 15:50:13 -04:00
										 |  |  |     DeferredJobRegistry, | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2025-01-24 09:10:54 -05:00
										 |  |  | from lyric_search.sources import private, cache as LyricsCache, redis_cache | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  | class Misc(FastAPI): | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Misc Endpoints | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, app: FastAPI, my_util, constants, radio) -> None: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         """Initialize Misc endpoints.""" | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  |         self.app: FastAPI = app | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |         self.util = my_util | 
					
						
							|  |  |  |         self.constants = constants | 
					
						
							|  |  |  |         self.lyr_cache = LyricsCache.Cache() | 
					
						
							| 
									
										
										
										
											2025-01-22 06:38:40 -05:00
										 |  |  |         self.redis_cache = redis_cache.RedisCache() | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |         self.redis_client: Any = redis.Redis(password=private.REDIS_PW) | 
					
						
							| 
									
										
										
										
											2025-02-11 08:41:29 -05:00
										 |  |  |         self.radio = radio | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |         self.activity_image: Optional[bytes] = None | 
					
						
							| 
									
										
										
										
											2025-05-01 15:55:43 -04:00
										 |  |  |         self.nos_json_path: str = os.path.join( | 
					
						
							| 
									
										
										
										
											2025-06-08 08:53:18 -04:00
										 |  |  |             "/", "usr", "local", "share", "naas", "reasons.json" | 
					
						
							| 
									
										
										
										
											2025-05-01 15:55:43 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |         self.nos: list[str] = [] | 
					
						
							|  |  |  |         self.last_5_nos: list[str] = [] | 
					
						
							| 
									
										
										
										
											2025-02-11 20:01:07 -05:00
										 |  |  |         self.endpoints: dict = { | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |             "widget/redis": self.homepage_redis_widget, | 
					
						
							|  |  |  |             "widget/sqlite": self.homepage_sqlite_widget, | 
					
						
							| 
									
										
										
										
											2025-01-22 06:38:40 -05:00
										 |  |  |             "widget/lyrics": self.homepage_lyrics_widget, | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             "widget/radio": self.homepage_radio_widget, | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |             "widget/rq": self.homepage_rq_widget, | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |             "misc/get_activity_image": self.get_activity_image, | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |             "misc/no": self.no, | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |         for endpoint, handler in self.endpoints.items(): | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             app.add_api_route( | 
					
						
							| 
									
										
										
										
											2025-07-01 11:38:38 -04:00
										 |  |  |                 f"/{endpoint}", | 
					
						
							|  |  |  |                 handler, | 
					
						
							|  |  |  |                 methods=["GET"], | 
					
						
							|  |  |  |                 include_in_schema=True, | 
					
						
							| 
									
										
										
										
											2025-07-15 11:39:12 -04:00
										 |  |  |                 dependencies=[Depends(RateLimiter(times=10, seconds=2))], | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.add_api_route( | 
					
						
							| 
									
										
										
										
											2025-07-01 13:02:53 -04:00
										 |  |  |             "/misc/upload_activity_image", | 
					
						
							|  |  |  |             self.upload_activity_image, | 
					
						
							|  |  |  |             methods=["POST"], | 
					
						
							| 
									
										
										
										
											2025-07-15 11:39:12 -04:00
										 |  |  |             dependencies=[Depends(RateLimiter(times=10, seconds=2))], | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |         logging.debug("Loading NaaS reasons") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-03 06:31:19 -04:00
										 |  |  |         with open(self.nos_json_path, "r", encoding="utf-8") as f: | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |             self.nos = json.loads(f.read()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         logging.debug("Loaded %s reasons", len(self.nos)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_no(self) -> str: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             no = random.choice(self.nos) | 
					
						
							|  |  |  |             if no in self.last_5_nos: | 
					
						
							|  |  |  |                 return self.get_no()  # recurse | 
					
						
							|  |  |  |             self.last_5_nos.append(no) | 
					
						
							|  |  |  |             if len(self.last_5_nos) >= 5: | 
					
						
							|  |  |  |                 self.last_5_nos.pop(0) | 
					
						
							| 
									
										
										
										
											2025-05-03 06:39:55 -04:00
										 |  |  |             return no | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |         except Exception as e: | 
					
						
							|  |  |  |             logging.debug("Exception: %s", str(e)) | 
					
						
							|  |  |  |             return "No." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async def no(self) -> JSONResponse: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Get a random 'no' reason. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains a random 'no' reason. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 15:54:27 -04:00
										 |  |  |         return JSONResponse(content={"no": self.get_no()}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |     async def upload_activity_image( | 
					
						
							|  |  |  |         self, image: UploadFile, key: Annotated[str, Form()], request: Request | 
					
						
							|  |  |  |     ) -> Response: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Upload activity image. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters: | 
					
						
							|  |  |  |         - **image** (UploadFile): The uploaded image file. | 
					
						
							|  |  |  |         - **key** (str): The API key for authentication. | 
					
						
							|  |  |  |         - **request** (Request): The HTTP request object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **Response**: Indicates success or failure of the upload. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         if ( | 
					
						
							|  |  |  |             not key | 
					
						
							|  |  |  |             or not isinstance(key, str) | 
					
						
							|  |  |  |             or not self.util.check_key(path=request.url.path, req_type=2, key=key) | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             raise HTTPException(status_code=403, detail="Unauthorized") | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |         if not image: | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             return JSONResponse( | 
					
						
							|  |  |  |                 status_code=500, | 
					
						
							|  |  |  |                 content={ | 
					
						
							|  |  |  |                     "err": True, | 
					
						
							|  |  |  |                     "errorText": "Invalid request", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |         self.activity_image = await image.read() | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         return JSONResponse( | 
					
						
							|  |  |  |             content={ | 
					
						
							|  |  |  |                 "success": True, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |     async def get_activity_image(self, request: Request) -> Response: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Get the activity image. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters: | 
					
						
							|  |  |  |         - **request** (Request): The HTTP request object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **Response**: The activity image or a fallback image. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |         if isinstance(self.activity_image, bytes): | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             return Response(content=self.activity_image, media_type="image/png") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 08:11:55 -05:00
										 |  |  |         # Fallback | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         fallback_path = os.path.join( | 
					
						
							|  |  |  |             "/var/www/codey.lol/public", "images", "plex_placeholder.png" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with open(fallback_path, "rb") as f: | 
					
						
							|  |  |  |             return Response(content=f.read(), media_type="image/png") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-19 21:57:21 -04:00
										 |  |  |     async def get_radio_np(self, station: str = "main") -> tuple[str, str, str]: | 
					
						
							| 
									
										
										
										
											2025-01-22 09:00:51 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get radio now playing info. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-22 09:00:51 -05:00
										 |  |  |         Args: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |             station: Station name. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-22 09:00:51 -05:00
										 |  |  |         Returns: | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |             Tuple of (artistsong, album, genre). | 
					
						
							| 
									
										
										
										
											2025-01-22 09:00:51 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-19 21:57:21 -04:00
										 |  |  |         np: dict = self.radio.radio_util.now_playing[station] | 
					
						
							| 
									
										
										
										
											2025-07-15 13:48:51 -04:00
										 |  |  |         artistsong: str = "N/A - N/A" | 
					
						
							|  |  |  |         artist = np.get("artist") | 
					
						
							|  |  |  |         song = np.get("song") | 
					
						
							|  |  |  |         if artist and song: | 
					
						
							|  |  |  |             artistsong = f"{artist} - {song}" | 
					
						
							| 
									
										
										
										
											2025-07-19 21:57:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         album: str = np.get("album", "N/A") | 
					
						
							|  |  |  |         genre: str = np.get("genre", "N/A") | 
					
						
							| 
									
										
										
										
											2025-03-18 09:39:20 -04:00
										 |  |  |         return (artistsong, album, genre) | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  |     async def homepage_redis_widget(self) -> JSONResponse: | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get Redis stats for homepage widget. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains Redis stats. | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |         # Measure response time w/ test lyric search | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         time_start: float = time.time()  # Start time for response_time | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |         test_lyrics_result = self.redis_client.ft().search(  # noqa: F841 | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             "@artist: test @song: test" | 
					
						
							| 
									
										
										
										
											2025-04-26 22:01:25 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-01-21 19:16:23 -05:00
										 |  |  |         time_end: float = time.time() | 
					
						
							|  |  |  |         # End response time test | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |         total_keys = self.redis_client.dbsize() | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         response_time: float = time_end - time_start | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |         index_info = self.redis_client.ft().info() | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         indexed_lyrics: int = index_info.get("num_docs") | 
					
						
							|  |  |  |         return JSONResponse( | 
					
						
							|  |  |  |             content={ | 
					
						
							|  |  |  |                 "responseTime": round(response_time, 7), | 
					
						
							|  |  |  |                 "storedKeys": total_keys, | 
					
						
							|  |  |  |                 "indexedLyrics": indexed_lyrics, | 
					
						
							| 
									
										
										
										
											2025-07-15 13:48:51 -04:00
										 |  |  |                 "sessions": -1, | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-09-09 15:50:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |     async def homepage_rq_widget(self) -> JSONResponse: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get RQ job stats for homepage widget. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains RQ job stats. | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         queue_name = "dls" | 
					
						
							|  |  |  |         queue = Queue(queue_name, self.redis_client) | 
					
						
							|  |  |  |         queued = queue.count | 
					
						
							|  |  |  |         started = StartedJobRegistry(queue_name, connection=self.redis_client).count | 
					
						
							|  |  |  |         failed = FailedJobRegistry(queue_name, connection=self.redis_client).count | 
					
						
							| 
									
										
										
										
											2025-09-09 15:50:13 -04:00
										 |  |  |         finished = FinishedJobRegistry(queue_name, connection=self.redis_client).count | 
					
						
							|  |  |  |         deferred = DeferredJobRegistry(queue_name, connection=self.redis_client).count | 
					
						
							| 
									
										
										
										
											2025-08-23 08:20:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return JSONResponse( | 
					
						
							|  |  |  |             content={ | 
					
						
							|  |  |  |                 queue_name: { | 
					
						
							|  |  |  |                     "queued": queued, | 
					
						
							|  |  |  |                     "started": started, | 
					
						
							|  |  |  |                     "failed": failed, | 
					
						
							|  |  |  |                     "finished": finished, | 
					
						
							|  |  |  |                     "deferred": deferred, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-09 15:50:13 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  |     async def homepage_sqlite_widget(self) -> JSONResponse: | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get SQLite stats for homepage widget. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains SQLite stats. | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-11 20:01:07 -05:00
										 |  |  |         row_count: int = await self.lyr_cache.sqlite_rowcount() | 
					
						
							|  |  |  |         distinct_artists: int = await self.lyr_cache.sqlite_distinct("artist") | 
					
						
							|  |  |  |         lyrics_length: int = await self.lyr_cache.sqlite_lyrics_length() | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         return JSONResponse( | 
					
						
							|  |  |  |             content={ | 
					
						
							|  |  |  |                 "storedRows": row_count, | 
					
						
							|  |  |  |                 "distinctArtists": distinct_artists, | 
					
						
							|  |  |  |                 "lyricsLength": lyrics_length, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-16 08:45:40 -05:00
										 |  |  |     async def homepage_lyrics_widget(self) -> JSONResponse: | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get lyrics stats for homepage widget. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains lyrics stats. | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:37:37 -05:00
										 |  |  |         found_counts: Optional[dict] = await self.redis_cache.get_found_counts() | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  |         if not isinstance(found_counts, dict): | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             logging.info( | 
					
						
							|  |  |  |                 "DEBUG: Type of found counts from redis: %s\nContents: %s", | 
					
						
							|  |  |  |                 type(found_counts), | 
					
						
							|  |  |  |                 found_counts, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             return JSONResponse( | 
					
						
							|  |  |  |                 status_code=500, | 
					
						
							|  |  |  |                 content={ | 
					
						
							|  |  |  |                     "err": True, | 
					
						
							|  |  |  |                     "errorText": "General failure.", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-02-16 08:45:40 -05:00
										 |  |  |         return JSONResponse(content=found_counts) | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-19 21:57:21 -04:00
										 |  |  |     async def homepage_radio_widget(self, station: str = "main") -> JSONResponse: | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-09-23 13:17:34 -04:00
										 |  |  |         Get radio now playing for homepage widget. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters: | 
					
						
							|  |  |  |         - **station** (str): Station name. Defaults to "main". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns: | 
					
						
							|  |  |  |         - **JSONResponse**: Contains now playing info. | 
					
						
							| 
									
										
										
										
											2025-02-16 08:17:27 -05:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-07-19 21:57:21 -04:00
										 |  |  |         radio_np: tuple = await self.get_radio_np(station) | 
					
						
							| 
									
										
										
										
											2025-02-15 21:09:33 -05:00
										 |  |  |         if not radio_np: | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |             return JSONResponse( | 
					
						
							|  |  |  |                 status_code=500, | 
					
						
							|  |  |  |                 content={ | 
					
						
							|  |  |  |                     "err": True, | 
					
						
							|  |  |  |                     "errorText": "General failure.", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-03-18 09:39:20 -04:00
										 |  |  |         (artistsong, album, genre) = radio_np | 
					
						
							| 
									
										
										
										
											2025-04-17 07:28:05 -04:00
										 |  |  |         return JSONResponse( | 
					
						
							|  |  |  |             content={ | 
					
						
							|  |  |  |                 "now_playing": artistsong, | 
					
						
							|  |  |  |                 "album": album, | 
					
						
							|  |  |  |                 "genre": genre, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) |