add router for get widget files

This commit is contained in:
harold 2025-03-06 16:05:40 +05:00
parent 131acf7182
commit 0d4a2d84d9
11 changed files with 347 additions and 1 deletions

View File

@ -81,3 +81,45 @@ func GetFile(fileService model.FileService) echo.HandlerFunc {
return request.Blob(http.StatusOK, fileType, file)
}
}
// GetWidgetFiles godoc
// @Summary Get all widget files
// @Description Retrieve all widget files, filtered by type if specified
// @Tags Files
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param type query string false "File type (audio or image)" Enums(audio, image)
// @Success 200 {array} model.DataFile "List of files"
// @Failure 400 {object} echo.HTTPError "Bad request"
// @Failure 401 {object} echo.HTTPError "Unauthorized or expired token"
// @Router /files/widgets [get]
func GetWidgetFiles(fileService model.FileService) echo.HandlerFunc {
return func(request echo.Context) error {
ctx := context.Background()
fileType := request.QueryParam("type")
if fileType != "" && fileType != "audio" && fileType != "image" {
return echo.NewHTTPError(http.StatusUnprocessableEntity, "Invalid file type")
}
authData, err := fileService.CheckToken(request)
if err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
widgetFiles, err := fileService.WidgetsFiles(
ctx,
fileType,
authData.AccountID,
)
if err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to retrieve files")
}
return request.JSON(http.StatusOK, widgetFiles)
}
}

View File

@ -103,4 +103,5 @@ func IncludeFileHandlers(
) {
server.POST(PREFIX+"/files", files.AddNewFile(fileService))
server.GET(PREFIX+"/files/:file_id", files.GetFile(fileService))
server.GET(PREFIX+"/files/widgets", files.GetWidgetFiles(fileService))
}

View File

