231 lines
8.2 KiB
Python
231 lines
8.2 KiB
Python
# Python imports
|
|
import os, subprocess, json
|
|
|
|
from os.path import isdir, isfile, join
|
|
from os import listdir
|
|
|
|
# Gtk imports
|
|
from xdg.DesktopEntry import DesktopEntry
|
|
|
|
# Application imports
|
|
from core import Context
|
|
|
|
|
|
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()
|
|
|
|
|
|
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')
|