130 lines
3.8 KiB
Go
130 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/studio-b12/gowebdav"
|
|
)
|
|
|
|
func (a *App) getSettings(c *gin.Context) {
|
|
c.JSON(200, gin.H{
|
|
"amApi": a.cfg.AMAPI, "downloadDir": a.cfg.DownloadDir,
|
|
"webdavUrl": a.cfg.WebDAVURL, "webdavUser": a.cfg.WebDAVUser,
|
|
"webdavPass": "", "hasWebdavPassword": a.cfg.WebDAVPass != "", "webdavPath": a.cfg.WebDAVPath,
|
|
"quality": a.cfg.DefaultQuality, "webdavVersionPolicy": a.cfg.WebDAVVersionPolicy,
|
|
"localFilePolicy": a.cfg.LocalFilePolicy,
|
|
})
|
|
}
|
|
|
|
func (a *App) putSettings(c *gin.Context) {
|
|
var v map[string]string
|
|
if c.BindJSON(&v) != nil {
|
|
c.Status(400)
|
|
return
|
|
}
|
|
if x := v["amApi"]; x != "" {
|
|
a.cfg.AMAPI = x
|
|
a.saveSetting("am_api", x)
|
|
a.am = &AMAPIClient{BaseURL: x, HTTP: a.httpClient}
|
|
}
|
|
if x := v["downloadDir"]; x != "" {
|
|
a.cfg.DownloadDir = x
|
|
a.saveSetting("download_dir", x)
|
|
}
|
|
if p := v["webdavVersionPolicy"]; p == "keep" || p == "replace_lower" {
|
|
a.cfg.WebDAVVersionPolicy = p
|
|
}
|
|
if p := v["localFilePolicy"]; p == "keep" || p == "delete_after_upload" {
|
|
a.cfg.LocalFilePolicy = p
|
|
}
|
|
if x, ok := v["webdavUrl"]; ok {
|
|
a.cfg.WebDAVURL = x
|
|
}
|
|
if x, ok := v["webdavUser"]; ok {
|
|
a.cfg.WebDAVUser = x
|
|
}
|
|
// The GET endpoint intentionally never returns the WebDAV password.
|
|
// Therefore an empty webdavPass means "keep the existing password", not clear it.
|
|
if x, ok := v["webdavPass"]; ok && x != "" {
|
|
a.cfg.WebDAVPass = x
|
|
}
|
|
if x, ok := v["webdavPath"]; ok {
|
|
a.cfg.WebDAVPath = strings.Trim(x, "/")
|
|
}
|
|
if x, ok := v["quality"]; ok && x != "" {
|
|
a.cfg.DefaultQuality = x
|
|
}
|
|
for k, x := range map[string]string{
|
|
"webdav_url": a.cfg.WebDAVURL, "webdav_user": a.cfg.WebDAVUser, "webdav_pass": a.cfg.WebDAVPass,
|
|
"webdav_path": a.cfg.WebDAVPath, "quality": a.cfg.DefaultQuality,
|
|
"webdav_version_policy": a.cfg.WebDAVVersionPolicy, "local_file_policy": a.cfg.LocalFilePolicy,
|
|
} {
|
|
a.saveSetting(k, x)
|
|
}
|
|
if a.cfg.WebDAVURL != "" {
|
|
a.storage = NewWebDAVStorage(a.cfg)
|
|
} else {
|
|
a.storage = nil
|
|
}
|
|
// Credentials/config changes should repair already-downloaded local files
|
|
// immediately instead of waiting for the periodic retry interval.
|
|
go a.resyncPendingUploads()
|
|
c.JSON(200, gin.H{"ok": true})
|
|
}
|
|
|
|
func (a *App) testWebDAV(c *gin.Context) {
|
|
var v struct{ URL, User, Pass, Path string }
|
|
if c.BindJSON(&v) != nil {
|
|
c.Status(400)
|
|
return
|
|
}
|
|
// An empty password means "use the saved password". The password is never
|
|
// returned to the browser, so this also makes a fresh settings page test
|
|
// the credential that is actually stored by the server.
|
|
if v.URL == "" {
|
|
v.URL = a.cfg.WebDAVURL
|
|
}
|
|
if v.User == "" {
|
|
v.User = a.cfg.WebDAVUser
|
|
}
|
|
if v.Pass == "" {
|
|
v.Pass = a.cfg.WebDAVPass
|
|
}
|
|
v.Path = strings.Trim(v.Path, "/")
|
|
if v.Path == "" {
|
|
v.Path = a.cfg.WebDAVPath
|
|
}
|
|
if v.URL == "" || v.User == "" || v.Pass == "" {
|
|
c.JSON(400, gin.H{"ok": false, "error": "WebDAV URL、用户名或密码未配置"})
|
|
return
|
|
}
|
|
client := gowebdav.NewClient(v.URL, v.User, v.Pass)
|
|
client.SetTimeout(20 * time.Second)
|
|
if err := client.Connect(); err != nil {
|
|
c.JSON(502, gin.H{"ok": false, "error": "WebDAV authentication failed: " + err.Error()})
|
|
return
|
|
}
|
|
if v.Path != "" {
|
|
if err := client.MkdirAll(v.Path, 0755); err != nil {
|
|
c.JSON(502, gin.H{"ok": false, "error": "WebDAV target path is not writable: " + err.Error()})
|
|
return
|
|
}
|
|
}
|
|
var token [12]byte
|
|
if _, err := rand.Read(token[:]); err != nil {
|
|
c.JSON(500, gin.H{"ok": false, "error": "failed to create test token"})
|
|
return
|
|
}
|
|
testPath := strings.Trim(v.Path, "/") + "/.am-downloader-test-" + fmt.Sprintf("%x", token[:])
|
|
if err := client.Write(testPath, []byte("ok"), 0644); err != nil {
|
|
c.JSON(502, gin.H{"ok": false, "error": "WebDAV write test failed: " + err.Error()})
|
|
return
|
|
}
|
|
_ = client.Remove(testPath)
|
|
c.JSON(200, gin.H{"ok": true, "path": v.Path})
|
|
}
|