feat: add Storage Optimizer with SHA-256 hashing and Civitai hash lookup
This commit is contained in:
@@ -83,6 +83,12 @@ public class ModelSearchService implements IModelSearchService {
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private de.tki.comfymodels.service.impl.ModelHashRegistry hashRegistry;
|
||||
|
||||
@Autowired
|
||||
private de.tki.comfymodels.service.IModelValidator modelValidator;
|
||||
|
||||
private void performSearch(ModelInfo info, int index, String fileName, String workflowContext,
|
||||
BiConsumer<Integer, String> onStatusUpdate,
|
||||
BiConsumer<Integer, ModelInfo> onModelFound) {
|
||||
@@ -93,6 +99,18 @@ public class ModelSearchService implements IModelSearchService {
|
||||
if (validateAndSetUrl(info, index, manualMatch.get().getUrl(), "📂 USER DEFINED", onStatusUpdate, onModelFound)) return;
|
||||
}
|
||||
|
||||
// Priority 2: Civitai Hash Lookup (if file exists locally but we want the source URL/Metadata)
|
||||
// This is useful for re-downloading or finding updates
|
||||
String modelsPath = configService.getModelsPath();
|
||||
java.io.File localFile = new java.io.File(modelsPath, (info.getSave_path() != null ? info.getSave_path() : (info.getType() != null ? info.getType() : "checkpoints")) + java.io.File.separator + info.getName());
|
||||
if (localFile.exists()) {
|
||||
onStatusUpdate.accept(index, "🔍 Hashing for Civitai...");
|
||||
String hash = hashRegistry.getOrCalculateHash(localFile);
|
||||
if (hash != null) {
|
||||
if (fetchCivitaiUrlByHash(info, index, hash, onStatusUpdate, onModelFound)) return;
|
||||
}
|
||||
}
|
||||
|
||||
onStatusUpdate.accept(index, "✨ Gemini Scouting...");
|
||||
String aiHint = geminiService.discoverBestRepo(info.getName(), fileName, workflowContext);
|
||||
if (aiHint != null && !aiHint.equalsIgnoreCase("UNKNOWN")) {
|
||||
@@ -275,6 +293,29 @@ public class ModelSearchService implements IModelSearchService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean fetchCivitaiUrlByHash(ModelInfo info, int rowIndex, String hash,
|
||||
BiConsumer<Integer, String> onStatusUpdate,
|
||||
BiConsumer<Integer, ModelInfo> onModelFound) {
|
||||
try {
|
||||
String searchUrl = "https://civitai.com/api/v1/model-versions/by-hash/" + hash;
|
||||
HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder().uri(URI.create(searchUrl)).build(), HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() == 200) {
|
||||
JSONObject version = new JSONObject(response.body());
|
||||
JSONArray files = version.optJSONArray("files");
|
||||
if (files != null) {
|
||||
for (int j = 0; j < files.length(); j++) {
|
||||
JSONObject file = files.getJSONObject(j);
|
||||
// We check if the name matches or if it's the primary file for this version
|
||||
if (file.optString("name").equalsIgnoreCase(info.getName()) || file.optBoolean("primary", false)) {
|
||||
return validateAndSetUrl(info, rowIndex, file.optString("downloadUrl"), "🛡️ Civitai (Hash Match)", onStatusUpdate, onModelFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean fetchCivitaiUrl(ModelInfo info, int rowIndex, String query,
|
||||
BiConsumer<Integer, String> onStatusUpdate,
|
||||
BiConsumer<Integer, ModelInfo> onModelFound) {
|
||||
|
||||
Reference in New Issue
Block a user