Reworked "install.sh" to call "install.py"
- Reworked "install.sh" to call "install.py" - All the functionality in "install.py" - Launches graphical installer when called with "--gui" option: "install.sh --gui"
This commit is contained in:
parent
a8199debc9
commit
a1c5fbf7ea
5 changed files with 390 additions and 480 deletions
|
@ -1,5 +1,10 @@
|
||||||
# Changelog Backuppy
|
# Changelog Backuppy
|
||||||
|
|
||||||
|
## [0.7] - 2021-05-06
|
||||||
|
### Added
|
||||||
|
- Reworked "install.sh" to call "install.py"
|
||||||
|
- Launches graphical installer when called with "--gui" option: "install.sh --gui"
|
||||||
|
|
||||||
## [0.6] - 2021-05-06
|
## [0.6] - 2021-05-06
|
||||||
### Added
|
### Added
|
||||||
- Write alias to Backuppy.sh into .bashrc/.zshrc only if not already existing
|
- Write alias to Backuppy.sh into .bashrc/.zshrc only if not already existing
|
||||||
|
|
391
install.py
391
install.py
|
@ -1,343 +1,176 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
project: Backuppy
|
project: Backuppy
|
||||||
version: 0.6
|
version: 0.7
|
||||||
file: install.py
|
file: install.py
|
||||||
summary: main entry python file
|
summary: main entry python file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Standard library imports
|
# Standard library imports
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
# Third party imports
|
|
||||||
from PySide2 import QtWidgets
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from languages import english
|
from languages import english
|
||||||
from languages import german
|
from languages import german
|
||||||
|
|
||||||
# local globals
|
# local globals
|
||||||
VERSION: str = "0.6"
|
# ----------------------
|
||||||
EMAIL: str = "fotocoder@joschu.ch"
|
VERSION: str = "0.7"
|
||||||
TARGET_SCRIPT: str = "Backuppy.sh"
|
# ----------------------
|
||||||
EXCLUDE_FILE: str = "exclude.txt"
|
MYDIR = os.getcwd()
|
||||||
|
EXCLUDE_FILE = "exclude.txt"
|
||||||
|
BACKUPPY_SCRIPT = "Backuppy.sh"
|
||||||
|
SHELL = os.environ.get("SHELL")
|
||||||
|
HOME = os.environ.get("HOME")
|
||||||
LANG_EN: str = "English"
|
LANG_EN: str = "English"
|
||||||
LANG_DE: str = "German"
|
LANG_DE: str = "German"
|
||||||
LANGUAGE: str = LANG_EN
|
LANGUAGE: str = None
|
||||||
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
|
RSYNC_CMD: str = None
|
||||||
|
EMAIL: str = "fotocoder@joschu.ch"
|
||||||
|
|
||||||
|
def set_language(language):
|
||||||
|
global LANGUAGE
|
||||||
|
LANGUAGE = language
|
||||||
|
|
||||||
|
def trace(message_txt):
|
||||||
|
""" Print a formatted message to std out. """
|
||||||
|
print("[ OK ] " + message_txt)
|
||||||
|
|
||||||
def get_lang_text(search_str: str):
|
def get_lang_text(search_str: str):
|
||||||
|
global LANGUAGE
|
||||||
""" Returns a string from the appropriate language file. """
|
""" Returns a string from the appropriate language file. """
|
||||||
return_str: str = eval("english." + search_str)
|
return_str: str = eval("english." + search_str)
|
||||||
global LANGUAGE
|
|
||||||
if LANGUAGE == LANG_DE:
|
if LANGUAGE == LANG_DE:
|
||||||
return_str = eval("german." + search_str)
|
return_str = eval("german." + search_str)
|
||||||
return return_str
|
return return_str
|
||||||
|
|
||||||
def trace(message_txt: str):
|
def install_cli_main():
|
||||||
""" Print a formatted message to std out. """
|
language = input("Hello, first of all, which language do you prefer: German [DE] or English [EN]?\n> ")
|
||||||
print("[ OK ]" + message_txt)
|
if language.upper() == "DE":
|
||||||
|
set_language(LANG_DE)
|
||||||
class BackuppyWizard(QtWidgets.QWizard):
|
print("Perfekt, nun ist das deutsche Sprachpaket aktiviert. Willkommen!\n")
|
||||||
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:
|
else:
|
||||||
LANGUAGE = LANG_EN
|
print("Perfect, the English language package is now activated. Welcome!.\n")
|
||||||
return True
|
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
class Page02(QtWidgets.QWizardPage):
|
print("\n" + get_lang_text("intromsg1") + "\n")
|
||||||
def __init__(self, parent=None):
|
time.sleep(1)
|
||||||
super().__init__(parent)
|
|
||||||
self.label1 = QtWidgets.QLabel()
|
|
||||||
self.label2 = QtWidgets.QLabel()
|
|
||||||
|
|
||||||
layout = QtWidgets.QVBoxLayout()
|
print("\n" + get_lang_text("intromsg2") + "\n")
|
||||||
layout.addWidget(self.label1)
|
time.sleep(1)
|
||||||
layout.addWidget(self.label2)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def initializePage(self):
|
# which Rsync options are available and which one you want to use
|
||||||
self.label1.setText(get_lang_text("languagepack"))
|
print(get_lang_text("rsyncopt") + "\n")
|
||||||
self.label2.setText(get_lang_text("intromsg2"))
|
time.sleep(1)
|
||||||
|
|
||||||
|
# asks if you want to exclude files/directories from backup and creates an exclude file in case of Yes
|
||||||
class Page03(QtWidgets.QWizardPage):
|
exclude = input(get_lang_text("excludefile1") + "\n> ")
|
||||||
def __init__(self, parent=None):
|
if exclude.upper() in ("J", "Y"):
|
||||||
super().__init__(parent)
|
print(get_lang_text("excludefile2") + "\n")
|
||||||
self.label = QtWidgets.QLabel()
|
os.environ["BUPY_CREATE_EXCLUDE"] = "True"
|
||||||
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:
|
else:
|
||||||
EXCLUDE = False
|
print(get_lang_text("excludefile3") + "\n")
|
||||||
return True
|
time.sleep(1)
|
||||||
|
|
||||||
class Page04(QtWidgets.QWizardPage):
|
# Asks for the source directory which should be saved
|
||||||
def __init__(self, parent=None):
|
print(get_lang_text("srcdir1"))
|
||||||
super().__init__(parent)
|
time.sleep(1)
|
||||||
self.label = QtWidgets.QLabel()
|
sourcedir = input(get_lang_text("srcdir2") + "\n> ")
|
||||||
layout = QtWidgets.QVBoxLayout()
|
|
||||||
layout.addWidget(self.label)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def initializePage(self):
|
print(f"{get_lang_text('srcdir3_1')} {sourcedir} {get_lang_text('srcdir3_2')}")
|
||||||
global EXCLUDE
|
time.sleep(1)
|
||||||
if EXCLUDE:
|
|
||||||
self.label.setText(get_lang_text("excludefile2"))
|
|
||||||
else:
|
|
||||||
self.label.setText(get_lang_text("excludefile3"))
|
|
||||||
|
|
||||||
class Page05(QtWidgets.QWizardPage):
|
# asks for the destination directory in which the backup should be saved
|
||||||
def __init__(self, parent=None):
|
targetdir = input(get_lang_text("targetdir1") + "\n> ")
|
||||||
super().__init__(parent)
|
print(f"{get_lang_text('targetdir2_1')} {targetdir} {get_lang_text('targetdir2_2')}")
|
||||||
self.label1 = QtWidgets.QLabel()
|
time.sleep(1)
|
||||||
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):
|
# collects all the information needed to execute the rsync command and creates it.
|
||||||
self.label1.setText(get_lang_text("srcdir1"))
|
print(get_lang_text("collect") + "\n")
|
||||||
self.label2.setText(get_lang_text("srcdir2"))
|
time.sleep(1)
|
||||||
|
exclude_file = os.path.join(MYDIR, EXCLUDE_FILE)
|
||||||
|
|
||||||
def validatePage(self):
|
RSYNC_CMD = f"rsync -aqp --exclude-from={exclude_file} {sourcedir} {targetdir}"
|
||||||
global SOURCEDIR
|
os.environ["BUPY_RSYNC_CMD"] = RSYNC_CMD
|
||||||
SOURCEDIR = self.edit.text()
|
print(f"{RSYNC_CMD}")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
return True
|
# Outro
|
||||||
|
print(get_lang_text("outro1"))
|
||||||
|
time.sleep(2)
|
||||||
|
print(get_lang_text("outro2") + " " + EMAIL)
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
class Page06(QtWidgets.QWizardPage):
|
return exclude_file
|
||||||
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):
|
def create_alias(directory, backuppy_script):
|
||||||
self.label1.setText(get_lang_text("srcdir3_1"))
|
# alias entry in .bashrc or .zshrc
|
||||||
bold_text = f"<p><strong>{SOURCEDIR}</strong></p>"
|
backuppy_script = os.path.join(directory, backuppy_script)
|
||||||
self.label2.setText(bold_text)
|
alias_str = f"alias backuppy='sudo {backuppy_script}'"
|
||||||
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"<p><strong>{TARGETDIR}</strong></p>"
|
|
||||||
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"<p><strong>{RSYNC_CMD}</strong></p>"
|
|
||||||
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"<a href='mailto: {EMAIL}'>{EMAIL}</a>"
|
|
||||||
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
|
|
||||||
# Check for installed ZSH
|
# Check for installed ZSH
|
||||||
if current_shell.upper().find("ZSH") > 0:
|
if SHELL.upper().find("ZSH") > 0:
|
||||||
rc_filepath = os.path.join(user_home, ".zshrc")
|
rc_filepath = os.path.join(HOME, ".zshrc")
|
||||||
|
|
||||||
# Check for installed BASH
|
# Check for installed BASH
|
||||||
if current_shell.upper().find("BASH") > 0:
|
if SHELL.upper().find("BASH") > 0:
|
||||||
rc_filepath = os.path.join(user_home, ".bashrc")
|
rc_filepath = os.path.join(HOME, ".bashrc")
|
||||||
|
|
||||||
# Append our alias if not already existing
|
# Append our alias if not already existing
|
||||||
if os.path.isfile(rc_filepath):
|
if os.path.isfile(rc_filepath):
|
||||||
fileRc = open(rc_filepath, "r") # open file in read mode
|
fileRc = open(rc_filepath, "r") # open file in read mode
|
||||||
|
|
||||||
backuppy_entry_exists = False
|
backuppy_entry_exists = False
|
||||||
for line in fileRc:
|
for line in fileRc:
|
||||||
if "alias backuppy=" in line:
|
if "alias backuppy=" in line:
|
||||||
backuppy_entry_exists = True
|
backuppy_entry_exists = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if not backuppy_entry_exists:
|
if not backuppy_entry_exists:
|
||||||
trace(f"Writing {ALIAS_STR} to config file '{rc_filepath}'.")
|
trace(f"Writing {alias_str} to config file '{rc_filepath}'.")
|
||||||
fileRc = open(rc_filepath, "a") # open file in append mode
|
fileRc = open(rc_filepath, "a") # open file in append mode
|
||||||
fileRc.write("\n# Following line was created by Backuppy\n" + ALIAS_STR + "\n")
|
fileRc.write("\n# Following line was created by Backuppy\n" + alias_str + "\n")
|
||||||
fileRc.close()
|
fileRc.close()
|
||||||
|
|
||||||
## STEP 2: Create the exclude script if desired
|
def create_backuppy_script(directory, backuppy_script, rsync_cmd):
|
||||||
if EXCLUDE:
|
# creates the file 'Backuppy.sh'
|
||||||
global EXCLUDE_FILE
|
backuppy_file = os.path.join(directory, backuppy_script)
|
||||||
EXCLUDE_FILE = os.path.join(MYDIR, EXCLUDE_FILE)
|
with open(backuppy_file, "w") as fBackuppy:
|
||||||
with open(EXCLUDE_FILE, "w") as file2:
|
trace(f"creating backuppy-file '{backuppy_file}'.")
|
||||||
trace(f"creating exclude-file '{EXCLUDE_FILE}'.")
|
fBackuppy.write("#!/bin/bash\n" + rsync_cmd + "\n")
|
||||||
file2.writelines("\n")
|
|
||||||
|
|
||||||
## STEP 3: enter the rsync command in Backuppy.sh
|
os.chmod(backuppy_file, 0o777) # make file executable
|
||||||
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")
|
|
||||||
|
|
||||||
|
def do_the_install():
|
||||||
|
""" Does the things with our environment variables. """
|
||||||
|
|
||||||
if __name__ == '__main__':
|
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)
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
trace(f"Starting Backuppy install.py v{VERSION}")
|
trace(f"Starting Backuppy install.py v{VERSION}")
|
||||||
app = QtWidgets.QApplication()
|
|
||||||
wizard = BackuppyWizard()
|
|
||||||
wizard.show()
|
|
||||||
|
|
||||||
app.exec_()
|
if argv and argv[0] == "--gui":
|
||||||
|
import install_gui
|
||||||
|
trace("Starting GUI-version.\n")
|
||||||
|
install_gui.main() # 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
|
||||||
|
|
||||||
|
do_the_install()
|
||||||
|
|
||||||
trace("Ending Backuppy install.py")
|
trace("Ending Backuppy install.py")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# sys.argv.append("--gui") # TODO: disable for production
|
||||||
|
sys.exit(main(sys.argv[1:]))
|
||||||
|
|
109
install.sh
109
install.sh
|
@ -1,107 +1,14 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Variables
|
|
||||||
mydir=$PWD
|
|
||||||
langDE="./languages/german.py"
|
|
||||||
langEN="./languages/english.py"
|
|
||||||
|
|
||||||
# Check if graphical installer should be executed
|
# Check if graphical installer should be executed
|
||||||
if [ "$1" == "--gui" ]; then
|
if [ "$1" == "--gui" ]; then
|
||||||
python3 -B install.py
|
if ! command -v pip3> /dev/null
|
||||||
exit 0
|
then
|
||||||
|
echo "Please install PIP on your system for the graphical version of Backuppy!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
pip3 install pyside2
|
||||||
|
python3 -B install.py "$1"
|
||||||
else
|
else
|
||||||
# Intro
|
python3 -B install.py
|
||||||
# language
|
|
||||||
echo -e "Hello, first of all, which language do you prefer: German [DE] or English [EN]?"
|
|
||||||
read language
|
|
||||||
if [ $language = "DE" ]; then
|
|
||||||
echo -e "Perfekt, nun ist das deutsche Sprachpaket aktiviert. Willkommen! \n"
|
|
||||||
. $langDE
|
|
||||||
sleep 1
|
|
||||||
fi
|
|
||||||
if [ $language = "EN" ]; then
|
|
||||||
echo -e "Perfect, the English language package is now activated. Welcome!. \n"
|
|
||||||
. $langEN
|
|
||||||
sleep 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n$intromsg1 \n"
|
|
||||||
sleep 1
|
|
||||||
echo -e " \n$intromsg2\n"
|
|
||||||
sleep 1
|
|
||||||
# Installer
|
|
||||||
|
|
||||||
# creates the file 'Backuppy.sh'
|
|
||||||
touch Backuppy.sh
|
|
||||||
echo "#!/bin/bash" >> Backuppy.sh
|
|
||||||
chmod +x Backuppy.sh
|
|
||||||
# which Rsync options are available and which one you want to use
|
|
||||||
echo -e "$rsyncopt \n"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# asks if you want to exclude files/directories from backup and creates an exclude file in case of Yes
|
|
||||||
echo -e "$excludefile1"
|
|
||||||
read exclude
|
|
||||||
if [ $exclude = "J" ]; then
|
|
||||||
echo -e "$excludefile2 \n"
|
|
||||||
touch exclude.txt
|
|
||||||
sleep 1
|
|
||||||
elif [ $exclude = "Y" ]; then
|
|
||||||
echo -e "$excludefile2 \n"
|
|
||||||
touch exclude.txt
|
|
||||||
sleep 1
|
|
||||||
fi
|
|
||||||
if [ $exclude = "N" ]; then
|
|
||||||
echo -e "$excludefile3 \n"
|
|
||||||
sleep 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Asks for the source directory which should be saved
|
|
||||||
echo -e "$srcdir1"
|
|
||||||
sleep 1
|
|
||||||
echo -e "$srcdir2"
|
|
||||||
read sourcedir
|
|
||||||
echo -e "$srcdir3_1 $sourcedir $srcdir3_2"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# asks for the destination directory in which the backup should be saved
|
|
||||||
echo -e "$targetdir1"
|
|
||||||
read targetdir
|
|
||||||
echo -e "$targetdir2_1 $targetdir $targetdir2_2"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# alias entry in .bashrc or .zshrc
|
|
||||||
# .zshrc case 1
|
|
||||||
echo $SHELL
|
|
||||||
if [ $SHELL = "/usr/bin/zsh" ]; then
|
|
||||||
echo "alias backuppy='sudo $mydir/Backuppy.sh'" >> ~/.zshrc
|
|
||||||
fi
|
|
||||||
# zshrc case 2
|
|
||||||
echo $SHELL
|
|
||||||
if [ $SHELL = "/bin/zsh" ]; then
|
|
||||||
echo "alias backuppy='sudo $mydir/Backuppy.sh'" >> ~/.zshrc
|
|
||||||
fi
|
|
||||||
#bashrc case 1
|
|
||||||
if [ $SHELL = "/usr/bin/bash" ]; then
|
|
||||||
echo "alias backuppy='sudo $mydir/Backuppy.sh'" >> ~/.bashrc
|
|
||||||
fi
|
|
||||||
# bashrc case 2
|
|
||||||
if [ $SHELL = "/bin/bash" ]; then
|
|
||||||
echo "alias backuppy='sudo $mydir/Backuppy.sh'" >> ~/.bashrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
# collects all the information needed to execute the rsync command and creates it.
|
|
||||||
echo -e "$collect \n"
|
|
||||||
sleep 1
|
|
||||||
echo -e "rsync -aqp --exclude-from=$mydir/exclude.txt $sourcedir $targetdir \n"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# enter the rsync command in Backuppy.sh
|
|
||||||
echo "rsync -aqp --exclude-from=$mydir/exclude.txt $sourcedir $targetdir" >> Backuppy.sh
|
|
||||||
|
|
||||||
# Outro
|
|
||||||
echo -e "$outro1"
|
|
||||||
sleep 2
|
|
||||||
echo "$outro2"
|
|
||||||
exit 0
|
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Variables
|
|
||||||
MYDIR = os.getcwd()
|
|
||||||
SHELL = os.environ.get("SHELL")
|
|
||||||
HOME = os.environ.get("HOME")
|
|
||||||
|
|
||||||
# Intro
|
|
||||||
# language
|
|
||||||
|
|
||||||
language = input("Hello, first of all, which language do you prefer: German [DE] or English [EN]?\n> ")
|
|
||||||
if language.upper() == "DE":
|
|
||||||
from languages.german import *
|
|
||||||
print("Perfekt, nun ist das deutsche Sprachpaket aktiviert. Willkommen!\n")
|
|
||||||
else:
|
|
||||||
from languages.english import *
|
|
||||||
print("Perfect, the English language package is now activated. Welcome!.\n")
|
|
||||||
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
print("\n" + intromsg1 + "\n")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
print("\n" + intromsg2 + "\n")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Installer
|
|
||||||
|
|
||||||
# creates the file 'Backuppy.sh'
|
|
||||||
fBackuppy = open("Backuppy.sh", "w")
|
|
||||||
fBackuppy.write("#!/bin/bash")
|
|
||||||
os.chmod("Backuppy.sh", 0o777) # make file executable
|
|
||||||
|
|
||||||
# which Rsync options are available and which one you want to use
|
|
||||||
print(rsyncopt + "\n")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# asks if you want to exclude files/directories from backup and creates an exclude file in case of Yes
|
|
||||||
exclude = input(excludefile1 + "\n> ")
|
|
||||||
if exclude.upper() in ("J", "Y"):
|
|
||||||
print(excludefile2 + "\n")
|
|
||||||
fExclude = open("exclude.txt", "w")
|
|
||||||
fExclude.close()
|
|
||||||
else:
|
|
||||||
print(excludefile3 + "\n")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Asks for the source directory which should be saved
|
|
||||||
print(srcdir1)
|
|
||||||
time.sleep(1)
|
|
||||||
sourcedir = input(srcdir2 + "\n> ")
|
|
||||||
|
|
||||||
print(f"{srcdir3_1} {sourcedir} {srcdir3_2}")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# asks for the destination directory in which the backup should be saved
|
|
||||||
targetdir = input(targetdir1 + "\n> ")
|
|
||||||
print(f"{targetdir2_1} {targetdir} {targetdir2_2}")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# alias entry in .bashrc or .zshrc
|
|
||||||
print(SHELL)
|
|
||||||
|
|
||||||
# .zshrc case1 and case2
|
|
||||||
if SHELL.upper().find("ZSH") >0:
|
|
||||||
# Appending to bash config file
|
|
||||||
fRc = open(os.path.join(HOME, ".zshrc"), "a") # append mode
|
|
||||||
fRc.write("\n" + f"alias backuppy='sudo {MYDIR}/Backuppy.sh'" + "\n")
|
|
||||||
fRc.close()
|
|
||||||
|
|
||||||
# .bashrc case1 and case2
|
|
||||||
elif SHELL.upper().find("BASH") >0:
|
|
||||||
# Appending to zsh config file
|
|
||||||
fRc = open(os.path.join(HOME, ".bashrc"), "a") # append mode
|
|
||||||
fRc.write("\n" + f"alias backuppy='sudo {MYDIR}/Backuppy.sh'" + "\n")
|
|
||||||
fRc.close()
|
|
||||||
|
|
||||||
# collects all the information needed to execute the rsync command and creates it.
|
|
||||||
print(collect + "\n")
|
|
||||||
time.sleep(1)
|
|
||||||
print(f"rsync -aqp --exclude-from={MYDIR}/exclude.txt {sourcedir} {targetdir}\n")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# enter the rsync command in Backuppy.sh
|
|
||||||
fBackuppy.write("\n" + f"rsync -aqp --exclude-from={MYDIR}/exclude.txt {sourcedir} {targetdir}" + "\n")
|
|
||||||
fBackuppy.close()
|
|
||||||
|
|
||||||
# Outro
|
|
||||||
print(outro1)
|
|
||||||
time.sleep(2)
|
|
||||||
print(outro2 + " fotocoder@joschu.ch")
|
|
260
install_gui.py
Normal file
260
install_gui.py
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
project: Backuppy
|
||||||
|
version: 0.7
|
||||||
|
file: install_gui.py
|
||||||
|
summary: main entry python file
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Standard library imports
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from PySide2 import QtWidgets
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from install import *
|
||||||
|
|
||||||
|
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):
|
||||||
|
if self.comboBox.currentText() == LANG_DE:
|
||||||
|
set_language(LANG_DE)
|
||||||
|
|
||||||
|
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"))
|
||||||
|
os.environ["BUPY_CREATE_EXCLUDE"] = "True"
|
||||||
|
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"<p><strong>{SOURCEDIR}</strong></p>"
|
||||||
|
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"<p><strong>{TARGETDIR}</strong></p>"
|
||||||
|
self.label2.setText(bold_text)
|
||||||
|
self.label3.setText(get_lang_text("targetdir2_2"))
|
||||||
|
|
||||||
|
def validatePage(self):
|
||||||
|
global RSYNC_CMD, MYDIR, SOURCEDIR, TARGETDIR
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
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"<p><strong>{RSYNC_CMD}</strong></p>"
|
||||||
|
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"<a href='mailto: {EMAIL}'>{EMAIL}</a>"
|
||||||
|
self.label3.setText(urlLink)
|
||||||
|
self.label3.setOpenExternalLinks(True)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app = QtWidgets.QApplication()
|
||||||
|
wizard = BackuppyWizard()
|
||||||
|
wizard.show()
|
||||||
|
|
||||||
|
app.exec_()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue