diff --git a/cmd/main.go b/cmd/main.go index 25f1f84..3f67c6a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,6 +7,7 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/app" cleanupsessions "git.optclblast.xyz/draincloud/draincloud-core/internal/cron/cleanup_sessions" + filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine" "git.optclblast.xyz/draincloud/draincloud-core/internal/plugin" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/postgres" ) @@ -23,7 +24,9 @@ func main() { cleanupSessionsCron := cleanupsessions.New(pg) cleanupSessionsCron.Run(ctx) - go app.New(pg). + engine := filesengine.NewFilesEngine(nil, nil) + + go app.New(pg, engine). Run(ctx) <-ctx.Done() diff --git a/go.mod b/go.mod index ecfe2a4..c63c765 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -37,6 +38,9 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nats-io/nats.go v1.37.0 // indirect + github.com/nats-io/nkeys v0.4.7 // indirect + github.com/nats-io/nuid v1.0.1 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect diff --git a/go.sum b/go.sum index 121cb37..0db5302 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,8 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -81,6 +83,12 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE= +github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= +github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= +github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/internal/app/app.go b/internal/app/app.go index c664ab6..e689f4d 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -7,7 +7,6 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/domain" filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine" - "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" "github.com/gin-gonic/gin" ) @@ -25,7 +24,7 @@ func New( mux := gin.Default() d := &DrainCloud{ - database: database, + database: database, filesEngine: filesEngine, } @@ -38,13 +37,7 @@ func New( filesGroup := mux.Group("/files") { - filesGroup.POST("/upload", func(ctx *gin.Context) { - err := d.uploadFile(ctx) - if err != nil { - logger.Error(ctx.Request.Context(), "", logger.Err(err)) - ctx.String(400, err.Error()) - } - }) + filesGroup.POST("/upload", d.UploadFile) } d.mux = mux diff --git a/internal/app/upload_file.go b/internal/app/upload_file.go index 0e382dd..9acd81b 100644 --- a/internal/app/upload_file.go +++ b/internal/app/upload_file.go @@ -1,11 +1,14 @@ package app import ( + "fmt" "io" "log/slog" + "strings" filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" + "git.optclblast.xyz/draincloud/draincloud-core/internal/reqcontext" "github.com/davecgh/go-spew/spew" "github.com/gin-gonic/gin" ) @@ -21,14 +24,20 @@ func (d *DrainCloud) UploadFile(ctx *gin.Context) { return } - if err := d.uploadFile(ctx); err != nil { + userID, err := reqcontext.GetUserID(ctx) + if err != nil { + writeError(ctx, ErrorAccessDenied) + return + } + + if err := d.uploadFile(ctx, userID); err != nil { logger.Error(ctx, "uploadFile handle", logger.Err(err)) writeError(ctx, err) return } } -func (d *DrainCloud) uploadFile(ctx *gin.Context) error { +func (d *DrainCloud) uploadFile(ctx *gin.Context, userID int64) error { title := ctx.PostForm("file") logger.Info(ctx, "uploadFile", slog.Any("postForm data", spew.Sdump(title))) @@ -43,10 +52,29 @@ func (d *DrainCloud) uploadFile(ctx *gin.Context) error { return err } - d.filesEngine.SaveFile(ctx, filesengine.File{ - Name: header.Filename, - // UserID: , + ext := parseExtension(header.Filename) + + id, err := d.filesEngine.SaveFile(ctx, filesengine.File{ + Name: header.Filename, + UserID: userID, + Data: data, + Ext: ext, + Size: int64(len(data)), + Type: "", // че такое type? }) + if err != nil { + return fmt.Errorf("failed to save file: %w", err) + } + logger.Debug(ctx, "new file id", "id", id) return nil } + +func parseExtension(filename string) filesengine.FileExtension { + parts := strings.Split(filename, ".") + if len(parts) == 0 { + return filesengine.FileExtensionUnspecified + } + + return filesengine.FileExtension(parts[len(parts)-1]) +} diff --git a/internal/config/external_provider/ecternal_provider.go b/internal/config/external_provider/external_provider.go similarity index 100% rename from internal/config/external_provider/ecternal_provider.go rename to internal/config/external_provider/external_provider.go diff --git a/internal/config/external_provider/natskv/nats.go b/internal/config/external_provider/natskv/nats.go new file mode 100644 index 0000000..b281663 --- /dev/null +++ b/internal/config/external_provider/natskv/nats.go @@ -0,0 +1,30 @@ +package natskv + +import ( + "context" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" + "github.com/nats-io/nats.go/jetstream" +) + +type Provider struct { + cc jetstream.KeyValue +} + +func New( + ctx context.Context, + js jetstream.JetStream, +) *Provider { + kv, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{ + Bucket: "rtc", + Description: "Real Time Config", + Storage: jetstream.FileStorage, + Replicas: 2, + Compression: true, + }) + if err != nil { + logger.Fatal(ctx, "[natskv][New] failed to initialize rtc", logger.Err(err)) + } + + return &Provider{cc: kv} +} diff --git a/internal/files_engine/engine.go b/internal/files_engine/engine.go index 122798a..f96b245 100644 --- a/internal/files_engine/engine.go +++ b/internal/files_engine/engine.go @@ -24,7 +24,7 @@ func NewFilesEngine( type File struct { Name string UserID int64 - Ext string + Ext FileExtension Type string Size int64 Data []byte @@ -34,6 +34,7 @@ func (e *FilesEngine) SaveFile( ctx context.Context, file File, ) (int64, error) { + e.metaStorage.SaveMetadata(ctx, file.Type, ) return -1, nil } diff --git a/internal/files_engine/files.go b/internal/files_engine/files.go new file mode 100644 index 0000000..f9a45d4 --- /dev/null +++ b/internal/files_engine/files.go @@ -0,0 +1,7 @@ +package filesengine + +type FileExtension string + +const ( + FileExtensionUnspecified FileExtension = "unspecified" +) diff --git a/internal/jetstream/js.go b/internal/jetstream/js.go new file mode 100644 index 0000000..ad33b63 --- /dev/null +++ b/internal/jetstream/js.go @@ -0,0 +1 @@ +package jetstream diff --git a/internal/server/server.go b/internal/server/server.go deleted file mode 100644 index 45f3c05..0000000 --- a/internal/server/server.go +++ /dev/null @@ -1,15 +0,0 @@ -package server - -import ( - "context" - "net/http" -) - -type Server struct { - mux *http.ServeMux // Mux - ctx context.Context // Global application context -} - -func RegisterHandler(ctx context.Context, h http.HandlerFunc) { - -}