Initial Commit

This commit is contained in:
LunarEclipse 2024-04-27 23:23:40 +02:00
commit 00828d4c08
9 changed files with 999 additions and 0 deletions

553
MainWindow.glade Normal file
View File

@ -0,0 +1,553 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<template class="main_window" parent="GtkApplicationWindow">
<property name="can-focus">False</property>
<property name="title" translatable="yes">PDF Table Extractor</property>
<property name="icon-name">document-page-setup</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox" id="header_left_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkButtonBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="layout-style">expand</property>
<child>
<object class="GtkButton" id="open_button">
<property name="label" translatable="yes">Open</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_open_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="always-show-image">True</property>
<signal name="clicked" handler="on_open_button_small_clicked" swapped="no"/>
<signal name="clicked" handler="test" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">pan-down-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="released" handler="example_button_released_cb" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">zoom-draw-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="header_right_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="always-show-image">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
<accessibility>
<action action_name="click" description="Expand Menu"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject">
<property name="AtkObject::accessible-name" translatable="yes">Extra Options</property>
<property name="AtkObject::accessible-role">menu</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButtonBox" id="save_button_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="layout-style">expand</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Save</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="always-show-image">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">document-save-as-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkPaned" id="main_paned">
<property name="visible">True</property>
<property name="app-paintable">True</property>
<property name="can-focus">True</property>
<property name="position">800</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkListBox" id="pdf_list_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child type="placeholder">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="spacing">5</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">dialog-information</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Open a file to begin</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook1">
<property name="width-request">300</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkListBox" id="general_tab">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Scan All Pages</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="tooltip-text" translatable="yes">Custom Page Selection</property>
<property name="placeholder-text" translatable="yes">e.g. 2-6, 9, 12-16</property>
<property name="input-hints">GTK_INPUT_HINT_NO_SPELLCHECK | GTK_INPUT_HINT_NONE</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="left-padding">12</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Guess Table Locations</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Lattice Mode</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Force PDF to be extracted using lattice-mode extraction
(if there are ruling lines separating each cell, as in a PDF of an Excel spreadsheet)</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Use Line Returns</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Use embedded line returns (Lattice Mode only)</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Options</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">General</property>
</object>
<packing>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
<object class="GtkListBoxRow" id="selection_tab">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkListBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Manually Set Column Positions</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;TODO: column display&gt;</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="left-padding">12</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Lattice Mode</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Force PDF to be extracted using lattice-mode extraction
(if there are ruling lines separating each cell, as in a PDF of an Excel spreadsheet)</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Use Line Returns</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Use embedded line returns (Lattice Mode only)</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Options</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Selection</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab-fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</template>
<object class="GtkFileFilter" id="pdfFileFilter">
<mime-types>
<mime-type>application/pdf</mime-type>
</mime-types>
</object>
</interface>

1
README.md Normal file
View File

@ -0,0 +1 @@
# Silly :3

67
experiments/draw_test.py Normal file
View File

@ -0,0 +1,67 @@
import sys
import traceback
from typing import Dict, List, Optional, Sequence, Tuple, TypeAlias
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gio, Gtk, GObject
gi.require_foreign("cairo")
import cairo
class CustomDrawingArea(Gtk.DrawingArea):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_size_request(200, 200)
self.set_app_paintable(True)
self.connect_after("draw", self.on_draw, {})
def on_draw(self, widget: Gtk.DrawingArea, cr: cairo.Context, data: GObject.GPointer):
width = widget.get_allocated_width()
height = widget.get_allocated_height()
print(f"w: {width}, h: {height}")
sctx = widget.get_style_context()
Gtk.render_background(sctx, cr, 0, 0, width, height)
cr.set_source_rgba(1.0, 0.0, 0.0, 1.0)
cr.rectangle(0, 0, width, height)
cr.fill()
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app: Application = self.get_application() # type: ignore
assert self.app is not None
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.add(box)
self.area = CustomDrawingArea()
frame = Gtk.Frame(label="DrawingArea")
frame.add(self.area)
box.pack_start(frame, expand=True, fill=True, padding=20)
box.add(Gtk.Button(label=":)"))
class Application(Gtk.Application):
def __init__(self, *args, **kwargs):
super().__init__(
*args,
application_id="zone.lunareclipse.draw_test",
flags=Gio.ApplicationFlags.FLAGS_NONE,
**kwargs
)
self.window = None
def do_activate(self):
self.window = self.window or MainWindow(application=self)
self.window.show_all()
if __name__ == "__main__":
app = Application()
app.run(sys.argv)

