Skip to content

Commit 6c13220

Browse files
lsteinLincoln Stein
andauthored
clean up in anticipation of 9.0.2 release (#70)
- rename album.js to album-manager.js for consistency with .py and .css files - change user message "starting umapping" to "starting mapping" to avoid jargon - UPDATE REQUIREMENTS TO 3.10-3.13. 3.13 seems to work fine. - update documentation Co-authored-by: Lincoln Stein <lstein@gmail.com>
1 parent c1748f5 commit 6c13220

12 files changed

Lines changed: 59 additions & 43 deletions

File tree

INSTALL/lib/windows.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ $version = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_
7777
if (-not $version) {
7878
Install-Python "Could not determine Python version."
7979
}
80-
if ([version]$version -lt [version]"3.10" -or [version]$version -ge [version]"3.13") {
80+
if ([version]$version -lt [version]"3.10" -or [version]$version -ge [version]"3.14") {
8181
Install-Python "An incompatible Python version is installed."
8282
}
8383

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ PhotoMap's unique feature is its ability to identify thematically similar images
2727

2828
In this map, each image in the photo collection is represented as a dot. The colors distinguish different clusters of related images. You can zoom in and out of the map and pan around it. Hover the mouse over a dot in order to see a preview thumbnail of its image, or click on a cluster to view its contents at full resolution.
2929

30-
You can move the semantic map around, shrink it down in size, or hide it altogether. As you browser your photo collection, a yellow dot marker will highlight the location of the current image in the map.
30+
You can move the semantic map around, shrink it down in size, or hide it altogether. As you browse your photo collection, a yellow dot marker will highlight the location of the current image in the map.
3131

3232
## Text and Image Similarity Search
3333

@@ -118,7 +118,7 @@ Follow these instructions if you are comfortable with installing Python packages
118118

119119
#### Mac/Linux
120120

121-
Make sure that your version of Python is between 3.10 and 3.12. Not all required libraries are available in 3.13.
121+
Make sure that your version of Python is between 3.10 and 3.13. Other versions are not guaranteed to work.
122122

123123
python3 -m venv ~/photomap --prompt photomap
124124
source ~/photomap/bin/activate
@@ -130,7 +130,7 @@ Then open your web browser and point it to [http://127.0.0.1:8050](http://128.0.
130130

131131
#### Windows
132132

133-
Make sure that your version of Python is between 3.10 and 3.12. Not all required libraries are available in 3.13. Also make sure that Python is on your PATH.
133+
Make sure that your version of Python is between 3.10 and 3.13. Other versions are not guaranteed to work. Also make sure that Python is on your PATH.
134134

135135
python3 -m venv C:\Users\<your name>\Documents\photomap --prompt photomap
136136
C:\Users\<your name>\Documents\photomap\Scripts\activate

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ PhotoMapAI's unique feature is its ability to identify thematically similar imag
3434

3535
In this map, each image in the photo collection is represented as a dot. The colors distinguish different clusters of related images. You can zoom in and out of the map and pan around it. Hover the mouse over a dot in order to see a preview thumbnail of its image, or click on a cluster to view its contents at full resolution.
3636

37-
You can move the semantic map around, shrink it down in size, or hide it altogether. As you browser your photo collection, a yellow dot marker will highlight the location of the current image in the map.
37+
You can move the semantic map around, shrink it down in size, or hide it altogether. As you browse your photo collection, a yellow dot marker will highlight the location of the current image in the map.
3838

3939
## Text and Image Similarity Search
4040

photomap/backend/embeddings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def traversal_callback(count, message):
478478
progress_tracker.set_error(album_key, str(e))
479479
raise
480480

481-
progress_tracker.start_operation(album_key, total_images, "umapping")
481+
progress_tracker.start_operation(album_key, total_images, "mapping")
482482
try:
483483
umap_embeddings = await asyncio.to_thread(
484484
self.create_umap_index, result.embeddings
@@ -669,7 +669,7 @@ def traversal_callback(count, message):
669669
self._save_embeddings(combined_result)
670670

671671
# Rebuild the umap index
672-
progress_tracker.start_operation(album_key, total_new_images, "umapping")
672+
progress_tracker.start_operation(album_key, total_new_images, "mapping")
673673
new_result.umap_embeddings = await asyncio.to_thread(
674674
lambda: self.umap_embeddings
675675
)

photomap/backend/progress.py

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
'''
1+
"""
22
Progress tracking module for indexing operations in Clipslide.
33
This module provides a global progress tracker for indexing operations,
44
allowing for tracking the status, progress, and estimated time remaining
5-
for each album being processed.'''
6-
from typing import Dict, Optional
5+
for each album being processed."""
6+
7+
import logging
8+
import time
79
from dataclasses import dataclass
810
from enum import Enum
9-
import time
10-
import logging
11+
from typing import Dict, Optional
1112

1213
logging.basicConfig(level=logging.INFO)
1314
logger = logging.getLogger(__name__)
1415

16+
1517
class IndexStatus(Enum):
1618
IDLE = "idle"
1719
SCANNING = "scanning"
1820
INDEXING = "indexing"
19-
UMAPPING = "umapping"
21+
UMAPPING = "mapping"
2022
COMPLETED = "completed"
2123
ERROR = "error"
2224

25+
2326
@dataclass
2427
class ProgressInfo:
2528
album_key: str
@@ -29,17 +32,17 @@ class ProgressInfo:
2932
total_images: int
3033
start_time: float
3134
error_message: Optional[str] = None
32-
35+
3336
@property
34-
def progress_percentage(self)-> float:
37+
def progress_percentage(self) -> float:
3538
if self.total_images == 0:
3639
return 0.0
3740
return (self.images_processed / self.total_images) * 100
38-
41+
3942
@property
4043
def elapsed_time(self) -> float:
4144
return time.time() - self.start_time
42-
45+
4346
@property
4447
def estimated_time_remaining(self) -> Optional[float]:
4548
if self.images_processed == 0:
@@ -48,12 +51,13 @@ def estimated_time_remaining(self) -> Optional[float]:
4851
remaining_images = self.total_images - self.images_processed
4952
return remaining_images / rate if rate > 0 else None
5053

54+
5155
class ProgressTracker:
5256
"""Global progress tracker for indexing operations."""
53-
57+
5458
def __init__(self):
5559
self._progress: Dict[str, ProgressInfo] = {}
56-
60+
5761
def start_operation(self, album_key: str, total_images: int, operation_type: str):
5862
"""Start tracking progress for an album."""
5963
self._progress[album_key] = ProgressInfo(
@@ -62,50 +66,62 @@ def start_operation(self, album_key: str, total_images: int, operation_type: str
6266
current_step=f"Starting {operation_type}",
6367
images_processed=0,
6468
total_images=total_images,
65-
start_time=time.time()
69+
start_time=time.time(),
6670
)
67-
71+
6872
def update_total_images(self, album_key: str, total_images: int):
6973
"""Update the total number of images for an operation."""
7074
if album_key in self._progress:
7175
self._progress[album_key].total_images = total_images
72-
73-
def update_progress(self, album_key: str, images_processed: int, current_step: str = ""):
76+
77+
def update_progress(
78+
self, album_key: str, images_processed: int, current_step: str = ""
79+
):
7480
"""Update progress for an album."""
7581
if album_key in self._progress:
7682
progress = self._progress[album_key]
7783
progress.images_processed = images_processed
7884
progress.current_step = current_step
79-
if images_processed >= progress.total_images and progress.status != IndexStatus.SCANNING:
85+
if (
86+
images_processed >= progress.total_images
87+
and progress.status != IndexStatus.SCANNING
88+
):
8089
progress.status = IndexStatus.COMPLETED
81-
90+
8291
def set_error(self, album_key: str, error_message: str):
8392
"""Set error status for an album."""
8493
if album_key in self._progress:
8594
progress = self._progress[album_key]
8695
progress.status = IndexStatus.ERROR
8796
progress.error_message = error_message
88-
97+
8998
def get_progress(self, album_key: str) -> Optional[ProgressInfo]:
9099
"""Get progress info for an album."""
91100
return self._progress.get(album_key)
92-
101+
93102
def remove_progress(self, album_key: str):
94103
"""Remove progress tracking for an album."""
95104
self._progress.pop(album_key, None)
96-
105+
97106
def is_running(self, album_key: str) -> bool:
98107
"""Check if an operation is currently running for an album."""
99108
progress = self._progress.get(album_key)
100-
return progress is not None and progress.status in [IndexStatus.SCANNING, IndexStatus.INDEXING, IndexStatus.UMAPPING]
101-
102-
def complete_operation(self, album_key: str, message: str = "Operation completed") -> None:
109+
return progress is not None and progress.status in [
110+
IndexStatus.SCANNING,
111+
IndexStatus.INDEXING,
112+
IndexStatus.UMAPPING,
113+
]
114+
115+
def complete_operation(
116+
self, album_key: str, message: str = "Operation completed"
117+
) -> None:
103118
"""Mark an operation as completed."""
104119
if album_key in self._progress:
105120
progress = self._progress[album_key]
106121
progress.status = IndexStatus.COMPLETED
107122
progress.current_step = message
108123
progress.images_processed = progress.total_images
109124

125+
110126
# Global instance
111-
progress_tracker = ProgressTracker()
127+
progress_tracker = ProgressTracker()

photomap/frontend/static/javascript/album.js renamed to photomap/frontend/static/javascript/album-manager.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class AlbumManager {
1919
static STATUS_CLASSES = {
2020
SCANNING: "index-status scanning",
2121
INDEXING: "index-status indexing",
22-
UMAPPING: "index-status umapping",
22+
UMAPPING: "index-status mapping",
2323
COMPLETED: "index-status completed",
2424
ERROR: "index-status error",
2525
DEFAULT: "index-status",
@@ -802,7 +802,7 @@ export class AlbumManager {
802802
// Just show the progress UI and let the existing polling handle updates
803803
setTimeout(() => {
804804
this.showProgressUI(albumCard); // This will scroll into view
805-
}, AlbumManager.AUTO_INDEX_DELAY);
805+
}, AlbumManager.AUTO_INDEXING_DELAY);
806806
}
807807
}
808808

@@ -1023,7 +1023,7 @@ export class AlbumManager {
10231023
if (
10241024
progress.status === "indexing" ||
10251025
progress.status === "scanning" ||
1026-
progress.status === "umapping"
1026+
progress.status === "mapping"
10271027
) {
10281028
console.log(
10291029
`Backend reports indexing already in progress for album: ${albumKey}`
@@ -1274,9 +1274,9 @@ export class AlbumManager {
12741274
status.textContent = progress.current_step || "Scanning for images...";
12751275
status.style.color = "#ff9800"; // Orange for scanning
12761276
estimatedTime.textContent = "";
1277-
} else if (progress.status === "umapping") {
1277+
} else if (progress.status === "mapping") {
12781278
status.className = AlbumManager.STATUS_CLASSES.UMAPPING;
1279-
status.textContent = progress.current_step || "Generating image umap...";
1279+
status.textContent = progress.current_step || "Generating image map...";
12801280
status.style.color = "#2196f3"; // Blue for umapping
12811281
estimatedTime.textContent = "";
12821282
} else {

photomap/frontend/static/javascript/events.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// events.js
22
// This file manages event listeners for the application, including slide transitions and slideshow controls.
3-
import { checkAlbumIndex } from "./album.js";
3+
import { checkAlbumIndex } from "./album-manager.js";
44
import { eventRegistry } from "./event-registry.js";
55
import { initializeGridSwiper } from "./grid-view.js";
66
import { deleteImage, getIndexMetadata } from "./index.js";

photomap/frontend/static/javascript/settings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// settings.js
22
// This file manages the settings of the application, including saving and restoring settings to/from local storage
3-
import { albumManager } from "./album.js";
3+
import { albumManager } from "./album-manager.js";
44
import { exitSearchMode } from "./search-ui.js";
55
import { saveSettingsToLocalStorage, setAlbum, state } from "./state.js";
66
import { addNewSlide, removeSlidesAfterCurrent } from "./swiper.js";

photomap/frontend/static/javascript/state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// state.js
22
// This file manages the state of the application, including slide management and metadata handling.
3-
import { albumManager } from "./album.js";
3+
import { albumManager } from "./album-manager.js";
44
import { getIndexMetadata } from "./index.js";
55
import { switchAlbum } from "./settings.js";
66

photomap/frontend/static/javascript/umap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// umap.js
22
// This file handles the UMAP visualization and interaction logic.
3-
import { albumManager } from "./album.js";
3+
import { albumManager } from "./album-manager.js";
44
import { getImagePath, setSearchResults } from "./search.js";
55
import { getCurrentSlideIndex } from "./slide-state.js";
66
import { state } from "./state.js";

0 commit comments

Comments
 (0)