This commit is contained in:
mm 2024-09-27 13:50:20 +05:00
parent 14e82f3298
commit b94abfe75b
22 changed files with 418 additions and 562 deletions

View File

@ -1,6 +1,24 @@
package main package main
import "donat-widget/internal/app/http" import (
"context"
"donat-widget/internal/app/http"
"donat-widget/internal/config"
)
import (
"donat-widget/infrastructure/pg"
"donat-widget/infrastructure/weed"
)
import (
WidgetRepo "donat-widget/internal/repository/widget"
DonatRepo "donat-widget/internal/repository/widget/donat"
MediaRepo "donat-widget/internal/repository/widget/media"
WidgetService "donat-widget/internal/service/widget"
DonatService "donat-widget/internal/service/widget/donat"
MediaService "donat-widget/internal/service/widget/media"
)
// @title Widget service // @title Widget service
// @version 1.0 // @version 1.0
@ -10,6 +28,26 @@ import "donat-widget/internal/app/http"
// @BasePath /api/widget // @BasePath /api/widget
func main() { func main() {
httpServer := http.NewApp() cfg := config.Init()
http.Run(httpServer)
// INFRASTRUCTURE
db := pg.NewPgPool(context.Background(), cfg.Db.Username, cfg.Db.Password, cfg.Db.Host, cfg.Db.Port, cfg.Db.DBName)
storage := weed.NewWeed(cfg.Storage.Filer, cfg.Storage.Master)
// REPOSITORIES
widgetRepo := WidgetRepo.New(db)
mediaRepo := MediaRepo.New(db, storage)
donatRepo := DonatRepo.New(db)
// SERVICES
widgetService := WidgetService.New(widgetRepo, donatRepo)
mediaService := MediaService.New(mediaRepo)
donatService := DonatService.New(donatRepo)
http.NewApp(
db,
widgetService,
mediaService,
donatService,
)
} }

View File

@ -33,28 +33,6 @@ func NewPgPool(
return pgInstance return pgInstance
} }
func (pg *Postgres) CreateTable(ctx context.Context) error {
_, err := pg.db.Exec(ctx, createTableQuery)
if err != nil {
return err
}
_, err = pg.db.Exec(ctx, onUpdateTableQuery)
if err != nil {
return err
}
return nil
}
func (pg *Postgres) DropTable(ctx context.Context) error {
_, err := pg.db.Exec(ctx, dropTableQuery)
if err != nil {
return err
}
return nil
}
func (pg *Postgres) Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error) { func (pg *Postgres) Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error) {
result, err := pg.db.Exec(ctx, query, args...) result, err := pg.db.Exec(ctx, query, args...)
if err != nil { if err != nil {
@ -70,3 +48,20 @@ func (pg *Postgres) Query(ctx context.Context, query string, args ...interface{}
} }
return result, nil return result, nil
} }
func (pg *Postgres) CreateTable(ctx context.Context, query string) error {
_, err := pg.db.Exec(ctx, query)
if err != nil {
return err
}
return nil
}
func (pg *Postgres) DropTable(ctx context.Context, query string) error {
_, err := pg.db.Exec(ctx, query)
if err != nil {
return err
}
return nil
}

View File

@ -1,50 +0,0 @@
package pg
var createTableQuery = `
CREATE TABLE IF NOT EXISTS widgets (
id SERIAL PRIMARY KEY,
streamer_id INTEGER NOT NULL,
template_id INTEGER NOT NULL,
background_url TEXT DEFAULT '',
image_url TEXT DEFAULT '',
audio_url TEXT DEFAULT '',
duration INTEGER DEFAULT 30,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS donats (
id SERIAL PRIMARY KEY,
widget_id INTEGER NOT NULL,
text TEXT DEFAULT '',
amount TEXT DEFAULT '',
donat_user TEXT DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
`
var onUpdateTableQuery = `
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER update_updated_at_trigger
BEFORE UPDATE ON widgets
FOR EACH ROW
EXECUTE PROCEDURE update_updated_at();
CREATE TRIGGER update_updated_at_trigger
BEFORE UPDATE ON donats
FOR EACH ROW
EXECUTE PROCEDURE update_updated_at();
`
var dropTableQuery = `
DROP TABLE IF EXISTS widgets;
DROP TABLE IF EXISTS donats;
`

View File

@ -17,7 +17,7 @@ func NewWeed(
filer string, filer string,
masterUrl string, masterUrl string,
) (*Weed, error) { ) *Weed {
filers := []string{filer} filers := []string{filer}
sw, err := goseaweedfs.NewSeaweed( sw, err := goseaweedfs.NewSeaweed(
masterUrl, masterUrl,
@ -26,9 +26,9 @@ func NewWeed(
&http.Client{Timeout: 5 * time.Minute}, &http.Client{Timeout: 5 * time.Minute},
) )
if err != nil { if err != nil {
return &Weed{}, err panic("Failed to create seaweed: " + err.Error())
} }
return &Weed{sw}, err return &Weed{sw}
} }

View File

