#! /usr/bin/python3 # -*- coding: UTF-8 -*- """Make the fillpdf program available on this computer.""" import os import os.path import argparse import shutil import sys import subprocess # for cloning from constants import (CONFIGFILE, CONFIG_INSTALLDIR, CONFIG_FORMDIR, CONFIG_SEPARATOR) FORMS_DIRNAME = "TU-Dokumente" FORMS_URL = ("https://gitlab.math.tu-dresden.de/s1140568/" + FORMS_DIRNAME + ".git") def getPath(): """Get list of directories that are in the PATH environment variable. Returns: List of directories as strings. If loading path variable did not work, this list is empty. """ return os.environ.get('PATH', "").split(':') # "" is the default value def checkLinkAccess(dir): """Tell if I can create a link there. Try to create a link. If there was no error and indeed there is a link, remove the link and return True. Otherwise return False. """ # find a filename that is not used yet: linkloc = os.path.join(dir, "z") while os.path.lexists(linkloc): linkloc = linkloc + "z" if len(linkloc) > len(dir) + 100: print("Found files with names with 1 to 100 z's in " + "directory " + dir + " Probably error.") return False try: # try to create a link to the arbitrary position . os.symlink(os.curdir, linkloc) except FileNotFoundError as fnfe: # the directory dir does not exist return False except PermissionError as pe: # a cannot create a link there return False else: try: os.remove(linkloc) except FileNotFoundError as fnfe: print("In order to check if I have write access to the " + "directory " + dir + " I created a link " + linkloc + " there." + " I cannot remove it so do it yourself.") except PermissionError as pe: print("In order to check if I have write access to the " + "directory " + dir + " I created a link " + linkloc + " there." + " I cannot remove it so do it yourself.") return True def defaultPath(): """Choose a suitable default directory for installing. Try to access the path variable. If possible use first entry where I can create a symlink and is of the form: /usr/local/bin ~/bin ~/.config/bin If not possible use first where I can create a link. """ pathdirs = getPath() # check if sudo/ root: rootdir = os.path.join("/", "usr", "local", "bin") if rootdir in pathdirs and checkLinkAccess(rootdir): return rootpath for userdir in [os.path.join(os.environ.get("HOME", ""), ".local", "bin"), os.path.join(os.environ.get("HOME", ""), "bin")]: if userdir in pathdirs: if checkLinkAccess(userdir): return userdir try: os.mkdirs(userdir) except OSError: # already exists # some other error, do not use this # print("Debug: userdir link creation failed") pass else: if checkLinkAccess(userdir): return userdir else: # something did not work print("Debug: userdir link creation check failed " + "after creating dir") else: print("Debug: " + userdir + " is not in the path. It should be" + " on a typical system.") # print("Debug: non of the typical directories worked. " + # "Use the first possible.") for directory in pathdirs: if checkLinkAccess(directory): return directory print("""No suitable path for installing was found. Do one of the following: • execute this script as sudo/ root • add a directory where you have write access in the path • specify a directory via the --path option and add this directory""" + " to the path.") raise FileNotFoundError("No directory for installation found.") def createProgramSymlinks(where): """Create symlinks to some of scripts in this project. Arguments: where: the directory where to create the symlinks. Raises: multiple possibilities of error """ here = os.path.dirname(__file__) origloc = 0 linkloc = 1 # dict { script : (where it is, where the link should be) } # print("Debug: here: ", here) scripts = {script : (os.path.abspath( os.path.join(here, script + ".py")), os.path.join(where, script)) for script in ["fillform", "reise"]} # print("Debug: scripts: ", scripts) todoscripts = [] # check if the scripts exist, i.e. I am at the right place for script in scripts: # F_OK = does file exist? if not os.access(scripts[script][origloc], os.F_OK): raise FileNotFoundError("I cannot find the script " + script + " in " + scripts[script][origloc] + ".") if os.access(scripts[script][linkloc], os.F_OK, follow_symlinks=False): if os.path.islink(scripts[script][linkloc]): if not os.path.exists(scripts[script][linkloc]): # os.path.exists says False on broken symlinks raise FileExistsError("The symlink " + scripts[script][linkloc] + " already exists." + " It is a broken symlink." + " You may like to delete it " + "and start " + " this install script again.") elif os.path.samefile(os.readlink(scripts[script][linkloc]), scripts[script][origloc]): # print("Debug: link " + script + # " already links correctly.") # nothing to do: link already links correctly pass else: raise FileExistsError("The symlink " + scripts[script][linkloc] + " already exists and points " + "somewhere else.") else: raise FileExistsError("The file " + scripts[script][linkloc] + " already exists.") else: todoscripts.append(script) for script in todoscripts: try: os.symlink(scripts[script][origloc], scripts[script][linkloc]) except NotImplementedError: print("The python doc says this happens only on Windows" + " previous to Windows 6.0 (Vista). You should really " + "know better than using Windows.") raise except OSError as e: print("Apparently you do not have the permissions to create" + " a symlink in the directory " + where + ". Call this install script with --path