added proton drive integration
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package drive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const binaryName = "proton-drive"
|
||||
|
||||
// Lookup returns the full path to the proton-drive binary in PATH.
|
||||
func Lookup() (string, error) {
|
||||
return exec.LookPath(binaryName)
|
||||
}
|
||||
|
||||
// CheckAuth verifies that the user is authenticated by listing /my-files.
|
||||
func CheckAuth() error {
|
||||
binary, err := Lookup()
|
||||
if err != nil {
|
||||
return fmt.Errorf("proton-drive not found in PATH: %w", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(binary, "filesystem", "list", "/my-files")
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("not authenticated with proton-drive (run 'proton-drive auth login'): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upload uploads localPath to remotePath on Proton Drive.
|
||||
// remotePath is a full path including filename (e.g. /my-files/md/report.md).
|
||||
// The CLI uploads to a parent directory and preserves the local filename,
|
||||
// so if the remote filename differs from the local one, a temp copy is staged.
|
||||
// Existing remote files are overwritten (--conflict-strategy replace).
|
||||
func Upload(localPath, remotePath string) error {
|
||||
binary, err := Lookup()
|
||||
if err != nil {
|
||||
return fmt.Errorf("proton-drive not found in PATH: %w", err)
|
||||
}
|
||||
|
||||
remoteDir := filepath.Dir(remotePath)
|
||||
remoteName := filepath.Base(remotePath)
|
||||
localName := filepath.Base(localPath)
|
||||
|
||||
if remoteName == localName {
|
||||
return runUpload(binary, localPath, remoteDir)
|
||||
}
|
||||
|
||||
tmpDir, err := os.MkdirTemp("", "dirmd-upload-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create temp dir: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tmpFile := filepath.Join(tmpDir, remoteName)
|
||||
if err := copyFile(localPath, tmpFile); err != nil {
|
||||
return fmt.Errorf("cannot stage temp file: %w", err)
|
||||
}
|
||||
|
||||
return runUpload(binary, tmpFile, remoteDir)
|
||||
}
|
||||
|
||||
func runUpload(binary, localPath, remoteDir string) error {
|
||||
cmd := exec.Command(binary, "filesystem", "upload", localPath, remoteDir,
|
||||
"--conflict-strategy", "replace")
|
||||
|
||||
var stderr strings.Builder
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("upload to proton-drive failed: %w: %s",
|
||||
err, strings.TrimSpace(stderr.String()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
data, err := os.ReadFile(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(dst, data, 0644)
|
||||
}
|
||||
Reference in New Issue
Block a user