Commit f5dc714d authored by Christopher Schinnerl's avatar Christopher Schinnerl

Add recursive flag to siac for folder downloads

parent dd10c714
Pipeline #57575521 passed with stages
in 44 minutes and 50 seconds
......@@ -15,17 +15,18 @@ import (
var (
// Flags.
dictionaryLanguage string // dictionary for seed utils
hostContractOutputType string // output type for host contracts
hostVerbose bool // display additional host info
initForce bool // destroy and re-encrypt the wallet on init if it already exists
initPassword bool // supply a custom password when creating a wallet
renterAllContracts bool // Show all active and expired contracts
renterDownloadAsync bool // Downloads files asynchronously
renterListVerbose bool // Show additional info about uploaded files.
renterShowHistory bool // Show download history in addition to download queue.
siaDir string // Path to sia data dir
walletRawTxn bool // Encode/decode transactions in base64-encoded binary.
dictionaryLanguage string // dictionary for seed utils
hostContractOutputType string // output type for host contracts
hostVerbose bool // display additional host info
initForce bool // destroy and re-encrypt the wallet on init if it already exists
initPassword bool // supply a custom password when creating a wallet
renterAllContracts bool // Show all active and expired contracts
renterDownloadAsync bool // Downloads files asynchronously
renterDownloadRecursive bool // Downloads folders recursively.
renterListVerbose bool // Show additional info about uploaded files.
renterShowHistory bool // Show download history in addition to download queue.
siaDir string // Path to sia data dir
walletRawTxn bool // Encode/decode transactions in base64-encoded binary.
allowanceFunds string // amount of money to be used within a period
allowancePeriod string // length of period
......@@ -147,6 +148,7 @@ func main() {
renterContractsCmd.Flags().BoolVarP(&renterAllContracts, "all", "A", false, "Show all expired contracts in addition to active contracts")
renterDownloadsCmd.Flags().BoolVarP(&renterShowHistory, "history", "H", false, "Show download history in addition to the download queue")
renterFilesDownloadCmd.Flags().BoolVarP(&renterDownloadAsync, "async", "A", false, "Download file asynchronously")
renterFilesDownloadCmd.Flags().BoolVarP(&renterDownloadRecursive, "recursive", "R", false, "Download folder recursively")
renterFilesListCmd.Flags().BoolVarP(&renterListVerbose, "verbose", "v", false, "Show additional file info such as redundancy")
renterExportCmd.AddCommand(renterExportContractTxnsCmd)
......
......@@ -758,40 +758,38 @@ Contract %v
fmt.Println("Contract not found")
}
// renterfilesdownload downloads the dir at the given path from the Sia network
// to the local specified destination.
func renterdirdownload(path, destination string) {
destination = abs(destination)
// Parse SiaPath.
siaPath, err := modules.NewSiaPath(path)
if err != nil {
die("Failed to parse SiaPath:", err)
}
// downloadDir downloads the dir at the specified siaPath to the specified
// location. It returns all the files for which a download was initialized as
// tracked files and the ones which were ignored as skipped. Errors are composed
// into a single error.
func downloadDir(siaPath modules.SiaPath, destination string) (tfs []trackedFile, skipped []string, err error) {
// Get dir info.
rd, err := httpClient.RenterGetDir(siaPath)
if err != nil {
die("Failed to get dir info:", err)
err = errors.AddContext(err, "failed to get dir info")
return
}
// Create destination on disk.
if err := os.MkdirAll(destination, 0755); err != nil {
die("Failed to create destination dir:", err)
if err = os.MkdirAll(destination, 0755); err != nil {
err = errors.AddContext(err, "failed to create destination dir")
return
}
// Download files.
tfs := make([]trackedFile, 0, len(rd.Files))
var skipped []string
for _, file := range rd.Files {
// Skip files that already exist.
dst := filepath.Join(destination, file.SiaPath.Name())
if _, err := os.Stat(dst); err == nil {
if _, err = os.Stat(dst); err == nil {
skipped = append(skipped, dst)
continue
} else if !os.IsNotExist(err) {
die("Failed to get file stats:", err)
err = errors.AddContext(err, "failed to get file stats")
return
}
// Download file.
err = httpClient.RenterDownloadFullGet(file.SiaPath, dst, true)
if err != nil {
die("Failed to start download:", err)
err = errors.AddContext(err, "Failed to start download")
return
}
// Append file to tracked files.
tfs = append(tfs, trackedFile{
......@@ -799,6 +797,35 @@ func renterdirdownload(path, destination string) {
dst: dst,
})
}
// If the download isn't recursive we are done.
if !renterDownloadRecursive {
return
}
// Call downloadDir on all subdirs.
for i := 1; i < len(rd.Directories); i++ {
subDir := rd.Directories[i]
rtfs, rskipped, rerr := downloadDir(subDir.SiaPath, filepath.Join(destination, subDir.SiaPath.Name()))
tfs = append(tfs, rtfs...)
skipped = append(skipped, rskipped...)
err = errors.Compose(err, rerr)
}
return
}
// renterfilesdownload downloads the dir at the given path from the Sia network
// to the local specified destination.
func renterdirdownload(path, destination string) {
destination = abs(destination)
// Parse SiaPath.
siaPath, err := modules.NewSiaPath(path)
if err != nil {
die("Failed to parse SiaPath:", err)
}
// Download dir.
tfs, skipped, downloadErr := downloadDir(siaPath, destination)
if renterDownloadAsync && downloadErr != nil {
fmt.Println("At least one error occured when initializing the download:", downloadErr)
}
// If the download is async, report success.
if renterDownloadAsync {
fmt.Printf("Queued Download '%s' to %s.\n", siaPath.String(), abs(destination))
......@@ -816,6 +843,9 @@ func renterdirdownload(path, destination string) {
os.Exit(0)
}
// Print errors.
if downloadErr != nil {
fmt.Println("At least one error occured when initializing the download:", downloadErr)
}
for _, fd := range failedDownloads {
fmt.Printf("Download of file '%v' to destination '%v' failed: %v\n", fd.SiaPath, fd.Destination, fd.Error)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment