Files
Azornes-Comfyui-Model-Resolver/web/resolver/views/model_hash_compare_methods.js
T

181 lines
6.4 KiB
JavaScript

import { normalizeSha256 } from '../utils/hash_utils.js';
import { getSourceDisplayLabel, normalizeSourceKey } from '../utils/source_labels.js';
export const modelHashCompareMethods = {
formatSha256Short(value = '') {
const hash = normalizeSha256(value) || String(value || '').trim();
if (hash.length <= 18) return hash;
return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
},
collectHashCandidatesForCompare(value, source = 'metadata', seen = new Set(), depth = 0) {
const candidates = [];
if (value === undefined || value === null || depth > 5) return candidates;
const addHash = (rawValue, hashSource = source) => {
const hash = normalizeSha256(rawValue);
if (!hash || seen.has(hash)) return;
seen.add(hash);
candidates.push({ hash, source: hashSource || source || 'metadata' });
};
if (typeof value === 'string' || typeof value === 'number') {
addHash(value);
return candidates;
}
if (Array.isArray(value)) {
value.forEach(item => {
candidates.push(...this.collectHashCandidatesForCompare(item, source, seen, depth + 1));
});
return candidates;
}
if (typeof value !== 'object') return candidates;
[
['local_match_sha256', 'local match'],
['sha256', source],
['hash', source],
['SHA256', source],
['file_hash', source],
['fileHash', source]
].forEach(([key, label]) => addHash(value[key], label));
const hashes = value.hashes;
if (Array.isArray(hashes)) {
candidates.push(...this.collectHashCandidatesForCompare(hashes, source, seen, depth + 1));
} else if (hashes && typeof hashes === 'object') {
['SHA256', 'sha256', 'hash'].forEach(key => addHash(hashes[key], source));
}
[
['file_info', value.file_info],
['file', value.file],
['selected_file', value.selected_file],
['path_metadata', value.path_metadata],
['download_metadata', value.download_metadata],
['metadata', value.metadata],
['selected_version', value.selected_version || value.selectedVersion],
['version', value.version],
['civitai', value.civitai]
].forEach(([key, nestedValue]) => {
if (nestedValue !== undefined && nestedValue !== null) {
candidates.push(...this.collectHashCandidatesForCompare(nestedValue, `${source} ${key}`, seen, depth + 1));
}
});
['files', 'mirrors', 'download_files', 'downloadFiles', 'modelVersions', 'versions'].forEach(key => {
if (Array.isArray(value[key])) {
candidates.push(...this.collectHashCandidatesForCompare(value[key], `${source} ${key}`, seen, depth + 1));
}
});
return candidates;
},
getLocalHashCandidatesForCompare(model = {}) {
const seen = new Set();
return this.collectHashCandidatesForCompare(model, 'local model metadata', seen);
},
getLocalHashComparePath(model = {}) {
return model?.open_path
|| model?.resolved_path
|| model?.path
|| model?.file_path
|| '';
},
getHashCompareFilename(model = {}) {
return model.filename
|| model.name
|| this.getFilenameFromPath(this.getLocalHashComparePath(model))
|| 'Selected local model';
},
updateHashCompareModelMetadata(model = {}, result = {}) {
const sha256 = normalizeSha256(result?.sha256 || result?.hash || '');
if (!sha256 || !model || typeof model !== 'object') return;
model.sha256 = sha256;
model.hash = sha256;
if (!model.hashes || typeof model.hashes !== 'object' || Array.isArray(model.hashes)) {
model.hashes = {};
}
model.hashes.SHA256 = sha256;
if (result.metadata_path) {
model.metadata_path = result.metadata_path;
}
},
getHashCompareSourceLabel(sourceKey = '', result = {}) {
const explicitLabel = result?.sourceLabel || result?.source_label || '';
if (explicitLabel) return String(explicitLabel);
const rawSource = normalizeSourceKey(
result?.source || result?.details_source || sourceKey || '',
{ trim: false }
);
return getSourceDisplayLabel(rawSource, {
context: 'hash_compare',
fallback: String(sourceKey || 'Source').replace(/[_-]+/g, ' '),
});
},
getHashCompareResultName(result = {}) {
const primary = result?.name
|| result?.model_name
|| result?.modelName
|| result?.repo_id
|| result?.repo
|| result?.filename
|| result?.path
|| result?.model_url
|| result?.url
|| 'Model';
const version = result?.version_name || result?.versionName || result?.version || '';
const display = this.getVersionedModelName?.(String(primary), String(version || ''))
|| String(primary);
return this.truncateText?.(display, 96) || display;
},
getHashCompareResultUrl(result = {}) {
return String(
result?.version_url
|| result?.model_url
|| result?.platform_url
|| result?.source_url
|| result?.openUrl
|| result?.url
|| result?.download_url
|| ''
).trim();
},
dedupeHashCompareMatches(matches = []) {
const seen = new Set();
const unique = [];
matches.forEach(match => {
if (!match) return;
const key = [
match.sourceLabel || match.sourceKey || '',
match.name || '',
match.url || '',
match.sha256 || ''
].map(value => String(value || '').toLowerCase()).join('::');
if (seen.has(key)) return;
seen.add(key);
unique.push(match);
});
return unique;
},
getHashCompareLocalMatchIdentity(model = {}) {
const explicitIdentity = String(model?.local_match_identity || '').trim();
if (explicitIdentity) return explicitIdentity;
return this.getLocalMatchIdentity?.({ model }) || '';
},
};