@ -138,6 +138,61 @@ const docTemplate = `{
}
}
},
"/files/widgets": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all widget files, filtered by type if specified",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Files"
],
"summary": "Get all widget files",
"parameters": [
{
"enum": [
"audio",
"image"
],
"type": "string",
"description": "File type (audio or image)",
"name": "type",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of files",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.DataFile"
}
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/files/{file_id}": {
"get": {
"description": "Retrieve a file by its ID",
@ -708,6 +763,32 @@ const docTemplate = `{
}
}
},
"donat-widget_internal_model.DataFile": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"extension": {
"type": "string"
},
"file_link": {
"type": "string"
},
"file_name": {
"type": "string"
},
"file_type": {
"type": "string"
},
"id": {
"type": "string"
},
"streamer_id": {
"type": "integer"
}
}
},
"donat-widget_internal_model.FilterSettingResponse": {
"type": "object",
"properties": {

View File

@ -131,6 +131,61 @@
}
}
},
"/files/widgets": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all widget files, filtered by type if specified",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Files"
],
"summary": "Get all widget files",
"parameters": [
{
"enum": [
"audio",
"image"
],
"type": "string",
"description": "File type (audio or image)",
"name": "type",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of files",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.DataFile"
}
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/files/{file_id}": {
"get": {
"description": "Retrieve a file by its ID",
@ -701,6 +756,32 @@
}
}
},
"donat-widget_internal_model.DataFile": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"extension": {
"type": "string"
},
"file_link": {
"type": "string"
},
"file_name": {
"type": "string"
},
"file_type": {
"type": "string"
},
"id": {
"type": "string"
},
"streamer_id": {
"type": "integer"
}
}
},
"donat-widget_internal_model.FilterSettingResponse": {
"type": "object",
"properties": {

View File

@ -34,6 +34,23 @@ definitions:
- name
- template_id
type: object
donat-widget_internal_model.DataFile:
properties:
created_at:
type: string
extension:
type: string
file_link:
type: string
file_name:
type: string
file_type:
type: string
id:
type: string
streamer_id:
type: integer
type: object
donat-widget_internal_model.FilterSettingResponse:
properties:
enable_links:
@ -324,6 +341,41 @@ paths:
summary: Get a file
tags:
- Files
/files/widgets:
get:
consumes:
- application/json
description: Retrieve all widget files, filtered by type if specified
parameters:
- description: File type (audio or image)
enum:
- audio
- image
in: query
name: type
type: string
produces:
- application/json
responses:
"200":
description: List of files
schema:
items:
$ref: '#/definitions/donat-widget_internal_model.DataFile'
type: array
"400":
description: Bad request
schema:
$ref: '#/definitions/echo.HTTPError'
"401":
description: Unauthorized or expired token
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get all widget files
tags:
- Files
/filters-settings:
get:
consumes:

View File

@ -46,7 +46,6 @@ type WidgetRepo interface {
name string,
) (WidgetID, error)
CheckWidgetName(ctx context.Context, streamerID int, name string) (bool, error)
GetWidgetsByStreamerID(ctx context.Context, streamerID int) ([]*GetWidgetDb, error)
//GetWidgetByID(ctx context.Context, widgetID WidgetID) ([]*GetWidgetDb, error)
@ -152,6 +151,7 @@ type FileRepo interface {
extension, fileType string,
) (string, error)
GetByID(ctx context.Context, fileID string) ([]byte, string, error)
WidgetsFiles(ctx context.Context, fileType string, streamerID int) ([]*DataFile, error)
}
type FileService interface {
@ -163,4 +163,5 @@ type FileService interface {
streamerID int,
) (string, error)
GetByID(ctx context.Context, fileID string) ([]byte, string, error)
WidgetsFiles(ctx context.Context, fileType string, streamerID int) ([]*DataFile, error)
}

View File

@ -5,6 +5,17 @@ import (
"time"
)
type DataFile struct {
ID uuid.UUID `db:"id" json:"id"`
FileType string `db:"file_type" json:"file_type"`
FileName string `db:"file_name" json:"file_name"`
Extension string `db:"extension" json:"extension"`
StreamerID int `db:"streamer_id" json:"streamer_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
Size float32 `db:"size" json:"size"`
FileLink string `json:"file_link"`
}
type GetWidgetDb struct {
ID int `db:"id" json:"id" example:"1" format:"int64" description:"Unique identifier of the widget"`
StreamerID int `db:"streamer_id" json:"streamer_id" example:"1001" format:"int64" description:"ID of the streamer"`

View File

@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS donats (
widget_id INTEGER NOT NULL,
order_id TEXT NOT NULL,
target_id INTEGER NOT NULL,
size FLOAT NOT NULL,
text TEXT NOT NULL,
amount INTEGER NOT NULL,

View File

@ -125,3 +125,17 @@ var GetWidgetByName = `SELECT id FROM widgets WHERE (
`
var FileById = `SELECT file_name, streamer_id, file_type FROM files WHERE id = (@id);`
var AudioFilesWidgets = `
SELECT f.*
FROM files AS f
JOIN widgets AS w ON w.audio = f.id
WHERE f.streamer_id = (@streamer_id);
`
var ImageFilesWidgets = `
SELECT f.*
FROM files AS f
JOIN widgets AS w ON w.image = f.id
WHERE f.streamer_id = (@streamer_id);
`

View File

@ -5,6 +5,7 @@ import (
"donat-widget/internal/model"
"donat-widget/internal/model/sql"
"fmt"
"github.com/georgysavva/scany/v2/pgxscan"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"mime/multipart"
@ -37,11 +38,13 @@ func (fileRepo *RepoFile) AddNew(
return "", err
}
sizeInKB := float64(file.Size) / 1024
args := pgx.NamedArgs{
"streamer_id": streamerID,
"file_name": fileName,
"file_type": fileType,
"extension": extension,
"size": sizeInKB,
}
fileIDRaw, err := fileRepo.db.Insert(ctx, sql.AddNewFile, args)
@ -87,3 +90,36 @@ func (fileRepo *RepoFile) GetByID(
return fileContent, fileType, nil
}
func (fileRepo *RepoFile) WidgetsFiles(
ctx context.Context,
fileType string,
streamerID int,
) ([]*model.DataFile, error) {
args := pgx.NamedArgs{
"streamer_id": streamerID,
}
var stmt string
if fileType == "audio" {
stmt = sql.AudioFilesWidgets
} else {
stmt = sql.ImageFilesWidgets
}
rows, err := fileRepo.db.Select(ctx, stmt, args)
if err != nil {
return nil, fmt.Errorf("error retrieving file info: %v", err)
}
defer rows.Close()
var files []*model.DataFile
err = pgxscan.ScanAll(&files, rows)
if len(files) == 0 {
return nil, nil
}
return files, nil
}

View File

@ -70,6 +70,32 @@ func (fileService *ServiceFile) GetByID(
return fileBytes, fileType, nil
}
func (fileService *ServiceFile) WidgetsFiles(
ctx context.Context,
fileType string,
streamerID int,
) ([]*model.DataFile, error) {
files, err := fileService.fileRepo.WidgetsFiles(
ctx,
fileType,
streamerID,
)
if err != nil {
return nil, err
}
if files == nil {
return []*model.DataFile{}, nil
}
for _, file := range files {
file.FileLink = "http://localhost/file/" + file.ID.String()
}
return files, nil
}
func (fileService *ServiceFile) CheckToken(
request echo.Context,
) (api.CheckTokenResponse, error) {