22package xt
33
44import (
5+ "fmt"
56 "log"
67 "os"
78 "path/filepath"
@@ -20,54 +21,69 @@ func Extract(job *Job) {
2021
2122 job .fixModes ()
2223
23- total := 0
24+ total := archives . Count ()
2425 count := 0
26+ size := int64 (0 )
27+ fCount := 0
28+ start := time .Now ()
2529
26- for _ , files := range archives {
27- total += len (files )
28- }
29-
30- for _ , files := range archives {
31- for _ , fileName := range files {
30+ for folder , files := range archives {
31+ for _ , archive := range files {
3232 count ++
33- log .Printf ("==> Extracting Archive (%d/%d): %s" , count , total , fileName )
34-
35- file := & xtractr.XFile {
36- FilePath : fileName , // Path to archive being extracted.
37- OutputDir : job .Output , // Folder to extract archive into.
38- FileMode : job .FileMode .Mode (), // Write files with this mode.
39- DirMode : job .DirMode .Mode (), // Write folders with this mode.
40- Passwords : job .Passwords , // (RAR/7zip) Archive password(s).
41- SquashRoot : job .SquashRoot , // Remove single root folder?
42- }
43-
44- file .SetLogger (job )
45-
46- start := time .Now ()
33+ log .Printf ("==> Extracting Archive (%d/%d): %s" , count , total , archive )
4734
48- // If preserving the file hierarchy, set the output directory to the
49- // folder of the archive being extracted.
50- if job .Preserve {
51- file .OutputDir = filepath .Dir (fileName )
52- }
53-
54- size , files , _ , err := xtractr .ExtractFile (file )
35+ output , fSize , files , duration , err := job .processArchive (folder , archive )
5536 if err != nil {
56- log .Printf ("[ERROR] Archive: %s: %v" , fileName , err )
57- continue
37+ log .Printf ("[ERROR] Extracting: %v" , err )
38+ } else {
39+ log .Printf ("==> Extracted Archive %s to %s in %v: bytes: %d, files: %d" ,
40+ archive , output , duration .Round (time .Millisecond ), fSize , len (files ))
5841 }
5942
60- log .Printf ("==> Extracted Archive %s in %v: bytes: %d, files: %d" ,
61- fileName , time .Since (start ).Round (time .Millisecond ), size , len (files ))
62-
63- if len (files ) > 0 {
43+ if len (files ) > 0 && job .Verbose {
6444 log .Printf ("==> Files:\n - %s" , strings .Join (files , "\n - " ))
6545 }
46+
47+ size += fSize
48+ fCount += len (files )
6649 }
6750 }
51+
52+ log .Printf ("==> Done." )
53+ log .Printf ("==> Extracted %d archives; wrote %d bytes into %d files in %v" ,
54+ total , size , fCount , time .Since (start ).Round (time .Millisecond ))
55+ }
56+
57+ func (j * Job ) processArchive (folder , archive string ) (string , int64 , []string , time.Duration , error ) {
58+ file := & xtractr.XFile {
59+ FilePath : archive , // Path to archive being extracted.
60+ OutputDir : j .Output , // Folder to extract archive into.
61+ FileMode : j .FileMode .Mode (), // Write files with this mode.
62+ DirMode : j .DirMode .Mode (), // Write folders with this mode.
63+ Passwords : j .Passwords , // (RAR/7zip) Archive password(s).
64+ SquashRoot : j .SquashRoot , // Remove single root folder?
65+ }
66+ file .SetLogger (j )
67+
68+ // If preserving the file hierarchy: set the output directory to the same path as the input file.
69+ if j .Preserve {
70+ // Remove input path prefix from fileName,
71+ // append fileName.Dir to job.Output,
72+ // extract file into job.Output/file(sub)Folder(s).
73+ file .OutputDir = filepath .Join (j .Output , filepath .Dir (strings .TrimPrefix (archive , folder )))
74+ }
75+
76+ start := time .Now ()
77+
78+ size , files , _ , err := xtractr .ExtractFile (file )
79+ if err != nil {
80+ err = fmt .Errorf ("archive: %s: %w" , archive , err )
81+ }
82+
83+ return file .OutputDir , size , files , time .Since (start ), err
6884}
6985
70- func (j * Job ) getArchives () map [ string ][] string {
86+ func (j * Job ) getArchives () xtractr. ArchiveList {
7187 archives := map [string ][]string {}
7288
7389 for _ , fileName := range j .Paths {
@@ -87,13 +103,14 @@ func (j *Job) getArchives() map[string][]string {
87103 exclude = xtractr .AllExcept (j .Include ... )
88104 }
89105
90- for folder , fileList := range xtractr .FindCompressedFiles (xtractr.Filter {
106+ for _ , fileList := range xtractr .FindCompressedFiles (xtractr.Filter {
91107 Path : fileName ,
92108 ExcludeSuffix : exclude ,
93109 MaxDepth : int (j .MaxDepth ),
94110 MinDepth : int (j .MinDepth ),
95111 }) {
96- archives [folder ] = fileList
112+ // Group archive lists by the parent search folder that found them.
113+ archives [fileName ] = append (archives [fileName ], fileList ... )
97114 }
98115 }
99116
0 commit comments