Reintroduced caching — if it has been less than a 1 second since the last call, just return the same payload
This commit is contained in:
+65
-39
@@ -1,5 +1,5 @@
|
|||||||
# Versioning
|
# Versioning
|
||||||
APP_VERSION = "0.0.4"
|
APP_VERSION = "0.0.5"
|
||||||
DEVELOPER = "nutty"
|
DEVELOPER = "nutty"
|
||||||
|
|
||||||
|
|
||||||
@@ -161,6 +161,22 @@ try:
|
|||||||
|
|
||||||
async def get_all_media_info():
|
async def get_all_media_info():
|
||||||
try:
|
try:
|
||||||
|
# We will cache the last execution time and payload to avoid redundant parsing if requests flood in faster than 1 second.
|
||||||
|
current_time = time.time()
|
||||||
|
if not hasattr(get_all_media_info, "last_execution"):
|
||||||
|
get_all_media_info.last_execution = 0
|
||||||
|
get_all_media_info.last_payload = None
|
||||||
|
|
||||||
|
# If requests flood in faster than 1 second, return the cached result
|
||||||
|
# to completely spare the CPU from redundant parsing.
|
||||||
|
if (current_time - get_all_media_info.last_execution) < 1.0 and get_all_media_info.last_payload:
|
||||||
|
# print("Using cached media info.")
|
||||||
|
return get_all_media_info.last_payload
|
||||||
|
# else:
|
||||||
|
# print("Fetching fresh media info.")
|
||||||
|
|
||||||
|
get_all_media_info.last_execution = current_time
|
||||||
|
|
||||||
# Instantiate the SMTC manager -> This allows use to "talk" to the Windows Media API
|
# Instantiate the SMTC manager -> This allows use to "talk" to the Windows Media API
|
||||||
manager = await SMTC.request_async()
|
manager = await SMTC.request_async()
|
||||||
|
|
||||||
@@ -271,51 +287,56 @@ try:
|
|||||||
try:
|
try:
|
||||||
stream_ref = raw_media.thumbnail
|
stream_ref = raw_media.thumbnail
|
||||||
stream = await stream_ref.open_read_async()
|
stream = await stream_ref.open_read_async()
|
||||||
reader = DataReader(stream.get_input_stream_at(0))
|
|
||||||
await reader.load_async(stream.size)
|
|
||||||
buffer = bytearray(stream.size)
|
|
||||||
reader.read_bytes(buffer)
|
|
||||||
|
|
||||||
# Generate a safe filename based on the app_id
|
# Only proceed if there's actual data to read
|
||||||
safe_app_id = "".join(c for c in app_id if c.isalnum() or c in ('_', '-'))
|
if stream.size > 0:
|
||||||
thumb_filename = f"{safe_app_id}.jpg"
|
reader = DataReader(stream.get_input_stream_at(0))
|
||||||
thumb_path = os.path.join(THUMB_DIR, thumb_filename)
|
await reader.load_async(stream.size)
|
||||||
|
buffer = bytearray(stream.size)
|
||||||
|
reader.read_bytes(buffer)
|
||||||
|
|
||||||
# Hash the raw image bytes to check if the artwork actually changed
|
# Generate a safe filename based on the app_id
|
||||||
import hashlib
|
safe_app_id = "".join(c for c in app_id if c.isalnum() or c in ('_', '-'))
|
||||||
img_hash = hashlib.md5(buffer).hexdigest()
|
thumb_filename = f"{safe_app_id}.jpg"
|
||||||
|
thumb_path = os.path.join(THUMB_DIR, thumb_filename)
|
||||||
|
|
||||||
# Track hashes in memory to avoid writing to disk if nothing changed
|
# Hash the raw image bytes to check if the artwork actually changed
|
||||||
if not hasattr(get_all_media_info, "cache"):
|
import hashlib
|
||||||
get_all_media_info.cache = {}
|
img_hash = hashlib.md5(buffer).hexdigest()
|
||||||
|
|
||||||
# Check if we already processed this exact artwork for this app
|
# Track hashes in memory to avoid writing to disk if nothing changed
|
||||||
if get_all_media_info.cache.get(safe_app_id) == img_hash and os.path.exists(thumb_path):
|
if not hasattr(get_all_media_info, "cache"):
|
||||||
# Artwork hasn't changed, reuse existing file and version timestamp
|
get_all_media_info.cache = {}
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# Process and save with Pillow only when bytes actually change
|
|
||||||
img = Image.open(io.BytesIO(buffer))
|
|
||||||
if img.mode in ("RGBA", "P"):
|
|
||||||
img = img.convert("RGB")
|
|
||||||
|
|
||||||
# Save at full resolution, but use faster compression settings
|
# Check if we already processed this exact artwork for this app
|
||||||
img.save(
|
if get_all_media_info.cache.get(safe_app_id) == img_hash and os.path.exists(thumb_path):
|
||||||
thumb_path,
|
# Artwork hasn't changed, reuse existing file and version timestamp
|
||||||
"JPEG",
|
# print("Using cached artwork.")
|
||||||
quality=40, # Sweet spot for small size / high visual fidelity
|
pass
|
||||||
subsampling=2, # Faster compression algorithm for low-end CPUs
|
else:
|
||||||
optimize=False # Skips the extra CPU pass
|
print(f"Processing new artwork for: {media_data['Artist']} - {media_data['Title']}")
|
||||||
)
|
# Process and save with Pillow only when bytes actually change
|
||||||
|
img = Image.open(io.BytesIO(buffer))
|
||||||
|
if img.mode in ("RGBA", "P"):
|
||||||
|
img = img.convert("RGB")
|
||||||
|
|
||||||
# Update cache hash
|
# Save at full resolution, but use faster compression settings
|
||||||
get_all_media_info.cache[safe_app_id] = img_hash
|
img.save(
|
||||||
|
thumb_path,
|
||||||
|
"JPEG",
|
||||||
|
quality=40, # Sweet spot for small size / high visual fidelity
|
||||||
|
subsampling=2, # Faster compression algorithm for low-end CPUs
|
||||||
|
optimize=False # Skips the extra CPU pass
|
||||||
|
)
|
||||||
|
|
||||||
# Use file modification time as the version token so browsers cache it aggressively
|
# Update cache hash
|
||||||
thumb_version = int(os.path.getmtime(thumb_path) * 1000)
|
get_all_media_info.cache[safe_app_id] = img_hash
|
||||||
|
|
||||||
# Construct the URL with the version query parameter
|
# Use file modification time as the version token so browsers cache it aggressively
|
||||||
thumb_url = f"http://{HOST}:{PORT}/artwork/{safe_app_id}?v={thumb_version}"
|
thumb_version = int(os.path.getmtime(thumb_path) * 1000)
|
||||||
|
|
||||||
|
# Construct the URL with the version query parameter
|
||||||
|
thumb_url = f"http://{HOST}:{PORT}/artwork/{safe_app_id}?v={thumb_version}"
|
||||||
except Exception:
|
except Exception:
|
||||||
thumb_url = None
|
thumb_url = None
|
||||||
|
|
||||||
@@ -331,11 +352,16 @@ try:
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Build the final payload
|
# Build the final payload
|
||||||
return {
|
payload = {
|
||||||
"app_version": APP_VERSION,
|
"app_version": APP_VERSION,
|
||||||
"current_session_id": current_session_id,
|
"current_session_id": current_session_id,
|
||||||
"sessions": sessions_list
|
"sessions": sessions_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Save to global payload cache
|
||||||
|
get_all_media_info.last_payload = payload
|
||||||
|
return payload
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"current_session_id": None, "sessions": [], "error": str(e)}
|
return {"current_session_id": None, "sessions": [], "error": str(e)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user