From a6fcfd3d486d44f2d79cc5c72f3bb1f833152a1a Mon Sep 17 00:00:00 2001 From: Patrick Gaskin Date: Fri, 18 Oct 2019 22:30:14 -0400 Subject: [PATCH] Added cover path utilities * Image part hashing based on @shermp's Kobo-UNCaGED code. * Qt resizing algorithm re-implementation based on our (@NiLuJe, @geek1011) implementation for KU. * Path/ImageID/ContentID conversion based on my seriesmeta code from kepubify. --- kobo/device.go | 9 ++++++++- kobo/util.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/kobo/device.go b/kobo/device.go index 6c4480d..2252d0a 100644 --- a/kobo/device.go +++ b/kobo/device.go @@ -322,7 +322,7 @@ func (c CoverType) String() string { return c.NickelString() } -// Resize returnes the dimensions to resize sz to for the cover type and target size. +// Resize returns the dimensions to resize sz to for the cover type and target size. func (c CoverType) Resize(target image.Point, sz image.Point) image.Point { switch c { case CoverTypeLibList: @@ -333,6 +333,13 @@ func (c CoverType) Resize(target image.Point, sz image.Point) image.Point { panic("unknown cover type") } +// GeneratePath generates the path for the cover of an ImageID. The path is always +// separated with forward slashes. +func (c CoverType) GeneratePath(iid string) string { + dir1, dir2, base := hashedImageParts(iid) + return fmt.Sprintf(".kobo-images/%s/%s/%s - %s.jpg", dir1, dir2, base, c.NickelString()) +} + func (d Device) StorageGB() int { switch d { case DeviceTouchAB, DeviceTouchC, DeviceMini: diff --git a/kobo/util.go b/kobo/util.go index 8e6b71f..39e6dbd 100644 --- a/kobo/util.go +++ b/kobo/util.go @@ -1,11 +1,29 @@ package kobo import ( + "fmt" "image" + "path/filepath" "strconv" "strings" ) +// PathToContentID generates the Kobo ContentId for a path relative to the +// internal storage root (slashes are converted to forward slashes automatically). +func PathToContentID(relpath string) string { + return fmt.Sprintf("file:///mnt/onboard/%s", filepath.ToSlash(relpath)) +} + +// ContentIDToImageID converts the Kobo ContentId to the ImageId. +func ContentIDToImageID(contentID string) string { + return strings.NewReplacer( + " ", "_", + "/", "_", + ":", "_", + ".", "_", + ).Replace(contentID) +} + // resizeKeepAspectRatio resizes sz to fill bounds while keeping the aspect // ratio. It is based on the code for QSize::scaled with the modes // Qt::KeepAspectRatio and Qt::KeepAspectRatioByExpanding. @@ -30,6 +48,20 @@ func resizeKeepAspectRatio(sz image.Point, bounds image.Point, expand bool) imag return image.Pt(bounds.X, int(float64(bounds.X)/ar)) } +// hashedImageParts returns the parts needed for constructing the path to the +// cached image. The result can be applied like: +// .kobo-images/{dir1}/{dir2}/{basename} - N3_SOMETHING.jpg +func hashedImageParts(imageID string) (dir1, dir2, basename string) { + imgID := []byte(imageID) + h := uint32(0x00000000) + for _, x := range imgID { + h = (h << 4) + uint32(x) + h ^= (h & 0xf0000000) >> 23 + h &= 0x0fffffff + } + return fmt.Sprintf("%d", h&(0xff*1)), fmt.Sprintf("%d", (h&(0xff00*1))>>8), imageID +} + func strSplitInt(str string) []int64 { spl := strings.Split(str, ".") ints := make([]int64, len(spl))