PK >HhTi i edocuments/process.py# -*- coding: utf-8 -*-
import os
import re
from tempfile import NamedTemporaryFile
from subprocess import check_call
from shutil import copyfile
import edocuments
def process(
names, filename=None, destination_filename=None,
in_extention=None, progress=None, progress_text=""):
cmds = edocuments.config.get("cmds", {})
out_ext = in_extention
original_filename = filename
if destination_filename is None:
destination_filename = filename
for no, name in enumerate(names):
cmd = cmds.get(name)
if cmd is None:
raise "Missing command '%s' in `cmds`" % name
if isinstance(cmd, str):
cmd = dict(cmd=cmd)
if cmd.get('type') == 'rename':
destination_filename = _rename(cmd, destination_filename)
else:
if 'out_ext' in cmd:
out_ext = cmd['out_ext']
inplace = cmd.get('inplace', False)
cmd_cmd = cmd.get('cmd')
if inplace:
out_name = filename
else:
if out_ext is None:
out_name = NamedTemporaryFile(mode='w+b').name
else:
out_name = NamedTemporaryFile(
mode='w+b',
suffix='.' + out_ext
).name
params = {}
if filename is not None:
params["in"] = "'%s'" % filename.replace("'", "'\''")
if not inplace:
params["out"] = "'%s'" % out_name.replace("'", "'\''")
cmd_cmd = cmd_cmd.format(**params)
print("{name}: {cmd}".format(name=name, cmd=cmd_cmd))
if progress is not None:
progress.setLabelText(progress_text.format(name=name, **cmd))
if progress.wasCanceled():
return
check_call(cmd_cmd, shell=True)
if progress is not None:
progress.setValue(no + 1)
filename = out_name
if original_filename is not None and original_filename != filename:
os.unlink(original_filename)
if out_ext is not None:
destination_filename = "%s.%s" % (re.sub(
r"\.[a-z0-9A-Z]{2,5}$", "",
destination_filename
), out_ext)
if filename != destination_filename:
directory = os.path.dirname(destination_filename)
print(directory)
if not os.path.exists(directory):
os.makedirs(directory)
copyfile(filename, destination_filename)
os.unlink(filename)
return destination_filename
def _rename(cmd, destination_filename):
from_re = cmd.get('from')
to_re = cmd.get('to')
if cmd.get('format') in ['upper', 'lower']:
def format_term(term):
if cmd.get('format') == 'upper':
return term.upper()
else:
return term.lower()
to_re = lambda m: format_term(m.group(0))
return re.sub(from_re, to_re, destination_filename)
def destination_filename(names, filename, extention=None):
cmds = edocuments.config.get("cmds", {})
for name in names:
cmd = cmds.get(name)
if cmd is None:
raise "Missing command '%s' in `cmds`" % name
if isinstance(cmd, str):
cmd = {}
if cmd.get('type') == 'rename':
filename = _rename(cmd, filename)
else:
if 'out_ext' in cmd:
extention = cmd['out_ext']
if extention is not None:
filename = "%s.%s" % (re.sub(
r"\.[a-z0-9A-Z]{2,5}$", "",
filename
), extention)
return filename
PK >HO edocuments/label_dialog.py# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QDialog
from PyQt5.QtGui import QPixmap
from edocuments.ui.label_dialog import Ui_Dialog
class Dialog(QDialog):
def __init__(self):
super().__init__()
self.ui = Ui_Dialog()
self.ui.setupUi(self)
def set_image(self, image_filename):
size = 800
pixmap = QPixmap(image_filename)
if pixmap.width() > pixmap.height():
if pixmap.width() > size:
pixmap = pixmap.scaledToWidth(size)
else:
if pixmap.height() > size:
pixmap = pixmap.scaledToHeight(size)
self.ui.label.setPixmap(pixmap)
self.ui.label.setMask(pixmap.mask())
self.ui.label.show()
PK a?Hb} edocuments/__init__.py# -*- coding: utf-8 -*-
import os
import sys
from yaml import load
from autoupgrade import AutoUpgrade
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication
from edocuments.main_widget import MainWindow
CONFIG_FILENAME = "edocuments.yaml"
if 'APPDATA' in os.environ:
CONFIG_PATH = os.path.join(os.environ['APPDATA'], CONFIG_FILENAME)
elif 'XDG_CONFIG_HOME' in os.environ:
CONFIG_PATH = os.path.join(os.environ['XDG_CONFIG_HOME'], CONFIG_FILENAME)
else:
CONFIG_PATH = os.path.join(os.environ['HOME'], '.config', CONFIG_FILENAME)
config = {}
root_folder = None
settings = None
def gui_main():
global config, root_folder, settings
with open(CONFIG_PATH) as f:
config = load(f.read())
root_folder = "%s/%s/" % (
os.path.expanduser('~'),
config.get("root_folder"),
)
settings = QSettings("org", "edocuments")
app = QApplication(sys.argv)
mw = MainWindow()
if settings.value("geometry") is not None:
mw.restoreGeometry(settings.value("geometry"))
if settings.value("state") is not None:
mw.restoreState(settings.value("state"))
au = AutoUpgrade('edocuments')
if au.check():
msg = QMessageBox(self)
msg.setWindowTitle("eDocuments - Upgrade")
msg.setText("A new version is available")
msg.setInformativeText("Do you want to do anupdate and restart?")
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
ret = msg.exec()
if ret == QMessageBox.Yes:
au.upgrade(dependencies=True)
au.restart()
mw.show()
app.exec()
settings.setValue("geometry", mw.saveGeometry())
settings.setValue("state", mw.saveState())
settings.sync()
PK ^?Hq edocuments/main_widget.py# -*- coding: utf-8 -*-
import re
import pathlib
from os import path
from threading import Thread
from subprocess import call
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QMainWindow, QFileDialog, \
QErrorMessage, QMessageBox, QProgressDialog
import edocuments
from edocuments.process import process, destination_filename
from edocuments.ui.main import Ui_MainWindow
from edocuments.label_dialog import Dialog
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.scan_comments.setText(edocuments.config.get("scan_comments"))
default_index = 0
for s in edocuments.config.get("scans", []):
if s.get("default") is True:
default_index = self.ui.scan_type.count()
self.ui.scan_type.addItem(s.get("name"), s)
self.ui.scan_type.setCurrentIndex(default_index)
self.ui.scan_browse.clicked.connect(self.scan_browse)
self.ui.scan_to.returnPressed.connect(self.scan_start)
self.ui.scan_to.editingFinished.connect(self.scan_start)
self.ui.scan_start.clicked.connect(self.scan_start)
self.image_dialog = Dialog()
def scan_browse(self, event):
filename = QFileDialog.getSaveFileName(
self, "Scan to", directory=self.filename()
)[0]
filename = re.sub(r"\.[a-z0-9A-Z]{2,5}$", "", filename)
if filename[:len(edocuments.root_folder)] == edocuments.root_folder:
filename = filename[len(edocuments.root_folder):]
self.ui.scan_to.setText(filename)
def filename(self):
filename = self.ui.scan_to.text()
if len(filename) == 0 or filename[0] != '/':
filename = path.join(edocuments.root_folder, filename)
return filename
def scan_start(self, event):
if pathlib.Path(self.filename()).is_dir():
err = QErrorMessage(self)
err.setWindowTitle("eDocuments - Error")
err.showMessage("The destination is a directory!")
return
destination = destination_filename(
self.ui.scan_type.currentData().get("cmds"),
self.filename()
)
if pathlib.Path(destination).is_file():
msg = QMessageBox(self)
msg.setWindowTitle("Scanning...")
msg.setText("The destination file already exists")
msg.setInformativeText("Do you want to overwrite it?")
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel | QMessageBox.Open)
ret = msg.exec()
if ret == QMessageBox.Ok:
self._scan()
elif ret == QMessageBox.Open:
cmd = edocuments.config.get('open_cmd').split(' ')
cmd.append(destination)
call(cmd)
else:
self._scan()
def _scan(self):
cmds = self.ui.scan_type.currentData().get("cmds")
self.progress = QProgressDialog("Scanning...", "Cancel", 0, len(cmds), self)
self.progress.setWindowTitle("Scanning...")
self.progress.setWindowModality(Qt.WindowModal)
self.progress.show()
t = Thread(target=self._do_scan)
t.start()
def _do_scan(self):
cmds = self.ui.scan_type.currentData().get("cmds")
filename = process(
cmds, destination_filename=self.filename(),
progress=self.progress, progress_text='{display}'
)
self.progress.hide()
self.image_dialog.set_image(filename)
self.image_dialog.exec()
PK >H". . edocuments/ui/label_dialog.py# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'edocuments/ui/label_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.4.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(194, 70)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(Dialog)
self.label.setText("")
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
PK x>H<`\1 edocuments/ui/main.py# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'edocuments/ui/main.ui'
#
# Created by: PyQt5 UI code generator 5.4.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(583, 525)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setEnabled(True)
self.tabWidget.setObjectName("tabWidget")
self.search = QtWidgets.QWidget()
self.search.setObjectName("search")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.search)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.horizontalLayout.setObjectName("horizontalLayout")
self.search_text = QtWidgets.QLineEdit(self.search)
self.search_text.setObjectName("search_text")
self.horizontalLayout.addWidget(self.search_text)
self.search_btn = QtWidgets.QPushButton(self.search)
self.search_btn.setObjectName("search_btn")
self.horizontalLayout.addWidget(self.search_btn)
self.verticalLayout_4.addLayout(self.horizontalLayout)
self.groupBox_2 = QtWidgets.QGroupBox(self.search)
self.groupBox_2.setObjectName("groupBox_2")
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.groupBox_2)
self.verticalLayout_7.setObjectName("verticalLayout_7")
self.advance_query = QtWidgets.QPlainTextEdit(self.groupBox_2)
self.advance_query.setObjectName("advance_query")
self.verticalLayout_7.addWidget(self.advance_query)
self.verticalLayout_4.addWidget(self.groupBox_2)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.search_result_list = QtWidgets.QListWidget(self.search)
self.search_result_list.setObjectName("search_result_list")
self.horizontalLayout_2.addWidget(self.search_result_list)
self.verticalLayout_5 = QtWidgets.QVBoxLayout()
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.search_result_test = QtWidgets.QTextBrowser(self.search)
self.search_result_test.setObjectName("search_result_test")
self.verticalLayout_5.addWidget(self.search_result_test)
self.search_result_graphics = QtWidgets.QGraphicsView(self.search)
self.search_result_graphics.setObjectName("search_result_graphics")
self.verticalLayout_5.addWidget(self.search_result_graphics)
self.horizontalLayout_2.addLayout(self.verticalLayout_5)
self.horizontalLayout_2.setStretch(0, 1)
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.tabWidget.addTab(self.search, "")
self.scan = QtWidgets.QWidget()
self.scan.setObjectName("scan")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scan)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label = QtWidgets.QLabel(self.scan)
self.label.setObjectName("label")
self.horizontalLayout_3.addWidget(self.label)
self.scan_type = QtWidgets.QComboBox(self.scan)
self.scan_type.setObjectName("scan_type")
self.horizontalLayout_3.addWidget(self.scan_type)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.direct = QtWidgets.QGroupBox(self.scan)
self.direct.setObjectName("direct")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.direct)
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.scan_to = QtWidgets.QLineEdit(self.direct)
self.scan_to.setObjectName("scan_to")
self.horizontalLayout_5.addWidget(self.scan_to)
self.scan_browse = QtWidgets.QPushButton(self.direct)
self.scan_browse.setObjectName("scan_browse")
self.horizontalLayout_5.addWidget(self.scan_browse)
self.scan_start = QtWidgets.QPushButton(self.direct)
self.scan_start.setObjectName("scan_start")
self.horizontalLayout_5.addWidget(self.scan_start)
self.verticalLayout_2.addWidget(self.direct)
self.groupBox = QtWidgets.QGroupBox(self.scan)
self.groupBox.setObjectName("groupBox")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.scan_comments = QtWidgets.QLabel(self.groupBox)
self.scan_comments.setText("")
self.scan_comments.setObjectName("scan_comments")
self.verticalLayout_6.addWidget(self.scan_comments)
self.verticalLayout_2.addWidget(self.groupBox)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem)
self.tabWidget.addTab(self.scan, "")
self.verticalLayout.addWidget(self.tabWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 583, 24))
self.menubar.setObjectName("menubar")
self.menuUpdate_library = QtWidgets.QMenu(self.menubar)
self.menuUpdate_library.setObjectName("menuUpdate_library")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionUpdate = QtWidgets.QAction(MainWindow)
self.actionUpdate.setObjectName("actionUpdate")
self.menuUpdate_library.addAction(self.actionUpdate)
self.menubar.addAction(self.menuUpdate_library.menuAction())
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "eDocuments - a Simple and Productive Personal Documents Library"))
self.search_btn.setText(_translate("MainWindow", "Search"))
self.groupBox_2.setTitle(_translate("MainWindow", "Advance query"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.search), _translate("MainWindow", "Search"))
self.label.setText(_translate("MainWindow", "Scan type"))
self.direct.setTitle(_translate("MainWindow", "Scan"))
self.scan_browse.setText(_translate("MainWindow", "Browse..."))
self.scan_start.setText(_translate("MainWindow", "Scan"))
self.groupBox.setTitle(_translate("MainWindow", "Comments"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.scan), _translate("MainWindow", "Scan"))
self.menuUpdate_library.setTitle(_translate("MainWindow", "&Library"))
self.actionUpdate.setText(_translate("MainWindow", "&Update"))
PK =H edocuments/ui/__init__.pyPK c?H9 9 * edocuments-0.1.0.dist-info/DESCRIPTION.rstA sample and productive personal documents library
* Scan your documents
* Auto rotate
* index them on the file name and on the content (OCR)
* Mange your pdf
* index them on the file name and on the content
* Search in your library
`Sources `_
PK c?Hc08 8 + edocuments-0.1.0.dist-info/entry_points.txt[console_scripts]
edocuments-gui = edocuments:gui_main
PK c?H: ( edocuments-0.1.0.dist-info/metadata.json{"classifiers": ["Programming Language :: Python :: 3"], "extensions": {"python.commands": {"wrap_console": {"edocuments-gui": "edocuments:gui_main"}}, "python.details": {"contacts": [{"email": "stephane.brunner@gmail.com", "name": "St\u00e9phane Brunner", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/sbrunner/epaper/"}}, "python.exports": {"console_scripts": {"edocuments-gui": "edocuments:gui_main"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "keywords": ["simple", "productive", "personal", "documents", "library", "scan", "index", "search"], "metadata_version": "2.0", "name": "edocuments", "run_requires": [{"requires": ["PyYAML", "autoupgrade"]}], "summary": "EDocuments - a simple and productive personal documents library", "test_requires": [{"requires": ["PyYAML", "autoupgrade"]}], "version": "0.1.0"}PK c?H^x ( edocuments-0.1.0.dist-info/top_level.txtedocuments
PK c?H''\ \ edocuments-0.1.0.dist-info/WHEELWheel-Version: 1.0
Generator: bdist_wheel (0.26.0)
Root-Is-Purelib: true
Tag: py2-none-any
PK c?H.