diff --git a/py/services/civitai_client.py b/py/services/civitai_client.py index a9929fc1..ce0854a7 100644 --- a/py/services/civitai_client.py +++ b/py/services/civitai_client.py @@ -163,14 +163,16 @@ class CivitaiClient: logger.error(f"Error fetching model version info: {e}") return None - async def get_model_metadata(self, model_id: str) -> Optional[Dict]: + async def get_model_metadata(self, model_id: str) -> Tuple[Optional[Dict], int]: """Fetch model metadata (description and tags) from Civitai API Args: model_id: The Civitai model ID Returns: - Optional[Dict]: A dictionary containing model metadata or None if not found + Tuple[Optional[Dict], int]: A tuple containing: + - A dictionary with model metadata or None if not found + - The HTTP status code from the request """ try: session = await self.session @@ -178,9 +180,11 @@ class CivitaiClient: url = f"{self.base_url}/models/{model_id}" async with session.get(url, headers=headers) as response: - if response.status != 200: - logger.warning(f"Failed to fetch model metadata: Status {response.status}") - return None + status_code = response.status + + if status_code != 200: + logger.warning(f"Failed to fetch model metadata: Status {status_code}") + return None, status_code data = await response.json() @@ -191,19 +195,19 @@ class CivitaiClient: } if metadata["description"] or metadata["tags"]: - return metadata + return metadata, status_code else: logger.warning(f"No metadata found for model {model_id}") - return None + return None, status_code except Exception as e: logger.error(f"Error fetching model metadata: {e}", exc_info=True) - return None + return None, 0 # Keep old method for backward compatibility, delegating to the new one async def get_model_description(self, model_id: str) -> Optional[str]: """Fetch the model description from Civitai API (Legacy method)""" - metadata = await self.get_model_metadata(model_id) + metadata, _ = await self.get_model_metadata(model_id) return metadata.get("description") if metadata else None async def close(self): diff --git a/py/services/lora_scanner.py b/py/services/lora_scanner.py index 487afe48..8b764b6d 100644 --- a/py/services/lora_scanner.py +++ b/py/services/lora_scanner.py @@ -384,6 +384,11 @@ class LoraScanner: lora_data: Lora metadata dictionary to update """ try: + # Skip if already marked as deleted on Civitai + if lora_data.get('civitai_deleted', False): + logger.debug(f"Skipping metadata fetch for {file_path}: marked as deleted on Civitai") + return + # Check if we need to fetch additional metadata from Civitai needs_metadata_update = False model_id = None @@ -408,10 +413,24 @@ class LoraScanner: logger.info(f"Fetching missing metadata for {file_path} with model ID {model_id}") from ..services.civitai_client import CivitaiClient client = CivitaiClient() - model_metadata = await client.get_model_metadata(model_id) + + # Get metadata and status code + model_metadata, status_code = await client.get_model_metadata(model_id) await client.close() - if (model_metadata): + # Handle 404 status (model deleted from Civitai) + if status_code == 404: + logger.warning(f"Model {model_id} appears to be deleted from Civitai (404 response)") + # Mark as deleted to avoid future API calls + lora_data['civitai_deleted'] = True + + # Save the updated metadata back to file + metadata_path = os.path.splitext(file_path)[0] + '.metadata.json' + with open(metadata_path, 'w', encoding='utf-8') as f: + json.dump(lora_data, f, indent=2, ensure_ascii=False) + + # Process valid metadata if available + elif model_metadata: logger.info(f"Updating metadata for {file_path} with model ID {model_id}") # Update tags if they were missing