Channel API done without verification

This commit is contained in:
JustSong 2023-04-22 22:02:59 +08:00
parent af96007025
commit 6164829239
5 changed files with 115 additions and 124 deletions

View File

@ -83,3 +83,15 @@ const (
UserStatusEnabled = 1 // don't use 0, 0 is the default value!
UserStatusDisabled = 2 // also don't use 0
)
const (
ChannelStatusUnknown = 0
ChannelStatusEnabled = 1 // don't use 0, 0 is the default value!
ChannelStatusDisabled = 2 // also don't use 0
)
const (
ChannelTypeUnknown = 0
ChannelTypeOpenAI = 1
ChannelTypeAPI2D = 2
)

View File

@ -1,15 +1,11 @@
package controller
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"one-api/common"
"one-api/model"
"path/filepath"
"strconv"
"strings"
"time"
)
func GetAllChannels(c *gin.Context) {
@ -17,7 +13,7 @@ func GetAllChannels(c *gin.Context) {
if p < 0 {
p = 0
}
files, err := model.GetAllChannels(p*common.ItemsPerPage, common.ItemsPerPage)
channels, err := model.GetAllChannels(p*common.ItemsPerPage, common.ItemsPerPage)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
@ -28,14 +24,14 @@ func GetAllChannels(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
"data": files,
"data": channels,
})
return
}
func SearchChannels(c *gin.Context) {
keyword := c.Query("keyword")
files, err := model.SearchChannels(keyword)
channels, err := model.SearchChannels(keyword)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
@ -46,13 +42,13 @@ func SearchChannels(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
"data": files,
"data": channels,
})
return
}
func UploadFile(c *gin.Context) {
form, err := c.MultipartForm()
func GetChannel(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
@ -60,43 +56,39 @@ func UploadFile(c *gin.Context) {
})
return
}
uploadPath := common.UploadPath
description := c.PostForm("description")
if description == "" {
description = "无描述信息"
channel, err := model.GetChannelById(id)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
uploader := c.GetString("username")
if uploader == "" {
uploader = "访客用户"
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
"data": channel,
})
return
}
func AddChannel(c *gin.Context) {
channel := model.Channel{}
err := c.ShouldBindJSON(&channel)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
uploaderId := c.GetInt("id")
currentTime := time.Now().Format("2006-01-02 15:04:05")
files := form.File["file"]
for _, file := range files {
filename := filepath.Base(file.Filename)
ext := filepath.Ext(filename)
link := common.GetUUID() + ext
savePath := filepath.Join(uploadPath, link) // both parts are checked, so this path should be safe to use
if err := c.SaveUploadedFile(file, savePath); err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
// save to database
fileObj := &model.Channel{
Description: description,
Uploader: uploader,
UploadTime: currentTime,
UploaderId: uploaderId,
Link: link,
Filename: filename,
}
err = fileObj.Insert()
if err != nil {
_ = fmt.Errorf(err.Error())
}
err = channel.Insert()
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
@ -105,56 +97,45 @@ func UploadFile(c *gin.Context) {
return
}
func DeleteFile(c *gin.Context) {
fileIdStr := c.Param("id")
fileId, err := strconv.Atoi(fileIdStr)
if err != nil || fileId == 0 {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": "无效的参数",
})
return
}
fileObj := &model.Channel{
Id: fileId,
}
model.DB.Where("id = ?", fileId).First(&fileObj)
if fileObj.Link == "" {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "文件不存在!",
})
return
}
err = fileObj.Delete()
func DeleteChannel(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
channel := model.Channel{Id: id}
err := channel.Delete()
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": true,
"success": false,
"message": err.Error(),
})
return
} else {
message := "文件删除成功"
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": message,
})
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
})
return
}
func DownloadFile(c *gin.Context) {
path := c.Param("file")
fullPath := filepath.Join(common.UploadPath, path)
if !strings.HasPrefix(fullPath, common.UploadPath) {
// We may being attacked!
c.Status(403)
func UpdateChannel(c *gin.Context) {
channel := model.Channel{}
err := c.ShouldBindJSON(&channel)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
c.File(fullPath)
// Update download counter
go func() {
model.UpdateDownloadCounter(path)
}()
err = channel.Update()
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
})
return
}

