Import source: handler/fs/fs
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user