Skip to content

Commit 0e00220

Browse files
committed
stablize
1 parent d2ccab7 commit 0e00220

File tree

8 files changed

+41
-13
lines changed

8 files changed

+41
-13
lines changed

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,27 @@ load-weights:
1818
docker run --name extract-model \
1919
-v $$HOME/.cache/huggingface:/root/.cache/huggingface \
2020
-e MODEL_REPO="$(MODEL_REPO)" \
21+
-e MODEL_REVISION="$(MODEL_REVISION)" \
2122
-e FILENAMES="$(FILENAMES)" \
2223
weights-loader \
23-
sh -c 'python /dock/hugging-offline.py --repo-id "$$MODEL_REPO" --filenames $$FILENAMES > /dock/build.log 2>&1'
24+
sh -c 'python /dock/hugging-offline.py --repo-id "$$MODEL_REPO" --revision "$$MODEL_REVISION" --filenames $$FILENAMES > /dock/build.log 2>&1'
2425
@echo "Part 3/3 Copying weights to local directory and display log"
2526
docker cp extract-model:/dock/models/. ./models/
2627
docker cp extract-model:/dock/build.log ./weights.log || true
2728
docker rm extract-model
2829
cat ./weights.log || true
2930

3031
load-aesthetic-scorer:
32+
@[ -n "$(AESTHETIC_SCORER_REVISION)" ] || (echo "Set AESTHETIC_SCORER_REVISION to an immutable commit hash before download"; exit 1)
3133
$(MAKE) load-clip-vit-base-patch32
3234
$(MAKE) load-weights MODEL_REPO="rsinema/aesthetic-scorer" \
35+
MODEL_REVISION="$(AESTHETIC_SCORER_REVISION)" \
3336
FILENAMES="model.pt preprocessor_config.json tokenizer.json tokenizer_config.json special_tokens_map.json merges.txt vocab.json"
3437

3538
load-clip-vit-base-patch32:
39+
@[ -n "$(CLIP_VIT_REVISION)" ] || (echo "Set CLIP_VIT_REVISION to an immutable commit hash before download"; exit 1)
3640
$(MAKE) load-weights MODEL_REPO="openai/clip-vit-base-patch32" \
41+
MODEL_REVISION="$(CLIP_VIT_REVISION)" \
3742
FILENAMES="pytorch_model.bin config.json preprocessor_config.json tokenizer.json tokenizer_config.json special_tokens_map.json merges.txt vocab.json"
3843

3944
build-ai-api:

app/api/admin/rename/route.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ async function POST(req: NextRequest) {
1414
if (isZodError(err)) {
1515
return NextResponse.json(errorSchema(simplifyZodMessages(err)), { status: 400 })
1616
}
17+
if (err instanceof ReferenceError) {
18+
return NextResponse.json(errorSchema(err.message), { status: 400 })
19+
}
1720
return NextResponse.json(errorSchema('Internal Server Error'), { status: 500 })
1821
}
1922
}

apps/load-weights/hugging-offline.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def log_huggingface_whoami():
2626
except Exception as e:
2727
logger.error(f"❌ Unable to verify Hugging Face authentication: {e}")
2828

29-
def download_weights(repo_id: str, filenames: list[str]):
29+
def download_weights(repo_id: str, filenames: list[str], revision: str | None = None):
3030
log_huggingface_whoami()
3131
# Create destination path
3232
dest_dir = os.path.join("models", repo_id.replace("/", "_"))
@@ -35,7 +35,11 @@ def download_weights(repo_id: str, filenames: list[str]):
3535
for filename in filenames:
3636
logger.info(f"📥 Downloading {filename} from {repo_id} on Hugging Face Hub...")
3737
try:
38-
path = hf_hub_download(repo_id=repo_id, filename=filename)
38+
path = hf_hub_download(
39+
repo_id=repo_id,
40+
filename=filename,
41+
revision=revision or None,
42+
)
3943
# Move and rename
4044
dest_path = os.path.join(dest_dir, filename)
4145
shutil.copy(path, dest_path)
@@ -68,5 +72,10 @@ def download_weights(repo_id: str, filenames: list[str]):
6872
default=["pytorch_model.bin", "config.json"],
6973
help="List of filenames to download (space-separated)"
7074
)
75+
parser.add_argument(
76+
"--revision",
77+
default=None,
78+
help="Optional immutable model revision/commit to pin downloads"
79+
)
7180
args = parser.parse_args()
72-
download_weights(args.repo_id, args.filenames)
81+
download_weights(args.repo_id, args.filenames, args.revision)

src/components/All/Items.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { MouseEvent, RefObject } from 'react'
12
import type { ImageGalleryRef } from 'react-image-gallery'
23
import { useCallback } from 'react'
34

@@ -12,18 +13,18 @@ const SHOW_THUMB_MIN_LEN = 3
1213
interface InputProps {
1314
items: ServerSideAllItem[];
1415
keyword: string;
15-
refImageGallery: React.RefObject<ImageGalleryRef | null>;
16+
refImageGallery: RefObject<ImageGalleryRef | null>;
1617
}
1718

