This commit is contained in:
Michael
2026-04-29 20:11:57 +02:00
commit a14103ad8e
167 changed files with 7060 additions and 0 deletions

View File

@ -0,0 +1,39 @@
package db
import (
"context"
"fmt"
"os"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
var Pool *pgxpool.Pool
func Connect() error {
dsn := fmt.Sprintf(
"postgres://%s:%s@%s:%s/%s?sslmode=disable",
os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"),
os.Getenv("DB_HOST"),
os.Getenv("DB_PORT"),
os.Getenv("DB_NAME"),
)
c, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
pool, err := pgxpool.New(c, dsn)
if err != nil {
return err
}
if err := pool.Ping(c); err != nil {
pool.Close()
return err
}
Pool = pool
return nil
}

18
app/internal/infr/env/init.go vendored Normal file
View File

@ -0,0 +1,18 @@
// Package env provides environment variables
package env
import (
"log"
"github.com/joho/godotenv"
)
// SetupEnvFile is a function to setup .env file
func SetupEnvFile() {
envFile := ".env"
var err error
if (godotenv.Load(envFile)); err != nil {
log.Printf("No %s file found, reading from environment", envFile)
}
}

View File

@ -0,0 +1,11 @@
package qrgenerator
import "git.heldm.com/held/qrcode/internal/qrcode/vo"
func CreateQR(qr vo.QRImg) ([]byte, error) {
if qr.ImgFormat() == "svg" {
return GenerateSVG(qr.Link())
}
return GenerateQRCodePNG(qr)
}

View File

@ -0,0 +1,15 @@
package qrgenerator
import (
"git.heldm.com/held/qrcode/internal/qrcode/vo"
qrcode "github.com/skip2/go-qrcode"
)
func GenerateQRCodePNG(qr vo.QRImg) ([]byte, error) {
png, err := qrcode.Encode(qr.Link(), qrcode.Medium, qr.ImgSize())
if err != nil {
return nil, err
}
return png, nil
}

View File

@ -0,0 +1,14 @@
package qrgenerator
import (
qrsvg "github.com/wamuir/svg-qr-code"
)
func GenerateSVG(text string) ([]byte, error) {
qr, err := qrsvg.New(text)
if err != nil {
return nil, err
}
return []byte(qr.String()), nil
}

168
app/internal/infr/s3/s3.go Normal file
View File

@ -0,0 +1,168 @@
// Package s3 is a package for s3
package s3
import (
"context"
"errors"
"fmt"
"mime/multipart"
"os"
"strconv"
"time"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// Client ...
var Client *minio.Client
// Init ...
func Init() error {
c := context.Background()
endpoint := os.Getenv("S3_ENDPOINT")
accessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
useSSL, errUseSSL := strconv.ParseBool(os.Getenv("S3_USE_SSL"))
if errUseSSL != nil {
return errUseSSL
}
println("S3 endpoint: ", endpoint)
client, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
Secure: useSSL,
})
if err != nil {
return err
}
Client = client
backetName := os.Getenv("S3_BUCKET")
region := os.Getenv("S3_REGION")
println("S3 bucket: ", backetName)
if err := Client.MakeBucket(c, backetName, minio.MakeBucketOptions{Region: region}); err != nil {
println("Error can't create bucket ", err.Error())
// Check to see if we already own this bucket (which happens if you run this twice)
exists, err := Client.BucketExists(c, backetName)
println("Bucket exists: ", exists)
if err == nil && exists {
println("We already own %s\n", backetName)
} else {
println("Error can't create bucket ", err.Error())
return err
}
}
println("S3 init success")
return nil
}
// Upload ...
func Upload(file *multipart.FileHeader, fileName, path string) (string, error) {
fileOpen, errOpen := file.Open()
if errOpen != nil {
return "", errOpen
}
defer fileOpen.Close()
src := path + fileName
_, err := Client.PutObject(
context.Background(),
os.Getenv("S3_BUCKET"),
src,
fileOpen,
file.Size,
minio.PutObjectOptions{
ContentType: file.Header.Get("Content-Type"),
})
if err != nil {
return "", err
}
return src, nil
}
// UploadWebpFile ...
func UploadWebpFile(file *os.File, src string) error {
fileInfo, err := file.Stat()
if err != nil {
return err
}
fileOpen, err := os.Open(file.Name())
if err != nil {
return err
}
info, err := Client.PutObject(
context.Background(),
os.Getenv("S3_BUCKET"),
src,
fileOpen,
fileInfo.Size(),
minio.PutObjectOptions{
ContentType: "image/webp",
})
if err != nil {
fmt.Println("Error upload file: ", err.Error())
fmt.Println("info: ", fileInfo.Size())
return err
}
fmt.Println(info)
return nil
}
// CreatePathAndName name and path for file
func CreatePath(path string) (string, string) {
year, _, _ := time.Now().Date()
nameFold := strconv.FormatInt(time.Now().UnixNano(), 10)
path = path + "/" + strconv.FormatInt(int64(year), 10) + "/" + nameFold + "/"
return nameFold, path
}
// UploadRandom is a function separate files by year and create random name
func UploadRandom(file *multipart.FileHeader, path string) (string, error) {
year, _, _ := time.Now().Date()
path = path + "/" + strconv.FormatInt(int64(year), 10) + "/"
fileName := strconv.FormatInt(time.Now().UnixNano(), 10) + "-" + file.Filename
return Upload(file, fileName, path)
}
// Remove ...
func Remove(src string) error {
c := context.Background()
return Client.RemoveObject(c, os.Getenv("S3_BUCKET"), src, minio.RemoveObjectOptions{})
}
// RemoveAll ...
func RemoveAll(srcs []string) error {
c := context.Background()
for _, src := range srcs {
if src == "" {
continue
}
if err := Client.RemoveObject(c, os.Getenv("S3_BUCKET"), src, minio.RemoveObjectOptions{}); err != nil {
return errors.New("Remove file error: " + err.Error())
}
}
return nil
}
// GetObject ...
func GetObject(src string) (*minio.Object, error) {
c := context.Background()
return Client.GetObject(c, os.Getenv("S3_BUCKET"), src, minio.GetObjectOptions{})
}