idle
This commit is contained in:
BIN
go_cloud/api
BIN
go_cloud/api
Binary file not shown.
@@ -8,6 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -524,7 +525,7 @@ func wopiPutFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read file content from request body
|
// Read file content from request body first
|
||||||
content, err := io.ReadAll(r.Body)
|
content, err := io.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[WOPI-STORAGE] Failed to read request body: %v\n", err)
|
fmt.Printf("[WOPI-STORAGE] Failed to read request body: %v\n", err)
|
||||||
@@ -533,28 +534,84 @@ func wopiPutFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB,
|
|||||||
}
|
}
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
// Upload to storage
|
// Check for suggested target (used for export operations like Save as PDF)
|
||||||
fmt.Printf("[WOPI-STORAGE] PutFile uploading: file=%s remotePath=%s\n", fileID, remotePath)
|
suggestedTarget := r.Header.Get("X-WOPI-SuggestedTarget")
|
||||||
err = webDAVClient.Upload(r.Context(), remotePath, strings.NewReader(string(content)), int64(len(content)))
|
isExport := suggestedTarget != ""
|
||||||
|
|
||||||
|
var targetFile *database.File
|
||||||
|
var targetRemotePath string
|
||||||
|
|
||||||
|
if isExport {
|
||||||
|
// Parse suggested target
|
||||||
|
var newName string
|
||||||
|
if strings.HasPrefix(suggestedTarget, ".") {
|
||||||
|
// Extension only, e.g., ".pdf"
|
||||||
|
baseName := strings.TrimSuffix(file.Name, filepath.Ext(file.Name))
|
||||||
|
newName = baseName + suggestedTarget
|
||||||
|
} else {
|
||||||
|
// Full filename, e.g., "document.pdf"
|
||||||
|
newName = suggestedTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine new path
|
||||||
|
var newPath string
|
||||||
|
if file.OrgID != nil {
|
||||||
|
// For org files, place in same directory
|
||||||
|
dir := filepath.Dir(file.Path)
|
||||||
|
newPath = filepath.Join(dir, newName)
|
||||||
|
} else {
|
||||||
|
// For user files, place in same directory
|
||||||
|
dir := filepath.Dir(file.Path)
|
||||||
|
newPath = filepath.Join(dir, newName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new file entry in database
|
||||||
|
newFile, err := db.CreateFile(r.Context(), file.OrgID, file.UserID, newName, newPath, "application/pdf", int64(len(content)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[WOPI-STORAGE] Failed to upload file: file=%s path=%s error=%v\n", fileID, file.Path, err)
|
fmt.Printf("[WOPI-EXPORT] Failed to create export file: %v\n", err)
|
||||||
|
errors.WriteError(w, errors.CodeInternal, "Failed to create export file", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
targetFile = newFile
|
||||||
|
|
||||||
|
// Set remote path for the new file
|
||||||
|
if file.OrgID != nil {
|
||||||
|
rel := strings.TrimPrefix(newPath, "/")
|
||||||
|
targetRemotePath = path.Join("/orgs", file.OrgID.String(), rel)
|
||||||
|
} else {
|
||||||
|
targetRemotePath = newPath
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[WOPI-EXPORT] Export operation: original=%s new=%s path=%s\n", file.Name, newName, targetRemotePath)
|
||||||
|
} else {
|
||||||
|
// Normal save operation
|
||||||
|
targetFile = file
|
||||||
|
targetRemotePath = remotePath
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload to storage
|
||||||
|
fmt.Printf("[WOPI-STORAGE] PutFile uploading: file=%s remotePath=%s\n", targetFile.ID.String(), targetRemotePath)
|
||||||
|
err = webDAVClient.Upload(r.Context(), targetRemotePath, strings.NewReader(string(content)), int64(len(content)))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("[WOPI-STORAGE] Failed to upload file: file=%s path=%s error=%v\n", targetFile.ID.String(), targetFile.Path, err)
|
||||||
errors.WriteError(w, errors.CodeInternal, "Failed to save file", http.StatusInternalServerError)
|
errors.WriteError(w, errors.CodeInternal, "Failed to save file", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update file size and modification time in database
|
// Update file size and modification time in database
|
||||||
newSize := int64(len(content))
|
newSize := int64(len(content))
|
||||||
err = db.UpdateFileSize(r.Context(), fileUUID, newSize, &userID)
|
err = db.UpdateFileSize(r.Context(), targetFile.ID, newSize, &userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[WOPI-STORAGE] Failed to update file size: file=%s error=%v\n", fileID, err)
|
fmt.Printf("[WOPI-STORAGE] Failed to update file size: file=%s error=%v\n", targetFile.ID.String(), err)
|
||||||
// Don't fail the upload, just log the warning
|
// Don't fail the upload, just log the warning
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[WOPI-STORAGE] PutFile: file=%s user=%s bytes=%d\n", fileID, userID.String(), newSize)
|
fmt.Printf("[WOPI-STORAGE] PutFile: file=%s user=%s bytes=%d\n", targetFile.ID.String(), userID.String(), newSize)
|
||||||
|
|
||||||
// Return response
|
// Return response
|
||||||
response := models.WOPIPutFileResponse{
|
response := models.WOPIPutFileResponse{
|
||||||
ItemVersion: fileUUID.String(),
|
ItemVersion: targetFile.ID.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|||||||
Reference in New Issue
Block a user