/usr/bin/obamenu is in openbox 3.6.1-7.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
# Version 1.1.7
# ---- config ---
applications_dirs = ("/usr/share/applications", )
image_dir_base = "/usr/share" # without "pixmaps" -/usr/local/share in FreeBSD, /usr/share on linux
icon_Theme = "Humanity"
image_cat_prefix = "applications-" # if empty will create no icon text only menu
application_groups = ("Office", "Development", "Graphics", "Internet", "Games", "System", "Multimedia", "Utilities", "Settings")
group_aliases = {"Audio":"Multimedia","AudioVideo":"Multimedia","Network":"Internet","Game":"Games", "Utility":"Utilities", "GTK":"", "GNOME":""}
ignoreList = ("evince-previewer", "Ted", "wingide3.2", "python3.4", "feh","xfce4-power-manager-settings" )
terminal_string = "evte -e" # your favourites terminal exec string
simpleOBheader = False # print full xml style OB header
# --- End of user config ---
import glob
class dtItem(object):
def __init__(self, fName):
self.fileName = fName
self.Name = ""
self.Comment = ""
self.Exec = ""
self.Terminal = None
self.Type = ""
self.Icon = ""
self.Categories = ()
def addName(self, data):
self.Name = xescape(data)
def addComment(self, data):
self.Comment = data
def addExec(self, data):
if len(data) > 3 and data[-2] == '%': # get rid of filemanager arguments in dt files
data = data[:-2].strip()
self.Exec = data
def addIcon(self, data):
self.Icon = ""
if image_cat_prefix == "":
return
image_dir = image_dir_base + "/pixmaps/"
di = data.strip()
if len(di) < 3:
#"Error in %s: Invalid or no icon '%s'" % (self.fileName, di)
return
dix = di.find("/") # is it a full path?
if dix >= 0 and dix <= 2: # yes, its a path (./path or ../path or /path ...)
self.Icon = di
return
#else a short name like "myapp"
tmp = image_dir + di + ".*"
tmp = glob.glob(tmp)
if len(tmp) > 0:
self.Icon = tmp[0]
return
def addTerminal(self, data):
if data == "True" or data == "true":
self.Terminal = True
else:
self.Terminal = False
def addType(self, data):
self.Type = data
def addCategories(self, data):
self.Categories = data
def getCatIcon(cat):
iconDir = image_dir_base + "/icons/" + icon_Theme + "/categories/24/"
cat = image_cat_prefix + cat.lower()
tmp = glob.glob(iconDir + cat + ".*")
if len(tmp) > 0:
return tmp[0]
return ""
def xescape(s):
Rep = {"&":"&", "<":"<", ">":">", "'":"'", "\"":"""}
for p in ("&", "<", ">", "'","\""):
sl = len(s); last = -1
while last < sl:
i = s.find(p, last+1)
if i < 0:
done = True
break
last = i
l = s[:i]
r = s[i+1:]
s = l + Rep[p] + r
return s
def process_category(cat, curCats, appGroups = application_groups, aliases = group_aliases ):
# first process aliases
if aliases.has_key(cat):
if aliases[cat] == "":
return "" # ignore this one
cat = aliases[cat]
if cat in appGroups and cat not in curCats: # valid categories only and no doublettes, please
curCats.append(cat)
return cat
return ""
def process_dtfile(dtf, catDict): # process this file & extract relevant info
active = False # parse only after "[Desktop Entry]" line
fh = open(dtf, "r")
lines = fh.readlines()
this = dtItem(dtf)
for l in lines:
l = l.strip()
if l == "[Desktop Entry]":
active = True
continue
if active == False: # we don't care about licenses or other comments
continue
if l == None or len(l) < 1 or l[0] == '#':
continue
if l[0]== '[' and l != "[Desktop Entry]":
active = False
continue
# else
eqi = l.split('=')
if len(eqi) < 2:
print "Error: Invalid .desktop line'" + l + "'"
continue
# Check what it is ...
if eqi[0] == "Name":
this.addName(eqi[1])
elif eqi[0] == "Comment":
this.addComment(eqi[1])
elif eqi[0] == "Exec":
this.addExec(eqi[1])
elif eqi[0] == "Icon":
this.addIcon(eqi[1])
elif eqi[0] == "Terminal":
this.addTerminal(eqi[1])
elif eqi[0] == "Type":
if eqi[1] != "Application":
continue
this.addType(eqi[1])
elif eqi[0] == "Categories":
if eqi[1][-1] == ';':
eqi[1] = eqi[1][0:-1]
cats = []
# DEBUG
dtCats = eqi[1].split(';')
for cat in dtCats:
result = process_category(cat, cats)
this.addCategories(cats)
else:
continue
# add to catDict
#this.dprint()
if len(this.Categories) > 0: # don't care about stuff w/o category
for cat in this.Categories:
catDict[cat].append(this)
categoryDict = {}
if __name__ == "__main__":
# init the application group dict (which will contain list of apps)
for appGroup in application_groups:
categoryDict[appGroup] = []
# now let's look into the app dirs ...
for appDir in applications_dirs:
appDir += "/*.desktop"
dtFiles = glob.glob(appDir)
# process each .desktop file in dir
for dtf in dtFiles:
skipFlag = False
for ifn in ignoreList:
if dtf.find(ifn) >= 0:
skipFlag = True
if skipFlag == False:
process_dtfile(dtf, categoryDict)
# now, generate jwm menu include
if simpleOBheader == True:
print '<openbox_pipe_menu>' # magic header
else:
print '<?xml version="1.0" encoding="UTF-8" ?><openbox_pipe_menu xmlns="http://openbox.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://openbox.org/" >' # magic header
appGroupLen = len(application_groups)
for ag in range(appGroupLen ):
catList = categoryDict[application_groups[ag]]
if len(catList) < 1:
continue # don't create empty menus
catStr = "<menu id=\"openbox-%s\" label=\"%s\" " % (application_groups[ag], application_groups[ag])
tmp = getCatIcon(application_groups[ag])
if tmp != "":
catStr += "icon=\"%s\"" % tmp
print catStr, ">"
for app in catList:
progStr = "<item "
progStr += "label=\"%s\" " % app.Name
if app.Icon != "":
progStr += "icon=\"%s\" " % app.Icon
progStr += "><action name=\"Execute\"><command><![CDATA["
if app.Terminal == True:
progStr += terminal_string + " "
progStr += "%s]]></command></action></item>" % app.Exec
print progStr
print "</menu>"
print "</openbox_pipe_menu>" # magic footer
pass # done/debug break
|