1
0
Fork 0
photos/cmd/web/web.go

176 lines
3.8 KiB
Go

package main
import (
"bytes"
"fmt"
"net/http"
"os"
"time"
"git.makerforce.io/photos/photos/internal/httphelpers"
lib "git.makerforce.io/photos/photos/pkg/bucket"
"git.makerforce.io/photos/photos/pkg/credentials"
"git.makerforce.io/photos/photos/pkg/signer"
"git.makerforce.io/photos/photos/web"
)
var creds *credentials.Client
var sig *signer.Signer
var sharedFileServer http.Handler
var endpoint string
var controlEndpoint string
func main() {
var err error
// Setup bucket credential source
creds, err = credentials.NewClientFromEnv()
if err != nil {
panic(err)
}
// Setup bucket signer
sig, err = signer.NewSignerFromEnv()
if err != nil {
panic(err)
}
transport := &http.Transport{
MaxIdleConns: 4,
MaxIdleConnsPerHost: 4,
IdleConnTimeout: 60 * time.Second,
DisableCompression: true,
}
http.DefaultClient = &http.Client{
Transport: transport,
Timeout: 60 * time.Second,
}
// Read configuration
endpoint = os.Getenv("WEB_ENDPOINT")
controlEndpoint = os.Getenv("CONTROL_ENDPOINT")
sharedFileServer = http.FileServer(http.FS(web.FS))
server := &http.Server{
Addr: ":8004",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
http.HandleFunc("/shared/", shared)
http.HandleFunc("/update", update)
err = server.ListenAndServe()
if err != nil {
panic(err)
}
}
func shared(w http.ResponseWriter, req *http.Request) {
// For static files, allow all CORS
w.Header().Add("Access-Control-Allow-Origin", "*")
sharedFileServer.ServeHTTP(w, req)
}
func update(w http.ResponseWriter, req *http.Request) {
var err error
if req.Method != http.MethodPost {
err := fmt.Errorf("%w: %v", httphelpers.ErrorMethodNotAllowed, req.Method)
httphelpers.ErrorResponse(w, err)
return
}
bucket := lib.Bucket(req.FormValue("bucket"))
err = bucket.Validate()
if err != nil {
err := fmt.Errorf("%w: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
var cred credentials.Credential
cred, err = creds.Get(bucket)
if err != nil {
err := fmt.Errorf("%w: error getting credentials: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
title, err := getBucketMetadataTitle(bucket, cred)
if err != nil {
/*
err := fmt.Errorf("bucket title: %w", err)
httphelpers.ErrorResponse(w, err)
return
*/
title = ""
}
photos, err := getPhotos(bucket, cred)
if err != nil {
err := fmt.Errorf("cannot list bucket: %w", err)
httphelpers.ErrorResponse(w, err)
return
}
detailedPhotos := make([]Photo, 0)
for _, photo := range photos {
size, err := getPhotoMetadataSize(bucket, cred, photo)
if err != nil {
err := fmt.Errorf("photo size: %w: %v", err, photo)
httphelpers.ErrorResponse(w, err)
return
}
title, err := getPhotoMetadataTitle(bucket, cred, photo)
if err != nil {
err := fmt.Errorf("photo title: %w: %v", err, photo)
httphelpers.ErrorResponse(w, err)
return
}
tags, err := getPhotoMetadataTags(bucket, cred, photo)
if err != nil {
err := fmt.Errorf("photo tags: %w: %v", err, photo)
httphelpers.ErrorResponse(w, err)
return
}
detailedPhotos = append(detailedPhotos, Photo{photo, size, title, tags})
}
data := IndexTemplateData{
Assets: endpoint + "/shared/",
Control: controlEndpoint,
Bucket: bucket,
Title: title,
Photos: detailedPhotos,
}
buf := new(bytes.Buffer)
err = viewTemplate.Execute(buf, data)
if err != nil {
httphelpers.ErrorResponse(w, err)
return
}
err = putBucketView(bucket, cred, buf.Bytes())
if err != nil {
httphelpers.ErrorResponse(w, err)
return
}
buf.Reset()
err = manageTemplate.Execute(buf, data)
if err != nil {
httphelpers.ErrorResponse(w, err)
return
}
err = putBucketManage(bucket, cred, buf.Bytes())
if err != nil {
httphelpers.ErrorResponse(w, err)
return
}
}