17
experiments/main.py Normal file
View File

@ -0,0 +1,17 @@
import argparse
import tabula
if __name__ == "__main__":
#parser = argparse.ArgumentParser()
#parser.add_argument("filename")
#args = parser.parse_args()
table = tabula.io.read_pdf(
"../sources/2018_Torres-Benitez_Metabolomic analysis Parmotrema.pdf",
pages=[5],
lattice=False,
multiple_tables=True,
)
print(table)
print("test")

View File

@ -0,0 +1,54 @@
import sys
from typing import Dict, List, Optional, Sequence, Tuple, TypeAlias
from PySide6.QtWidgets import QApplication, QDialog, QHBoxLayout, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PySide6.QtCore import Slot
from PySide6.QtPdf import QPdfDocument
from PySide6.QtPdfWidgets import QPdfView
import fitz
TEST_FILENAME = "/home/luna/Documents/Resources/Praca Licencjacka/sources/2018_Torres-Benitez_Metabolomic analysis Parmotrema.pdf"
Coords: TypeAlias = Tuple[float, float]
class Selection:
def __init__(self, bounds: Tuple[Coords, Coords], columns: Optional[Sequence[float]] = None):
self.bounds = bounds
self.columns = columns
class Document:
def __init__(self, filename: str):
self.filename = filename
self.document = fitz.Document(filename)
self.selections: Dict[int, List[Selection]] = {}
class SelectablePdfView(QPdfView):
pass
class State():
pass
class Frontend():
def __init__(self, argv: Sequence[str]):
self.app = QApplication(argv)
self.window = QMainWindow()
self.state = State()
self.thumbnails = QWidget()
self.pdfDocument = QPdfDocument()
self.optionsPanel = QWidget()
central_widget = QWidget()
cw_layout = QHBoxLayout(central_widget)
cw_layout.addWidget(self.thumbnails)
cw_layout.addWidget(self.optionsPanel)
self.window.setCentralWidget(central_widget)
def exec(self):
self.window.show()
self.app.exec()
if __name__ == "__main__":
app = Frontend(sys.argv)
app.exec()

41
experiments/qt6_test.py Normal file
View File

@ -0,0 +1,41 @@
import sys
from typing import Sequence
from PySide6.QtWidgets import QApplication, QDialog, QLabel, QPushButton, QVBoxLayout
from PySide6.QtCore import Slot
class Application():
def __init__(self, argv: Sequence[str]):
self.app = QApplication(argv)
self.counter = 0
self.window = QDialog()
self.layout = QVBoxLayout(self.window)
self.label = QLabel("0")
self.button_increment = QPushButton("Increment counter!")
self.button_decrement = QPushButton("Decrement counter!")
self.window.setWindowTitle("PDF Table Extractor")
self.layout.addWidget(self.label)
self.layout.addWidget(self.button_increment)
self.layout.addWidget(self.button_decrement)
self.button_increment.clicked.connect(self.increment)
self.button_decrement.clicked.connect(self.decrement)
print(self.window.layout())
@Slot()
def increment(self):
self.counter += 1
self.label.setText(f"{self.counter}")
@Slot()
def decrement(self):
self.counter -= 1
self.label.setText(f"{self.counter}")
def exec(self):
self.window.show()
self.app.exec()
if __name__ == "__main__":
app = Application(sys.argv)
app.exec()

