feat (minio): done, upload wip
This commit is contained in:
@@ -16,6 +16,7 @@ require (
|
||||
github.com/karincake/risoles v0.0.3
|
||||
github.com/karincake/semprit v0.0.3
|
||||
github.com/karincake/serabi v0.0.14
|
||||
github.com/minio/minio-go/v7 v7.0.95
|
||||
github.com/rs/zerolog v1.33.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
gorm.io/gorm v1.25.12
|
||||
@@ -23,8 +24,11 @@ require (
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.36.2-0.20250806044935-5bb51a0a956e // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-redis/redis v6.15.9+incompatible // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
@@ -34,12 +38,20 @@ require (
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.28 // indirect
|
||||
github.com/microsoft/go-mssqldb v1.7.2 // indirect
|
||||
github.com/minio/crc64nvme v1.0.2 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/nxadm/tail v1.4.11 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
|
||||
@@ -25,12 +25,18 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
@@ -85,6 +91,11 @@ github.com/karincake/semprit v0.0.3 h1:znleGRu73xrHk6a70+jRQgVh9VF3TAhttQz6vfgNd
|
||||
github.com/karincake/semprit v0.0.3/go.mod h1:nLtNmWlHkxMKG0IMzqnnfkn1L/RVYGXVW3LchfYQMu8=
|
||||
github.com/karincake/serabi v0.0.14 h1:yK3nBLRXdoUNSUDIfbZqIQxnZ6U6Ij5QEO8d5QzZzsw=
|
||||
github.com/karincake/serabi v0.0.14/go.mod h1:GcnPBWb+UotDxvb/a2CKwourCEyVIL4P9+YxVmZ5zgk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -100,6 +111,12 @@ github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEu
|
||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/minio/crc64nvme v1.0.2 h1:6uO1UxGAD+kwqWWp7mBFsi5gAse66C4NXO8cmcVculg=
|
||||
github.com/minio/crc64nvme v1.0.2/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.95 h1:ywOUPg+PebTMTzn9VDsoFJy32ZuARN9zhB+K3IYEvYU=
|
||||
github.com/minio/minio-go/v7 v7.0.95/go.mod h1:wOOX3uxS334vImCNRVyIDdXX9OsXDm89ToynKgqUKlo=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
|
||||
@@ -108,6 +125,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
@@ -117,6 +136,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -131,6 +152,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
|
||||
@@ -11,6 +11,7 @@ type (
|
||||
CheckupScopeCode string
|
||||
AmbulatoryClassCode string
|
||||
InpatientClassCode string
|
||||
UploadCode string
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,6 +65,12 @@ const (
|
||||
ICCICU InpatientClassCode = "icu" // ICU
|
||||
ICCHCU InpatientClassCode = "hcu" // HCU
|
||||
ICCVK InpatientClassCode = "vk" // Verlos kamer
|
||||
|
||||
UCPRN UploadCode = "person-resident-number" // Person Resident Number
|
||||
UCPDL UploadCode = "person-driver-license" // Person Driver License
|
||||
UCPP UploadCode = "person-passport" // Person Passport
|
||||
UCPFC UploadCode = "person-family-card" // Person Family Card
|
||||
UCMIR UploadCode = "mcu-item-result" // Mcu Item Result
|
||||
)
|
||||
|
||||
func (ec EncounterClassCode) Code() string {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package minio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
a "github.com/karincake/apem"
|
||||
lo "github.com/karincake/apem/loggero"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
)
|
||||
|
||||
var O MinioCfg = MinioCfg{}
|
||||
var I *minio.Client
|
||||
|
||||
type MinioCfg struct {
|
||||
Endpoint string
|
||||
Region string
|
||||
AccessKey string `yaml:"accessKey"`
|
||||
SecretKey string `yaml:"secretKey"`
|
||||
UseSsl bool `yaml:"useSsl"`
|
||||
BucketName []string `yaml:"bucketName"`
|
||||
}
|
||||
|
||||
type UploadReaderInput struct {
|
||||
File io.Reader
|
||||
Name string
|
||||
Size int64
|
||||
ContentType string
|
||||
BucketName string
|
||||
}
|
||||
|
||||
type UploadPathInput struct {
|
||||
BucketName string
|
||||
ContentType string
|
||||
Name string
|
||||
Path string
|
||||
}
|
||||
|
||||
type PresignedGetInput struct {
|
||||
Bucket string
|
||||
Object string
|
||||
Expiry time.Duration
|
||||
ReqParams url.Values
|
||||
}
|
||||
|
||||
type ResponsePostPolicy struct {
|
||||
Url string `json:"url"`
|
||||
FormData map[string]string `json:"form-data"`
|
||||
}
|
||||
|
||||
func (c MinioCfg) GetRegion() string {
|
||||
return c.Region
|
||||
}
|
||||
|
||||
func (c MinioCfg) GetEndpoint() string {
|
||||
return c.Endpoint
|
||||
}
|
||||
|
||||
func (c MinioCfg) GetUseSsl() bool {
|
||||
return c.UseSsl
|
||||
}
|
||||
|
||||
func (c MinioCfg) GetBucketName() []string {
|
||||
return c.BucketName
|
||||
}
|
||||
|
||||
// connect db
|
||||
func Connect() {
|
||||
a.ParseSingleCfg(&O)
|
||||
NewClient(&O)
|
||||
if I == nil {
|
||||
panic("minio client is nil")
|
||||
}
|
||||
lo.I.Println("Instantiation for object storage service using Minio, status: DONE!!")
|
||||
}
|
||||
|
||||
func NewClient(cfg *MinioCfg) error {
|
||||
// Initialize minio client object.
|
||||
endpoint := cfg.Endpoint
|
||||
if endpoint == "" {
|
||||
return errors.New("config minio endpoint empty")
|
||||
}
|
||||
accessKey := cfg.AccessKey
|
||||
if accessKey == "" {
|
||||
return errors.New("config minio access key empty")
|
||||
}
|
||||
secretKey := cfg.SecretKey
|
||||
if secretKey == "" {
|
||||
return errors.New("config minio secret key empty")
|
||||
}
|
||||
useSSL := cfg.UseSsl
|
||||
minioClient, err := minio.New(endpoint, &minio.Options{
|
||||
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
|
||||
Secure: useSSL,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
I = minioClient
|
||||
return nil
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
|
||||
/******************** infra ********************/
|
||||
gs "simrs-vx/internal/infra/gorm-setting"
|
||||
minio "simrs-vx/internal/infra/minio"
|
||||
ssdb "simrs-vx/internal/infra/ss-db"
|
||||
|
||||
/******************** pkg ********************/
|
||||
@@ -50,6 +51,7 @@ import (
|
||||
hc "simrs-vx/pkg/handler-crud-helper"
|
||||
lh "simrs-vx/pkg/lang-helper"
|
||||
handlerlogger "simrs-vx/pkg/middleware/handler-logger"
|
||||
mh "simrs-vx/pkg/minio-helper"
|
||||
zlc "simrs-vx/pkg/zerolog-ctx"
|
||||
|
||||
/******************** sources ********************/
|
||||
@@ -97,6 +99,8 @@ func SetRoutes() http.Handler {
|
||||
a.RegisterExtCall(zlc.Adjust)
|
||||
a.RegisterExtCall(ssdb.SetInstance)
|
||||
a.RegisterExtCall(lh.Populate)
|
||||
a.RegisterExtCall(minio.Connect)
|
||||
a.RegisterExtCall(mh.I.SetClient)
|
||||
a.RegisterExtCall(validation.RegisterValidation)
|
||||
|
||||
r := http.NewServeMux()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package upload
|
||||
|
||||
// "net/http"
|
||||
|
||||
// uh "simrs-vx/pkg/upload-helper"
|
||||
|
||||
// uploadHandler handles single file upload requests
|
||||
// func uploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// if r.Method == "OPTIONS" {
|
||||
// w.WriteHeader(http.StatusNoContent)
|
||||
// return
|
||||
// }
|
||||
|
||||
// if r.Method != "POST" {
|
||||
// writeJSONResponse(w, http.StatusMethodNotAllowed, uh.UploadResponse{
|
||||
// Success: false,
|
||||
// Message: "Method not allowed. Use POST.",
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// // Parse multipart form (32MB max memory)
|
||||
// err := r.ParseMultipartForm(32 << 20)
|
||||
// if err != nil {
|
||||
// writeJSONResponse(w, http.StatusBadRequest, uh.UploadResponse{
|
||||
// Success: false,
|
||||
// Message: "Failed to parse multipart form",
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// // Get file from form
|
||||
// file, header, err := r.FormFile("file")
|
||||
// if err != nil {
|
||||
// writeJSONResponse(w, http.StatusBadRequest, uh.UploadResponse{
|
||||
// Success: false,
|
||||
// Message: "No file uploaded or invalid file field name. Use 'file' as field name.",
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
// defer file.Close()
|
||||
|
||||
// // Upload file
|
||||
// response, err := service.UploadFile(file, header.Filename, header.Size)
|
||||
// if err != nil {
|
||||
// writeJSONResponse(w, http.StatusInternalServerError, *response)
|
||||
// return
|
||||
// }
|
||||
|
||||
// if response.Success {
|
||||
// writeJSONResponse(w, http.StatusOK, *response)
|
||||
// } else {
|
||||
// writeJSONResponse(w, http.StatusBadRequest, *response)
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,149 @@
|
||||
package miniohelper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
m "simrs-vx/internal/infra/minio"
|
||||
|
||||
"github.com/minio/minio-go/v7"
|
||||
)
|
||||
|
||||
type minioRepository struct {
|
||||
client *minio.Client
|
||||
}
|
||||
|
||||
var I minioRepository = minioRepository{}
|
||||
|
||||
func (repo *minioRepository) SetClient() {
|
||||
repo.client = m.I
|
||||
}
|
||||
|
||||
// Check exist bucket if not exist create Bucket
|
||||
func (repo *minioRepository) createBucket(bucketName string, region string) error {
|
||||
exist, err := repo.client.BucketExists(context.Background(), bucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
return nil
|
||||
}
|
||||
if err := repo.client.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: region, ObjectLocking: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upload file reader to MinIO
|
||||
func (repo *minioRepository) PutObject(input m.UploadReaderInput) (*minio.UploadInfo, error) {
|
||||
if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := minio.PutObjectOptions{
|
||||
ContentType: input.ContentType,
|
||||
UserMetadata: map[string]string{"x-amz-acl": "public-read"},
|
||||
}
|
||||
|
||||
uploadInfo, err := repo.client.PutObject(context.Background(), input.BucketName, input.Name, input.File, input.Size, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &uploadInfo, err
|
||||
}
|
||||
|
||||
// Upload file path to MinIO
|
||||
func (repo *minioRepository) FPutObject(input m.UploadPathInput) (*minio.UploadInfo, error) {
|
||||
if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := minio.PutObjectOptions{
|
||||
ContentType: input.ContentType,
|
||||
UserMetadata: map[string]string{"x-amz-acl": "public-read"},
|
||||
}
|
||||
|
||||
uploadInfo, err := repo.client.FPutObject(context.Background(), input.BucketName, input.Name, input.Path, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &uploadInfo, err
|
||||
}
|
||||
|
||||
// Move file from old to new MinIO path
|
||||
func (repo *minioRepository) MoveObject(src minio.CopySrcOptions, dst minio.CopyDestOptions) (*minio.UploadInfo, error) {
|
||||
uploadInfo, err := repo.client.CopyObject(context.Background(), dst, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.RemoveObject(src.Bucket, src.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &uploadInfo, err
|
||||
}
|
||||
|
||||
// Generatet public link MinIO
|
||||
func (repo *minioRepository) GenerateUrl(bucket, object string) string {
|
||||
mode := "http"
|
||||
if m.O.GetUseSsl() {
|
||||
mode = "https"
|
||||
}
|
||||
return fmt.Sprintf("%s://%s/%s/%s", mode, m.O.GetEndpoint(), bucket, object)
|
||||
}
|
||||
|
||||
// Download file from MinIO
|
||||
func (repo *minioRepository) GetObject(bucket string, fileName string) (*minio.Object, error) {
|
||||
object, err := repo.client.GetObject(context.Background(), bucket, fileName, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return object, nil
|
||||
}
|
||||
|
||||
// Delete file from MinIO
|
||||
func (repo *minioRepository) RemoveObject(bucket string, fileName string) error {
|
||||
if err := repo.client.RemoveObject(context.Background(), bucket, fileName, minio.RemoveObjectOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// create presigned url to post object with custom policy
|
||||
func (repo *minioRepository) GeneratePresignedPost(policy *minio.PostPolicy) (*url.URL, map[string]string, error) {
|
||||
presignedUrl, formData, err := repo.client.PresignedPostPolicy(context.Background(), policy)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return presignedUrl, formData, nil
|
||||
}
|
||||
|
||||
// create presigned url to get object
|
||||
func (repo *minioRepository) GeneratePresignedGetObject(input m.PresignedGetInput) (*url.URL, error) {
|
||||
presignedUrl, err := repo.client.PresignedGetObject(context.Background(), input.Bucket, input.Object, input.Expiry, input.ReqParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return presignedUrl, nil
|
||||
}
|
||||
|
||||
func getBucketName(idx int) string {
|
||||
return m.O.GetBucketName()[idx]
|
||||
}
|
||||
|
||||
func GetBucketPatient() (string, error) {
|
||||
bucketName := getBucketName(0)
|
||||
if bucketName == "" {
|
||||
return "", errors.New("bucket name unknown")
|
||||
}
|
||||
return bucketName, nil
|
||||
}
|
||||
|
||||
func GetEndpointUrl(bucket string) string {
|
||||
mode := "http"
|
||||
if m.O.GetUseSsl() {
|
||||
mode = "https"
|
||||
}
|
||||
return fmt.Sprintf("%s://%s/%s", mode, m.O.GetEndpoint(), bucket)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package uploadhelper
|
||||
|
||||
type UploadResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
URL string `json:"url,omitempty"`
|
||||
FileName string `json:"filename,omitempty"`
|
||||
}
|
||||
|
||||
type MultipleUploadResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
TotalFiles int `json:"total_files"`
|
||||
SuccessCount int `json:"success_count"`
|
||||
Results []UploadResponse `json:"results"`
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package uploadhelper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
ere "simrs-vx/internal/domain/references/encounter"
|
||||
)
|
||||
|
||||
func getBucketForType(docType string) (string, error) {
|
||||
switch strings.ToLower(docType) {
|
||||
case "resident", "resident-number", "ktp":
|
||||
return string(ere.UCPRN), nil
|
||||
case "driver-license", "sim", "license":
|
||||
return string(ere.UCPDL), nil
|
||||
case "passport", "paspor":
|
||||
return string(ere.UCPP), nil
|
||||
case "family-card", "kk", "family":
|
||||
return string(ere.UCPFC), nil
|
||||
case "mcu", "medical", "mcu-result":
|
||||
return string(ere.UCMIR), nil
|
||||
default:
|
||||
return "", fmt.Errorf("unknown document type: %s", docType)
|
||||
}
|
||||
}
|
||||
|
||||
// getValidFileTypesForBucket returns allowed file types for each bucket
|
||||
func getValidFileTypesForBucket(bucketName string) []string {
|
||||
switch bucketName {
|
||||
case string(ere.UCPRN), string(ere.UCPDL), string(ere.UCPP), string(ere.UCPFC):
|
||||
return []string{".jpg", ".jpeg", ".png", ".pdf", ".gif"}
|
||||
case string(ere.UCMIR):
|
||||
return []string{".jpg", ".jpeg", ".png", ".pdf", ".gif", ".doc", ".docx", ".xls", ".xlsx"}
|
||||
default:
|
||||
return []string{".jpg", ".jpeg", ".png", ".pdf"}
|
||||
}
|
||||
}
|
||||
|
||||
// isValidFileType checks if the uploaded file type is allowed for the specific bucket
|
||||
func isValidFileType(filename, bucketName string) bool {
|
||||
allowedTypes := getValidFileTypesForBucket(bucketName)
|
||||
ext := strings.ToLower(filepath.Ext(filename))
|
||||
|
||||
for _, allowedExt := range allowedTypes {
|
||||
if ext == allowedExt {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// getContentType determines the content type based on file extension
|
||||
func getContentType(filename string) string {
|
||||
switch strings.ToLower(filepath.Ext(filename)) {
|
||||
case ".jpg", ".jpeg":
|
||||
return "image/jpeg"
|
||||
case ".png":
|
||||
return "image/png"
|
||||
case ".pdf":
|
||||
return "application/pdf"
|
||||
case ".gif":
|
||||
return "image/gif"
|
||||
case ".doc":
|
||||
return "application/msword"
|
||||
case ".docx":
|
||||
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
case ".xls":
|
||||
return "application/vnd.ms-excel"
|
||||
case ".xlsx":
|
||||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
default:
|
||||
return "application/octet-stream"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user