From 2c6df7c527380640bc690961e89ef3738befdee0 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Mon, 24 Jan 2022 22:32:31 -0600 Subject: [PATCH] Major refactor --- {old-bash-ver => old-bash-version}/LICENSE | 0 {old-bash-ver => old-bash-version}/README.md | 0 .../images/pic1.png | Bin .../images/pic2.png | Bin {old-bash-ver => old-bash-version}/install.sh | 0 {old-bash-ver => old-bash-version}/shellMen | 0 requirements.txt | 3 + src/__builtins__.py | 19 ++ src/__init__.py | 232 +----------------- src/__main__.py | 25 +- src/core/__init__.py | 8 - src/signal_classes/Controller.py | 188 ++++++++++++++ src/signal_classes/Controller_Data.py | 30 +++ .../Context.py => signal_classes/Menu.py} | 38 ++- src/signal_classes/__init__.py | 7 + src/signal_classes/mixins/ProcessorMixin.py | 43 ++++ .../mixins/StylesMixin.py | 0 .../mixins/__init__.py | 1 + src/{core => }/utils/Logger.py | 8 +- src/utils/Settings.py | 51 ++++ src/{core => }/utils/__init__.py | 1 + 21 files changed, 397 insertions(+), 257 deletions(-) rename {old-bash-ver => old-bash-version}/LICENSE (100%) rename {old-bash-ver => old-bash-version}/README.md (100%) rename {old-bash-ver => old-bash-version}/images/pic1.png (100%) rename {old-bash-ver => old-bash-version}/images/pic2.png (100%) rename {old-bash-ver => old-bash-version}/install.sh (100%) rename {old-bash-ver => old-bash-version}/shellMen (100%) create mode 100644 requirements.txt create mode 100644 src/__builtins__.py delete mode 100644 src/core/__init__.py create mode 100644 src/signal_classes/Controller.py create mode 100644 src/signal_classes/Controller_Data.py rename src/{core/Context.py => signal_classes/Menu.py} (64%) create mode 100644 src/signal_classes/__init__.py create mode 100644 src/signal_classes/mixins/ProcessorMixin.py rename src/{core => signal_classes}/mixins/StylesMixin.py (100%) rename src/{core => signal_classes}/mixins/__init__.py (59%) rename src/{core => }/utils/Logger.py (91%) create mode 100644 src/utils/Settings.py rename src/{core => }/utils/__init__.py (63%) diff --git a/old-bash-ver/LICENSE b/old-bash-version/LICENSE similarity index 100% rename from old-bash-ver/LICENSE rename to old-bash-version/LICENSE diff --git a/old-bash-ver/README.md b/old-bash-version/README.md similarity index 100% rename from old-bash-ver/README.md rename to old-bash-version/README.md diff --git a/old-bash-ver/images/pic1.png b/old-bash-version/images/pic1.png similarity index 100% rename from old-bash-ver/images/pic1.png rename to old-bash-version/images/pic1.png diff --git a/old-bash-ver/images/pic2.png b/old-bash-version/images/pic2.png similarity index 100% rename from old-bash-ver/images/pic2.png rename to old-bash-version/images/pic2.png diff --git a/old-bash-ver/install.sh b/old-bash-version/install.sh similarity index 100% rename from old-bash-ver/install.sh rename to old-bash-version/install.sh diff --git a/old-bash-ver/shellMen b/old-bash-version/shellMen similarity index 100% rename from old-bash-ver/shellMen rename to old-bash-version/shellMen diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1463e06 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +PyInquirer +pyxdg +setproctitle diff --git a/src/__builtins__.py b/src/__builtins__.py new file mode 100644 index 0000000..913686d --- /dev/null +++ b/src/__builtins__.py @@ -0,0 +1,19 @@ +# Python imports +import builtins + +# Lib imports + +# Application imports + + +class Builtins: + def dummy(self): + pass + + + +# NOTE: Just reminding myself we can add to builtins two different ways... +# __builtins__.update({"event_system": Builtins()}) +builtins.app_name = "Shellmen" +builtins.debug = False +builtins.trace_debug = False diff --git a/src/__init__.py b/src/__init__.py index efb7a2d..209ef30 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,230 +1,20 @@ # Python imports -import os, subprocess, json +import os, inspect, time -from os.path import isdir, isfile, join -from os import listdir - -# Gtk imports -from xdg.DesktopEntry import DesktopEntry +# Lib imports # Application imports -from core import Context +from utils import Settings +from signal_classes import Controller +from __builtins__ import Builtins -class Main(Context): - """ - This is the start class called from "__main__" - """ - def __init__(self, args): - """ - Initialize it all... - """ - super().__init__(args) - HOME_APPS = os.path.expanduser('~') + "/.local/share/applications/" - paths = ["/opt/", "/usr/share/applications/", HOME_APPS] - baseOptions = ["[ TO MAIN MENU ]", "Favorites"] - self.menuData = self.getDesktopFilesInfo(paths) - self.faves = self.loadFaves() - query = "" - - while True: - try: - self.clear() - group = self.call_method("mainMenu")["group"] - self.clear() - - if "Search..." in group: - query = self.call_method("searchMenu")["query"] - if "[ Set Favorites ]" in group: - progsList = self.getSubgroup("Search...", "") - fixedProgsList = [] - - for prog in progsList: - fixedProgsList.append({'name': prog}) - - self.faves = self.call_method("setFavoritesMenu", [fixedProgsList])["setFaves"] - self.saveFaves(self.faves) - continue - if "[ Exit ]" in group: - break - - progsList = ["[ TO MAIN MENU ]"] - progsList += self.getSubgroup(group, query) - entry = self.call_method("subMenu", [group, progsList])["prog"] - - self.logger.debug(entry) - if entry not in baseOptions: - self.logger.info("[Executing Program] Group: {} Entry: {}".format(group, entry)) - self.executeProgram(group, entry) - except Exception as e: - self.logger.error(e) - def call_method(self, method_name, data = None): - mName = str(method_name) - method = getattr(self, mName, lambda data: "No valid key passed...\nkey= " + mName + "\nargs= " + data) - return method(data) if data else method() +class Main(Builtins): + def __init__(self, args, unknownargs): + settings = Settings() + controller = Controller(settings, args, unknownargs) - - def loadFaves(self, data = None): - configFolder = os.getenv("HOME") + "/.config/shellmen" - configFile = configFolder + "/favorites.json" - self.logger.info("[Opening saved favorites file: {}".format(configFile)) - faves = [] - - if os.path.isdir(configFolder) == False: - os.mkdir(configFolder) - if os.path.isfile(configFile) == False: - open(configFile, 'a').close() - - with open(configFile) as infile: - try: - faves = json.load(infile) - except Exception as e: - pass - - infile.close() - - return faves - - - def saveFaves(self, data = None): - configFolder = os.getenv("HOME") + "/.config/shellmen" - configFile = configFolder + "/favorites.json" - with open(configFile, 'w') as outfile: - json.dump(data, outfile) - - - def getDesktopFilesInfo(self, paths): - menuObjs = { - "Accessories": [], - "Multimedia": [], - "Graphics": [], - "Game": [], - "Office": [], - "Development": [], - "Internet": [], - "Settings": [], - "System": [], - "Wine": [], - "Other": [] - } - - for path in paths: - if not "/opt/" in path: - self.listAndUpdateDesktopFiles(path, menuObjs); - else: - for folder in listdir(path): - try: - fPath = path + folder + "/" - self.listAndUpdateDesktopFiles(fPath, menuObjs); - except Exception as e: - self.logger.debug(e) - - return menuObjs - - def listAndUpdateDesktopFiles(self, path, menuObjs): - for f in listdir(path): - fPath = path + f - if isfile(fPath) and f.endswith(".desktop"): - xdgObj = DesktopEntry(fPath) - - title = xdgObj.getName() - groups = xdgObj.getCategories() - comment = xdgObj.getComment() - # icon = xdgObj.getIcon() - mainExec = xdgObj.getExec() - tryExec = xdgObj.getTryExec() - - group = "" - if "Accessories" in groups or "Utility" in groups: - group = "Accessories" - elif "Multimedia" in groups or "Video" in groups or "Audio" in groups: - group = "Multimedia" - elif "Development" in groups: - group = "Development" - elif "Game" in groups: - group = "Game" - elif "Internet" in groups or "Network" in groups: - group = "Internet" - elif "Graphics" in groups: - group = "Graphics" - elif "Office" in groups: - group = "Office" - elif "System" in groups: - group = "System" - elif "Settings" in groups: - group = "Settings" - elif "Wine" in groups: - group = "Wine" - else: - group = "Other" - - menuObjs[group].append( {"title": title, "groups": groups, - "comment": comment, "exec": mainExec, - "tryExec": tryExec, "fileName": f - }) - - - def getSubgroup(self, group, query = ""): - desktopObjs = [] - if "Search..." in group: - gkeys = self.menuData.keys() - for gkey in gkeys: - for opt in self.menuData[gkey]: - keys = opt.keys() - if "comment" in keys and len(opt["comment"]) > 0 : - if query.lower() in opt["comment"].lower(): - desktopObjs.append( opt["title"] + " || " + opt["comment"] ) - if query.lower() in opt["title"].lower() or query.lower() in opt["fileName"].lower(): - desktopObjs.append( opt["title"] + " || " + opt["fileName"].replace(".desktop", "") ) - elif "Favorites" in group: - desktopObjs = self.faves - else: - for opt in self.menuData[group]: - keys = opt.keys() - if "comment" in keys and len(opt["comment"]) > 0 : - desktopObjs.append( opt["title"] + " || " + opt["comment"] ) - else: - desktopObjs.append( opt["title"] + " || " + opt["fileName"].replace(".desktop", "") ) - - return desktopObjs - - - def executeProgram(self, group, entry): - parts = entry.split("||") - program = parts[0].strip() - comment = parts[1].strip() - - if "Search..." in group or "Favorites" in group: - gkeys = self.menuData.keys() - for gkey in gkeys: - self.pre_execute(self.menuData[gkey], program, comment) - else: - self.pre_execute(self.menuData[group], program, comment) - - - def pre_execute(self, options, program, comment): - for opt in options: - if program in opt["title"]: - keys = opt.keys() - if comment in opt["comment"] or comment in opt["fileName"]: - try: - self.execute(opt["tryExec"]) - except Exception as e: - try: - if "exec" in keys and len(opt["exec"]): - self.execute(opt["exec"]) - except Exception as e: - self.logger.debug(e) - - - def execute(self, option): - DEVNULL = open(os.devnull, 'w') - command = option.split("%")[0] - self.logger.debug(command) - subprocess.Popen(command.split(), cwd=os.getenv("HOME"), start_new_session=True, stdout=DEVNULL, stderr=DEVNULL) - - - def clear(self): - os.system('cls' if os.name == 'nt' else 'clear') + if not controller: + raise Exception("Controller exited and doesn't exist...") diff --git a/src/__main__.py b/src/__main__.py index 6dba2fb..b2e005f 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -1,6 +1,16 @@ +#!/usr/bin/python3 + # Python imports -import argparse +import argparse, faulthandler, traceback +from setproctitle import setproctitle + +import tracemalloc +tracemalloc.start() + + +# Lib imports + # Application imports from __init__ import Main @@ -8,12 +18,19 @@ from __init__ import Main if __name__ == "__main__": try: + # import web_pdb + # web_pdb.set_trace() + + setproctitle('Shellmen') + faulthandler.enable() # For better debug info parser = argparse.ArgumentParser() # Add long and short arguments parser.add_argument("--theme", "-t", default="default", help="The theme to use for the menu. (default, orange, red, purple, green)") # Read arguments (If any...) - args = parser.parse_args() - main = Main(args) + args, unknownargs = parser.parse_known_args() + + Main(args, unknownargs) except Exception as e: - print( repr(e) ) + traceback.print_exc() + quit() diff --git a/src/core/__init__.py b/src/core/__init__.py deleted file mode 100644 index 8852ccd..0000000 --- a/src/core/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -""" - Core module -""" - -from .mixins import StylesMixin - -from .utils import Logger -from .Context import Context diff --git a/src/signal_classes/Controller.py b/src/signal_classes/Controller.py new file mode 100644 index 0000000..c4dae7e --- /dev/null +++ b/src/signal_classes/Controller.py @@ -0,0 +1,188 @@ +# Python imports +import threading, subprocess +from os.path import isfile +from os import listdir + + +# Gtk imports +from xdg.DesktopEntry import DesktopEntry + +# Application imports +from .mixins import * +from . import Menu, Controller_Data + + + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + + return wrapper + + +class Controller(ProcessorMixin, Menu, Controller_Data): + def __init__(self, _settings, args, unknownargs): + super().__init__(_settings, args) + + self.setup_controller_data(_settings) + + base_options = ["[ TO MAIN MENU ]", "Favorites"] + self.menu_data = self.get_desktop_files_info(self.app_paths) + query = "" + + while True: + try: + self.clear_console() + group = self.call_method("main_menu")["group"] + self.clear_console() + + if "Search..." in group: + query = self.call_method("search_menu")["query"] + if "[ Set Favorites ]" in group: + programs_list = self.get_sub_group("Search...", "") + fixed_programs_list = [] + + for prog in programs_list: + fixed_programs_list.append({'name': prog}) + + self.favorites = self.call_method("set_favorites_menu", [fixed_programs_list])["setFaves"] + self.save_faves(self.favorites) + continue + if "[ Exit ]" in group: + break + + programs_list = ["[ TO MAIN MENU ]"] + programs_list += self.get_sub_group(group, query) + entry = self.call_method("sub_menu", [group, programs_list])["prog"] + + self.logger.debug(entry) + if entry not in base_options: + self.logger.info(f"[Executing Program] Group: {group} Entry: {entry}") + self.execute_program(group, entry) + except Exception as e: + self.logger.error(e) + + + + def get_desktop_files_info(self, paths): + menu_objects = { + "Accessories": [], + "Multimedia": [], + "Graphics": [], + "Game": [], + "Office": [], + "Development": [], + "Internet": [], + "Settings": [], + "System": [], + "Wine": [], + "Other": [] + } + + for path in paths: + if not "/opt/" in path: + self.list_and_update_desktop_iles(path, menu_objects); + else: + for folder in listdir(path): + try: + full_path = f"{path}{folder}/" + self.list_and_update_desktop_iles(full_path, menu_objects); + except Exception as e: + self.logger.debug(e) + + return menu_objects + + def list_and_update_desktop_iles(self, path, menu_objects): + try: + for f in listdir(path): + full_path = f"{path}{f}" + if isfile(full_path) and f.endswith(".desktop"): + xdg_object = DesktopEntry(full_path) + hidden = xdg_object.getHidden() + nodisplay = xdg_object.getNoDisplay() + type = xdg_object.getType() + groups = xdg_object.getCategories() + # Do not show those marked as hidden or not to display + if hidden or nodisplay: + continue + + if type == "Application" and groups != "": + title = xdg_object.getName() + comment = xdg_object.getComment() + # icon = xdg_object.getIcon() + mainExec = xdg_object.getExec() + tryExec = xdg_object.getTryExec() + + group = "" + if "Accessories" in groups or "Utility" in groups: + group = "Accessories" + elif "Multimedia" in groups or "Video" in groups or "Audio" in groups: + group = "Multimedia" + elif "Development" in groups: + group = "Development" + elif "Game" in groups: + group = "Game" + elif "Internet" in groups or "Network" in groups: + group = "Internet" + elif "Graphics" in groups: + group = "Graphics" + elif "Office" in groups: + group = "Office" + elif "System" in groups: + group = "System" + elif "Settings" in groups: + group = "Settings" + elif "Wine" in groups: + group = "Wine" + else: + group = "Other" + + menu_objects[group].append( {"title": title, "groups": groups, + "comment": comment, "exec": mainExec, + "tryExec": tryExec, "fileName": f + }) + except Exception as e: + self.logger.debug(e) + + + def get_sub_group(self, group, query = ""): + desktop_objects = [] + if "Search..." in group: + group_keys = self.menu_data.keys() + for group_key in group_keys: + for opt in self.menu_data[group_key]: + keys = opt.keys() + if "comment" in keys and len(opt["comment"]) > 0 : + if query.lower() in opt["comment"].lower(): + desktop_objects.append( opt["title"] + " || " + opt["comment"] ) + if query.lower() in opt["title"].lower() or query.lower() in opt["fileName"].lower(): + desktop_objects.append( opt["title"] + " || " + opt["fileName"].replace(".desktop", "") ) + elif "Favorites" in group: + desktop_objects = self.favorites + else: + for opt in self.menu_data[group]: + keys = opt.keys() + if "comment" in keys and len(opt["comment"]) > 0 : + desktop_objects.append( opt["title"] + " || " + opt["comment"] ) + else: + desktop_objects.append( opt["title"] + " || " + opt["fileName"].replace(".desktop", "") ) + + return desktop_objects + + + + + def tear_down(self, widget=None, eve=None): + quit() + + def get_clipboard_data(self): + proc = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE) + retcode = proc.wait() + data = proc.stdout.read() + return data.decode("utf-8").strip() + + def set_clipboard_data(self, data): + proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE) + proc.stdin.write(data) + proc.stdin.close() + retcode = proc.wait() diff --git a/src/signal_classes/Controller_Data.py b/src/signal_classes/Controller_Data.py new file mode 100644 index 0000000..ab017f0 --- /dev/null +++ b/src/signal_classes/Controller_Data.py @@ -0,0 +1,30 @@ +# Python imports +import os, signal + +# Lib imports +from gi.repository import GLib + +# Application imports + + + +class Controller_Data: + def clear_console(self): + os.system('cls' if os.name == 'nt' else 'clear') + + def call_method(self, _method_name, data = None): + method_name = str(_method_name) + method = getattr(self, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}") + return method(data) if data else method() + + def has_method(self, obj, name): + return callable(getattr(obj, name, None)) + + def setup_controller_data(self, _settings): + self.settings = _settings + self.logger = self.settings.get_logger() + self.app_paths = self.settings.get_app_paths() + self.favorites_path = self.settings.get_favorites_path() + self.favorites = self.settings.get_favorites() + + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.tear_down) diff --git a/src/core/Context.py b/src/signal_classes/Menu.py similarity index 64% rename from src/core/Context.py rename to src/signal_classes/Menu.py index 929fbb3..bf42059 100644 --- a/src/core/Context.py +++ b/src/signal_classes/Menu.py @@ -9,7 +9,6 @@ import json from PyInquirer import style_from_dict, Token, prompt, Separator # Application imports -from .utils import Logger from .mixins import StylesMixin @@ -21,67 +20,66 @@ GROUPS = [ "Search...", "Favorites", "Accessories", "Multimedia", "Graphics", "O ] -class Context(StylesMixin): +class Menu(StylesMixin): """ The menu class has sub methods that are called per run. """ - def __init__(self, args): + def __init__(self, settings, args): """ Construct a new 'Menu' object which pulls in mixins. :param args: The terminal passed arguments :return: returns nothing """ - self.logger = Logger().get_logger("MAIN") - # Set the theme - self.theme = self.call_method(args.theme) - self.menuData = None + self.logger = settings.get_logger() + self.theme = self.call_method(args.theme) + self.menu_data = None - def mainMenu(self, _grouplist = None): + def main_menu(self, _group_list = None): """ Displays the main menu using the defined GROUPS list... """ - grouplist = GROUPS if not _grouplist else _grouplist + group_list = GROUPS if not _group_list else _group_list menu = { 'type': 'list', 'name': 'group', 'message': '[ MAIN MENU ]', - 'choices': grouplist + 'choices': group_list } return prompt(menu, style=self.theme) - def setFavoritesMenu(self, _grouplist = None): - GROUPS = [{'name': '[ TO MAIN MENU ]'}, {'name': 'This is a stub method for Favorites...'}] - grouplist = GROUPS if not _grouplist[0] else _grouplist[0] + def set_favorites_menu(self, _group_list = None): + GROUPS = [{'name': '[ TO MAIN MENU ]'}, {'name': 'This is a stub method for Favorites...'}] + group_list = GROUPS if not _group_list[0] else _group_list[0] menu = { 'type': 'checkbox', 'qmark': '>', 'message': 'Select Favorites', 'name': 'setFaves', - 'choices': grouplist + 'choices': group_list } return prompt(menu, style=self.theme) - def subMenu(self, data = ["NO GROUP NAME", "NO PROGRAMS PASSED IN"]): - group = data[0] - progList = data[1] + def sub_menu(self, data = ["NO GROUP NAME", "NO PROGRAMS PASSED IN"]): + group = data[0] + prog_list = data[1] menu = { 'type': 'list', 'name': 'prog', - 'message': '[ ' + group + ' ]', - 'choices': progList + 'message': f'[ {group} ]', + 'choices': prog_list } return prompt(menu, style=self.theme) - def searchMenu(self): + def search_menu(self): menu = { 'type': 'input', 'name': 'query', diff --git a/src/signal_classes/__init__.py b/src/signal_classes/__init__.py new file mode 100644 index 0000000..b212e68 --- /dev/null +++ b/src/signal_classes/__init__.py @@ -0,0 +1,7 @@ +""" + Gtk Bound Signal Module +""" +from .mixins import * +from .Menu import Menu +from .Controller_Data import Controller_Data +from .Controller import Controller diff --git a/src/signal_classes/mixins/ProcessorMixin.py b/src/signal_classes/mixins/ProcessorMixin.py new file mode 100644 index 0000000..e81138b --- /dev/null +++ b/src/signal_classes/mixins/ProcessorMixin.py @@ -0,0 +1,43 @@ +# Python imports +import os, subprocess + +# Lib imports + +# Application imports + + + +class ProcessorMixin: + def execute_program(self, group, entry): + parts = entry.split("||") + program = parts[0].strip() + comment = parts[1].strip() + + if "Search..." in group or "Favorites" in group: + group_keys = self.menu_data.keys() + for group_key in group_keys: + self.pre_execute(self.menu_data[group_key], program, comment) + else: + self.pre_execute(self.menu_data[group], program, comment) + + + def pre_execute(self, options, program, comment): + for opt in options: + if program in opt["title"]: + keys = opt.keys() + if comment in opt["comment"] or comment in opt["fileName"]: + try: + self.execute(opt["tryExec"]) + except Exception as e: + try: + if "exec" in keys and len(opt["exec"]): + self.execute(opt["exec"]) + except Exception as e: + self.logger.debug(e) + + + def execute(self, option): + DEVNULL = open(os.devnull, 'w') + command = option.split("%")[0] + self.logger.debug(command) + subprocess.Popen(command.split(), cwd=os.getenv("HOME"), start_new_session=True, stdout=DEVNULL, stderr=DEVNULL) diff --git a/src/core/mixins/StylesMixin.py b/src/signal_classes/mixins/StylesMixin.py similarity index 100% rename from src/core/mixins/StylesMixin.py rename to src/signal_classes/mixins/StylesMixin.py diff --git a/src/core/mixins/__init__.py b/src/signal_classes/mixins/__init__.py similarity index 59% rename from src/core/mixins/__init__.py rename to src/signal_classes/mixins/__init__.py index e101abd..2ff067c 100644 --- a/src/core/mixins/__init__.py +++ b/src/signal_classes/mixins/__init__.py @@ -2,3 +2,4 @@ Mixins module """ from .StylesMixin import StylesMixin +from .ProcessorMixin import ProcessorMixin diff --git a/src/core/utils/Logger.py b/src/utils/Logger.py similarity index 91% rename from src/core/utils/Logger.py rename to src/utils/Logger.py index d7bc3ae..06eed47 100644 --- a/src/core/utils/Logger.py +++ b/src/utils/Logger.py @@ -5,8 +5,8 @@ import os, logging class Logger: - def __init__(self): - pass + def __init__(self, config_path): + self._CONFIG_PATH = config_path def get_logger(self, loggerName = "NO_LOGGER_NAME_PASSED", createFile = True): """ @@ -42,8 +42,8 @@ class Logger: log.addHandler(ch) if createFile: - folder = "core/logs" - file = folder + "/shellmen.log" + folder = self._CONFIG_PATH + file = f"{folder}/application.log" if not os.path.exists(folder): os.mkdir(folder) diff --git a/src/utils/Settings.py b/src/utils/Settings.py new file mode 100644 index 0000000..3d7b0c6 --- /dev/null +++ b/src/utils/Settings.py @@ -0,0 +1,51 @@ +# Python imports +import os, json + +# Gtk imports + +# Application imports +from . import Logger + + + +class Settings: + def __init__(self): + self._SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__)) + self._USER_HOME = os.path.expanduser('~') + self._CONFIG_PATH = f"{self._USER_HOME}/.config/{app_name.lower()}" + self._FAVORITES_FILE = f"{self._CONFIG_PATH}/favorites.json" + self._HOME_APPS = f"{self._USER_HOME}/.local/share/applications/" + self._APP_PATHS = ["/opt/", "/usr/share/applications/", self._HOME_APPS] + + self._logger = Logger(self._CONFIG_PATH).get_logger() + self._faves = [] + + if not os.path.exists(self._CONFIG_PATH): + os.mkdir(self._CONFIG_PATH) + self._logger = Logger(self._CONFIG_PATH).get_logger() + + if not os.path.exists(self._FAVORITES_FILE): + open(self._FAVORITES_FILE, 'a').close() + + + with open(self._FAVORITES_FILE) as f: + try: + self._faves = json.load(f) + except Exception as e: + pass + + f.close() + + + + def save_faves(self, data = None): + with open(self._FAVORITES_FILE, 'w') as f: + json.dump(data, f) + f.close() + + + + def get_logger(self): return self._logger + def get_favorites_path(self): return self._FAVORITES_FILE + def get_app_paths(self): return self._APP_PATHS + def get_favorites(self): return self._faves diff --git a/src/core/utils/__init__.py b/src/utils/__init__.py similarity index 63% rename from src/core/utils/__init__.py rename to src/utils/__init__.py index d9e8f55..415301e 100644 --- a/src/core/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,3 +3,4 @@ """ from .Logger import Logger +from .Settings import Settings