commit:     7393925a7d78fc70d02c40ce93c2041422162955
Author:     Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 10 03:18:12 2023 +0000
Commit:     Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org>
CommitDate: Mon Apr 10 03:18:43 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=7393925a

app-text/krop: Drop PyPdf2 dependency, use pikepdf

Bug: https://bugs.gentoo.org/889246
Signed-off-by: Andreas K. Hüttel <dilfridge <AT> gentoo.org>

 app-text/krop/files/krop-0.6.0-links.patch   |  64 ++++++++++++
 app-text/krop/files/krop-0.6.0-pikepdf.patch | 150 +++++++++++++++++++++++++++
 app-text/krop/krop-0.6.0-r2.ebuild           |  47 +++++++++
 3 files changed, 261 insertions(+)

diff --git a/app-text/krop/files/krop-0.6.0-links.patch 
b/app-text/krop/files/krop-0.6.0-links.patch
new file mode 100644
index 000000000000..c311b10cf88e
--- /dev/null
+++ b/app-text/krop/files/krop-0.6.0-links.patch
@@ -0,0 +1,64 @@
+From a39f8328cf59492e68643f499c0d0fbda910444c Mon Sep 17 00:00:00 2001
+From: Armin Straub <31167361+arminstr...@users.noreply.github.com>
+Date: Sun, 17 Jan 2021 15:50:49 -0600
+Subject: [PATCH] Preserve links within a PDF (thanks to chrthi)
+
+---
+ ChangeLog          |  4 ++++
+ krop/mainwindow.py |  1 +
+ krop/pdfcropper.py | 11 +++++++++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/ChangeLog b/ChangeLog
+index eb7dbb1..4ffbedb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++krop (0.6.1)  2021-00-00 -- Armin Straub
++
++  * Preserve links within a PDF (thanks to chrthi for doing this).
++
+ krop (0.6.0)  2020-06-09 -- Armin Straub
+ 
+   + Fixed aspect ratios, like letter size, can be chosen for selections.
+diff --git a/krop/mainwindow.py b/krop/mainwindow.py
+index fd1ae32..e8adadf 100644
+--- a/krop/mainwindow.py
++++ b/krop/mainwindow.py
+@@ -413,6 +413,7 @@ def slotKrop(self):
+             pdf = PdfFile()
+             pdf.loadFromFile(inputFileName)
+             cropper = PdfCropper()
++            cropper.copyDocumentRoot(pdf)
+             for nr in pages:
+                 c = self.viewer.cropValues(nr)
+                 cropper.addPageCropped(pdf, nr, c, alwaysinclude, rotation)
+diff --git a/krop/pdfcropper.py b/krop/pdfcropper.py
+index 679c6fc..db30646 100644
+--- a/krop/pdfcropper.py
++++ b/krop/pdfcropper.py
+@@ -55,6 +55,8 @@ def writeToFile(self, filename):
+         stream.close()
+     def addPageCropped(self, pdffile, pagenumber, croplist, rotate=0):
+         pass
++    def copyDocumentRoot(self, pdffile):
++        pass
+ 
+ 
+ class PyPdfFile(AbstractPdfFile):
+@@ -110,6 +112,15 @@ def cropPage(self, page, crop, rotate):
+         if rotate != 0:
+             page.rotateClockwise(rotate)
+ 
++    def copyDocumentRoot(self, pdffile):
++        # Sounds promising in PyPDF2 (see 
PdfFileWriter.cloneDocumentFromReader),
++        # but doesn't seem to produce a readable PDF:
++        # self.output.cloneReaderDocumentRoot(pdffile.reader)
++        # Instead, this copies at least the named destinations for links:
++        for dest in pdffile.reader.namedDestinations.values():
++            self.output.addNamedDestinationObject(dest)
++
++
+ def optimizePdfGhostscript(oldfilename, newfilename):
+     import subprocess
+     subprocess.check_call(('gs', '-sDEVICE=pdfwrite', '-sOutputFile=' + 
newfilename,

diff --git a/app-text/krop/files/krop-0.6.0-pikepdf.patch 
b/app-text/krop/files/krop-0.6.0-pikepdf.patch
new file mode 100644
index 000000000000..17f59f2f72b3
--- /dev/null
+++ b/app-text/krop/files/krop-0.6.0-pikepdf.patch
@@ -0,0 +1,150 @@
+From b1d17b605088e118a8799fd027a892310e00d29e Mon Sep 17 00:00:00 2001
+From: Hongzhuo Liang <lianghongz...@126.com>
+Date: Fri, 27 Jan 2023 17:57:04 +0100
+Subject: [PATCH] support pikepdf instead of pypdf2
+
+---
+ krop/mainwindow.py |  1 -
+ krop/pdfcropper.py | 79 ++++++++++++++--------------------------------
+ 2 files changed, 24 insertions(+), 56 deletions(-)
+
+diff --git a/krop/mainwindow.py b/krop/mainwindow.py
+index e8adadf..fd1ae32 100644
+--- a/krop/mainwindow.py
++++ b/krop/mainwindow.py
+@@ -413,7 +413,6 @@ def slotKrop(self):
+             pdf = PdfFile()
+             pdf.loadFromFile(inputFileName)
+             cropper = PdfCropper()
+-            cropper.copyDocumentRoot(pdf)
+             for nr in pages:
+                 c = self.viewer.cropValues(nr)
+                 cropper.addPageCropped(pdf, nr, c, alwaysinclude, rotation)
+diff --git a/krop/pdfcropper.py b/krop/pdfcropper.py
+index db30646..42500de 100644
+--- a/krop/pdfcropper.py
++++ b/krop/pdfcropper.py
+@@ -15,23 +15,8 @@
+ 
+ import copy
+ import sys
++from pikepdf import Pdf
+ 
+-# Unless specified otherwise, use PyPDF2 instead of pyPdf if available.
+-usepypdf2 = '--no-PyPDF2' not in sys.argv
+-if usepypdf2:
+-    try:
+-        from PyPDF2 import PdfFileReader, PdfFileWriter
+-    except ImportError:
+-        usepypdf2 = False
+-if not usepypdf2:
+-    try:
+-        from pyPdf import PdfFileReader, PdfFileWriter
+-    except ImportError:
+-        _msg = "Please install PyPDF2 (or its predecessor pyPdf) first."\
+-            "\n\tOn recent versions of Ubuntu, the following should do the 
trick:"\
+-            "\n\tsudo apt-get install python-pypdf2"\
+-            "\n\t(or, if using python3) sudo apt-get install python3-pypdf2"
+-        raise RuntimeError(_msg)
+ 
+ class PdfEncryptedError(Exception):
+     pass
+@@ -55,8 +40,6 @@ def writeToFile(self, filename):
+         stream.close()
+     def addPageCropped(self, pdffile, pagenumber, croplist, rotate=0):
+         pass
+-    def copyDocumentRoot(self, pdffile):
+-        pass
+ 
+ 
+ class PyPdfFile(AbstractPdfFile):
+@@ -64,23 +47,16 @@ class PyPdfFile(AbstractPdfFile):
+     def __init__(self):
+         self.reader = None
+     def loadFromStream(self, stream):
+-        if usepypdf2:
+-            self.reader = PdfFileReader(stream, strict=False)
+-        else:
+-            self.reader = PdfFileReader(stream)
+-        if self.reader.isEncrypted:
+-            try:
+-                if not self.reader.decrypt(''):
+-                    raise PdfEncryptedError
+-            except:
+-                raise PdfEncryptedError
+-    def getPage(self, nr):
+-        page = self.reader.getPage(nr-1)
++        self.reader = Pdf.open(stream)
++        if self.reader.is_encrypted:
++            raise PdfEncryptedError
++
+ 
+ class PyPdfCropper(AbstractPdfCropper):
+     """Implementation of PdfCropper using pyPdf"""
+     def __init__(self):
+-        self.output = PdfFileWriter()
++        self.pdf = Pdf.new()
++
+     def writeToStream(self, stream):
+         # For certain large pdf files, PdfFileWriter.write() causes the error:
+         #  maximum recursion depth exceeded while calling a Python object
+@@ -88,37 +64,31 @@ def writeToStream(self, stream):
+         # We therefore temporarily increase the recursion limit.
+         old_reclimit = sys.getrecursionlimit()
+         sys.setrecursionlimit(10000)
+-        self.output.write(stream)
++        self.pdf.save(stream)
+         sys.setrecursionlimit(old_reclimit)
++
+     def addPageCropped(self, pdffile, pagenumber, croplist, alwaysinclude, 
rotate=0):
+-        page = pdffile.reader.getPage(pagenumber)
++        page = pdffile.reader.pages[pagenumber]
+         if not croplist and alwaysinclude:
+-            self.output.addPage(page)
++            self.pdf.pages.append(page)
+         for c in croplist:
+-            newpage = copy.copy(page)
+-            self.cropPage(newpage, c, rotate)
+-            self.output.addPage(newpage)
+-    def cropPage(self, page, crop, rotate):
++            new_box = self.getCropPageParm(page, c)
++            # Update the various PDF boxes
++            new_page = copy.copy(page)
++            new_page.mediabox = new_box
++            new_page.cropbox = new_box
++            new_page.trimbox = new_box
++            if rotate != 0:
++                new_page.rotate(rotate, True)
++            self.pdf.pages.append(new_page)
++
++    def getCropPageParm(self, page, crop):
+         # Note that the coordinate system is up-side down compared with Qt.
+-        x0, y0 = page.cropBox.lowerLeft
+-        x1, y1 = page.cropBox.upperRight
++        x0, y0, x1, y1 = page.cropbox
+         x0, y0, x1, y1 = float(x0), float(y0), float(x1), float(y1)
+         x0, x1 = x0+crop[0]*(x1-x0), x1-crop[2]*(x1-x0)
+         y0, y1 = y0+crop[3]*(y1-y0), y1-crop[1]*(y1-y0)
+-        # Update the various PDF boxes
+-        for box in (page.artBox, page.bleedBox, page.cropBox, page.mediaBox, 
page.trimBox):
+-            box.lowerLeft = (x0, y0)
+-            box.upperRight = (x1, y1)
+-        if rotate != 0:
+-            page.rotateClockwise(rotate)
+-
+-    def copyDocumentRoot(self, pdffile):
+-        # Sounds promising in PyPDF2 (see 
PdfFileWriter.cloneDocumentFromReader),
+-        # but doesn't seem to produce a readable PDF:
+-        # self.output.cloneReaderDocumentRoot(pdffile.reader)
+-        # Instead, this copies at least the named destinations for links:
+-        for dest in pdffile.reader.namedDestinations.values():
+-            self.output.addNamedDestinationObject(dest)
++        return [x0, y0, x1, y1]
+ 
+ 
+ def optimizePdfGhostscript(oldfilename, newfilename):
+@@ -128,4 +98,3 @@ def optimizePdfGhostscript(oldfilename, newfilename):
+ 
+ PdfFile = PyPdfFile
+ PdfCropper = PyPdfCropper
+-

diff --git a/app-text/krop/krop-0.6.0-r2.ebuild 
b/app-text/krop/krop-0.6.0-r2.ebuild
new file mode 100644
index 000000000000..830a5e54f24d
--- /dev/null
+++ b/app-text/krop/krop-0.6.0-r2.ebuild
@@ -0,0 +1,47 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+PYTHON_COMPAT=( python3_{9,10} )
+DISTUTILS_USE_SETUPTOOLS=rdepend
+
+inherit desktop distutils-r1 xdg-utils
+
+if [[ ${PV} == 9999 ]] ; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/arminstraub/krop.git";
+else
+       SRC_URI="https://github.com/arminstraub/${PN}/archive/v${PV}.tar.gz -> 
${P}.tar.gz"
+       KEYWORDS="~amd64 ~x86"
+fi
+
+DESCRIPTION="A tool to crop PDF files"
+HOMEPAGE="http://arminstraub.com/software/krop";
+
+LICENSE="GPL-3"
+SLOT="0"
+IUSE=""
+
+PATCHES=(
+       "${FILESDIR}/${P}-links.patch"
+       "${FILESDIR}/${P}-pikepdf.patch"
+)
+
+RDEPEND="dev-python/python-poppler-qt5[${PYTHON_USEDEP}]
+       dev-python/pikepdf[${PYTHON_USEDEP}]
+       dev-python/PyQt5[${PYTHON_USEDEP},gui,widgets]"
+
+src_install() {
+       distutils-r1_src_install
+       domenu "${WORKDIR}/${P}/${PN}.desktop"
+}
+
+pkg_postinst() {
+       xdg_mimeinfo_database_update
+       xdg_desktop_database_update
+}
+
+pkg_postrm() {
+       xdg_mimeinfo_database_update
+       xdg_desktop_database_update
+}

Reply via email to