diff --git a/kernel/conf/sync.go b/kernel/conf/sync.go index 6b5cd3936..141f898ed 100644 --- a/kernel/conf/sync.go +++ b/kernel/conf/sync.go @@ -17,14 +17,16 @@ package conf type Sync struct { - CloudName string `json:"cloudName"` // 云端同步目录名称 - Enabled bool `json:"enabled"` // 是否开启同步 - Mode int `json:"mode"` // 同步模式,0:未设置(为兼容已有配置,initConf 函数中会转换为 1),1:自动,2:手动 https://github.com/siyuan-note/siyuan/issues/5089 - Synced int64 `json:"synced"` // 最近同步时间 - Stat string `json:"stat"` // 最近同步统计信息 - GenerateConflictDoc bool `json:"generateConflictDoc"` // 云端同步冲突时是否生成冲突文档 - Provider int `json:"provider"` // 云端存储服务提供者,0:思源官方,1:第三方七牛云,2:S3 协议对象存储 - OSS *OSS `json:"oss"` // 对象存储服务配置 + CloudName string `json:"cloudName"` // 云端同步目录名称 + Enabled bool `json:"enabled"` // 是否开启同步 + Mode int `json:"mode"` // 同步模式,0:未设置(为兼容已有配置,initConf 函数中会转换为 1),1:自动,2:手动 https://github.com/siyuan-note/siyuan/issues/5089 + Synced int64 `json:"synced"` // 最近同步时间 + Stat string `json:"stat"` // 最近同步统计信息 + GenerateConflictDoc bool `json:"generateConflictDoc"` // 云端同步冲突时是否生成冲突文档 + Provider int `json:"provider"` // 云端存储服务提供者 + Qiniu *Qiniu `json:"qiniu"` // 七牛云存储服务配置 + S3 *S3 `json:"s3"` // S3 对象存储服务配置 + WebDAV *WebDAV `json:"webdav"` // WebDAV 服务配置 } func NewSync() *Sync { @@ -37,7 +39,14 @@ func NewSync() *Sync { } } -type OSS struct { +type Qiniu struct { + Endpoint string `json:"endpoint"` // 服务端点 + AccessKey string `json:"accessKey"` // Access Key + SecretKey string `json:"secretKey"` // Secret Key + Bucket string `json:"bucket"` // 存储空间 +} + +type S3 struct { Endpoint string `json:"endpoint"` // 服务端点 AccessKey string `json:"accessKey"` // Access Key SecretKey string `json:"secretKey"` // Secret Key @@ -45,8 +54,15 @@ type OSS struct { Region string `json:"region"` // 存储区域 } +type WebDAV struct { + Endpoint string `json:"endpoint"` // 服务端点 + Username string `json:"username"` // 用户名 + Password string `json:"password"` // 密码 +} + const ( - ProviderSiYuan = 0 - ProviderQiniu = 1 - ProviderS3 = 2 + ProviderSiYuan = 0 // ProviderSiYuan 为思源官方提供的云端存储服务 + ProviderQiniu = 1 // ProviderQiniu 为第三方七牛云提供的云端存储服务 + ProviderS3 = 2 // ProviderS3 为 S3 协议对象存储提供的云端存储服务 + ProviderWebDAV = 3 // ProviderWebDAV 为 WebDAV 协议提供的云端存储服务 ) diff --git a/kernel/go.mod b/kernel/go.mod index 409cebcb4..8085fce64 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -36,13 +36,14 @@ require ( github.com/panjf2000/ants/v2 v2.6.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/radovskyb/watcher v1.0.7 - github.com/siyuan-note/dejavu v0.0.0-20221102120909-ed9ad2509c64 + github.com/siyuan-note/dejavu v0.0.0-20221102152853-ac01094745a0 github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75 github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da github.com/siyuan-note/filelock v0.0.0-20221007163134-7e64809023ef github.com/siyuan-note/httpclient v0.0.0-20221019094331-c904ac9be571 github.com/siyuan-note/logging v0.0.0-20221031125421-9b7234d79d8a github.com/steambap/captcha v1.4.1 + github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423 github.com/vmihailenco/msgpack/v5 v5.3.5 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 diff --git a/kernel/go.sum b/kernel/go.sum index 82305d8e3..87e218145 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -353,8 +353,8 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/siyuan-note/dejavu v0.0.0-20221102120909-ed9ad2509c64 h1:psY8hXz/t7cwqJFR+6+vebb5s3P1AzqfkaJ+gIQGLjw= -github.com/siyuan-note/dejavu v0.0.0-20221102120909-ed9ad2509c64/go.mod h1:+U86jfsvpacZBThE3Ouf/ZQ4EsB4jGPJsMO2iuRv0LQ= +github.com/siyuan-note/dejavu v0.0.0-20221102152853-ac01094745a0 h1:7pRPJ6+IJMsDafbCbA7BR0mv6VWyGblgdUnxqftDjvE= +github.com/siyuan-note/dejavu v0.0.0-20221102152853-ac01094745a0/go.mod h1:HL3cSxYLEwNpmmxvP38hJJPozt8jQW62lsizy8C23aw= github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75 h1:Bi7/7f29LW+Fm0cHc0J1NO1cZqyJwljSWVmfOqVZgaE= github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75/go.mod h1:H8fyqqAbp9XreANjeSbc72zEdFfKTXYN34tc1TjZwtw= github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da h1:/jNhl7LC+9BhkWvNxuJDdsNfA/2wvfuj9mqWx4CbV90= @@ -387,6 +387,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423 h1:Wd8WDEEusB5+En4PiRWJp1cP59QLNsQun+mOTW8+s6s= +github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= diff --git a/kernel/model/conf.go b/kernel/model/conf.go index ff42b3d0a..8466215fc 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -242,18 +242,18 @@ func InitConf() { if 0 == Conf.Sync.Mode { Conf.Sync.Mode = 1 } - if nil == Conf.Sync.OSS { - Conf.Sync.OSS = &conf.OSS{} + if nil == Conf.Sync.Qiniu { + Conf.Sync.Qiniu = &conf.Qiniu{} } - endpoint := Conf.Sync.OSS.Endpoint - endpoint = strings.TrimSpace(endpoint) - if !strings.HasPrefix(endpoint, "http://") && !strings.HasPrefix(endpoint, "https://") { - endpoint = "http://" + endpoint + Conf.Sync.Qiniu.Endpoint = util.NormalizeEndpoint(Conf.Sync.Qiniu.Endpoint) + if nil == Conf.Sync.S3 { + Conf.Sync.S3 = &conf.S3{} } - if !strings.HasSuffix(endpoint, "/") { - endpoint = endpoint + "/" + Conf.Sync.S3.Endpoint = util.NormalizeEndpoint(Conf.Sync.S3.Endpoint) + if nil == Conf.Sync.WebDAV { + Conf.Sync.WebDAV = &conf.WebDAV{} } - Conf.Sync.OSS.Endpoint = endpoint + Conf.Sync.WebDAV.Endpoint = util.NormalizeEndpoint(Conf.Sync.WebDAV.Endpoint) if nil == Conf.Api { Conf.Api = conf.NewAPI() diff --git a/kernel/model/repository.go b/kernel/model/repository.go index 84da78951..a5b15e9c8 100644 --- a/kernel/model/repository.go +++ b/kernel/model/repository.go @@ -44,6 +44,7 @@ import ( "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" + "github.com/studio-b12/gowebdav" ) func init() { @@ -822,6 +823,13 @@ func newRepository() (ret *dejavu.Repo, err error) { cloudRepo = &cloud.SiYuan{BaseCloud: &cloud.BaseCloud{Conf: cloudConf}} case conf.ProviderQiniu: cloudRepo = &cloud.Qiniu{BaseCloud: &cloud.BaseCloud{Conf: cloudConf}} + case conf.ProviderWebDAV: + webdavClient := gowebdav.NewClient(cloudConf.Endpoint, cloudConf.Username, cloudConf.Password) + a := cloudConf.Username + ":" + cloudConf.Password + auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(a)) + webdavClient.SetHeader("Authorization", auth) + webdavClient.SetTimeout(30 * time.Second) + cloudRepo = &cloud.WebDAV{BaseCloud: &cloud.BaseCloud{Conf: cloudConf}, Client: webdavClient} default: err = fmt.Errorf("unknown cloud provider [%d]", Conf.Sync.Provider) return @@ -832,6 +840,7 @@ func newRepository() (ret *dejavu.Repo, err error) { ret, err = dejavu.NewRepo(util.DataDir, util.RepoDir, util.HistoryDir, util.TempDir, Conf.Repo.Key, ignoreLines, cloudRepo) if nil != err { logging.LogErrorf("init data repo failed: %s", err) + return } return } @@ -1029,14 +1038,29 @@ func buildCloudConf() (ret *cloud.Conf, err error) { AvailableSize: availableSize, Server: util.AliyunServer, - Endpoint: Conf.Sync.OSS.Endpoint, - AccessKey: Conf.Sync.OSS.AccessKey, - SecretKey: Conf.Sync.OSS.SecretKey, - Bucket: Conf.Sync.OSS.Bucket, - Region: Conf.Sync.OSS.Region, + // S3 + AccessKey: Conf.Sync.S3.AccessKey, + SecretKey: Conf.Sync.S3.SecretKey, + Bucket: Conf.Sync.S3.Bucket, + Region: Conf.Sync.S3.Region, + + // WebDAV + Username: Conf.Sync.WebDAV.Username, + Password: Conf.Sync.WebDAV.Password, } - if conf.ProviderSiYuan == Conf.Sync.Provider { + + switch Conf.Sync.Provider { + case conf.ProviderSiYuan: ret.Endpoint = "https://siyuan-data.b3logfile.com/" + case conf.ProviderQiniu: + ret.Endpoint = Conf.Sync.Qiniu.Endpoint + case conf.ProviderS3: + ret.Endpoint = Conf.Sync.S3.Endpoint + case conf.ProviderWebDAV: + ret.Endpoint = Conf.Sync.WebDAV.Endpoint + default: + err = fmt.Errorf("invalid provider [%d]", Conf.Sync.Provider) + return } return } diff --git a/kernel/util/path.go b/kernel/util/path.go index 26be07a28..5b290f151 100644 --- a/kernel/util/path.go +++ b/kernel/util/path.go @@ -159,3 +159,17 @@ func GetChildDocDepth(treeAbsPath string) (ret int) { ret = depth - baseDepth return } + +func NormalizeEndpoint(endpoint string) string { + endpoint = strings.TrimSpace(endpoint) + if "" == endpoint { + return "" + } + if !strings.HasPrefix(endpoint, "http://") && !strings.HasPrefix(endpoint, "https://") { + endpoint = "http://" + endpoint + } + if !strings.HasSuffix(endpoint, "/") { + endpoint = endpoint + "/" + } + return endpoint +}