1819
function All({ items, keyword, refImageGallery }: InputProps) {
19-
const showThumbnail = keyword.length > SHOW_THUMB_MIN_LEN
20+
const showThumbnail = keyword.length >= SHOW_THUMB_MIN_LEN
2021
const { width, height } = config.resizeDimensions.thumb
2122

2223
const selectThumb = useCallback((index: number) => {
2324
refImageGallery.current?.slideToIndex(index)
2425
}, [refImageGallery])
2526

26-
const handleSlideToClick = useCallback((e: React.MouseEvent<HTMLUListElement>) => {
27+
const handleSlideToClick = useCallback((e: MouseEvent<HTMLUListElement>) => {
2728
const btn = (e.target as HTMLElement).closest('button[data-slide-index]')
2829
const idx = btn?.getAttribute('data-slide-index')
2930
if (idx != null) selectThumb(Number(idx))
@@ -38,7 +39,7 @@ function All({ items, keyword, refImageGallery }: InputProps) {
3839
{!showThumbnail && item.caption}
3940
{showThumbnail && <Img src={item.thumbPath} alt={item.caption} title={item.corpus} width={width} height={height} />}
4041
</Link>
41-
<button className={styles.slideTo} type="button" data-slide-index={index}><a>Slide to</a></button>
42+
<button className={styles.slideTo} type="button" data-slide-index={index}>Slide to</button>
4243
</li>
4344
))}
4445
</ul>

src/hooks/useSearch.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ export default function useSearch<ItemType extends ServerSideItem>({
128128
? (currentItem as any).filename[0]
129129
: (currentItem as any).filename)
130130
: null
131-
const coordinates = (currentItem as any)?.coordinates as [number, number] | null
132131

133132
if (selectById && identifier) {
134133
selectById(identifier, true)
@@ -210,6 +209,7 @@ export default function useSearch<ItemType extends ServerSideItem>({
210209
variant="plain"
211210
onClick={handleClear}
212211
title="Clear search and view adjacent photos"
212+
aria-label="Clear advanced query"
213213
>
214214
×
215215
</Button>
@@ -226,6 +226,7 @@ export default function useSearch<ItemType extends ServerSideItem>({
226226
variant="plain"
227227
onClick={() => handleRemoveKeywordToken(idx)}
228228
title={`Remove keyword token ${token}`}
229+
aria-label={`Remove keyword token ${token}`}
229230
>
230231
×
231232
</Button>
@@ -245,6 +246,7 @@ export default function useSearch<ItemType extends ServerSideItem>({
245246
variant="plain"
246247
onClick={() => onClearMapFilter?.()}
247248
title="Clear map filter"
249+
aria-label="Clear map filter"
248250
>
249251
×
250252
</Button>

src/lib/filenames.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,20 @@ function futureFilenamesOutputs(sourceFilenames: string[], prefix: string, xmlSt
111111
return outputFormats()
112112
}
113113

114-
function exactModeOutputs(orderedBases: string[], exactFilenameBase: string) {
114+
function exactModeOutputs(
115+
orderedBases: string[],
116+
exactFilenameBase: string,
117+
sourceFilenames: string[] = orderedBases.map((base) => `${base}.jpg`),
118+
) {
119+
if (orderedBases.length !== 1) {
120+
throw new ReferenceError('Exact filename mode requires a single selected base')
121+
}
122+
115123
const files = orderedBases.map(() => exactFilenameBase)
116124
const items: AlbumXmlItem[] = files.map((file) => ({
117125
base: file,
118126
filename: `${file}.jpg`,
119-
isVideo: false,
127+
isVideo: videoTypeInList(sourceFilenames, orderedBases[0]),
120128
}))
121129
// Exact mode starts at 101 so first item id is MMDD01.
122130
return { files, xml: buildAlbumXml(items, 101) }

src/lib/rename.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async function renamePaths({
6666
const effectivePrefix = trimmed
6767

6868
const generated = useExact
69-
? exactModeOutputs(orderedBases, effectivePrefix)
69+
? exactModeOutputs(orderedBases, effectivePrefix, filtered)
7070
: futureFilenamesOutputs(orderedBases, effectivePrefix)
7171
const baseToNewBase = new Map(orderedBases.map((b, i) => [b, generated.files[i]]))
7272

src/utils/person-age.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function buildAgeSummary(items: Item[]): { ages: { age: number; count: nu
6060
it.persons.forEach((p) => {
6161
if (!p.dob) return
6262
const age = calcAgeAtDate(p.dob, photoDate)
63-
if (age !== null) counts.set(age, (counts.get(age) || 0) + 1)
63+
if (age !== null && age >= 0) counts.set(age, (counts.get(age) || 0) + 1)
6464
})
6565
})
6666
return {

0 commit comments

Comments
 (0)