@@ -25,6 +25,7 @@ type Extract struct {
2525 Status ExtractStatus
2626 IDs map [string ]any
2727 Resp * xtractr.Response
28+ Progress * Progress
2829}
2930
3031// Shared config items for all starr apps.
@@ -73,11 +74,28 @@ func (u *Unpackerr) checkQueueChanges(now time.Time) {
7374 data .Updated = now
7475 }
7576
76- u .Printf ("[%s] Status: %s (%v, elapsed: %v)" , data .App , name , data .Status .Desc (),
77- now .Sub (data .Updated ).Round (time .Second ))
77+ u .Printf ("[%s] Status: %s (%v, elapsed: %v) %s " , data .App , name , data .Status .Desc (),
78+ now .Sub (data .Updated ).Round (time .Second ), data . Progress )
7879 }
7980}
8081
82+ func (p * Progress ) String () string {
83+ if p == nil {
84+ return ""
85+ }
86+
87+ var wrote , total uint64
88+
89+ if p .Total > 0 {
90+ wrote , total = p .Wrote , p .Total
91+ } else if p .Compressed > 0 {
92+ wrote , total = p .Read , p .Compressed
93+ }
94+
95+ return fmt .Sprintf ("archive %d/%d current: %d/%d bytes (%.0f)" ,
96+ p .Extracted + 1 , p .Archives , wrote , total , p .Percent ())
97+ }
98+
8199// extractCompletedDownloads process each download and checks if it needs to be extracted.
82100// This is called from the main go routine in start.go and it only processes starr apps, not folders.
83101func (u * Unpackerr ) extractCompletedDownloads (now time.Time ) {
@@ -126,18 +144,54 @@ func (u *Unpackerr) extractCompletedDownload(name string, now time.Time, item *E
126144 Name : name ,
127145 Filter : xtractr.Filter {
128146 Path : item .Path ,
129- ExcludeSuffix : xtractr .AllExcept ([] string {
147+ ExcludeSuffix : xtractr .AllExcept (
130148 ".rar" , ".r00" , ".zip" , ".7z" , ".7z.001" , ".gz" , ".tgz" , ".tar" , ".tar.gz" , ".bz2" , ".tbz2" ,
131- } ),
149+ ),
132150 },
133151 TempFolder : false ,
134152 DeleteOrig : false ,
135153 CBChannel : u .updates ,
154+ Updates : u .handleProgressUpdate (name ),
136155 })
137156
138157 u .logQueuedDownload (queueSize , item , files )
139158}
140159
160+ type Progress struct {
161+ xtractr.Progress
162+ // Name of this item in the Map.
163+ Name string
164+ // Number of archives in this Xtract.
165+ Archives int
166+ // Number of archives extracted from this Xtract.
167+ Extracted int
168+ }
169+
170+ func (u * Unpackerr ) handleProgressUpdate (name string ) chan xtractr.Progress {
171+ chn := make (chan xtractr.Progress )
172+ prog := & Progress {Name : name }
173+
174+ go func () {
175+ for p := range chn {
176+ if prog .Progress = p ; p .Done {
177+ prog .Extracted ++
178+ }
179+
180+ u .progress <- prog // ends up in u.handleProgress() (below)
181+ }
182+ }()
183+
184+ return chn
185+ }
186+
187+ func (u * Unpackerr ) handleProgress (prog * Progress ) {
188+ if item := u .Map [prog .Name ]; item != nil {
189+ if item .Progress = prog ; item .Resp != nil {
190+ prog .Archives = len (item .Resp .Archives )
191+ }
192+ }
193+ }
194+
141195func (u * Unpackerr ) logQueuedDownload (queueSize int , item * Extract , files xtractr.ArchiveList ) {
142196 count := fmt .Sprint ("1 archive: " , files .Random ()[0 ])
143197 if fileCount := files .Count (); fileCount > 1 {
@@ -206,6 +260,10 @@ func (u *Unpackerr) checkExtractDone(now time.Time) {
206260func (u * Unpackerr ) handleXtractrCallback (resp * xtractr.Response ) {
207261 if item := u .Map [resp .X .Name ]; resp .Done && item != nil {
208262 u .updateMetrics (resp , item .App , item .URL )
263+
264+ if item .Progress != nil {
265+ item .Progress .Archives = len (resp .Archives )
266+ }
209267 }
210268
211269 switch now := resp .Started .Add (resp .Elapsed ); {
@@ -218,6 +276,7 @@ func (u *Unpackerr) handleXtractrCallback(resp *xtractr.Response) {
218276 default :
219277 files := fileList (resp .X .Path )
220278
279+ close (resp .X .Updates )
221280 u .Printf ("Extraction Finished: %s => elapsed: %v, archives: %d, extra archives: %d, " +
222281 "files extracted: %d, wrote: %dMiB" , resp .X .Name , resp .Elapsed .Round (time .Second ),
223282 resp .Archives .Count (), resp .Extras .Count (), len (resp .NewFiles ), resp .Size / mebiByte )
0 commit comments