@ -8,22 +8,6 @@ import (
"strconv" "strconv"
) )
type donatSetter interface {
SetDonat(
ctx context.Context,
widgetID model.WidgetID,
text string,
amount model.DonatAmount,
donatUser string,
) error
}
type SetDonatRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
Text string `json:"text" validate:"required"`
Amount model.DonatAmount `json:"amount" validate:"required"`
DonatUser string `json:"donatUser" validate:"required"`
}
// SetDonat // SetDonat
// //
// @Description Set donat // @Description Set donat
@ -32,7 +16,7 @@ type SetDonatRequest struct {
// @Produce json // @Produce json
// @Param RegisterData body SetDonatRequest true "Set donat" // @Param RegisterData body SetDonatRequest true "Set donat"
// @Router /api/widget/donat/set [post] // @Router /api/widget/donat/set [post]
func SetDonat(donatService donatSetter) echo.HandlerFunc { func SetDonat(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -63,13 +47,6 @@ func SetDonat(donatService donatSetter) echo.HandlerFunc {
} }
} }
type donatDeleter interface {
DeleteDonat(
ctx context.Context,
DonatID model.DonatID,
) error
}
// DeleteDonat // DeleteDonat
// //
// @Description Delete donat // @Description Delete donat
@ -77,7 +54,7 @@ type donatDeleter interface {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Router /api/widget/donat/delete/{donatID} [post] // @Router /api/widget/donat/delete/{donatID} [post]
func DeleteDonat(donatService donatDeleter) echo.HandlerFunc { func DeleteDonat(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()

View File

@ -0,0 +1,10 @@
package donat
import "donat-widget/internal/model"
type SetDonatRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
Text string `json:"text" validate:"required"`
Amount model.DonatAmount `json:"amount" validate:"required"`
DonatUser string `json:"donatUser" validate:"required"`
}

View File

@ -8,18 +8,6 @@ import (
"strconv" "strconv"
) )
type FileSetter interface {
SetMediaFile(
ctx context.Context,
mediaType model.MediaType,
widgetID model.WidgetID,
file model.UploadFile,
filename string,
size int64,
collection string,
) error
}
// SetMediaFile // SetMediaFile
// //
// @Description Upload media // @Description Upload media
@ -29,7 +17,7 @@ type FileSetter interface {
// @Param file formData file true "File to upload" // @Param file formData file true "File to upload"
// @Param widgetId path int true "Widget ID" // @Param widgetId path int true "Widget ID"
// @Router /api/widget/media/{mediaType}/upload [post] // @Router /api/widget/media/{mediaType}/upload [post]
func SetMediaFile(service FileSetter) echo.HandlerFunc { func SetMediaFile(service model.MediaService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -67,14 +55,6 @@ func SetMediaFile(service FileSetter) echo.HandlerFunc {
} }
} }
type FileGetter interface {
GetMediaFile(
ctx context.Context,
widgetID model.WidgetID,
mediaType model.MediaType,
) (model.DownloadFile, error)
}
// GetMediaFile // GetMediaFile
// //
// @Description Get media // @Description Get media
@ -83,7 +63,7 @@ type FileGetter interface {
// @Param widgetId path int true "Widget ID" // @Param widgetId path int true "Widget ID"
// @Param mediaType path string true "'background' or 'image' or 'audio'" // @Param mediaType path string true "'background' or 'image' or 'audio'"
// @Router /api/widget/media/{mediaType}/get/{widgetID} [post] // @Router /api/widget/media/{mediaType}/get/{widgetID} [post]
func GetMediaFile(service FileGetter) echo.HandlerFunc { func GetMediaFile(service model.MediaService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -109,19 +89,7 @@ func GetMediaFile(service FileGetter) echo.HandlerFunc {
} }
} }
type FileUpdater interface { func UpdateMediaFile(service model.MediaService) echo.HandlerFunc {
UpdateMediaFile(
ctx context.Context,
widgetID model.WidgetID,
mediaType model.MediaType,
file model.UploadFile,
filename string,
size int64,
collection string,
) error
}
func UpdateMediaFile(service FileUpdater) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -160,25 +128,12 @@ func UpdateMediaFile(service FileUpdater) echo.HandlerFunc {
} }
} }
type UrlSetter interface {
SetMediaUrl(
ctx context.Context,
mediaType model.MediaType,
widgetID model.WidgetID,
mediaURL model.MediaUrl,
) error
}
type SetRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"`
}
// SetMediaUrl // SetMediaUrl
// //
// @Description Set media URL // @Description Set media URL
// @Param mediaType path string true "'background' or 'image' or 'audio'" // @Param mediaType path string true "'background' or 'image' or 'audio'"
// @Router /api/widget/media/{mediaType}/set [post] // @Router /api/widget/media/{mediaType}/set [post]
func SetMediaUrl(service UrlSetter) echo.HandlerFunc { func SetMediaUrl(service model.MediaService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()

View File

@ -0,0 +1,8 @@
package media
import "donat-widget/internal/model"
type SetRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"`
}

View File

@ -0,0 +1,27 @@
package widget
import "donat-widget/internal/model"
type CreateWidgetRequest struct {
StreamerID model.StreamerID `json:"streamerID" validate:"required"`
TemplateID model.TemplateID `json:"templateID" validate:"required"`
}
type CreateWidgetResponse struct {
WidgetID model.WidgetID `json:"widgetID"`
}
type GetWidgetInfoResponse struct {
AudioUrl model.MediaUrl `json:"audioUrl"`
ImageUrl model.MediaUrl `json:"imageUrl"`
Text string `json:"text"`
Amount model.DonatAmount `json:"amount"`
DonatUser string `json:"donatUser"`
Display model.Display `json:"display"`
Duration model.Duration `json:"duration"`
DonatID model.DonatID `json:"donatID"`
}
type UpdateDurationRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
Duration model.Duration `json:"duration" validate:"required"`
}

View File

