#!/bin/python3 # Program Shoud run with sudo -HE # https://github.com/acidburnmonkey # import os import re import subprocess import requests import shutil import logging import gdown from rich.console import Console from rich.theme import Theme # pylint: disable=subprocess-run-check # pylint: disable=broad-exception-caught # pylint: disable=logging-fstring-interpolation logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) formater = logging.Formatter("%(asctime)s | %(levelno)s | %(funcName)s| %(message)s") f_handler = logging.FileHandler('logg.log') f_handler.setFormatter(formater) logger.addHandler(f_handler) logging.basicConfig( format="%(asctime)s | %(levelno)s | %(funcName)s| %(message)s ", filename='logg.log', level=logging.WARNING ) ap_theme = Theme({'ok':'green', 'error':'red', 'checkt':'bold cyan','promp':'orange1'}) console = Console(theme=ap_theme) user = os.getlogin() home = os.path.join('/home',user) def main(): setup = '' # confirm_user ='' local_user = user sudo_check() console.print(f"Setting up for user {local_user} ", style='promp') # while(True): # confirm_user = input(" y/n ") # if (confirm_user.lower() == 'n'): # user := input('Type username : ') # continue # elif (confirm_user.lower() == 'y'): # break console.print('optimizing dnf.conf', style='ok') dnf_config() install_programs_dnf() zsh_fonts() hyprland() # Pass D or L to copy_dotfiles function while (True): console.print('Set up dotfiles for Desktop (D) or Laptop (L) ?', style='promp') setup = input('>').lower() if setup == 'l' or setup == 'd': copy_dotfiles(setup) break executable_scripts() msic_configs() systemd() #correcting ownership # subprocess.run(f"chown -R {user}:{user} {os.path.join(home,'.config')}",shell=True ,stdout=subprocess.DEVNULL) ################ # END OF MAIN # ################ def dnf_config(): console.rule("Configuring dnf", style='checkt') # dnf conf with open('/etc/dnf/dnf.conf' , 'r+') as f: text = 'max_parallel_downloads=10 \nfastestmirror=true' match = re.search(r'(max_parallel_downloads=10)', f.read()) if not match: with open('/etc/dnf/dnf.conf', 'a+') as f: f.write(text) console.print(' changes made to dnf_config :heavy_check_mark:', style='ok') logger.info('changes made to dnf_config') else: console.print(' dnf.conf already optimized :heavy_check_mark:', style='checkt') subprocess.check_call('sudo dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm',stdout=subprocess.DEVNULL, shell=True) subprocess.check_call('sudo dnf install -y https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm',stdout=subprocess.DEVNULL, shell=True) console.print('rpmfusion added to repos :heavy_check_mark:', style='ok') logger.info('rpmfusion added to repos') #update Dnf subprocess.run('dnf upgrade -y', shell=True) logger.info('Updated Dnf ') def hyprland(): console.rule("Configuring hyprland", style='checkt') # create tty launcher with open(home +'/.local/bin/wrappedhl', 'w+') as file: file.write('''#!/bin/sh cd ~ export _JAVA_AWT_WM_NONREPARENTING=1 export XCURSOR_SIZE=24 exec Hyprland ''') file.seek(0) for line in file: line.strip() # create .desktop file with open('/usr/share/wayland-sessions/hyprland.desktop', 'w+') as file: file.write(f'''[Desktop Entry] Name=Hyprland Comment=An intelligent dynamic tiling Wayland compositor Exec={home}/.local/bin/wrappedhl Type=Application ''') file.seek(0) for line in file: line.strip() #making them executable subprocess.run(f'chmod +x {home}/.local/bin/wrappedhl', shell=True) subprocess.run('chmod +x /usr/share/wayland-sessions/hyprland.desktop', shell=True) logger.info('Created hyprland .desktop and wrappedhl') console.print('Created hyprland .desktop and wrappedhl :heavy_check_mark:', style='ok') # install programs dnfmax list i can pass to dnf of programs to install def install_programs_dnf(): console.rule("Installing All Programs DNF ", style='checkt') programs =[] with open("data.txt", 'r') as file: for line in file: programs.append(line.strip()) #for some reason they have to be passed to dnf individually # instead of unpacked list *programs for program in programs: try: subprocess.run(f'dnf install -y {program} ', shell=True) except Exception as e: console.print(Exception(),":x:" , style='error') logging.critical(f"Error at Installing programs: {str(e)}") logger.info('Installed programs in data.txt') ## checks for sudo def sudo_check(): sudo_user = os.getenv("SUDO_USER") if sudo_user is None: console.print("This program must run as sudo -HE ./script ", style='error') exit() else: console.print('ok :heavy_check_mark:', style='ok') # Oh my zsh setup + flathub def zsh_fonts(): console.rule("Installing Zsh fonts", style='checkt') try: console.print("installing oh my zsh ", style='ok') #installs oh my zsh ohmy_url = "https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh" zsh_installer = requests.get(ohmy_url, timeout=10) open('install.sh', 'wb').write(zsh_installer.content) #removing exec line with open('install.sh', 'r') as f: contents = f.read() pattern = r'^\s*exec zsh -l$' matches = re.findall(pattern, contents, flags=re.MULTILINE) if matches: contents = re.sub(pattern, '', contents, flags=re.MULTILINE) with open('install.sh', 'w') as f: f.write(contents) subprocess.run('chmod +x install.sh ', stdout=subprocess.DEVNULL, shell=True, check=True) subprocess.run(f'sudo -u {user} ./install.sh', shell=True, check=True) console.print("installing oh my zsh auto sugestions ", style='ok') # zsh auto sugestions subprocess.run(f'git clone https://github.com/zsh-users/zsh-autosuggestions {home}/.oh-my-zsh/custom/plugins/zsh-autosuggestions', shell=True) console.print("installing powerlevel10k ", style='ok') #powerlevel 10k subprocess.run(f"git clone --depth=1 https://github.com/romkatv/powerlevel10k.git {home}/.oh-my-zsh/custom/themes/powerlevel10k", shell=True) logger.info('Installed Oh_my_zsh , powerlevel10k , autosuggestions') except Exception as e: logging.warning(f"Could not set up Zsh: {str(e)}") console.print("Error setting up ohmyzsh :X:", style='error') console.print("installing flathub", style='ok') # flathub subprocess.run('flatpak remote-add --if-not-exists flathub https://flatInstalled programs in data.txthub.org/repo/flathub.flatpakrepo', shell=True, stdout=subprocess.DEVNULL) logger.info('Installed Flathub') # copy and override dotfiles def copy_dotfiles(setup): console.rule("Copying Dotfiles", style='checkt') # list of relevant configs lis = os.listdir() exeptions = ['.git', 'desktop', '.bashrc','.zshrc','picom.conf', 'polybar','data.txt' ,'i3','README.md','.gitignore','cinnamon-configs','Laptop-configs'] for z in exeptions: if z in lis: lis.remove(z) destination = os.path.join(home,'.config') shutil.copy2('.zshrc',home) shutil.copy2('.p10k.zsh',home) shutil.copy2('.vimrc',home) if (setup =='l'): console.print("Setting up dotfiles for Laptop", style='ok') # copying files recusrsively for dir in lis: print(subprocess.run(f'cp -r {dir} {destination}', shell=True)) elif (setup =='d'): console.print("Setting up dotfiles for Desktop", style='ok') # copying files recusrsively for dir in lis: print(subprocess.run(f'cp -r {dir} {destination}', shell=True)) console.print("Dotfiles copied :heavy_check_mark:", style='ok') logger.info('Dotfiles copied') def executable_scripts(): console.rule('Making scripts executable', style='checkt') for root ,_,files in os.walk(os.path.join(home,'.config')): for element in files: if '.sh' in element or '.py' in element: try: subprocess.run(f"chmod +x {os.path.join(root,element)}", shell=True) except Exception as e: logging.critical(f"Error at executable_scripts: {str(e)}") console.print("Job done :heavy_check_mark:", style='ok') logger.info('Made scripts in .config executable') def msic_configs(): console.rule('Setting up final configs', style='checkt') current_dir = os.getcwd() try : os.mkdir('misic') os.mkdir(os.path.join(home,'.fonts')) os.mkdir(os.path.join(home,'.themes')) except FileExistsError: pass os.chdir(os.path.join(current_dir,'misic')) #### Fonts # https://drive.google.com/drive/folders/1BciF4x3_K3T8p1Y17lHn_xWXnSAZpvDE fonts_url = 'https://drive.google.com/uc?id=1jebIzgH9BLLn7Ou3xOnSiIj2unIdyXFI' output ='fonts-c.zip' gdown.download(fonts_url,output, quiet=False) subprocess.run(f"unzip {output} -d {os.path.join(home,'.fonts')}",stdout=subprocess.DEVNULL ,shell=True) subprocess.run("fc-cache -f",stdout=subprocess.DEVNULL ,shell=True) console.print("Fonts downloaded :heavy_check_mark:", style='ok') logger.info('Fonts donwloaded ') #Icons subprocess.run('git clone --depth 1 https://github.com/EliverLara/candy-icons.git /usr/share/icons/candy-icons', shell=True, stdout=subprocess.DEVNULL) console.print("Icons have been downloaded :heavy_check_mark:", style='ok') logger.info('candy-icons downloaded') try: themes_urls =['https://drive.google.com/uc?id=1KkqC5vaBjePSHxjBI_8PWfm3jNW5gO7k','https://drive.google.com/uc?id=1-qq3wmuQhkKHpW_8OrRNS92AHD9LE4un' ,'https://drive.google.com/uc?id=1mxkN9b4Ws7CeqF_KaTlA3dA5e75UUa4y','https://drive.google.com/uc?id=1cYLRsxmWeQJMOS7QEGEgJenRPKxgwN7X'] for index,file in enumerate(themes_urls): output = str(index)+'.zip' gdown.download(file, output ,quiet=False) subprocess.run(f"unzip {output} -d {os.path.join(home,'.themes')}", shell=True, stdout=subprocess.DEVNULL) console.print("Themes have been downloaded :heavy_check_mark:", style='ok') logger.info('Themes have been downloaded') ## Set themes Gtk subprocess.run("gsettings set org.gnome.desktop.interface icon-theme 'candy-icons'", shell=True) subprocess.run("gsettings set org.gnome.desktop.interface gtk-theme 'Catppuccin-Macchiato-Standard-Blue-Dark'", shell=True) subprocess.run("gsettings set org.gnome.desktop.interface font-name 'Roboto-Regular'", shell=True) #Flatpak force theme subprocess.run("flatpak override --filesystem=$HOME/.themes", shell=True) subprocess.run("flatpak override --env=GTK_THEME=Catppuccin-Macchiato-Standard-Blue-Dark", shell=True) console.print("Themes have been Set :heavy_check_mark:", style='ok') logger.info('Themes have been Set') except Exception as e: logging.critical(f"Could not get themes :{str(e)}") console.print("Error with Themes :X:", style='error') def systemd(): console.rule('Enabling user services', style='checkt') user_services = ['gnome-keyring.service', 'ssh-agent.service', 'polkit-gnome-authentication-agent.service', 'hypridle.service','gnome-keyring-daemon.service'] try: for services in user_services: subprocess.run(f'systemctl --user enable {services}', shell=True) except Exception as e: logging.critical(f"Could not start service :{str(e)}") console.print("Error starting some services :X:", style='error') if __name__ == '__main__': main()