Refactor static methods as functions in util module

This commit is contained in:
Guthrie McAfee Armstrong 2022-06-04 20:39:25 -04:00
parent 42a1f01e6f
commit 17ff3a8795
No known key found for this signature in database
GPG key ID: ED4DAE89F08242D2
11 changed files with 311 additions and 341 deletions

View file

@ -1,11 +1,6 @@
import os import os
import sys import sys
import appdirs
CONTAINER_NAME = "dangerzone.rocks/dangerzone"
APPDATA_PATH = appdirs.user_config_dir("dangerzone")
if "DANGERZONE_MODE" in os.environ: if "DANGERZONE_MODE" in os.environ:
mode = os.environ["DANGERZONE_MODE"] mode = os.environ["DANGERZONE_MODE"]
else: else:

View file

@ -7,6 +7,7 @@ from colorama import Fore, Style
from .global_common import GlobalCommon from .global_common import GlobalCommon
from .common import Common from .common import Common
from .container import convert from .container import convert
import dangerzone.util as dzutil
def print_header(s): def print_header(s):
@ -73,14 +74,14 @@ def cli_main(output_filename, ocr_lang, filename):
# Validate OCR language # Validate OCR language
if ocr_lang: if ocr_lang:
valid = False valid = False
for lang in global_common.ocr_languages: for lang in dzutil.OCR_LANGUAGES:
if global_common.ocr_languages[lang] == ocr_lang: if dzutil.OCR_LANGUAGES[lang] == ocr_lang:
valid = True valid = True
break break
if not valid: if not valid:
click.echo("Invalid OCR language code. Valid language codes:") click.echo("Invalid OCR language code. Valid language codes:")
for lang in global_common.ocr_languages: for lang in dzutil.OCR_LANGUAGES:
click.echo(f"{global_common.ocr_languages[lang]}: {lang}") click.echo(f"{dzutil.OCR_LANGUAGES[lang]}: {lang}")
return return
# Ensure container is installed # Ensure container is installed

View file

@ -1,10 +1,3 @@
import os
import stat
import platform
import tempfile
import appdirs
class Common(object): class Common(object):
""" """
The Common class is a singleton of shared functionality throughout an open dangerzone window The Common class is a singleton of shared functionality throughout an open dangerzone window

View file

@ -1,4 +1,3 @@
import platform
import subprocess import subprocess
import pipes import pipes
import shutil import shutil
@ -6,23 +5,7 @@ import os
import tempfile import tempfile
import appdirs import appdirs
# What container tech is used for this platform? import dangerzone.util as dzutil
if platform.system() == "Linux":
container_tech = "podman"
else:
# Windows, Darwin, and unknown use docker for now, dangerzone-vm eventually
container_tech = "docker"
# Define startupinfo for subprocesses
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
else:
startupinfo = None
# Name of the dangerzone container
container_name = "dangerzone.rocks/dangerzone"
def exec(args, stdout_callback=None): def exec(args, stdout_callback=None):
@ -36,7 +19,7 @@ def exec(args, stdout_callback=None):
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
bufsize=1, bufsize=1,
universal_newlines=True, universal_newlines=True,
startupinfo=startupinfo, startupinfo=dzutil.get_subprocess_startupinfo(),
) as p: ) as p:
if stdout_callback: if stdout_callback:
for line in p.stdout: for line in p.stdout:
@ -47,12 +30,7 @@ def exec(args, stdout_callback=None):
def exec_container(args, stdout_callback=None): def exec_container(args, stdout_callback=None):
if container_tech == "podman": args = [dzutil.CONTAINER_RUNTIME] + args
container_runtime = shutil.which("podman")
else:
container_runtime = shutil.which("docker")
args = [container_runtime] + args
return exec(args, stdout_callback) return exec(args, stdout_callback)
@ -87,7 +65,7 @@ def convert(input_filename, output_filename, ocr_lang, stdout_callback):
f"{input_filename}:/tmp/input_file", f"{input_filename}:/tmp/input_file",
"-v", "-v",
f"{pixel_dir}:/dangerzone", f"{pixel_dir}:/dangerzone",
container_name, dzutil.CONTAINER_NAME,
"/usr/bin/python3", "/usr/bin/python3",
"/usr/local/bin/dangerzone.py", "/usr/local/bin/dangerzone.py",
"document-to-pixels", "document-to-pixels",
@ -112,7 +90,7 @@ def convert(input_filename, output_filename, ocr_lang, stdout_callback):
f"OCR={ocr}", f"OCR={ocr}",
"-e", "-e",
f"OCR_LANGUAGE={ocr_lang}", f"OCR_LANGUAGE={ocr_lang}",
container_name, dzutil.CONTAINER_NAME,
"/usr/bin/python3", "/usr/bin/python3",
"/usr/local/bin/dangerzone.py", "/usr/local/bin/dangerzone.py",
"pixels-to-pdf", "pixels-to-pdf",
@ -139,7 +117,6 @@ def convert(input_filename, output_filename, ocr_lang, stdout_callback):
return success return success
# From global_common: # From global_common:
# def validate_convert_to_pixel_output(self, common, output): # def validate_convert_to_pixel_output(self, common, output):

