mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
Allow selecting a document, then show settings
This commit is contained in:
parent
b527776e28
commit
c9e32ef82d
6 changed files with 200 additions and 18 deletions
2
Pipfile
2
Pipfile
|
@ -6,6 +6,8 @@ name = "pypi"
|
||||||
[packages]
|
[packages]
|
||||||
PyQt5 = "*"
|
PyQt5 = "*"
|
||||||
click = "*"
|
click = "*"
|
||||||
|
appdirs = "*"
|
||||||
|
pyxdg = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
black = "*"
|
black = "*"
|
||||||
|
|
|
@ -2,7 +2,11 @@ import sys
|
||||||
import os
|
import os
|
||||||
import inspect
|
import inspect
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import appdirs
|
||||||
from PyQt5 import QtGui
|
from PyQt5 import QtGui
|
||||||
|
from xdg.DesktopEntry import DesktopEntry
|
||||||
|
|
||||||
|
from .settings import Settings
|
||||||
|
|
||||||
|
|
||||||
class Common(object):
|
class Common(object):
|
||||||
|
@ -14,13 +18,17 @@ class Common(object):
|
||||||
# Temporary directory to store pixel data
|
# Temporary directory to store pixel data
|
||||||
self.pixel_dir = tempfile.TemporaryDirectory()
|
self.pixel_dir = tempfile.TemporaryDirectory()
|
||||||
self.safe_dir = tempfile.TemporaryDirectory()
|
self.safe_dir = tempfile.TemporaryDirectory()
|
||||||
print(f"pixel_dir is: {self.pixel_dir.name}")
|
print(
|
||||||
print(f"safe_dir is: {self.safe_dir.name}")
|
f"Temporary directories created, dangerous={self.pixel_dir.name}, safe={self.safe_dir.name}"
|
||||||
|
)
|
||||||
|
|
||||||
self.document_filename = None
|
self.document_filename = None
|
||||||
|
|
||||||
self.fixed_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont)
|
self.fixed_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont)
|
||||||
|
|
||||||
|
self.appdata_path = appdirs.user_config_dir("dangerzone")
|
||||||
|
|
||||||
|
self.pdf_viewers = self._find_pdf_viewers()
|
||||||
|
|
||||||
self.ocr_languages = {
|
self.ocr_languages = {
|
||||||
"Afrikaans": "ar",
|
"Afrikaans": "ar",
|
||||||
"Amharic": "amh",
|
"Amharic": "amh",
|
||||||
|
@ -184,6 +192,8 @@ class Common(object):
|
||||||
"Vietnamese script": "Vietnamese",
|
"Vietnamese script": "Vietnamese",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.settings = Settings(self)
|
||||||
|
|
||||||
def set_document_filename(self, filename):
|
def set_document_filename(self, filename):
|
||||||
self.document_filename = filename
|
self.document_filename = filename
|
||||||
|
|
||||||
|
@ -203,3 +213,27 @@ class Common(object):
|
||||||
|
|
||||||
resource_path = os.path.join(prefix, filename)
|
resource_path = os.path.join(prefix, filename)
|
||||||
return resource_path
|
return resource_path
|
||||||
|
|
||||||
|
def _find_pdf_viewers(self):
|
||||||
|
pdf_viewers = {}
|
||||||
|
|
||||||
|
for search_path in [
|
||||||
|
"/usr/share/applications",
|
||||||
|
"/usr/local/share/applications",
|
||||||
|
os.path.expanduser("~/.local/share/applications"),
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
for filename in os.listdir(search_path):
|
||||||
|
full_filename = os.path.join(search_path, filename)
|
||||||
|
if os.path.splitext(filename)[1] == ".desktop":
|
||||||
|
|
||||||
|
desktop_entry = DesktopEntry(full_filename)
|
||||||
|
if "application/pdf" in desktop_entry.getMimeTypes():
|
||||||
|
pdf_viewers[
|
||||||
|
desktop_entry.getName()
|
||||||
|
] = desktop_entry.getExec()
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return pdf_viewers
|
||||||
|
|
41
dangerzone/doc_selection_widget.py
Normal file
41
dangerzone/doc_selection_widget.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class DocSelectionWidget(QtWidgets.QWidget):
|
||||||
|
document_selected = QtCore.pyqtSignal(str)
|
||||||
|
|
||||||
|
def __init__(self, common):
|
||||||
|
super(DocSelectionWidget, self).__init__()
|
||||||
|
self.common = common
|
||||||
|
|
||||||
|
# Dangerous document selection
|
||||||
|
self.dangerous_doc_label = QtWidgets.QLabel()
|
||||||
|
self.dangerous_doc_label.hide()
|
||||||
|
self.dangerous_doc_button = QtWidgets.QPushButton(
|
||||||
|
"Select dangerous document ..."
|
||||||
|
)
|
||||||
|
self.dangerous_doc_button.setStyleSheet(
|
||||||
|
"QPushButton { font-weight: bold; padding: 10px; }"
|
||||||
|
)
|
||||||
|
self.dangerous_doc_button.clicked.connect(self.dangerous_doc_button_clicked)
|
||||||
|
|
||||||
|
dangerous_doc_layout = QtWidgets.QHBoxLayout()
|
||||||
|
dangerous_doc_layout.addStretch()
|
||||||
|
dangerous_doc_layout.addWidget(self.dangerous_doc_button)
|
||||||
|
dangerous_doc_layout.addStretch()
|
||||||
|
|
||||||
|
# Layout
|
||||||
|
layout = QtWidgets.QVBoxLayout()
|
||||||
|
layout.addStretch()
|
||||||
|
layout.addLayout(dangerous_doc_layout)
|
||||||
|
layout.addStretch()
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
def dangerous_doc_button_clicked(self):
|
||||||
|
filename = QtWidgets.QFileDialog.getOpenFileName(
|
||||||
|
self, "Open document", filter="Documents (*.pdf *.docx *.xlsx)",
|
||||||
|
)
|
||||||
|
if filename[0] != "":
|
||||||
|
filename = filename[0]
|
||||||
|
self.common.set_document_filename(filename)
|
||||||
|
self.document_selected.emit(filename)
|
|
@ -2,6 +2,7 @@ import shutil
|
||||||
import os
|
import os
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
from .doc_selection_widget import DocSelectionWidget
|
||||||
from .settings_widget import SettingsWidget
|
from .settings_widget import SettingsWidget
|
||||||
from .tasks_widget import TasksWidget
|
from .tasks_widget import TasksWidget
|
||||||
|
|
||||||
|
@ -33,9 +34,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
header_layout.addWidget(header_label)
|
header_layout.addWidget(header_label)
|
||||||
header_layout.addStretch()
|
header_layout.addStretch()
|
||||||
|
|
||||||
|
# Doc selection widget
|
||||||
|
self.doc_selection_widget = DocSelectionWidget(self.common)
|
||||||
|
self.doc_selection_widget.document_selected.connect(self.document_selected)
|
||||||
|
self.doc_selection_widget.show()
|
||||||
|
|
||||||
# Settings
|
# Settings
|
||||||
self.settings_widget = SettingsWidget(self.common)
|
self.settings_widget = SettingsWidget(self.common)
|
||||||
self.settings_widget.show()
|
self.doc_selection_widget.document_selected.connect(
|
||||||
|
self.settings_widget.document_selected
|
||||||
|
)
|
||||||
|
self.settings_widget.hide()
|
||||||
|
|
||||||
# Tasks
|
# Tasks
|
||||||
self.tasks_widget = TasksWidget(self.common)
|
self.tasks_widget = TasksWidget(self.common)
|
||||||
|
@ -44,6 +53,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
# Layout
|
# Layout
|
||||||
layout = QtWidgets.QVBoxLayout()
|
layout = QtWidgets.QVBoxLayout()
|
||||||
layout.addLayout(header_layout)
|
layout.addLayout(header_layout)
|
||||||
|
layout.addWidget(self.doc_selection_widget, stretch=1)
|
||||||
layout.addWidget(self.settings_widget, stretch=1)
|
layout.addWidget(self.settings_widget, stretch=1)
|
||||||
layout.addWidget(self.tasks_widget, stretch=1)
|
layout.addWidget(self.tasks_widget, stretch=1)
|
||||||
|
|
||||||
|
@ -53,6 +63,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
def document_selected(self, filename):
|
||||||
|
self.doc_selection_widget.hide()
|
||||||
|
self.settings_widget.show()
|
||||||
|
|
||||||
def closeEvent(self, e):
|
def closeEvent(self, e):
|
||||||
e.accept()
|
e.accept()
|
||||||
self.app.quit()
|
self.app.quit()
|
||||||
|
|
55
dangerzone/settings.py
Normal file
55
dangerzone/settings.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import appdirs
|
||||||
|
|
||||||
|
|
||||||
|
class Settings:
|
||||||
|
def __init__(self, common):
|
||||||
|
self.common = common
|
||||||
|
self.settings_filename = os.path.join(self.common.appdata_path, "settings.json")
|
||||||
|
|
||||||
|
self.default_settings = {
|
||||||
|
"save": True,
|
||||||
|
"ocr": True,
|
||||||
|
"ocr_language": "English",
|
||||||
|
"open": True,
|
||||||
|
"open_app": list(self.common.pdf_viewers)[0],
|
||||||
|
"update_container": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.load()
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
return self.settings[key]
|
||||||
|
|
||||||
|
def set(self, key, val):
|
||||||
|
self.settings[key] = val
|
||||||
|
self.settings.save()
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if os.path.isfile(self.settings_filename):
|
||||||
|
# If the settings file exists, load it
|
||||||
|
try:
|
||||||
|
with open(self.settings_filename, "r") as settings_file:
|
||||||
|
self.settings = json.load(settings_file)
|
||||||
|
|
||||||
|
# If it's missing any fields, add them from the default settings
|
||||||
|
for key in self.default_settings:
|
||||||
|
if key not in self.settings:
|
||||||
|
self.settings[key] = self.default_settings[key]
|
||||||
|
|
||||||
|
except:
|
||||||
|
print("Error loading settings, falling back to default")
|
||||||
|
self.settings = self.default_settings
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Save with default settings
|
||||||
|
print("Settings file doesn't exist, starting with default")
|
||||||
|
self.settings = self.default_settings
|
||||||
|
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
os.makedirs(self.common.appdata_path, exist_ok=True)
|
||||||
|
with open(self.settings_filename, "w") as settings_file:
|
||||||
|
json.dump(self.settings, settings_file, indent=4)
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,37 +7,30 @@ class SettingsWidget(QtWidgets.QWidget):
|
||||||
super(SettingsWidget, self).__init__()
|
super(SettingsWidget, self).__init__()
|
||||||
self.common = common
|
self.common = common
|
||||||
|
|
||||||
# Dangerous document selection
|
# Dangerous document
|
||||||
self.dangerous_doc_label = QtWidgets.QLabel()
|
self.dangerous_doc_label = QtWidgets.QLabel()
|
||||||
self.dangerous_doc_label.hide()
|
self.dangerous_doc_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
self.dangerous_doc_button = QtWidgets.QPushButton(
|
self.dangerous_doc_label.setStyleSheet(
|
||||||
"Select dangerous document ..."
|
"QLabel { font-size: 16px; font-weight: bold; color: #572606; padding: 10px; }"
|
||||||
)
|
)
|
||||||
self.dangerous_doc_button.setStyleSheet("QPushButton { font-weight: bold }")
|
|
||||||
|
|
||||||
dangerous_doc_layout = QtWidgets.QHBoxLayout()
|
|
||||||
dangerous_doc_layout.addWidget(self.dangerous_doc_label)
|
|
||||||
dangerous_doc_layout.addWidget(self.dangerous_doc_button)
|
|
||||||
dangerous_doc_layout.addStretch()
|
|
||||||
|
|
||||||
# Save safe version
|
# Save safe version
|
||||||
self.save_checkbox = QtWidgets.QCheckBox("Save safe PDF")
|
self.save_checkbox = QtWidgets.QCheckBox("Save safe PDF")
|
||||||
self.save_lineedit = QtWidgets.QLineEdit()
|
self.save_lineedit = QtWidgets.QLineEdit()
|
||||||
self.save_lineedit.setReadOnly(True)
|
self.save_lineedit.setReadOnly(True)
|
||||||
self.save_browse_button = QtWidgets.QPushButton("Save as...")
|
self.save_browse_button = QtWidgets.QPushButton("Save as...")
|
||||||
|
|
||||||
save_layout = QtWidgets.QHBoxLayout()
|
save_layout = QtWidgets.QHBoxLayout()
|
||||||
save_layout.addWidget(self.save_checkbox)
|
save_layout.addWidget(self.save_checkbox)
|
||||||
save_layout.addWidget(self.save_lineedit)
|
save_layout.addWidget(self.save_lineedit)
|
||||||
save_layout.addWidget(self.save_browse_button)
|
save_layout.addWidget(self.save_browse_button)
|
||||||
save_layout.addStretch()
|
save_layout.addStretch()
|
||||||
|
self.save_location = None
|
||||||
|
|
||||||
# OCR document
|
# OCR document
|
||||||
self.ocr_checkbox = QtWidgets.QCheckBox("OCR document, language")
|
self.ocr_checkbox = QtWidgets.QCheckBox("OCR document, language")
|
||||||
self.ocr_combobox = QtWidgets.QComboBox()
|
self.ocr_combobox = QtWidgets.QComboBox()
|
||||||
for k in self.common.ocr_languages:
|
for k in self.common.ocr_languages:
|
||||||
self.ocr_combobox.addItem(k, QtCore.QVariant(self.common.ocr_languages[k]))
|
self.ocr_combobox.addItem(k, QtCore.QVariant(self.common.ocr_languages[k]))
|
||||||
|
|
||||||
ocr_layout = QtWidgets.QHBoxLayout()
|
ocr_layout = QtWidgets.QHBoxLayout()
|
||||||
ocr_layout.addWidget(self.ocr_checkbox)
|
ocr_layout.addWidget(self.ocr_checkbox)
|
||||||
ocr_layout.addWidget(self.ocr_combobox)
|
ocr_layout.addWidget(self.ocr_combobox)
|
||||||
|
@ -45,7 +39,8 @@ class SettingsWidget(QtWidgets.QWidget):
|
||||||
# Open safe document
|
# Open safe document
|
||||||
self.open_checkbox = QtWidgets.QCheckBox("Open safe document")
|
self.open_checkbox = QtWidgets.QCheckBox("Open safe document")
|
||||||
self.open_combobox = QtWidgets.QComboBox()
|
self.open_combobox = QtWidgets.QComboBox()
|
||||||
|
for k in self.common.pdf_viewers:
|
||||||
|
self.open_combobox.addItem(k, QtCore.QVariant(self.common.pdf_viewers[k]))
|
||||||
open_layout = QtWidgets.QHBoxLayout()
|
open_layout = QtWidgets.QHBoxLayout()
|
||||||
open_layout.addWidget(self.open_checkbox)
|
open_layout.addWidget(self.open_checkbox)
|
||||||
open_layout.addWidget(self.open_combobox)
|
open_layout.addWidget(self.open_combobox)
|
||||||
|
@ -69,7 +64,7 @@ class SettingsWidget(QtWidgets.QWidget):
|
||||||
|
|
||||||
# Layout
|
# Layout
|
||||||
layout = QtWidgets.QVBoxLayout()
|
layout = QtWidgets.QVBoxLayout()
|
||||||
layout.addLayout(dangerous_doc_layout)
|
layout.addWidget(self.dangerous_doc_label)
|
||||||
layout.addLayout(save_layout)
|
layout.addLayout(save_layout)
|
||||||
layout.addLayout(ocr_layout)
|
layout.addLayout(ocr_layout)
|
||||||
layout.addLayout(open_layout)
|
layout.addLayout(open_layout)
|
||||||
|
@ -77,3 +72,44 @@ class SettingsWidget(QtWidgets.QWidget):
|
||||||
layout.addLayout(button_layout)
|
layout.addLayout(button_layout)
|
||||||
layout.addStretch()
|
layout.addStretch()
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
# Load values from settings
|
||||||
|
if self.common.settings.get("save"):
|
||||||
|
self.save_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||||
|
else:
|
||||||
|
self.save_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
|
if self.common.settings.get("ocr"):
|
||||||
|
self.ocr_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||||
|
else:
|
||||||
|
self.ocr_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
|
index = self.ocr_combobox.findText(self.common.settings.get("ocr_language"))
|
||||||
|
if index != -1:
|
||||||
|
self.ocr_combobox.setCurrentIndex(index)
|
||||||
|
|
||||||
|
if self.common.settings.get("open"):
|
||||||
|
self.open_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||||
|
else:
|
||||||
|
self.open_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
|
index = self.open_combobox.findText(self.common.settings.get("open_app"))
|
||||||
|
if index != -1:
|
||||||
|
self.open_combobox.setCurrentIndex(index)
|
||||||
|
|
||||||
|
if self.common.settings.get("update_container"):
|
||||||
|
self.update_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||||
|
else:
|
||||||
|
self.update_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
|
def document_selected(self, filename):
|
||||||
|
# Update the danger doc label
|
||||||
|
self.dangerous_doc_label.setText(
|
||||||
|
f"Dangerous: {os.path.basename(self.common.document_filename)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update the save location
|
||||||
|
self.save_location = (
|
||||||
|
f"{os.path.splitext(self.common.document_filename)[0]}-safe.pdf"
|
||||||
|
)
|
||||||
|
self.save_lineedit.setText(os.path.basename(self.save_location))
|
||||||
|
|
Loading…
Reference in a new issue