View File

@ -2,50 +2,49 @@ package model
import (
_ "gorm.io/driver/sqlite"
"gorm.io/gorm"
"one-api/common"
"os"
"path"
)
type Channel struct {
Id int `json:"id"`
Filename string `json:"filename" gorm:"index"`
Description string `json:"description"`
Uploader string `json:"uploader" gorm:"index"`
UploaderId int `json:"uploader_id" gorm:"index"`
Link string `json:"link" gorm:"unique;index"`
UploadTime string `json:"upload_time"`
DownloadCounter int `json:"download_counter"`
Id int `json:"id"`
Type int `json:"type" gorm:"default:0"`
Key string `json:"key"`
Status int `json:"status" gorm:"default:1"`
}
func GetAllChannels(startIdx int, num int) ([]*Channel, error) {
var files []*Channel
var channels []*Channel
var err error
err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&files).Error
return files, err
err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&channels).Error
return channels, err
}
func SearchChannels(keyword string) (files []*Channel, err error) {
err = DB.Select([]string{"id", "filename", "description", "uploader", "uploader_id", "link", "upload_time", "download_counter"}).Where(
"filename LIKE ? or uploader LIKE ? or uploader_id = ?", keyword+"%", keyword+"%", keyword).Find(&files).Error
return files, err
func SearchChannels(keyword string) (channels []*Channel, err error) {
err = DB.Select([]string{"id", "key"}, keyword, keyword).Find(&channels).Error
return channels, err
}
func (file *Channel) Insert() error {
func GetChannelById(id int) (*Channel, error) {
channel := Channel{Id: id}
var err error = nil
err = DB.Select([]string{"id", "type"}).First(&channel, "id = ?", id).Error
return &channel, err
}
func (channel *Channel) Insert() error {
var err error
err = DB.Create(file).Error
err = DB.Create(channel).Error
return err
}
func (channel *Channel) Update() error {
var err error
err = DB.Model(channel).Updates(channel).Error
return err
}
// Delete Make sure link is valid! Because we will use os.Remove to delete it!
func (file *Channel) Delete() error {
func (channel *Channel) Delete() error {
var err error
err = DB.Delete(file).Error
err = os.Remove(path.Join(common.UploadPath, file.Link))
err = DB.Delete(channel).Error
return err
}
func UpdateDownloadCounter(link string) {
DB.Model(&Channel{}).Where("link = ?", link).UpdateColumn("download_counter", gorm.Expr("download_counter + 1"))
}

View File

@ -54,13 +54,15 @@ func SetApiRouter(router *gin.Engine) {
optionRoute.GET("/", controller.GetOptions)
optionRoute.PUT("/", controller.UpdateOption)
}
fileRoute := apiRouter.Group("/file")
fileRoute.Use(middleware.AdminAuth())
channelRoute := apiRouter.Group("/channel")
channelRoute.Use(middleware.AdminAuth())
{
fileRoute.GET("/", controller.GetAllChannels)
fileRoute.GET("/search", controller.SearchChannels)
fileRoute.POST("/", middleware.UploadRateLimit(), controller.UploadFile)
fileRoute.DELETE("/:id", controller.DeleteFile)
channelRoute.GET("/", controller.GetAllChannels)
channelRoute.GET("/search", controller.SearchChannels)
channelRoute.GET("/:id", controller.GetChannel)
channelRoute.POST("/", controller.AddChannel)
channelRoute.PUT("/", controller.UpdateChannel)
channelRoute.DELETE("/:id", controller.DeleteChannel)
}
}
}

View File

@ -6,14 +6,11 @@ import (
"github.com/gin-gonic/gin"
"net/http"
"one-api/common"
"one-api/controller"
"one-api/middleware"
)
func setWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
router.Use(middleware.GlobalWebRateLimit())
fileDownloadRoute := router.Group("/")
fileDownloadRoute.GET("/upload/:file", middleware.DownloadRateLimit(), controller.DownloadFile)
router.Use(middleware.Cache())
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
router.NoRoute(func(c *gin.Context) {