View file

@ -1,15 +1,11 @@
import sys
import os
import inspect
import platform
import subprocess import subprocess
import shutil
import gzip import gzip
import colorama import colorama
from colorama import Fore, Back, Style from colorama import Fore, Back, Style
from . import CONTAINER_NAME import dangerzone
from .settings import Settings from dangerzone.settings import Settings
import dangerzone.util as dzutil
class GlobalCommon(object): class GlobalCommon(object):
@ -18,182 +14,11 @@ class GlobalCommon(object):
""" """
def __init__(self): def __init__(self):
# Version self.version = dzutil.VERSION
try:
with open(self.get_resource_path("version.txt")) as f:
self.version = f.read().strip()
except FileNotFoundError:
# In dev mode, in Windows, get_resource_path doesn't work properly for the container, but luckily
# it doesn't need to know the version
self.version = "unknown"
# Initialize terminal colors # Initialize terminal colors
colorama.init(autoreset=True) colorama.init(autoreset=True)
# Languages supported by tesseract
self.ocr_languages = {
"Afrikaans": "ar",
"Albanian": "sqi",
"Amharic": "amh",
"Arabic": "ara",
"Arabic script": "Arabic",
"Armenian": "hye",
"Armenian script": "Armenian",
"Assamese": "asm",
"Azerbaijani": "aze",
"Azerbaijani (Cyrillic)": "aze_cyrl",
"Basque": "eus",
"Belarusian": "bel",
"Bengali": "ben",
"Bengali script": "Bengali",
"Bosnian": "bos",
"Breton": "bre",
"Bulgarian": "bul",
"Burmese": "mya",
"Canadian Aboriginal script": "Canadian_Aboriginal",
"Catalan": "cat",
"Cebuano": "ceb",
"Cherokee": "chr",
"Cherokee script": "Cherokee",
"Chinese - Simplified": "chi_sim",
"Chinese - Simplified (vertical)": "chi_sim_vert",
"Chinese - Traditional": "chi_tra",
"Chinese - Traditional (vertical)": "chi_tra_vert",
"Corsican": "cos",
"Croatian": "hrv",
"Cyrillic script": "Cyrillic",
"Czech": "ces",
"Danish": "dan",
"Devanagari script": "Devanagari",
"Divehi": "div",
"Dutch": "nld",
"Dzongkha": "dzo",
"English": "eng",
"English, Middle (1100-1500)": "enm",
"Esperanto": "epo",
"Estonian": "est",
"Ethiopic script": "Ethiopic",
"Faroese": "fao",
"Filipino": "fil",
"Finnish": "fin",
"Fraktur script": "Fraktur",
"Frankish": "frk",
"French": "fra",
"French, Middle (ca.1400-1600)": "frm",
"Frisian (Western)": "fry",
"Gaelic (Scots)": "gla",
"Galician": "glg",
"Georgian": "kat",
"Georgian script": "Georgian",
"German": "deu",
"Greek": "ell",
"Greek script": "Greek",
"Gujarati": "guj",
"Gujarati script": "Gujarati",
"Gurmukhi script": "Gurmukhi",
"Hangul script": "Hangul",
"Hangul (vertical) script": "Hangul_vert",
"Han - Simplified script": "HanS",
"Han - Simplified (vertical) script": "HanS_vert",
"Han - Traditional script": "HanT",
"Han - Traditional (vertical) script": "HanT_vert",
"Hatian": "hat",
"Hebrew": "heb",
"Hebrew script": "Hebrew",
"Hindi": "hin",
"Hungarian": "hun",
"Icelandic": "isl",
"Indonesian": "ind",
"Inuktitut": "iku",
"Irish": "gle",
"Italian": "ita",
"Italian - Old": "ita_old",
"Japanese": "jpn",
"Japanese script": "Japanese",
"Japanese (vertical)": "jpn_vert",
"Japanese (vertical) script": "Japanese_vert",
"Javanese": "jav",
"Kannada": "kan",
"Kannada script": "Kannada",
"Kazakh": "kaz",
"Khmer": "khm",
"Khmer script": "Khmer",
"Korean": "kor",
"Korean (vertical)": "kor_vert",
"Kurdish (Arabic)": "kur_ara",
"Kyrgyz": "kir",
"Lao": "lao",
"Lao script": "Lao",
"Latin": "lat",
"Latin script": "Latin",
"Latvian": "lav",
"Lithuanian": "lit",
"Luxembourgish": "ltz",
"Macedonian": "mkd",
"Malayalam": "mal",
"Malayalam script": "Malayalam",
"Malay": "msa",
"Maltese": "mlt",
"Maori": "mri",
"Marathi": "mar",
"Mongolian": "mon",
"Myanmar script": "Myanmar",
"Nepali": "nep",
"Norwegian": "nor",
"Occitan (post 1500)": "oci",
"Old Georgian": "kat_old",
"Oriya (Odia) script": "Oriya",
"Oriya": "ori",
"Pashto": "pus",
"Persian": "fas",
"Polish": "pol",
"Portuguese": "por",
"Punjabi": "pan",
"Quechua": "que",
"Romanian": "ron",
"Russian": "rus",
"Sanskrit": "san",
"script and orientation": "osd",
"Serbian (Latin)": "srp_latn",
"Serbian": "srp",
"Sindhi": "snd",
"Sinhala script": "Sinhala",
"Sinhala": "sin",
"Slovakian": "slk",
"Slovenian": "slv",
"Spanish, Castilian - Old": "spa_old",
"Spanish": "spa",
"Sundanese": "sun",
"Swahili": "swa",
"Swedish": "swe",
"Syriac script": "Syriac",
"Syriac": "syr",
"Tajik": "tgk",
"Tamil script": "Tamil",
"Tamil": "tam",
"Tatar": "tat",
"Telugu script": "Telugu",
"Telugu": "tel",
"Thaana script": "Thaana",
"Thai script": "Thai",
"Thai": "tha",
"Tibetan script": "Tibetan",
"Tibetan Standard": "bod",
"Tigrinya": "tir",
"Tonga": "ton",
"Turkish": "tur",
"Ukrainian": "ukr",
"Urdu": "urd",
"Uyghur": "uig",
"Uzbek (Cyrillic)": "uzb_cyrl",
"Uzbek": "uzb",
"Vietnamese script": "Vietnamese",
"Vietnamese": "vie",
"Welsh": "cym",
"Yiddish": "yid",
"Yoruba": "yor",
}
# Load settings # Load settings
self.settings = Settings() self.settings = Settings()
@ -339,9 +164,9 @@ class GlobalCommon(object):
+ "" + ""
) )
print(Back.BLACK + Fore.YELLOW + Style.DIM + "│ │") print(Back.BLACK + Fore.YELLOW + Style.DIM + "│ │")
left_spaces = (15 - len(self.version) - 1) // 2 left_spaces = (15 - len(dzutil.VERSION) - 1) // 2
right_spaces = left_spaces right_spaces = left_spaces
if left_spaces + len(self.version) + 1 + right_spaces < 15: if left_spaces + len(dzutil.VERSION) + 1 + right_spaces < 15:
right_spaces += 1 right_spaces += 1
print( print(
Back.BLACK Back.BLACK
@ -352,7 +177,7 @@ class GlobalCommon(object):
+ Back.BLACK + Back.BLACK
+ Fore.LIGHTWHITE_EX + Fore.LIGHTWHITE_EX
+ Style.BRIGHT + Style.BRIGHT
+ f"{' '*left_spaces}Dangerzone v{self.version}{' '*right_spaces}" + f"{' '*left_spaces}Dangerzone v{dzutil.VERSION}{' '*right_spaces}"
+ Fore.YELLOW + Fore.YELLOW
+ Style.DIM + Style.DIM
+ "" + ""
@ -372,48 +197,6 @@ class GlobalCommon(object):
) )
print(Back.BLACK + Fore.YELLOW + Style.DIM + "╰──────────────────────────╯") print(Back.BLACK + Fore.YELLOW + Style.DIM + "╰──────────────────────────╯")
@staticmethod
def get_container_runtime():
if platform.system() == "Linux":
return shutil.which("podman")
else:
return shutil.which("docker")
@staticmethod
def get_resource_path(filename):
if getattr(sys, "dangerzone_dev", False):
# Look for resources directory relative to python file
prefix = os.path.join(
os.path.dirname(
os.path.dirname(
os.path.abspath(inspect.getfile(inspect.currentframe()))
)
),
"share",
)
else:
if platform.system() == "Darwin":
prefix = os.path.join(
os.path.dirname(os.path.dirname(sys.executable)), "Resources/share"
)
elif platform.system() == "Linux":
prefix = os.path.join(sys.prefix, "share", "dangerzone")
else:
# Windows
prefix = os.path.join(os.path.dirname(sys.executable), "share")
resource_path = os.path.join(prefix, filename)
return resource_path
@staticmethod
def get_subprocess_startupinfo():
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
return startupinfo
else:
return None
@staticmethod @staticmethod
def install_container(): def install_container():
""" """
@ -426,13 +209,13 @@ class GlobalCommon(object):
print("Installing Dangerzone container image...") print("Installing Dangerzone container image...")
p = subprocess.Popen( p = subprocess.Popen(
[GlobalCommon.get_container_runtime(), "load"], [dzutil.CONTAINER_RUNTIME, "load"],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
startupinfo=GlobalCommon.get_subprocess_startupinfo(), startupinfo=dzutil.get_subprocess_startupinfo(),
) )
chunk_size = 10240 chunk_size = 10240
compressed_container_path = GlobalCommon.get_resource_path("container.tar.gz") compressed_container_path = dzutil.get_resource_path("container.tar.gz")
with gzip.open(compressed_container_path) as f: with gzip.open(compressed_container_path) as f:
while True: while True:
chunk = f.read(chunk_size) chunk = f.read(chunk_size)
@ -455,22 +238,22 @@ class GlobalCommon(object):
See if the podman container is installed. Linux only. See if the podman container is installed. Linux only.
""" """
# Get the image id # Get the image id
with open(GlobalCommon.get_resource_path("image-id.txt")) as f: with open(dzutil.get_resource_path("image-id.txt")) as f:
expected_image_id = f.read().strip() expected_image_id = f.read().strip()
# See if this image is already installed # See if this image is already installed
installed = False installed = False
found_image_id = subprocess.check_output( found_image_id = subprocess.check_output(
[ [
GlobalCommon.get_container_runtime(), dzutil.CONTAINER_RUNTIME,
"image", "image",
"list", "list",
"--format", "--format",
"{{.ID}}", "{{.ID}}",
CONTAINER_NAME, dangerzone.util.CONTAINER_NAME,
], ],
text=True, text=True,
startupinfo=GlobalCommon.get_subprocess_startupinfo(), startupinfo=dzutil.get_subprocess_startupinfo(),
) )
found_image_id = found_image_id.strip() found_image_id = found_image_id.strip()
@ -483,8 +266,8 @@ class GlobalCommon(object):
try: try:
subprocess.check_output( subprocess.check_output(
[GlobalCommon.get_container_runtime(), "rmi", "--force", found_image_id], [dzutil.CONTAINER_RUNTIME, "rmi", "--force", found_image_id],
startupinfo=GlobalCommon.get_subprocess_startupinfo(), startupinfo=dzutil.get_subprocess_startupinfo(),
) )
except: except:
print("Couldn't delete old container image, so leaving it there") print("Couldn't delete old container image, so leaving it there")

