Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
85 lines
2.2 KiB
Go
85 lines
2.2 KiB
Go
package fs
|
|
|
|
import (
|
|
"io"
|
|
"path"
|
|
"reactor-crw"
|
|
)
|
|
|
|
// PathResolver defines a simple interface to resolve path for content
|
|
// before saving it.
|
|
type pathResolver interface {
|
|
// CreateFolder creates a new folder in the "current" dir. The current
|
|
// directory is specified in Config.SavePath provided by a user. If dir
|
|
// with such name already exists it'll skip creation step.
|
|
CreateFolder(name string) error
|
|
|
|
// CreateFile creates a new file for downloaded content in the directory
|
|
// created by the CreateFolder function and returns the corresponding
|
|
// io.WriteCloser. If a file with such a name already exists then it'll
|
|
// be overwritten.
|
|
CreateFile(name string) (io.WriteCloser, error)
|
|
|
|
// Remove removes a file or folder by its name. If provided path does not
|
|
// exist it'll be skipped.
|
|
Remove(name string)
|
|
}
|
|
|
|
// FileSaver defines ContentHandler implementation that will download content
|
|
// and save it to the host's file system. It resolves the corresponding file
|
|
// path with PathResolver.
|
|
type FileSaver struct {
|
|
pr pathResolver
|
|
t reactor_crw.Transport
|
|
}
|
|
|
|
// NewFileSaver creates a new FileSaver instance along with a new folder that
|
|
// will act as a context for a new instance. All files will be processed within
|
|
// this new folder.
|
|
func NewFileSaver(pr pathResolver, t reactor_crw.Transport, baseFolder string) (*FileSaver, error) {
|
|
err := pr.CreateFolder(baseFolder)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &FileSaver{
|
|
pr: pr,
|
|
t: t,
|
|
}, nil
|
|
}
|
|
|
|
// Process downloads content by the corresponding URL by making an HTTP request
|
|
// and saves the result to the file system. In case of error during saving the
|
|
// content the corresponding file will be deleted from the file system.
|
|
func (f *FileSaver) Process(url string, progress chan<- int, e chan<- error) {
|
|
defer func() {
|
|
progress <- 1
|
|
}()
|
|
|
|
data, err := f.t.FetchData(url)
|
|
if err != nil {
|
|
e <- err
|
|
return
|
|
}
|
|
|
|
defer func(b io.ReadCloser) {
|
|
_ = b.Close()
|
|
}(data)
|
|
|
|
file, err := f.pr.CreateFile(path.Base(url))
|
|
if err != nil {
|
|
e <- err
|
|
return
|
|
}
|
|
|
|
defer func(f io.WriteCloser) {
|
|
_ = f.Close()
|
|
}(file)
|
|
|
|
_, err = io.Copy(file, data)
|
|
if err != nil {
|
|
f.pr.Remove(path.Base(url))
|
|
e <- err
|
|
}
|
|
}
|