@@ -2,9 +2,9 @@ package grabber
22
33import (
44 "fmt"
5+ "io/ioutil"
56 "os"
67 "path"
7- "runtime"
88 "time"
99
1010 "github.com/crazy-max/ftpgrab/v7/internal/config"
@@ -21,9 +21,10 @@ import (
2121
2222// Client represents an active grabber object
2323type Client struct {
24- config * config.Download
25- db * db.Client
26- server * server.Client
24+ config * config.Download
25+ db * db.Client
26+ server * server.Client
27+ tempdir string
2728}
2829
2930// New creates new grabber instance
@@ -49,10 +50,17 @@ func New(dlConfig *config.Download, dbConfig *config.Db, serverConfig *config.Se
4950 return nil , errors .Wrap (err , "Cannot connect to server" )
5051 }
5152
53+ // Temp dir to download files
54+ tempdir , err := ioutil .TempDir ("" , ".ftpgrab.*" )
55+ if err != nil {
56+ return nil , errors .Wrap (err , "Cannot create temp dir" )
57+ }
58+
5259 return & Client {
53- config : dlConfig ,
54- db : dbCli ,
55- server : serverCli ,
60+ config : dlConfig ,
61+ db : dbCli ,
62+ server : serverCli ,
63+ tempdir : tempdir ,
5664 }, nil
5765}
5866
@@ -115,13 +123,14 @@ func (c *Client) download(file File, retry int) *journal.Entry {
115123 sublogger .Warn ().Err (err ).Msg ("Cannot fix parent folder permissions" )
116124 }
117125
118- destfile , err := os . Create (destpath )
126+ destfile , err := c . createFile (destpath )
119127 if err != nil {
120128 sublogger .Error ().Err (err ).Msg ("Cannot create destination file" )
121129 entry .Level = journal .EntryLevelError
122130 entry .Text = fmt .Sprintf ("Cannot create destination file: %v" , err )
123131 return entry
124132 }
133+ defer destfile .Close ()
125134
126135 err = c .server .Retrieve (srcpath , destfile )
127136 if err != nil {
@@ -135,9 +144,31 @@ func (c *Client) download(file File, retry int) *journal.Entry {
135144 return c .download (file , retry )
136145 }
137146 } else {
147+ if err = destfile .Close (); err != nil {
148+ sublogger .Error ().Err (err ).Msg ("Cannot close destination file" )
149+ entry .Level = journal .EntryLevelError
150+ entry .Text = fmt .Sprintf ("Cannot close destination file: %v" , err )
151+ return entry
152+ }
153+
154+ if * c .config .TempFirst {
155+ log .Debug ().
156+ Str ("tempfile" , destfile .Name ()).
157+ Str ("destfile" , destpath ).
158+ Msgf ("Move temp file" )
159+ err := moveFile (destfile .Name (), destpath )
160+ if err != nil {
161+ sublogger .Error ().Err (err ).Msg ("Cannot move file" )
162+ entry .Level = journal .EntryLevelError
163+ entry .Text = fmt .Sprintf ("Cannot move file: %v" , err )
164+ return entry
165+ }
166+ }
167+
138168 sublogger .Info ().
139169 Str ("duration" , time .Since (retrieveStart ).Round (time .Millisecond ).String ()).
140170 Msg ("File successfully downloaded" )
171+
141172 entry .Level = journal .EntryLevelSuccess
142173 entry .Text = fmt .Sprintf ("%s successfully downloaded in %s" ,
143174 units .HumanSize (float64 (file .Info .Size ())),
@@ -159,6 +190,22 @@ func (c *Client) download(file File, retry int) *journal.Entry {
159190 return entry
160191}
161192
193+ func (c * Client ) createFile (filename string ) (* os.File , error ) {
194+ if * c .config .TempFirst {
195+ tempfile , err := ioutil .TempFile (c .tempdir , path .Base (filename ))
196+ if err != nil {
197+ return nil , err
198+ }
199+ return tempfile , nil
200+ }
201+
202+ destfile , err := os .Create (filename )
203+ if err != nil {
204+ return nil , err
205+ }
206+ return destfile , nil
207+ }
208+
162209func (c * Client ) getStatus (file File ) journal.EntryStatus {
163210 if ! c .isIncluded (file ) {
164211 return journal .EntryStatusNotIncluded
@@ -201,32 +248,6 @@ func (c *Client) isExcluded(file File) bool {
201248 return false
202249}
203250
204- func (c * Client ) fixPerms (filepath string ) error {
205- if runtime .GOOS == "windows" {
206- return nil
207- }
208-
209- fileinfo , err := os .Stat (filepath )
210- if err != nil {
211- return err
212- }
213-
214- chmod := os .FileMode (c .config .ChmodFile )
215- if fileinfo .IsDir () {
216- chmod = os .FileMode (c .config .ChmodDir )
217- }
218-
219- if err := os .Chmod (filepath , chmod ); err != nil {
220- return err
221- }
222-
223- if err := os .Chown (filepath , c .config .UID , c .config .GID ); err != nil {
224- return err
225- }
226-
227- return nil
228- }
229-
230251// Close closes grabber
231252func (c * Client ) Close () {
232253 if err := c .db .Close (); err != nil {
@@ -235,4 +256,7 @@ func (c *Client) Close() {
235256 if err := c .server .Close (); err != nil {
236257 log .Warn ().Err (err ).Msg ("Cannot close server connection" )
237258 }
259+ if err := os .RemoveAll (c .tempdir ); err != nil {
260+ log .Warn ().Err (err ).Msg ("Cannot remove temp folder" )
261+ }
238262}
0 commit comments