View file

@ -53,7 +53,7 @@ def gui_main(filename):
# Create the system tray # Create the system tray
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
systray = SysTray(global_common, gui_common, app) systray = SysTray(gui_common, app)
closed_windows = {} closed_windows = {}
windows = {} windows = {}

View file

@ -4,17 +4,14 @@ import subprocess
import shlex import shlex
import pipes import pipes
from PySide6 import QtCore, QtGui, QtWidgets from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtGui import QIcon
from colorama import Fore from colorama import Fore
from . import Application from . import Application
from ..global_common import GlobalCommon from ..global_common import GlobalCommon
import dangerzone.util as dzutil
if platform.system() == "Darwin": if platform.system() == "Linux":
import plistlib
elif platform.system() == "Linux":
import grp
import getpass
from xdg.DesktopEntry import DesktopEntry # type: ignore from xdg.DesktopEntry import DesktopEntry # type: ignore
@ -39,14 +36,6 @@ class GuiCommon(object):
# Are we done waiting (for Docker Desktop to be installed, or for container to install) # Are we done waiting (for Docker Desktop to be installed, or for container to install)
self.is_waiting_finished = False self.is_waiting_finished = False
@staticmethod
def get_window_icon():
if platform.system() == "Windows":
path = GlobalCommon.get_resource_path("dangerzone.ico")
else:
path = GlobalCommon.get_resource_path("icon.png")
return QtGui.QIcon(path)
def open_pdf_viewer(self, filename: str): def open_pdf_viewer(self, filename: str):
if platform.system() == "Darwin": if platform.system() == "Darwin":
# Open in Preview # Open in Preview
@ -118,7 +107,7 @@ class Alert(QtWidgets.QDialog):
): ):
super(Alert, self).__init__() super(Alert, self).__init__()
self.setWindowTitle("dangerzone") self.setWindowTitle("dangerzone")
self.setWindowIcon(GuiCommon.get_window_icon()) self.setWindowIcon(QIcon(dzutil.WINDOW_ICON_PATH))
self.setModal(True) self.setModal(True)
flags = ( # TODO Mypy: unsupported left operand type for | ("WindowType") flags = ( # TODO Mypy: unsupported left operand type for | ("WindowType")
@ -133,7 +122,7 @@ class Alert(QtWidgets.QDialog):
logo = QtWidgets.QLabel() logo = QtWidgets.QLabel()
logo.setPixmap( logo.setPixmap(
QtGui.QPixmap.fromImage( QtGui.QPixmap.fromImage(
QtGui.QImage(GlobalCommon.get_resource_path("icon.png")) QtGui.QImage(dzutil.get_resource_path("icon.png"))
) )
) )

View file

@ -5,8 +5,10 @@ import subprocess
import json import json
import shutil import shutil
from PySide6 import QtCore, QtGui, QtWidgets from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtGui import QIcon
from colorama import Style, Fore from colorama import Style, Fore
import dangerzone.util as dzutil
from . import GuiCommon from . import GuiCommon
from ..common import Common from ..common import Common
from ..container import convert from ..container import convert
@ -24,7 +26,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.common = Common() self.common = Common()
self.setWindowTitle("Dangerzone") self.setWindowTitle("Dangerzone")
self.setWindowIcon(self.gui_common.get_window_icon()) self.setWindowIcon(QIcon(dzutil.WINDOW_ICON_PATH))
self.setMinimumWidth(600) self.setMinimumWidth(600)
self.setMinimumHeight(400) self.setMinimumHeight(400)
@ -33,7 +35,7 @@ class MainWindow(QtWidgets.QMainWindow):
logo = QtWidgets.QLabel() logo = QtWidgets.QLabel()
logo.setPixmap( logo.setPixmap(
QtGui.QPixmap.fromImage( QtGui.QPixmap.fromImage(
QtGui.QImage(self.global_common.get_resource_path("icon.png")) QtGui.QImage(dzutil.get_resource_path("icon.png"))
) )
) )
header_label = QtWidgets.QLabel("dangerzone") header_label = QtWidgets.QLabel("dangerzone")
@ -165,7 +167,7 @@ class WaitingWidget(QtWidgets.QWidget):
[container_runtime, "image", "ls"], [container_runtime, "image", "ls"],
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
startupinfo=self.global_common.get_subprocess_startupinfo(), startupinfo=dzutil.get_subprocess_startupinfo(),
) as p: ) as p:
p.communicate() p.communicate()
if p.returncode != 0: if p.returncode != 0:
@ -361,8 +363,8 @@ class SettingsWidget(QtWidgets.QWidget):
# 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.global_common.ocr_languages: for k in dzutil.OCR_LANGUAGES:
self.ocr_combobox.addItem(k, self.global_common.ocr_languages[k]) self.ocr_combobox.addItem(k, dzutil.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)
@ -499,7 +501,7 @@ class ConvertThread(QtCore.QThread):
def run(self): def run(self):
if self.global_common.settings.get("ocr"): if self.global_common.settings.get("ocr"):
ocr_lang = self.global_common.ocr_languages[ ocr_lang = dzutil.OCR_LANGUAGES[
self.global_common.settings.get("ocr_language") self.global_common.settings.get("ocr_language")
] ]
else: else:
@ -557,7 +559,7 @@ class ConvertWidget(QtWidgets.QWidget):
self.error_image = QtWidgets.QLabel() self.error_image = QtWidgets.QLabel()
self.error_image.setPixmap( self.error_image.setPixmap(
QtGui.QPixmap.fromImage( QtGui.QPixmap.fromImage(
QtGui.QImage(self.global_common.get_resource_path("error.png")) QtGui.QImage(dzutil.get_resource_path("error.png"))
) )
) )
self.error_image.hide() self.error_image.hide()
@ -616,7 +618,7 @@ class ConvertWidget(QtWidgets.QWidget):
subprocess.Popen( subprocess.Popen(
f'explorer.exe /select,"{dest_filename_windows}"', f'explorer.exe /select,"{dest_filename_windows}"',
shell=True, shell=True,
startupinfo=self.global_common.get_subprocess_startupinfo(), startupinfo=dzutil.get_subprocess_startupinfo(),
) )
# Open # Open