@ -8,21 +8,6 @@ import (
"strconv" "strconv"
) )
type widgetCreator interface {
CreateWidget(
ctx context.Context,
streamerID model.StreamerID,
templateID model.TemplateID,
) (model.WidgetID, error)
}
type CreateWidgetRequest struct {
StreamerID model.StreamerID `json:"streamerID" validate:"required"`
TemplateID model.TemplateID `json:"templateID" validate:"required"`
}
type CreateWidgetResponse struct {
WidgetID model.WidgetID `json:"widgetID"`
}
// CreateWidget // CreateWidget
// //
// @Description Create widget // @Description Create widget
@ -32,7 +17,7 @@ type CreateWidgetResponse struct {
// @Param RegisterData body CreateWidgetRequest true "Create widget" // @Param RegisterData body CreateWidgetRequest true "Create widget"
// @Success 200 {object} CreateWidgetResponse // @Success 200 {object} CreateWidgetResponse
// @Router /api/widget/create [post] // @Router /api/widget/create [post]
func CreateWidget(widgetService widgetCreator) echo.HandlerFunc { func CreateWidget(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -63,13 +48,6 @@ func CreateWidget(widgetService widgetCreator) echo.HandlerFunc {
} }
} }
type widgetHTMLGetter interface {
GetWidgetHTML(
ctx context.Context,
widgetID model.WidgetID,
) (model.WidgetHTML, error)
}
// GetWidgetHTML @Description Get widget // GetWidgetHTML @Description Get widget
// //
// @Tags Widget // @Tags Widget
@ -77,7 +55,7 @@ type widgetHTMLGetter interface {
// @Produce json // @Produce json
// @Success 200 // @Success 200
// @Router /api/widget/html/{widgetID} [get] // @Router /api/widget/html/{widgetID} [get]
func GetWidgetHTML(widgetService widgetHTMLGetter) echo.HandlerFunc { func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -98,24 +76,6 @@ func GetWidgetHTML(widgetService widgetHTMLGetter) echo.HandlerFunc {
} }
} }
type widgetInfoGetter interface {
GetWidgetInfo(
ctx context.Context,
widgetID model.WidgetID,
) (*model.DonatAndWidget, error)
}
type GetInfoResponse struct {
AudioUrl model.MediaUrl `json:"audioUrl"`
ImageUrl model.MediaUrl `json:"imageUrl"`
Text string `json:"text"`
Amount model.DonatAmount `json:"amount"`
DonatUser string `json:"donatUser"`
Display model.Display `json:"display"`
Duration model.Duration `json:"duration"`
DonatID model.DonatID `json:"donatID"`
}
// GetWidgetInfo // GetWidgetInfo
// //
// @Description Widget Info // @Description Widget Info
@ -124,7 +84,7 @@ type GetInfoResponse struct {
// @Produce json // @Produce json
// @Param widgetID path int true "Widget ID" // @Param widgetID path int true "Widget ID"
// @Router /api/widget/info/{widgetID} [get] // @Router /api/widget/info/{widgetID} [get]
func GetWidgetInfo(widgetService widgetInfoGetter) echo.HandlerFunc { func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -139,14 +99,14 @@ func GetWidgetInfo(widgetService widgetInfoGetter) echo.HandlerFunc {
} }
if !donatAndWidget.Display { if !donatAndWidget.Display {
response := GetInfoResponse{ response := GetWidgetInfoResponse{
Display: donatAndWidget.Display, Display: donatAndWidget.Display,
} }
slog.Info("Get widget info successfully") slog.Info("Get widget info successfully")
return request.JSON(200, response) return request.JSON(200, response)
} }
response := GetInfoResponse{ response := GetWidgetInfoResponse{
AudioUrl: donatAndWidget.Widget.AudioUrl, AudioUrl: donatAndWidget.Widget.AudioUrl,
ImageUrl: donatAndWidget.Widget.ImageUrl, ImageUrl: donatAndWidget.Widget.ImageUrl,
Text: donatAndWidget.Donat.Text, Text: donatAndWidget.Donat.Text,
@ -161,19 +121,6 @@ func GetWidgetInfo(widgetService widgetInfoGetter) echo.HandlerFunc {
} }
} }
type widgetDurationUpdater interface {
UpdateWidgetDuration(
ctx context.Context,
widgetID model.WidgetID,
duration model.Duration,
) error
}
type UpdateDurationRequest struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
Duration model.Duration `json:"duration" validate:"required"`
}
// UpdateDuration // UpdateDuration
// //
// @Description UpdateDuration // @Description UpdateDuration
@ -183,7 +130,7 @@ type UpdateDurationRequest struct {
// @Param UpdateData body UpdateDurationRequest true "UpdateDuration" // @Param UpdateData body UpdateDurationRequest true "UpdateDuration"
// @Success 200 // @Success 200
// @Router /api/widget/duration/update [post] // @Router /api/widget/duration/update [post]
func UpdateDuration(widgetService widgetDurationUpdater) echo.HandlerFunc { func UpdateDuration(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
@ -197,7 +144,7 @@ func UpdateDuration(widgetService widgetDurationUpdater) echo.HandlerFunc {
return echo.NewHTTPError(400, err.Error()) return echo.NewHTTPError(400, err.Error())
} }
err = widgetService.UpdateWidgetDuration( err = widgetService.UpdateDuration(
ctx, ctx,
widgetData.WidgetID, widgetData.WidgetID,
widgetData.Duration, widgetData.Duration,

View File

@ -2,124 +2,77 @@ package http
import ( import (
"context" "context"
"donat-widget/internal/model/sql"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/swaggo/echo-swagger" "github.com/swaggo/echo-swagger"
"log/slog" "log/slog"
"os"
) )
import ( import (
"donat-widget/infrastructure/pg"
"donat-widget/infrastructure/weed"
"donat-widget/internal/config"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/pkg/validator" "donat-widget/pkg/validator"
) )
import ( import (
widgetHandler "donat-widget/internal/api/http/handlers/widget" . "donat-widget/internal/api/http/handlers/widget"
widgetService "donat-widget/internal/service/widget" . "donat-widget/internal/api/http/handlers/widget/donat"
. "donat-widget/internal/api/http/handlers/widget/media"
mediaHandler "donat-widget/internal/api/http/handlers/widget/media"
mediaService "donat-widget/internal/service/widget/media"
donatHandler "donat-widget/internal/api/http/handlers/widget/donat"
donatService "donat-widget/internal/service/widget/donat"
) )
type App struct { var PREFIX = "/api/widget"
Config *config.Config
}
func NewApp() *echo.Echo { func NewApp(
app := &App{} db model.Db,
_ = app.InitLogger() widgetService model.WidgetService,
app.Config = app.InitConfig() mediaService model.MediaService,
db := app.initDB() donatService model.DonatService,
storage := app.InitStorage() ) {
server := InitHTTPServer()
InitHandlers(server, db, storage)
return server
}
func Run(server *echo.Echo) {
server.Logger.Fatal(server.Start(":8002"))
}
func InitHTTPServer() *echo.Echo {
server := echo.New() server := echo.New()
server.Validator = validator.NewValidator() server.Validator = validator.NewValidator()
return server
}
func (a *App) InitConfig() *config.Config {
cfg := config.Init()
return cfg
}
func (a *App) InitLogger() *slog.Logger {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
slog.SetDefault(logger)
return logger
}
func (a *App) InitStorage() *weed.Weed {
storage, err := weed.NewWeed(
a.Config.Storage.Filer,
a.Config.Storage.Master,
)
if err != nil {
panic(err)
}
return storage
}
func (a *App) initDB() *pg.Postgres {
db := pg.NewPgPool(
context.Background(),
a.Config.Db.Username,
a.Config.Db.Password,
a.Config.Db.Host,
a.Config.Db.Port,
a.Config.Db.DBName,
)
return db
}
func InitHandlers(
server *echo.Echo,
db *pg.Postgres,
storage model.Storage,
) {
PREFIX := "/api/widget"
server.GET(PREFIX+"/docs/*", echoSwagger.WrapHandler) server.GET(PREFIX+"/docs/*", echoSwagger.WrapHandler)
server.GET(PREFIX+"/table/create", CreateTale(db)) server.GET(PREFIX+"/table/create", CreateTale(db))
server.GET(PREFIX+"/table/drop", DropTale(db)) server.GET(PREFIX+"/table/drop", DropTale(db))
widgetSvc := widgetService.New(db) IncludeWidgetHandlers(server, widgetService)
server.GET(PREFIX+"/create", widgetHandler.CreateWidget(widgetSvc)) IncludeMediaHandlers(server, mediaService)
server.GET(PREFIX+"/html/:widgetID", widgetHandler.GetWidgetHTML(widgetSvc)) IncludeDonatHandlers(server, donatService)
server.GET(PREFIX+"/info/:widgetID", widgetHandler.GetWidgetInfo(widgetSvc))
server.GET(PREFIX+"/duration/update", widgetHandler.UpdateDuration(widgetSvc))
mediaSvc := mediaService.New(db, storage) server.Logger.Fatal(server.Start(":8002"))
server.POST(PREFIX+"/media/:mediaType/upload", mediaHandler.SetMediaFile(mediaSvc))
server.GET(PREFIX+"/media/:mediaType/get/:widgetID", mediaHandler.GetMediaFile(mediaSvc))
server.POST(PREFIX+"/media/:mediaType/set", mediaHandler.SetMediaUrl(mediaSvc))
donatSvc := donatService.New(db)
server.POST(PREFIX+"/donat/set", donatHandler.SetDonat(donatSvc))
server.DELETE(PREFIX+"/donat/delete/:donatID", donatHandler.DeleteDonat(donatSvc))
} }
func CreateTale(db *pg.Postgres) echo.HandlerFunc { func IncludeDonatHandlers(
server *echo.Echo,
donatService model.DonatService,
) {
server.POST(PREFIX+"/donat/set", SetDonat(donatService))
server.DELETE(PREFIX+"/donat/delete/:donatID", DeleteDonat(donatService))
}
func IncludeMediaHandlers(
server *echo.Echo,
mediaService model.MediaService,
) {
server.POST(PREFIX+"/media/:mediaType/upload", SetMediaFile(mediaService))
server.POST(PREFIX+"/media/:mediaType/set", SetMediaUrl(mediaService))
server.GET(PREFIX+"/media/:mediaType/get/:widgetID", GetMediaFile(mediaService))
}
func IncludeWidgetHandlers(
server *echo.Echo,
widgetService model.WidgetService,
) {
server.POST(PREFIX+"/create", CreateWidget(widgetService))
server.PATCH(PREFIX+"/duration/update", UpdateDuration(widgetService))
server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService))
server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService))
}
func CreateTale(db model.Db) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
err := db.CreateTable(ctx) err := db.CreateTable(ctx, sql.CreateTableQuery)
if err != nil { if err != nil {
slog.Error("db.CreateTable: ", err) slog.Error("db.CreateTable: ", err)
return err return err
@ -130,11 +83,11 @@ func CreateTale(db *pg.Postgres) echo.HandlerFunc {
} }
} }
func DropTale(db *pg.Postgres) echo.HandlerFunc { func DropTale(db model.Db) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
err := db.DropTable(ctx) err := db.DropTable(ctx, sql.DropTableQuery)
if err != nil { if err != nil {
slog.Error("db.DropTable: ", err) slog.Error("db.DropTable: ", err)
return err return err

View File

@ -3,108 +3,64 @@ package model
import ( import (
"context" "context"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgconn"
) )
type Storage interface { type WidgetService interface {
Upload( CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID) (WidgetID, error)
file UploadFile, DeleteWidget(ctx context.Context, widgetID WidgetID) error
filename string, UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
size int64, GetWidgetInfo(ctx context.Context, widgetID WidgetID) (*DonatAndWidget, error)
collection string, GetWidgetHTML(ctx context.Context, widgetID WidgetID) (WidgetHTML, error)
) (FileData, error)
Download(
FileID FileID,
) (DownloadFile, error)
Update(
file UploadFile,
fileID FileID,
filename string,
size int64,
collection string,
) error
} }
type WidgetRepo interface { type WidgetRepo interface {
CreateWidget( CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID) (WidgetID, error)
ctx context.Context, DeleteWidget(ctx context.Context, widgetID WidgetID) error
streamerID StreamerID, UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
templateId TemplateID, GetWidget(ctx context.Context, widgetID WidgetID) (*Widget, error)
) (WidgetID, error)
DeleteWidget(
ctx context.Context,
widgetID WidgetID,
) error
GetWidget(
ctx context.Context,
widgetID WidgetID,
) (*Widget, error)
UpdateWidgetDuration(
ctx context.Context,
widgetID WidgetID,
duration Duration,
) error
} }
type DonatRepo interface { type MediaService interface {
SetDonat( SetMediaFile(ctx context.Context, mediaType MediaType, widgetID WidgetID, file UploadFile, filename string, size int64, collection string) error
ctx context.Context, SetMediaUrl(ctx context.Context, mediaType MediaType, widgetID WidgetID, mediaURL MediaUrl) error
widgetID WidgetID, UpdateMediaFile(ctx context.Context, widgetID WidgetID, mediaType MediaType, file UploadFile, filename string, size int64, collection string) error
text string, GetMediaFile(ctx context.Context, widgetID WidgetID, mediaType MediaType) (DownloadFile, error)
amount DonatAmount,
donatUser string,
) error
GetDonat(
ctx context.Context,
widgetID WidgetID,
) ([]*Donat, error)
DeleteDonat(
ctx context.Context,
donatID DonatID,
) error
} }
type MediaRepo interface { type MediaRepo interface {
SetMediaFile( SetMediaFile(file UploadFile, filename string, size int64, collection string) (FileID, error)
file UploadFile, GetMediaFile(fileID FileID) (DownloadFile, error)
filename string, GetMediaUrl(ctx context.Context, widgetID WidgetID, mediaType MediaType) (MediaUrl, error)
size int64, SetMediaUrl(ctx context.Context, widgetID WidgetID, mediaUrl MediaUrl, mediaType MediaType) error
collection string, UpdateMediaFile(ctx context.Context, widgetID WidgetID, file UploadFile, fileID FileID, filename string, size int64, collection string, mediaType MediaType) error
) (FileID, error) }
GetMediaFile(
fileID FileID, type DonatService interface {
) (DownloadFile, error) SetDonat(ctx context.Context, widgetID WidgetID, text string, amount DonatAmount, donatUser string) error
GetMediaUrl( DeleteDonat(ctx context.Context, DonatID DonatID) error
ctx context.Context, }
widgetID WidgetID,
mediaType MediaType, type DonatRepo interface {
) (MediaUrl, error) SetDonat(ctx context.Context, widgetID WidgetID, text string, amount DonatAmount, donatUser string) error
SetMediaUrl( GetDonat(ctx context.Context, widgetID WidgetID) ([]*Donat, error)
ctx context.Context, DeleteDonat(ctx context.Context, donatID DonatID) error
widgetID WidgetID,
mediaUrl MediaUrl,
mediaType MediaType,
) error
UpdateMediaFile(
ctx context.Context,
widgetID WidgetID,
file UploadFile,
fileID FileID,
filename string,
size int64,
collection string,
mediaType MediaType,
) error
} }
type Error interface { type Error interface {
Error() string Error() string
} }
type Storage interface {
Upload(file UploadFile, filename string, size int64, collection string) (FileData, error)
Download(FileID FileID) (DownloadFile, error)
Update(file UploadFile, fileID FileID, filename string, size int64, collection string) error
}
type Db interface { type Db interface {
Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error) Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error)
Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error) Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
CreateTable(ctx context.Context, query string) error
DropTable(ctx context.Context, query string) error
} }

