From f7fc2e5d9b9b907973b55bda51c180814a7a92a2 Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski <janne@kuschku.de> Date: Sun, 25 Jul 2021 21:23:22 +0200 Subject: [PATCH] Significant cleanup and improvements Signed-off-by: Janne Mareike Koschinski <janne@kuschku.de> --- .gitignore | 3 +- api/album_get.go | 25 ++++++++ api/album_list.go | 28 +++++++++ api/albumimage_get.go | 25 ++++++++ api/albumimage_list.go | 25 ++++++++ api/image_get.go | 25 ++++++++ api/image_list.go | 28 +++++++++ auth/parse_user.go | 19 ++++++ cmd/backend/main.go | 36 +++++++++++ cmd/frontend/main.go | 62 +++++++++++++++++++ config.example.yaml | 65 ++++++++++++++++++++ configuration/auth.go | 5 ++ configuration/configuration.go | 9 +++ configuration/conversion.go | 16 +++++ configuration/database.go | 6 ++ configuration/queue.go | 10 +++ configuration/redis.go | 6 ++ configuration/types/loglevel.go | 24 ++++++++ configuration/types/timeout.go | 21 +++++++ environment/environment.go | 104 ++++++++++++++++++++------------ environment/repositories.go | 9 +++ go.mod | 1 + go.sum | 2 + main.go | 58 ------------------ repo/album_images.go | 8 +-- s3/upload_source.go | 19 ++++++ task/image_resize.go | 31 +++++++--- util/return_json.go | 13 ++++ 28 files changed, 571 insertions(+), 112 deletions(-) create mode 100644 api/album_get.go create mode 100644 api/album_list.go create mode 100644 api/albumimage_get.go create mode 100644 api/albumimage_list.go create mode 100644 api/image_get.go create mode 100644 api/image_list.go create mode 100644 auth/parse_user.go create mode 100644 cmd/backend/main.go create mode 100644 cmd/frontend/main.go create mode 100644 config.example.yaml create mode 100644 configuration/auth.go create mode 100644 configuration/configuration.go create mode 100644 configuration/conversion.go create mode 100644 configuration/database.go create mode 100644 configuration/queue.go create mode 100644 configuration/redis.go create mode 100644 configuration/types/loglevel.go create mode 100644 configuration/types/timeout.go create mode 100644 environment/repositories.go delete mode 100644 main.go create mode 100644 s3/upload_source.go create mode 100644 util/return_json.go diff --git a/.gitignore b/.gitignore index f8570a4..0155fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.idea/ /vendor/ -/node_modules/ \ No newline at end of file +/node_modules/ +/config.yaml diff --git a/api/album_get.go b/api/album_get.go new file mode 100644 index 0000000..741a40a --- /dev/null +++ b/api/album_get.go @@ -0,0 +1,25 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "github.com/gorilla/mux" + "net/http" +) + +func GetAlbum(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + vars := mux.Vars(request) + album, err := env.Repositories.Albums.Get(vars["albumId"]) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, album) + }) +} diff --git a/api/album_list.go b/api/album_list.go new file mode 100644 index 0000000..9429759 --- /dev/null +++ b/api/album_list.go @@ -0,0 +1,28 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/auth" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "net/http" +) + +func ListAlbums(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + user, err := auth.ParseUser(request, env) + if err != nil { + http.Error(writer, err.Error(), http.StatusUnauthorized) + } + albums, err := env.Repositories.Albums.List(user) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, albums) + }) +} diff --git a/api/albumimage_get.go b/api/albumimage_get.go new file mode 100644 index 0000000..f140856 --- /dev/null +++ b/api/albumimage_get.go @@ -0,0 +1,25 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "github.com/gorilla/mux" + "net/http" +) + +func GetAlbumImage(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + vars := mux.Vars(request) + albumImage, err := env.Repositories.AlbumImages.Get(vars["albumId"], vars["imageId"]) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, albumImage) + }) +} diff --git a/api/albumimage_list.go b/api/albumimage_list.go new file mode 100644 index 0000000..5b284df --- /dev/null +++ b/api/albumimage_list.go @@ -0,0 +1,25 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "github.com/gorilla/mux" + "net/http" +) + +func ListAlbumImages(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + vars := mux.Vars(request) + albumImages, err := env.Repositories.AlbumImages.List(vars["albumId"]) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, albumImages) + }) +} diff --git a/api/image_get.go b/api/image_get.go new file mode 100644 index 0000000..9ec538a --- /dev/null +++ b/api/image_get.go @@ -0,0 +1,25 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "github.com/gorilla/mux" + "net/http" +) + +func GetImage(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + vars := mux.Vars(request) + image, err := env.Repositories.Images.Get(vars["imageId"]) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, image) + }) +} diff --git a/api/image_list.go b/api/image_list.go new file mode 100644 index 0000000..4148b4c --- /dev/null +++ b/api/image_list.go @@ -0,0 +1,28 @@ +package api + +import ( + "database/sql" + "git.kuschku.de/justjanne/imghost-frontend/auth" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "net/http" +) + +func ListImages(env environment.Environment) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + user, err := auth.ParseUser(request, env) + if err != nil { + http.Error(writer, err.Error(), http.StatusUnauthorized) + } + images, err := env.Repositories.Images.List(user) + if err == sql.ErrNoRows { + http.NotFound(writer, request) + return + } else if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + + util.ReturnJson(writer, images) + }) +} diff --git a/auth/parse_user.go b/auth/parse_user.go new file mode 100644 index 0000000..fab59f3 --- /dev/null +++ b/auth/parse_user.go @@ -0,0 +1,19 @@ +package auth + +import ( + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/model" + "net/http" +) + +func ParseUser(request *http.Request, env environment.Environment) (user model.User, err error) { + // TODO: Implement actual user auth + user = model.User{ + Id: "ad45284c-be4d-4546-8171-41cf126ac091", + Name: "justJanne", + Email: "janne@kuschku.de", + Roles: []string{"imghost:user", "imghost:admin"}, + } + + return +} diff --git a/cmd/backend/main.go b/cmd/backend/main.go new file mode 100644 index 0000000..102b6d2 --- /dev/null +++ b/cmd/backend/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/task" + "github.com/hibiken/asynq" + _ "github.com/lib/pq" + "gopkg.in/yaml.v2" + "log" + "os" +) + +func main() { + var config configuration.Configuration + configFile, err := os.Open("config.yaml") + if err != nil { + panic(err) + } + err = yaml.NewDecoder(configFile).Decode(&config) + if err != nil { + panic(err) + } + + env, err := environment.NewServerEnvironment(config) + if err != nil { + panic(err) + } + defer env.Destroy() + + mux := asynq.NewServeMux() + mux.HandleFunc(config.Conversion.ResizeTaskId, task.HandleImageResizeTask) + if err := env.QueueServer.Run(mux); err != nil { + log.Fatalf("could not run server: %v", err) + } +} diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go new file mode 100644 index 0000000..d101b77 --- /dev/null +++ b/cmd/frontend/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "git.kuschku.de/justjanne/imghost-frontend/api" + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/util" + "github.com/gorilla/mux" + _ "github.com/lib/pq" + "gopkg.in/yaml.v2" + "net/http" + "os" +) + +func main() { + var config configuration.Configuration + configFile, err := os.Open("config.yaml") + if err != nil { + panic(err) + } + err = yaml.NewDecoder(configFile).Decode(&config) + if err != nil { + panic(err) + } + + env, err := environment.NewClientEnvironment(config) + if err != nil { + panic(err) + } + defer env.Destroy() + + router := mux.NewRouter() + // Image API + router.Handle( + "/api/v1/images", + api.ListImages(env)).Methods(http.MethodGet) + router.Handle( + "/api/v1/images/{imageId}", + api.GetImage(env)).Methods(http.MethodGet) + + // Album API + router.Handle( + "/api/v1/albums", + api.ListAlbums(env)).Methods(http.MethodGet) + router.Handle( + "/api/v1/albums/{imageId}", + api.GetAlbum(env)).Methods(http.MethodGet) + + // Album Image API + router.Handle( + "/api/v1/albums/{albumId}/images", + api.ListAlbumImages(env)).Methods(http.MethodGet) + router.Handle( + "/api/v1/albums/{albumId}/images/{imageId}", + api.GetAlbumImage(env)).Methods(http.MethodGet) + + // TODO: Implement mutating API methods + + if err = http.ListenAndServe(":8080", util.MethodOverride(router)); err != nil { + panic(err) + } +} diff --git a/config.example.yaml b/config.example.yaml new file mode 100644 index 0000000..1d7a960 --- /dev/null +++ b/config.example.yaml @@ -0,0 +1,65 @@ +auth: + role_prefix: "imghost" + +queue: + concurrency: 10 + log_level: "info" + strict_priority: false + queues: + critical: 6 + default: 3 + low: 1 + +database: + type: "postgres" + url: "postgresql://imghost:hunter2@db.example.com/imghost" + +redis: + address: ":6379" + password: "" + +conversion: + task_id: "image:resize" + max_retry: 10 + timeout: "3m" + queue: "default" + unique_timeout: "3m" + quality: + compression_quality: 100 + sampling_factors: [ 1,1 ] + sizes: + - suffix: "s" + size: + width: 90 + height: 90 + format: "cover" + - suffix: "b" + size: + width: 160 + height: 160 + format: "cover" + - suffix: "t" + size: + width: 160 + height: 160 + format: "contain" + - suffix: "m" + size: + width: 320 + height: 320 + format: "contain" + - suffix: "l" + size: + width: 640 + height: 640 + format: "contain" + - suffix: "h" + size: + width: 1024 + height: 1024 + format: "contain" + - suffix: "" + size: + width: 0 + height: 0 + format: "contain" diff --git a/configuration/auth.go b/configuration/auth.go new file mode 100644 index 0000000..d87ba42 --- /dev/null +++ b/configuration/auth.go @@ -0,0 +1,5 @@ +package configuration + +type AuthConfiguration struct { + RolePrefix string `json:"role_prefix"` +} diff --git a/configuration/configuration.go b/configuration/configuration.go new file mode 100644 index 0000000..42558ae --- /dev/null +++ b/configuration/configuration.go @@ -0,0 +1,9 @@ +package configuration + +type Configuration struct { + Queue QueueConfiguration `json:"queue"` + Database DatabaseConfiguration `json:"database"` + Redis RedisConfiguration `json:"redis"` + Conversion ConversionConfiguration `json:"conversion"` + Auth AuthConfiguration `json:"auth"` +} diff --git a/configuration/conversion.go b/configuration/conversion.go new file mode 100644 index 0000000..11d896d --- /dev/null +++ b/configuration/conversion.go @@ -0,0 +1,16 @@ +package configuration + +import ( + "git.kuschku.de/justjanne/imghost-frontend/configuration/types" + "github.com/justjanne/imgconv" +) + +type ConversionConfiguration struct { + TaskId string `json:"task_id"` + MaxRetry int `json:"max_retry"` + Timeout types.Timeout `json:"timeout"` + Queue string `json:"queue"` + UniqueTimeout types.Timeout `json:"unique_timeout"` + Quality imgconv.Quality `json:"quality"` + Sizes []imgconv.Size `json:"sizes"` +} diff --git a/configuration/database.go b/configuration/database.go new file mode 100644 index 0000000..2719add --- /dev/null +++ b/configuration/database.go @@ -0,0 +1,6 @@ +package configuration + +type DatabaseConfiguration struct { + Type string `json:"type"` + Url string `json:"url"` +} diff --git a/configuration/queue.go b/configuration/queue.go new file mode 100644 index 0000000..b10105c --- /dev/null +++ b/configuration/queue.go @@ -0,0 +1,10 @@ +package configuration + +import "git.kuschku.de/justjanne/imghost-frontend/configuration/types" + +type QueueConfiguration struct { + Concurrency int `json:"concurrency"` + LogLevel types.Severity `json:"log_level"` + StrictPriority bool `json:"strict_priority"` + Queues map[string]int `json:"queues"` +} diff --git a/configuration/redis.go b/configuration/redis.go new file mode 100644 index 0000000..cb93818 --- /dev/null +++ b/configuration/redis.go @@ -0,0 +1,6 @@ +package configuration + +type RedisConfiguration struct { + Address string `json:"address"` + Password string `json:"password"` +} diff --git a/configuration/types/loglevel.go b/configuration/types/loglevel.go new file mode 100644 index 0000000..8338ad7 --- /dev/null +++ b/configuration/types/loglevel.go @@ -0,0 +1,24 @@ +package types + +import ( + "github.com/hibiken/asynq" +) + +type Severity asynq.LogLevel + +func (severity *Severity) UnmarshalYAML(unmarshal func(interface{}) error) error { + var spec string + if err := unmarshal(&spec); err != nil { + return err + } + + var loglevel asynq.LogLevel + err := loglevel.Set(spec) + if err != nil { + return err + } + + *severity = Severity(loglevel) + + return nil +} diff --git a/configuration/types/timeout.go b/configuration/types/timeout.go new file mode 100644 index 0000000..8a988e3 --- /dev/null +++ b/configuration/types/timeout.go @@ -0,0 +1,21 @@ +package types + +import "time" + +type Timeout time.Duration + +func (timeout *Timeout) UnmarshalYAML(unmarshal func(interface{}) error) error { + var spec string + if err := unmarshal(&spec); err != nil { + return err + } + + duration, err := time.ParseDuration(spec) + if err != nil { + return err + } + + *timeout = Timeout(duration) + + return nil +} diff --git a/environment/environment.go b/environment/environment.go index 114924a..31a0e4e 100644 --- a/environment/environment.go +++ b/environment/environment.go @@ -1,62 +1,88 @@ package environment import ( - "encoding/json" + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/repo" "github.com/hibiken/asynq" "github.com/jmoiron/sqlx" - "github.com/justjanne/imgconv" - "os" + "time" ) type Environment struct { - Queue *asynq.Client - Database *sqlx.DB - RolePrefix string - Sizes []imgconv.Size - Quality imgconv.Quality + Configuration configuration.Configuration + QueueClient *asynq.Client + QueueServer *asynq.Server + Database *sqlx.DB + Repositories Repositories } -func NewEnvironment( - redisAddress string, - dbType string, - dbUrl string, - rolePrefix string, - sizes []imgconv.Size, - quality imgconv.Quality, -) (env Environment, err error) { - env.Queue = asynq.NewClient(asynq.RedisClientOpt{ - Addr: redisAddress, - }) - env.Database, err = sqlx.Open(dbType, dbUrl) - env.RolePrefix = rolePrefix - env.Sizes = sizes - env.Quality = quality - return -} - -func InitializeEnvironment() (env Environment, err error) { - var sizes []imgconv.Size - if err = json.Unmarshal([]byte(os.Getenv("CONFIG_SIZES")), &sizes); err != nil { +func newCommonEnvironment(config configuration.Configuration) (env Environment, err error) { + env.Configuration = config + if env.Database, err = sqlx.Open(config.Database.Type, config.Database.Url); err != nil { + return + } + if env.Repositories.Images, err = repo.NewImageRepo(env.Database); err != nil { + return + } + if env.Repositories.Albums, err = repo.NewAlbumRepo(env.Database); err != nil { return } - var quality imgconv.Quality - if err = json.Unmarshal([]byte(os.Getenv("CONFIG_QUALITY")), &quality); err != nil { + if env.Repositories.AlbumImages, err = repo.NewAlbumImageRepo(env.Database); err != nil { return } - rolePrefix := os.Getenv("CONFIG_ROLE_PREFIX") + return +} - redisAddress := os.Getenv("REDIS_ADDRESS") - dbType := os.Getenv("DB_TYPE") - dbUrl := os.Getenv("DB_URL") - return NewEnvironment(redisAddress, dbType, dbUrl, rolePrefix, sizes, quality) +func NewClientEnvironment(config configuration.Configuration) (Environment, error) { + env, err := newCommonEnvironment(config) + if err != nil { + return env, err + } + env.QueueClient = asynq.NewClient(asynq.RedisClientOpt{ + Addr: config.Redis.Address, + Password: config.Redis.Password, + }) + env.QueueClient.SetDefaultOptions( + config.Conversion.TaskId, + asynq.MaxRetry(config.Conversion.MaxRetry), + asynq.Timeout(time.Duration(config.Conversion.Timeout)), + asynq.Queue(config.Conversion.Queue), + asynq.Unique(time.Duration(config.Conversion.UniqueTimeout)), + ) + return env, err } -func (env Environment) Destroy() error { - if err := env.Queue.Close(); err != nil { - return err +func NewServerEnvironment(config configuration.Configuration) (Environment, error) { + env, err := newCommonEnvironment(config) + if err != nil { + return env, err } + env.QueueServer = asynq.NewServer( + asynq.RedisClientOpt{ + Addr: config.Redis.Address, + Password: config.Redis.Password, + }, + asynq.Config{ + Concurrency: config.Queue.Concurrency, + LogLevel: asynq.LogLevel(config.Queue.LogLevel), + Queues: config.Queue.Queues, + StrictPriority: config.Queue.StrictPriority, + }, + ) + return env, err +} + +func (env Environment) Destroy() error { if err := env.Database.Close(); err != nil { return err } + if env.QueueClient != nil { + if err := env.QueueClient.Close(); err != nil { + return err + } + } + if env.QueueServer != nil { + env.QueueServer.Shutdown() + } return nil } diff --git a/environment/repositories.go b/environment/repositories.go new file mode 100644 index 0000000..ff2a7ec --- /dev/null +++ b/environment/repositories.go @@ -0,0 +1,9 @@ +package environment + +import "git.kuschku.de/justjanne/imghost-frontend/repo" + +type Repositories struct { + Images repo.Images + Albums repo.Albums + AlbumImages repo.AlbumImages +} diff --git a/go.mod b/go.mod index 96db1b4..3698c09 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module git.kuschku.de/justjanne/imghost-frontend go 1.13 require ( + github.com/gorilla/mux v1.8.0 // indirect github.com/hibiken/asynq v0.18.2 github.com/jmoiron/sqlx v1.3.4 github.com/justjanne/imgconv v1.0.3 // indirect diff --git a/go.sum b/go.sum index 190c08b..89853b5 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hibiken/asynq v0.18.2 h1:hbLVygnmQMc2evTmNildtUWaUPHIBtggA59MoaHp/bY= github.com/hibiken/asynq v0.18.2/go.mod h1:Sn3Ql1clxIO5kXoFOAE3W73tX81Hkau+2Kam9LfgymM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= diff --git a/main.go b/main.go deleted file mode 100644 index e5a5af7..0000000 --- a/main.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "fmt" - "git.kuschku.de/justjanne/imghost-frontend/environment" - "git.kuschku.de/justjanne/imghost-frontend/model" - "git.kuschku.de/justjanne/imghost-frontend/repo" - _ "github.com/lib/pq" -) - -func main() { - user := model.User{ - Id: "ad45284c-be4d-4546-8171-41cf126ac091", - Name: "justJanne", - Email: "janne@kuschku.de", - Roles: []string{"imghost:user", "imghost:admin"}, - } - - var env environment.Environment - env, err := environment.InitializeEnvironment() - if err != nil { - panic(err) - } - defer env.Destroy() - - imageRepo, err := repo.NewImageRepo(env.Database) - if err != nil { - panic(err) - } - - albumRepo, err := repo.NewAlbumRepo(env.Database) - if err != nil { - panic(err) - } - - albumImageRepo, err := repo.NewAlbumImageRepo(env.Database) - if err != nil { - panic(err) - } - - images, err := imageRepo.List(user) - if err != nil { - panic(err) - } - fmt.Printf("images: %v\n", len(images)) - - albums, err := albumRepo.List(user) - if err != nil { - panic(err) - } - fmt.Printf("albums: %v\n", len(albums)) - - albumImages, err := albumImageRepo.List(model.Album{}) - if err != nil { - panic(err) - } - fmt.Printf("albumImages: %v\n", len(albumImages)) -} diff --git a/repo/album_images.go b/repo/album_images.go index 9cfdbc5..b58a0a1 100644 --- a/repo/album_images.go +++ b/repo/album_images.go @@ -71,9 +71,9 @@ func NewAlbumImageRepo(db *sqlx.DB) (repo AlbumImages, err error) { return repo, nil } -func (repo AlbumImages) List(album model.Album) (images []model.AlbumImage, err error) { +func (repo AlbumImages) List(albumId string) (images []model.AlbumImage, err error) { rows, err := repo.queryList.Queryx(map[string]interface{}{ - "albumId": album.Id, + "albumId": albumId, }) if err != nil { return @@ -89,9 +89,9 @@ func (repo AlbumImages) List(album model.Album) (images []model.AlbumImage, err return } -func (repo AlbumImages) Get(album model.Album, imageId string) (image model.AlbumImage, err error) { +func (repo AlbumImages) Get(albumId string, imageId string) (image model.AlbumImage, err error) { err = repo.queryGet.Get(&image, map[string]interface{}{ - "albumId": album.Id, + "albumId": albumId, "imageId": imageId, }) return diff --git a/s3/upload_source.go b/s3/upload_source.go new file mode 100644 index 0000000..8393c17 --- /dev/null +++ b/s3/upload_source.go @@ -0,0 +1,19 @@ +package s3 + +import ( + "git.kuschku.de/justjanne/imghost-frontend/environment" + "github.com/justjanne/imgconv" +) + +// TODO: Implement +func UploadSource(env environment.Environment, imageId string, source string) error { + return nil +} + +func DownloadSource(env environment.Environment, imageId string) (string, error) { + return "", nil +} + +func UploadImage(env environment.Environment, imageId string, format imgconv.Size, source string) error { + return nil +} diff --git a/task/image_resize.go b/task/image_resize.go index 1e140b2..99021cc 100644 --- a/task/image_resize.go +++ b/task/image_resize.go @@ -3,34 +3,38 @@ package task import ( "context" "encoding/json" + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/environment" + "git.kuschku.de/justjanne/imghost-frontend/s3" "git.kuschku.de/justjanne/imghost-frontend/util" "github.com/hibiken/asynq" "github.com/justjanne/imgconv" "gopkg.in/gographics/imagick.v2/imagick" ) -const TypeImageResize = "image:Resize" - type ImageResizePayload struct { ImageId string Sizes []imgconv.Size Quality imgconv.Quality } -func NewResizeTask(imageId string, sizes []imgconv.Size, quality imgconv.Quality) (task *asynq.Task, err error) { +func NewResizeTask(imageId string, config configuration.Configuration) (task *asynq.Task, err error) { payload, err := json.Marshal(ImageResizePayload{ ImageId: imageId, - Sizes: sizes, - Quality: quality, + Sizes: config.Conversion.Sizes, + Quality: config.Conversion.Quality, }) if err != nil { return } - task = asynq.NewTask(TypeImageResize, payload) + task = asynq.NewTask(config.Conversion.ResizeTaskId, payload) return } func HandleImageResizeTask(ctx context.Context, task *asynq.Task) (err error) { + // TODO: Handle environment for tasks + env := environment.Environment{} + var payload ImageResizePayload if err = json.Unmarshal(task.Payload(), &payload); err != nil { return @@ -39,8 +43,11 @@ func HandleImageResizeTask(ctx context.Context, task *asynq.Task) (err error) { wand := imagick.NewMagickWand() defer wand.Destroy() - tmpFile := "" - if err = wand.ReadImage(tmpFile); err != nil { + file, err := s3.DownloadSource(env, payload.ImageId) + if err != nil { + return + } + if err = wand.ReadImage(file); err != nil { return } var originalImage imgconv.ImageHandle @@ -50,7 +57,8 @@ func HandleImageResizeTask(ctx context.Context, task *asynq.Task) (err error) { err = util.LaunchGoroutines(len(payload.Sizes), func(index int) error { size := payload.Sizes[index] - tmpTargetFile := "" + // TODO: Allocate temp file + tmpFile := "" image := originalImage.CloneImage() if err := image.Crop(size); err != nil { return err @@ -58,7 +66,10 @@ func HandleImageResizeTask(ctx context.Context, task *asynq.Task) (err error) { if err := image.Resize(size); err != nil { return err } - if err := image.Write(payload.Quality, tmpTargetFile); err != nil { + if err := image.Write(payload.Quality, tmpFile); err != nil { + return err + } + if err := s3.UploadImage(env, payload.ImageId, size, tmpFile); err != nil { return err } return nil diff --git a/util/return_json.go b/util/return_json.go new file mode 100644 index 0000000..aad85ef --- /dev/null +++ b/util/return_json.go @@ -0,0 +1,13 @@ +package util + +import ( + "encoding/json" + "net/http" +) + +func ReturnJson(writer http.ResponseWriter, data interface{}) { + writer.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(writer).Encode(data); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + } +} -- GitLab