mirror of
https://github.com/tgdrive/teldrive.git
synced 2025-09-05 05:54:55 +08:00
create directory from path for rclone to reduce db calls
This commit is contained in:
parent
3710002aa4
commit
0b97ce03ed
8 changed files with 100 additions and 28 deletions
48
database/migrations/20230820014560_create_dirs_from_path.sql
Normal file
48
database/migrations/20230820014560_create_dirs_from_path.sql
Normal file
|
@ -0,0 +1,48 @@
|
|||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
CREATE OR REPLACE FUNCTION teldrive.create_directories(
|
||||
IN tg_id BIGINT,
|
||||
IN long_path TEXT
|
||||
) RETURNS SETOF teldrive.files AS $$
|
||||
DECLARE
|
||||
path_parts TEXT[];
|
||||
current_directory_id TEXT;
|
||||
new_directory_id TEXT;
|
||||
directory_name TEXT;
|
||||
path_so_far TEXT;
|
||||
depth_dir integer;
|
||||
begin
|
||||
|
||||
path_parts := string_to_array(regexp_replace(long_path, '^/+', ''), '/');
|
||||
|
||||
path_so_far := '';
|
||||
depth_dir := 0;
|
||||
|
||||
SELECT id into current_directory_id FROM teldrive.files WHERE parent_id='root';
|
||||
|
||||
|
||||
FOR directory_name IN SELECT unnest(path_parts) LOOP
|
||||
path_so_far := CONCAT(path_so_far,'/', directory_name);
|
||||
depth_dir := depth_dir +1;
|
||||
SELECT id INTO new_directory_id
|
||||
FROM teldrive.files
|
||||
WHERE parent_id = current_directory_id
|
||||
AND "name" = directory_name AND "user_id"=tg_id;
|
||||
|
||||
IF new_directory_id IS NULL THEN
|
||||
INSERT INTO teldrive.files ("name", "type", mime_type, parent_id, "user_id",starred,"depth","path")
|
||||
VALUES (directory_name, 'folder', 'drive/folder', current_directory_id, tg_id,false,depth_dir,path_so_far)
|
||||
RETURNING id INTO new_directory_id;
|
||||
END IF;
|
||||
|
||||
current_directory_id := new_directory_id;
|
||||
END LOOP;
|
||||
|
||||
RETURN QUERY SELECT * FROM teldrive.files WHERE id = current_directory_id;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
DROP FUNCTION IF EXISTS teldrive.create_directories;
|
|
@ -13,7 +13,7 @@ func addAuthRoutes(rg *gin.RouterGroup) {
|
|||
|
||||
r := rg.Group("/auth")
|
||||
|
||||
authService := services.AuthService{Db: database.DB, SessionMaxAge: 30 * 24 * 60 * 60}
|
||||
authService := services.AuthService{Db: database.DB, SessionMaxAge: 30 * 24 * 60 * 60, SessionCookieName: "user-session"}
|
||||
|
||||
r.POST("/login", func(c *gin.Context) {
|
||||
|
||||
|
|
|
@ -80,6 +80,18 @@ func addFileRoutes(rg *gin.RouterGroup) {
|
|||
c.JSON(http.StatusOK, res)
|
||||
})
|
||||
|
||||
r.POST("/makekdir", func(c *gin.Context) {
|
||||
|
||||
res, err := fileService.MakeDirectory(c)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithError(err.Code, err.Error)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
})
|
||||
|
||||
r.POST("/deletefiles", func(c *gin.Context) {
|
||||
|
||||
res, err := fileService.DeleteFiles(c)
|
||||
|
|
|
@ -4,14 +4,13 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/divyam234/teldrive/services"
|
||||
"github.com/divyam234/teldrive/utils/auth"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-jose/go-jose/v3/jwt"
|
||||
)
|
||||
|
||||
func Authmiddleware(c *gin.Context) {
|
||||
cookie, err := c.Request.Cookie(services.GetUserSessionCookieName(c))
|
||||
cookie, err := c.Request.Cookie("user-session")
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "missing session cookie"})
|
||||
|
|
|
@ -72,3 +72,7 @@ type FileOperation struct {
|
|||
Files []string `json:"files"`
|
||||
Destination string `json:"destination,omitempty"`
|
||||
}
|
||||
|
||||
type MkDir struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
|
|
@ -31,8 +31,9 @@ import (
|
|||
)
|
||||
|
||||
type AuthService struct {
|
||||
Db *gorm.DB
|
||||
SessionMaxAge int
|
||||
Db *gorm.DB
|
||||
SessionMaxAge int
|
||||
SessionCookieName string
|
||||
}
|
||||
|
||||
type SessionData struct {
|
||||
|
@ -86,18 +87,6 @@ func generateTgSession(dcID int, authKey []byte, port int) string {
|
|||
return "1" + base64Encoded
|
||||
}
|
||||
|
||||
func GetUserSessionCookieName(c *gin.Context) string {
|
||||
config := utils.GetConfig()
|
||||
var cookieName string
|
||||
if config.Https {
|
||||
cookieName = "__Secure-user-session"
|
||||
} else {
|
||||
cookieName = "user-session"
|
||||
}
|
||||
|
||||
return cookieName
|
||||
}
|
||||
|
||||
func setCookie(c *gin.Context, key string, value string, age int) {
|
||||
|
||||
config := utils.GetConfig()
|
||||
|
@ -173,13 +162,13 @@ func (as *AuthService) LogIn(c *gin.Context) (*schemas.Message, *types.AppError)
|
|||
return nil, &types.AppError{Error: errors.New("failed to create or update user"), Code: http.StatusInternalServerError}
|
||||
}
|
||||
}
|
||||
setCookie(c, GetUserSessionCookieName(c), jweToken, as.SessionMaxAge)
|
||||
setCookie(c, as.SessionCookieName, jweToken, as.SessionMaxAge)
|
||||
return &schemas.Message{Status: true, Message: "login success"}, nil
|
||||
}
|
||||
|
||||
func (as *AuthService) GetSession(c *gin.Context) *types.Session {
|
||||
|
||||
cookie, err := c.Request.Cookie(GetUserSessionCookieName(c))
|
||||
cookie, err := c.Request.Cookie(as.SessionCookieName)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -206,7 +195,7 @@ func (as *AuthService) GetSession(c *gin.Context) *types.Session {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
setCookie(c, GetUserSessionCookieName(c), jweToken, as.SessionMaxAge)
|
||||
setCookie(c, as.SessionCookieName, jweToken, as.SessionMaxAge)
|
||||
return session
|
||||
}
|
||||
|
||||
|
@ -222,7 +211,7 @@ func (as *AuthService) Logout(c *gin.Context) (*schemas.Message, *types.AppError
|
|||
|
||||
tgClient.Tg.API().AuthLogOut(c)
|
||||
utils.StopClient(stop, userId)
|
||||
setCookie(c, GetUserSessionCookieName(c), "", -1)
|
||||
setCookie(c, as.SessionCookieName, "", -1)
|
||||
return &schemas.Message{Status: true, Message: "logout success"}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
@ -22,6 +21,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/gotd/td/telegram"
|
||||
"github.com/gotd/td/tg"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
range_parser "github.com/quantumsheep/range-parser"
|
||||
"gorm.io/gorm"
|
||||
|
@ -79,6 +79,10 @@ func (fs *FileService) CreateFile(c *gin.Context) (*schemas.FileOut, *types.AppE
|
|||
fileDb := mapFileInToFile(fileIn)
|
||||
|
||||
if err := fs.Db.Create(&fileDb).Error; err != nil {
|
||||
pgErr := err.(*pgconn.PgError)
|
||||
if pgErr.Code == "23505" {
|
||||
return nil, &types.AppError{Error: errors.New("file exists"), Code: http.StatusBadRequest}
|
||||
}
|
||||
return nil, &types.AppError{Error: errors.New("failed to create a file"), Code: http.StatusBadRequest}
|
||||
|
||||
}
|
||||
|
@ -163,12 +167,11 @@ func (fs *FileService) ListFiles(c *gin.Context) (*schemas.FileResponse, *types.
|
|||
|
||||
query := fs.Db.Model(&models.File{}).Limit(pagingParams.PerPage)
|
||||
|
||||
log.Println(fileQuery.Path)
|
||||
if fileQuery.Op == "list" {
|
||||
filters := []string{}
|
||||
filters = setOrderFilter(&pagingParams, &sortingParams, filters)
|
||||
|
||||
if pathExists, message := fs.CheckIfPathExists(&fileQuery.Path); pathExists == false {
|
||||
if pathExists, message := fs.CheckIfPathExists(&fileQuery.Path); !pathExists {
|
||||
return nil, &types.AppError{Error: errors.New(message), Code: http.StatusNotFound}
|
||||
}
|
||||
|
||||
|
@ -235,6 +238,27 @@ func (fs *FileService) CheckIfPathExists(path *string) (bool, string) {
|
|||
return true, ""
|
||||
}
|
||||
|
||||
func (fs *FileService) MakeDirectory(c *gin.Context) (*schemas.FileOut, *types.AppError) {
|
||||
|
||||
var payload schemas.MkDir
|
||||
|
||||
var files []models.File
|
||||
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
return nil, &types.AppError{Error: errors.New("invalid request payload"), Code: http.StatusBadRequest}
|
||||
}
|
||||
|
||||
userId := getAuthUserId(c)
|
||||
if err := fs.Db.Raw("select * from teldrive.create_directories(?, ?)", userId, payload.Path).Scan(&files).Error; err != nil {
|
||||
return nil, &types.AppError{Error: errors.New("failed to create directories"), Code: http.StatusInternalServerError}
|
||||
}
|
||||
|
||||
file := mapFileToFileOut(files[0])
|
||||
|
||||
return &file, nil
|
||||
|
||||
}
|
||||
|
||||
func (fs *FileService) MoveFiles(c *gin.Context) (*schemas.Message, *types.AppError) {
|
||||
|
||||
var payload schemas.FileOperation
|
||||
|
|
|
@ -100,10 +100,6 @@ func (us *UploadService) UploadFile(c *gin.Context) (*schemas.UploadPartOut, *ty
|
|||
|
||||
fileName := uploadQuery.Filename
|
||||
|
||||
if uploadQuery.TotalParts > 1 {
|
||||
fileName = fmt.Sprintf("%s.part.%03d", fileName, uploadQuery.PartNo)
|
||||
}
|
||||
|
||||
upload, err := u.Upload(c, uploader.NewUpload(fileName, file, fileSize))
|
||||
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Reference in a new issue