server/admin/sync/importer_cloud.go

142 lines
3.6 KiB
Go

package sync
import (
"errors"
"io"
"net/http"
"net/url"
"os"
"path"
"strings"
"github.com/studio-b12/gowebdav"
)
// CloudImporter implements an Importer, where files to imports are located
// remotely, under a WebDAV server (such as sabre/dav, owncloud, ...).
type CloudImporter struct {
// baseDAV is the URL (most probably http or https one) to the root directory.
// It should contains all themes, in separated directories.
baseDAV url.URL
// username is the username used to perform authentication through BasicAuth.
username string
// password is the password used to perform authentication through BasicAuth.
password string
}
// NewCloudImporter registers a new object CloudImporter, as the URL conversion
// can returns errors.
func NewCloudImporter(baseDAV string, username string, password string) (*CloudImporter, error) {
if r, err := url.Parse(baseDAV); err != nil {
return nil, err
} else {
return &CloudImporter{*r, username, password}, nil
}
}
func (i CloudImporter) Kind() string {
return "cloud file importer: " + i.baseDAV.String()
}
func (i CloudImporter) Id() *string {
return nil
}
func (i CloudImporter) Init() error {
return nil
}
func (i CloudImporter) Sync() error {
return nil
}
func (i CloudImporter) Exists(filename string) bool {
fullURL := i.baseDAV
fullURL.Path = path.Join(fullURL.Path, filename)
client := http.Client{}
if req, err := http.NewRequest("HEAD", fullURL.String(), nil); err == nil {
req.SetBasicAuth(i.username, i.password)
if resp, err := client.Do(req); err == nil {
defer resp.Body.Close()
return resp.StatusCode == http.StatusOK
}
}
return false
}
func (i CloudImporter) toURL(filename string) string {
fullURL := i.baseDAV
fullURL.Path = path.Join(fullURL.Path, filename)
return fullURL.String()
}
func (i CloudImporter) importFile(URI string, next func(string, string) (interface{}, error)) (interface{}, error) {
return ImportFile(i, URI, next)
}
func (i CloudImporter) GetFile(filename string) (io.Reader, error) {
fullURL := i.baseDAV
fullURL.Path = path.Join(fullURL.Path, filename)
client := http.Client{}
if req, err := http.NewRequest("GET", fullURL.String(), nil); err != nil {
return nil, err
} else {
req.SetBasicAuth(i.username, i.password)
if resp, err := client.Do(req); err != nil {
return nil, err
} else {
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, errors.New(resp.Status)
} else {
return resp.Body, nil
}
}
}
}
func (i CloudImporter) writeFile(filename string, reader io.Reader) error {
fullURL := i.baseDAV
fullURL.Path = path.Join(fullURL.Path, filename)
client := http.Client{}
if req, err := http.NewRequest("PUT", fullURL.String(), reader); err != nil {
return err
} else {
req.SetBasicAuth(i.username, i.password)
if resp, err := client.Do(req); err != nil {
return err
} else {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return errors.New(resp.Status)
} else {
return nil
}
}
}
}
func (i CloudImporter) ListDir(filename string) ([]string, error) {
client := gowebdav.NewClient(i.baseDAV.String(), i.username, i.password)
if files, err := client.ReadDir(strings.Replace(url.PathEscape(filename), "%2F", "/", -1)); err != nil {
return nil, err
} else {
res := make([]string, 0)
for _, file := range files {
res = append(res, file.Name())
}
return res, nil
}
}
func (i CloudImporter) Stat(filename string) (os.FileInfo, error) {
return gowebdav.NewClient(i.baseDAV.String(), i.username, i.password).Stat(strings.Replace(url.PathEscape(filename), "%2F", "/", -1))
}