84
experiments/test.py Normal file
View File

@ -0,0 +1,84 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class FileChooserWindow(Gtk.Window):
def __init__(self):
super().__init__(title="FileChooser Example")
box = Gtk.Box(spacing=6)
self.add(box)
button1 = Gtk.Button(label="Choose File")
button1.connect("clicked", self.on_file_clicked)
box.add(button1)
button2 = Gtk.Button(label="Choose Folder")
button2.connect("clicked", self.on_folder_clicked)
box.add(button2)
def on_file_clicked(self, widget):
dialog = Gtk.FileChooserDialog(
title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN
)
dialog.add_buttons(
Gtk.STOCK_CANCEL,
Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN,
Gtk.ResponseType.OK,
)
self.add_filters(dialog)
response = dialog.run()
if response == Gtk.ResponseType.OK:
print("Open clicked")
print("File selected: " + dialog.get_filename())
elif response == Gtk.ResponseType.CANCEL:
print("Cancel clicked")
dialog.destroy()
def add_filters(self, dialog):
filter_text = Gtk.FileFilter()
filter_text.set_name("Text files")
filter_text.add_mime_type("text/plain")
dialog.add_filter(filter_text)
filter_py = Gtk.FileFilter()
filter_py.set_name("Python files")
filter_py.add_mime_type("text/x-python")
dialog.add_filter(filter_py)
filter_any = Gtk.FileFilter()
filter_any.set_name("Any files")
filter_any.add_pattern("*")
dialog.add_filter(filter_any)
def on_folder_clicked(self, widget):
dialog = Gtk.FileChooserDialog(
title="Please choose a folder",
parent=self,
action=Gtk.FileChooserAction.SELECT_FOLDER,
)
dialog.add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK
)
dialog.set_default_size(800, 400)
response = dialog.run()
if response == Gtk.ResponseType.OK:
print("Select clicked")
print("Folder selected: " + dialog.get_filename())
elif response == Gtk.ResponseType.CANCEL:
print("Cancel clicked")
dialog.destroy()
win = FileChooserWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

160
pdf_table_extractor.py Normal file
View File