View File

@ -1,6 +1,8 @@
package model package model
import ( import (
"strconv"
"strings"
"time" "time"
) )
@ -16,6 +18,34 @@ type Widget struct {
UpdatedAt time.Time UpdatedAt time.Time
} }
func (widget *Widget) GetMediaUrl(mediaType MediaType) MediaUrl {
var mediaUrl MediaUrl
if mediaType == "background_url" {
mediaUrl = widget.BackgroundUrl
} else if mediaType == "image_url" {
mediaUrl = widget.ImageUrl
} else if mediaType == "audio_url" {
mediaUrl = widget.AudioUrl
}
return mediaUrl
}
func (widget *Widget) NormalizeUrl() {
selfDomain := "http://localhost:8002/api/widget/media"
strWidgetID := strconv.Itoa(int(widget.ID))
if !strings.Contains(string(widget.ImageUrl), "http") && widget.ImageUrl != "" {
widget.ImageUrl = MediaUrl(selfDomain + "/image/get/" + strWidgetID)
}
if !strings.Contains(string(widget.BackgroundUrl), "http") && widget.BackgroundUrl != "" {
widget.BackgroundUrl = MediaUrl(selfDomain + "/background/get/" + strWidgetID)
}
if !strings.Contains(string(widget.AudioUrl), "http") && widget.AudioUrl != "" {
widget.AudioUrl = MediaUrl(selfDomain + "/audio/get/" + strWidgetID)
}
}
type Donat struct { type Donat struct {
ID DonatID ID DonatID
WidgetID WidgetID WidgetID WidgetID

View File

@ -0,0 +1,48 @@
package sql
var CreateTableQuery = `
CREATE TABLE IF NOT EXISTS widgets (
id SERIAL PRIMARY KEY,
streamer_id INTEGER NOT NULL,
template_id INTEGER NOT NULL,
background_url TEXT DEFAULT '',
image_url TEXT DEFAULT '',
audio_url TEXT DEFAULT '',
duration INTEGER DEFAULT 30,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS donats (
id SERIAL PRIMARY KEY,
widget_id INTEGER NOT NULL,
text TEXT DEFAULT '',
amount TEXT DEFAULT '',
donat_user TEXT DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER update_updated_at_trigger
BEFORE UPDATE ON widgets
FOR EACH ROW
EXECUTE PROCEDURE update_updated_at();
CREATE TRIGGER update_updated_at_trigger
BEFORE UPDATE ON donats
FOR EACH ROW
EXECUTE PROCEDURE update_updated_at();
`
var DropTableQuery = `
DROP TABLE IF EXISTS widgets;
DROP TABLE IF EXISTS donats;
`

View File

@ -0,0 +1,53 @@
package sql
import (
"donat-widget/internal/model"
"fmt"
)
var CreateWidgetQuery = `
INSERT INTO widgets (streamer_id, template_id)
VALUES (@streamer_id, @template_id);
`
var SetDonatQuery = `
INSERT INTO donats (widget_id, text, amount, donat_user)
VALUES (@widget_id, @text, @amount, @donat_user);
`
var DeleteDonatQuery = `
DELETE FROM donats WHERE id = (@id);
`
var UpdateDurationQuery = `
UPDATE widgets
SET duration = (@duration)
WHERE id = (@id)
`
func UpdateMediaUrlQuery(mediaType model.MediaType) string {
query := fmt.Sprintf(`
UPDATE widgets
SET %s = (@%s)
WHERE id = (@id)
`, mediaType, mediaType)
return query
}
var GetDonatQuery = `
SELECT * FROM donats WHERE widget_id = (@widget_id);
`
var GetWidgetQuery = `
SELECT * FROM widgets
WHERE id = (@id);
`
func GetMediaUrl(mediaType model.MediaType) string {
query := fmt.Sprintf(`
SELECT %s
FROM widgets
WHERE id = (@id)
`, mediaType)
return query
}

View File

@ -5,6 +5,8 @@ import (
"mime/multipart" "mime/multipart"
) )
type QueryArgs map[string]any
type StreamerID int type StreamerID int
type WidgetID int type WidgetID int
type TemplateID int type TemplateID int

View File

@ -3,15 +3,16 @@ package donat
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/sql"
"github.com/georgysavva/scany/v2/pgxscan" "github.com/georgysavva/scany/v2/pgxscan"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"log/slog" "log/slog"
) )
func New( func New(db model.Db) *RepoDonat {
db model.Db, return &RepoDonat{
) *RepoDonat { db: db,
return &RepoDonat{db} }
} }
type RepoDonat struct { type RepoDonat struct {
@ -25,23 +26,18 @@ func (repoDonat *RepoDonat) SetDonat(
amount model.DonatAmount, amount model.DonatAmount,
donatUser string, donatUser string,
) error { ) error {
query := ` args := model.QueryArgs{
INSERT INTO donats (widget_id, text, amount, donat_user)
VALUES (@widget_id, @text, @amount, @donat_user);
`
args := pgx.NamedArgs{
"widget_id": widgetID, "widget_id": widgetID,
"text": text, "text": text,
"amount": amount, "amount": amount,
"donat_user": donatUser, "donat_user": donatUser,
} }
_, err := repoDonat.db.Query(ctx, sql.SetDonatQuery, args)
_, err := repoDonat.db.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error("repoDonat.db.Query: " + err.Error())
return err return err
} }
return nil return nil
} }
@ -49,21 +45,16 @@ func (repoDonat *RepoDonat) GetDonat(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, widgetID model.WidgetID,
) ([]*model.Donat, error) { ) ([]*model.Donat, error) {
query := `
SELECT * FROM donats WHERE widget_id = (@widget_id);
`
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"widget_id": widgetID, "widget_id": widgetID,
} }
rows, err := repoDonat.db.Query(ctx, sql.GetDonatQuery, args)
rows, err := repoDonat.db.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error("repoDonat.db.Query: " + err.Error())
return nil, err return nil, err
} }
var donats []*model.Donat
var donats []*model.Donat
err = pgxscan.ScanAll(&donats, rows) err = pgxscan.ScanAll(&donats, rows)
if err != nil { if err != nil {
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error()) slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error())
@ -77,15 +68,10 @@ func (repoDonat *RepoDonat) DeleteDonat(
ctx context.Context, ctx context.Context,
donatID model.DonatID, donatID model.DonatID,
) error { ) error {
query := `
DELETE FROM donats WHERE id = (@id);
`
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"id": donatID, "id": donatID,
} }
_, err := repoDonat.db.Query(ctx, sql.DeleteDonatQuery, args)
_, err := repoDonat.db.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error("repoDonat.db.Query: " + err.Error())
return err return err

