@@ -2,18 +2,12 @@ package main
22
33import (
44 "bufio"
5- "bytes"
6- "compressor/common"
5+ "compressor/platform"
76 "flag"
87 "fmt"
98 "github.com/fatih/color"
10- "image"
11- "image/jpeg"
12- _ "image/png"
13- "io/fs"
149 "log"
1510 "os"
16- "path/filepath"
1711 "strconv"
1812 "strings"
1913 "sync"
@@ -27,18 +21,17 @@ type Task struct {
2721}
2822
2923var (
30- id string // use unix timestamp as id
31- logger * log.Logger // global logger with color
32- fileLogger * log.Logger // global logger without color
33- config * Config // from json
34- failList []Task // gather all failed jobs for summary
24+ id string // use unix timestamp as id
25+ logger * log.Logger // global logger with color
26+ fileLogger * log.Logger // global logger without color
27+ config * platform. Config // from json
28+ failList []Task // gather all failed jobs for summary
3529)
3630
3731// runtime variable
3832var (
3933 total int // the number of images
4034 wg * sync.WaitGroup // thread limit
41- dirMutex * sync.Mutex // dir lock for creating file
4235 taskList []Task // task slice
4336 inCh chan Task // in-task channel
4437 outCh chan Task // out-task channel
@@ -63,9 +56,9 @@ func init() {
6356
6457 if * configPathPtr != "" {
6558 // parse config file
66- config = LoadConfig (* configPathPtr )
59+ config = platform . LoadConfig (* configPathPtr )
6760 } else {
68- config = & Config {
61+ config = & platform. Config {
6962 ThreadCount : * threadCountPtr ,
7063 InputFormat : strings .Split (* inputFormatPtr , " " ),
7164 InputPath : * inputPathPtr ,
@@ -75,11 +68,9 @@ func init() {
7568 }
7669 }
7770 // initialize logger
78- logger = common .GetLogger ()
71+ logger = platform .GetLogger ()
7972
80- ParseConfig (config )
81-
82- dirMutex = & sync.Mutex {}
73+ platform .ParseConfig (config )
8374 wg = & sync.WaitGroup {}
8475
8576 // initialize channel
@@ -88,119 +79,6 @@ func init() {
8879 failCh = make (chan Task , 1 )
8980}
9081
91- func travel () {
92- // find all images
93- err := filepath .WalkDir (config .InputPath , func (path string , d fs.DirEntry , e error ) error {
94- if e != nil {
95- logger .Println (color .RedString ("Walk Error:" ), path , e .Error ())
96- if config .LogToFile {
97- fileLogger .Println ("Walk Error:" , path , e .Error ())
98- }
99- return e
100- }
101- if ! d .IsDir () {
102- if ext := strings .ToLower (filepath .Ext (d .Name ()))[1 :]; config .isAccept (ext ) {
103- newPath := filepath .Join (config .OutputPath , filepath .Base (path ))
104- newPath = strings .TrimSuffix (newPath , filepath .Ext (newPath )) + OutputFormat
105- if err := os .MkdirAll (filepath .Dir (newPath ), 0755 ); err != nil {
106- logger .Println (color .RedString ("Create New Path Failed" ))
107- if config .LogToFile {
108- fileLogger .Println ("Create New Path Failed" )
109- }
110- return err
111- }
112- taskList = append (taskList , Task {Input : path , Output : newPath })
113- }
114- }
115- return nil
116- })
117- if err != nil {
118- panic (err .Error ())
119- }
120- total = len (taskList )
121- }
122-
123- func doTask (t * Task ) error {
124- file , err := os .Open (t .Input )
125- if err != nil {
126- return err
127- }
128-
129- filename , err := common .Touch (t .Output , dirMutex , MaxRenameRetry )
130- if err != nil {
131- return err
132- }
133- t .Output = filename
134-
135- img , _ , err := image .Decode (file )
136- if err != nil {
137- return err
138- }
139-
140- buf := new (bytes.Buffer )
141- err = jpeg .Encode (buf , img , config .jpegQuality )
142- if err != nil {
143- return err
144- }
145- t .Data = buf .Bytes ()
146- return nil
147- }
148-
149- // compress job, multiple goroutine
150- func compress () {
151- defer wg .Done ()
152- // get job from channel,
153- // channel inCh will be closed by sender
154- for t := range inCh {
155- // check if success
156- if err := doTask (& t ); err != nil {
157- // if failed, push to fail channel (multi-sender)
158- t .Data = []byte (err .Error ())
159- failCh <- t
160- continue
161- }
162- outCh <- t
163- }
164- }
165-
166- func writeToFiles () {
167- defer wg .Done ()
168- count := 0
169- for t := range outCh {
170- err := os .WriteFile (t .Output , t .Data , 0644 )
171- if err != nil {
172- t .Data = []byte (err .Error ())
173- failCh <- t
174- continue
175- }
176- count ++
177- logger .Println (color .GreenString (fmt .Sprintf ("(%d/%d)" , count , total )),
178- t .Input , color .GreenString ("->" ), t .Output )
179- if config .LogToFile {
180- fileLogger .Println (fmt .Sprintf ("(%d/%d)" , count , total ),
181- t .Input , "->" , t .Output )
182- }
183- }
184- }
185-
186- // transfer
187- // when process finished, failCh will be closed
188- func transferFailList () {
189- defer wg .Done ()
190- for t := range failCh {
191- failList = append (failList , t )
192- }
193- }
194-
195- // transfer
196- // close the channel cuz this is the only sender
197- func transferTaskList () {
198- defer close (inCh )
199- for t := range taskList {
200- inCh <- taskList [t ]
201- }
202- }
203-
20482func process () {
20583 // confirm tasks
20684 logger .Println (color .GreenString ("Input Path:" ), config .InputPath )
@@ -229,7 +107,7 @@ func process() {
229107 }
230108
231109 if config .LogToFile {
232- fileLogger = common .GetFileLogger (id )
110+ fileLogger = platform .GetFileLogger (id )
233111 fileLogger .Println ("Input Path:" , config .InputPath )
234112 fileLogger .Println ("Output Path:" , config .OutputPath )
235113 fileLogger .Println ("Thread Count:" , strconv .Itoa (config .ThreadCount ))
@@ -311,7 +189,7 @@ func main() {
311189
312190func usage () {
313191 _ , _ = fmt .Fprintf (os .Stderr ,
314- `Version: 2.3
192+ `Version: 2.4
315193Usage: compressor [-h] [Options]
316194
317195Options:
0 commit comments