Upload 2 files
Browse files- app.py +1 -1
- templates/step4_results.html +28 -6
app.py
CHANGED
|
@@ -424,7 +424,7 @@ def process_drive_with_parallel_face_detection(job_id, folder_id, upload_dir, fa
|
|
| 424 |
if download_complete.is_set():
|
| 425 |
pct = 30 + int((processed_count[0] / max(total_files[0], 1)) * 40)
|
| 426 |
processing_jobs[job_id]['progress'] = min(pct, 70)
|
| 427 |
-
processing_jobs[job_id]['message'] = f'Scanning faces: {processed_count[0]}/{total_files[0]}
|
| 428 |
processing_jobs[job_id]['photos_checked'] = processed_count[0]
|
| 429 |
print(f"[Job {job_id}] [HYBRID] Downloaded: {downloaded_count[0]}, Face checked: {processed_count[0]}, Matched: {len(matched_photos)}")
|
| 430 |
|
|
|
|
| 424 |
if download_complete.is_set():
|
| 425 |
pct = 30 + int((processed_count[0] / max(total_files[0], 1)) * 40)
|
| 426 |
processing_jobs[job_id]['progress'] = min(pct, 70)
|
| 427 |
+
processing_jobs[job_id]['message'] = f'Scanning faces: {processed_count[0]}/{total_files[0]}'
|
| 428 |
processing_jobs[job_id]['photos_checked'] = processed_count[0]
|
| 429 |
print(f"[Job {job_id}] [HYBRID] Downloaded: {downloaded_count[0]}, Face checked: {processed_count[0]}, Matched: {len(matched_photos)}")
|
| 430 |
|
templates/step4_results.html
CHANGED
|
@@ -844,14 +844,32 @@
|
|
| 844 |
|
| 845 |
.cluster-photo {
|
| 846 |
position: relative;
|
| 847 |
-
width:
|
| 848 |
-
height: 140px;
|
| 849 |
border-radius: 12px;
|
| 850 |
overflow: hidden;
|
| 851 |
cursor: pointer;
|
| 852 |
border: 4px solid transparent;
|
| 853 |
transition: all 0.2s;
|
| 854 |
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 855 |
}
|
| 856 |
|
| 857 |
.cluster-photo:hover {
|
|
@@ -868,7 +886,7 @@
|
|
| 868 |
opacity: 0.85;
|
| 869 |
}
|
| 870 |
|
| 871 |
-
.cluster-photo img {
|
| 872 |
width: 100%;
|
| 873 |
height: 100%;
|
| 874 |
object-fit: cover;
|
|
@@ -2308,15 +2326,19 @@
|
|
| 2308 |
for (const p of clusterPhotos) {
|
| 2309 |
const scorePercent = p.score ? (p.score * 100).toFixed(0) : '0';
|
| 2310 |
const pThumb = getPhotoThumbnail(p);
|
|
|
|
| 2311 |
|
| 2312 |
const div = document.createElement('div');
|
| 2313 |
div.className = `cluster-photo ${p.isSelected ? 'selected' : 'rejected'}`;
|
| 2314 |
div.onclick = () => openModal(p, p.isSelected);
|
| 2315 |
|
| 2316 |
div.innerHTML = `
|
| 2317 |
-
<
|
| 2318 |
-
|
| 2319 |
-
|
|
|
|
|
|
|
|
|
|
| 2320 |
`;
|
| 2321 |
|
| 2322 |
clusterPhotosDiv.appendChild(div);
|
|
|
|
| 844 |
|
| 845 |
.cluster-photo {
|
| 846 |
position: relative;
|
| 847 |
+
width: 160px;
|
|
|
|
| 848 |
border-radius: 12px;
|
| 849 |
overflow: hidden;
|
| 850 |
cursor: pointer;
|
| 851 |
border: 4px solid transparent;
|
| 852 |
transition: all 0.2s;
|
| 853 |
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
| 854 |
+
background: #f8f8f8;
|
| 855 |
+
}
|
| 856 |
+
|
| 857 |
+
.cluster-photo-img {
|
| 858 |
+
width: 100%;
|
| 859 |
+
height: 160px;
|
| 860 |
+
position: relative;
|
| 861 |
+
overflow: hidden;
|
| 862 |
+
}
|
| 863 |
+
|
| 864 |
+
.cluster-photo-filename {
|
| 865 |
+
padding: 6px 8px;
|
| 866 |
+
font-size: 11px;
|
| 867 |
+
color: #555;
|
| 868 |
+
text-align: center;
|
| 869 |
+
white-space: nowrap;
|
| 870 |
+
overflow: hidden;
|
| 871 |
+
text-overflow: ellipsis;
|
| 872 |
+
background: #f8f8f8;
|
| 873 |
}
|
| 874 |
|
| 875 |
.cluster-photo:hover {
|
|
|
|
| 886 |
opacity: 0.85;
|
| 887 |
}
|
| 888 |
|
| 889 |
+
.cluster-photo-img img {
|
| 890 |
width: 100%;
|
| 891 |
height: 100%;
|
| 892 |
object-fit: cover;
|
|
|
|
| 2326 |
for (const p of clusterPhotos) {
|
| 2327 |
const scorePercent = p.score ? (p.score * 100).toFixed(0) : '0';
|
| 2328 |
const pThumb = getPhotoThumbnail(p);
|
| 2329 |
+
const displayName = p.filename.length > 18 ? p.filename.substring(0, 15) + '...' : p.filename;
|
| 2330 |
|
| 2331 |
const div = document.createElement('div');
|
| 2332 |
div.className = `cluster-photo ${p.isSelected ? 'selected' : 'rejected'}`;
|
| 2333 |
div.onclick = () => openModal(p, p.isSelected);
|
| 2334 |
|
| 2335 |
div.innerHTML = `
|
| 2336 |
+
<div class="cluster-photo-img">
|
| 2337 |
+
<img src="/thumbnail/${jobId}/${pThumb}" alt="${p.filename}">
|
| 2338 |
+
<div class="cluster-photo-score">${scorePercent}%</div>
|
| 2339 |
+
<div class="cluster-photo-badge">${p.isSelected ? '✓' : '✗'}</div>
|
| 2340 |
+
</div>
|
| 2341 |
+
<div class="cluster-photo-filename" title="${p.filename}">${displayName}</div>
|
| 2342 |
`;
|
| 2343 |
|
| 2344 |
clusterPhotosDiv.appendChild(div);
|