View File

@ -3,10 +3,9 @@ package media
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/sql"
"errors" "errors"
"fmt"
"github.com/georgysavva/scany/v2/pgxscan" "github.com/georgysavva/scany/v2/pgxscan"
"github.com/jackc/pgx/v5"
"log/slog" "log/slog"
) )
@ -14,7 +13,10 @@ func New(
db model.Db, db model.Db,
storage model.Storage, storage model.Storage,
) *RepoMedia { ) *RepoMedia {
return &RepoMedia{db, storage} return &RepoMedia{
db: db,
storage: storage,
}
} }
type RepoMedia struct { type RepoMedia struct {
@ -28,19 +30,13 @@ func (repoMedia *RepoMedia) SetMediaFile(
size int64, size int64,
collection string, collection string,
) (model.FileID, error) { ) (model.FileID, error) {
fileData, err := repoMedia.storage.Upload( fileData, err := repoMedia.storage.Upload(file, filename, size, collection)
file,
filename,
size,
collection,
)
if err != nil { if err != nil {
slog.Error("repoMedia.storage.Upload: " + err.Error()) slog.Error("repoMedia.storage.Upload: " + err.Error())
return "", err return "", err
} }
fileID := fileData.FileID
return model.FileID(fileID), nil return model.FileID(fileData.FileID), nil
} }
func (repoMedia *RepoMedia) GetMediaFile( func (repoMedia *RepoMedia) GetMediaFile(
@ -51,6 +47,7 @@ func (repoMedia *RepoMedia) GetMediaFile(
slog.Error("repoMedia.storage.Download: " + err.Error()) slog.Error("repoMedia.storage.Download: " + err.Error())
return nil, err return nil, err
} }
return file, err return file, err
} }
@ -64,30 +61,18 @@ func (repoMedia *RepoMedia) UpdateMediaFile(
collection string, collection string,
mediaType model.MediaType, mediaType model.MediaType,
) error { ) error {
err := repoMedia.storage.Update( err := repoMedia.storage.Update(file, fileID, filename, size, collection)
file,
fileID,
filename,
size,
collection,
)
if err != nil { if err != nil {
slog.Error("repoMedia.storage.Update: " + err.Error()) slog.Error("repoMedia.storage.Update: " + err.Error())
return err return err
} }
mediaType = mediaType + "_url" mediaType = mediaType + "_url"
query := fmt.Sprintf(` args := model.QueryArgs{
UPDATE widgets
SET %s = (@%s)
WHERE id = (@id)
`, mediaType, mediaType)
args := pgx.NamedArgs{
string(mediaType): model.MediaUrl(fileID), string(mediaType): model.MediaUrl(fileID),
"id": widgetID, "id": widgetID,
} }
_, err = repoMedia.db.Query(ctx, query, args) _, err = repoMedia.db.Query(ctx, sql.UpdateMediaUrlQuery(mediaType), args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error("repoMedia.db.Query: " + err.Error())
return err return err
@ -103,17 +88,12 @@ func (repoMedia *RepoMedia) SetMediaUrl(
mediaType model.MediaType, mediaType model.MediaType,
) error { ) error {
mediaType = mediaType + "_url" mediaType = mediaType + "_url"
query := fmt.Sprintf(`
UPDATE widgets
SET %s = (@%s)
WHERE id = (@id)
`, mediaType, mediaType)
args := pgx.NamedArgs{ args := model.QueryArgs{
string(mediaType): mediaUrl, string(mediaType): mediaUrl,
"id": widgetID, "id": widgetID,
} }
_, err := repoMedia.db.Query(ctx, query, args) _, err := repoMedia.db.Query(ctx, sql.UpdateMediaUrlQuery(mediaType), args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error("repoMedia.db.Query: " + err.Error())
return err return err
@ -127,22 +107,16 @@ func (repoMedia *RepoMedia) GetMediaUrl(
mediaType model.MediaType, mediaType model.MediaType,
) (model.MediaUrl, error) { ) (model.MediaUrl, error) {
mediaType = mediaType + "_url" mediaType = mediaType + "_url"
query := fmt.Sprintf(` args := model.QueryArgs{
SELECT %s
FROM widgets
WHERE id = (@id)
`, mediaType)
args := pgx.NamedArgs{
"id": widgetID, "id": widgetID,
} }
rows, err := repoMedia.db.Query(ctx, sql.GetMediaUrl(mediaType), args)
var widgets []*model.Widget
rows, err := repoMedia.db.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error("repoMedia.db.Query: " + err.Error())
return "", err return "", err
} }
var widgets []*model.Widget
err = pgxscan.ScanAll(&widgets, rows) err = pgxscan.ScanAll(&widgets, rows)
if err != nil { if err != nil {
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error()) slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error())
@ -155,15 +129,7 @@ func (repoMedia *RepoMedia) GetMediaUrl(
} }
widget := widgets[0] widget := widgets[0]
var mediaUrl model.MediaUrl mediaUrl := widget.GetMediaUrl(mediaType)
if mediaType == "background_url" {
mediaUrl = widget.BackgroundUrl
} else if mediaType == "image_url" {
mediaUrl = widget.ImageUrl
} else if mediaType == "audio_url" {
mediaUrl = widget.AudioUrl
}
return mediaUrl, nil return mediaUrl, nil
} }