View file

@ -1,19 +1,19 @@
from PySide6 import QtWidgets from PySide6 import QtWidgets
from PySide6.QtGui import QIcon
from dangerzone.global_common import GlobalCommon
from dangerzone.gui import GuiCommon, Application from dangerzone.gui import GuiCommon, Application
import dangerzone.util as dzutil
class SysTray(QtWidgets.QSystemTrayIcon): class SysTray(QtWidgets.QSystemTrayIcon):
def __init__( def __init__(
self, global_common: GlobalCommon, gui_common: GuiCommon, app: Application self, gui_common: GuiCommon, app: Application
): ):
super(SysTray, self).__init__() super(SysTray, self).__init__()
self.global_common = global_common
self.gui_common = gui_common self.gui_common = gui_common
self.app = app self.app = app
self.setIcon(self.gui_common.get_window_icon()) self.setIcon(QIcon(dzutil.WINDOW_ICON_PATH))
menu = QtWidgets.QMenu() menu = QtWidgets.QMenu()

View file

@ -1,12 +1,12 @@
import os import os
import json import json
from dangerzone import APPDATA_PATH import dangerzone.util as dzutil
class Settings: class Settings:
def __init__(self): def __init__(self):
self.settings_filename = os.path.join(APPDATA_PATH, "settings.json") self.settings_filename = os.path.join(dzutil.APPDATA_PATH, "settings.json")
self.default_settings = { self.default_settings = {
"save": True, "save": True,
"ocr": True, "ocr": True,
@ -47,6 +47,6 @@ class Settings:
self.save() self.save()
def save(self): def save(self):
os.makedirs(APPDATA_PATH, exist_ok=True) os.makedirs(dzutil.APPDATA_PATH, exist_ok=True)
with open(self.settings_filename, "w") as settings_file: with open(self.settings_filename, "w") as settings_file:
json.dump(self.settings, settings_file, indent=4) json.dump(self.settings, settings_file, indent=4)

230
dangerzone/util.py Normal file
View file

@ -0,0 +1,230 @@
import inspect
import os
import platform
import shutil
import subprocess
import sys
import appdirs
# If a general-purpose function doesn't depend on anything else in the dangerzone package, then it belongs here.
def get_resource_path(filename):
if getattr(sys, "dangerzone_dev", False):
# Look for resources directory relative to python file
prefix = os.path.join(
os.path.dirname(
os.path.dirname(
os.path.abspath(inspect.getfile(inspect.currentframe()))
)
),
"share",
)
else:
if platform.system() == "Darwin":
prefix = os.path.join(
os.path.dirname(os.path.dirname(sys.executable)), "Resources/share"
)
elif platform.system() == "Linux":
prefix = os.path.join(sys.prefix, "share", "dangerzone")
else:
# Windows
prefix = os.path.join(os.path.dirname(sys.executable), "share")
resource_path = os.path.join(prefix, filename)
return resource_path
def get_subprocess_startupinfo():
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
return startupinfo
else:
return None
def _get_version() -> str:
"""Dangerzone version number. Prefer dangerzone.VERSION to this function."""
try:
with open(get_resource_path("version.txt")) as f:
version = f.read().strip()
except FileNotFoundError:
# In dev mode, in Windows, get_resource_path doesn't work properly for the container, but luckily
# it doesn't need to know the version
version = "unknown"
return version
VERSION = _get_version()
APPDATA_PATH = appdirs.user_config_dir("dangerzone")
SYSTEM = platform.system()
CONTAINER_NAME = "dangerzone.rocks/dangerzone"
CONTAINER_COMMAND = "podman" if SYSTEM == "Linux" else "Docker"
CONTAINER_RUNTIME = shutil.which(CONTAINER_COMMAND)
WINDOW_ICON_FILENAME = "dangerzone.ico" if SYSTEM == "Windows" else "icon.png"
WINDOW_ICON_PATH = get_resource_path(WINDOW_ICON_FILENAME)
# Languages supported by tesseract
OCR_LANGUAGES = {
"Afrikaans": "ar",
"Albanian": "sqi",
"Amharic": "amh",
"Arabic": "ara",
"Arabic script": "Arabic",
"Armenian": "hye",
"Armenian script": "Armenian",
"Assamese": "asm",
"Azerbaijani": "aze",
"Azerbaijani (Cyrillic)": "aze_cyrl",
"Basque": "eus",
"Belarusian": "bel",
"Bengali": "ben",
"Bengali script": "Bengali",
"Bosnian": "bos",
"Breton": "bre",
"Bulgarian": "bul",
"Burmese": "mya",
"Canadian Aboriginal script": "Canadian_Aboriginal",
"Catalan": "cat",
"Cebuano": "ceb",
"Cherokee": "chr",
"Cherokee script": "Cherokee",
"Chinese - Simplified": "chi_sim",
"Chinese - Simplified (vertical)": "chi_sim_vert",
"Chinese - Traditional": "chi_tra",
"Chinese - Traditional (vertical)": "chi_tra_vert",
"Corsican": "cos",
"Croatian": "hrv",
"Cyrillic script": "Cyrillic",
"Czech": "ces",
"Danish": "dan",
"Devanagari script": "Devanagari",
"Divehi": "div",
"Dutch": "nld",
"Dzongkha": "dzo",
"English": "eng",
"English, Middle (1100-1500)": "enm",
"Esperanto": "epo",
"Estonian": "est",
"Ethiopic script": "Ethiopic",
"Faroese": "fao",
"Filipino": "fil",
"Finnish": "fin",
"Fraktur script": "Fraktur",
"Frankish": "frk",
"French": "fra",
"French, Middle (ca.1400-1600)": "frm",
"Frisian (Western)": "fry",
"Gaelic (Scots)": "gla",
"Galician": "glg",
"Georgian": "kat",
"Georgian script": "Georgian",
"German": "deu",
"Greek": "ell",
"Greek script": "Greek",
"Gujarati": "guj",
"Gujarati script": "Gujarati",
"Gurmukhi script": "Gurmukhi",
"Hangul script": "Hangul",
"Hangul (vertical) script": "Hangul_vert",
"Han - Simplified script": "HanS",
"Han - Simplified (vertical) script": "HanS_vert",
"Han - Traditional script": "HanT",
"Han - Traditional (vertical) script": "HanT_vert",
"Hatian": "hat",
"Hebrew": "heb",
"Hebrew script": "Hebrew",
"Hindi": "hin",
"Hungarian": "hun",
"Icelandic": "isl",
"Indonesian": "ind",
"Inuktitut": "iku",
"Irish": "gle",
"Italian": "ita",
"Italian - Old": "ita_old",
"Japanese": "jpn",
"Japanese script": "Japanese",
"Japanese (vertical)": "jpn_vert",
"Japanese (vertical) script": "Japanese_vert",
"Javanese": "jav",
"Kannada": "kan",
"Kannada script": "Kannada",
"Kazakh": "kaz",
"Khmer": "khm",
"Khmer script": "Khmer",
"Korean": "kor",
"Korean (vertical)": "kor_vert",
"Kurdish (Arabic)": "kur_ara",
"Kyrgyz": "kir",
"Lao": "lao",
"Lao script": "Lao",
"Latin": "lat",
"Latin script": "Latin",
"Latvian": "lav",
"Lithuanian": "lit",
"Luxembourgish": "ltz",
"Macedonian": "mkd",
"Malayalam": "mal",
"Malayalam script": "Malayalam",
"Malay": "msa",
"Maltese": "mlt",
"Maori": "mri",
"Marathi": "mar",
"Mongolian": "mon",
"Myanmar script": "Myanmar",
"Nepali": "nep",
"Norwegian": "nor",
"Occitan (post 1500)": "oci",
"Old Georgian": "kat_old",
"Oriya (Odia) script": "Oriya",
"Oriya": "ori",
"Pashto": "pus",
"Persian": "fas",
"Polish": "pol",
"Portuguese": "por",
"Punjabi": "pan",
"Quechua": "que",
"Romanian": "ron",
"Russian": "rus",
"Sanskrit": "san",
"script and orientation": "osd",
"Serbian (Latin)": "srp_latn",
"Serbian": "srp",
"Sindhi": "snd",
"Sinhala script": "Sinhala",
"Sinhala": "sin",
"Slovakian": "slk",
"Slovenian": "slv",
"Spanish, Castilian - Old": "spa_old",
"Spanish": "spa",
"Sundanese": "sun",
"Swahili": "swa",
"Swedish": "swe",
"Syriac script": "Syriac",
"Syriac": "syr",
"Tajik": "tgk",
"Tamil script": "Tamil",
"Tamil": "tam",
"Tatar": "tat",
"Telugu script": "Telugu",
"Telugu": "tel",
"Thaana script": "Thaana",
"Thai script": "Thai",
"Thai": "tha",
"Tibetan script": "Tibetan",
"Tibetan Standard": "bod",
"Tigrinya": "tir",
"Tonga": "ton",
"Turkish": "tur",
"Ukrainian": "ukr",
"Urdu": "urd",
"Uyghur": "uig",
"Uzbek (Cyrillic)": "uzb_cyrl",
"Uzbek": "uzb",
"Vietnamese script": "Vietnamese",
"Vietnamese": "vie",
"Welsh": "cym",
"Yiddish": "yid",
"Yoruba": "yor"
}