gshare/gshare.go

174 lines
4.2 KiB
Go

package main
import (
"fmt"
log "github.com/sirupsen/logrus"
"os"
"errors"
"strings"
"gopkg.in/yaml.v3"
"github.com/studio-b12/gowebdav"
"github.com/alexflint/go-arg"
"github.com/dustin/go-humanize"
)
type NextcloudServers struct {
Configs []NextcloudServer `nextcloud`
}
type NextcloudServer struct {
Uuid string
Name string
Url string
Username string
Token string
}
type LsCmd struct {
Remote string `arg:"positional" help:"remote folder" default:"/"`
Detailed bool `arg:"-d,--details",default:"false"`
Recurse bool `arg:"-r,--recurse",default:"false"`
}
type RmCmd struct {
Remote string `arg:"positional,required"`
Force bool `arg:"-f,--force",default:"false"`
Recurse bool `arg:"-r,--recurse",default:"false"`
}
type UploadCmd struct {
Local string `arg:"positional,required"`
Remote string `arg:"positional"`
Force bool `arg:"-f,--force",default:"false"`
}
type DownloadCmd struct {
Remote string `arg:"positional"`
Local string `arg:"positional"`
Force bool `arg:"-f,--force",default:"false"`
}
type ShareCmd struct {
Remote string `arg:"positional"`
Name string `arg:"-n,--name"`
}
type args struct {
Servername string `arg:"--server"`
Ls *LsCmd `arg:"subcommand:ls"`
Rm *RmCmd `arg:"subcommand:rm"`
Upload *UploadCmd `arg:"subcommand:upload"`
Download *DownloadCmd `arg:"subcommand:download"`
Share *ShareCmd `arg:"subcommand:share"`
}
func (args) Version() string {
return "1.0.0"
}
func loadConfig(name string) (NextcloudServer, error) {
var err_msg string
var config_err NextcloudServer
var filename = os.Args[0]
f, err := os.ReadFile("~/.config/gshare/config.yaml")
if err != nil {
log.Fatal(err)
}
var config NextcloudServers
if err := yaml.Unmarshal([]byte(f), &config); err != nil {
log.Fatal(err)
}
switch size := len(config.Configs); size {
case 0:
err_msg = fmt.Sprintf("No server configured. You should configure one with %s config add", filename)
log.Fatal(err_msg)
return config_err, errors.New(err_msg)
case 1:
log.Debug("Only one server configured")
return config.Configs[0], nil
default:
if len(name) == 0 {
err_msg = fmt.Sprintf("Multiple servers configured. You should specify a server name with %s --server servername %s", filename)
err_msg = "You should specify a server name with --server servername"
log.Fatal(err_msg)
return config_err, errors.New(err_msg)
}
}
for _, s := range config.Configs {
if s.Name == name {
return s, nil
}
}
err_msg = fmt.Sprintf("Could not find requested server with name %s", name)
log.Fatal(err_msg)
return config_err, errors.New(err_msg)
}
func listDir(c gowebdav.Client, dir string, details bool, recurse bool, recursecount int) {
files, err := c.ReadDir(dir)
if err != nil {
log.Fatal(err)
}
if recursecount == 0 {
fmt.Println(dir)
}
for i, file := range files {
var pfx = strings.Repeat("|", recursecount)
var sfx = "|-"
if details {
var ftype = "[File]"
var size = ""
if file.IsDir() {
ftype = "[Dir]"
} else {
size = humanize.Bytes(uint64(file.Size()))
}
if i == len(files) - 1 {
sfx = "\\-"
}
fmt.Println(fmt.Sprintf("%s%s %s %s %s", pfx, sfx, ftype, file.Name(), size))
} else {
fmt.Println(fmt.Sprintf("%s%s %s", pfx, sfx, file.Name()))
}
if recurse {
if file.IsDir() {
new_dir := fmt.Sprintf("%s/%s", dir, file.Name())
listDir(c, new_dir, details, recurse, recursecount+1)
}
}
}
}
func Remove(c gowebdav.Client, dir string, force bool, recurse bool) {
fmt.Println(fmt.Sprintf("%s, %t, %t", dir, force, recurse))
c.Remove(dir)
}
func nextcloudConnect(config NextcloudServer) gowebdav.Client {
baseUrl := fmt.Sprintf("%s/remote.php/dav/files/%s", config.Url, config.Username)
c := gowebdav.NewClient(baseUrl, config.Username, config.Token)
return *c
}
func main() {
var args args
p := arg.MustParse(&args)
if p.Subcommand() == nil {
p.Fail("missing subcommand")
}
config, err := loadConfig(args.Servername)
if err != nil {
log.Fatal(err)
}
switch {
case args.Ls != nil:
c := nextcloudConnect(config)
c.Connect()
listDir(c, args.Ls.Remote, args.Ls.Detailed, args.Ls.Recurse, 0)
case args.Rm != nil:
c := nextcloudConnect(config)
c.Connect()
Remove(c, args.Rm.Remote, args.Rm.Force, args.Rm.Recurse)
}
}