Spaces:
Running
Running
Commit Β·
ef20961
1
Parent(s): 8668f1e
Only migrate locations that have a photo; resequence 1..N + remove stale rows
Browse files- supabase_schema.sql: drop the static seed (Male/Female photo sets differ);
rows now come from the migration based on actual uploaded photos
- seed_supabase_locations.py: upload only folders containing a photo, resequence
sort_order 1..N per gender (no gaps), and delete leftover/empty rows so the
app shows only real locations
- scripts/seed_supabase_locations.py +30 -11
- supabase_schema.sql +6 -15
scripts/seed_supabase_locations.py
CHANGED
|
@@ -56,34 +56,53 @@ def main():
|
|
| 56 |
|
| 57 |
print(f"β Supabase: {supabase_store.SUPABASE_URL} bucket={supabase_store.BUCKET}\n")
|
| 58 |
|
| 59 |
-
uploaded = empty = errors = 0
|
| 60 |
for gender in ("Male", "Female"):
|
| 61 |
gdir = os.path.join(LOCATIONS_DIR, gender)
|
| 62 |
if not os.path.isdir(gdir):
|
| 63 |
continue
|
| 64 |
print(f"== {gender} ==")
|
|
|
|
|
|
|
|
|
|
| 65 |
for folder in sorted(os.listdir(gdir), key=folder_number):
|
| 66 |
fpath = os.path.join(gdir, folder)
|
| 67 |
if not os.path.isdir(fpath):
|
| 68 |
continue
|
| 69 |
-
label = clean_label(folder)
|
| 70 |
-
order = folder_number(folder)
|
| 71 |
imgs = [f for f in sorted(os.listdir(fpath)) if f.lower().endswith(IMG_EXTS)]
|
| 72 |
-
if
|
| 73 |
-
|
|
|
|
|
|
|
| 74 |
empty += 1
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
| 76 |
try:
|
| 77 |
-
data = to_jpeg_bytes(
|
| 78 |
-
supabase_store.upsert_location(gender, label, data, sort_order=
|
| 79 |
-
|
|
|
|
| 80 |
uploaded += 1
|
| 81 |
except Exception as e:
|
| 82 |
-
print(f" β {
|
| 83 |
errors += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
print()
|
| 85 |
|
| 86 |
-
print(f"Done β {uploaded} uploaded, {empty} empty,
|
|
|
|
| 87 |
|
| 88 |
|
| 89 |
if __name__ == "__main__":
|
|
|
|
| 56 |
|
| 57 |
print(f"β Supabase: {supabase_store.SUPABASE_URL} bucket={supabase_store.BUCKET}\n")
|
| 58 |
|
| 59 |
+
uploaded = empty = errors = removed = 0
|
| 60 |
for gender in ("Male", "Female"):
|
| 61 |
gdir = os.path.join(LOCATIONS_DIR, gender)
|
| 62 |
if not os.path.isdir(gdir):
|
| 63 |
continue
|
| 64 |
print(f"== {gender} ==")
|
| 65 |
+
|
| 66 |
+
# Only folders that actually contain a photo, in the original 1β19 order.
|
| 67 |
+
with_photos = []
|
| 68 |
for folder in sorted(os.listdir(gdir), key=folder_number):
|
| 69 |
fpath = os.path.join(gdir, folder)
|
| 70 |
if not os.path.isdir(fpath):
|
| 71 |
continue
|
|
|
|
|
|
|
| 72 |
imgs = [f for f in sorted(os.listdir(fpath)) if f.lower().endswith(IMG_EXTS)]
|
| 73 |
+
if imgs:
|
| 74 |
+
with_photos.append((clean_label(folder), os.path.join(fpath, imgs[0])))
|
| 75 |
+
else:
|
| 76 |
+
print(f" Β· {clean_label(folder):<28} β no photo (skipped)")
|
| 77 |
empty += 1
|
| 78 |
+
|
| 79 |
+
# Upload, RESEQUENCED 1..N (gaps from skipped folders removed).
|
| 80 |
+
kept = set()
|
| 81 |
+
for seq, (label, img_path) in enumerate(with_photos, start=1):
|
| 82 |
try:
|
| 83 |
+
data = to_jpeg_bytes(img_path)
|
| 84 |
+
supabase_store.upsert_location(gender, label, data, sort_order=seq)
|
| 85 |
+
kept.add(label)
|
| 86 |
+
print(f" β {seq:>2}. {label:<28} β {os.path.basename(img_path)}")
|
| 87 |
uploaded += 1
|
| 88 |
except Exception as e:
|
| 89 |
+
print(f" β {seq:>2}. {label:<28} ERROR: {e}")
|
| 90 |
errors += 1
|
| 91 |
+
|
| 92 |
+
# Remove any leftover Supabase rows for this gender that we didn't just
|
| 93 |
+
# upload (e.g. empty seeded rows, or locations whose photo was removed).
|
| 94 |
+
for row in supabase_store.list_locations(gender):
|
| 95 |
+
if row["label"] not in kept:
|
| 96 |
+
try:
|
| 97 |
+
supabase_store.delete_location(gender, row["folder"])
|
| 98 |
+
print(f" β removed stale: {row['label']}")
|
| 99 |
+
removed += 1
|
| 100 |
+
except Exception as e:
|
| 101 |
+
print(f" ! could not remove {row['label']}: {e}")
|
| 102 |
print()
|
| 103 |
|
| 104 |
+
print(f"Done β {uploaded} uploaded, {empty} empty (skipped), "
|
| 105 |
+
f"{removed} stale removed, {errors} errors.")
|
| 106 |
|
| 107 |
|
| 108 |
if __name__ == "__main__":
|
supabase_schema.sql
CHANGED
|
@@ -50,18 +50,9 @@ create policy "location images public read"
|
|
| 50 |
on storage.objects for select
|
| 51 |
using (bucket_id = 'location-images');
|
| 52 |
|
| 53 |
-
-- ββ 4.
|
| 54 |
-
--
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
(1,'Marwadi University'),(2,'ICT Department'),(3,'Library'),
|
| 60 |
-
(4,'Electronic Circuit Lab'),(5,'Embedded System Lab'),
|
| 61 |
-
(6,'Data Science And AI Lab'),(7,'Ideation Lab'),(8,'IoT Lab'),
|
| 62 |
-
(9,'VLSI Lab'),(10,'Web Development Lab'),(11,'Project Lab'),
|
| 63 |
-
(12,'Programming Lab'),(13,'MUIIR'),(14,'Classroom'),
|
| 64 |
-
(15,'Sports Ground'),(16,'Field'),(17,'Music Room'),
|
| 65 |
-
(18,'Library G Floor'),(19,'Ground')
|
| 66 |
-
) as l(ord, name)
|
| 67 |
-
on conflict (gender, name) do nothing;
|
|
|
|
| 50 |
on storage.objects for select
|
| 51 |
using (bucket_id = 'location-images');
|
| 52 |
|
| 53 |
+
-- ββ 4. Rows are NOT seeded here ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 54 |
+
-- Locations are created from the photos you actually uploaded, by running:
|
| 55 |
+
-- python scripts/seed_supabase_locations.py
|
| 56 |
+
-- Only folders that contain a photo become rows (resequenced 1..N per gender),
|
| 57 |
+
-- and the Control Panel adds/updates more later. This avoids empty placeholder
|
| 58 |
+
-- locations showing up on the app page.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|