View File

@ -3,22 +3,20 @@ package widget
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/sql"
"errors" "errors"
"github.com/georgysavva/scany/v2/pgxscan" "github.com/georgysavva/scany/v2/pgxscan"
"github.com/jackc/pgx/v5"
"log/slog" "log/slog"
"strconv"
"strings"
) )
func New( func New(db model.Db) *RepoWidget {
db model.Db, return &RepoWidget{
) *RepoWidget { db: db,
return &RepoWidget{db} }
} }
type RepoWidget struct { type RepoWidget struct {
model.Db db model.Db
} }
func (widgetRepo *RepoWidget) CreateWidget( func (widgetRepo *RepoWidget) CreateWidget(
@ -26,19 +24,13 @@ func (widgetRepo *RepoWidget) CreateWidget(
streamerID model.StreamerID, streamerID model.StreamerID,
templateID model.TemplateID, templateID model.TemplateID,
) (model.WidgetID, error) { ) (model.WidgetID, error) {
query := ` args := model.QueryArgs{
INSERT INTO widgets (streamer_id, template_id)
VALUES (@streamer_id, @template_id);
`
args := pgx.NamedArgs{
"streamer_id": streamerID, "streamer_id": streamerID,
"template_id": templateID, "template_id": templateID,
} }
_, err := widgetRepo.db.Query(ctx, sql.CreateWidgetQuery, args)
_, err := widgetRepo.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.Query: " + err.Error()) slog.Error("widgetRepo.db.Query: " + err.Error())
return 0, err return 0, err
} }
@ -50,21 +42,16 @@ func (widgetRepo *RepoWidget) GetWidget(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, widgetID model.WidgetID,
) (*model.Widget, error) { ) (*model.Widget, error) {
query := ` args := model.QueryArgs{
SELECT * FROM widgets
WHERE id = (@id);
`
args := pgx.NamedArgs{
"id": widgetID, "id": widgetID,
} }
rows, err := widgetRepo.db.Query(ctx, sql.GetWidgetQuery, args)
var widgets []*model.Widget
rows, err := widgetRepo.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.Query: " + err.Error()) slog.Error("widgetRepo.db.Query: " + err.Error())
return nil, err return nil, err
} }
var widgets []*model.Widget
err = pgxscan.ScanAll(&widgets, rows) err = pgxscan.ScanAll(&widgets, rows)
if err != nil { if err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
@ -77,20 +64,7 @@ func (widgetRepo *RepoWidget) GetWidget(
} }
widget := widgets[0] widget := widgets[0]
widget.NormalizeUrl()
selfDomain := "http://localhost:8002/api/widget/media"
strWidgetID := strconv.Itoa(int(widgetID))
if !strings.Contains(string(widget.ImageUrl), "http") && widget.ImageUrl != "" {
widget.ImageUrl = model.MediaUrl(selfDomain + "/image/get/" + strWidgetID)
}
if !strings.Contains(string(widget.BackgroundUrl), "http") && widget.BackgroundUrl != "" {
widget.BackgroundUrl = model.MediaUrl(selfDomain + "/background/get/" + strWidgetID)
}
if !strings.Contains(string(widget.AudioUrl), "http") && widget.AudioUrl != "" {
widget.AudioUrl = model.MediaUrl(selfDomain + "/audio/get/" + strWidgetID)
}
return widget, nil return widget, nil
} }
@ -102,25 +76,18 @@ func (widgetRepo *RepoWidget) DeleteWidget(
panic("implement me") panic("implement me")
} }
func (widgetRepo *RepoWidget) UpdateWidgetDuration( func (widgetRepo *RepoWidget) UpdateDuration(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, widgetID model.WidgetID,
duration model.Duration, duration model.Duration,
) error { ) error {
query := ` args := model.QueryArgs{
UPDATE widgets
SET duration = (@duration)
WHERE id = (@id)
`
args := pgx.NamedArgs{
"id": widgetID, "id": widgetID,
"duration": duration, "duration": duration,
} }
_, err := widgetRepo.db.Query(ctx, sql.UpdateDurationQuery, args)
_, err := widgetRepo.Query(ctx, query, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.Query: " + err.Error()) slog.Error("widgetRepo.db.Query: " + err.Error())
return err return err
} }

