From 113e7ebcb099774f6b2d80d807680a787dd3ff14 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Fri, 10 May 2024 14:08:16 +0200 Subject: [PATCH 01/13] update deps --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 893f94f..d3f09c8 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/raff/pdfreader v0.0.0-20220308062436-033e8ac577f0 github.com/schollz/progressbar/v3 v3.14.2 github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e - golang.org/x/image v0.15.0 + golang.org/x/image v0.16.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -23,7 +23,7 @@ require ( github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect ) diff --git a/go.sum b/go.sum index e443d1d..bbdb40d 100644 --- a/go.sum +++ b/go.sum @@ -39,17 +39,17 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= -golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= -golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 5c7775cd47467292870519ce3956f82cf68a3058 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Fri, 10 May 2024 18:05:51 +0200 Subject: [PATCH 02/13] simplify profiles --- .../converter/options/converter_options.go | 2 +- .../converter/profiles/converter_profiles.go | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/internal/converter/options/converter_options.go b/internal/converter/options/converter_options.go index ec29fb4..f39cea3 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/converter/options/converter_options.go @@ -330,7 +330,7 @@ func (o *Options) SaveConfig() error { // GetProfile shortcut to get current profile func (o *Options) GetProfile() *profiles.Profile { - return o.profiles.Get(o.Profile) + return o.profiles[o.Profile] } // AvailableProfiles all available profiles diff --git a/internal/converter/profiles/converter_profiles.go b/internal/converter/profiles/converter_profiles.go index 139459e..df404ac 100644 --- a/internal/converter/profiles/converter_profiles.go +++ b/internal/converter/profiles/converter_profiles.go @@ -13,11 +13,12 @@ type Profile struct { Height int `json:"height"` } -type Profiles []Profile +type Profiles map[string]*Profile // New Initialize list of all supported profiles. func New() Profiles { - return []Profile{ + res := make(Profiles) + for _, r := range []Profile{ // High Resolution for Tablet {"HR", "High Resolution", 2400, 3840}, {"SR", "Standard Resolution", 1200, 1920}, @@ -50,7 +51,10 @@ func New() Profiles { // reMarkable {"RM1", "reMarkable 1", 1404, 1872}, {"RM2", "reMarkable 2", 1404, 1872}, + } { + res[r.Code] = &r } + return res } func (p Profiles) String() string { @@ -65,13 +69,3 @@ func (p Profiles) String() string { } return strings.Join(s, "\n") } - -// Get Lookup profile by code -func (p Profiles) Get(name string) *Profile { - for _, profile := range p { - if profile.Code == name { - return &profile - } - } - return nil -} From e10eeadc4e193353d5711bfb1d067890c6117cd7 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Fri, 10 May 2024 18:10:07 +0200 Subject: [PATCH 03/13] remove pointer from image options --- internal/epub/options/epub_options.go | 10 +++++----- internal/epub/templates/epub_templates_content.go | 2 +- main.go | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go index 2d2367a..d41a499 100644 --- a/internal/epub/options/epub_options.go +++ b/internal/epub/options/epub_options.go @@ -22,7 +22,7 @@ type View struct { } type Image struct { - Crop *Crop + Crop Crop Quality int Brightness int Contrast int @@ -34,7 +34,7 @@ type Image struct { NoBlankImage bool Manga bool HasCover bool - View *View + View View GrayScale bool GrayScaleMode int Resize bool @@ -56,10 +56,10 @@ type Options struct { Quiet bool Json bool Workers int - Image *Image + Image Image } -func (o *Options) WorkersRatio(pct int) (nbWorkers int) { +func (o Options) WorkersRatio(pct int) (nbWorkers int) { nbWorkers = o.Workers * pct / 100 if nbWorkers < 1 { nbWorkers = 1 @@ -67,6 +67,6 @@ func (o *Options) WorkersRatio(pct int) (nbWorkers int) { return } -func (o *Options) ImgStorage() string { +func (o Options) ImgStorage() string { return fmt.Sprintf("%s.tmp", o.Output) } diff --git a/internal/epub/templates/epub_templates_content.go b/internal/epub/templates/epub_templates_content.go index 7b3a662..1544806 100644 --- a/internal/epub/templates/epub_templates_content.go +++ b/internal/epub/templates/epub_templates_content.go @@ -16,7 +16,7 @@ type ContentOptions struct { Author string Publisher string UpdatedAt string - ImageOptions *epuboptions.Image + ImageOptions epuboptions.Image Cover *epubimage.Image Images []*epubimage.Image Current int diff --git a/main.go b/main.go index 23c238d..e26c226 100644 --- a/main.go +++ b/main.go @@ -124,8 +124,8 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s DryVerbose: cmd.Options.DryVerbose, Quiet: cmd.Options.Quiet, Json: cmd.Options.Json, - Image: &epuboptions.Image{ - Crop: &epuboptions.Crop{ + Image: epuboptions.Image{ + Crop: epuboptions.Crop{ Enabled: cmd.Options.Crop, Left: cmd.Options.CropRatioLeft, Up: cmd.Options.CropRatioUp, @@ -145,7 +145,7 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s NoBlankImage: cmd.Options.NoBlankImage, Manga: cmd.Options.Manga, HasCover: cmd.Options.HasCover, - View: &epuboptions.View{ + View: epuboptions.View{ Width: profile.Width, Height: profile.Height, AspectRatio: cmd.Options.AspectRatio, From b1e246240c7c90659c4725fe076f9a9026f5ce35 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:25:20 +0200 Subject: [PATCH 04/13] remove pointer from profiles --- internal/converter/options/converter_options.go | 5 ++++- internal/converter/profiles/converter_profiles.go | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/converter/options/converter_options.go b/internal/converter/options/converter_options.go index f39cea3..b7a91df 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/converter/options/converter_options.go @@ -330,7 +330,10 @@ func (o *Options) SaveConfig() error { // GetProfile shortcut to get current profile func (o *Options) GetProfile() *profiles.Profile { - return o.profiles[o.Profile] + if p, ok := o.profiles[o.Profile]; ok { + return &p + } + return nil } // AvailableProfiles all available profiles diff --git a/internal/converter/profiles/converter_profiles.go b/internal/converter/profiles/converter_profiles.go index df404ac..e6d1357 100644 --- a/internal/converter/profiles/converter_profiles.go +++ b/internal/converter/profiles/converter_profiles.go @@ -13,7 +13,7 @@ type Profile struct { Height int `json:"height"` } -type Profiles map[string]*Profile +type Profiles map[string]Profile // New Initialize list of all supported profiles. func New() Profiles { @@ -52,7 +52,7 @@ func New() Profiles { {"RM1", "reMarkable 1", 1404, 1872}, {"RM2", "reMarkable 2", 1404, 1872}, } { - res[r.Code] = &r + res[r.Code] = r } return res } From 5404390fd803b7da27c8ce07c4b5bb01771d542d Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:25:52 +0200 Subject: [PATCH 05/13] remove pointer from epub image --- internal/epub/image/epub_image.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/epub/image/epub_image.go b/internal/epub/image/epub_image.go index 8c3a2ed..1578ceb 100644 --- a/internal/epub/image/epub_image.go +++ b/internal/epub/image/epub_image.go @@ -24,47 +24,47 @@ type Image struct { } // SpaceKey key name of the blank page after the image -func (i *Image) SpaceKey() string { +func (i Image) SpaceKey() string { return fmt.Sprintf("space_%d", i.Id) } // SpacePath path of the blank page -func (i *Image) SpacePath() string { +func (i Image) SpacePath() string { return fmt.Sprintf("Text/%s.xhtml", i.SpaceKey()) } // EPUBSpacePath path of the blank page into the EPUB -func (i *Image) EPUBSpacePath() string { +func (i Image) EPUBSpacePath() string { return fmt.Sprintf("OEBPS/%s", i.SpacePath()) } // PageKey key for page -func (i *Image) PageKey() string { +func (i Image) PageKey() string { return fmt.Sprintf("page_%d_p%d", i.Id, i.Part) } // PagePath page path linked to the image -func (i *Image) PagePath() string { +func (i Image) PagePath() string { return fmt.Sprintf("Text/%s.xhtml", i.PageKey()) } // EPUBPagePath page path into the EPUB -func (i *Image) EPUBPagePath() string { +func (i Image) EPUBPagePath() string { return fmt.Sprintf("OEBPS/%s", i.PagePath()) } // ImgKey key for image -func (i *Image) ImgKey() string { +func (i Image) ImgKey() string { return fmt.Sprintf("img_%d_p%d", i.Id, i.Part) } // ImgPath image path -func (i *Image) ImgPath() string { +func (i Image) ImgPath() string { return fmt.Sprintf("Images/%s.%s", i.ImgKey(), i.Format) } // EPUBImgPath image path into the EPUB -func (i *Image) EPUBImgPath() string { +func (i Image) EPUBImgPath() string { return fmt.Sprintf("OEBPS/%s", i.ImgPath()) } @@ -72,7 +72,7 @@ func (i *Image) EPUBImgPath() string { // // center by default. // align to left or right if it's part of the split double page. -func (i *Image) ImgStyle(viewWidth, viewHeight int, align string) string { +func (i Image) ImgStyle(viewWidth, viewHeight int, align string) string { relWidth, relHeight := i.RelSize(viewWidth, viewHeight) marginW, marginH := float64(viewWidth-relWidth)/2, float64(viewHeight-relHeight)/2 @@ -97,7 +97,7 @@ func (i *Image) ImgStyle(viewWidth, viewHeight int, align string) string { return strings.Join(style, "; ") } -func (i *Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { +func (i Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { w, h := viewWidth, viewHeight srcw, srch := i.Width, i.Height From a94e67dd06bc4c8c90014b01f0d1e14b485a1a06 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:26:04 +0200 Subject: [PATCH 06/13] remove pointer from epub filters --- .../imagefilters/epub_image_filters_autocontrast.go | 12 ++++++------ .../imagefilters/epub_image_filters_cover_title.go | 6 +++--- .../epub_image_filters_crop_split_double_page.go | 6 +++--- .../epub/imagefilters/epub_image_filters_pixel.go | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/internal/epub/imagefilters/epub_image_filters_autocontrast.go b/internal/epub/imagefilters/epub_image_filters_autocontrast.go index 0a9a490..44dbe75 100644 --- a/internal/epub/imagefilters/epub_image_filters_autocontrast.go +++ b/internal/epub/imagefilters/epub_image_filters_autocontrast.go @@ -10,14 +10,14 @@ import ( // AutoContrast Automatically improve contrast func AutoContrast() gift.Filter { - return &autocontrast{} + return autocontrast{} } type autocontrast struct { } // compute the color number between 0 and 1 that hold half of the pixel -func (f *autocontrast) mean(src image.Image) float32 { +func (f autocontrast) mean(src image.Image) float32 { bucket := map[int]int{} for x := src.Bounds().Min.X; x < src.Bounds().Max.X; x++ { for y := src.Bounds().Min.Y; y < src.Bounds().Max.Y; y++ { @@ -44,7 +44,7 @@ func (f *autocontrast) mean(src image.Image) float32 { } // ensure value stay into 0 to 1 bound -func (f *autocontrast) cap(v float32) float32 { +func (f autocontrast) cap(v float32) float32 { if v < 0 { return 0 } @@ -55,12 +55,12 @@ func (f *autocontrast) cap(v float32) float32 { } // power of 2 for float32 -func (f *autocontrast) pow2(v float32) float32 { +func (f autocontrast) pow2(v float32) float32 { return v * v } // Draw into the dst after applying the filter -func (f *autocontrast) Draw(dst draw.Image, src image.Image, options *gift.Options) { +func (f autocontrast) Draw(dst draw.Image, src image.Image, options *gift.Options) { // half of the pixel has this color idx colorMean := f.mean(src) @@ -84,7 +84,7 @@ func (f *autocontrast) Draw(dst draw.Image, src image.Image, options *gift.Optio } // Bounds calculates the appropriate bounds of an image after applying the filter. -func (*autocontrast) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { +func (autocontrast) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = srcBounds return } diff --git a/internal/epub/imagefilters/epub_image_filters_cover_title.go b/internal/epub/imagefilters/epub_image_filters_cover_title.go index 7692e91..0d96c5f 100644 --- a/internal/epub/imagefilters/epub_image_filters_cover_title.go +++ b/internal/epub/imagefilters/epub_image_filters_cover_title.go @@ -13,7 +13,7 @@ import ( // CoverTitle Create a title with the cover image func CoverTitle(title string, align string, pctWidth int, pctMargin int, maxFontSize int, borderSize int) gift.Filter { - return &coverTitle{title, align, pctWidth, pctMargin, maxFontSize, borderSize} + return coverTitle{title, align, pctWidth, pctMargin, maxFontSize, borderSize} } type coverTitle struct { @@ -26,12 +26,12 @@ type coverTitle struct { } // Bounds size is the same as source -func (p *coverTitle) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { +func (p coverTitle) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { return srcBounds } // Draw blur the src image, and create a box with the title in the middle -func (p *coverTitle) Draw(dst draw.Image, src image.Image, _ *gift.Options) { +func (p coverTitle) Draw(dst draw.Image, src image.Image, _ *gift.Options) { draw.Draw(dst, dst.Bounds(), src, src.Bounds().Min, draw.Src) if p.title == "" { return diff --git a/internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go b/internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go index 2eb7d65..38dade4 100644 --- a/internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go +++ b/internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go @@ -11,14 +11,14 @@ import ( // // This will cut in the middle of the page. func CropSplitDoublePage(right bool) gift.Filter { - return &cropSplitDoublePage{right} + return cropSplitDoublePage{right} } type cropSplitDoublePage struct { right bool } -func (p *cropSplitDoublePage) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { +func (p cropSplitDoublePage) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { if p.right { dstBounds = image.Rect( srcBounds.Max.X/2, srcBounds.Min.Y, @@ -33,6 +33,6 @@ func (p *cropSplitDoublePage) Bounds(srcBounds image.Rectangle) (dstBounds image return } -func (p *cropSplitDoublePage) Draw(dst draw.Image, src image.Image, options *gift.Options) { +func (p cropSplitDoublePage) Draw(dst draw.Image, src image.Image, options *gift.Options) { gift.Crop(dst.Bounds()).Draw(dst, src, options) } diff --git a/internal/epub/imagefilters/epub_image_filters_pixel.go b/internal/epub/imagefilters/epub_image_filters_pixel.go index 97e20fd..376bbc0 100644 --- a/internal/epub/imagefilters/epub_image_filters_pixel.go +++ b/internal/epub/imagefilters/epub_image_filters_pixel.go @@ -12,13 +12,13 @@ import ( // // An image 0x0 is not a valid image, and failed to read. func Pixel() gift.Filter { - return &pixel{} + return pixel{} } type pixel struct { } -func (p *pixel) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { +func (p pixel) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { if srcBounds.Dx() == 0 || srcBounds.Dy() == 0 { dstBounds = image.Rect(0, 0, 1, 1) } else { @@ -27,7 +27,7 @@ func (p *pixel) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { return } -func (p *pixel) Draw(dst draw.Image, src image.Image, _ *gift.Options) { +func (p pixel) Draw(dst draw.Image, src image.Image, _ *gift.Options) { if dst.Bounds().Dx() == 1 && dst.Bounds().Dy() == 1 { dst.Set(0, 0, color.White) return From 3d31108aba0bcf680d34176b22fd33fb9c407d6d Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:26:51 +0200 Subject: [PATCH 07/13] remove pointer from epub zip --- internal/epub/zip/epub_zip.go | 20 ++++++------- internal/epub/zip/epub_zip_image.go | 12 ++++---- internal/epub/zip/epub_zip_storage_image.go | 31 ++++++++++----------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/internal/epub/zip/epub_zip.go b/internal/epub/zip/epub_zip.go index 5c32b33..3dd054f 100644 --- a/internal/epub/zip/epub_zip.go +++ b/internal/epub/zip/epub_zip.go @@ -17,17 +17,17 @@ type EPUBZip struct { } // New create a new EPUB -func New(path string) (*EPUBZip, error) { +func New(path string) (EPUBZip, error) { w, err := os.Create(path) if err != nil { - return nil, err + return EPUBZip{}, err } wz := zip.NewWriter(w) - return &EPUBZip{w, wz}, nil + return EPUBZip{w, wz}, nil } // Close compress pipe and file. -func (e *EPUBZip) Close() error { +func (e EPUBZip) Close() error { if err := e.wz.Close(); err != nil { return err } @@ -37,10 +37,10 @@ func (e *EPUBZip) Close() error { // WriteMagic Write mimetype, in a very specific way. // // This will be valid with epubcheck tools. -func (e *EPUBZip) WriteMagic() error { +func (e EPUBZip) WriteMagic() error { t := time.Now().UTC() //goland:noinspection GoDeprecation - fh := &zip.FileHeader{ + fh := zip.FileHeader{ Name: "mimetype", Method: zip.Store, Modified: t, @@ -53,7 +53,7 @@ func (e *EPUBZip) WriteMagic() error { fh.CreatorVersion = fh.CreatorVersion&0xff00 | 20 // preserve compatibility byte fh.ReaderVersion = 20 fh.SetMode(0600) - m, err := e.wz.CreateRaw(fh) + m, err := e.wz.CreateRaw(&fh) if err != nil { return err @@ -62,12 +62,12 @@ func (e *EPUBZip) WriteMagic() error { return err } -func (e *EPUBZip) Copy(fz *zip.File) error { +func (e EPUBZip) Copy(fz *zip.File) error { return e.wz.Copy(fz) } // WriteRaw Write image. They are already compressed, so we write them down directly. -func (e *EPUBZip) WriteRaw(raw *ZipImage) error { +func (e EPUBZip) WriteRaw(raw ZipImage) error { m, err := e.wz.CreateRaw(raw.Header) if err != nil { return err @@ -77,7 +77,7 @@ func (e *EPUBZip) WriteRaw(raw *ZipImage) error { } // WriteContent Write file. Compressed it using deflate. -func (e *EPUBZip) WriteContent(file string, content []byte) error { +func (e EPUBZip) WriteContent(file string, content []byte) error { m, err := e.wz.CreateHeader(&zip.FileHeader{ Name: file, Modified: time.Now(), diff --git a/internal/epub/zip/epub_zip_image.go b/internal/epub/zip/epub_zip_image.go index 060cb86..5df69ae 100644 --- a/internal/epub/zip/epub_zip_image.go +++ b/internal/epub/zip/epub_zip_image.go @@ -18,7 +18,7 @@ type ZipImage struct { } // CompressImage create gzip encoded jpeg -func CompressImage(filename string, format string, img image.Image, quality int) (*ZipImage, error) { +func CompressImage(filename string, format string, img image.Image, quality int) (ZipImage, error) { var ( data, cdata bytes.Buffer err error @@ -33,27 +33,27 @@ func CompressImage(filename string, format string, img image.Image, quality int) err = fmt.Errorf("unknown format %q", format) } if err != nil { - return nil, err + return ZipImage{}, err } wcdata, err := flate.NewWriter(&cdata, flate.BestCompression) if err != nil { - return nil, err + return ZipImage{}, err } _, err = wcdata.Write(data.Bytes()) if err != nil { - return nil, err + return ZipImage{}, err } err = wcdata.Close() if err != nil { - return nil, err + return ZipImage{}, err } t := time.Now() //goland:noinspection GoDeprecation - return &ZipImage{ + return ZipImage{ &zip.FileHeader{ Name: filename, CompressedSize64: uint64(cdata.Len()), diff --git a/internal/epub/zip/epub_zip_storage_image.go b/internal/epub/zip/epub_zip_storage_image.go index dd918cd..f08f7d8 100644 --- a/internal/epub/zip/epub_zip_storage_image.go +++ b/internal/epub/zip/epub_zip_storage_image.go @@ -14,16 +14,16 @@ type StorageImageWriter struct { mut *sync.Mutex } -func NewStorageImageWriter(filename string, format string) (*StorageImageWriter, error) { +func NewStorageImageWriter(filename string, format string) (StorageImageWriter, error) { fh, err := os.Create(filename) if err != nil { - return nil, err + return StorageImageWriter{}, err } fz := zip.NewWriter(fh) - return &StorageImageWriter{fh, fz, format, &sync.Mutex{}}, nil + return StorageImageWriter{fh, fz, format, &sync.Mutex{}}, nil } -func (e *StorageImageWriter) Close() error { +func (e StorageImageWriter) Close() error { if err := e.fz.Close(); err != nil { _ = e.fh.Close() return err @@ -31,7 +31,7 @@ func (e *StorageImageWriter) Close() error { return e.fh.Close() } -func (e *StorageImageWriter) Add(filename string, img image.Image, quality int) error { +func (e StorageImageWriter) Add(filename string, img image.Image, quality int) error { zipImage, err := CompressImage(filename, e.format, img, quality) if err != nil { return err @@ -59,42 +59,41 @@ type StorageImageReader struct { files map[string]*zip.File } -func NewStorageImageReader(filename string) (*StorageImageReader, error) { +func NewStorageImageReader(filename string) (StorageImageReader, error) { fh, err := os.Open(filename) if err != nil { - return nil, err + return StorageImageReader{}, err } s, err := fh.Stat() if err != nil { - return nil, err + return StorageImageReader{}, err } fz, err := zip.NewReader(fh, s.Size()) if err != nil { - return nil, err + return StorageImageReader{}, err } files := map[string]*zip.File{} for _, z := range fz.File { files[z.Name] = z } - return &StorageImageReader{filename, fh, fz, files}, nil + return StorageImageReader{filename, fh, fz, files}, nil } -func (e *StorageImageReader) Get(filename string) *zip.File { +func (e StorageImageReader) Get(filename string) *zip.File { return e.files[filename] } -func (e *StorageImageReader) Size(filename string) uint64 { - img := e.Get(filename) - if img != nil { +func (e StorageImageReader) Size(filename string) uint64 { + if img, ok := e.files[filename]; ok { return img.CompressedSize64 + 30 + uint64(len(img.Name)) } return 0 } -func (e *StorageImageReader) Close() error { +func (e StorageImageReader) Close() error { return e.fh.Close() } -func (e *StorageImageReader) Remove() error { +func (e StorageImageReader) Remove() error { return os.Remove(e.filename) } From a351106eb72d6450242907ab05afdff6c125885b Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:26:59 +0200 Subject: [PATCH 08/13] remove pointer from epub template --- .../epub/templates/epub_templates_content.go | 36 +++++++++---------- internal/epub/templates/epub_templates_toc.go | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/internal/epub/templates/epub_templates_content.go b/internal/epub/templates/epub_templates_content.go index 1544806..5c46d98 100644 --- a/internal/epub/templates/epub_templates_content.go +++ b/internal/epub/templates/epub_templates_content.go @@ -9,7 +9,7 @@ import ( epuboptions "github.com/celogeek/go-comic-converter/v2/internal/epub/options" ) -type ContentOptions struct { +type Content struct { Title string HasTitlePage bool UID string @@ -17,8 +17,8 @@ type ContentOptions struct { Publisher string UpdatedAt string ImageOptions epuboptions.Image - Cover *epubimage.Image - Images []*epubimage.Image + Cover epubimage.Image + Images []epubimage.Image Current int Total int } @@ -31,10 +31,10 @@ type tag struct { value string } -// Content create the content file +// Get create the content file // //goland:noinspection HttpUrlsUsage,HttpUrlsUsage,HttpUrlsUsage,HttpUrlsUsage -func Content(o *ContentOptions) string { +func (o Content) String() string { doc := etree.NewDocument() doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) @@ -44,8 +44,8 @@ func Content(o *ContentOptions) string { pkg.CreateAttr("version", "3.0") pkg.CreateAttr("prefix", "rendition: http://www.idpf.org/vocab/rendition/#") - addToElement := func(elm *etree.Element, meth func(o *ContentOptions) []tag) { - for _, p := range meth(o) { + addToElement := func(elm *etree.Element, meth func() []tag) { + for _, p := range meth() { meta := elm.CreateElement(p.name) for k, v := range p.attrs { meta.CreateAttr(k, v) @@ -60,10 +60,10 @@ func Content(o *ContentOptions) string { metadata := pkg.CreateElement("metadata") metadata.CreateAttr("xmlns:dc", "http://purl.org/dc/elements/1.1/") metadata.CreateAttr("xmlns:opf", "http://www.idpf.org/2007/opf") - addToElement(metadata, getMeta) + addToElement(metadata, o.getMeta) manifest := pkg.CreateElement("manifest") - addToElement(manifest, getManifest) + addToElement(manifest, o.getManifest) spine := pkg.CreateElement("spine") if o.ImageOptions.Manga { @@ -73,13 +73,13 @@ func Content(o *ContentOptions) string { } if o.ImageOptions.View.PortraitOnly { - addToElement(spine, getSpinePortrait) + addToElement(spine, o.getSpinePortrait) } else { - addToElement(spine, getSpineAuto) + addToElement(spine, o.getSpineAuto) } guide := pkg.CreateElement("guide") - addToElement(guide, getGuide) + addToElement(guide, o.getGuide) doc.Indent(2) r, _ := doc.WriteToString() @@ -88,7 +88,7 @@ func Content(o *ContentOptions) string { } // metadata part of the content -func getMeta(o *ContentOptions) []tag { +func (o Content) getMeta() []tag { metas := []tag{ {"meta", tagAttrs{"property": "dcterms:modified"}, o.UpdatedAt}, {"meta", tagAttrs{"property": "schema:accessMode"}, "visual"}, @@ -141,9 +141,9 @@ func getMeta(o *ContentOptions) []tag { return metas } -func getManifest(o *ContentOptions) []tag { +func (o Content) getManifest() []tag { var imageTags, pageTags, spaceTags []tag - addTag := func(img *epubimage.Image, withSpace bool) { + addTag := func(img epubimage.Image, withSpace bool) { imageTags = append(imageTags, tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""}, ) @@ -193,7 +193,7 @@ func getManifest(o *ContentOptions) []tag { } // spine part of the content -func getSpineAuto(o *ContentOptions) []tag { +func (o Content) getSpineAuto() []tag { isOnTheRight := !o.ImageOptions.Manga if o.ImageOptions.AppleBookCompatibility { isOnTheRight = !isOnTheRight @@ -255,7 +255,7 @@ func getSpineAuto(o *ContentOptions) []tag { return spine } -func getSpinePortrait(o *ContentOptions) []tag { +func (o Content) getSpinePortrait() []tag { var spine []tag if o.HasTitlePage { spine = append(spine, @@ -273,7 +273,7 @@ func getSpinePortrait(o *ContentOptions) []tag { } // getGuide Section guide of the content -func getGuide(o *ContentOptions) []tag { +func (o Content) getGuide() []tag { return []tag{ {"reference", tagAttrs{"type": "cover", "title": "cover", "href": "Text/cover.xhtml"}, ""}, {"reference", tagAttrs{"type": "text", "title": "content", "href": o.Images[0].PagePath()}, ""}, diff --git a/internal/epub/templates/epub_templates_toc.go b/internal/epub/templates/epub_templates_toc.go index 9df2766..ac5d625 100644 --- a/internal/epub/templates/epub_templates_toc.go +++ b/internal/epub/templates/epub_templates_toc.go @@ -12,7 +12,7 @@ import ( // Toc create toc // //goland:noinspection HttpUrlsUsage -func Toc(title string, hasTitle bool, stripFirstDirectoryFromToc bool, images []*epubimage.Image) string { +func Toc(title string, hasTitle bool, stripFirstDirectoryFromToc bool, images []epubimage.Image) string { doc := etree.NewDocument() doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) doc.CreateDirective("DOCTYPE html") From 3c582ae52dcda5865d9423a73348b3b61ec72a8f Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:27:09 +0200 Subject: [PATCH 09/13] remove pointer from epub processor --- .../imageprocessor/epub_image_processor.go | 24 +++++----- .../epub_image_processor_loader.go | 44 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/internal/epub/imageprocessor/epub_image_processor.go b/internal/epub/imageprocessor/epub_image_processor.go index 2a5f098..c2cad84 100644 --- a/internal/epub/imageprocessor/epub_image_processor.go +++ b/internal/epub/imageprocessor/epub_image_processor.go @@ -20,16 +20,16 @@ import ( ) type EPUBImageProcessor struct { - *epuboptions.Options + epuboptions.Options } -func New(o *epuboptions.Options) *EPUBImageProcessor { - return &EPUBImageProcessor{o} +func New(o epuboptions.Options) EPUBImageProcessor { + return EPUBImageProcessor{o} } // Load extract and convert images -func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) { - images = make([]*epubimage.Image, 0) +func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { + images = make([]epubimage.Image, 0) imageCount, imageInput, err := e.load() if err != nil { return nil, err @@ -38,7 +38,7 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) { // dry run, skip conversion if e.Dry { for img := range imageInput { - images = append(images, &epubimage.Image{ + images = append(images, epubimage.Image{ Id: img.Id, Path: img.Path, Name: img.Name, @@ -49,7 +49,7 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) { return images, nil } - imageOutput := make(chan *epubimage.Image) + imageOutput := make(chan epubimage.Image) // processing bar := epubprogress.New(epubprogress.Options{ @@ -140,7 +140,7 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) { return images, nil } -func (e *EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw.Image { +func (e EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw.Image { if e.Options.Image.GrayScale { return image.NewGray(r) } @@ -173,7 +173,7 @@ func (e *EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) dra // transform image into 1 or 3 images // only doublepage with autosplit has 3 versions -func (e *EPUBImageProcessor) transformImage(input *task, part int, right bool) *epubimage.Image { +func (e EPUBImageProcessor) transformImage(input task, part int, right bool) epubimage.Image { g := gift.New() src := input.Image srcBounds := src.Bounds() @@ -262,7 +262,7 @@ func (e *EPUBImageProcessor) transformImage(input *task, part int, right bool) * dst := e.createImage(src, g.Bounds(src.Bounds())) g.Draw(dst, src) - return &epubimage.Image{ + return epubimage.Image{ Id: input.Id, Part: part, Raw: dst, @@ -290,7 +290,7 @@ type CoverTitleDataOptions struct { BorderSize int } -func (e *EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Image { +func (e EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Image { return image.NewPaletted(bounds, color.Palette{ color.Gray{}, color.Gray{Y: 0x11}, @@ -312,7 +312,7 @@ func (e *EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Ima } // CoverTitleData create a title page with the cover -func (e *EPUBImageProcessor) CoverTitleData(o *CoverTitleDataOptions) (*epubzip.ZipImage, error) { +func (e EPUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.ZipImage, error) { // Create a blur version of the cover g := gift.New(epubimagefilters.CoverTitle(o.Text, o.Align, o.PctWidth, o.PctMargin, o.MaxFontSize, o.BorderSize)) var dst draw.Image diff --git a/internal/epub/imageprocessor/epub_image_processor_loader.go b/internal/epub/imageprocessor/epub_image_processor_loader.go index c77241d..d34c828 100644 --- a/internal/epub/imageprocessor/epub_image_processor_loader.go +++ b/internal/epub/imageprocessor/epub_image_processor_loader.go @@ -42,7 +42,7 @@ type task struct { var errNoImagesFound = errors.New("no images found") // only accept jpg, png and webp as source file -func (e *EPUBImageProcessor) isSupportedImage(path string) bool { +func (e EPUBImageProcessor) isSupportedImage(path string) bool { switch strings.ToLower(filepath.Ext(path)) { case ".jpg", ".jpeg", ".png", ".webp", ".tiff": { @@ -53,7 +53,7 @@ func (e *EPUBImageProcessor) isSupportedImage(path string) bool { } // Load images from input -func (e *EPUBImageProcessor) load() (totalImages int, output chan *task, err error) { +func (e EPUBImageProcessor) load() (totalImages int, output chan task, err error) { fi, err := os.Stat(e.Input) if err != nil { return @@ -77,7 +77,7 @@ func (e *EPUBImageProcessor) load() (totalImages int, output chan *task, err err } } -func (e *EPUBImageProcessor) corruptedImage(path, name string) image.Image { +func (e EPUBImageProcessor) corruptedImage(path, name string) image.Image { var w, h float64 = 1200, 1920 f, _ := truetype.Parse(gomonobold.TTF) face := truetype.NewFace(f, &truetype.Options{Size: 64, DPI: 72}) @@ -101,7 +101,7 @@ func (e *EPUBImageProcessor) corruptedImage(path, name string) image.Image { } // load a directory of images -func (e *EPUBImageProcessor) loadDir() (totalImages int, output chan *task, err error) { +func (e EPUBImageProcessor) loadDir() (totalImages int, output chan task, err error) { images := make([]string, 0) input := filepath.Clean(e.Input) @@ -133,16 +133,16 @@ func (e *EPUBImageProcessor) loadDir() (totalImages int, output chan *task, err Id int Path string } - jobs := make(chan *job) + jobs := make(chan job) go func() { defer close(jobs) for i, path := range images { - jobs <- &job{i, path} + jobs <- job{i, path} } }() // read in parallel and get an image - output = make(chan *task, e.Workers) + output = make(chan task, e.Workers) wg := &sync.WaitGroup{} for range e.WorkersRatio(50) { wg.Add(1) @@ -169,7 +169,7 @@ func (e *EPUBImageProcessor) loadDir() (totalImages int, output chan *task, err if err != nil { img = e.corruptedImage(p, fn) } - output <- &task{ + output <- task{ Id: job.Id, Image: img, Path: p, @@ -190,7 +190,7 @@ func (e *EPUBImageProcessor) loadDir() (totalImages int, output chan *task, err } // load a zip file that include images -func (e *EPUBImageProcessor) loadCbz() (totalImages int, output chan *task, err error) { +func (e EPUBImageProcessor) loadCbz() (totalImages int, output chan task, err error) { r, err := zip.OpenReader(e.Input) if err != nil { return @@ -226,15 +226,15 @@ func (e *EPUBImageProcessor) loadCbz() (totalImages int, output chan *task, err Id int F *zip.File } - jobs := make(chan *job) + jobs := make(chan job) go func() { defer close(jobs) for _, img := range images { - jobs <- &job{indexedNames[img.Name], img} + jobs <- job{indexedNames[img.Name], img} } }() - output = make(chan *task, e.Workers) + output = make(chan task, e.Workers) wg := &sync.WaitGroup{} for range e.WorkersRatio(50) { wg.Add(1) @@ -256,7 +256,7 @@ func (e *EPUBImageProcessor) loadCbz() (totalImages int, output chan *task, err if err != nil { img = e.corruptedImage(p, fn) } - output <- &task{ + output <- task{ Id: job.Id, Image: img, Path: p, @@ -276,7 +276,7 @@ func (e *EPUBImageProcessor) loadCbz() (totalImages int, output chan *task, err } // load a rar file that include images -func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err error) { +func (e EPUBImageProcessor) loadCbr() (totalImages int, output chan task, err error) { var isSolid bool files, err := rardecode.List(e.Input) if err != nil { @@ -312,7 +312,7 @@ func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err Open func() (io.ReadCloser, error) } - jobs := make(chan *job) + jobs := make(chan job) go func() { defer close(jobs) if isSolid && !e.Dry { @@ -340,7 +340,7 @@ func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err utils.Printf("\nerror processing image %s: %s\n", f.Name, rerr) os.Exit(1) } - jobs <- &job{i, f.Name, func() (io.ReadCloser, error) { + jobs <- job{i, f.Name, func() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(b.Bytes())), nil }} } @@ -348,14 +348,14 @@ func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err } else { for _, img := range files { if i, ok := indexedNames[img.Name]; ok { - jobs <- &job{i, img.Name, img.Open} + jobs <- job{i, img.Name, img.Open} } } } }() // send file to the queue - output = make(chan *task, e.Workers) + output = make(chan task, e.Workers) wg := &sync.WaitGroup{} for range e.WorkersRatio(50) { wg.Add(1) @@ -377,7 +377,7 @@ func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err if err != nil { img = e.corruptedImage(p, fn) } - output <- &task{ + output <- task{ Id: job.Id, Image: img, Path: p, @@ -395,7 +395,7 @@ func (e *EPUBImageProcessor) loadCbr() (totalImages int, output chan *task, err } // extract image from a pdf -func (e *EPUBImageProcessor) loadPdf() (totalImages int, output chan *task, err error) { +func (e EPUBImageProcessor) loadPdf() (totalImages int, output chan task, err error) { pdf := pdfread.Load(e.Input) if pdf == nil { err = fmt.Errorf("can't read pdf") @@ -404,7 +404,7 @@ func (e *EPUBImageProcessor) loadPdf() (totalImages int, output chan *task, err totalImages = len(pdf.Pages()) pageFmt := fmt.Sprintf("page %%0%dd", len(fmt.Sprintf("%d", totalImages))) - output = make(chan *task) + output = make(chan task) go func() { defer close(output) defer pdf.Close() @@ -419,7 +419,7 @@ func (e *EPUBImageProcessor) loadPdf() (totalImages int, output chan *task, err if err != nil { img = e.corruptedImage("", name) } - output <- &task{ + output <- task{ Id: i, Image: img, Path: "", From a76f29e91dd2646b10c8e3eceae0c67ca56d3f33 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:27:27 +0200 Subject: [PATCH 10/13] remove pointer from main --- internal/epub/epub.go | 67 +++++++++++++++++++++---------------------- main.go | 2 +- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/internal/epub/epub.go b/internal/epub/epub.go index 2d2ef14..2fb8038 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -25,23 +25,22 @@ import ( ) type EPub struct { - *epuboptions.Options + epuboptions.Options UID string Publisher string UpdatedAt string templateProcessor *template.Template - imageProcessor *epubimageprocessor.EPUBImageProcessor + imageProcessor epubimageprocessor.EPUBImageProcessor } type epubPart struct { - Cover *epubimage.Image - Images []*epubimage.Image - Reader *zip.ReadCloser + Cover epubimage.Image + Images []epubimage.Image } // New initialize EPUB -func New(options *epuboptions.Options) *EPub { +func New(options epuboptions.Options) EPub { uid := uuid.Must(uuid.NewV4()) tmpl := template.New("parser") tmpl.Funcs(template.FuncMap{ @@ -49,7 +48,7 @@ func New(options *epuboptions.Options) *EPub { "zoom": func(s int, z float32) int { return int(float32(s) * z) }, }) - return &EPub{ + return EPub{ Options: options, UID: uid.String(), Publisher: "GO Comic Converter", @@ -60,7 +59,7 @@ func New(options *epuboptions.Options) *EPub { } // render templates -func (e *EPub) render(templateString string, data map[string]any) string { +func (e EPub) render(templateString string, data map[string]any) string { var result strings.Builder tmpl := template.Must(e.templateProcessor.Parse(templateString)) if err := tmpl.Execute(&result, data); err != nil { @@ -70,7 +69,7 @@ func (e *EPub) render(templateString string, data map[string]any) string { } // write image to the zip -func (e *EPub) writeImage(wz *epubzip.EPUBZip, img *epubimage.Image, zipImg *zip.File) error { +func (e EPub) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.File) error { err := wz.WriteContent( img.EPUBPagePath(), []byte(e.render(epubtemplates.Text, map[string]any{ @@ -88,7 +87,7 @@ func (e *EPub) writeImage(wz *epubzip.EPUBZip, img *epubimage.Image, zipImg *zip } // write blank page -func (e *EPub) writeBlank(wz *epubzip.EPUBZip, img *epubimage.Image) error { +func (e EPub) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { return wz.WriteContent( img.EPUBSpacePath(), []byte(e.render(epubtemplates.Blank, map[string]any{ @@ -99,7 +98,7 @@ func (e *EPub) writeBlank(wz *epubzip.EPUBZip, img *epubimage.Image) error { } // write title image -func (e *EPub) writeCoverImage(wz *epubzip.EPUBZip, img *epubimage.Image, part, totalParts int) error { +func (e EPub) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, totalParts int) error { title := "Cover" text := "" if totalParts > 1 { @@ -119,7 +118,7 @@ func (e *EPub) writeCoverImage(wz *epubzip.EPUBZip, img *epubimage.Image, part, return err } - coverTitle, err := e.imageProcessor.CoverTitleData(&epubimageprocessor.CoverTitleDataOptions{ + coverTitle, err := e.imageProcessor.CoverTitleData(epubimageprocessor.CoverTitleDataOptions{ Src: img.Raw, Name: "cover", Text: text, @@ -142,7 +141,7 @@ func (e *EPub) writeCoverImage(wz *epubzip.EPUBZip, img *epubimage.Image, part, } // write title image -func (e *EPub) writeTitleImage(wz *epubzip.EPUBZip, img *epubimage.Image, title string) error { +func (e EPub) writeTitleImage(wz epubzip.EPUBZip, img epubimage.Image, title string) error { titleAlign := "" if !e.Image.View.PortraitOnly { if e.Image.Manga { @@ -176,7 +175,7 @@ func (e *EPub) writeTitleImage(wz *epubzip.EPUBZip, img *epubimage.Image, title return err } - coverTitle, err := e.imageProcessor.CoverTitleData(&epubimageprocessor.CoverTitleDataOptions{ + coverTitle, err := e.imageProcessor.CoverTitleData(epubimageprocessor.CoverTitleDataOptions{ Src: img.Raw, Name: "title", Text: title, @@ -198,11 +197,11 @@ func (e *EPub) writeTitleImage(wz *epubzip.EPUBZip, img *epubimage.Image, title } // extract image and split it into part -func (e *EPub) getParts() (parts []*epubPart, imgStorage *epubzip.StorageImageReader, err error) { +func (e EPub) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReader, err error) { images, err := e.imageProcessor.Load() if err != nil { - return nil, nil, err + return } // sort result by id and part @@ -213,23 +212,23 @@ func (e *EPub) getParts() (parts []*epubPart, imgStorage *epubzip.StorageImageRe return images[i].Id < images[j].Id }) - parts = make([]*epubPart, 0) + parts = make([]epubPart, 0) cover := images[0] if e.Image.HasCover { images = images[1:] } if e.Dry { - parts = append(parts, &epubPart{ + parts = append(parts, epubPart{ Cover: cover, Images: images, }) - return parts, nil, nil + return } imgStorage, err = epubzip.NewStorageImageReader(e.ImgStorage()) if err != nil { - return nil, nil, err + return } // compute size of the EPUB part and try to be as close as possible of the target @@ -239,37 +238,37 @@ func (e *EPub) getParts() (parts []*epubPart, imgStorage *epubzip.StorageImageRe baseSize := uint64(128*1024) + imgStorage.Size(cover.EPUBImgPath())*2 currentSize := baseSize - currentImages := make([]*epubimage.Image, 0) + currentImages := make([]epubimage.Image, 0) part := 1 for _, img := range images { imgSize := imgStorage.Size(img.EPUBImgPath()) + xhtmlSize if maxSize > 0 && len(currentImages) > 0 && currentSize+imgSize > maxSize { - parts = append(parts, &epubPart{ + parts = append(parts, epubPart{ Cover: cover, Images: currentImages, }) part += 1 currentSize = baseSize - currentImages = make([]*epubimage.Image, 0) + currentImages = make([]epubimage.Image, 0) } currentSize += imgSize currentImages = append(currentImages, img) } if len(currentImages) > 0 { - parts = append(parts, &epubPart{ + parts = append(parts, epubPart{ Cover: cover, Images: currentImages, }) } - return parts, imgStorage, nil + return } // create a tree from the directories. // // this is used to simulate the toc. -func (e *EPub) getTree(images []*epubimage.Image, skipFiles bool) string { +func (e EPub) getTree(images []epubimage.Image, skipFiles bool) string { t := epubtree.New() for _, img := range images { if skipFiles { @@ -286,7 +285,7 @@ func (e *EPub) getTree(images []*epubimage.Image, skipFiles bool) string { return c.WriteString("") } -func (e *EPub) computeAspectRatio(epubParts []*epubPart) float64 { +func (e EPub) computeAspectRatio(epubParts []epubPart) float64 { var ( bestAspectRatio float64 bestAspectRatioCount int @@ -313,7 +312,7 @@ func (e *EPub) computeAspectRatio(epubParts []*epubPart) float64 { return bestAspectRatio } -func (e *EPub) computeViewPort(epubParts []*epubPart) { +func (e EPub) computeViewPort(epubParts []epubPart) { if e.Image.View.AspectRatio == -1 { return //keep device size } @@ -332,14 +331,14 @@ func (e *EPub) computeViewPort(epubParts []*epubPart) { } } -func (e *EPub) writePart(path string, currentPart, totalParts int, part *epubPart, imgStorage *epubzip.StorageImageReader) error { +func (e EPub) writePart(path string, currentPart, totalParts int, part epubPart, imgStorage epubzip.StorageImageReader) error { hasTitlePage := e.TitlePage == 1 || (e.TitlePage == 2 && totalParts > 1) wz, err := epubzip.New(path) if err != nil { return err } - defer func(wz *epubzip.EPUBZip) { + defer func(wz epubzip.EPUBZip) { _ = wz.Close() }(wz) @@ -355,7 +354,7 @@ func (e *EPub) writePart(path string, currentPart, totalParts int, part *epubPar content := []zipContent{ {"META-INF/container.xml", epubtemplates.Container}, {"META-INF/com.apple.ibooks.display-options.xml", epubtemplates.AppleBooks}, - {"OEBPS/content.opf", epubtemplates.Content(&epubtemplates.ContentOptions{ + {"OEBPS/content.opf", epubtemplates.Content{ Title: title, HasTitlePage: hasTitlePage, UID: e.UID, @@ -367,7 +366,7 @@ func (e *EPub) writePart(path string, currentPart, totalParts int, part *epubPar Images: part.Images, Current: currentPart, Total: totalParts, - })}, + }.String()}, {"OEBPS/toc.xhtml", epubtemplates.Toc(title, hasTitlePage, e.StripFirstDirectoryFromToc, part.Images)}, {"OEBPS/Text/style.css", e.render(epubtemplates.Style, map[string]any{ "View": e.Image.View, @@ -413,7 +412,7 @@ func (e *EPub) writePart(path string, currentPart, totalParts int, part *epubPar } // create the zip -func (e *EPub) Write() error { +func (e EPub) Write() error { epubParts, imgStorage, err := e.getParts() if err != nil { return err @@ -424,7 +423,7 @@ func (e *EPub) Write() error { utils.Printf("TOC:\n - %s\n%s\n", e.Title, e.getTree(p.Images, true)) if e.DryVerbose { if e.Image.HasCover { - utils.Printf("Cover:\n%s\n", e.getTree([]*epubimage.Image{p.Cover}, false)) + utils.Printf("Cover:\n%s\n", e.getTree([]epubimage.Image{p.Cover}, false)) } utils.Printf("Files:\n%s\n", e.getTree(p.Images, false)) } diff --git a/main.go b/main.go index e26c226..d751563 100644 --- a/main.go +++ b/main.go @@ -110,7 +110,7 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s profile := cmd.Options.GetProfile() - if err := epub.New(&epuboptions.Options{ + if err := epub.New(epuboptions.Options{ Input: cmd.Options.Input, Output: cmd.Options.Output, LimitMb: cmd.Options.LimitMb, From 577d51a8190fac0e8b8b577e19ebaa48fba597f5 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:31:27 +0200 Subject: [PATCH 11/13] rename epub --- internal/epub/epub.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/internal/epub/epub.go b/internal/epub/epub.go index 2fb8038..4c5d9d1 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -24,7 +24,7 @@ import ( "github.com/celogeek/go-comic-converter/v2/internal/utils" ) -type EPub struct { +type EPUB struct { epuboptions.Options UID string Publisher string @@ -40,7 +40,7 @@ type epubPart struct { } // New initialize EPUB -func New(options epuboptions.Options) EPub { +func New(options epuboptions.Options) EPUB { uid := uuid.Must(uuid.NewV4()) tmpl := template.New("parser") tmpl.Funcs(template.FuncMap{ @@ -48,7 +48,7 @@ func New(options epuboptions.Options) EPub { "zoom": func(s int, z float32) int { return int(float32(s) * z) }, }) - return EPub{ + return EPUB{ Options: options, UID: uid.String(), Publisher: "GO Comic Converter", @@ -59,7 +59,7 @@ func New(options epuboptions.Options) EPub { } // render templates -func (e EPub) render(templateString string, data map[string]any) string { +func (e EPUB) render(templateString string, data map[string]any) string { var result strings.Builder tmpl := template.Must(e.templateProcessor.Parse(templateString)) if err := tmpl.Execute(&result, data); err != nil { @@ -69,7 +69,7 @@ func (e EPub) render(templateString string, data map[string]any) string { } // write image to the zip -func (e EPub) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.File) error { +func (e EPUB) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.File) error { err := wz.WriteContent( img.EPUBPagePath(), []byte(e.render(epubtemplates.Text, map[string]any{ @@ -87,7 +87,7 @@ func (e EPub) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.Fi } // write blank page -func (e EPub) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { +func (e EPUB) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { return wz.WriteContent( img.EPUBSpacePath(), []byte(e.render(epubtemplates.Blank, map[string]any{ @@ -98,7 +98,7 @@ func (e EPub) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { } // write title image -func (e EPub) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, totalParts int) error { +func (e EPUB) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, totalParts int) error { title := "Cover" text := "" if totalParts > 1 { @@ -141,7 +141,7 @@ func (e EPub) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, tot } // write title image -func (e EPub) writeTitleImage(wz epubzip.EPUBZip, img epubimage.Image, title string) error { +func (e EPUB) writeTitleImage(wz epubzip.EPUBZip, img epubimage.Image, title string) error { titleAlign := "" if !e.Image.View.PortraitOnly { if e.Image.Manga { @@ -197,7 +197,7 @@ func (e EPub) writeTitleImage(wz epubzip.EPUBZip, img epubimage.Image, title str } // extract image and split it into part -func (e EPub) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReader, err error) { +func (e EPUB) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReader, err error) { images, err := e.imageProcessor.Load() if err != nil { @@ -268,7 +268,7 @@ func (e EPub) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReade // create a tree from the directories. // // this is used to simulate the toc. -func (e EPub) getTree(images []epubimage.Image, skipFiles bool) string { +func (e EPUB) getTree(images []epubimage.Image, skipFiles bool) string { t := epubtree.New() for _, img := range images { if skipFiles { @@ -285,7 +285,7 @@ func (e EPub) getTree(images []epubimage.Image, skipFiles bool) string { return c.WriteString("") } -func (e EPub) computeAspectRatio(epubParts []epubPart) float64 { +func (e EPUB) computeAspectRatio(epubParts []epubPart) float64 { var ( bestAspectRatio float64 bestAspectRatioCount int @@ -312,7 +312,7 @@ func (e EPub) computeAspectRatio(epubParts []epubPart) float64 { return bestAspectRatio } -func (e EPub) computeViewPort(epubParts []epubPart) { +func (e EPUB) computeViewPort(epubParts []epubPart) { if e.Image.View.AspectRatio == -1 { return //keep device size } @@ -331,7 +331,7 @@ func (e EPub) computeViewPort(epubParts []epubPart) { } } -func (e EPub) writePart(path string, currentPart, totalParts int, part epubPart, imgStorage epubzip.StorageImageReader) error { +func (e EPUB) writePart(path string, currentPart, totalParts int, part epubPart, imgStorage epubzip.StorageImageReader) error { hasTitlePage := e.TitlePage == 1 || (e.TitlePage == 2 && totalParts > 1) wz, err := epubzip.New(path) @@ -412,7 +412,7 @@ func (e EPub) writePart(path string, currentPart, totalParts int, part epubPart, } // create the zip -func (e EPub) Write() error { +func (e EPUB) Write() error { epubParts, imgStorage, err := e.getParts() if err != nil { return err From 30ac67b06d5f483fdc0e174c040a35b6d876b437 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 14:59:21 +0200 Subject: [PATCH 12/13] move to pkg --- internal/epub/options/epub_options.go | 72 ------------------- internal/epub/templates/epub_templates.go | 21 ------ internal/{ => pkg}/converter/converter.go | 25 ++++--- .../converter/options.go} | 16 ++--- .../converter/order.go} | 10 +-- .../converter/profiles.go} | 6 +- internal/{ => pkg}/epub/epub.go | 42 +++++------ .../image => pkg/epubimage}/epub_image.go | 26 +++---- .../epubimagefilters/auto_contrast.go} | 0 .../epubimagefilters/auto_crop.go} | 0 .../epubimagefilters/cover_title.go} | 0 .../crop_split_double_page.go} | 0 .../epubimagefilters/pixel.go} | 0 .../epubimageprocessor/loader.go} | 5 +- .../epubimageprocessor/processor.go} | 34 ++++----- internal/pkg/epuboptions/color.go | 5 ++ internal/pkg/epuboptions/crop.go | 8 +++ internal/pkg/epuboptions/epub_options.go | 33 +++++++++ internal/pkg/epuboptions/image.go | 22 ++++++ internal/pkg/epuboptions/view.go | 8 +++ .../epubprogress}/epub_progress.go | 12 ++-- .../epubprogress/json.go} | 18 ++--- internal/pkg/epubtemplates/applebooks.go | 6 ++ .../epubtemplates/applebooks.xml.tmpl} | 0 internal/pkg/epubtemplates/blank.go | 7 ++ .../epubtemplates/blank.xhtml.tmpl} | 0 internal/pkg/epubtemplates/container.go | 6 ++ .../epubtemplates/container.xml.tmpl} | 0 .../epubtemplates/content.go} | 10 +-- .../epubtemplates/style.css.tmpl} | 0 internal/pkg/epubtemplates/style.go | 6 ++ internal/pkg/epubtemplates/text.go | 6 ++ .../epubtemplates/text.xhtml.tmpl} | 0 .../epubtemplates/toc.go} | 4 +- .../{epub/tree => pkg/epubtree}/epub_tree.go | 10 +-- .../{epub/zip => pkg/epubzip}/epub_zip.go | 2 +- .../epubzip/image.go} | 14 ++-- .../epubzip/storage_image_reader.go} | 46 ------------ internal/pkg/epubzip/storage_image_writer.go | 52 ++++++++++++++ .../sortpath.go => pkg/sortpath/by.go} | 0 .../sortpath/parser.go} | 0 internal/{ => pkg}/utils/utils.go | 0 main.go | 10 +-- 43 files changed, 278 insertions(+), 264 deletions(-) delete mode 100644 internal/epub/options/epub_options.go delete mode 100644 internal/epub/templates/epub_templates.go rename internal/{ => pkg}/converter/converter.go (96%) rename internal/{converter/options/converter_options.go => pkg/converter/options.go} (96%) rename internal/{converter/converter_order.go => pkg/converter/order.go} (52%) rename internal/{converter/profiles/converter_profiles.go => pkg/converter/profiles.go} (94%) rename internal/{ => pkg}/epub/epub.go (90%) rename internal/{epub/image => pkg/epubimage}/epub_image.go (80%) rename internal/{epub/imagefilters/epub_image_filters_autocontrast.go => pkg/epubimagefilters/auto_contrast.go} (100%) rename internal/{epub/imagefilters/epub_image_filters_autocrop.go => pkg/epubimagefilters/auto_crop.go} (100%) rename internal/{epub/imagefilters/epub_image_filters_cover_title.go => pkg/epubimagefilters/cover_title.go} (100%) rename internal/{epub/imagefilters/epub_image_filters_crop_split_double_page.go => pkg/epubimagefilters/crop_split_double_page.go} (100%) rename internal/{epub/imagefilters/epub_image_filters_pixel.go => pkg/epubimagefilters/pixel.go} (100%) rename internal/{epub/imageprocessor/epub_image_processor_loader.go => pkg/epubimageprocessor/loader.go} (98%) rename internal/{epub/imageprocessor/epub_image_processor.go => pkg/epubimageprocessor/processor.go} (88%) create mode 100644 internal/pkg/epuboptions/color.go create mode 100644 internal/pkg/epuboptions/crop.go create mode 100644 internal/pkg/epuboptions/epub_options.go create mode 100644 internal/pkg/epuboptions/image.go create mode 100644 internal/pkg/epuboptions/view.go rename internal/{epub/progress => pkg/epubprogress}/epub_progress.go (84%) rename internal/{epub/progress/epub_progress_json.go => pkg/epubprogress/json.go} (60%) create mode 100644 internal/pkg/epubtemplates/applebooks.go rename internal/{epub/templates/epub_templates_applebooks.xml.tmpl => pkg/epubtemplates/applebooks.xml.tmpl} (100%) create mode 100644 internal/pkg/epubtemplates/blank.go rename internal/{epub/templates/epub_templates_blank.xhtml.tmpl => pkg/epubtemplates/blank.xhtml.tmpl} (100%) create mode 100644 internal/pkg/epubtemplates/container.go rename internal/{epub/templates/epub_templates_container.xml.tmpl => pkg/epubtemplates/container.xml.tmpl} (100%) rename internal/{epub/templates/epub_templates_content.go => pkg/epubtemplates/content.go} (96%) rename internal/{epub/templates/epub_templates_style.css.tmpl => pkg/epubtemplates/style.css.tmpl} (100%) create mode 100644 internal/pkg/epubtemplates/style.go create mode 100644 internal/pkg/epubtemplates/text.go rename internal/{epub/templates/epub_templates_text.xhtml.tmpl => pkg/epubtemplates/text.xhtml.tmpl} (100%) rename internal/{epub/templates/epub_templates_toc.go => pkg/epubtemplates/toc.go} (94%) rename internal/{epub/tree => pkg/epubtree}/epub_tree.go (89%) rename internal/{epub/zip => pkg/epubzip}/epub_zip.go (97%) rename internal/{epub/zip/epub_zip_image.go => pkg/epubzip/image.go} (87%) rename internal/{epub/zip/epub_zip_storage_image.go => pkg/epubzip/storage_image_reader.go} (53%) create mode 100644 internal/pkg/epubzip/storage_image_writer.go rename internal/{sortpath/sortpath.go => pkg/sortpath/by.go} (100%) rename internal/{sortpath/sortpath_parser.go => pkg/sortpath/parser.go} (100%) rename internal/{ => pkg}/utils/utils.go (100%) diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go deleted file mode 100644 index d41a499..0000000 --- a/internal/epub/options/epub_options.go +++ /dev/null @@ -1,72 +0,0 @@ -// Package epuboptions Options for EPUB creation. -package epuboptions - -import "fmt" - -type Crop struct { - Enabled bool - Left, Up, Right, Bottom int - Limit int - SkipIfLimitReached bool -} - -type Color struct { - Foreground, Background string -} - -type View struct { - Width, Height int - AspectRatio float64 - PortraitOnly bool - Color Color -} - -type Image struct { - Crop Crop - Quality int - Brightness int - Contrast int - AutoContrast bool - AutoRotate bool - AutoSplitDoublePage bool - KeepDoublePageIfSplit bool - KeepSplitDoublePageAspect bool - NoBlankImage bool - Manga bool - HasCover bool - View View - GrayScale bool - GrayScaleMode int - Resize bool - Format string - AppleBookCompatibility bool -} - -type Options struct { - Input string - Output string - Title string - TitlePage int - Author string - LimitMb int - StripFirstDirectoryFromToc bool - Dry bool - DryVerbose bool - SortPathMode int - Quiet bool - Json bool - Workers int - Image Image -} - -func (o Options) WorkersRatio(pct int) (nbWorkers int) { - nbWorkers = o.Workers * pct / 100 - if nbWorkers < 1 { - nbWorkers = 1 - } - return -} - -func (o Options) ImgStorage() string { - return fmt.Sprintf("%s.tmp", o.Output) -} diff --git a/internal/epub/templates/epub_templates.go b/internal/epub/templates/epub_templates.go deleted file mode 100644 index dd80a40..0000000 --- a/internal/epub/templates/epub_templates.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package epubtemplates Templates use to create xml files of the EPUB. -package epubtemplates - -import _ "embed" - -var ( - //go:embed "epub_templates_container.xml.tmpl" - Container string - - //go:embed "epub_templates_applebooks.xml.tmpl" - AppleBooks string - - //go:embed "epub_templates_style.css.tmpl" - Style string - - //go:embed "epub_templates_text.xhtml.tmpl" - Text string - - //go:embed "epub_templates_blank.xhtml.tmpl" - Blank string -) diff --git a/internal/converter/converter.go b/internal/pkg/converter/converter.go similarity index 96% rename from internal/converter/converter.go rename to internal/pkg/converter/converter.go index f7edc51..1722a05 100644 --- a/internal/converter/converter.go +++ b/internal/pkg/converter/converter.go @@ -18,27 +18,26 @@ import ( "strings" "time" - "github.com/celogeek/go-comic-converter/v2/internal/converter/options" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) type Converter struct { - Options *options.Options + Options *Options Cmd *flag.FlagSet - order []converterOrder + order []order isZeroValueErrs []error startAt time.Time } // New Create a new parser func New() *Converter { - o := options.New() + o := NewOptions() cmd := flag.NewFlagSet("go-comic-converter", flag.ExitOnError) conv := &Converter{ Options: o, Cmd: cmd, - order: make([]converterOrder, 0), + order: make([]order, 0), startAt: time.Now(), } @@ -48,9 +47,9 @@ func New() *Converter { utils.Printf("Usage of %s:\n", filepath.Base(os.Args[0])) for _, o := range conv.order { switch v := o.(type) { - case converterOrderSection: + case orderSection: utils.Printf("\n%s:\n", o.Value()) - case converterOrderName: + case orderName: utils.Println(conv.Usage(v.isString, cmd.Lookup(v.Value()))) } } @@ -69,31 +68,31 @@ func (c *Converter) LoadConfig() error { // AddSection Create a new section of config func (c *Converter) AddSection(section string) { - c.order = append(c.order, converterOrderSection{value: section}) + c.order = append(c.order, orderSection{value: section}) } // AddStringParam Add a string parameter func (c *Converter) AddStringParam(p *string, name string, value string, usage string) { c.Cmd.StringVar(p, name, value, usage) - c.order = append(c.order, converterOrderName{value: name, isString: true}) + c.order = append(c.order, orderName{value: name, isString: true}) } // AddIntParam Add an integer parameter func (c *Converter) AddIntParam(p *int, name string, value int, usage string) { c.Cmd.IntVar(p, name, value, usage) - c.order = append(c.order, converterOrderName{value: name}) + c.order = append(c.order, orderName{value: name}) } // AddFloatParam Add an float parameter func (c *Converter) AddFloatParam(p *float64, name string, value float64, usage string) { c.Cmd.Float64Var(p, name, value, usage) - c.order = append(c.order, converterOrderName{value: name}) + c.order = append(c.order, orderName{value: name}) } // AddBoolParam Add a boolean parameter func (c *Converter) AddBoolParam(p *bool, name string, value bool, usage string) { c.Cmd.BoolVar(p, name, value, usage) - c.order = append(c.order, converterOrderName{value: name}) + c.order = append(c.order, orderName{value: name}) } // InitParse Initialize the parser with all section and parameter. diff --git a/internal/converter/options/converter_options.go b/internal/pkg/converter/options.go similarity index 96% rename from internal/converter/options/converter_options.go rename to internal/pkg/converter/options.go index b7a91df..4e06c9e 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/pkg/converter/options.go @@ -1,5 +1,5 @@ // Package options manage options with default value from config. -package options +package converter import ( "encoding/json" @@ -9,8 +9,6 @@ import ( "strings" "gopkg.in/yaml.v3" - - "github.com/celogeek/go-comic-converter/v2/internal/converter/profiles" ) type Options struct { @@ -77,11 +75,11 @@ type Options struct { Help bool `yaml:"-"` // Internal - profiles profiles.Profiles + profiles Profiles } -// New Initialize default options. -func New() *Options { +// NewOptions Initialize default options. +func NewOptions() *Options { return &Options{ Profile: "SR", Quality: 85, @@ -100,7 +98,7 @@ func New() *Options { BackgroundColor: "FFF", Format: "jpeg", TitlePage: 1, - profiles: profiles.New(), + profiles: NewProfiles(), } } @@ -310,7 +308,7 @@ func (o *Options) ShowConfig() string { // ResetConfig reset all settings to default value func (o *Options) ResetConfig() error { - if err := New().SaveConfig(); err != nil { + if err := NewOptions().SaveConfig(); err != nil { return err } return o.LoadConfig() @@ -329,7 +327,7 @@ func (o *Options) SaveConfig() error { } // GetProfile shortcut to get current profile -func (o *Options) GetProfile() *profiles.Profile { +func (o *Options) GetProfile() *Profile { if p, ok := o.profiles[o.Profile]; ok { return &p } diff --git a/internal/converter/converter_order.go b/internal/pkg/converter/order.go similarity index 52% rename from internal/converter/converter_order.go rename to internal/pkg/converter/order.go index df431dd..45effd5 100644 --- a/internal/converter/converter_order.go +++ b/internal/pkg/converter/order.go @@ -1,27 +1,27 @@ package converter // Name or Section -type converterOrder interface { +type order interface { Value() string } // Section -type converterOrderSection struct { +type orderSection struct { value string } -func (s converterOrderSection) Value() string { +func (s orderSection) Value() string { return s.value } // Name // // isString is used to quote the default value. -type converterOrderName struct { +type orderName struct { value string isString bool } -func (s converterOrderName) Value() string { +func (s orderName) Value() string { return s.value } diff --git a/internal/converter/profiles/converter_profiles.go b/internal/pkg/converter/profiles.go similarity index 94% rename from internal/converter/profiles/converter_profiles.go rename to internal/pkg/converter/profiles.go index e6d1357..c01a09b 100644 --- a/internal/converter/profiles/converter_profiles.go +++ b/internal/pkg/converter/profiles.go @@ -1,5 +1,5 @@ // Package profiles manage supported profiles for go-comic-converter. -package profiles +package converter import ( "fmt" @@ -15,8 +15,8 @@ type Profile struct { type Profiles map[string]Profile -// New Initialize list of all supported profiles. -func New() Profiles { +// NewProfiles Initialize list of all supported profiles. +func NewProfiles() Profiles { res := make(Profiles) for _, r := range []Profile{ // High Resolution for Tablet diff --git a/internal/epub/epub.go b/internal/pkg/epub/epub.go similarity index 90% rename from internal/epub/epub.go rename to internal/pkg/epub/epub.go index 4c5d9d1..b72be7a 100644 --- a/internal/epub/epub.go +++ b/internal/pkg/epub/epub.go @@ -14,18 +14,18 @@ import ( "github.com/gofrs/uuid" - epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image" - epubimageprocessor "github.com/celogeek/go-comic-converter/v2/internal/epub/imageprocessor" - epuboptions "github.com/celogeek/go-comic-converter/v2/internal/epub/options" - epubprogress "github.com/celogeek/go-comic-converter/v2/internal/epub/progress" - epubtemplates "github.com/celogeek/go-comic-converter/v2/internal/epub/templates" - epubtree "github.com/celogeek/go-comic-converter/v2/internal/epub/tree" - epubzip "github.com/celogeek/go-comic-converter/v2/internal/epub/zip" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimage" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimageprocessor" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epuboptions" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubprogress" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubtemplates" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubtree" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubzip" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) type EPUB struct { - epuboptions.Options + epuboptions.EPUBOptions UID string Publisher string UpdatedAt string @@ -35,12 +35,12 @@ type EPUB struct { } type epubPart struct { - Cover epubimage.Image - Images []epubimage.Image + Cover epubimage.EPUBImage + Images []epubimage.EPUBImage } // New initialize EPUB -func New(options epuboptions.Options) EPUB { +func New(options epuboptions.EPUBOptions) EPUB { uid := uuid.Must(uuid.NewV4()) tmpl := template.New("parser") tmpl.Funcs(template.FuncMap{ @@ -49,7 +49,7 @@ func New(options epuboptions.Options) EPUB { }) return EPUB{ - Options: options, + EPUBOptions: options, UID: uid.String(), Publisher: "GO Comic Converter", UpdatedAt: time.Now().UTC().Format("2006-01-02T15:04:05Z"), @@ -69,7 +69,7 @@ func (e EPUB) render(templateString string, data map[string]any) string { } // write image to the zip -func (e EPUB) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.File) error { +func (e EPUB) writeImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, zipImg *zip.File) error { err := wz.WriteContent( img.EPUBPagePath(), []byte(e.render(epubtemplates.Text, map[string]any{ @@ -87,7 +87,7 @@ func (e EPUB) writeImage(wz epubzip.EPUBZip, img epubimage.Image, zipImg *zip.Fi } // write blank page -func (e EPUB) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { +func (e EPUB) writeBlank(wz epubzip.EPUBZip, img epubimage.EPUBImage) error { return wz.WriteContent( img.EPUBSpacePath(), []byte(e.render(epubtemplates.Blank, map[string]any{ @@ -98,7 +98,7 @@ func (e EPUB) writeBlank(wz epubzip.EPUBZip, img epubimage.Image) error { } // write title image -func (e EPUB) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, totalParts int) error { +func (e EPUB) writeCoverImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, part, totalParts int) error { title := "Cover" text := "" if totalParts > 1 { @@ -141,7 +141,7 @@ func (e EPUB) writeCoverImage(wz epubzip.EPUBZip, img epubimage.Image, part, tot } // write title image -func (e EPUB) writeTitleImage(wz epubzip.EPUBZip, img epubimage.Image, title string) error { +func (e EPUB) writeTitleImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, title string) error { titleAlign := "" if !e.Image.View.PortraitOnly { if e.Image.Manga { @@ -238,7 +238,7 @@ func (e EPUB) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReade baseSize := uint64(128*1024) + imgStorage.Size(cover.EPUBImgPath())*2 currentSize := baseSize - currentImages := make([]epubimage.Image, 0) + currentImages := make([]epubimage.EPUBImage, 0) part := 1 for _, img := range images { @@ -250,7 +250,7 @@ func (e EPUB) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReade }) part += 1 currentSize = baseSize - currentImages = make([]epubimage.Image, 0) + currentImages = make([]epubimage.EPUBImage, 0) } currentSize += imgSize currentImages = append(currentImages, img) @@ -268,7 +268,7 @@ func (e EPUB) getParts() (parts []epubPart, imgStorage epubzip.StorageImageReade // create a tree from the directories. // // this is used to simulate the toc. -func (e EPUB) getTree(images []epubimage.Image, skipFiles bool) string { +func (e EPUB) getTree(images []epubimage.EPUBImage, skipFiles bool) string { t := epubtree.New() for _, img := range images { if skipFiles { @@ -423,7 +423,7 @@ func (e EPUB) Write() error { utils.Printf("TOC:\n - %s\n%s\n", e.Title, e.getTree(p.Images, true)) if e.DryVerbose { if e.Image.HasCover { - utils.Printf("Cover:\n%s\n", e.getTree([]epubimage.Image{p.Cover}, false)) + utils.Printf("Cover:\n%s\n", e.getTree([]epubimage.EPUBImage{p.Cover}, false)) } utils.Printf("Files:\n%s\n", e.getTree(p.Images, false)) } diff --git a/internal/epub/image/epub_image.go b/internal/pkg/epubimage/epub_image.go similarity index 80% rename from internal/epub/image/epub_image.go rename to internal/pkg/epubimage/epub_image.go index 1578ceb..fe33cf2 100644 --- a/internal/epub/image/epub_image.go +++ b/internal/pkg/epubimage/epub_image.go @@ -1,4 +1,4 @@ -// Package epubimage Image helpers to transform image. +// Package epubimage EPUBImage helpers to transform image. package epubimage import ( @@ -7,7 +7,7 @@ import ( "strings" ) -type Image struct { +type EPUBImage struct { Id int Part int Raw image.Image @@ -24,47 +24,47 @@ type Image struct { } // SpaceKey key name of the blank page after the image -func (i Image) SpaceKey() string { +func (i EPUBImage) SpaceKey() string { return fmt.Sprintf("space_%d", i.Id) } // SpacePath path of the blank page -func (i Image) SpacePath() string { +func (i EPUBImage) SpacePath() string { return fmt.Sprintf("Text/%s.xhtml", i.SpaceKey()) } // EPUBSpacePath path of the blank page into the EPUB -func (i Image) EPUBSpacePath() string { +func (i EPUBImage) EPUBSpacePath() string { return fmt.Sprintf("OEBPS/%s", i.SpacePath()) } // PageKey key for page -func (i Image) PageKey() string { +func (i EPUBImage) PageKey() string { return fmt.Sprintf("page_%d_p%d", i.Id, i.Part) } // PagePath page path linked to the image -func (i Image) PagePath() string { +func (i EPUBImage) PagePath() string { return fmt.Sprintf("Text/%s.xhtml", i.PageKey()) } // EPUBPagePath page path into the EPUB -func (i Image) EPUBPagePath() string { +func (i EPUBImage) EPUBPagePath() string { return fmt.Sprintf("OEBPS/%s", i.PagePath()) } // ImgKey key for image -func (i Image) ImgKey() string { +func (i EPUBImage) ImgKey() string { return fmt.Sprintf("img_%d_p%d", i.Id, i.Part) } // ImgPath image path -func (i Image) ImgPath() string { +func (i EPUBImage) ImgPath() string { return fmt.Sprintf("Images/%s.%s", i.ImgKey(), i.Format) } // EPUBImgPath image path into the EPUB -func (i Image) EPUBImgPath() string { +func (i EPUBImage) EPUBImgPath() string { return fmt.Sprintf("OEBPS/%s", i.ImgPath()) } @@ -72,7 +72,7 @@ func (i Image) EPUBImgPath() string { // // center by default. // align to left or right if it's part of the split double page. -func (i Image) ImgStyle(viewWidth, viewHeight int, align string) string { +func (i EPUBImage) ImgStyle(viewWidth, viewHeight int, align string) string { relWidth, relHeight := i.RelSize(viewWidth, viewHeight) marginW, marginH := float64(viewWidth-relWidth)/2, float64(viewHeight-relHeight)/2 @@ -97,7 +97,7 @@ func (i Image) ImgStyle(viewWidth, viewHeight int, align string) string { return strings.Join(style, "; ") } -func (i Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { +func (i EPUBImage) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { w, h := viewWidth, viewHeight srcw, srch := i.Width, i.Height diff --git a/internal/epub/imagefilters/epub_image_filters_autocontrast.go b/internal/pkg/epubimagefilters/auto_contrast.go similarity index 100% rename from internal/epub/imagefilters/epub_image_filters_autocontrast.go rename to internal/pkg/epubimagefilters/auto_contrast.go diff --git a/internal/epub/imagefilters/epub_image_filters_autocrop.go b/internal/pkg/epubimagefilters/auto_crop.go similarity index 100% rename from internal/epub/imagefilters/epub_image_filters_autocrop.go rename to internal/pkg/epubimagefilters/auto_crop.go diff --git a/internal/epub/imagefilters/epub_image_filters_cover_title.go b/internal/pkg/epubimagefilters/cover_title.go similarity index 100% rename from internal/epub/imagefilters/epub_image_filters_cover_title.go rename to internal/pkg/epubimagefilters/cover_title.go diff --git a/internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go b/internal/pkg/epubimagefilters/crop_split_double_page.go similarity index 100% rename from internal/epub/imagefilters/epub_image_filters_crop_split_double_page.go rename to internal/pkg/epubimagefilters/crop_split_double_page.go diff --git a/internal/epub/imagefilters/epub_image_filters_pixel.go b/internal/pkg/epubimagefilters/pixel.go similarity index 100% rename from internal/epub/imagefilters/epub_image_filters_pixel.go rename to internal/pkg/epubimagefilters/pixel.go diff --git a/internal/epub/imageprocessor/epub_image_processor_loader.go b/internal/pkg/epubimageprocessor/loader.go similarity index 98% rename from internal/epub/imageprocessor/epub_image_processor_loader.go rename to internal/pkg/epubimageprocessor/loader.go index d34c828..cfdf7e1 100644 --- a/internal/epub/imageprocessor/epub_image_processor_loader.go +++ b/internal/pkg/epubimageprocessor/loader.go @@ -27,8 +27,9 @@ import ( pdfimage "github.com/raff/pdfreader/image" "github.com/raff/pdfreader/pdfread" - "github.com/celogeek/go-comic-converter/v2/internal/sortpath" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/sortpath" + + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) type task struct { diff --git a/internal/epub/imageprocessor/epub_image_processor.go b/internal/pkg/epubimageprocessor/processor.go similarity index 88% rename from internal/epub/imageprocessor/epub_image_processor.go rename to internal/pkg/epubimageprocessor/processor.go index c2cad84..daf92b7 100644 --- a/internal/epub/imageprocessor/epub_image_processor.go +++ b/internal/pkg/epubimageprocessor/processor.go @@ -11,25 +11,25 @@ import ( "github.com/disintegration/gift" - epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image" - epubimagefilters "github.com/celogeek/go-comic-converter/v2/internal/epub/imagefilters" - epuboptions "github.com/celogeek/go-comic-converter/v2/internal/epub/options" - epubprogress "github.com/celogeek/go-comic-converter/v2/internal/epub/progress" - epubzip "github.com/celogeek/go-comic-converter/v2/internal/epub/zip" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimage" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimagefilters" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epuboptions" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubprogress" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubzip" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) type EPUBImageProcessor struct { - epuboptions.Options + epuboptions.EPUBOptions } -func New(o epuboptions.Options) EPUBImageProcessor { +func New(o epuboptions.EPUBOptions) EPUBImageProcessor { return EPUBImageProcessor{o} } // Load extract and convert images -func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { - images = make([]epubimage.Image, 0) +func (e EPUBImageProcessor) Load() (images []epubimage.EPUBImage, err error) { + images = make([]epubimage.EPUBImage, 0) imageCount, imageInput, err := e.load() if err != nil { return nil, err @@ -38,7 +38,7 @@ func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { // dry run, skip conversion if e.Dry { for img := range imageInput { - images = append(images, epubimage.Image{ + images = append(images, epubimage.EPUBImage{ Id: img.Id, Path: img.Path, Name: img.Name, @@ -49,7 +49,7 @@ func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { return images, nil } - imageOutput := make(chan epubimage.Image) + imageOutput := make(chan epubimage.EPUBImage) // processing bar := epubprogress.New(epubprogress.Options{ @@ -82,7 +82,7 @@ func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { // do not keep double page if requested if !(img.DoublePage && input.Id > 0 && - e.Options.Image.AutoSplitDoublePage && !e.Options.Image.KeepDoublePageIfSplit) { + e.EPUBOptions.Image.AutoSplitDoublePage && !e.EPUBOptions.Image.KeepDoublePageIfSplit) { if err = imgStorage.Add(img.EPUBImgPath(), img.Raw, e.Image.Quality); err != nil { _ = bar.Close() utils.Printf("error with %s: %s", input.Name, err) @@ -141,7 +141,7 @@ func (e EPUBImageProcessor) Load() (images []epubimage.Image, err error) { } func (e EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw.Image { - if e.Options.Image.GrayScale { + if e.EPUBOptions.Image.GrayScale { return image.NewGray(r) } @@ -173,7 +173,7 @@ func (e EPUBImageProcessor) createImage(src image.Image, r image.Rectangle) draw // transform image into 1 or 3 images // only doublepage with autosplit has 3 versions -func (e EPUBImageProcessor) transformImage(input task, part int, right bool) epubimage.Image { +func (e EPUBImageProcessor) transformImage(input task, part int, right bool) epubimage.EPUBImage { g := gift.New() src := input.Image srcBounds := src.Bounds() @@ -262,7 +262,7 @@ func (e EPUBImageProcessor) transformImage(input task, part int, right bool) epu dst := e.createImage(src, g.Bounds(src.Bounds())) g.Draw(dst, src) - return epubimage.Image{ + return epubimage.EPUBImage{ Id: input.Id, Part: part, Raw: dst, @@ -312,7 +312,7 @@ func (e EPUBImageProcessor) Cover16LevelOfGray(bounds image.Rectangle) draw.Imag } // CoverTitleData create a title page with the cover -func (e EPUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.ZipImage, error) { +func (e EPUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.Image, error) { // Create a blur version of the cover g := gift.New(epubimagefilters.CoverTitle(o.Text, o.Align, o.PctWidth, o.PctMargin, o.MaxFontSize, o.BorderSize)) var dst draw.Image diff --git a/internal/pkg/epuboptions/color.go b/internal/pkg/epuboptions/color.go new file mode 100644 index 0000000..75112b5 --- /dev/null +++ b/internal/pkg/epuboptions/color.go @@ -0,0 +1,5 @@ +package epuboptions + +type Color struct { + Foreground, Background string +} diff --git a/internal/pkg/epuboptions/crop.go b/internal/pkg/epuboptions/crop.go new file mode 100644 index 0000000..4cc66bb --- /dev/null +++ b/internal/pkg/epuboptions/crop.go @@ -0,0 +1,8 @@ +package epuboptions + +type Crop struct { + Enabled bool + Left, Up, Right, Bottom int + Limit int + SkipIfLimitReached bool +} diff --git a/internal/pkg/epuboptions/epub_options.go b/internal/pkg/epuboptions/epub_options.go new file mode 100644 index 0000000..8018566 --- /dev/null +++ b/internal/pkg/epuboptions/epub_options.go @@ -0,0 +1,33 @@ +// Package epuboptions EPUBOptions for EPUB creation. +package epuboptions + +import "fmt" + +type EPUBOptions struct { + Input string + Output string + Title string + TitlePage int + Author string + LimitMb int + StripFirstDirectoryFromToc bool + Dry bool + DryVerbose bool + SortPathMode int + Quiet bool + Json bool + Workers int + Image Image +} + +func (o EPUBOptions) WorkersRatio(pct int) (nbWorkers int) { + nbWorkers = o.Workers * pct / 100 + if nbWorkers < 1 { + nbWorkers = 1 + } + return +} + +func (o EPUBOptions) ImgStorage() string { + return fmt.Sprintf("%s.tmp", o.Output) +} diff --git a/internal/pkg/epuboptions/image.go b/internal/pkg/epuboptions/image.go new file mode 100644 index 0000000..807d583 --- /dev/null +++ b/internal/pkg/epuboptions/image.go @@ -0,0 +1,22 @@ +package epuboptions + +type Image struct { + Crop Crop + Quality int + Brightness int + Contrast int + AutoContrast bool + AutoRotate bool + AutoSplitDoublePage bool + KeepDoublePageIfSplit bool + KeepSplitDoublePageAspect bool + NoBlankImage bool + Manga bool + HasCover bool + View View + GrayScale bool + GrayScaleMode int + Resize bool + Format string + AppleBookCompatibility bool +} diff --git a/internal/pkg/epuboptions/view.go b/internal/pkg/epuboptions/view.go new file mode 100644 index 0000000..d2fbdd5 --- /dev/null +++ b/internal/pkg/epuboptions/view.go @@ -0,0 +1,8 @@ +package epuboptions + +type View struct { + Width, Height int + AspectRatio float64 + PortraitOnly bool + Color Color +} diff --git a/internal/epub/progress/epub_progress.go b/internal/pkg/epubprogress/epub_progress.go similarity index 84% rename from internal/epub/progress/epub_progress.go rename to internal/pkg/epubprogress/epub_progress.go index ab3d2f8..0cefb67 100644 --- a/internal/epub/progress/epub_progress.go +++ b/internal/pkg/epubprogress/epub_progress.go @@ -2,13 +2,14 @@ package epubprogress import ( + "encoding/json" "fmt" "os" "time" "github.com/schollz/progressbar/v3" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) type Options struct { @@ -20,18 +21,21 @@ type Options struct { TotalJob int } -type EpubProgress interface { +type EPUBProgress interface { Add(num int) error Close() error } -func New(o Options) EpubProgress { +func New(o Options) EPUBProgress { if o.Quiet { return progressbar.DefaultSilent(int64(o.Max)) } if o.Json { - return newEpubProgressJson(o) + return &jsonprogress{ + o: o, + e: json.NewEncoder(os.Stdout), + } } fmtJob := fmt.Sprintf("%%0%dd", len(fmt.Sprint(o.TotalJob))) diff --git a/internal/epub/progress/epub_progress_json.go b/internal/pkg/epubprogress/json.go similarity index 60% rename from internal/epub/progress/epub_progress_json.go rename to internal/pkg/epubprogress/json.go index cce3709..cb495fb 100644 --- a/internal/epub/progress/epub_progress_json.go +++ b/internal/pkg/epubprogress/json.go @@ -2,28 +2,20 @@ package epubprogress import ( "encoding/json" - "os" ) -type Json struct { +type jsonprogress struct { o Options e *json.Encoder current int } -func newEpubProgressJson(o Options) EpubProgress { - return &Json{ - o: o, - e: json.NewEncoder(os.Stdout), - } -} - -func (p *Json) Add(num int) error { +func (p *jsonprogress) Add(num int) error { p.current += num return p.e.Encode(map[string]any{ - "type": "progress", + "type": "epubprogress", "data": map[string]any{ - "progress": map[string]any{ + "epubprogress": map[string]any{ "current": p.current, "total": p.o.Max, }, @@ -36,6 +28,6 @@ func (p *Json) Add(num int) error { }) } -func (p *Json) Close() error { +func (p *jsonprogress) Close() error { return nil } diff --git a/internal/pkg/epubtemplates/applebooks.go b/internal/pkg/epubtemplates/applebooks.go new file mode 100644 index 0000000..4e5257a --- /dev/null +++ b/internal/pkg/epubtemplates/applebooks.go @@ -0,0 +1,6 @@ +package epubtemplates + +import _ "embed" + +//go:embed "applebooks.xml.tmpl" +var AppleBooks string diff --git a/internal/epub/templates/epub_templates_applebooks.xml.tmpl b/internal/pkg/epubtemplates/applebooks.xml.tmpl similarity index 100% rename from internal/epub/templates/epub_templates_applebooks.xml.tmpl rename to internal/pkg/epubtemplates/applebooks.xml.tmpl diff --git a/internal/pkg/epubtemplates/blank.go b/internal/pkg/epubtemplates/blank.go new file mode 100644 index 0000000..5267aa3 --- /dev/null +++ b/internal/pkg/epubtemplates/blank.go @@ -0,0 +1,7 @@ +// Package epubtemplates Templates use to create xml files of the EPUB. +package epubtemplates + +import _ "embed" + +//go:embed "blank.xhtml.tmpl" +var Blank string diff --git a/internal/epub/templates/epub_templates_blank.xhtml.tmpl b/internal/pkg/epubtemplates/blank.xhtml.tmpl similarity index 100% rename from internal/epub/templates/epub_templates_blank.xhtml.tmpl rename to internal/pkg/epubtemplates/blank.xhtml.tmpl diff --git a/internal/pkg/epubtemplates/container.go b/internal/pkg/epubtemplates/container.go new file mode 100644 index 0000000..e08f916 --- /dev/null +++ b/internal/pkg/epubtemplates/container.go @@ -0,0 +1,6 @@ +package epubtemplates + +import _ "embed" + +//go:embed "container.xml.tmpl" +var Container string diff --git a/internal/epub/templates/epub_templates_container.xml.tmpl b/internal/pkg/epubtemplates/container.xml.tmpl similarity index 100% rename from internal/epub/templates/epub_templates_container.xml.tmpl rename to internal/pkg/epubtemplates/container.xml.tmpl diff --git a/internal/epub/templates/epub_templates_content.go b/internal/pkg/epubtemplates/content.go similarity index 96% rename from internal/epub/templates/epub_templates_content.go rename to internal/pkg/epubtemplates/content.go index 5c46d98..c263f09 100644 --- a/internal/epub/templates/epub_templates_content.go +++ b/internal/pkg/epubtemplates/content.go @@ -5,8 +5,8 @@ import ( "github.com/beevik/etree" - epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image" - epuboptions "github.com/celogeek/go-comic-converter/v2/internal/epub/options" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimage" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epuboptions" ) type Content struct { @@ -17,8 +17,8 @@ type Content struct { Publisher string UpdatedAt string ImageOptions epuboptions.Image - Cover epubimage.Image - Images []epubimage.Image + Cover epubimage.EPUBImage + Images []epubimage.EPUBImage Current int Total int } @@ -143,7 +143,7 @@ func (o Content) getMeta() []tag { func (o Content) getManifest() []tag { var imageTags, pageTags, spaceTags []tag - addTag := func(img epubimage.Image, withSpace bool) { + addTag := func(img epubimage.EPUBImage, withSpace bool) { imageTags = append(imageTags, tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""}, ) diff --git a/internal/epub/templates/epub_templates_style.css.tmpl b/internal/pkg/epubtemplates/style.css.tmpl similarity index 100% rename from internal/epub/templates/epub_templates_style.css.tmpl rename to internal/pkg/epubtemplates/style.css.tmpl diff --git a/internal/pkg/epubtemplates/style.go b/internal/pkg/epubtemplates/style.go new file mode 100644 index 0000000..4711a7a --- /dev/null +++ b/internal/pkg/epubtemplates/style.go @@ -0,0 +1,6 @@ +package epubtemplates + +import _ "embed" + +//go:embed "style.css.tmpl" +var Style string diff --git a/internal/pkg/epubtemplates/text.go b/internal/pkg/epubtemplates/text.go new file mode 100644 index 0000000..4b5ddc3 --- /dev/null +++ b/internal/pkg/epubtemplates/text.go @@ -0,0 +1,6 @@ +package epubtemplates + +import _ "embed" + +//go:embed "text.xhtml.tmpl" +var Text string diff --git a/internal/epub/templates/epub_templates_text.xhtml.tmpl b/internal/pkg/epubtemplates/text.xhtml.tmpl similarity index 100% rename from internal/epub/templates/epub_templates_text.xhtml.tmpl rename to internal/pkg/epubtemplates/text.xhtml.tmpl diff --git a/internal/epub/templates/epub_templates_toc.go b/internal/pkg/epubtemplates/toc.go similarity index 94% rename from internal/epub/templates/epub_templates_toc.go rename to internal/pkg/epubtemplates/toc.go index ac5d625..96636dc 100644 --- a/internal/epub/templates/epub_templates_toc.go +++ b/internal/pkg/epubtemplates/toc.go @@ -6,13 +6,13 @@ import ( "github.com/beevik/etree" - epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimage" ) // Toc create toc // //goland:noinspection HttpUrlsUsage -func Toc(title string, hasTitle bool, stripFirstDirectoryFromToc bool, images []epubimage.Image) string { +func Toc(title string, hasTitle bool, stripFirstDirectoryFromToc bool, images []epubimage.EPUBImage) string { doc := etree.NewDocument() doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) doc.CreateDirective("DOCTYPE html") diff --git a/internal/epub/tree/epub_tree.go b/internal/pkg/epubtree/epub_tree.go similarity index 89% rename from internal/epub/tree/epub_tree.go rename to internal/pkg/epubtree/epub_tree.go index 6afac0a..0f6dbec 100644 --- a/internal/epub/tree/epub_tree.go +++ b/internal/pkg/epubtree/epub_tree.go @@ -23,7 +23,7 @@ import ( "strings" ) -type Tree struct { +type EPUBTree struct { nodes map[string]*Node } @@ -33,19 +33,19 @@ type Node struct { } // New initialize tree with a root node -func New() *Tree { - return &Tree{map[string]*Node{ +func New() *EPUBTree { + return &EPUBTree{map[string]*Node{ ".": {".", []*Node{}}, }} } // Root root node -func (n *Tree) Root() *Node { +func (n *EPUBTree) Root() *Node { return n.nodes["."] } // Add the filename to the tree -func (n *Tree) Add(filename string) { +func (n *EPUBTree) Add(filename string) { cn := n.Root() cp := "" for _, p := range strings.Split(filepath.Clean(filename), string(filepath.Separator)) { diff --git a/internal/epub/zip/epub_zip.go b/internal/pkg/epubzip/epub_zip.go similarity index 97% rename from internal/epub/zip/epub_zip.go rename to internal/pkg/epubzip/epub_zip.go index 3dd054f..62f3058 100644 --- a/internal/epub/zip/epub_zip.go +++ b/internal/pkg/epubzip/epub_zip.go @@ -67,7 +67,7 @@ func (e EPUBZip) Copy(fz *zip.File) error { } // WriteRaw Write image. They are already compressed, so we write them down directly. -func (e EPUBZip) WriteRaw(raw ZipImage) error { +func (e EPUBZip) WriteRaw(raw Image) error { m, err := e.wz.CreateRaw(raw.Header) if err != nil { return err diff --git a/internal/epub/zip/epub_zip_image.go b/internal/pkg/epubzip/image.go similarity index 87% rename from internal/epub/zip/epub_zip_image.go rename to internal/pkg/epubzip/image.go index 5df69ae..df87c4f 100644 --- a/internal/epub/zip/epub_zip_image.go +++ b/internal/pkg/epubzip/image.go @@ -12,13 +12,13 @@ import ( "time" ) -type ZipImage struct { +type Image struct { Header *zip.FileHeader Data []byte } // CompressImage create gzip encoded jpeg -func CompressImage(filename string, format string, img image.Image, quality int) (ZipImage, error) { +func CompressImage(filename string, format string, img image.Image, quality int) (Image, error) { var ( data, cdata bytes.Buffer err error @@ -33,27 +33,27 @@ func CompressImage(filename string, format string, img image.Image, quality int) err = fmt.Errorf("unknown format %q", format) } if err != nil { - return ZipImage{}, err + return Image{}, err } wcdata, err := flate.NewWriter(&cdata, flate.BestCompression) if err != nil { - return ZipImage{}, err + return Image{}, err } _, err = wcdata.Write(data.Bytes()) if err != nil { - return ZipImage{}, err + return Image{}, err } err = wcdata.Close() if err != nil { - return ZipImage{}, err + return Image{}, err } t := time.Now() //goland:noinspection GoDeprecation - return ZipImage{ + return Image{ &zip.FileHeader{ Name: filename, CompressedSize64: uint64(cdata.Len()), diff --git a/internal/epub/zip/epub_zip_storage_image.go b/internal/pkg/epubzip/storage_image_reader.go similarity index 53% rename from internal/epub/zip/epub_zip_storage_image.go rename to internal/pkg/epubzip/storage_image_reader.go index f08f7d8..42acaef 100644 --- a/internal/epub/zip/epub_zip_storage_image.go +++ b/internal/pkg/epubzip/storage_image_reader.go @@ -2,55 +2,9 @@ package epubzip import ( "archive/zip" - "image" "os" - "sync" ) -type StorageImageWriter struct { - fh *os.File - fz *zip.Writer - format string - mut *sync.Mutex -} - -func NewStorageImageWriter(filename string, format string) (StorageImageWriter, error) { - fh, err := os.Create(filename) - if err != nil { - return StorageImageWriter{}, err - } - fz := zip.NewWriter(fh) - return StorageImageWriter{fh, fz, format, &sync.Mutex{}}, nil -} - -func (e StorageImageWriter) Close() error { - if err := e.fz.Close(); err != nil { - _ = e.fh.Close() - return err - } - return e.fh.Close() -} - -func (e StorageImageWriter) Add(filename string, img image.Image, quality int) error { - zipImage, err := CompressImage(filename, e.format, img, quality) - if err != nil { - return err - } - - e.mut.Lock() - defer e.mut.Unlock() - fh, err := e.fz.CreateRaw(zipImage.Header) - if err != nil { - return err - } - _, err = fh.Write(zipImage.Data) - if err != nil { - return err - } - - return nil -} - type StorageImageReader struct { filename string fh *os.File diff --git a/internal/pkg/epubzip/storage_image_writer.go b/internal/pkg/epubzip/storage_image_writer.go new file mode 100644 index 0000000..ccec171 --- /dev/null +++ b/internal/pkg/epubzip/storage_image_writer.go @@ -0,0 +1,52 @@ +package epubzip + +import ( + "archive/zip" + "image" + "os" + "sync" +) + +type StorageImageWriter struct { + fh *os.File + fz *zip.Writer + format string + mut *sync.Mutex +} + +func NewStorageImageWriter(filename string, format string) (StorageImageWriter, error) { + fh, err := os.Create(filename) + if err != nil { + return StorageImageWriter{}, err + } + fz := zip.NewWriter(fh) + return StorageImageWriter{fh, fz, format, &sync.Mutex{}}, nil +} + +func (e StorageImageWriter) Close() error { + if err := e.fz.Close(); err != nil { + _ = e.fh.Close() + return err + } + return e.fh.Close() +} + +func (e StorageImageWriter) Add(filename string, img image.Image, quality int) error { + zipImage, err := CompressImage(filename, e.format, img, quality) + if err != nil { + return err + } + + e.mut.Lock() + defer e.mut.Unlock() + fh, err := e.fz.CreateRaw(zipImage.Header) + if err != nil { + return err + } + _, err = fh.Write(zipImage.Data) + if err != nil { + return err + } + + return nil +} diff --git a/internal/sortpath/sortpath.go b/internal/pkg/sortpath/by.go similarity index 100% rename from internal/sortpath/sortpath.go rename to internal/pkg/sortpath/by.go diff --git a/internal/sortpath/sortpath_parser.go b/internal/pkg/sortpath/parser.go similarity index 100% rename from internal/sortpath/sortpath_parser.go rename to internal/pkg/sortpath/parser.go diff --git a/internal/utils/utils.go b/internal/pkg/utils/utils.go similarity index 100% rename from internal/utils/utils.go rename to internal/pkg/utils/utils.go diff --git a/main.go b/main.go index d751563..856253c 100644 --- a/main.go +++ b/main.go @@ -14,10 +14,10 @@ import ( "github.com/tcnksm/go-latest" - "github.com/celogeek/go-comic-converter/v2/internal/converter" - "github.com/celogeek/go-comic-converter/v2/internal/epub" - epuboptions "github.com/celogeek/go-comic-converter/v2/internal/epub/options" - "github.com/celogeek/go-comic-converter/v2/internal/utils" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/converter" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epub" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/epuboptions" + "github.com/celogeek/go-comic-converter/v2/internal/pkg/utils" ) func main() { @@ -110,7 +110,7 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s profile := cmd.Options.GetProfile() - if err := epub.New(epuboptions.Options{ + if err := epub.New(epuboptions.EPUBOptions{ Input: cmd.Options.Input, Output: cmd.Options.Output, LimitMb: cmd.Options.LimitMb, From cdd3668ca2d7d8dca06f059c92909dc159252d12 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sat, 11 May 2024 15:44:47 +0200 Subject: [PATCH 13/13] improve readability main --- main.go | 126 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/main.go b/main.go index 856253c..85e81a3 100644 --- a/main.go +++ b/main.go @@ -28,25 +28,40 @@ func main() { cmd.InitParse() cmd.Parse() - if cmd.Options.Version { - bi, ok := debug.ReadBuildInfo() - if !ok { - utils.Println("failed to fetch current version") - os.Exit(1) - } + switch { + case cmd.Options.Version: + version() + case cmd.Options.Save: + save(cmd) + case cmd.Options.Show: + show(cmd) + case cmd.Options.Reset: + reset(cmd) + default: + generate(cmd) + } - githubTag := &latest.GithubTag{ - Owner: "celogeek", - Repository: "go-comic-converter", - } - v, err := githubTag.Fetch() - if err != nil || len(v.Versions) < 1 { - utils.Println("failed to fetch the latest version") - os.Exit(1) - } - latestVersion := v.Versions[0] +} - utils.Printf(`go-comic-converter +func version() { + bi, ok := debug.ReadBuildInfo() + if !ok { + utils.Println("failed to fetch current version") + os.Exit(1) + } + + githubTag := &latest.GithubTag{ + Owner: "celogeek", + Repository: "go-comic-converter", + } + v, err := githubTag.Fetch() + if err != nil || len(v.Versions) < 1 { + utils.Println("failed to fetch the latest version") + os.Exit(1) + } + latestVersion := v.Versions[0] + + utils.Printf(`go-comic-converter Path : %s Sum : %s Version : %s @@ -55,47 +70,54 @@ func main() { To install the latest version: $ go install github.com/celogeek/go-comic-converter/v%d@%s `, - bi.Main.Path, - bi.Main.Sum, - bi.Main.Version, - latestVersion.Original(), - latestVersion.Segments()[0], - latestVersion.Original(), - ) - return - } + bi.Main.Path, + bi.Main.Sum, + bi.Main.Version, + latestVersion.Original(), + latestVersion.Segments()[0], + latestVersion.Original(), + ) +} - if cmd.Options.Save { - if err := cmd.Options.SaveConfig(); err != nil { - cmd.Fatal(err) - } - utils.Printf( - "%s%s\n\nSaving to %s\n", - cmd.Options.Header(), - cmd.Options.ShowConfig(), - cmd.Options.FileName(), - ) - return +func save(cmd *converter.Converter) { + if err := cmd.Options.SaveConfig(); err != nil { + cmd.Fatal(err) } + utils.Printf( + "%s%s\n\nSaving to %s\n", + cmd.Options.Header(), + cmd.Options.ShowConfig(), + cmd.Options.FileName(), + ) +} - if cmd.Options.Show { - utils.Println(cmd.Options.Header(), cmd.Options.ShowConfig()) - return +func show(cmd *converter.Converter) { + utils.Println(cmd.Options.Header(), cmd.Options.ShowConfig()) +} + +func reset(cmd *converter.Converter) { + if err := cmd.Options.ResetConfig(); err != nil { + cmd.Fatal(err) } - - if cmd.Options.Reset { - if err := cmd.Options.ResetConfig(); err != nil { - cmd.Fatal(err) - } - utils.Printf( - "%s%s\n\nReset default to %s\n", - cmd.Options.Header(), - cmd.Options.ShowConfig(), - cmd.Options.FileName(), - ) - return + utils.Printf( + "%s%s\n\nReset default to %s\n", + cmd.Options.Header(), + cmd.Options.ShowConfig(), + cmd.Options.FileName(), + ) + if err := cmd.Options.ResetConfig(); err != nil { + cmd.Fatal(err) } + utils.Printf( + "%s%s\n\nReset default to %s\n", + cmd.Options.Header(), + cmd.Options.ShowConfig(), + cmd.Options.FileName(), + ) +} + +func generate(cmd *converter.Converter) { if err := cmd.Validate(); err != nil { cmd.Fatal(err) }