diff --git a/endpoints/lighting.py b/endpoints/lighting.py index 3b60fcf..503f3ee 100644 --- a/endpoints/lighting.py +++ b/endpoints/lighting.py @@ -179,7 +179,7 @@ class Lighting(FastAPI): methods=["GET"], include_in_schema=True, dependencies=[ - Depends(RateLimiter(times=10, seconds=2)), + Depends(RateLimiter(times=25, seconds=2)), Depends(get_current_user), ], ) @@ -190,7 +190,7 @@ class Lighting(FastAPI): methods=["POST"], include_in_schema=True, dependencies=[ - Depends(RateLimiter(times=10, seconds=2)), + Depends(RateLimiter(times=25, seconds=2)), Depends(get_current_user), ], ) @@ -266,7 +266,7 @@ class Lighting(FastAPI): await self.ensure_cync_connection() - # Apply to Cync device + # Validate and extract state values power = state.get("power", "off") if power not in ["on", "off"]: raise HTTPException( @@ -296,41 +296,58 @@ class Lighting(FastAPI): else: rgb = None - # Use persistent Cync API object - if not self.cync_api: - raise HTTPException(status_code=500, detail="Cync API not initialized.") - devices = self.cync_api.get_devices() - if not devices or not isinstance(devices, (list, tuple)): - raise HTTPException( - status_code=500, detail="No devices returned from Cync API." - ) - light = next( - ( - d - for d in devices - if hasattr(d, "name") and d.name == self.cync_device_name - ), - None, - ) - if not light: - raise HTTPException( - status_code=404, - detail=f"Device '{self.cync_device_name}' not found", - ) + # Apply to Cync device with retry on connection issues + max_retries = 2 + for attempt in range(max_retries): + try: + # Use persistent Cync API object + if not self.cync_api: + raise Exception("Cync API not initialized.") + devices = self.cync_api.get_devices() + if not devices or not isinstance(devices, (list, tuple)): + raise Exception("No devices returned from Cync API.") + light = next( + ( + d + for d in devices + if hasattr(d, "name") and d.name == self.cync_device_name + ), + None, + ) + if not light: + raise Exception(f"Device '{self.cync_device_name}' not found") - # Set power - if power == "on": - await light.turn_on() - else: - await light.turn_off() + # Set power + if power == "on": + await light.turn_on() + else: + await light.turn_off() - # Set brightness - if "brightness" in state: - await light.set_brightness(brightness) + # Set brightness + if "brightness" in state: + await light.set_brightness(brightness) - # Set color - if rgb: - await light.set_rgb(rgb) + # Set color + if rgb: + await light.set_rgb(rgb) + + break # Success, exit retry loop + except Exception as e: + if attempt < max_retries - 1: + logging.warning( + "Device operation failed (attempt %d/%d): %s. Retrying with reconnection.", + attempt + 1, + max_retries, + e, + ) + await self.ensure_cync_connection() + else: + logging.error( + "Device operation failed after %d attempts: %s", + max_retries, + e, + ) + raise logging.info( "Successfully applied state to device '%s': %s", diff --git a/endpoints/lyric_search.py b/endpoints/lyric_search.py index c36d2c7..e43ef00 100644 --- a/endpoints/lyric_search.py +++ b/endpoints/lyric_search.py @@ -210,20 +210,20 @@ class LyricSearch(FastAPI): if data.sub and not data.lrc: seeked_found_line: Optional[int] = None - lyric_lines: list[str] = result["lyrics"].strip().split(" / ") + # Split lyrics into lines based on
or newline characters + lyrics_text = result["lyrics"].strip() + if "
" in lyrics_text: + lyric_lines = lyrics_text.split("
") + else: + lyric_lines = lyrics_text.split("\n") for i, line in enumerate(lyric_lines): - line = regex.sub(r"\u2064", "", line.strip()) - if data.sub.strip().lower() in line.strip().lower(): + # Remove any special characters and extra spaces + cleaned_line = regex.sub(r"\u2064", "", line.strip()) + if data.sub.strip().lower() in cleaned_line.lower(): seeked_found_line = i - logging.debug( - "Found %s at %s, match for %s!", - line, - seeked_found_line, - data.sub, - ) # REMOVEME: DEBUG break - if not seeked_found_line: + if seeked_found_line is None: return JSONResponse( status_code=500, content={ @@ -232,7 +232,10 @@ class LyricSearch(FastAPI): "failed_seek": True, }, ) - result["lyrics"] = " / ".join(lyric_lines[seeked_found_line:]) + # Only include lines strictly starting from the matched line + # Use the same separator that was used to split + separator = "
" if "
" in result["lyrics"] else "\n" + result["lyrics"] = separator.join(lyric_lines[seeked_found_line:]) result["confidence"] = int(result["confidence"]) result["time"] = f"{float(result['time']):.4f}"