View File

@ -3,7 +3,6 @@ package donat
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
mediaRepo "donat-widget/internal/repository/widget/donat"
"log/slog" "log/slog"
) )
@ -12,10 +11,10 @@ type ServiceDonat struct {
} }
func New( func New(
db model.Db, donatRepo model.DonatRepo,
) *ServiceDonat { ) *ServiceDonat {
return &ServiceDonat{ return &ServiceDonat{
donatRepo: mediaRepo.New(db), donatRepo: donatRepo,
} }
} }

View File

@ -3,21 +3,17 @@ package media
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
mediaRepo "donat-widget/internal/repository/widget/media"
"log/slog" "log/slog"
) )
type ServiceMedia struct { func New(mediaRepo model.MediaRepo) *ServiceMedia {
mediaRepo model.MediaRepo return &ServiceMedia{
mediaRepo: mediaRepo,
}
} }
func New( type ServiceMedia struct {
db model.Db, mediaRepo model.MediaRepo
storage model.Storage,
) *ServiceMedia {
return &ServiceMedia{
mediaRepo: mediaRepo.New(db, storage),
}
} }
func (mediaService *ServiceMedia) SetMediaFile( func (mediaService *ServiceMedia) SetMediaFile(

View File

@ -3,23 +3,24 @@ package widget
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
widgetRepo "donat-widget/internal/repository/widget"
donatRepo "donat-widget/internal/repository/widget/donat"
"log/slog" "log/slog"
) )
func New(
widgetRepo model.WidgetRepo,
donatRepo model.DonatRepo,
) *ServiceWidget {
return &ServiceWidget{
widgetRepo: widgetRepo,
donatRepo: donatRepo,
}
}
type ServiceWidget struct { type ServiceWidget struct {
widgetRepo model.WidgetRepo widgetRepo model.WidgetRepo
donatRepo model.DonatRepo donatRepo model.DonatRepo
} }
func New(db model.Db) *ServiceWidget {
return &ServiceWidget{
widgetRepo: widgetRepo.New(db),
donatRepo: donatRepo.New(db),
}
}
func (widgetService *ServiceWidget) CreateWidget( func (widgetService *ServiceWidget) CreateWidget(
ctx context.Context, ctx context.Context,
streamerID model.StreamerID, streamerID model.StreamerID,
@ -45,6 +46,20 @@ func (widgetService *ServiceWidget) DeleteWidget(
return nil return nil
} }
func (widgetService *ServiceWidget) UpdateDuration(
ctx context.Context,
widgetID model.WidgetID,
duration model.Duration,
) error {
err := widgetService.widgetRepo.UpdateDuration(ctx, widgetID, duration)
if err != nil {
slog.Error("widgetService.widgetRepo.UpdateDuration: " + err.Error())
return err
}
return nil
}
func (widgetService *ServiceWidget) GetWidgetHTML( func (widgetService *ServiceWidget) GetWidgetHTML(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, widgetID model.WidgetID,
@ -57,14 +72,10 @@ func (widgetService *ServiceWidget) GetWidgetHTML(
return widgetHTML, err return widgetHTML, err
} }
backgroundUrl := widget.BackgroundUrl if widget.TemplateID == 1 {
templateID := widget.TemplateID
if templateID == 1 {
widgetHTML = model.GetTemplate1( widgetHTML = model.GetTemplate1(
widgetID, widgetID,
backgroundUrl, widget.BackgroundUrl,
) )
} }
return widgetHTML, nil return widgetHTML, nil
@ -102,21 +113,3 @@ func (widgetService *ServiceWidget) GetWidgetInfo(
return &donatAndWidget, nil return &donatAndWidget, nil
} }
func (widgetService *ServiceWidget) UpdateWidgetDuration(
ctx context.Context,
widgetID model.WidgetID,
duration model.Duration,
) error {
err := widgetService.widgetRepo.UpdateWidgetDuration(
ctx,
widgetID,
duration,
)
if err != nil {
slog.Error("widgetService.widgetRepo.UpdateWidgetDuration: " + err.Error())
return err
}
return nil
}