From cd97b6262fe47497d97ba3a33641f9d942f9bda7 Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Sat, 16 Jan 2021 17:00:17 -0500 Subject: [PATCH] Finally Framework --- cmd/cmd.go | 80 -------------- imagini.db => cmd/imagini.db | Bin 69632 -> 73728 bytes main.go => cmd/main.go | 31 ++++-- cmd/server/server.go | 57 ++++++++++ internal/api/albums.go | 9 ++ internal/api/api.go | 24 +++++ {routes => internal/api}/auth.go | 27 +++-- internal/api/info.go | 9 ++ internal/api/media_items.go | 9 ++ {routes => internal/api}/middlewares.go | 2 +- internal/api/routes.go | 33 ++++++ internal/api/tags.go | 9 ++ internal/api/upload.go | 9 ++ {routes => internal/api}/users.go | 10 +- internal/auth/auth.go | 18 +++- internal/config/config.go | 2 +- internal/context/context.go | 21 ---- internal/{query/query.go => db/db.go} | 38 ++++--- internal/{query => db}/errors.go | 2 +- internal/{query => db}/users.go | 16 +-- internal/models/db.go | 34 +++--- internal/session/session.go | 25 +++++ internal/sessions/sessions.go | 9 -- routes/albums.go | 9 -- routes/info.go | 9 -- routes/media_items.go | 9 -- routes/routes.go | 138 ------------------------ routes/tags.go | 9 -- routes/upload.go | 9 -- 29 files changed, 297 insertions(+), 360 deletions(-) delete mode 100644 cmd/cmd.go rename imagini.db => cmd/imagini.db (90%) rename main.go => cmd/main.go (53%) create mode 100644 cmd/server/server.go create mode 100644 internal/api/albums.go create mode 100644 internal/api/api.go rename {routes => internal/api}/auth.go (56%) create mode 100644 internal/api/info.go create mode 100644 internal/api/media_items.go rename {routes => internal/api}/middlewares.go (98%) create mode 100644 internal/api/routes.go create mode 100644 internal/api/tags.go create mode 100644 internal/api/upload.go rename {routes => internal/api}/users.go (70%) delete mode 100644 internal/context/context.go rename internal/{query/query.go => db/db.go} (83%) rename internal/{query => db}/errors.go (86%) rename internal/{query => db}/users.go (63%) create mode 100644 internal/session/session.go delete mode 100644 internal/sessions/sessions.go delete mode 100644 routes/albums.go delete mode 100644 routes/info.go delete mode 100644 routes/media_items.go delete mode 100644 routes/routes.go delete mode 100644 routes/tags.go delete mode 100644 routes/upload.go diff --git a/cmd/cmd.go b/cmd/cmd.go deleted file mode 100644 index 7d11b7d..0000000 --- a/cmd/cmd.go +++ /dev/null @@ -1,80 +0,0 @@ -package cmd - -import ( - "net/http" - - "reichard.io/imagini/routes" - "reichard.io/imagini/internal/context" - - "github.com/urfave/cli/v2" - log "github.com/sirupsen/logrus" -) - -var CmdServe = cli.Command{ - Name: "serve", - Aliases: []string{"s"}, - Usage: "Start Imagini web server.", - Action: serveWeb, -} - -func serveWeb(cliCtx *cli.Context) error { - log.Info("Serving Web") - - ctx := context.NewImaginiContext() - routes.RegisterRoutes(ctx) - - if err := http.ListenAndServe(":" + ctx.Config.ListenPort, nil); err != nil { - log.Fatal(err) - } - - return nil -} - -// func testDatabase(cliCtx *cli.Context) error { -// log.Info("Testing Database") -// c := config.NewConfig() -// db.ConnectDB(c) -// -// err := auth.CreateUser(models.User{ -// Username: "User123", -// Email: "user26@evan.pub", -// FirstName: "User", -// LastName: "Reichard", -// AuthType: "Local", -// }, "myPassword123") -// -// if err != nil { -// fmt.Println(err) -// } -// -// resp := auth.AuthenticateUser(models.APICredentials{User:"User123", Password: "myPassword123"}) -// if resp == true { -// log.Info("USER SUCCESSFULLY AUTHENTICATED BY USERNAME") -// }else { -// log.Info("USER NOT AUTHENTICATED") -// } -// -// resp = auth.AuthenticateUser(models.APICredentials{User:"user26@evan.pub", Password: "myPassword123"}) -// if resp == true { -// log.Info("USER SUCCESSFULLY AUTHENTICATED BY EMAIL") -// }else { -// log.Info("USER NOT AUTHENTICATED") -// } -// -// resp = auth.AuthenticateUser(models.APICredentials{User:"user@evan.pub", Password: "myPassword12"}) -// if resp == true { -// log.Info("USER SUCCESSFULLY AUTHENTICATED BY EMAIL") -// }else { -// log.Info("USER NOT AUTHENTICATED") -// } -// -// // foundUser, err := db.GetUser(db.User{Username: "User123"}) -// -// // if errors.Is(err, gorm.ErrRecordNotFound) { -// // log.Warn("RECORD NOT FOUND") -// // } else { -// // log.Info("FOUND USER", foundUser) -// // } -// -// return nil -// } diff --git a/imagini.db b/cmd/imagini.db similarity index 90% rename from imagini.db rename to cmd/imagini.db index 7def2e9d05b99a62a5c3dd2d8355f70076dda3e5..eca2661838d0f1c68e8b10fbf0358ad349b79375 100644 GIT binary patch delta 737 zcmZozz|wGlWr94T&_o3{jS>by)({4MPQDtR?R=hma=f2;g1KIBp9$^;Era+#_=^QGI zyqkMCbQxKB*~Gn7!KPm0lw#&fNzHrbj_iQO1vS26o!OTIUpC5-Ii+S-iG@{{%W=UKyT z)JaH5Elw`VEGWs$&qFg(C!s7crxfZ?xDJpFoB#8(E3jlS@Mmon6iDE&Zxm+aW$^W7 z;1%cP6>ntaH8Lw=yu*GdD6b1_~LNS{WD+l21&@&CCM_fr?S0 zilKpuuc1X)v6qKwrM`1|QDAUsqMp86XliJFl$k}Uw}H5Kxp75_yQN=Lsz;7bskwJ< YT4;G_u>U59fBKXE`EzV$OZc@O00H075C8xG delta 646 zcmZoTz|ydQWr94T;6w#CwSEQx)-MeFDtyy<)%a5QEO`!bmvQ~#isbyrk;1uy{Um!P z>lb#D&4L0MtjtZe{FB336&M9JSFp-5vI?+?yDLui=aZOh&&f7<2b%!1U>x7%(`?F& z{FC3aS&K{XvWts~GByd9BqrsgmL#SZgD~G@NA`Sioq!-uU&o+G1#j0#1&xHvlmt!9 zrah>w-|}Z zF`18hop@$mNosm(kxoKUYEFDXVo64VLP=^x$>dMmNsMfhLwQsg*(X=?*m4Rmvx|$1 zGd9;xKFHIg;pZQs;1}xSqY&!n85ruSlTccmT9lWVn+nmb0F$2_$!jg3lTeUYTwI=C zlma#TKCkFxdA`@2k&Nu(+S-gwnUjV2=PBqUq@)%n7iAWdWaj5VRO%#@CFYbu4c+{P zUrK=`mw`VQ7+uNy^^F3IJPh9647}pJyyA_lMg~TPx(0^2hDHj8=2iwKR)$7;7Usql zX1WHZRt5$Hq!UweGxL1%lM{1Pj1pB04OGkmy|T(PlQM!W@}u-3B7zcKqnuqz3sVA0 q+>%XPqWr@}ER8MPOG~_rU0e+ UUID? type User struct { gorm.Model - Email string `json:"email" gorm:"unique;not null"` - Username string `json:"username" gorm:"unique;not null"` + Email string `json:"email" gorm:"unique"` + Username string `json:"username" gorm:"unique"` FirstName string `json:"first_name"` LastName string `json:"last_name"` - AuthType string `json:"auth_type"` - Password string `json:"password"` + AuthType string `json:"auth_type" gorm:"default:Local;not null"` + Password string `json:"-"` + JWTSecret string `json:"-" gorm:"unique;not null"` // TODO: Auto Generate UUID } type MediaItem struct { gorm.Model - User User `json:"user" gorm:"ForeignKey:ID"` + User User `json:"user" gorm:"ForeignKey:ID;not null"` EXIFDate time.Time `json:"exif_date"` Latitude string `json:"latitude"` Longitude string `json:"longitude"` - MediaType uint `json:"media_type"` - RelPath string `json:"rel_path"` + MediaType string `json:"media_type" gorm:"default:Photo;not null"` // Photo, Video + RelPath string `json:"rel_path" gorm:"not null"` Tags []Tag `json:"tags" gorm:"many2many:media_tags;"` Albums []Album `json:"albums" gorm:"many2many:media_albums;"` } type Tag struct { gorm.Model - Name string `json:"name"` + Name string `json:"name" gorm:"not null"` } type Album struct { gorm.Model - Name string `json:"name"` + Name string `json:"name" gorm:"not null"` } diff --git a/internal/session/session.go b/internal/session/session.go new file mode 100644 index 0000000..38d0ba6 --- /dev/null +++ b/internal/session/session.go @@ -0,0 +1,25 @@ +package session + +import ( + "sync" +) + +type SessionManager struct { + Mutex sync.Mutex +} + +func NewMgr() *SessionManager { + return &SessionManager{} +} + +func (sm *SessionManager) Set(key, value string) { + +} + +func (sm *SessionManager) Get(key string) string { + return "" +} + +func (sm *SessionManager) Delete(key string) { + +} diff --git a/internal/sessions/sessions.go b/internal/sessions/sessions.go deleted file mode 100644 index 276d64e..0000000 --- a/internal/sessions/sessions.go +++ /dev/null @@ -1,9 +0,0 @@ -package sessions - -// import ( -// "github.com/dgrijalva/jwt-go" -// ) - -type Manager struct { - -} diff --git a/routes/albums.go b/routes/albums.go deleted file mode 100644 index faec9f0..0000000 --- a/routes/albums.go +++ /dev/null @@ -1,9 +0,0 @@ -package routes - -import ( - "net/http" -) - -func (ctx *ImaginiContext) albumsHandler(w http.ResponseWriter, r *http.Request) { - -} diff --git a/routes/info.go b/routes/info.go deleted file mode 100644 index b488b18..0000000 --- a/routes/info.go +++ /dev/null @@ -1,9 +0,0 @@ -package routes - -import ( - "net/http" -) - -func (ctx *ImaginiContext) infoHandler(w http.ResponseWriter, r *http.Request) { - -} diff --git a/routes/media_items.go b/routes/media_items.go deleted file mode 100644 index f09b5b4..0000000 --- a/routes/media_items.go +++ /dev/null @@ -1,9 +0,0 @@ -package routes - -import ( - "net/http" -) - -func (ctx *ImaginiContext) mediaItemsHandler(w http.ResponseWriter, r *http.Request) { - -} diff --git a/routes/routes.go b/routes/routes.go deleted file mode 100644 index 27140f2..0000000 --- a/routes/routes.go +++ /dev/null @@ -1,138 +0,0 @@ -package routes - -import ( - "encoding/json" - "net/http" - "reichard.io/imagini/internal/context" -) - -type ImaginiContext struct { - *context.ImaginiContext -} - -func RegisterRoutes(cctx *context.ImaginiContext) { - ctx := &ImaginiContext{cctx} - http.HandleFunc("/MediaItems", ctx.mediaItemsHandler) - http.HandleFunc("/Upload", ctx.uploadHandler) - http.HandleFunc("/Albums", ctx.albumsHandler) - http.HandleFunc("/Logout", ctx.logoutHandler) - http.HandleFunc("/Login", ctx.loginHandler) - http.HandleFunc("/Users", ctx.usersHandler) - http.HandleFunc("/Tags", ctx.tagsHandler) - http.HandleFunc("/Info", ctx.infoHandler) - http.HandleFunc("/Me", ctx.meHandler) -} - -// https://stackoverflow.com/a/59764037 -func JSONError(w http.ResponseWriter, err string, code int) { - w.Header().Set("Content-Type", "application/json; charset=utf-8") - w.Header().Set("X-Content-Type-Options", "nosniff") - w.WriteHeader(code) - json.NewEncoder(w).Encode(map[string]interface{}{"error": err}) -} - -func JSONSuccess(w http.ResponseWriter, msg string, code int) { - w.Header().Set("Content-Type", "application/json; charset=utf-8") - w.Header().Set("X-Content-Type-Options", "nosniff") - w.WriteHeader(code) - json.NewEncoder(w).Encode(map[string]interface{}{"success": msg}) -} - -// METHOD: -// switch r.Method { -// case http.MethodGet: -// // Serve the resource. -// case http.MethodPost: -// // Create a new record. -// case http.MethodPut: -// // Update an existing record. -// case http.MethodDelete: -// // Remove the record. -// default: -// // Give an error message. -// } - - -// commonMiddleware := []Middleware{ -// logMiddleware, -// authMiddleware, -// } -// http.Handle("/Users", MultipleMiddleware(usersHandler, commonMiddleware...)) -// http.Handle("/Uploads/", MultipleMiddleware(uploadsHandler, commonMiddleware...)) - -// // http.HandleFunc("/uploads/", uploadsHandler()) -// http.Handle("/Uploads/", func(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// _, ok := ValidateUserToken(r) - -// if ok { -// next.ServeHTTP(w, r) -// } else { -// w.WriteHeader(http.StatusUnauthorized) -// } -// }) -// }(http.StripPrefix("/Uploads/", tusHandler))) - -// Filter Example: -// query := r.URL.Query() -// filters, present := query["filters"] - -// func uploadsHandler() http.Handler { -// store := filestore.FileStore{ -// Path: "./Uploads", -// } -// composer := tusd.NewStoreComposer() -// store.UseIn(composer) -// -// handler, err := tusd.NewHandler(tusd.Config{ -// BasePath: "/uploads/", -// StoreComposer: composer, -// NotifyCompleteUploads: true, -// }) -// -// if err != nil { -// panic(fmt.Errorf("Unable to create handler: %s", err)) -// } -// -// go func() { -// for { -// event := <-handler.CompleteUploads -// fmt.Printf("Upload %s finished\n", event.Upload.ID) -// } -// }() -// -// // return func(w http.ResponseWriter, r *http.Request) { -// // http.StripPrefix("/Uploads/", handler).ServeHTTP(w, r) -// // }; -// -// return http.StripPrefix("/Uploads/", handler) -// } - -// func processMedia() { -// var mi db.MediaItem -// - // TODO: - // - Derive Magic -> mediaType - // - Create Thumbnail - // - Pull EXIF - // - EXIFDate - // - Latitude - // - Longitude - // - TensorFlow Classification - // - https://outcrawl.com/image-recognition-api-go-tensorflow - // - Update Tags / MediaTags Table - // - Save Image - // - Update MediaItems Table - - - - // import "github.com/disintegration/imaging" - // - // img, err := imaging.Open("original.jpg", imaging.AutoOrientation(true)) - // if err != nil { - // return nil, err - // } - // - // img = imaging.Fit(img, 240, 160, imaging.Lanczos) - // err = imaging.Save(img, "thumbnail.jpg") -// } diff --git a/routes/tags.go b/routes/tags.go deleted file mode 100644 index 93dd07a..0000000 --- a/routes/tags.go +++ /dev/null @@ -1,9 +0,0 @@ -package routes - -import ( - "net/http" -) - -func (ctx *ImaginiContext) tagsHandler(w http.ResponseWriter, r *http.Request) { - -} diff --git a/routes/upload.go b/routes/upload.go deleted file mode 100644 index 91abd32..0000000 --- a/routes/upload.go +++ /dev/null @@ -1,9 +0,0 @@ -package routes - -import ( - "net/http" -) - -func (ctx *ImaginiContext) uploadHandler(w http.ResponseWriter, r *http.Request) { - -}