diff --git a/api/image_get.go b/api/image_get.go index 68552eaf0b1bd7730c7828f353baea129081ebfb..d1ff4d2a31783d36bf9b063cb07b173304b61e22 100644 --- a/api/image_get.go +++ b/api/image_get.go @@ -1,29 +1,13 @@ package api import ( - "context" "database/sql" "git.kuschku.de/justjanne/imghost-frontend/environment" - "git.kuschku.de/justjanne/imghost-frontend/model" "git.kuschku.de/justjanne/imghost-frontend/util" "github.com/gorilla/mux" "net/http" ) -func EnrichImageInfo(env environment.FrontendEnvironment, image model.Image) (info model.ImageInfo, err error) { - info.Image = image - info.State, err = env.Repositories.ImageStates.Get(image.Id) - if err != nil { - return - } - imageUrl, err := env.Storage.UrlFor(context.Background(), env.Configuration.Storage.ImageBucket, info.Image.Id) - if err != nil { - return - } - info.Url = imageUrl.String() - return -} - func GetImage(env environment.FrontendEnvironment) http.Handler { return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { var err error @@ -37,12 +21,12 @@ func GetImage(env environment.FrontendEnvironment) http.Handler { http.Error(writer, err.Error(), http.StatusInternalServerError) return } - info, err := EnrichImageInfo(env, image) + err = image.LoadUrl(env.Storage, env.Configuration.Storage) if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) return } - util.ReturnJson(writer, info) + util.ReturnJson(writer, image) }) } diff --git a/api/image_list.go b/api/image_list.go index 3f08df0bb148c5ac82b930d57611e9e8eae8c447..eef39a53edfd41ce29ad34320189b0da02e7e50f 100644 --- a/api/image_list.go +++ b/api/image_list.go @@ -3,7 +3,6 @@ package api import ( "git.kuschku.de/justjanne/imghost-frontend/auth" "git.kuschku.de/justjanne/imghost-frontend/environment" - "git.kuschku.de/justjanne/imghost-frontend/model" "git.kuschku.de/justjanne/imghost-frontend/util" "net/http" ) @@ -15,15 +14,15 @@ func ListImages(env environment.FrontendEnvironment) http.Handler { http.Error(writer, err.Error(), http.StatusUnauthorized) } images, err := env.Repositories.Images.List(user) - var infos []model.ImageInfo - for _, image := range images { - info, err := EnrichImageInfo(env, image) + for idx, image := range images { + err = image.LoadUrl(env.Storage, env.Configuration.Storage) if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) + return } - infos = append(infos, info) + images[idx] = image } - util.ReturnJson(writer, infos) + util.ReturnJson(writer, images) }) } diff --git a/api/image_upload.go b/api/image_upload.go index 595a49dc992701a02f3ff20054160c64704c256a..4c8035e16057630fee3a23f8a8db3a58bd43f76c 100644 --- a/api/image_upload.go +++ b/api/image_upload.go @@ -139,7 +139,7 @@ func UploadImage(env environment.FrontendEnvironment) http.Handler { return } println("Enqueued task") - err = env.Repositories.ImageStates.Update(image.Id, repo.StateQueued) + err = env.Repositories.Images.UpdateState(image.Id, repo.StateQueued) if err != nil { println("failed updating image state") http.Error(writer, err.Error(), http.StatusInternalServerError) diff --git a/environment/backend.go b/environment/backend.go index cde2a748ff4fe20ec4639e866c02d609581a5ce0..73fd20ad2f24438a9aded730c6413cf1ed1a6f6a 100644 --- a/environment/backend.go +++ b/environment/backend.go @@ -24,9 +24,6 @@ func NewBackendEnvironment(config configuration.BackendConfiguration) (env Backe if env.Repositories.Images, err = repo.NewImageRepo(env.Database); err != nil { return } - if env.Repositories.ImageStates, err = repo.NewImageStateRepo(env.Database); err != nil { - return - } if env.Repositories.Albums, err = repo.NewAlbumRepo(env.Database); err != nil { return } diff --git a/environment/frontend.go b/environment/frontend.go index b29e552fd7e704949df2b633c56498900caef34a..607103d90afe3dda006db4b14b6e409107fae77e 100644 --- a/environment/frontend.go +++ b/environment/frontend.go @@ -26,9 +26,6 @@ func NewFrontendEnvironment(config configuration.FrontendConfiguration) (env Fro if env.Repositories.Images, err = repo.NewImageRepo(env.Database); err != nil { return } - if env.Repositories.ImageStates, err = repo.NewImageStateRepo(env.Database); err != nil { - return - } if env.Repositories.Albums, err = repo.NewAlbumRepo(env.Database); err != nil { return } diff --git a/environment/repositories.go b/environment/repositories.go index c307ff7d1a01e225e67e75f6dd8503208ba974bd..ff2a7ec5efc15f5bb91d508d5b03ff03d1c02cb8 100644 --- a/environment/repositories.go +++ b/environment/repositories.go @@ -4,7 +4,6 @@ import "git.kuschku.de/justjanne/imghost-frontend/repo" type Repositories struct { Images repo.Images - ImageStates repo.ImageStates Albums repo.Albums AlbumImages repo.AlbumImages } diff --git a/model/image.go b/model/image.go index f3ba2ed39665f0ace26daf2c07c11e898861a842..a095a9ed8d4acb33ba8b0f0324f2b650682ccf35 100644 --- a/model/image.go +++ b/model/image.go @@ -2,6 +2,8 @@ package model import ( "errors" + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/storage" "time" ) @@ -14,6 +16,8 @@ type Image struct { UpdatedAt time.Time `json:"updated_at" db:"updated_at"` OriginalName string `json:"original_name" db:"original_name"` MimeType string `json:"mime_type" db:"mime_type"` + State string `json:"state" db:"state"` + Url string `json:"url"` } func (image Image) VerifyOwner(user User) error { @@ -23,3 +27,8 @@ func (image Image) VerifyOwner(user User) error { return nil } + +func (image *Image) LoadUrl(storage storage.Storage, config configuration.StorageConfiguration) (err error) { + image.Url = storage.UrlFor(config.ImageBucket, image.Id).String() + return +} diff --git a/model/image_info.go b/model/image_info.go deleted file mode 100644 index 00a62e5932852eb59d24e2eca0be93e42d4a363f..0000000000000000000000000000000000000000 --- a/model/image_info.go +++ /dev/null @@ -1,7 +0,0 @@ -package model - -type ImageInfo struct { - Image Image `json:"image"` - State string `json:"state"` - Url string `json:"url"` -} diff --git a/repo/image_state.go b/repo/image_state.go deleted file mode 100644 index 2c0026bff7334d63f9f062703dec5611926cb7d0..0000000000000000000000000000000000000000 --- a/repo/image_state.go +++ /dev/null @@ -1,56 +0,0 @@ -package repo - -import ( - "github.com/jmoiron/sqlx" -) - -const ( - StateCreated = "created" - StateQueued = "queued" - StateInProgress = "in_progress" - StateDone = "done" - StateError = "error" -) - -type ImageStates struct { - db *sqlx.DB - queryGet *sqlx.NamedStmt - stmtUpdate *sqlx.NamedStmt -} - -func NewImageStateRepo(db *sqlx.DB) (repo ImageStates, err error) { - repo.db = db - repo.queryGet, err = db.PrepareNamed(` - SELECT state - FROM images - WHERE id = :imageId - `) - if err != nil { - return - } - repo.stmtUpdate, err = db.PrepareNamed(` - UPDATE images - SET state = :state - WHERE id = :imageId - `) - if err != nil { - return - } - - return repo, nil -} - -func (repo ImageStates) Get(imageId string) (state string, err error) { - err = repo.queryGet.Get(&state, map[string]interface{}{ - "imageId": imageId, - }) - return -} - -func (repo ImageStates) Update(imageId string, state string) (err error) { - _, err = repo.stmtUpdate.Exec(map[string]interface{}{ - "imageId": imageId, - "state": state, - }) - return -} diff --git a/repo/images.go b/repo/images.go index a8b1531641ba0b380af38652eeee0a2a31bb0a38..57e3338a89226726f0d53cc19368aa0cfe3868fa 100644 --- a/repo/images.go +++ b/repo/images.go @@ -6,14 +6,23 @@ import ( ) type Images struct { - db *sqlx.DB - queryList *sqlx.NamedStmt - queryGet *sqlx.NamedStmt - stmtCreate *sqlx.NamedStmt - stmtUpdate *sqlx.NamedStmt - stmtDelete *sqlx.NamedStmt + db *sqlx.DB + queryList *sqlx.NamedStmt + queryGet *sqlx.NamedStmt + stmtCreate *sqlx.NamedStmt + stmtUpdate *sqlx.NamedStmt + stmtUpdateState *sqlx.NamedStmt + stmtDelete *sqlx.NamedStmt } +const ( + StateCreated = "created" + StateQueued = "queued" + StateInProgress = "in_progress" + StateDone = "done" + StateError = "error" +) + func NewImageRepo(db *sqlx.DB) (repo Images, err error) { repo.db = db repo.queryList, err = db.PrepareNamed(` @@ -23,7 +32,8 @@ func NewImageRepo(db *sqlx.DB) (repo Images, err error) { description, original_name, created_at, - updated_at + updated_at, + state FROM images WHERE owner = :userId ORDER BY created_at DESC @@ -38,7 +48,8 @@ func NewImageRepo(db *sqlx.DB) (repo Images, err error) { description, original_name, created_at, - updated_at + updated_at, + state FROM images WHERE id = :imageId `) @@ -62,6 +73,14 @@ func NewImageRepo(db *sqlx.DB) (repo Images, err error) { if err != nil { return } + repo.stmtUpdateState, err = db.PrepareNamed(` + UPDATE images + SET state = :state + WHERE id = :imageId + `) + if err != nil { + return + } repo.stmtDelete, err = db.PrepareNamed(` DELETE FROM images WHERE id = :imageId @@ -120,6 +139,14 @@ func (repo Images) Update(changed model.Image) (err error) { return } +func (repo Images) UpdateState(imageId string, state string) (err error) { + _, err = repo.stmtUpdateState.Exec(map[string]interface{}{ + "imageId": imageId, + "state": state, + }) + return +} + func (repo Images) Delete(changed model.Image) (err error) { _, err = repo.stmtDelete.Exec(map[string]interface{}{ "imageId": changed.Id, diff --git a/storage/storage.go b/storage/storage.go index ab535a5410e5277b936ae802abda35387d247cc6..ffb357105668f43f64008476081bea416849c7ef 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -8,7 +8,7 @@ import ( "io" "net/url" "os" - "time" + "path/filepath" ) type Storage struct { @@ -60,12 +60,8 @@ func (storage Storage) DownloadFile(ctx context.Context, bucketName string, file return } -func (storage Storage) UrlFor(ctx context.Context, bucketName string, fileName string) (url *url.URL, err error) { - url, err = storage.s3client.PresignedGetObject( - ctx, - bucketName, - fileName, - 7*24*time.Hour, - map[string][]string{}) - return +func (storage Storage) UrlFor(bucketName string, fileName string) *url.URL { + fileUrl := *storage.s3client.EndpointURL() + fileUrl.Path = filepath.Join(fileUrl.Path, bucketName, fileName) + return &fileUrl } diff --git a/task/image_resize_processor.go b/task/image_resize_processor.go index 20eaf98ef342e7ed0c05d1834356c1b0f450c087..8b79df8656240d382930ef46386c0fb3fcb5a561 100644 --- a/task/image_resize_processor.go +++ b/task/image_resize_processor.go @@ -31,7 +31,7 @@ func (processor *ImageProcessor) ProcessTask(ctx context.Context, task *asynq.Ta println("parsed task: " + payload.ImageId) - if err = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateInProgress); err != nil { + if err = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateInProgress); err != nil { println("failed to set image state: " + payload.ImageId) println(err.Error()) return @@ -44,7 +44,7 @@ func (processor *ImageProcessor) ProcessTask(ctx context.Context, task *asynq.Ta if err != nil { println("failed to create temp file: " + payload.ImageId) println(err.Error()) - _ = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateError) + _ = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateError) return } err = processor.env.Storage.DownloadFile( @@ -55,20 +55,20 @@ func (processor *ImageProcessor) ProcessTask(ctx context.Context, task *asynq.Ta if err != nil { println("failed to download file: " + sourceFile.Name()) println(err.Error()) - _ = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateError) + _ = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateError) return } if err = wand.ReadImage(sourceFile.Name()); err != nil { println("failed to read file: " + sourceFile.Name()) println(err.Error()) - _ = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateError) + _ = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateError) return } var originalImage imgconv.ImageHandle if originalImage, err = imgconv.NewImage(wand); err != nil { println("failed to load file: " + sourceFile.Name()) println(err.Error()) - _ = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateError) + _ = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateError) return err } @@ -102,11 +102,11 @@ func (processor *ImageProcessor) ProcessTask(ctx context.Context, task *asynq.Ta if err != nil { println("failed to convert image file") println(err.Error()) - _ = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateError) + _ = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateError) return } - if err = processor.env.Repositories.ImageStates.Update(payload.ImageId, repo.StateDone); err != nil { + if err = processor.env.Repositories.Images.UpdateState(payload.ImageId, repo.StateDone); err != nil { return } diff --git a/ui/src/ImageList.tsx b/ui/src/ImageList.tsx index adc89b9eeacdde02cf35bc158de7c5156104c94f..ca223227be3e40e00bca9d8ee265873a20e8b3bc 100644 --- a/ui/src/ImageList.tsx +++ b/ui/src/ImageList.tsx @@ -10,16 +10,18 @@ export default function ImageList() { <p>{error as string}</p> <ul> {data?.map(info => ( - <li> - <p>{info.image?.id}</p> - <p>{info.image?.title}</p> - <p>{info.image?.description}</p> - <p>{info.image?.original_name}</p> - <p>{info.image?.mime_type}</p> - <p>{info.image?.created_at}</p> - <p>{info.image?.updated_at}</p> + <li key={info.id}> + <p>{info.id}</p> + <p>{info.owner}</p> + <p>{info.title}</p> + <p>{info.description}</p> + <p>{info.original_name}</p> + <p>{info.mime_type}</p> + <p>{info.created_at}</p> + <p>{info.updated_at}</p> <p>{info.state}</p> - <img src={info.url} alt=""/> + <p>{info.url}</p> + <img src={info.url+"t"} alt=""/> </li> ))} </ul> diff --git a/ui/src/api/model/Image.ts b/ui/src/api/model/Image.ts index 2af55c34495363a9142dea02ef069e9d8dbcd347..e944e649414ef3856b46f3d82bd0885006916405 100644 --- a/ui/src/api/model/Image.ts +++ b/ui/src/api/model/Image.ts @@ -7,4 +7,6 @@ export interface Image { updated_at: string, original_name: string, mime_type: string, + state: string, + url: string, } diff --git a/ui/src/api/model/ImageInfo.ts b/ui/src/api/model/ImageInfo.ts deleted file mode 100644 index bbfa2395afa3c47c2ec8d51d807fe60006913942..0000000000000000000000000000000000000000 --- a/ui/src/api/model/ImageInfo.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {Image} from "./Image"; - -export interface ImageInfo { - image: Image, - state: string, - url: string, -} diff --git a/ui/src/api/useListImages.ts b/ui/src/api/useListImages.ts index a6424b51c4a5bbcbc98e1e4c748e4db2a33baf6d..d0e7ccf3bad6ba6c4a2ae92e822d5570976c7ebd 100644 --- a/ui/src/api/useListImages.ts +++ b/ui/src/api/useListImages.ts @@ -1,13 +1,13 @@ import {useQuery} from "react-query"; import axios from "axios"; import {useBaseUrl} from "./baseUrlContext"; -import {ImageInfo} from "./model/ImageInfo"; +import {Image} from "./model/Image"; export const useListImages = () => { const baseUrl = useBaseUrl(); return useQuery( "connector-deployments", - () => axios.get<ImageInfo[]>( + () => axios.get<Image[]>( "api/v1/images", { baseURL: baseUrl