Implement fetching photos from photoprism #19
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
|||||||
module go.balki.me/collage-maker
|
module go.balki.me/collage-maker
|
||||||
|
|
||||||
go 1.21
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
go.balki.me/anyhttp v0.3.0
|
go.balki.me/anyhttp v0.3.0
|
||||||
|
34
main.go
34
main.go
@ -58,8 +58,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
return photoPrismURL
|
return photoPrismURL
|
||||||
}()
|
}()
|
||||||
copy := *photoPrismURL
|
|
||||||
fmt.Println(copy)
|
|
||||||
collageNameGen = NewNameGen()
|
collageNameGen = NewNameGen()
|
||||||
imagesDirFs = os.DirFS(imagesDir)
|
imagesDirFs = os.DirFS(imagesDir)
|
||||||
imagesURLPath := "images"
|
imagesURLPath := "images"
|
||||||
@ -147,6 +145,38 @@ func main() {
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write(jData)
|
w.Write(jData)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/load-photos/{albumID}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
albumID := r.PathValue("albumID")
|
||||||
|
photos, err := LoadPhotos(albumID)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to load photos", "error", err, "album", albumID)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
photoURLs := []string{}
|
||||||
|
for _, photo := range photos {
|
||||||
|
photoURLs = append(photoURLs, fmt.Sprintf("/%s/%s.jpg", photosPath, photo.FileUID))
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for _, photo := range photos {
|
||||||
|
_, err := DownloadPhoto(&photo)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to download photo", "error", err, "album", albumID, "photoID", photo.FileUID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
jData, err := json.Marshal(photoURLs)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to marshal photoURLs", "error", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Write(jData)
|
||||||
|
})
|
||||||
|
|
||||||
addrType, server, done, err := anyhttp.Serve(listenAddr, idle.WrapHandler(nil))
|
addrType, server, done, err := anyhttp.Serve(listenAddr, idle.WrapHandler(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("anyhttp Serve failed", "error", err)
|
slog.Error("anyhttp Serve failed", "error", err)
|
||||||
|
47
web/choose.css
Normal file
47
web/choose.css
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#album_photos {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background-color: lightblue;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#album_photos img {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#selected_photos {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background-color: lightyellow;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#selected_photos img {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
background-color: lightgrey;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#album_selector {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current {
|
||||||
|
border: 5px solid;
|
||||||
|
border-color: red;
|
||||||
|
}
|
@ -4,20 +4,34 @@
|
|||||||
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
|
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
|
||||||
<!-- DEVONLY --> <script src="http://localhost:35729/livereload.js"></script>
|
<!-- DEVONLY --> <script src="http://localhost:35729/livereload.js"></script>
|
||||||
<script src="choose.js" defer></script>
|
<script src="choose.js" defer></script>
|
||||||
|
<link rel="stylesheet" href="choose.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<dialog id="notice_dialog">
|
<dialog id="notice_dialog">
|
||||||
<p id="notice_p"></p>
|
<p id="notice_p"></p>
|
||||||
<form><button type="submit" formmethod="dialog">X</button></form>
|
<form><button type="submit" formmethod="dialog">X</button></form>
|
||||||
</dialog>
|
</dialog>
|
||||||
<label>
|
<div class="container">
|
||||||
<span>Select Album</span>
|
<div class="controls">
|
||||||
<select id="album_selector" size="8">
|
<button id="load_albums_button">Load Albums</button>
|
||||||
</select>
|
<select id="album_selector" size="8"> </select>
|
||||||
</label>
|
<button id="load_photos_button">Load Photos</button>
|
||||||
<button id="load_albums_button">Load Albums</button>
|
</div>
|
||||||
<button id="load_photos_button">Load Photos</button>
|
<div id="selected_photos">
|
||||||
<div id="selected_photos"></div>
|
<div>1<img src="stock.jpg" /> </div>
|
||||||
|
<div>2<img src="stock.jpg" /> </div>
|
||||||
|
<div>3<img src="stock.jpg" /> </div>
|
||||||
|
<div>4<img src="stock.jpg" /> </div>
|
||||||
|
<div>5<img src="stock.jpg" /> </div>
|
||||||
|
<div>6<img src="stock.jpg" /> </div>
|
||||||
|
<div>7<img src="stock.jpg" /> </div>
|
||||||
|
<div>8<img src="stock.jpg" /> </div>
|
||||||
|
<div>9<img src="stock.jpg" /> </div>
|
||||||
|
<div>10<img src="stock.jpg" /> </div>
|
||||||
|
<div>11<img src="stock.jpg" /> </div>
|
||||||
|
<div>12<img src="stock.jpg" /> </div>
|
||||||
|
</div>
|
||||||
<div id="album_photos"></div>
|
<div id="album_photos"></div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -17,14 +17,38 @@ let noticeP
|
|||||||
/** @type {HTMLDialogElement} */
|
/** @type {HTMLDialogElement} */
|
||||||
let noticeDialog
|
let noticeDialog
|
||||||
|
|
||||||
|
/** @type {HTMLDivElement} */
|
||||||
|
let albumPhotosDiv
|
||||||
|
|
||||||
|
/** @type {HTMLDivElement} */
|
||||||
|
let selectedPhotosDiv
|
||||||
|
|
||||||
|
/** @type {HTMLImageElement} */
|
||||||
|
let selectedPhotoImg
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
albumSelect = document.getElementById("album_selector")
|
albumSelect = document.getElementById("album_selector")
|
||||||
loadAlbumsBtn = document.getElementById("load_albums_button")
|
loadAlbumsBtn = document.getElementById("load_albums_button")
|
||||||
loadPhotosBtn = document.getElementById("load_photos_button")
|
loadPhotosBtn = document.getElementById("load_photos_button")
|
||||||
noticeDialog = document.getElementById("notice_dialog")
|
noticeDialog = document.getElementById("notice_dialog")
|
||||||
|
albumPhotosDiv = document.getElementById("album_photos")
|
||||||
|
selectedPhotosDiv = document.getElementById("selected_photos")
|
||||||
noticeP = document.getElementById("notice_p")
|
noticeP = document.getElementById("notice_p")
|
||||||
loadAlbumsBtn.onclick = () => loadAlbums()
|
loadAlbumsBtn.onclick = () => loadAlbums()
|
||||||
loadPhotosBtn.onclick = () => loadPhotos()
|
loadPhotosBtn.onclick = () => loadPhotos()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type HTMLImageElement[]
|
||||||
|
*/
|
||||||
|
const selectedPhotos = selectedPhotosDiv.getElementsByTagName("img")
|
||||||
|
for (const img of selectedPhotos) {
|
||||||
|
img.onclick = () => {
|
||||||
|
selectedPhotoImg?.classList.remove("current")
|
||||||
|
selectedPhotoImg = img
|
||||||
|
selectedPhotoImg.classList.add("current")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedPhotos[0].click()
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAlbums() {
|
function loadAlbums() {
|
||||||
@ -67,9 +91,38 @@ function loadPhotos() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const [elem] = selected
|
const [elem] = selected
|
||||||
console.log(elem)
|
|
||||||
console.log(elem.text)
|
(async () => {
|
||||||
console.log(elem.value)
|
try {
|
||||||
|
const resp = await fetch(`load-photos/${elem.value}`)
|
||||||
|
/**
|
||||||
|
* @type String[]
|
||||||
|
*/
|
||||||
|
const photos = await resp.json()
|
||||||
|
if(photos.length == 0) {
|
||||||
|
showNotice("No Photos found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
albumPhotosDiv.replaceChildren()
|
||||||
|
for(const url of photos) {
|
||||||
|
const img = new Image()
|
||||||
|
img.src = url
|
||||||
|
albumPhotosDiv.appendChild(img)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type HTMLImageElement[]
|
||||||
|
*/
|
||||||
|
const photoImgs = albumPhotosDiv.children
|
||||||
|
for(const photo of photoImgs) {
|
||||||
|
photo.onclick = () => {
|
||||||
|
selectedPhotoImg.src = photo.src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user