@ -0,0 +1,160 @@
import sys
import traceback
from typing import Dict, List, Optional, Sequence, Tuple, TypeAlias
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gio, Gtk, GObject
gi.require_foreign("cairo")
import cairo
import fitz
TEST_FILENAME = "/home/luna/Documents/Resources/Praca Licencjacka/sources/2018_Torres-Benitez_Metabolomic analysis Parmotrema.pdf"
Coords: TypeAlias = Tuple[float, float]
class Selection:
def __init__(self, bounds: Tuple[Coords, Coords], columns: Optional[Sequence[float]] = None):
self.bounds = bounds
self.columns = columns
class Document:
def __init__(self, filename: str):
self.filename = filename
self.document = fitz.Document(filename)
self.selections: Dict[int, List[Selection]] = {}
class State():
pass
class PdfPage(Gtk.DrawingArea):
def __init__(self, page, *args, **kwargs):
super().__init__(*args, **kwargs)
self.page: fitz.Page = page
pix = self.page.get_pixmap(dpi=300) # type: ignore
self.set_size_request(pix.width, pix.height)
self.set_app_paintable(True) # type: ignore
self.connect("draw", self.on_draw, {})
def on_draw(self, widget, cr: cairo.Context, data: GObject.GPointer):
#app: Application = widget.get_window().get_application() # type: ignore
width = self.get_allocated_width()
height = self.get_allocated_height()
sctx = self.get_style_context()
Gtk.render_background(sctx, cr, 0, 0, width, height)
pix = self.page.get_pixmap(dpi=300) # type: ignore
png = pix.tobytes("png")
ims = cairo.ImageSurface.create_from_png(png)
cr.set_source_surface(ims, 0, 0)
cr.paint()
cr.set_source_rgba(255, 0, 0)
cr.set_line_width(10)
cr.move_to(0, 0)
cr.line_to(width, height)
cr.stroke()
@Gtk.Template.from_file("MainWindow.glade")
class MainWindow(Gtk.ApplicationWindow):
__gtype_name__ = "main_window"
open_button: Gtk.Button = Gtk.Template.Child() # type: ignore
header_bar: Gtk.HeaderBar = Gtk.Template.Child() # type: ignore
main_paned: Gtk.Paned = Gtk.Template.Child() # type: ignore
pdf_list_box: Gtk.ListBox = Gtk.Template.Child() # type: ignore
pdfFileFilter: Gtk.FileFilter = Gtk.Template.Child() # type: ignore
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app: Application = self.get_application() # type: ignore
assert self.app is not None
self.app.connect("notify::document", self.on_document_updated)
#self.pdf_list_box.add(PdfPage())
#@Gtk.Template.Callback()
#def example_button_released_cb(self, widget: Gtk.Button, **kwargs):
# assert self.example_button == widget
# print(widget.get_label())
# widget.set_label("woah")
@Gtk.Template.Callback()
def on_open_button_clicked(self, widget, *args, **kwargs):
dialog = Gtk.FileChooserDialog(
title="Choose PDF File to open",
transient_for=self, # equivalent to parent=
action=Gtk.FileChooserAction.OPEN,
filter=self.pdfFileFilter,
modal=True,
)
dialog.add_button("Cancel", Gtk.ResponseType.CANCEL)
dialog.add_button("Open", Gtk.ResponseType.ACCEPT)
response = dialog.run() # type: ignore
if response == Gtk.ResponseType.ACCEPT:
filename: str = dialog.get_filename() # type: ignore
try:
self.app.set_property("document", Document(filename))
except Exception as e:
message_dialog = Gtk.MessageDialog(
title="An error has occured.",
transient_for=self,
modal=True,
message_type=Gtk.MessageType.ERROR,
text=repr(e),
secondary_text=traceback.format_exc(),
buttons=Gtk.ButtonsType.OK,
)
message_dialog.run() # type: ignore
message_dialog.destroy()
dialog.destroy()
# Note: this won't run unless a new document object is put into place
# editing an existing one won't trigger it
def on_document_updated(self, recvobj, gparamstring):
document: Document = self.app.get_property("document")
self.header_bar.set_title(document.filename.split("/")[-1]) # type: ignore
self.header_bar.set_subtitle(document.filename) # type: ignore
for i in document.document.pages(): # type: ignore
page = PdfPage(i)
box = Gtk.Box()
box.pack_start(page, True, True, 20)
self.pdf_list_box.add(box) # type: ignore
@Gtk.Template.Callback()
def on_open_button_small_clicked(self, widget, **kwargs):
pass
class Application(Gtk.Application):
document = GObject.Property(type=GObject.TYPE_PYOBJECT, flags=GObject.ParamFlags.READWRITE)
def __init__(self, *args, **kwargs):
super().__init__(
*args,
application_id="zone.lunareclipse.pdf_table_extractor",
flags=Gio.ApplicationFlags.FLAGS_NONE,
#flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE, # TODO
**kwargs
)
self.window = None
def do_activate(self):
self.window = self.window or MainWindow(application=self)
self.window.show_all() # type: ignore
if __name__ == "__main__":
app = Application()
app.run(sys.argv)

22
pyproject.toml Normal file
View File

@ -0,0 +1,22 @@
[tool.poetry]
name = "pdf_table_extractor"
version = "0.1.0"
description = "Tool for extracting tabular data from PDFs"
authors = ["LunarEclipse <luna@lunareclipse.zone>"]
license = "GPL-3.0-only"
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.11,<3.13"
pygobject = "^3.48.2"
tabula-py = "^2.9.0"
PyMuPDF = "^1.24.0"
#pdfplumber = "^0.11.0"
#PySide6 = "^6.6.3" # qt
[tool.poetry.group.dev.dependencies]
pygobject-stubs = "^2.11.0" # this is actually broken lol
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"