Increase rate limit for lighting state requests and enhance error handling for Cync device operations. Improve lyric search processing by splitting lyrics based on line breaks and cleaning special characters (bugfix for subsearch/seek).
This commit is contained in:
@@ -179,7 +179,7 @@ class Lighting(FastAPI):
|
|||||||
methods=["GET"],
|
methods=["GET"],
|
||||||
include_in_schema=True,
|
include_in_schema=True,
|
||||||
dependencies=[
|
dependencies=[
|
||||||
Depends(RateLimiter(times=10, seconds=2)),
|
Depends(RateLimiter(times=25, seconds=2)),
|
||||||
Depends(get_current_user),
|
Depends(get_current_user),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -190,7 +190,7 @@ class Lighting(FastAPI):
|
|||||||
methods=["POST"],
|
methods=["POST"],
|
||||||
include_in_schema=True,
|
include_in_schema=True,
|
||||||
dependencies=[
|
dependencies=[
|
||||||
Depends(RateLimiter(times=10, seconds=2)),
|
Depends(RateLimiter(times=25, seconds=2)),
|
||||||
Depends(get_current_user),
|
Depends(get_current_user),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -266,7 +266,7 @@ class Lighting(FastAPI):
|
|||||||
|
|
||||||
await self.ensure_cync_connection()
|
await self.ensure_cync_connection()
|
||||||
|
|
||||||
# Apply to Cync device
|
# Validate and extract state values
|
||||||
power = state.get("power", "off")
|
power = state.get("power", "off")
|
||||||
if power not in ["on", "off"]:
|
if power not in ["on", "off"]:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -296,41 +296,58 @@ class Lighting(FastAPI):
|
|||||||
else:
|
else:
|
||||||
rgb = None
|
rgb = None
|
||||||
|
|
||||||
# Use persistent Cync API object
|
# Apply to Cync device with retry on connection issues
|
||||||
if not self.cync_api:
|
max_retries = 2
|
||||||
raise HTTPException(status_code=500, detail="Cync API not initialized.")
|
for attempt in range(max_retries):
|
||||||
devices = self.cync_api.get_devices()
|
try:
|
||||||
if not devices or not isinstance(devices, (list, tuple)):
|
# Use persistent Cync API object
|
||||||
raise HTTPException(
|
if not self.cync_api:
|
||||||
status_code=500, detail="No devices returned from Cync API."
|
raise Exception("Cync API not initialized.")
|
||||||
)
|
devices = self.cync_api.get_devices()
|
||||||
light = next(
|
if not devices or not isinstance(devices, (list, tuple)):
|
||||||
(
|
raise Exception("No devices returned from Cync API.")
|
||||||
d
|
light = next(
|
||||||
for d in devices
|
(
|
||||||
if hasattr(d, "name") and d.name == self.cync_device_name
|
d
|
||||||
),
|
for d in devices
|
||||||
None,
|
if hasattr(d, "name") and d.name == self.cync_device_name
|
||||||
)
|
),
|
||||||
if not light:
|
None,
|
||||||
raise HTTPException(
|
)
|
||||||
status_code=404,
|
if not light:
|
||||||
detail=f"Device '{self.cync_device_name}' not found",
|
raise Exception(f"Device '{self.cync_device_name}' not found")
|
||||||
)
|
|
||||||
|
|
||||||
# Set power
|
# Set power
|
||||||
if power == "on":
|
if power == "on":
|
||||||
await light.turn_on()
|
await light.turn_on()
|
||||||
else:
|
else:
|
||||||
await light.turn_off()
|
await light.turn_off()
|
||||||
|
|
||||||
# Set brightness
|
# Set brightness
|
||||||
if "brightness" in state:
|
if "brightness" in state:
|
||||||
await light.set_brightness(brightness)
|
await light.set_brightness(brightness)
|
||||||
|
|
||||||
# Set color
|
# Set color
|
||||||
if rgb:
|
if rgb:
|
||||||
await light.set_rgb(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(
|
logging.info(
|
||||||
"Successfully applied state to device '%s': %s",
|
"Successfully applied state to device '%s': %s",
|
||||||
|
@@ -210,20 +210,20 @@ class LyricSearch(FastAPI):
|
|||||||
|
|
||||||
if data.sub and not data.lrc:
|
if data.sub and not data.lrc:
|
||||||
seeked_found_line: Optional[int] = None
|
seeked_found_line: Optional[int] = None
|
||||||
lyric_lines: list[str] = result["lyrics"].strip().split(" / ")
|
# Split lyrics into lines based on <br> or newline characters
|
||||||
|
lyrics_text = result["lyrics"].strip()
|
||||||
|
if "<br>" in lyrics_text:
|
||||||
|
lyric_lines = lyrics_text.split("<br>")
|
||||||
|
else:
|
||||||
|
lyric_lines = lyrics_text.split("\n")
|
||||||
for i, line in enumerate(lyric_lines):
|
for i, line in enumerate(lyric_lines):
|
||||||
line = regex.sub(r"\u2064", "", line.strip())
|
# Remove any special characters and extra spaces
|
||||||
if data.sub.strip().lower() in line.strip().lower():
|
cleaned_line = regex.sub(r"\u2064", "", line.strip())
|
||||||
|
if data.sub.strip().lower() in cleaned_line.lower():
|
||||||
seeked_found_line = i
|
seeked_found_line = i
|
||||||
logging.debug(
|
|
||||||
"Found %s at %s, match for %s!",
|
|
||||||
line,
|
|
||||||
seeked_found_line,
|
|
||||||
data.sub,
|
|
||||||
) # REMOVEME: DEBUG
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if not seeked_found_line:
|
if seeked_found_line is None:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
content={
|
content={
|
||||||
@@ -232,7 +232,10 @@ class LyricSearch(FastAPI):
|
|||||||
"failed_seek": True,
|
"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 = "<br>" if "<br>" in result["lyrics"] else "\n"
|
||||||
|
result["lyrics"] = separator.join(lyric_lines[seeked_found_line:])
|
||||||
|
|
||||||
result["confidence"] = int(result["confidence"])
|
result["confidence"] = int(result["confidence"])
|
||||||
result["time"] = f"{float(result['time']):.4f}"
|
result["time"] = f"{float(result['time']):.4f}"
|
||||||
|
Reference in New Issue
Block a user