aboutsummaryrefslogtreecommitdiff
path: root/deskutils/bookworm
diff options
context:
space:
mode:
Diffstat (limited to 'deskutils/bookworm')
-rw-r--r--deskutils/bookworm/Makefile62
-rw-r--r--deskutils/bookworm/distinfo3
-rw-r--r--deskutils/bookworm/files/patch-data_com.github.babluboy.bookworm.appdata.xml.in41
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__dict.py135
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__html.py95
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__index.py91
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__k8proc.py142
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__ncx.py98
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__opf.py38
-rw-r--r--deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__unpack.py354
-rw-r--r--deskutils/bookworm/files/patch-src_bookworm.vala15
-rw-r--r--deskutils/bookworm/files/patch-src_pdfReader.vala62
-rw-r--r--deskutils/bookworm/files/patch-src_utils.vala38
-rw-r--r--deskutils/bookworm/pkg-descr5
-rw-r--r--deskutils/bookworm/pkg-plist223
15 files changed, 1402 insertions, 0 deletions
diff --git a/deskutils/bookworm/Makefile b/deskutils/bookworm/Makefile
new file mode 100644
index 000000000000..0e680d9107c3
--- /dev/null
+++ b/deskutils/bookworm/Makefile
@@ -0,0 +1,62 @@
+PORTNAME= bookworm
+DISTVERSION= 1.1.2
+PORTREVISION= 21
+CATEGORIES= deskutils
+
+MAINTAINER= miguel@gocobachi.dev
+COMMENT= Simple, focused ebook reader
+WWW= https://babluboy.github.io/bookworm/
+
+LICENSE= GPLv3
+LICENSE_FILE= ${WRKSRC}/COPYING
+
+BUILD_DEPENDS= curl>0:ftp/curl \
+ html2text>0:textproc/html2text
+LIB_DEPENDS= libappstream-glib.so:devel/appstream-glib \
+ libgee-0.8.so:devel/libgee \
+ libgranite.so:x11-toolkits/granite \
+ libpoppler-glib.so:graphics/poppler-glib \
+ libsoup-2.4.so:devel/libsoup \
+ libwebkit2gtk-4.0.so:www/webkit2-gtk3 \
+ libxml2.so:textproc/libxml2
+RUN_DEPENDS= bash:shells/bash \
+ pdftohtml:graphics/poppler-utils \
+ unar:archivers/unarchiver \
+ unzip:archivers/unzip
+
+USES= desktop-file-utils gettext gnome meson pkgconfig \
+ python shebangfix sqlite vala:build
+USE_GITHUB= yes
+GH_ACCOUNT= babluboy
+USE_GNOME= gdkpixbuf2 glib20 gtk30 libxml2 pango
+
+GLIB_SCHEMAS= com.github.babluboy.bookworm.gschema.xml
+SHEBANG_FILES= data/scripts/com.github.babluboy.bookworm.search.sh \
+ data/scripts/mobi_lib/mobi_dict.py \
+ data/scripts/mobi_lib/mobi_html.py \
+ data/scripts/mobi_lib/mobi_index.py \
+ data/scripts/mobi_lib/mobi_k8proc.py \
+ data/scripts/mobi_lib/mobi_ncx.py \
+ data/scripts/mobi_lib/mobi_opf.py \
+ data/scripts/mobi_lib/mobi_split.py \
+ data/scripts/mobi_lib/mobi_uncompress.py \
+ data/scripts/mobi_lib/mobi_unpack.py \
+ data/scripts/mobi_lib/mobi_utils.py
+
+MESON_BUILD_DIR= build
+
+PORTDOCS= README.md
+
+OPTIONS_DEFINE= DOCS
+
+post-configure:
+ @${MKDIR} ${WRKSRC}/${MESON_BUILD_DIR}
+
+post-install-DOCS-on:
+ @${MKDIR} ${STAGEDIR}${DOCSDIR}
+ ${INSTALL_DATA} ${WRKSRC}/README.md ${STAGEDIR}${DOCSDIR}
+
+do-test:
+ cd ${WRKSRC}/${MESON_BUILD_DIR} && ${LOCALBASE}/bin/ninja test
+
+.include <bsd.port.mk>
diff --git a/deskutils/bookworm/distinfo b/deskutils/bookworm/distinfo
new file mode 100644
index 000000000000..62681da78331
--- /dev/null
+++ b/deskutils/bookworm/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1593395828
+SHA256 (babluboy-bookworm-1.1.2_GH0.tar.gz) = 6d27e55697debfa08f7cc15805413b74c94c55111cdf2d333b306228eccad824
+SIZE (babluboy-bookworm-1.1.2_GH0.tar.gz) = 2102426
diff --git a/deskutils/bookworm/files/patch-data_com.github.babluboy.bookworm.appdata.xml.in b/deskutils/bookworm/files/patch-data_com.github.babluboy.bookworm.appdata.xml.in
new file mode 100644
index 000000000000..d474e0772145
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_com.github.babluboy.bookworm.appdata.xml.in
@@ -0,0 +1,41 @@
+--- data/com.github.babluboy.bookworm.appdata.xml.in.orig 2019-08-10 18:20:51 UTC
++++ data/com.github.babluboy.bookworm.appdata.xml.in
+@@ -14,10 +14,6 @@
+ </description>
+ <screenshots>
+ <screenshot type="default">
+- <caption>Bookworm Library View</caption>
+- <image>https://raw.githubusercontent.com/babluboy/bookworm/gh-pages/images/BookwormLibraryView.png</image>
+- </screenshot>
+- <screenshot type="default">
+ <caption>Bookworm Reading View</caption>
+ <image>https://raw.githubusercontent.com/babluboy/bookworm/gh-pages/images/BookwormReadingView.png</image>
+ </screenshot>
+@@ -46,16 +42,6 @@
+ </ul>
+ </description>
+ </release>
+- <release version="1.0.0" date="2018-02-11">
+- <description>
+- <p>Right to Left Reading</p>
+- <ul>
+- <li>Support for right-to-left script</li>
+- <li>A shiny new icon and new cover images</li>
+- <li>Better support for EPUB table of contents</li>
+- </ul>
+- </description>
+- </release>
+ <release version="1.1.0" date="2018-09-30">
+ <description>
+ <p>This release has some new features, fixes and new translations:</p>
+@@ -72,8 +58,8 @@
+ <li>Some minor CSS compatibility with Juno</li>
+ </ul>
+ </description>
+- </release>
+- <release version="1.0.0" date="2018-02-11">
++ </release>
++ <release version="1.0.0" date="2018-02-11">
+ <description>
+ <p>Right to Left Reading</p>
+ <ul>
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__dict.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__dict.py
new file mode 100644
index 000000000000..f5695b3b487d
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__dict.py
@@ -0,0 +1,135 @@
+--- data/scripts/mobi_lib/mobi_dict.py.orig 2021-08-16 04:04:05 UTC
++++ data/scripts/mobi_lib/mobi_dict.py
+@@ -27,37 +27,37 @@ class dictSupport:
+
+ decodeInflection = True
+ if metaOrthIndex != 0xFFFFFFFF:
+- print "Info: Document contains orthographic index, handle as dictionary"
++ print("Info: Document contains orthographic index, handle as dictionary")
+ if metaInflIndex == 0xFFFFFFFF:
+ decodeInflection = False
+ else:
+ metaInflIndexData = sect.loadSection(metaInflIndex)
+ metaIndexCount, = struct.unpack_from('>L', metaInflIndexData, 0x18)
+ if metaIndexCount != 1:
+- print "Error: Dictionary contains multiple inflection index sections, which is not yet supported"
++ print("Error: Dictionary contains multiple inflection index sections, which is not yet supported")
+ decodeInflection = False
+ inflIndexData = sect.loadSection(metaInflIndex + 1)
+ inflNameData = sect.loadSection(metaInflIndex + 1 + metaIndexCount)
+ tagSectionStart, = struct.unpack_from('>L', metaInflIndexData, 0x04)
+ inflectionControlByteCount, inflectionTagTable = readTagSection(tagSectionStart, metaInflIndexData)
+ if DEBUG_DICT:
+- print "inflectionTagTable: %s" % inflectionTagTable
++ print("inflectionTagTable: %s" % inflectionTagTable)
+ if self.hasTag(inflectionTagTable, 0x07):
+- print "Error: Dictionary uses obsolete inflection rule scheme which is not yet supported"
++ print("Error: Dictionary uses obsolete inflection rule scheme which is not yet supported")
+ decodeInflection = False
+
+ data = sect.loadSection(metaOrthIndex)
+ tagSectionStart, = struct.unpack_from('>L', data, 0x04)
+ controlByteCount, tagTable = readTagSection(tagSectionStart, data)
+ orthIndexCount, = struct.unpack_from('>L', data, 0x18)
+- print "orthIndexCount is", orthIndexCount
++ print("orthIndexCount is", orthIndexCount)
+ if DEBUG_DICT:
+- print "orthTagTable: %s" % tagTable
++ print("orthTagTable: %s" % tagTable)
+ hasEntryLength = self.hasTag(tagTable, 0x02)
+ if not hasEntryLength:
+- print "Info: Index doesn't contain entry length tags"
++ print("Info: Index doesn't contain entry length tags")
+
+- print "Read dictionary index data"
++ print("Read dictionary index data")
+ for i in range(metaOrthIndex + 1, metaOrthIndex + 1 + orthIndexCount):
+ data = sect.loadSection(i)
+ idxtPos, = struct.unpack_from('>L', data, 0x14)
+@@ -145,10 +145,10 @@ class dictSupport:
+
+ # Make sure that the required tags are available.
+ if 0x05 not in tagMap:
+- print "Error: Required tag 0x05 not found in tagMap"
++ print("Error: Required tag 0x05 not found in tagMap")
+ return ""
+ if 0x1a not in tagMap:
+- print "Error: Required tag 0x1a not found in tagMap"
++ print("Error: Required tag 0x1a not found in tagMap")
+ return ""
+
+ result += "<idx:infl>"
+@@ -230,7 +230,7 @@ class dictSupport:
+ totalConsumed += consumed
+ values.append(data)
+ if totalConsumed != valueBytes:
+- print "Error: Should consume %s bytes, but consumed %s" % (valueBytes, totalConsumed)
++ print("Error: Should consume %s bytes, but consumed %s" % (valueBytes, totalConsumed))
+ tagHashMap[tag] = values
+
+ # Test that all bytes have been processed if endPos is given.
+@@ -238,12 +238,12 @@ class dictSupport:
+ # The last entry might have some zero padding bytes, so complain only if non zero bytes are left.
+ for char in entryData[dataStart:endPos]:
+ if char != chr(0x00):
+- print "Warning: There are unprocessed index bytes left: %s" % toHex(entryData[dataStart:endPos])
++ print("Warning: There are unprocessed index bytes left: %s" % toHex(entryData[dataStart:endPos]))
+ if DEBUG_DICT:
+- print "controlByteCount: %s" % controlByteCount
+- print "tagTable: %s" % tagTable
+- print "data: %s" % toHex(entryData[startPos:endPos])
+- print "tagHashMap: %s" % tagHashMap
++ print("controlByteCount: %s" % controlByteCount)
++ print("tagTable: %s" % tagTable)
++ print("data: %s" % toHex(entryData[startPos:endPos]))
++ print("tagHashMap: %s" % tagHashMap)
+ break
+
+ return tagHashMap
+@@ -273,10 +273,10 @@ class dictSupport:
+ position -= offset
+ elif byte > 0x13:
+ if mode == -1:
+- print "Error: Unexpected first byte %i of inflection rule" % byte
++ print("Error: Unexpected first byte %i of inflection rule" % byte)
+ return None
+ elif position == -1:
+- print "Error: Unexpected first byte %i of inflection rule" % byte
++ print("Error: Unexpected first byte %i of inflection rule" % byte)
+ return None
+ else:
+ if mode == 0x01:
+@@ -292,19 +292,19 @@ class dictSupport:
+ deleted = byteArray.pop(position)
+ if deleted != char:
+ if DEBUG_DICT:
+- print "0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, deleted)
+- print "Error: Delete operation of inflection rule failed"
++ print("0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, deleted))
++ print("Error: Delete operation of inflection rule failed")
+ return None
+ elif mode == 0x04:
+ # Delete at word start
+ deleted = byteArray.pop(position)
+ if deleted != char:
+ if DEBUG_DICT:
+- print "0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, deleted)
+- print "Error: Delete operation of inflection rule failed"
++ print("0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, deleted))
++ print("Error: Delete operation of inflection rule failed")
+ return None
+ else:
+- print "Error: Inflection rule mode %x is not implemented" % mode
++ print("Error: Inflection rule mode %x is not implemented" % mode)
+ return None
+ elif byte == 0x01:
+ # Insert at word start
+@@ -327,7 +327,7 @@ class dictSupport:
+ position = 0
+ mode = byte
+ else:
+- print "Error: Inflection rule mode %x is not implemented" % byte
++ print("Error: Inflection rule mode %x is not implemented" % byte)
+ return None
+ return byteArray.tostring()
+
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__html.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__html.py
new file mode 100644
index 000000000000..e02d8e2fcfce
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__html.py
@@ -0,0 +1,95 @@
+--- data/scripts/mobi_lib/mobi_html.py.orig 2021-08-16 04:19:38 UTC
++++ data/scripts/mobi_lib/mobi_html.py
+@@ -23,7 +23,7 @@ class HTMLProcessor:
+ def findAnchors(self, rawtext, indx_data, positionMap):
+ # process the raw text
+ # find anchors...
+- print "Find link anchors"
++ print("Find link anchors")
+ link_pattern = re.compile(r'''<[^<>]+filepos=['"]{0,1}(\d+)[^<>]*>''', re.IGNORECASE)
+ # TEST NCX: merge in filepos from indx
+ pos_links = [int(m.group(1)) for m in link_pattern.finditer(rawtext)]
+@@ -38,7 +38,7 @@ class HTMLProcessor:
+ positionMap[position] = '<a id="filepos%d" />' % position
+
+ # apply dictionary metadata and anchors
+- print "Insert data into html"
++ print("Insert data into html")
+ pos = 0
+ lastPos = len(rawtext)
+ dataList = []
+@@ -63,7 +63,7 @@ class HTMLProcessor:
+ metadata = self.metadata
+
+ # put in the hrefs
+- print "Insert hrefs into html"
++ print("Insert hrefs into html")
+ # Two different regex search and replace routines.
+ # Best results are with the second so far IMO (DiapDealer).
+
+@@ -73,11 +73,11 @@ class HTMLProcessor:
+ srctext = link_pattern.sub(r'''<a href="#filepos\1"\2>''', srctext)
+
+ # remove empty anchors
+- print "Remove empty anchors from html"
++ print("Remove empty anchors from html")
+ srctext = re.sub(r"<a/>",r"", srctext)
+
+ # convert image references
+- print "Insert image references into html"
++ print("Insert image references into html")
+ # split string into image tag pieces and other pieces
+ image_pattern = re.compile(r'''(<img.*?>)''', re.IGNORECASE)
+ image_index_pattern = re.compile(r'''recindex=['"]{0,1}([0-9]+)['"]{0,1}''', re.IGNORECASE)
+@@ -91,7 +91,7 @@ class HTMLProcessor:
+ imageNumber = int(m.group(1))
+ imageName = imgnames[imageNumber-1]
+ if imageName is None:
+- print "Error: Referenced image %s was not recognized as a valid image" % imageNumber
++ print("Error: Referenced image %s was not recognized as a valid image" % imageNumber)
+ else:
+ replacement = 'src="images/' + imageName + '"'
+ tag = re.sub(image_index_pattern, replacement, tag, 1)
+@@ -128,7 +128,7 @@ class XHTMLK8Processor:
+ posfid_index_pattern = re.compile(r'''['"]kindle:pos:fid:([0-9|A-V]+):off:([0-9|A-V]+).*?["']''')
+
+ parts = []
+- print "Building proper xhtml for each file"
++ print("Building proper xhtml for each file")
+ for i in xrange(self.k8proc.getNumberOfParts()):
+ part = self.k8proc.getPart(i)
+ [partnum, dir, filename, beg, end, aidtext] = self.k8proc.getPartInfo(i)
+@@ -227,7 +227,7 @@ class XHTMLK8Processor:
+ self.used[imageName] = 'used'
+ tag = re.sub(img_index_pattern, replacement, tag, 1)
+ else:
+- print "Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag)
++ print("Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag))
+ srcpieces[j] = tag
+ flowpart = "".join(srcpieces)
+
+@@ -246,13 +246,13 @@ class XHTMLK8Processor:
+ self.used[imageName] = 'used'
+ tag = re.sub(url_img_index_pattern, replacement, tag, 1)
+ else:
+- print "Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag)
++ print("Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag))
+ # process links to fonts
+ for m in re.finditer(font_index_pattern, tag):
+ fontNumber = fromBase32(m.group(1))
+ fontName = self.imgnames[fontNumber-1]
+ if fontName is None:
+- print "Error: Referenced font %s was not recognized as a valid font in %s" % (fontNumber, tag)
++ print("Error: Referenced font %s was not recognized as a valid font in %s" % (fontNumber, tag))
+ else:
+ replacement = '"../Fonts/' + fontName + '"'
+ tag = re.sub(font_index_pattern, replacement, tag, 1)
+@@ -345,7 +345,7 @@ class XHTMLK8Processor:
+ self.used[imageName] = 'used'
+ tag = re.sub(img_index_pattern, replacement, tag, 1)
+ else:
+- print "Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag)
++ print("Error: Referenced image %s was not recognized as a valid image in %s" % (imageNumber, tag))
+ srcpieces[j] = tag
+ part = "".join(srcpieces)
+ # store away modified version
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__index.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__index.py
new file mode 100644
index 000000000000..a5d8eb193918
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__index.py
@@ -0,0 +1,91 @@
+--- data/scripts/mobi_lib/mobi_index.py.orig 2021-08-16 04:22:14 UTC
++++ data/scripts/mobi_lib/mobi_index.py
+@@ -32,15 +32,15 @@ class MobiIndex:
+ tagSectionStart = idxhdr['len']
+ controlByteCount, tagTable = readTagSection(tagSectionStart, data)
+ if DEBUG:
+- print "IndexCount is", IndexCount
+- print "TagTable: %s" % tagTable
++ print("IndexCount is", IndexCount)
++ print("TagTable: %s" % tagTable)
+ for i in range(idx + 1, idx + 1 + IndexCount):
+ data = sect.loadSection(i)
+ hdrinfo = self.parseINDXHeader(data)
+ idxtPos = hdrinfo['start']
+ entryCount = hdrinfo['count']
+ if DEBUG:
+- print idxtPos, entryCount
++ print(idxtPos, entryCount)
+ # loop through to build up the IDXT position starts
+ idxPositions = []
+ for j in range(entryCount):
+@@ -57,8 +57,8 @@ class MobiIndex:
+ tagMap = self.getTagMap(controlByteCount, tagTable, data, startPos+1+textLength, endPos)
+ outtbl.append([text, tagMap])
+ if DEBUG:
+- print tagMap
+- print text
++ print(tagMap)
++ print(text)
+ return outtbl, ctoc_text
+
+ def getTagMap(self, controlByteCount, tagTable, entryData, startPos, endPos):
+@@ -118,19 +118,19 @@ class MobiIndex:
+ totalConsumed += consumed
+ values.append(data)
+ if totalConsumed != valueBytes:
+- print "Error: Should consume %s bytes, but consumed %s" % (valueBytes, totalConsumed)
++ print("Error: Should consume %s bytes, but consumed %s" % (valueBytes, totalConsumed))
+ tagHashMap[tag] = values
+ # Test that all bytes have been processed if endPos is given.
+ if endPos is not None and dataStart != endPos:
+ # The last entry might have some zero padding bytes, so complain only if non zero bytes are left.
+ for char in entryData[dataStart:endPos]:
+ if char != chr(0x00):
+- print "Warning: There are unprocessed index bytes left: %s" % toHex(entryData[dataStart:endPos])
++ print("Warning: There are unprocessed index bytes left: %s" % toHex(entryData[dataStart:endPos]))
+ if DEBUG:
+- print "controlByteCount: %s" % controlByteCount
+- print "tagTable: %s" % tagTable
+- print "data: %s" % toHex(entryData[startPos:endPos])
+- print "tagHashMap: %s" % tagHashMap
++ print("controlByteCount: %s" % controlByteCount)
++ print("tagTable: %s" % tagTable)
++ print("data: %s" % toHex(entryData[startPos:endPos]))
++ print("tagHashMap: %s" % tagHashMap)
+ break
+
+ return tagHashMap
+@@ -154,7 +154,7 @@ class MobiIndex:
+ def parseINDXHeader(self, data):
+ "read INDX header"
+ if not data[:4] == 'INDX':
+- print "Warning: index section is not INDX"
++ print("Warning: index section is not INDX")
+ return False
+ words = (
+ 'len', 'nul1', 'type', 'gen', 'start', 'count', 'code',
+@@ -166,10 +166,10 @@ class MobiIndex:
+ for n in range(num):
+ header[words[n]] = values[n]
+ if DEBUG:
+- print "parsed INDX header:"
++ print("parsed INDX header:")
+ for n in words:
+- print n, "%X" % header[n],
+- print
++ print(n, "%X" % header[n])
++ print("")
+ return header
+
+ def readCTOC(self, txtdata):
+@@ -187,7 +187,7 @@ class MobiIndex:
+ name = txtdata[offset:offset+ilen]
+ offset += ilen
+ if DEBUG:
+- print "name length is ", ilen
+- print idx_offs, name
++ print("name length is ", ilen)
++ print(idx_offs, name)
+ ctoc_data[idx_offs] = name
+ return ctoc_data
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__k8proc.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__k8proc.py
new file mode 100644
index 000000000000..3c198a5d1216
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__k8proc.py
@@ -0,0 +1,142 @@
+--- data/scripts/mobi_lib/mobi_k8proc.py.orig 2021-08-16 04:24:52 UTC
++++ data/scripts/mobi_lib/mobi_k8proc.py
+@@ -33,11 +33,11 @@ class K8Processor:
+ sections = header[0x0c:]
+ self.fdsttbl = struct.unpack_from('>%dL' % (num_sections*2), sections, 0)[::2] + (0xfffffff, )
+ else:
+- print "Error: K8 Mobi with Missing FDST info"
++ print("Error: K8 Mobi with Missing FDST info")
+ if self.DEBUG:
+- print "\nFDST Section Map: %d entries" % len(self.fdsttbl)
++ print("\nFDST Section Map: %d entries" % len(self.fdsttbl))
+ for j in xrange(len(self.fdsttbl)):
+- print " %d - %0x" % (j, self.fdsttbl[j])
++ print(" %d - %0x" % (j, self.fdsttbl[j]))
+
+ # read/process skeleton index info to create the skeleton table
+ skeltbl = []
+@@ -50,10 +50,10 @@ class K8Processor:
+ fileptr += 1
+ self.skeltbl = skeltbl
+ if self.DEBUG:
+- print "\nSkel Table: %d entries" % len(self.skeltbl)
+- print "table: filenum, skeleton name, div tbl record count, start position, length"
++ print("\nSkel Table: %d entries" % len(self.skeltbl))
++ print("table: filenum, skeleton name, div tbl record count, start position, length")
+ for j in xrange(len(self.skeltbl)):
+- print self.skeltbl[j]
++ print(self.skeltbl[j])
+
+ # read/process the div index to create to <div> (and <p>) table
+ divtbl = []
+@@ -66,10 +66,10 @@ class K8Processor:
+ divtbl.append([int(text), ctocdata, tagMap[3][0], tagMap[4][0], tagMap[6][0], tagMap[6][1]])
+ self.divtbl = divtbl
+ if self.DEBUG:
+- print "\nDiv (Fragment) Table: %d entries" % len(self.divtbl)
+- print "table: file position, link id text, file num, sequence number, start position, length"
++ print("\nDiv (Fragment) Table: %d entries" % len(self.divtbl))
++ print("table: file position, link id text, file num, sequence number, start position, length")
+ for j in xrange(len(self.divtbl)):
+- print self.divtbl[j]
++ print(self.divtbl[j])
+
+ # read / process other index <guide> element of opf
+ othtbl = []
+@@ -88,10 +88,10 @@ class K8Processor:
+ othtbl.append([ref_type, ref_title, fileno])
+ self.othtbl = othtbl
+ if self.DEBUG:
+- print "\nOther (Guide) Table: %d entries" % len(self.othtbl)
+- print "table: ref_type, ref_title, divtbl entry number"
++ print("\nOther (Guide) Table: %d entries" % len(self.othtbl))
++ print("table: ref_type, ref_title, divtbl entry number")
+ for j in xrange(len(self.othtbl)):
+- print self.othtbl[j]
++ print(self.othtbl[j])
+
+
+ def buildParts(self, rawML):
+@@ -103,7 +103,7 @@ class K8Processor:
+ if end == 0xffffffff:
+ end = len(rawML)
+ if self.DEBUG:
+- print "splitting rawml starting at %d and ending at %d into flow piece %d" % (start, end, j)
++ print("splitting rawml starting at %d and ending at %d into flow piece %d" % (start, end, j))
+ self.flows.append(rawML[start:end])
+
+ # the first piece represents the xhtml text
+@@ -114,7 +114,7 @@ class K8Processor:
+ # *without* destroying any file position information needed for later href processing
+ # and create final list of file separation start: stop points and etc in partinfo
+ if self.DEBUG:
+- print "\nRebuilding flow piece 0: the main body of the ebook"
++ print("\nRebuilding flow piece 0: the main body of the ebook")
+ self.parts = []
+ self.partinfo = []
+ divptr = 0
+@@ -125,8 +125,8 @@ class K8Processor:
+ for i in range(divcnt):
+ [insertpos, idtext, filenum, seqnum, startpos, length] = self.divtbl[divptr]
+ if self.DEBUG:
+- print " moving div/frag %d starting at %d of length %d" % (divptr, startpos, length)
+- print " inside of skeleton number %d at postion %d" % (skelnum, insertpos)
++ print(" moving div/frag %d starting at %d of length %d" % (divptr, startpos, length))
++ print(" inside of skeleton number %d at postion %d" % (skelnum, insertpos))
+ if i == 0:
+ aidtext = idtext[12:-2]
+ filename = 'part%04d.xhtml' % filenum
+@@ -198,14 +198,14 @@ class K8Processor:
+ self.flowinfo.append([type, format, dir, fname])
+
+ if self.DEBUG:
+- print "\nFlow Map: %d entries" % len(self.flowinfo)
++ print("\nFlow Map: %d entries" % len(self.flowinfo))
+ for fi in self.flowinfo:
+- print fi
+- print "\n"
++ print(fi)
++ print("\n")
+
+- print "\nXHTML File Part Position Information: %d entries" % len(self.partinfo)
++ print("\nXHTML File Part Position Information: %d entries" % len(self.partinfo))
+ for pi in self.partinfo:
+- print pi
++ print(pi)
+
+ if False: # self.DEBUG:
+ # dump all of the locations of the aid tags used in TEXT
+@@ -214,12 +214,12 @@ class K8Processor:
+ # [^>]* means match any amount of chars except for '>' char
+ # [^'"] match any amount of chars except for the quote character
+ # \s* means match any amount of whitespace
+- print "\npositions of all aid= pieces"
++ print("\npositions of all aid= pieces")
+ id_pattern = re.compile(r'''<[^>]*\said\s*=\s*['"]([^'"]*)['"][^>]*>''',re.IGNORECASE)
+ for m in re.finditer(id_pattern, rawML):
+- print "%0x %s %0x" % (m.start(), m.group(1), fromBase32(m.group(1)))
++ print("%0x %s %0x" % (m.start(), m.group(1), fromBase32(m.group(1))))
+ [filename, partnum, start, end] = self.getFileInfo(m.start())
+- print " in %d %0x %0x" % (partnum, start, end)
++ print(" in %d %0x %0x" % (partnum, start, end))
+
+ return
+
+@@ -300,7 +300,7 @@ class K8Processor:
+ n = len(idtbl)
+ if n == 0:
+ if self.DEBUG:
+- print "Found no id in the textblock, link must be to top of file"
++ print("Found no id in the textblock, link must be to top of file")
+ return ''
+ # if npos is before first id= inside a tag, return the first
+ if npos < idtbl[0][0] :
+@@ -315,7 +315,7 @@ class K8Processor:
+ tgt = r-1
+ break
+ if self.DEBUG:
+- print pos, npos, idtbl[tgt]
++ print(pos, npos, idtbl[tgt])
+ return idtbl[tgt][1]
+
+
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__ncx.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__ncx.py
new file mode 100644
index 000000000000..efc028ed0cd2
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__ncx.py
@@ -0,0 +1,98 @@
+--- data/scripts/mobi_lib/mobi_ncx.py.orig 2021-08-16 04:25:11 UTC
++++ data/scripts/mobi_lib/mobi_ncx.py
+@@ -34,8 +34,8 @@ class ncxExtract:
+ if self.ncxidx != 0xffffffff:
+ outtbl, ctoc_text = self.mi.getIndexData(self.ncxidx)
+ if DEBUG_NCX:
+- print ctoc_text
+- print outtbl
++ print(ctoc_text)
++ print(outtbl)
+ num = 0
+ for [text, tagMap] in outtbl:
+ tmp = {
+@@ -68,16 +68,16 @@ class ncxExtract:
+ tmp['kind'] = ctoc_text.get(fieldvalue, 'Unknown Kind')
+ indx_data.append(tmp)
+ if DEBUG_NCX:
+- print "record number: ", num
+- print "name: ", tmp['name'],
+- print "position", tmp['pos']," length: ", tmp['len']
+- print "text: ", tmp['text']
+- print "kind: ", tmp['kind']
+- print "heading level: ", tmp['hlvl']
+- print "parent:", tmp['parent']
+- print "first child: ",tmp['child1']," last child: ", tmp['childn']
+- print "pos_fid is ", tmp['pos_fid']
+- print "\n\n"
++ print("record number: ", num)
++ print("name: ", tmp['name'])
++ print("position", tmp['pos']," length: ", tmp['len'])
++ print("text: ", tmp['text'])
++ print("kind: ", tmp['kind'])
++ print("heading level: ", tmp['hlvl'])
++ print("parent:", tmp['parent'])
++ print("first child: ",tmp['child1']," last child: ", tmp['childn'])
++ print("pos_fid is ", tmp['pos_fid'])
++ print("\n\n")
+ num += 1
+ num += 1
+ self.indx_data = indx_data
+@@ -118,10 +118,10 @@ class ncxExtract:
+ #recursive part
+ def recursINDX(max_lvl=0, num=0, lvl=0, start=-1, end=-1):
+ if start>len(indx_data) or end>len(indx_data):
+- print "Warning: missing INDX child entries", start, end, len(indx_data)
++ print("Warning: missing INDX child entries", start, end, len(indx_data))
+ return ''
+ if DEBUG_NCX:
+- print "recursINDX lvl %d from %d to %d" % (lvl, start, end)
++ print("recursINDX lvl %d from %d to %d" % (lvl, start, end))
+ xml = ''
+ if start <= 0:
+ start = 0
+@@ -155,13 +155,13 @@ class ncxExtract:
+ header = ncx_header % (ident, max_lvl + 1, title)
+ ncx = header + body + ncx_footer
+ if not len(indx_data) == num:
+- print "Warning: different number of entries in NCX", len(indx_data), num
++ print("Warning: different number of entries in NCX", len(indx_data), num)
+ return ncx
+
+ def writeNCX(self, metadata):
+ # build the xml
+ self.isNCX = True
+- print "Write ncx"
++ print("Write ncx")
+ htmlname = os.path.basename(self.files.outbase)
+ htmlname += '.html'
+ xml = self.buildNCX(htmlname, metadata['Title'][0], metadata['UniqueID'][0])
+@@ -202,10 +202,10 @@ class ncxExtract:
+ #recursive part
+ def recursINDX(max_lvl=0, num=0, lvl=0, start=-1, end=-1):
+ if start>len(indx_data) or end>len(indx_data):
+- print "Warning: missing INDX child entries", start, end, len(indx_data)
++ print("Warning: missing INDX child entries", start, end, len(indx_data))
+ return ''
+ if DEBUG_NCX:
+- print "recursINDX lvl %d from %d to %d" % (lvl, start, end)
++ print("recursINDX lvl %d from %d to %d" % (lvl, start, end))
+ xml = ''
+ if start <= 0:
+ start = 0
+@@ -244,13 +244,13 @@ class ncxExtract:
+ header = ncx_header % (ident, max_lvl + 1, title)
+ ncx = header + body + ncx_footer
+ if not len(indx_data) == num:
+- print "Warning: different number of entries in NCX", len(indx_data), num
++ print("Warning: different number of entries in NCX", len(indx_data), num)
+ return ncx
+
+ def writeK8NCX(self, ncx_data, metadata):
+ # build the xml
+ self.isNCX = True
+- print "Write K8 ncx"
++ print("Write K8 ncx")
+ xml = self.buildK8NCX(ncx_data, metadata['Title'][0], metadata['UniqueID'][0])
+ bname = 'toc.ncx'
+ ncxname = os.path.join(self.files.k8oebps,bname)
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__opf.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__opf.py
new file mode 100644
index 000000000000..cd27f3646c95
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__opf.py
@@ -0,0 +1,38 @@
+--- data/scripts/mobi_lib/mobi_opf.py.orig 2021-08-16 04:25:19 UTC
++++ data/scripts/mobi_lib/mobi_opf.py
+@@ -21,7 +21,7 @@ class OPFProcessor:
+
+ def writeOPF(self, has_obfuscated_fonts=False):
+ # write out the metadata as an OEB 1.0 OPF file
+- print "Write opf"
++ print("Write opf")
+ metadata = self.metadata
+
+ META_TAGS = ['Drm Server Id', 'Drm Commerce Id', 'Drm Ebookbase Book Id', 'ASIN', 'ThumbOffset', 'Fake Cover',
+@@ -100,7 +100,7 @@ class OPFProcessor:
+ imageNumber = int(metadata['CoverOffset'][0])
+ self.covername = self.imgnames[imageNumber]
+ if self.covername is None:
+- print "Error: Cover image %s was not recognized as a valid image" % imageNumber
++ print("Error: Cover image %s was not recognized as a valid image" % imageNumber)
+ else:
+ if self.isK8:
+ data.append('<meta name="cover" content="cover_img" />\n')
+@@ -126,7 +126,7 @@ class OPFProcessor:
+ priceList = metadata['Price']
+ currencyList = metadata['Currency']
+ if len(priceList) != len(currencyList):
+- print "Error: found %s price entries, but %s currency entries."
++ print("Error: found %s price entries, but %s currency entries.")
+ else:
+ for i in range(len(priceList)):
+ data.append('<SRP Currency="'+currencyList[i]+'">'+priceList[i]+'</SRP>\n')
+@@ -137,7 +137,7 @@ class OPFProcessor:
+ imageNumber = int(metadata['ThumbOffset'][0])
+ imageName = self.imgnames[imageNumber]
+ if imageName is None:
+- print "Error: Cover Thumbnail image %s was not recognized as a valid image" % imageNumber
++ print("Error: Cover Thumbnail image %s was not recognized as a valid image" % imageNumber)
+ else:
+ if self.isK8:
+ data.append('<meta name="Cover ThumbNail Image" content="'+ 'Images/'+imageName+'" />\n')
diff --git a/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__unpack.py b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__unpack.py
new file mode 100644
index 000000000000..dd3ca576da73
--- /dev/null
+++ b/deskutils/bookworm/files/patch-data_scripts_mobi__lib_mobi__unpack.py
@@ -0,0 +1,354 @@
+--- data/scripts/mobi_lib/mobi_unpack.py.orig 2021-08-16 04:42:50 UTC
++++ data/scripts/mobi_lib/mobi_unpack.py
+@@ -256,7 +256,7 @@ class MobiHeader:
+ self.header = self.sect.loadSection(self.start)
+ self.records, = struct.unpack_from('>H', self.header, 0x8)
+ self.length, self.type, self.codepage, self.unique_id, self.version = struct.unpack('>LLLLL', self.header[20:40])
+- print "Mobi Version: ", self.version
++ print("Mobi Version: ", self.version)
+
+ # codec
+ self.codec = 'windows-1252'
+@@ -266,18 +266,18 @@ class MobiHeader:
+ }
+ if self.codepage in codec_map.keys():
+ self.codec = codec_map[self.codepage]
+- print "Codec: ", self.codec
++ print("Codec: ", self.codec)
+
+ # title
+ toff, tlen = struct.unpack('>II', self.header[0x54:0x5c])
+ tend = toff + tlen
+ self.title=self.header[toff:tend]
+- print "Title: ", self.title
++ print("Title: ", self.title)
+
+ # set up for decompression/unpacking
+ compression, = struct.unpack_from('>H', self.header, 0x0)
+ if compression == 0x4448:
+- print "Huffdic compression"
++ print("Huffdic compression")
+ reader = HuffcdicReader()
+ huffoff, huffnum = struct.unpack_from('>LL', self.header, 0x70)
+ huffoff = huffoff + self.start
+@@ -286,10 +286,10 @@ class MobiHeader:
+ reader.loadCdic(self.sect.loadSection(huffoff+i))
+ self.unpack = reader.unpack
+ elif compression == 2:
+- print "Palmdoc compression"
++ print("Palmdoc compression")
+ self.unpack = PalmdocReader().unpack
+ elif compression == 1:
+- print "No compression"
++ print("No compression")
+ self.unpack = UncompressedReader().unpack
+ else:
+ raise unpackException('invalid compression type: 0x%4x' % compression)
+@@ -376,14 +376,14 @@ class MobiHeader:
+ self.fdst += self.start
+
+ if DEBUG:
+- print "firstaddl %0x" % self.firstaddl
+- print "ncxidx %0x" % self.ncxidx
+- print "exth flags %0x" % exth_flag
++ print("firstaddl %0x" % self.firstaddl)
++ print("ncxidx %0x" % self.ncxidx)
++ print("exth flags %0x" % exth_flag)
+ if self.version == 8 or self.start != 0:
+- print "skelidx %0x" % self.skelidx
+- print "dividx %0x" % self.dividx
+- print "othidx %0x" % self.othidx
+- print "fdst %0x" % self.fdst
++ print("skelidx %0x" % self.skelidx)
++ print("dividx %0x" % self.dividx)
++ print("othidx %0x" % self.othidx)
++ print("fdst %0x" % self.fdst)
+
+ # NOTE: See DumpMobiHeader.py for a complete set of header fields
+
+@@ -464,7 +464,7 @@ class MobiHeader:
+ trailers += 1
+ flags = flags >> 1
+ # get raw mobi markup languge
+- print "Unpack raw markup language"
++ print("Unpack raw markup language")
+ dataList = []
+ # offset = 0
+ for i in xrange(1, self.records+1):
+@@ -542,7 +542,7 @@ class MobiHeader:
+ else:
+ metadata[name].append(value)
+ if DEBUG:
+- print "multiple values: metadata[%s]=%s" % (name, metadata[name])
++ print("multiple values: metadata[%s]=%s" % (name, metadata[name]))
+ _length, num_items = struct.unpack('>LL', extheader[4:12])
+ extheader = extheader[12:]
+ pos = 0
+@@ -564,12 +564,12 @@ class MobiHeader:
+ value, = struct.unpack('>L',content)
+ addValue(name, str(value))
+ else:
+- print "Error: Value for %s has unexpected size of %s" % (name, size)
++ print("Error: Value for %s has unexpected size of %s" % (name, size))
+ elif id in id_map_hexstrings.keys():
+ name = id_map_hexstrings[id]
+ addValue(name, content.encode('hex'))
+ else:
+- print "Warning: Unknown metadata with id %s found" % id
++ print("Warning: Unknown metadata with id %s found" % id)
+ name = str(id) + ' (hex)'
+ addValue(name, content.encode('hex'))
+ pos += size
+@@ -600,11 +600,11 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ for mh in mhlst:
+
+ if mh.isK8():
+- print "\n\nProcessing K8 format Ebook ..."
++ print("\n\nProcessing K8 format Ebook ...")
+ elif mh.isPrintReplica():
+- print "\nProcessing PrintReplica (.azw4) format Ebook ..."
++ print("\nProcessing PrintReplica (.azw4) format Ebook ...")
+ else:
+- print "\nProcessing Mobi format Ebook ..."
++ print("\nProcessing Mobi format Ebook ...")
+
+ if DEBUG:
+ # write out raw mobi header data
+@@ -624,8 +624,8 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ metadata['Codec'] = [mh.codec]
+ metadata['UniqueID'] = [str(mh.unique_id)]
+ if DEBUG:
+- print "MetaData from EXTH"
+- print metadata
++ print("MetaData from EXTH")
++ print(metadata)
+
+ # save the raw markup language
+ rawML = mh.getRawML()
+@@ -643,12 +643,12 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+
+ # process additional sections that represent images, resources, fonts, and etc
+ # build up a list of image names to use to postprocess the rawml
+- print "Unpacking images, resources, fonts, etc"
++ print("Unpacking images, resources, fonts, etc")
+ firstaddl = mh.getfirstAddl()
+ if DEBUG:
+- print "firstaddl is ", firstaddl
+- print "num_sections is ", sect.num_sections
+- print "K8Boundary is ", K8Boundary
++ print("firstaddl is ", firstaddl)
++ print("num_sections is ", sect.num_sections)
++ print("K8Boundary is ", K8Boundary)
+ beg = firstaddl
+ end = sect.num_sections
+ if firstaddl < K8Boundary:
+@@ -656,12 +656,12 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ obfuscate_data = []
+ for i in xrange(beg, end):
+ if DEBUG:
+- print "Section is ", i
++ print("Section is ", i)
+ data = sect.loadSection(i)
+ type = data[0:4]
+ if type in ["FLIS", "FCIS", "FDST", "DATP"]:
+ if DEBUG:
+- print 'First 4 bytes: %s' % toHex(data[0:4])
++ print('First 4 bytes: %s' % toHex(data[0:4]))
+ fname = "%05d" % (1+i-beg)
+ fname = type + fname
+ if mh.isK8():
+@@ -669,13 +669,13 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ fname += '.dat'
+ outname= os.path.join(files.outdir, fname)
+ file(outname, 'wb').write(data)
+- print "Skipping ", type, " section"
++ print("Skipping ", type, " section")
+ imgnames.append(None)
+ continue
+ elif type == "SRCS":
+ # The mobi file was created by kindlegen and contains a zip archive with all source files.
+ # Extract the archive and save it.
+- print " Info: File contains kindlegen source archive, extracting as %s" % KINDLEGENSRC_FILENAME
++ print(" Info: File contains kindlegen source archive, extracting as %s" % KINDLEGENSRC_FILENAME)
+ srcname = os.path.join(files.outdir, KINDLEGENSRC_FILENAME)
+ file(srcname, 'wb').write(data[16:])
+ imgnames.append(None)
+@@ -709,29 +709,29 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ adler32, = struct.unpack_from('>I', font_data, len(font_data) - 4)
+ font_data = zlib.decompress(font_data[2:-4], -wbits, usize)
+ if len(font_data) != usize:
+- print 'Font Decompression Error: Uncompressed font size mismatch'
++ print('Font Decompression Error: Uncompressed font size mismatch')
+ if False:
+ # For some reason these almost never match, probably Amazon has a
+ # buggy Adler32 implementation
+ sig = (zlib.adler32(font_data) & 0xffffffff)
+ if sig != adler32:
+- print 'Font Decompression Error'
+- print 'Adler checksum did not match. Stored: %d Calculated: %d' % (adler32, sig)
++ print('Font Decompression Error')
++ print('Adler checksum did not match. Stored: %d Calculated: %d' % (adler32, sig))
+ else:
+- print "Error Decoding Font", str(err)
++ print("Error Decoding Font", str(err))
+ hdr = font_data[0:4]
+ if hdr == '\0\1\0\0' or hdr == 'true' or hdr == 'ttcf':
+ ext = '.ttf'
+ elif hdr == 'OTTO':
+ ext = '.otf'
+ else:
+- print "Warning: unknown font header %s" % hdr.encode('hex')
++ print("Warning: unknown font header %s" % hdr.encode('hex'))
+ ext = '.dat'
+ fontname = "font%05d" % (1+i-beg)
+ fontname += ext
+ if (ext == '.ttf' or ext == '.otf') and (fflags & 0x0002):
+ obfuscate_data.append(fontname)
+- print " extracting font: ", fontname
++ print(" extracting font: ", fontname)
+ outfnt = os.path.join(files.imgdir, fontname)
+ file(outfnt, 'wb').write(font_data)
+ imgnames.append(fontname)
+@@ -746,7 +746,7 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ if DEBUG:
+ data = data[4:]
+ rescname = "resc%05d.dat" % (1+i-beg)
+- print " extracting resource: ", rescname
++ print(" extracting resource: ", rescname)
+ outrsc = os.path.join(files.imgdir, rescname)
+ file(outrsc, 'wb').write(data)
+ imgnames.append(None)
+@@ -754,7 +754,7 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+
+ if data == EOF_RECORD:
+ if DEBUG:
+- print "Skip section %i as it contains the EOF record." % i
++ print("Skip section %i as it contains the EOF record." % i)
+ imgnames.append(None)
+ continue
+
+@@ -762,16 +762,16 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ # Get the proper file extension
+ imgtype = imghdr.what(None, data)
+ if imgtype is None:
+- print "Warning: Section %s contains no image or an unknown image format" % i
++ print("Warning: Section %s contains no image or an unknown image format" % i)
+ imgnames.append(None)
+ if DEBUG:
+- print 'First 4 bytes: %s' % toHex(data[0:4])
++ print('First 4 bytes: %s' % toHex(data[0:4]))
+ fname = "unknown%05d.dat" % (1+i-beg)
+ outname= os.path.join(files.outdir, fname)
+ file(outname, 'wb').write(data)
+ else:
+ imgname = "image%05d.%s" % (1+i-beg, imgtype)
+- print " extracting image: ", imgname
++ print(" extracting image: ", imgname)
+ outimg = os.path.join(files.imgdir, imgname)
+ file(outimg, 'wb').write(data)
+ imgnames.append(imgname)
+@@ -781,11 +781,11 @@ def process_all_mobi_headers(files, sect, mhlst, K8Bou
+ # Process print replica book.
+ if mh.isPrintReplica() and not k8only:
+ filenames = []
+- print "Print Replica ebook detected"
++ print("Print Replica ebook detected")
+ try:
+ mh.processPrintReplica(files)
+- except Exception, e:
+- print 'Error processing Print Replica: ' + str(e)
++ except Exception as e:
++ print('Error processing Print Replica: ' + str(e))
+ filenames.append(['', files.getInputFileBasename() + '.pdf'])
+ usedmap = {}
+ for name in imgnames:
+@@ -915,7 +915,7 @@ def unpackBook(infile, outdir):
+
+ # process the PalmDoc database header and verify it is a mobi
+ sect = Sectionizer(infile)
+- print "Palm DB type: ", sect.ident
++ print("Palm DB type: ", sect.ident)
+ if sect.ident != 'BOOKMOBI' and sect.ident != 'TEXtREAd':
+ raise unpackException('invalid file format')
+
+@@ -945,7 +945,7 @@ def unpackBook(infile, outdir):
+ if (after - before) == 8:
+ data = sect.loadSection(i)
+ if data == K8_BOUNDARY:
+- print "Mobi Ebook uses the new K8 file format"
++ print("Mobi Ebook uses the new K8 file format")
+ mh = MobiHeader(sect,i+1)
+ hasK8 = hasK8 or mh.isK8()
+ mhlst.append(mh)
+@@ -1010,32 +1010,32 @@ class Mobi8Reader:
+
+
+ def usage(progname):
+- print ""
+- print "Description:"
+- print " Unpacks an unencrypted Kindle/MobiPocket ebook to html and images"
+- print " or an unencrypted Kindle/Print Replica ebook to PDF and images"
+- print " into the specified output folder."
+- print "Usage:"
+- print " %s -r -s -d -h infile [outdir]" % progname
+- print "Options:"
+- print " -r write raw data to the output folder"
+- print " -s split combination mobis into mobi7 and mobi8 ebooks"
+- print " -d enable verbose debugging"
+- print " -h print this help message"
++ print("")
++ print("Description:")
++ print(" Unpacks an unencrypted Kindle/MobiPocket ebook to html and images")
++ print(" or an unencrypted Kindle/Print Replica ebook to PDF and images")
++ print(" into the specified output folder.")
++ print("Usage:")
++ print(" %s -r -s -d -h infile [outdir]" % progname)
++ print("Options:")
++ print(" -r write raw data to the output folder")
++ print(" -s split combination mobis into mobi7 and mobi8 ebooks")
++ print(" -d enable verbose debugging")
++ print(" -h print this help message")
+
+
+ def main(argv=sys.argv):
+ global DEBUG
+ global WRITE_RAW_DATA
+ global SPLIT_COMBO_MOBIS
+- print "MobiUnpack 0.47"
+- print " Copyright (c) 2009 Charles M. Hannum <root@ihack.net>"
+- print " With Additions by P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding."
++ print("MobiUnpack 0.47")
++ print(" Copyright (c) 2009 Charles M. Hannum <root@ihack.net>")
++ print(" With Additions by P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding.")
+ progname = os.path.basename(argv[0])
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hdrs")
+- except getopt.GetoptError, err:
+- print str(err)
++ except getopt.GetoptError as err:
++ print(str(err))
+ usage(progname)
+ sys.exit(2)
+
+@@ -1062,16 +1062,16 @@ def main(argv=sys.argv):
+
+ infileext = os.path.splitext(infile)[1].upper()
+ if infileext not in ['.MOBI', '.PRC', '.AZW', '.AZW4']:
+- print "Error: first parameter must be a Kindle/Mobipocket ebook or a Kindle/Print Replica ebook."
++ print("Error: first parameter must be a Kindle/Mobipocket ebook or a Kindle/Print Replica ebook.")
+ return 1
+
+ try:
+- print 'Unpacking Book...'
++ print('Unpacking Book...')
+ unpackBook(infile, outdir)
+- print 'Completed'
++ print('Completed')
+
+- except ValueError, e:
+- print "Error: %s" % e
++ except ValueError as e:
++ print("Error: %s" % e)
+ return 1
+
+ return 0
diff --git a/deskutils/bookworm/files/patch-src_bookworm.vala b/deskutils/bookworm/files/patch-src_bookworm.vala
new file mode 100644
index 000000000000..162cbd1b28bb
--- /dev/null
+++ b/deskutils/bookworm/files/patch-src_bookworm.vala
@@ -0,0 +1,15 @@
+--- src/bookworm.vala.orig 2019-08-10 18:20:51 UTC
++++ src/bookworm.vala
+@@ -481,7 +481,11 @@ public class BookwormApp.Bookworm : Granite.Applicatio
+ //Run dicovery of books as a background task if not already running
+ string checkBackgroundTask = BookwormApp.Utils.execute_sync_command("ps -ef");
+ if(checkBackgroundTask.index_of("bookworm --discover") == -1){
+- BookwormApp.Utils.execute_async_multiarg_command_pipes({"com.github.babluboy.bookworm", "--discover", "&"});
++ BookwormApp.Utils.execute_async_command({
++ "com.github.babluboy.bookworm",
++ "--discover",
++ "&"
++ });
+ }else{
+ debug("Bookworm discover process already running....");
+ }
diff --git a/deskutils/bookworm/files/patch-src_pdfReader.vala b/deskutils/bookworm/files/patch-src_pdfReader.vala
new file mode 100644
index 000000000000..179345937e4d
--- /dev/null
+++ b/deskutils/bookworm/files/patch-src_pdfReader.vala
@@ -0,0 +1,62 @@
+--- src/pdfReader.vala.orig 2019-08-10 18:20:51 UTC
++++ src/pdfReader.vala
+@@ -26,6 +26,7 @@ public class BookwormApp.pdfReader {
+ debug("Initiated process for parsing of PDF Book located at:"+aBook.getBookLocation());
+ //Extract the content of the PDF
+ string extractionLocation = extractEBook(aBook.getBookLocation());
++
+ if("false" == extractionLocation){ //handle error condition
+ aBook.setIsBookParsed(false);
+ aBook.setParsingIssue(BookwormApp.Constants.TEXT_FOR_EXTRACTION_ISSUE);
+@@ -60,30 +61,38 @@ public class BookwormApp.pdfReader {
+ public static string extractEBook(string eBookLocation){
+ info("[START] [FUNCTION:extractEBook] eBookLocation="+eBookLocation);
+ string extractionLocation = "false";
+- debug("Initiated process for content extraction of PDF Book located at:"+eBookLocation);
++
++ debug("Initiated process for content extraction of PDF Book located at:"+eBookLocation);
++
+ if(BookwormApp.Bookworm.settings == null){
+ BookwormApp.Bookworm.settings = BookwormApp.Settings.get_instance();
+ }
++
+ //create a location for extraction of eBook based on local storage prefference
+ if(BookwormApp.Bookworm.settings.is_local_storage_enabled){
+ extractionLocation = BookwormApp.Bookworm.bookworm_config_path + "/books/" + File.new_for_path(eBookLocation).get_basename();
+ }else{
+ extractionLocation = BookwormApp.Constants.EBOOK_EXTRACTION_LOCATION + File.new_for_path(eBookLocation).get_basename();
+ }
++
+ //check and create directory for extracting contents of ebook
+ BookwormApp.Utils.fileOperations("CREATEDIR", extractionLocation, "", "");
+- //extract eBook contents into temp location
+- BookwormApp.Utils.execute_async_multiarg_command_pipes({"pdftohtml",
+- "-noframes",
+- "-zoom", "2.0",
+- "-wbt", "20.0",
+- "-nomerge",
+- eBookLocation,
+- extractionLocation + "/" + File.new_for_path(eBookLocation).get_basename()+".html"
+- });
+-
+- debug("Output of pdftohtml command:"+BookwormApp.Utils.spawn_async_with_pipes_output.str);
+- info("[END] [FUNCTION:extractEBook] extractionLocation="+extractionLocation);
++
++ BookwormApp.Utils.execute_async_command({
++ "pdftohtml",
++ "-noframes",
++ "-zoom", "2.0",
++ "-wbt", "20.0",
++ "-nomerge",
++ eBookLocation,
++ extractionLocation
++ + "/"
++ + File.new_for_path(eBookLocation).get_basename()
++ + ".html"
++ });
++
++ info("[END] [FUNCTION:extractEBook] extractionLocation=" + extractionLocation);
++
+ return extractionLocation;
+ }
+
diff --git a/deskutils/bookworm/files/patch-src_utils.vala b/deskutils/bookworm/files/patch-src_utils.vala
new file mode 100644
index 000000000000..a214dd77af44
--- /dev/null
+++ b/deskutils/bookworm/files/patch-src_utils.vala
@@ -0,0 +1,38 @@
+--- src/utils.vala.orig 2019-08-10 18:20:51 UTC
++++ src/utils.vala
+@@ -94,6 +94,35 @@ namespace BookwormApp.Utils {
+ debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]...");
+ return 0;
+ }
++
++ public int execute_async_command(string[] args) {
++ MainLoop loop = new MainLoop();
++
++ try {
++ Pid child;
++
++ Process.spawn_async(
++ "/",
++ args,
++ null,
++ SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
++ null,
++ out child
++ );
++
++ ChildWatch.add(child, (pid, status) => {
++ Process.close_pid(pid);
++
++ loop.quit();
++ });
++
++ loop.run();
++ } catch (SpawnError error) {
++ warning("ERROR execute_async_command (" + string.joinv(" ", args) + ")");
++ }
++
++ return 0;
++ }
+
+ public string execute_sync_command (string cmd){
+ debug("Starting to execute sync command ["+cmd+"]...");
diff --git a/deskutils/bookworm/pkg-descr b/deskutils/bookworm/pkg-descr
new file mode 100644
index 000000000000..9a11b99d80b8
--- /dev/null
+++ b/deskutils/bookworm/pkg-descr
@@ -0,0 +1,5 @@
+Bookworm is a simple, focused eBook reader.
+
+Read the books you love without having to worry about the different format
+complexities like epub, pdf, mobi, cbr, etc. This version supports EPUB, PDF
+and Comics (CBR and CBZ) formats with support for more formats to follow soon.
diff --git a/deskutils/bookworm/pkg-plist b/deskutils/bookworm/pkg-plist
new file mode 100644
index 000000000000..dd3fbda7ba73
--- /dev/null
+++ b/deskutils/bookworm/pkg-plist
@@ -0,0 +1,223 @@
+bin/com.github.babluboy.bookworm
+share/applications/com.github.babluboy.bookworm.desktop
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_dict.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_html.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_index.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_k8proc.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_ncx.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_opf.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_split.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_uncompress.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_unpack.py
+share/com.github.babluboy.bookworm/scripts/mobi_lib/mobi_utils.py
+share/com.github.babluboy.bookworm/scripts/tasks/com.github.babluboy.bookworm.dictionary.sh
+share/com.github.babluboy.bookworm/scripts/tasks/com.github.babluboy.bookworm.search.sh
+share/icons/hicolor/128x128/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/128x128@2/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/16x16/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/16x16@2/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/24x24/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/24x24@2/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/32x32/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/32x32@2/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/48x48/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/48x48@2/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/64x64/apps/com.github.babluboy.bookworm.svg
+share/icons/hicolor/64x64@2/apps/com.github.babluboy.bookworm.svg
+share/locale/aa/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ab/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ae/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/af/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ak/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/am/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/an/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ar/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/as/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ast/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/av/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ay/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/az/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ba/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/be/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bh/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bm/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/br/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/bs/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ca/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ce/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ch/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ckb/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/co/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/cr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/cs/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/cu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/cv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/cy/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/da/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/de/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/dv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/dz/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ee/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/el/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/en_AU/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/en_CA/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/en_GB/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/eo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/es/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/es_MX/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/et/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/eu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fa/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ff/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fj/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fr_CA/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/fy/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ga/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/gd/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/gl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/gn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/gu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/gv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ha/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/he/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/hi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ho/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/hr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ht/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/hu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/hy/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/hz/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ia/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/id/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ie/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ig/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ii/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ik/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/io/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/is/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/it/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/iu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ja/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/jv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ka/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ki/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kj/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kk/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/km/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ko/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ks/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ku/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/kw/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ky/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/la/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lb/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/li/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ln/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lt/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/lv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mh/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mk/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ml/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ms/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/mt/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/my/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/na/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nb_NO/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nd/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ne/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ng/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/nv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ny/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/oc/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/oj/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/om/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/or/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/os/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/pa/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/pi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/pl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ps/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/pt/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/pt_BR/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/qu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/rm/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/rn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ro/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ru/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/rue/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/rw/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sa/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sc/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sd/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/se/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/si/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sk/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sm/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sma/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/so/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sq/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ss/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/st/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/su/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sv/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/sw/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ta/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/te/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tg/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/th/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ti/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tk/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tl/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tn/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/to/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tr/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ts/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tt/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/tw/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ty/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ug/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/uk/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ur/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/uz/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/ve/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/vi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/vo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/wa/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/wo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/xh/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/yi/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/yo/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/za/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/zh/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/zh_CN/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/zh_HK/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/zh_TW/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/locale/zu/LC_MESSAGES/com.github.babluboy.bookworm.mo
+share/metainfo/com.github.babluboy.bookworm.appdata.xml