diff --git a/.gitignore b/.gitignore index 8215ca8..e77dd36 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,10 @@ files/.wakatime.cfg backup/ # Don't include file backups *.bak +# todo list +*.todo +# VSCode settings +.vscode/ +# Python Cache +__pycache__/ +.pytest_cache/ diff --git a/lib.py b/lib.py new file mode 100644 index 0000000..71be9a3 --- /dev/null +++ b/lib.py @@ -0,0 +1,277 @@ +#!/bin/python3 +import subprocess + + +class Command: + def execute(command): + '''Execute bash command + + Arguments: + command {str} -- full command + + Returns: + int -- returncode + ''' + command = command.split(' ') + return subprocess.call(command) + + def get_output(command): + '''Get standard output of command + + Arguments: + command {str} -- full command + + Returns: + str -- stdout + ''' + command = command.split(' ') + return subprocess.run( + command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).stdout.decode('utf-8') + + def get_return_code(command): + '''Get return code of command + + Arguments: + command {str} -- full command + + Returns: + int -- returncode + ''' + command = command.split(' ') + return subprocess.run( + command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).returncode + + +class Color: + '''Contains list of colors for printing''' + def get_256_color(color): + '''Get color using tput (256-colors base) + + Arguments: + color {str/int} -- color id + + Returns: + color -- color prefix for strings + ''' + return Command.get_output(f'tput setaf {color}') + + def get_special_color(index): + '''Get special colors using tput (like bold, etc..) + + Arguments: + index {str} -- arguments following `tput` command + + Returns: + color -- color prefix for strings + ''' + return Command.get_output(f'tput {index}') + + RED = get_256_color(196) + BLUE = get_256_color(51) + GREEN = get_256_color(46) + YELLOW = get_256_color(226) + GOLD = get_256_color(214) + GREY = get_256_color(238) + + RESET = get_special_color('sgr0') + BOLD = get_special_color('bold') + + +class Print: + def question(question): + '''Print syntax for question + + Arguments: + question {str} -- text to print (question) + ''' + print(f'{Color.GREEN} // {question}{Color.RESET}') + + def question_options(options): + '''Print syntax for options for question + + Arguments: + options {str} -- options to print + ''' + print(f'{Color.GREEN} # {options}{Color.RESET}') + + def action(action): + '''Print syntax for actions + + Arguments: + action {str} -- text to print + ''' + print(f'{Color.GOLD} >> {action}{Color.RESET}') + + def err(text): + '''Print syntax for error + + Arguments: + text {str} -- error text to print + ''' + print(f'{Color.RED} !! {text}{Color.RESET}') + + def cancel(text): + '''Print syntax for cancellation + + Arguments: + text {str} -- text to print + ''' + print(f'{Color.GREY} >> {text}{Color.RESET}') + + def warning(text): + '''Print syntax for warnings + + Arguments: + text {str} -- warn text to print + ''' + print(f'{Color.YELLOW} ** {text}{Color.RESET}') + + +class Input: + def yes_no(question): + '''Generate question and wait for yes/no answer from user + + Arguments: + question {str} -- question text + + Returns: + bool -- question result (yes==true) + ''' + Print.question(question) + while True: + ans = input(' Y/N: ') + if ans.lower() == 'y': + return True + elif ans.lower() == 'n': + return False + else: + Print.err('Invalid option (Y/N)') + + def multiple(question, options): + '''Generate question and wait for user to pick one of options specified + + Arguments: + question {str} -- question text + options {list} -- list of possible options (strings) + + Returns: + str -- one of options + ''' + def get_input_range(max): + while True: + inp = input(' ->') + try: + inp = int(inp) + for n in range(0, max + 1): + if inp == n: + return inp + break + else: + Print.err(f'Invalid input, range: 1-{max}') + except ValueError: + Print.err(f'Invalid input (must be number: 1-{max})') + continue + + Print.question(question) + + options_str = '0: No/Cancel / ' + for index, option in enumerate(options): + options_str += f'{index + 1}: {option} / ' + # Remove ending ' / ' + options_str = options_str[:-3] + + Print.question_options(options_str) + answer = get_input_range(len(options)) + if answer != 0: + return options[answer - 1] + else: + return False + + +class Install: + def check_not_installed(package_name): + '''Check if specified package is currently not installed + + Arguments: + package_name {str/list} -- name of package/es to check + + Returns: + bool -- is/are package/all packages not installed? + ''' + if type(package_name) == str: + out = Command.get_return_code(f'pacman -Qi {package_name}') + if out == 1: + # NOT INSTALLED + return True + else: + # INSTALLED + return False + elif type(package_name) == list: + for package in package_name: + if not Install.check_not_installed(package): + break + else: + return True + return False + else: + raise TypeError( + 'check_not_installed() only takes string or list inputs') + + def package(package_name, install_text='default', reinstall=False): + '''Installation of package + + Arguments: + package_name {str} -- name of package to be installed + install_text {str} -- text presented to user before installing + + Returns: + bool -- installed + ''' + if Install.check_not_installed(package_name) or reinstall: + if install_text == 'default': + install_text = f'Do you wish to install {package_name}?' + if install_text[:10] == 'default + ': + install_text = f'Do you wish to install {package_name}? {install_text[10:]}' + if Input.yes_no(install_text): + Command.execute(f'sudo pacman -S {package_name}') + return True + else: + Print.cancel('Skipping...') + return False + else: + Print.cancel(f'{package_name} already installed') + return False + + def multiple_packages(packages, install_text, options, reinstall=False): + '''Installation of multiple packages + + Arguments: + packages {list} -- list of packages to choose from + install_text {str} -- text presented to user when picking which package to install + options {list} -- list of options to choose from (must be in same order as packages) + + Returns: + bool/str -- False if none / chosen package name + ''' + if Install.check_not_installed(packages) or reinstall: + choice = Input.multiple(f'{install_text}', options) + if choice: + for index, option in enumerate(options): + if choice == option: + Command.execute(f'sudo pacman -S {packages[index]}') + return packages[index] + else: + Print.cancel('Skipping...') + return False + else: + for package in packages: + if not Install.check_not_installed(package): + Print.cancel(f'{package} already installed') + return False + + def upgrade_pacman(): + # if Input.yes_no('Do you wish to Sync(S), refresh(y) and upgrade(u) pacman - Recommended?'): + # Command.execute('sudo pacman -Syu') + # else: + # Print.warning('Pacman upgrade cancelled.') + pass diff --git a/package_install.py b/package_install.py new file mode 100644 index 0000000..c6b7841 --- /dev/null +++ b/package_install.py @@ -0,0 +1,37 @@ +#!/bin/python3 +from lib import Print, Install + + +Install.upgrade_pacman() + +Print.action('Package Installation') + +Install.package('networkmanager') +Install.package( + 'git', 'default + (Required for some installations, otherwise they\'ll be skipped)') +Install.package('zsh', 'default + shell') +Install.package('sudo') + +# Desktop Enviroment +Install.multiple_packages(['plasma', 'plasma-desktop', 'gnome'], 'Do you wish to install DE (Desktop Enviroment)?', [ + 'Plasma (KDE)', 'Plasma-Desktop (KDE-Minimal dependencies)', 'Gnome']) +# Display Manager +Install.multiple_packages(['sddm', 'gdm', 'lightdm'], 'Do you wish to install DM (Display Manager)?', [ + 'SDDM (KDE)', 'GDM (Gnome)', 'LightDM']) + +# TODO: YAY install +Install.package('exa', 'default + (Better ls tool)') +Install.package('terminator', 'default + (advanced terminal)') +Install.package('konsole', 'default + (KDE terminal emulator)') +Install.package('dolphin', 'default + (File Manager)') +Install.package('discord', 'default + (Chat App)') +# TODO: Spotify (YAY) +Install.package( + 'spectacle', 'default + (Screenshot tool)') +# TODO: Qualculate (YAY) +Install.package('gnome-system-monitor', + 'Do you wish to install gnome system monitor?') +Install.package( + 'code', 'Do you wish to install Visual Studio Code (Text/Code Editor)?') + +Print.action('Package Installation Complete') diff --git a/package_install.sh b/package_install.sh deleted file mode 100644 index c94e20f..0000000 --- a/package_install.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/sh - -# Set some basic colors using tput (8-bit color: 256 colors) -bold="$(tput bold)" -red="$(tput setaf 196)" -blue="$(tput setaf 51)" -yellow="$(tput setaf 226)" -gold="$(tput setaf 214)" -grey="$(tput setaf 238)" -lgrey="$(tput setaf 243)" -green="$(tput setaf 46)" -reset="$(tput sgr0)" - -SCRIPT_DIR="$HOME/dotfiles" - -function choose() { - return $(whiptail \ - --title "$1" \ - --yesno "$2" 25 72 \ - 3>&1 1>&2 2>&3) -} - -function menu2() { - output=$(whiptail \ - --title "$1" \ - --menu "$2" 25 72 0 \ - "1" "$3" \ - "2" "$4" \ - 3>&1 1>&2 2>&3) -} - -function cecho() { - echo "${lgrey} (package-install) $1${reset}" -} - -function yes_no() { - while true; do - read -p "(Y/n): " yn - case $yn in - [Yy]* ) return 0; break;; - [Nn]* ) return 1;; - * ) echo "Invalid choice (y/n)";; - esac - done -} - -function choice2() { - cecho "${green} -> 1. $1" - cecho "${green} -> 2. $2" - cecho "${green} -> c. Cancel" - while true; do - read -p "(1/2/c): " yn - case $yn in - [1]* ) return "1"; break;; - [2]* ) return "2";; - [cC]* ) return "c";; - * ) echo "Invalid choice (1/2/c)";; - esac - done -} - -function choice3() { - cecho "${green} -> 1. $1" - cecho "${green} -> 2. $2" - cecho "${green} -> 3. $3" - cecho "${green} -> c. Cancel" - while true; do - read -p "(1/2/3/c): " yn - case $yn in - [1]* ) return "1"; break;; - [2]* ) return "2";; - [3]* ) return "3";; - [cC]* ) return "c";; - * ) echo "Invalid choice (1/2/c)";; - esac - done -} - - - -cecho "${blue} // Do you wish to upgrade packages before installing (recommended) [pacman -Syu]" -if (yes_no); then - sudo pacman -Syu -fi - -cecho "${gold} >> Choose which packages you wish to install" -cecho "${blue} // X window system (xorg xorg-server)" -if (yes_no); then - sudo pacman -S xorg xorg-server -fi - -cecho "${blue} // Desktop Enviroment (you will be able to choose which DE)" -if (yes_no); then - res = choice2 "KDE - Plasma" "Gnome" - if [ $res == "1" ]; then - cecho "${gold} >> Installing plasma" - sudo pacman -S --needed plasma - elif [ $res == "2" ]; then - cecho "${gold} >> Installing gnome" - sudo pacman -S --needed gnome - else - cecho "${yellow} >> Aborting Desktop Enviroment installation" - fi -fi - -cecho "${blue} // Desktop Manager (you will be able to choose which DM)" -if (yes_no); then - res = choice3 "SDDM (KDE)" "GDM (Gnome)" "LightDM" - if [ $res == "1" ]; then - cecho "${gold} >> Installing SDDM (KDE)" - sudo pacman -S --needed sddm - elif [ $res == "2" ]; then - sudo pacman -S --needed gdm - elif [ $res == "3" ]; then - sudo pacman -S --needed lightdm - else - echo "${lgrey} (package-install) ${yellow} >> Aborting Desktop Enviroment install" - fi -fi - -# sudo pacman -S plasma | sudo pacman -S gnome -sudo pacman -S git -sudo pacman -S