Channel API done without verification
This commit is contained in:
parent
af96007025
commit
6164829239
@ -83,3 +83,15 @@ const (
|
|||||||
UserStatusEnabled = 1 // don't use 0, 0 is the default value!
|
UserStatusEnabled = 1 // don't use 0, 0 is the default value!
|
||||||
UserStatusDisabled = 2 // also don't use 0
|
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
|
||||||
|
)
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"one-api/common"
|
"one-api/common"
|
||||||
"one-api/model"
|
"one-api/model"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetAllChannels(c *gin.Context) {
|
func GetAllChannels(c *gin.Context) {
|
||||||
@ -17,7 +13,7 @@ func GetAllChannels(c *gin.Context) {
|
|||||||
if p < 0 {
|
if p < 0 {
|
||||||
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 {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@ -28,14 +24,14 @@ func GetAllChannels(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": files,
|
"data": channels,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchChannels(c *gin.Context) {
|
func SearchChannels(c *gin.Context) {
|
||||||
keyword := c.Query("keyword")
|
keyword := c.Query("keyword")
|
||||||
files, err := model.SearchChannels(keyword)
|
channels, err := model.SearchChannels(keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@ -46,13 +42,13 @@ func SearchChannels(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": files,
|
"data": channels,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func UploadFile(c *gin.Context) {
|
func GetChannel(c *gin.Context) {
|
||||||
form, err := c.MultipartForm()
|
id, err := strconv.Atoi(c.Param("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@ -60,43 +56,39 @@ func UploadFile(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uploadPath := common.UploadPath
|
channel, err := model.GetChannelById(id)
|
||||||
description := c.PostForm("description")
|
if err != nil {
|
||||||
if description == "" {
|
c.JSON(http.StatusOK, gin.H{
|
||||||
description = "无描述信息"
|
"success": false,
|
||||||
|
"message": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
uploader := c.GetString("username")
|
c.JSON(http.StatusOK, gin.H{
|
||||||
if uploader == "" {
|
"success": true,
|
||||||
uploader = "访客用户"
|
"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")
|
err = channel.Insert()
|
||||||
currentTime := time.Now().Format("2006-01-02 15:04:05")
|
if err != nil {
|
||||||
files := form.File["file"]
|
c.JSON(http.StatusOK, gin.H{
|
||||||
for _, file := range files {
|
"success": false,
|
||||||
filename := filepath.Base(file.Filename)
|
"message": err.Error(),
|
||||||
ext := filepath.Ext(filename)
|
})
|
||||||
link := common.GetUUID() + ext
|
return
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
@ -105,56 +97,45 @@ func UploadFile(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteFile(c *gin.Context) {
|
func DeleteChannel(c *gin.Context) {
|
||||||
fileIdStr := c.Param("id")
|
id, _ := strconv.Atoi(c.Param("id"))
|
||||||
fileId, err := strconv.Atoi(fileIdStr)
|
channel := model.Channel{Id: id}
|
||||||
if err != nil || fileId == 0 {
|
err := channel.Delete()
|
||||||
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()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": false,
|
||||||
"message": err.Error(),
|
"message": err.Error(),
|
||||||
})
|
})
|
||||||
return
|
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) {
|
func UpdateChannel(c *gin.Context) {
|
||||||
path := c.Param("file")
|
channel := model.Channel{}
|
||||||
fullPath := filepath.Join(common.UploadPath, path)
|
err := c.ShouldBindJSON(&channel)
|
||||||
if !strings.HasPrefix(fullPath, common.UploadPath) {
|
if err != nil {
|
||||||
// We may being attacked!
|
c.JSON(http.StatusOK, gin.H{
|
||||||
c.Status(403)
|
"success": false,
|
||||||
|
"message": err.Error(),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.File(fullPath)
|
err = channel.Update()
|
||||||
// Update download counter
|
if err != nil {
|
||||||
go func() {
|
c.JSON(http.StatusOK, gin.H{
|
||||||
model.UpdateDownloadCounter(path)
|
"success": false,
|
||||||
}()
|
"message": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"success": true,
|
||||||
|
"message": "",
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,50 +2,49 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
_ "gorm.io/driver/sqlite"
|
_ "gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
|
||||||
"one-api/common"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
Filename string `json:"filename" gorm:"index"`
|
Type int `json:"type" gorm:"default:0"`
|
||||||
Description string `json:"description"`
|
Key string `json:"key"`
|
||||||
Uploader string `json:"uploader" gorm:"index"`
|
Status int `json:"status" gorm:"default:1"`
|
||||||
UploaderId int `json:"uploader_id" gorm:"index"`
|
|
||||||
Link string `json:"link" gorm:"unique;index"`
|
|
||||||
UploadTime string `json:"upload_time"`
|
|
||||||
DownloadCounter int `json:"download_counter"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllChannels(startIdx int, num int) ([]*Channel, error) {
|
func GetAllChannels(startIdx int, num int) ([]*Channel, error) {
|
||||||
var files []*Channel
|
var channels []*Channel
|
||||||
var err error
|
var err error
|
||||||
err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&files).Error
|
err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&channels).Error
|
||||||
return files, err
|
return channels, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchChannels(keyword string) (files []*Channel, err error) {
|
func SearchChannels(keyword string) (channels []*Channel, err error) {
|
||||||
err = DB.Select([]string{"id", "filename", "description", "uploader", "uploader_id", "link", "upload_time", "download_counter"}).Where(
|
err = DB.Select([]string{"id", "key"}, keyword, keyword).Find(&channels).Error
|
||||||
"filename LIKE ? or uploader LIKE ? or uploader_id = ?", keyword+"%", keyword+"%", keyword).Find(&files).Error
|
return channels, err
|
||||||
return files, 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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Make sure link is valid! Because we will use os.Remove to delete it!
|
// 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
|
var err error
|
||||||
err = DB.Delete(file).Error
|
err = DB.Delete(channel).Error
|
||||||
err = os.Remove(path.Join(common.UploadPath, file.Link))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateDownloadCounter(link string) {
|
|
||||||
DB.Model(&Channel{}).Where("link = ?", link).UpdateColumn("download_counter", gorm.Expr("download_counter + 1"))
|
|
||||||
}
|
|
||||||
|
@ -54,13 +54,15 @@ func SetApiRouter(router *gin.Engine) {
|
|||||||
optionRoute.GET("/", controller.GetOptions)
|
optionRoute.GET("/", controller.GetOptions)
|
||||||
optionRoute.PUT("/", controller.UpdateOption)
|
optionRoute.PUT("/", controller.UpdateOption)
|
||||||
}
|
}
|
||||||
fileRoute := apiRouter.Group("/file")
|
channelRoute := apiRouter.Group("/channel")
|
||||||
fileRoute.Use(middleware.AdminAuth())
|
channelRoute.Use(middleware.AdminAuth())
|
||||||
{
|
{
|
||||||
fileRoute.GET("/", controller.GetAllChannels)
|
channelRoute.GET("/", controller.GetAllChannels)
|
||||||
fileRoute.GET("/search", controller.SearchChannels)
|
channelRoute.GET("/search", controller.SearchChannels)
|
||||||
fileRoute.POST("/", middleware.UploadRateLimit(), controller.UploadFile)
|
channelRoute.GET("/:id", controller.GetChannel)
|
||||||
fileRoute.DELETE("/:id", controller.DeleteFile)
|
channelRoute.POST("/", controller.AddChannel)
|
||||||
|
channelRoute.PUT("/", controller.UpdateChannel)
|
||||||
|
channelRoute.DELETE("/:id", controller.DeleteChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,11 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"one-api/common"
|
"one-api/common"
|
||||||
"one-api/controller"
|
|
||||||
"one-api/middleware"
|
"one-api/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
|
func setWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
|
||||||
router.Use(middleware.GlobalWebRateLimit())
|
router.Use(middleware.GlobalWebRateLimit())
|
||||||
fileDownloadRoute := router.Group("/")
|
|
||||||
fileDownloadRoute.GET("/upload/:file", middleware.DownloadRateLimit(), controller.DownloadFile)
|
|
||||||
router.Use(middleware.Cache())
|
router.Use(middleware.Cache())
|
||||||
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
|
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
|
||||||
router.NoRoute(func(c *gin.Context) {
|
router.NoRoute(func(c *gin.Context) {
|
||||||
|
Loading…
Reference in New Issue
Block a user