Skip to content
This repository has been archived by the owner on Jun 18, 2020. It is now read-only.

Commit

Permalink
Introduce new -exclude flag
Browse files Browse the repository at this point in the history
This can be used multiple times and acts as an easy startsWith check,
i.e. if a remote path starts with one of the provided exclude strings it
will be skipped.
  • Loading branch information
wilriker committed Jun 4, 2019
1 parent a946a7c commit a15d06b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
22 changes: 13 additions & 9 deletions README.md
Expand Up @@ -5,18 +5,22 @@ By default it will backup 0:/sys folder.
## Usage
```
Usage of ./duetbackup:
-dirToBackup string
Directory on Duet to create a backup of (default "0:/sys")
-domain string
-dirToBackup string
Directory on Duet to create a backup of (default "0:/sys")
-domain string
Domain of Duet Wifi
-outDir string
Output dir of backup
-password string
-exclude value
Exclude paths starting with this string (can be passed multiple times)
-outDir string
Output dir of backup
-password string
Connection password (default "reprap")
-port uint
Port of Duet Wifi (default 80)
-removeLocal
-port uint
Port of Duet Wifi (default 80)
-removeLocal
Remove files locally that have been deleted on the Duet
-verbose
Output more details
```

## Feedback
Expand Down
54 changes: 43 additions & 11 deletions duetbackup.go
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"sort"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -43,6 +44,28 @@ func (lt *localTime) UnmarshalJSON(b []byte) (err error) {
return err
}

type excludes struct {
excls []string
}

func (e *excludes) String() string {
return strings.Join(e.excls, ",")
}

func (e *excludes) Set(value string) error {
e.excls = append(e.excls, value)
return nil
}

func (e *excludes) Contains(path string) bool {
for _, excl := range e.excls {
if strings.HasPrefix(path, excl) {
return true
}
}
return false
}

func getFileList(baseURL string, dir string, first uint64) (*filelist, error) {

fileListURL := "rr_filelist?dir="
Expand Down Expand Up @@ -85,11 +108,18 @@ func getFileList(baseURL string, dir string, first uint64) (*filelist, error) {
return &fl, nil
}

func updateLocalFiles(baseURL string, fl *filelist, outDir string, removeLocal, verbose bool) error {
func updateLocalFiles(baseURL string, fl *filelist, outDir string, excls excludes, removeLocal, verbose bool) error {

fileDownloadURL := "rr_download?name=" + url.QueryEscape(fl.Dir+"/")
fileDownloadURL := "rr_download?name="

for _, file := range fl.Files {
remoteFilename := fl.Dir + "/" + file.Name
if excls.Contains(remoteFilename) {
if verbose {
log.Println(" Skipping: ", remoteFilename)
}
continue
}
fileName := filepath.Join(outDir, file.Name)
fi, err := os.Stat(fileName)
if err != nil && !os.IsNotExist(err) {
Expand All @@ -102,15 +132,15 @@ func updateLocalFiles(baseURL string, fl *filelist, outDir string, removeLocal,
// Does not exist yet so try to create it
if fi == nil {
if verbose {
log.Println("Adding new directory", fileName)
log.Println(" Creating directory", fileName)
}
if err = os.MkdirAll(fileName, 0755); err != nil {
return err
}
}

// Go recursively into this directory
if err = syncFolder(baseURL, fl.Dir+"/"+file.Name, fileName, removeLocal, verbose); err != nil {
if err = syncFolder(baseURL, remoteFilename, fileName, excls, removeLocal, verbose); err != nil {
return err
}
continue
Expand All @@ -120,14 +150,14 @@ func updateLocalFiles(baseURL string, fl *filelist, outDir string, removeLocal,
if fi == nil || fi.ModTime().Before(file.Date.Time) {
if verbose {
if fi != nil {
log.Println("Updating", file.Name)
log.Println(" Updating: ", remoteFilename)
} else {
log.Println("Adding", file.Name)
log.Println(" Adding: ", remoteFilename)
}
}

// Download file
resp, err := httpClient.Get(baseURL + fileDownloadURL + url.QueryEscape(file.Name))
resp, err := httpClient.Get(baseURL + fileDownloadURL + url.QueryEscape(remoteFilename))
if err != nil {
return err
}
Expand Down Expand Up @@ -155,7 +185,7 @@ func updateLocalFiles(baseURL string, fl *filelist, outDir string, removeLocal,
os.Chtimes(fileName, file.Date.Time, file.Date.Time)
} else {
if verbose {
log.Println(file.Name, "is up-to-date")
log.Println(" Up-to-date:", remoteFilename)
}
}

Expand Down Expand Up @@ -190,15 +220,15 @@ func removeDeletedFiles(fl *filelist, outDir string, verbose bool) error {
return nil
}

func syncFolder(address, folder, outDir string, removeLocal, verbose bool) error {
func syncFolder(address, folder, outDir string, excls excludes, removeLocal, verbose bool) error {
log.Println("Fetching filelist for", folder)
fl, err := getFileList(address, url.QueryEscape(folder), 0)
if err != nil {
return err
}

log.Println("Downloading new/changed files from", folder, "to", outDir)
if err = updateLocalFiles(address, fl, outDir, removeLocal, verbose); err != nil {
if err = updateLocalFiles(address, fl, outDir, excls, removeLocal, verbose); err != nil {
return err
}

Expand Down Expand Up @@ -229,6 +259,7 @@ func main() {
var domain, dirToBackup, outDir, password string
var removeLocal, verbose bool
var port uint64
var excls excludes

flag.StringVar(&domain, "domain", "", "Domain of Duet Wifi")
flag.Uint64Var(&port, "port", 80, "Port of Duet Wifi")
Expand All @@ -237,6 +268,7 @@ func main() {
flag.StringVar(&password, "password", "reprap", "Connection password")
flag.BoolVar(&removeLocal, "removeLocal", false, "Remove files locally that have been deleted on the Duet")
flag.BoolVar(&verbose, "verbose", false, "Output more details")
flag.Var(&excls, "exclude", "Exclude paths starting with this string (can be passed multiple times)")
flag.Parse()

if domain == "" || outDir == "" {
Expand Down Expand Up @@ -267,7 +299,7 @@ func main() {
absPath = outDir
}

err = syncFolder(address, dirToBackup, absPath, removeLocal, verbose)
err = syncFolder(address, dirToBackup, absPath, excls, removeLocal, verbose)
if err != nil {
log.Fatal(err)
}
Expand Down

0 comments on commit a15d06b

Please sign in to comment.