diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index e975aa4..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# Changelog Backuppy - -## [1.02.000] - 2021-05-05 -### Added -- Now fully functional as the shell version - -### Changed -- Updated "README.md" concerning installation and usage -- Changed filename "Changelog.MD" to "CHANGELOG.md" - -### Fixed -- Fixed problem with the Bash/ZSH config - -## [1.01.001] - 2021-05-04 -### Changed -- Use E-MAIL constant - -## [1.01.000] - 2021-05-04 -### Added -- Graphical installer based on Python3 with PySide2 GUI framework (Qt-bindings for Python) -- Changelog.MD - -### Changed -- Directory ".languages" renamed to "languages" due to python module import syntax constraints -- Files "english.txt" and "german.txt" renamed to .-py due to follow the python filename schema - -# Changelog Backuppy - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/install.py b/install.py deleted file mode 100644 index e99284f..0000000 --- a/install.py +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/env python3 -""" -project: Backuppy -version: 1.02.000 -file: install.py -summary: main entry python file -""" - -# Standard library imports -import os - -# Third party imports -from PySide2 import QtCore -from PySide2 import QtGui -from PySide2 import QtCore, QtWidgets - -# local imports -from languages import english -from languages import german - -# local globals -VERSION: str = "1.02.000" -EMAIL: str = "fotocoder@joschu.ch" -TARGET_SCRIPT: str = "Backuppy.sh" -EXCLUDE_FILE: str = "exclude.txt" -LANG_EN: str = "English" -LANG_DE: str = "German" -LANGUAGE: str = LANG_EN -MYDIR: str = os.environ.get("mydir") -if not MYDIR: - MYDIR = os.getcwd() -SOURCEDIR: str = None -EXCLUDE: bool = True -TARGETDIR: str = None -RSYNC_CMD: str = None - -def get_lang_text(search_str: str): - """ Returns a string from the appropriate language file. """ - return_str: str = eval("english." + search_str) - global LANGUAGE - if LANGUAGE == LANG_DE: - return_str = eval("german." + search_str) - return return_str - -def trace(message_txt: str): - """ Print a formatted message to std out. """ - print(f"[ OK ]", message_txt) - -class BackuppyWizard(QtWidgets.QWizard): - def __init__(self, parent=None): - super().__init__(parent) - - self.addPage(Page01(self)) - self.addPage(Page02(self)) - self.addPage(Page03(self)) - self.addPage(Page04(self)) - self.addPage(Page05(self)) - self.addPage(Page06(self)) - self.addPage(Page07(self)) - 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) - - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label) - layout.addWidget(self.comboBox) - self.setLayout(layout) - - def validatePage(self): - global LANGUAGE - if self.comboBox.currentText() == LANG_DE: - LANGUAGE = LANG_DE - else: - LANGUAGE = LANG_EN - return True - - -class Page02(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("languagepack")) - self.label2.setText(get_lang_text("intromsg2")) - - -class Page03(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label = QtWidgets.QLabel() - self.groupbox = QtWidgets.QGroupBox() - self.groupbox.setFlat(True) - self.radio1 = QtWidgets.QRadioButton() - self.radio2 = QtWidgets.QRadioButton() - - vbox = QtWidgets.QVBoxLayout() - vbox.addWidget(self.radio1) - vbox.addWidget(self.radio2) - vbox.addStretch(1) - self.groupbox.setLayout(vbox) - - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label) - layout.addWidget(self.groupbox) - self.setLayout(layout) - - def initializePage(self): - self.label.setText(get_lang_text("excludefile1")) - self.radio1.setText(get_lang_text("Yes")) - self.radio2.setText(get_lang_text("No")) - self.radio1.setChecked(True) - - def validatePage(self): - global EXCLUDE - if self.radio1.isChecked(): - EXCLUDE = True - else: - EXCLUDE = False - return True - -class Page04(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label = QtWidgets.QLabel() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label) - self.setLayout(layout) - - def initializePage(self): - global EXCLUDE - if EXCLUDE: - self.label.setText(get_lang_text("excludefile2")) - else: - self.label.setText(get_lang_text("excludefile3")) - -class Page05(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - self.edit = QtWidgets.QLineEdit() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - layout.addWidget(self.edit) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("srcdir1")) - self.label2.setText(get_lang_text("srcdir2")) - - def validatePage(self): - global SOURCEDIR - SOURCEDIR = self.edit.text() - - return True - - -class Page06(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - self.label3 = QtWidgets.QLabel() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - layout.addWidget(self.label3) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("srcdir3_1")) - bold_text = f"
{SOURCEDIR}
" - self.label2.setText(bold_text) - self.label3.setText(get_lang_text("srcdir3_2")) - - -class Page07(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.edit = QtWidgets.QLineEdit() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.edit) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("targetdir1")) - - def validatePage(self): - global TARGETDIR - TARGETDIR = self.edit.text() - - return True - - -class Page08(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - self.label3 = QtWidgets.QLabel() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - layout.addWidget(self.label3) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("targetdir2_1")) - bold_text = f"{TARGETDIR}
" - self.label2.setText(bold_text) - self.label3.setText(get_lang_text("targetdir2_2")) - - def validatePage(self): - global RSYNC_CMD, MYDIR, SOURCEDIR, TARGETDIR - RSYNC_CMD = f"rsync -aqp --exclude-from={MYDIR}/exclude.txt {SOURCEDIR} {TARGETDIR}" - - return True - - -class Page09(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - self.setLayout(layout) - - def initializePage(self): - self.label1.setText(get_lang_text("collect")) - global RSYNC_CMD - #self.label2.setText(f"{RSYNC_CMD}") - bold_text = f"{RSYNC_CMD}
" - self.label2.setText(bold_text) - - -class Page10(QtWidgets.QWizardPage): - def __init__(self, parent=None): - super().__init__(parent) - self.label1 = QtWidgets.QLabel() - self.label2 = QtWidgets.QLabel() - self.label3 = QtWidgets.QLabel() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label1) - layout.addWidget(self.label2) - layout.addWidget(self.label3) - self.setLayout(layout) - self.setFinalPage(True) - - def initializePage(self): - self.label1.setText(get_lang_text("outro1")) - self.label2.setText(get_lang_text("outro2")) - urlLink = f"{EMAIL}" - self.label3.setText(urlLink) - self.label3.setOpenExternalLinks(True) - - def validatePage(self): - # create shell script with rsync command - create_shell_script(RSYNC_CMD) - - return True - - -def create_shell_script(command_str: str): - rc_filepath: str = None - - global MYDIR, EXCLUDE, TARGET_SCRIPT - - TARGET_SCRIPT = os.path.join(MYDIR, TARGET_SCRIPT) - ALIAS_STR = f"alias backuppy='sudo {TARGET_SCRIPT}'" - current_shell = os.environ.get("SHELL") - user_home = os.environ.get("HOME") - - ## STEP 1: update shell config scripts with alias for backuppy - # .zshrc case1 and case2 - if current_shell in ("/usr/bin/zsh", "/bin/zsh"): - # Appending to bash config file - rc_filepath = os.path.join(user_home, ".zshrc") - - # .bashrc case1 and case2 - elif current_shell in ("/usr/bin/bash", "/bin/bash"): - # Appending to zsh config file - rc_filepath = os.path.join(user_home, ".bashrc") - - if os.path.isfile(rc_filepath): - with open(rc_filepath, 'a') as file1: - trace(f"Writing {ALIAS_STR} to config file '{rc_filepath}'.") - file1.write("\n# Following line was created by Backuppy\n" + ALIAS_STR + "\n") - - ## STEP 2: Create the exclude script if desired - if EXCLUDE: - global EXCLUDE_FILE - EXCLUDE_FILE = os.path.join(MYDIR, EXCLUDE_FILE) - with open(EXCLUDE_FILE, "w") as file2: - trace(f"creating exclude-file '{EXCLUDE_FILE}'.") - file2.writelines("\n") - - ## STEP 3: enter the rsync command in Backuppy.sh - with open(TARGET_SCRIPT, "w") as file3: - trace(f"Writing rsync-command to file '{TARGET_SCRIPT}':\n {command_str}") - file3.writelines("#!/bin/bash" + "\n") - file3.writelines(command_str + "\n") - - -if __name__ == '__main__': - trace(f"Starting Backuppy install.py v{VERSION}") - app = QtWidgets.QApplication() - wizard = BackuppyWizard() - wizard.show() - - app.exec_() - - trace("Ending Backuppy install.py") diff --git a/languages/english.py b/languages/english.py index e04cfe2..891ef03 100644 --- a/languages/english.py +++ b/languages/english.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -# """ -# project: Backuppy -# file: languages/english.py -# summary: english language file -# """ +""" +project: Backuppy +file: languages/english.py +summary: english language file +""" Yes="Yes" @@ -17,7 +17,7 @@ intromsg2="The installer will now ask you a few things to adapt your backup scri rsyncopt="rsync offers various options, but to simplify the installation process, I have activated the options -a, -q and -p. \n If you want to set more options, you can do thjat in the file 'Backuppy.sh'." -excludefile1="Now I need to know if you want to exclude one or more files/directories from your backups.\nThen you can adjust this in the 'exclude.txt'.\nThere you can exclude directories and files in the format '/directory' '/file.txt'.\nDo you want to exclude files/directories or not? [Y/N]" +excludefile1="Now I need to know if you want to exclude one or more files/directories from your backups.\nThen you can adjust this in the 'exclude.txt'.\nThere you can exclude directories and files in the format '/directory' '/file.txt'.\nDo you want to exclude files/directories or not?" excludefile2="Perfect, then you can enter your files/directories to be excluded in the file 'exclude.txt' after completing the installation of Backuppy." diff --git a/languages/german.py b/languages/german.py index 07508c9..bf4081e 100644 --- a/languages/german.py +++ b/languages/german.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -# """ -# project: Backuppy -# file: languages/german.py -# summary: german language file -# """ +""" +project: Backuppy +file: languages/german.py +summary: german language file +""" Yes="Ja" @@ -17,7 +17,7 @@ intromsg2="Der Installer wird dich nun einige Dinge abfragen, um dein Backup-Skr rsyncopt="rsync bietet verschiedene Optionen an, um das Ganze jedoch zu vereinfachen, habe ich die Optionen -a, -q und -p aktiviert. \n Wenn du mehr einstellen willst, kannst du das in der Datei 'Backuppy.sh' machen." -excludefile1="Nun muss ich noch wissen, ob du ein oder mehrere Dateien/Verzeichnisse vom Backup ausschliessen möchtest.\nDann kannst du das in der 'exclude.txt' anpassen.\nDort kannst du dann im Format '/Verzeichnis' '/Datei.txt' Verzeichnisse und Dateien ausschliessen.\nMöchtest du Dateien/Verzeichnisse ausschliessen oder nicht? [J/N]" +excludefile1="Nun muss ich noch wissen, ob du ein oder mehrere Dateien/Verzeichnisse vom Backup ausschliessen möchtest.\nDann kannst du das in der 'exclude.txt' anpassen.\nDort kannst du dann im Format '/Verzeichnis' '/Datei.txt' Verzeichnisse und Dateien ausschliessen.\nMöchtest du Dateien/Verzeichnisse ausschliessen oder nicht?" excludefile2="Perfekt, dann kannst du nach der Fertigstellung der Installation von Backuppy deine auszuschliessenden\nDateien/Verzeichnisse in der Datei 'exclude.txt eintragen."