def get_kde_scaling_factor(): """Return the widgets scaling factor on KDE.""" scaling_factor = None was_found = False try: with open(KDE_CONFIG_FILE, 'r') as kde_obj: data = kde_obj.readlines() for line in data: line = list(map(lambda x: x.strip(), line.split("="))) if len(line) == 1: was_found = match( r'\[Containments\]\[[0-9]+\]\[General\]', line[0]) if len(line) > 1 and was_found and line[0].lower() == "iconsize": scaling_factor = int(line[1]) break if scaling_factor: Logger.debug("Scaling Factor/KDE: {}".format(scaling_factor)) return scaling_factor except (FileNotFoundError, KeyError) as kde_error: Logger.debug("Scaling Factor/KDE not detected.") Logger.error(kde_error) return None
def _validate_with_callback(self, key, callback): module = import_module("HardcodeTray.path") if hasattr(module, callback): method = getattr(module, callback) self.path = get_exact_folder(key, self.path, method) Logger.debug("Path with condition: " "{} {}".format(callback, self.path))
def blacklist(self): """Return a list of blacklist apps.""" blacklist = self._blacklist if blacklist: Logger.debug("Config/Blacklist: " "{}".format(",".join(blacklist))) return blacklist
def pack(self, icon_path): """Recreate the zip file from the tmp directory.""" from HardcodeTray.app import App nwjs_sdk = App.get("nwjs") if nwjs_sdk: binary_file = path.join(gettempdir(), self.binary) Logger.debug("NWJS Application: Creating new archive {}".format( self.binary)) make_archive(binary_file, "zip", self.tmp_path) move(binary_file + ".zip", binary_file + ".nw") local_binary_file = path.join(nwjs_sdk, self.binary) move(binary_file + ".nw", local_binary_file + ".nw") Logger.debug("NWJS Application: Creating executable file.") execute(["cat which nw " + self.binary + ".nw > " + self.binary], True, True, nwjs_sdk) remove(local_binary_file + ".nw") move(local_binary_file, path.join(str(icon_path), self.binary)) execute(["chmod", "+x", path.join(str(icon_path), self.binary)]) rmtree(self.tmp_path)
def nwjs(self): """Return nwjs sdk path.""" nwjs = self._nwjs if nwjs and path.exists(nwjs): Logger.debug("Config/NWJS SDK: {}".format(nwjs)) return nwjs return None
def factory(colors, conversion_tool=None): """Create a SVG to PNG object.""" def load(conversion_tool): """Load Objects dynamically.""" module = ConversionTools.choices()[conversion_tool].lower() svg = import_module("HardcodeTray.modules.svg." + module) return getattr(svg, conversion_tool) svg = None if conversion_tool: try: svg = load(conversion_tool)(colors) except SVGNotInstalled: exit(_("The selected conversion tool is not installed.")) else: for tool in ConversionTools.choices(): try: svg = load(tool)(colors) Logger.debug("SVG Factory: Import {}".format(tool)) break except SVGNotInstalled: Logger.debug("SVG Factory: Failed {}".format(tool)) if svg: return svg exit(_("Failed to load any SVG module."))
def pack(self, icon_path): """Recreate the zip file from the tmp directory.""" from HardcodeTray.app import App nwjs_sdk = App.get("nwjs") if nwjs_sdk: binary_file = path.join(gettempdir(), self.binary) Logger.debug( "NWJS Application: Creating new archive {}".format(self.binary)) make_archive(binary_file, "zip", self.tmp_path) move(binary_file + ".zip", binary_file + ".nw") local_binary_file = path.join(nwjs_sdk, self.binary) move(binary_file + ".nw", local_binary_file + ".nw") Logger.debug("NWJS Application: Creating executable file.") execute(["cat which nw " + self.binary + ".nw > " + self.binary], True, True, nwjs_sdk) remove(local_binary_file + ".nw") move(local_binary_file, path.join(str(icon_path), self.binary)) execute(["chmod", "+x", path.join(str(icon_path), self.binary)]) rmtree(self.tmp_path)
def select(self): """Show a select option for the backup of each application.""" backup_folders = self.get_backup_folders() total = len(backup_folders) if total != 0: backup_folders.sort() self._display_choices(backup_folders) print(_("(Q)uit to cancel")) has_chosen = False stopped = False while not has_chosen and not stopped: try: selected = input("Select a restore date : ") if selected in ["q", "quit", "exit"]: stopped = True selected = int(selected) if 1 <= selected <= total: has_chosen = True self._exists = True self._selected_backup = backup_folders[selected - 1] except ValueError: pass except KeyboardInterrupt: exit() if stopped: Logger.debug("The user stopped the " "reversion for {}".format(self.app.name)) else: Logger.debug("No backup folder found for " "the application {0}".format(self.app.name))
def get_kde_scaling_factor(): """Return the widgets scaling factor on KDE.""" scaling_factor = None was_found = False try: with open(KDE_CONFIG_FILE, 'r') as kde_obj: data = kde_obj.readlines() for line in data: line = list(map(lambda x: x.strip(), line.split("="))) if len(line) == 1: was_found = match(r'\[Containments\]\[[0-9]+\]\[General\]', line[0]) if len(line) > 1 and was_found and line[0].lower() == "iconsize": scaling_factor = int(line[1]) break if scaling_factor: Logger.debug("Scaling Factor/KDE: {}".format(scaling_factor)) return scaling_factor except (FileNotFoundError, KeyError) as kde_error: Logger.debug("Scaling Factor/KDE not detected.") Logger.error(kde_error) return None
def only(self): """Return list of apps to be fixed.""" only = self._args.only if only: only = only.lower().strip() Logger.debug("Arguments/Only: {}".format(only)) return only.split(",") return []
def icon_size(): """Return the icon size.""" if DESKTOP_ENV in ("pantheon", "xfce"): icon_size = 24 else: icon_size = 22 Logger.debug("System/Icon Size: {}".format(icon_size)) return icon_size
def extract(self, icon_path): """Extract the zip file in /tmp directory.""" if path.exists(self.tmp_path): rmtree(self.tmp_path) Logger.debug("NWJS Application: Extracting of {}".format(self.binary)) execute(["unzip", path.join(str(icon_path), self.binary), "-d", self.tmp_path])
def create_dir(directory): """ Create a directory and fix folder permissions. Args : folder (str): folder path """ if not path.exists(directory): Logger.debug("Creating directory: {}".format(directory)) makedirs(directory, exist_ok=True)
def theme(): """Return a theme object.""" theme_name = Gtk.Settings.get_default().get_property("gtk-icon-theme-name") theme = None if theme_name: Logger.debug("System/Theme: {}".format(theme_name)) theme = Theme(theme_name) else: Logger.error("System/Theme: Not detected.") return theme
def get_gnome_scaling_factor(): """Return gnome scaling factor.""" source = Gio.SettingsSchemaSource.get_default() if source.lookup("org.gnome.desktop.interface", True): gsettings = Gio.Settings.new("org.gnome.desktop.interface") scaling_factor = gsettings.get_uint('scaling-factor') + 1 Logger.debug("Scaling Factor/GNOME: {}".format(scaling_factor)) return scaling_factor else: Logger.debug("Scaling Factor/Gnome not detected.") return 1
def icon_size(self): """Return the icon size in the config file.""" icon_size = None if self._icons: icon_size = self._icons.get("size") Logger.debug("Config/Icon Size: {}".format(icon_size)) if icon_size not in ICONS_SIZE: Logger.warning("Config/Icon Size: Incorrect.") Logger.debug("Config/Icon Size: Detected icon " "size will be used.") return icon_size
def get_gnome_scaling_factor(): """Return gnome scaling factor.""" source = Gio.SettingsSchemaSource.get_default() if source.lookup('org.gnome.desktop.interface', True): gsettings = Gio.Settings.new('org.gnome.desktop.interface') scaling_factor = gsettings.get_uint('scaling-factor') + 1 Logger.debug("Scaling Factor/GNOME: {}".format(scaling_factor)) return scaling_factor else: Logger.debug("Scaling Factor/Gnome not detected.") return 1
def extract(self, icon_path): """Extract the zip file in /tmp directory.""" if path.exists(self.tmp_path): rmtree(self.tmp_path) Logger.debug("NWJS Application: Extracting of {}".format(self.binary)) execute([ "unzip", path.join(str(icon_path), self.binary), "-d", self.tmp_path ])
def theme(): """Return a theme object.""" theme_name = Gtk.Settings.get_default().get_property( "gtk-icon-theme-name") theme = None if theme_name: Logger.debug("System/Theme: {}".format(theme_name)) theme = Theme(theme_name) else: Logger.error("System/Theme: Not detected.") return theme
def scaling_factor(): """ Returns the scaling factor. """ if not App._scaling_factor: scaling_factor = App.get("scaling_factor") if scaling_factor and scaling_factor > 1: # Change icon size by * it by the scaling factor App._icon_size = round(App.icon_size() * scaling_factor, 0) Logger.debug("Icon Size: {}".format(App._icon_size)) App._scaling_factor = scaling_factor return App._scaling_factor
def extract(self, icon_path): """Extract the zip file in /tmp directory.""" if path.exists(self.tmp_path): rmtree(self.tmp_path) makedirs(self.tmp_path, exist_ok=True) Logger.debug("Zip Application: Extracting of {} started".format(self.binary)) with ZipFile(path.join(str(icon_path), self.binary)) as zip_object: zip_object.extractall(self.tmp_path) Logger.debug("Zip Application: Extracting is done.")
def pack(self, icon_path): """Recreate the zip file from the tmp directory.""" zip_file = path.join(str(icon_path), self.binary) if path.isfile(zip_file): Logger.debug("Zip Application: Removing old binary file {}".format(zip_file)) remove(zip_file) make_archive(zip_file.replace(".zip", ""), 'zip', self.tmp_path) Logger.debug("Zip Application: Creating a new zip archive.") if path.exists(self.tmp_path): rmtree(self.tmp_path)
def extract(self, icon_path): """Extract the zip file in /tmp directory.""" if path.exists(self.tmp_path): rmtree(self.tmp_path) makedirs(self.tmp_path, exist_ok=True) Logger.debug("Zip Application: Extracting of " "{} started".format(self.binary)) with ZipFile(path.join(str(icon_path), self.binary)) as zip_object: zip_object.extractall(self.tmp_path) Logger.debug("Zip Application: Extracting is done.")
def reinstall(self): """Overwrite the reinstall function, and remove the whole dir.""" done = False for icon_path in self.icons_path: icon_path = str(icon_path) if path.isdir(icon_path): rmtree(icon_path) Logger.debug("Qt Application: Reverting" " {} is done.".format(self.name)) done = True if not done: Logger.debug("Qt Application: Reverting " "{} is not done.".format(self.name)) self.success = done
def get_cinnamon_scaling_factor(): """Return Cinnamon desktop scaling factor.""" source = Gio.SettingsSchemaSource.get_default() if source.lookup('org.cinnamon.desktop.interface', True): gsettings = Gio.Settings.new('org.cinnamon.desktop.interface') scaling_factor = gsettings.get_uint('scaling-factor') if scaling_factor == 0: # Cinnamon does have an auto scaling feature which we can't use scaling_factor = 1 Logger.debug("Scaling Factor/Cinnamon: {}".format(scaling_factor)) return scaling_factor else: Logger.debug("Scaling Factor/Cinnamon not detected") return 1
def reinstall(self): """Overwrite the reinstall function, and remove the whole dir.""" done = False for icon_path in self.icons_path: icon_path = str(icon_path) if path.isdir(icon_path): rmtree(icon_path) Logger.debug("Qt Application: Reverting {} is done.".format( self.name)) done = True if not done: Logger.debug("Qt Application: Reverting {} is not done.".format( self.name)) self.success = done
def get_cinnamon_scaling_factor(): """Return Cinnamon desktop scaling factor.""" source = Gio.SettingsSchemaSource.get_default() if source.lookup("org.cinnamon.desktop.interface", True): gsettings = Gio.Settings.new("org.cinnamon.desktop.interface") scaling_factor = gsettings.get_uint('scaling-factor') if scaling_factor == 0: # Cinnamon does have an auto scaling feature which we can't use scaling_factor = 1 Logger.debug("Scaling Factor/Cinnamon: {}".format(scaling_factor)) return scaling_factor else: Logger.debug("Scaling Factor/Cinnamon not detected") return 1
def _read(self): """Read the config file.""" if path.isfile(CONFIG_FILE): Logger.debug("Reading config file: {}".format(CONFIG_FILE)) with open(CONFIG_FILE, 'r') as data: try: config = load(data) for key, value in config.items(): setattr(self, "_" + key, value) except ValueError: Logger.warning("The config file is " "not a valid json file.") else: Logger.debug("Config file: Not found.")
def pack(self, icon_path): """Recreate the zip file from the tmp directory.""" zip_file = path.join(str(icon_path), self.binary) if path.isfile(zip_file): Logger.debug("Zip Application: Removing " "old binary file {}".format(zip_file)) remove(zip_file) make_archive(zip_file.replace(".zip", ""), 'zip', self.tmp_path) Logger.debug("Zip Application: Creating a new zip archive.") if path.exists(self.tmp_path): rmtree(self.tmp_path)
def detect_de(de_list): """Detect the desktop environment, used to choose the proper icons size.""" try: desktop_env = [environ.get("DESKTOP_SESSION", "").lower(), environ.get("XDG_CURRENT_DESKTOP", "").lower()] except AttributeError: desktop_env = [] for desktop in desktop_env: if desktop in de_list: Logger.debug("DE: {0}".format(desktop.title())) return desktop Logger.debug("DE not detected.") return "other"
def create(self, filename): """Backup functions.""" from HardcodeTray.app import App if not App.get('backup_ignore'): if not self.backup_dir: self.create_backup_dir() backup_file = path.join(self.backup_dir, path.basename(filename)) if path.exists(filename): Logger.debug("Backup file: {0} to: {1}".format( filename, backup_file)) copy_file(filename, backup_file, True)
def create(self, filename): """Backup functions.""" from HardcodeTray.app import App if not App.get("backup_ignore"): if not self.backup_dir: self.create_backup_dir() backup_file = path.join(self.backup_dir, path.basename(filename)) if path.exists(filename): Logger.debug("Backup file: {0} to: {1}".format(filename, backup_file)) copy_file(filename, backup_file, True)
def detect_de(de_list): """Detect the desktop environment, used to choose the proper icons size.""" try: desktop_env = [ environ.get("DESKTOP_SESSION", "").lower(), environ.get("XDG_CURRENT_DESKTOP", "").lower() ] except AttributeError: desktop_env = [] for desktop in desktop_env: if desktop in de_list: Logger.debug("DE: {0}".format(desktop.title())) return desktop Logger.debug("DE not detected.") return "other"
def execute(command_list, verbose=True, shell=False, working_directory=None): """ Run a command using "Popen". Args : command_list(list) verbose(bool) """ Logger.debug("Executing command: {0}".format(" ".join(command_list))) if working_directory: cmd = Popen(command_list, stdout=PIPE, stderr=PIPE, shell=shell, cwd=working_directory) else: cmd = Popen(command_list, stdout=PIPE, stderr=PIPE, shell=shell) output, error = cmd.communicate() if verbose and error: Logger.error(error.decode("utf-8").strip()) return output
def create_backup_dir(self): """Create a backup directory for an application (application_name).""" backup_dir = path.join(BACKUP_FOLDER, self.app.name, strftime(BACKUP_FILE_FORMAT), "") exists = True new_backup_dir = backup_dir i = 1 while exists: if path.exists(new_backup_dir): new_backup_dir = backup_dir + "_" + str(i) if not path.isdir(new_backup_dir): Logger.debug("Create new backup folder " "for {}".format(self.app.name)) create_dir(new_backup_dir) exists = False i += 1 self._backup_dir = new_backup_dir
def execute(command_list, verbose=True, shell=False, working_directory=None): """ Run a command using subprocess.run(). Args : command_list(list) verbose(bool) """ Logger.debug("Executing command: {0}".format(" ".join(command_list))) if working_directory: cmd = run(command_list, capture_output=True, shell=False, check=False, cwd=working_directory) else: cmd = run(command_list, capture_output=True, shell=False, check=False) output, error = Popen.communicate() if verbose and error: Logger.error(error.decode('utf-8').strip()) return output
def clear_cache(self): """Clear Backup cache.""" backup_folder = path.join(BACKUP_FOLDER, self.name, "") Logger.debug("Clearing cache of: {}".format(self.name)) if path.exists(backup_folder): rmtree(backup_folder) Logger.debug("Cache cleaned.") else: Logger.debug("Cache not found.") self.success = False
def theme(self): """Return Theme object set by --theme.""" theme_obj = None theme = self._args.theme dark_theme = self._args.dark_theme light_theme = self._args.light_theme if theme: theme_obj = Theme(theme) Logger.debug("Arguments/Theme: {}".format(theme)) elif dark_theme and light_theme: theme_obj = Theme.new_with_dark_light(dark_theme, light_theme) Logger.debug("Arguments/Dark Theme: {}".format(dark_theme)) Logger.debug("Arguments/Light Theme: {}".format(light_theme)) return theme_obj
def theme(self): """Return theme object set in the config file.""" theme_obj = None if self._icons: theme = self._icons.get("theme", {}) if isinstance(theme, dict): dark_theme = theme.get("dark") light_theme = theme.get("light") if isinstance(theme, str): theme_obj = Theme(theme) Logger.debug("Config/Theme: {}".format(theme)) elif dark_theme and light_theme: theme_obj = Theme.new_with_dark_light(dark_theme, light_theme) Logger.debug("Config/Dark Theme: {}".format(dark_theme)) Logger.debug("Config/Light Theme: {}".format(light_theme)) return theme_obj
def conversion_tool(self): """Return conversion tool set in the config file.""" conversion_tool = self._conversion_tool Logger.debug("Config/Conversion Tool: {}".format(conversion_tool)) return conversion_tool
def conversion_tool(self): """Return conversion tool set by --conversion-tool.""" conversion_tool = self._args.conversion_tool Logger.debug("Arguments/Conversion Tool: " "{}".format(conversion_tool)) return conversion_tool
def icon_size(self): """Return Icon size set by args --size.""" icon_size = self._args.size Logger.debug("Arguments/Icon Size: {}".format(icon_size)) return icon_size