forked from FotoCoder/Backuppy
195 lines
6.4 KiB
Python
195 lines
6.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
project: Backuppy
|
|
version: 0.8.1
|
|
file: install.py
|
|
summary: python installer-script in CLI-mode
|
|
"""
|
|
|
|
# Standard library imports
|
|
import sys
|
|
import os
|
|
import time
|
|
|
|
# local imports
|
|
from languages import english
|
|
from languages import german
|
|
|
|
# local globals
|
|
# ----------------------
|
|
VERSION: str = "0.8.1"
|
|
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 = "English"
|
|
LANG_DE = "German"
|
|
LANGUAGE = LANG_EN
|
|
RSYNC_CMD: str = None
|
|
|
|
def set_language(language):
|
|
global LANGUAGE
|
|
LANGUAGE = language
|
|
|
|
def trace(message_txt, prefix_crlf=False):
|
|
""" Print a formatted message to std out.
|
|
|
|
:param "message_txt" [in] The message text that should be displayed.
|
|
:param "prefix_crlf" [in] If True, a carriage return/line feed will be done prior to the message text.
|
|
|
|
"""
|
|
|
|
if prefix_crlf:
|
|
print("\n")
|
|
print("[ OK ] " + message_txt)
|
|
|
|
def get_lang_text(search_str: str):
|
|
global LANGUAGE
|
|
""" Returns a string from the appropriate language file. """
|
|
return_str: str = eval("english." + search_str)
|
|
if LANGUAGE == LANG_DE:
|
|
return_str = eval("german." + search_str)
|
|
return return_str
|
|
|
|
def main_install_cli():
|
|
try:
|
|
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)
|
|
print("Perfekt, nun ist das deutsche Sprachpaket aktiviert. Willkommen!\n")
|
|
else:
|
|
print("Perfect, the English language package is now activated. Welcome!.\n")
|
|
|
|
time.sleep(1)
|
|
|
|
print("\n" + get_lang_text("intromsg1") + "\n")
|
|
time.sleep(1)
|
|
|
|
print("\n" + get_lang_text("intromsg2") + "\n")
|
|
time.sleep(1)
|
|
|
|
# which Rsync options are available and which one you want to use
|
|
print(get_lang_text("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(get_lang_text("excludefile1") + "\n> ")
|
|
global EXCLUDE
|
|
if exclude.upper() in ("J", "Y"):
|
|
EXCLUDE = True
|
|
print(get_lang_text("excludefile2") + "\n")
|
|
else:
|
|
EXCLUDE = False
|
|
print(get_lang_text("excludefile3") + "\n")
|
|
time.sleep(1)
|
|
|
|
# Asks for the source directory which should be saved
|
|
print(get_lang_text("srcdir1"))
|
|
time.sleep(1)
|
|
sourcedir = input(get_lang_text("srcdir2") + "\n> ")
|
|
|
|
print(f"{get_lang_text('srcdir3_1')} {sourcedir} {get_lang_text('srcdir3_2')}")
|
|
time.sleep(1)
|
|
|
|
# asks for the destination directory in which the backup should be saved
|
|
targetdir = input(get_lang_text("targetdir1") + "\n> ")
|
|
print(f"{get_lang_text('targetdir2_1')} {targetdir} {get_lang_text('targetdir2_2')}")
|
|
time.sleep(1)
|
|
|
|
# collects all the information needed to execute the rsync command and creates it.
|
|
print(get_lang_text("collect") + "\n")
|
|
time.sleep(1)
|
|
exclude_file = os.path.join(MYDIR, EXCLUDE_FILE)
|
|
|
|
RSYNC_CMD = f"rsync -aqp --exclude-from={exclude_file} {sourcedir} {targetdir}"
|
|
|
|
print(f"{RSYNC_CMD}")
|
|
time.sleep(1)
|
|
|
|
# Outro
|
|
print(get_lang_text("outro1"))
|
|
time.sleep(2)
|
|
print(get_lang_text("outro2") + " " + EMAIL)
|
|
|
|
return True, EXCLUDE, RSYNC_CMD
|
|
|
|
except KeyboardInterrupt:
|
|
trace("Programm interrupted by user.", prefix_crlf=True)
|
|
return False, None, None
|
|
|
|
|
|
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")
|
|
|
|
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_dir, ".zshrc")
|
|
# Check for installed BASH
|
|
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
|
|
backuppy_entry_exists = False
|
|
for line in fileRc:
|
|
if "alias backuppy=" in line:
|
|
backuppy_entry_exists = True
|
|
break
|
|
if not backuppy_entry_exists:
|
|
trace(f"Writing {alias_str} to config file '{rc_filepath}'.")
|
|
fileRc = open(rc_filepath, "a") # open file in append mode
|
|
fileRc.write("\n# Following line was created by Backuppy\n" + alias_str + "\n")
|
|
fileRc.close()
|
|
|
|
def create_backuppy_script(directory, backuppy_script, rsync_cmd):
|
|
# creates the file 'Backuppy.sh'
|
|
backuppy_file = os.path.join(directory, backuppy_script)
|
|
with open(backuppy_file, "w") as fBackuppy:
|
|
trace(f"creating backuppy-file '{backuppy_file}'.")
|
|
fBackuppy.write("#!/bin/bash\n" + rsync_cmd + "\n")
|
|
|
|
os.chmod(backuppy_file, 0o777) # make file executable
|
|
|
|
def do_the_install(is_exclude: bool, rsync_cmd: str):
|
|
""" Creates scripts and entries based on environment variables. """
|
|
|
|
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":
|
|
from install_gui import main_install_gui
|
|
trace("Starting GUI-version.")
|
|
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")
|
|
is_finalized, is_exclude, rsync_cmd = main_install_cli() # collect user input via CLI and store in env. variables
|
|
|
|
if is_finalized:
|
|
do_the_install(is_exclude, rsync_cmd)
|
|
|
|
trace("Ending Backuppy install.py")
|
|
|
|
if __name__ == '__main__':
|
|
# sys.argv.append("--gui") # TODO: disable for production
|
|
sys.exit(main(sys.argv[1:]))
|