create directory from path for rclone to reduce db calls

This commit is contained in:
divyam234 2023-08-21 03:11:33 +05:30
parent 3710002aa4
commit 0b97ce03ed
8 changed files with 100 additions and 28 deletions

View 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;

View file

@ -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) {

View file

@ -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)

View file

@ -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"})

View file

@ -72,3 +72,7 @@ type FileOperation struct {
Files []string `json:"files"`
Destination string `json:"destination,omitempty"`
}
type MkDir struct {
Path string `json:"path"`
}

View file

@ -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
}

View file

@ -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

View file

@ -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 {