From 845b7e9c9a339d8a6d6c37f9999d692614778391 Mon Sep 17 00:00:00 2001 From: Paul S Date: Fri, 7 May 2021 12:08:33 +0200 Subject: [PATCH] "Browse"-button on directory-selection dialogs --- CHANGELOG.md | 4 +++ install.py | 78 +++++++++++++++++++++++++++++--------------------- install.sh | 16 ++++++++++- install_gui.py | 68 +++++++++++++++++++++++++++++++------------ 4 files changed, 115 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2167c76..dc9236c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog Backuppy +## [0.8] - 2021-05-07 +### Added +- Introduce "Browse"-button on directory-selection dialogs + ## [0.7] - 2021-05-06 ### Added - Reworked "install.sh" to call "install.py" diff --git a/install.py b/install.py index ac7ace4..40bde02 100644 --- a/install.py +++ b/install.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 """ project: Backuppy -version: 0.7 +version: 0.8 file: install.py -summary: main entry python file +summary: python installer-script in CLI-mode """ # Standard library imports @@ -17,23 +17,28 @@ from languages import german # local globals # ---------------------- -VERSION: str = "0.7" -# ---------------------- -MYDIR = os.getcwd() +VERSION: str = "0.8" +EMAIL = "fotocoder@joschu.ch" EXCLUDE_FILE = "exclude.txt" BACKUPPY_SCRIPT = "Backuppy.sh" +# ---------------------- +MYDIR = os.getcwd() +EXCLUDE: bool = False SHELL = os.environ.get("SHELL") HOME = os.environ.get("HOME") -LANG_EN: str = "English" -LANG_DE: str = "German" -LANGUAGE: str = None +LANG_EN = "English" +LANG_DE = "German" +LANGUAGE = LANG_EN RSYNC_CMD: str = None -EMAIL: str = "fotocoder@joschu.ch" def set_language(language): global LANGUAGE LANGUAGE = language +def set_exclude(exclude_flag): + global EXCLUDE + EXCLUDE = exclude_flag + def trace(message_txt): """ Print a formatted message to std out. """ print("[ OK ] " + message_txt) @@ -46,7 +51,7 @@ def get_lang_text(search_str: str): return_str = eval("german." + search_str) return return_str -def install_cli_main(): +def main_install_cli(): language = input("Hello, first of all, which language do you prefer: German [DE] or English [EN]?\n> ") if language.upper() == "DE": set_language(LANG_DE) @@ -69,9 +74,10 @@ def install_cli_main(): # asks if you want to exclude files/directories from backup and creates an exclude file in case of Yes exclude = input(get_lang_text("excludefile1") + "\n> ") if exclude.upper() in ("J", "Y"): + set_exclude(True) print(get_lang_text("excludefile2") + "\n") - os.environ["BUPY_CREATE_EXCLUDE"] = "True" else: + set_exclude(False) print(get_lang_text("excludefile3") + "\n") time.sleep(1) @@ -94,7 +100,7 @@ def install_cli_main(): exclude_file = os.path.join(MYDIR, EXCLUDE_FILE) RSYNC_CMD = f"rsync -aqp --exclude-from={exclude_file} {sourcedir} {targetdir}" - os.environ["BUPY_RSYNC_CMD"] = RSYNC_CMD + print(f"{RSYNC_CMD}") time.sleep(1) @@ -103,25 +109,25 @@ def install_cli_main(): time.sleep(2) print(get_lang_text("outro2") + " " + EMAIL) + return True, EXCLUDE, RSYNC_CMD + def create_exclude_file(directory, exclude_file): exclude_file = os.path.join(directory, exclude_file) with open(exclude_file, "w") as fExclude: trace(f"creating exclude-file '{exclude_file}'.") fExclude.write("\n") - return exclude_file - -def create_alias(directory, backuppy_script): +def create_alias(shell, home_dir, directory, backuppy_script): # alias entry in .bashrc or .zshrc backuppy_script = os.path.join(directory, backuppy_script) alias_str = f"alias backuppy='sudo {backuppy_script}'" # Check for installed ZSH - if SHELL.upper().find("ZSH") > 0: - rc_filepath = os.path.join(HOME, ".zshrc") + if shell.upper().find("ZSH") > 0: + rc_filepath = os.path.join(home_dir, ".zshrc") # Check for installed BASH - if SHELL.upper().find("BASH") > 0: - rc_filepath = os.path.join(HOME, ".bashrc") + if shell.upper().find("BASH") > 0: + rc_filepath = os.path.join(home_dir, ".bashrc") # Append our alias if not already existing if os.path.isfile(rc_filepath): fileRc = open(rc_filepath, "r") # open file in read mode @@ -145,29 +151,37 @@ def create_backuppy_script(directory, backuppy_script, rsync_cmd): os.chmod(backuppy_file, 0o777) # make file executable -def do_the_install(): - """ Does the things with our environment variables. """ +def do_the_install(is_exclude: bool, rsync_cmd: str): + """ Creates scripts and entries based on environment variables. """ - is_exclude = os.environ.get("BUPY_CREATE_EXCLUDE") - rsync_cmd = os.environ.get("BUPY_RSYNC_CMD") - - if is_exclude == "True": - exclude_file = create_exclude_file(MYDIR, EXCLUDE_FILE) - create_alias(MYDIR, BACKUPPY_SCRIPT) - create_backuppy_script(MYDIR, BACKUPPY_SCRIPT, rsync_cmd) + if is_exclude: + create_exclude_file(MYDIR, EXCLUDE_FILE) + + if rsync_cmd: + create_backuppy_script(MYDIR, BACKUPPY_SCRIPT, rsync_cmd) + create_alias(SHELL, HOME, MYDIR, BACKUPPY_SCRIPT) def main(argv): trace(f"Starting Backuppy install.py v{VERSION}") + is_finalized = False if argv and argv[0] == "--gui": - import install_gui + from install_gui import main_install_gui trace("Starting GUI-version.\n") - install_gui.main() # collect user input via GUI and store in env. variables + is_finalized, is_exclude, rsync_cmd = main_install_gui() # collect user input via GUI and store in env. variables + else: trace("Starting CLI-version.\n") - install_cli_main() # collect user input via CLI and store in env. variables + is_finalized, is_exclude, rsync_cmd = main_install_cli() # collect user input via CLI and store in env. variables + if is_finalized: + print("CLI finalized.") + if is_exclude: + print("exclude is true.") + if rsync_cmd: + print("rsync command returned: " + rsync_cmd) - do_the_install() + if is_finalized: + do_the_install(is_exclude, rsync_cmd) trace("Ending Backuppy install.py") diff --git a/install.sh b/install.sh index 9711dd6..08fe784 100755 --- a/install.sh +++ b/install.sh @@ -1,14 +1,28 @@ #!/bin/bash +# """ +# project: Backuppy +# version: 0.8 +# file: install.sh +# summary: main entry shell script +# """ # Check if graphical installer should be executed if [ "$1" == "--gui" ]; then + # Check if PIP ist installed if ! command -v pip3> /dev/null then echo "Please install PIP on your system for the graphical version of Backuppy!" exit fi - pip3 install pyside2 + # Check if PIP module "PySide2" is installed + if ! pip list | grep PySide2> /dev/null + then + # Install PySide2 + pip3 install PySide2 + fi + # Launch python installer in GUI mode python3 -B install.py "$1" else + # Launch python installer in CLI mode python3 -B install.py fi diff --git a/install_gui.py b/install_gui.py index 88ab993..538fe1c 100644 --- a/install_gui.py +++ b/install_gui.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 """ project: Backuppy -version: 0.7 +version: 0.8 file: install_gui.py -summary: main entry python file +summary: python installer-script in GUI-mode (needs PySide2) """ # Standard library imports @@ -19,6 +19,8 @@ class BackuppyWizard(QtWidgets.QWizard): def __init__(self, parent=None): super().__init__(parent) + self.setWindowTitle(get_lang_text("intromsg1")) + self.addPage(Page01(self)) self.addPage(Page02(self)) self.addPage(Page03(self)) @@ -29,15 +31,15 @@ class BackuppyWizard(QtWidgets.QWizard): self.addPage(Page08(self)) self.addPage(Page09(self)) self.addPage(Page10(self)) - - self.setWindowTitle(english.intromsg1) + self.resize(640, 480) + class Page01(QtWidgets.QWizardPage): def __init__(self, parent=None): super().__init__(parent) self.label = QtWidgets.QLabel("Hello, first of all, which language do you prefer: English or German?") - # self.comboBox = QIComboBox(self) + self.comboBox = QtWidgets.QComboBox(self) self.comboBox.addItem(LANG_EN, LANG_EN) self.comboBox.addItem(LANG_DE, LANG_DE) @@ -66,6 +68,8 @@ class Page02(QtWidgets.QWizardPage): self.setLayout(layout) def initializePage(self): + self.setWindowTitle(get_lang_text("intromsg1")) + self.label1.setText(get_lang_text("languagepack")) self.label2.setText(get_lang_text("intromsg2")) @@ -97,13 +101,13 @@ class Page03(QtWidgets.QWizardPage): self.radio1.setChecked(True) def validatePage(self): - global EXCLUDE if self.radio1.isChecked(): - EXCLUDE = True + set_exclude(True) else: - EXCLUDE = False + set_exclude(False) return True + class Page04(QtWidgets.QWizardPage): def __init__(self, parent=None): super().__init__(parent) @@ -116,7 +120,6 @@ class Page04(QtWidgets.QWizardPage): global EXCLUDE if EXCLUDE: self.label.setText(get_lang_text("excludefile2")) - os.environ["BUPY_CREATE_EXCLUDE"] = "True" else: self.label.setText(get_lang_text("excludefile3")) @@ -125,20 +128,33 @@ class Page05(QtWidgets.QWizardPage): super().__init__(parent) self.label1 = QtWidgets.QLabel() self.label2 = QtWidgets.QLabel() - self.edit = QtWidgets.QLineEdit() + self.efSourceDir = QtWidgets.QLineEdit() + self.pbBrowse = QtWidgets.QPushButton("Browse") + self.pbBrowse.clicked.connect(self.on_pbBrowse_clicked) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label1) layout.addWidget(self.label2) - layout.addWidget(self.edit) + + hLayout = QtWidgets.QHBoxLayout() + hLayout.addWidget(self.efSourceDir) + hLayout.addWidget(self.pbBrowse) + + layout.addLayout(hLayout) + self.setLayout(layout) def initializePage(self): self.label1.setText(get_lang_text("srcdir1")) self.label2.setText(get_lang_text("srcdir2")) + def on_pbBrowse_clicked(self): + options = QtWidgets.QFileDialog.Options() | QtWidgets.QFileDialog.ShowDirsOnly + dirName = QtWidgets.QFileDialog.getExistingDirectory(self, "Select Directory", None, options) + self.efSourceDir.setText(dirName) + def validatePage(self): global SOURCEDIR - SOURCEDIR = self.edit.text() + SOURCEDIR = self.efSourceDir.text() return True @@ -166,18 +182,31 @@ class Page07(QtWidgets.QWizardPage): def __init__(self, parent=None): super().__init__(parent) self.label1 = QtWidgets.QLabel() - self.edit = QtWidgets.QLineEdit() + self.efTargetDir = QtWidgets.QLineEdit() + self.pbBrowse = QtWidgets.QPushButton("Browse") + self.pbBrowse.clicked.connect(self.on_pbBrowse_clicked) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label1) - layout.addWidget(self.edit) + + hLayout = QtWidgets.QHBoxLayout() + hLayout.addWidget(self.efTargetDir) + hLayout.addWidget(self.pbBrowse) + + layout.addLayout(hLayout) + self.setLayout(layout) def initializePage(self): self.label1.setText(get_lang_text("targetdir1")) + def on_pbBrowse_clicked(self): + options = QtWidgets.QFileDialog.Options() | QtWidgets.QFileDialog.ShowDirsOnly + dirName = QtWidgets.QFileDialog.getExistingDirectory(self, "Select Directory", None, options) + self.efTargetDir.setText(dirName) + def validatePage(self): global TARGETDIR - TARGETDIR = self.edit.text() + TARGETDIR = self.efTargetDir.text() return True @@ -205,7 +234,6 @@ class Page08(QtWidgets.QWizardPage): exclude_file = os.path.join(MYDIR, EXCLUDE_FILE) RSYNC_CMD = f"rsync -aqp --exclude-from={exclude_file} {SOURCEDIR} {TARGETDIR}" - os.environ["BUPY_RSYNC_CMD"] = RSYNC_CMD return True @@ -239,6 +267,7 @@ class Page10(QtWidgets.QWizardPage): layout.addWidget(self.label2) layout.addWidget(self.label3) self.setLayout(layout) + self.setFinalPage(True) def initializePage(self): @@ -248,8 +277,11 @@ class Page10(QtWidgets.QWizardPage): self.label3.setText(urlLink) self.label3.setOpenExternalLinks(True) + def validatePage(self): + return True, EXCLUDE, RSYNC_CMD -def main(): + +def main_install_gui(): app = QtWidgets.QApplication() wizard = BackuppyWizard() wizard.show() @@ -257,4 +289,4 @@ def main(): app.exec_() if __name__ == '__main__': - main() + main_install_gui()