|
|
@ -1,5 +1,6 @@ |
|
|
|
#!/usr/bin/env python |
|
|
|
# coding: utf-8 |
|
|
|
# vim:et:sta:sts=4:sw=4:ts=8:tw=79: |
|
|
|
|
|
|
|
from __future__ import print_function |
|
|
|
|
|
|
@ -27,45 +28,55 @@ prefix = 'not_set' |
|
|
|
if prefix == 'not_set': |
|
|
|
desktop_dir = '../desktop-directories/' |
|
|
|
else: |
|
|
|
desktop_dir = prefix+'/share/desktop-directories/' |
|
|
|
desktop_dir = prefix + '/share/desktop-directories/' |
|
|
|
|
|
|
|
if not os.path.isdir(desktop_dir): |
|
|
|
sys.exit('ERROR: Could not find '+desktop_dir) |
|
|
|
sys.exit('ERROR: Could not find ' + desktop_dir) |
|
|
|
|
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-applications.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-applications.directory') |
|
|
|
applications = de.getName().encode('utf-8') |
|
|
|
applications_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-accessories.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-accessories.directory') |
|
|
|
accessories = de.getName().encode('utf-8') |
|
|
|
accessories_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-development.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-development.directory') |
|
|
|
development = de.getName().encode('utf-8') |
|
|
|
development_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-education.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-education.directory') |
|
|
|
education = de.getName().encode('utf-8') |
|
|
|
education_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-games.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + 'xdgmenumaker-games.directory') |
|
|
|
games = de.getName().encode('utf-8') |
|
|
|
games_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-graphics.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-graphics.directory') |
|
|
|
graphics = de.getName().encode('utf-8') |
|
|
|
graphics_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-multimedia.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-multimedia.directory') |
|
|
|
multimedia = de.getName().encode('utf-8') |
|
|
|
multimedia_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-network.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-network.directory') |
|
|
|
network = de.getName().encode('utf-8') |
|
|
|
network_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-office.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-office.directory') |
|
|
|
office = de.getName().encode('utf-8') |
|
|
|
office_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-settings.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-settings.directory') |
|
|
|
settings = de.getName().encode('utf-8') |
|
|
|
settings_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-system.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + |
|
|
|
'xdgmenumaker-system.directory') |
|
|
|
system = de.getName().encode('utf-8') |
|
|
|
system_icon = de.getIcon() |
|
|
|
de = dentry.DesktopEntry(filename = desktop_dir+'xdgmenumaker-other.directory') |
|
|
|
de = dentry.DesktopEntry(filename=desktop_dir + 'xdgmenumaker-other.directory') |
|
|
|
other = de.getName().encode('utf-8') |
|
|
|
other_icon = de.getIcon() |
|
|
|
# Find out which terminal emulator to use for apps that need to be |
|
|
@ -84,6 +95,7 @@ except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e: |
|
|
|
else: |
|
|
|
terminal_app = 'xterm' |
|
|
|
|
|
|
|
|
|
|
|
def main(argv): |
|
|
|
global desktop |
|
|
|
global seticon |
|
|
@ -91,7 +103,7 @@ def main(argv): |
|
|
|
global submenu |
|
|
|
global pekwmdynamic |
|
|
|
try: |
|
|
|
opts, args = getopt.getopt(argv, "hins:f:", ["help", "icons" , |
|
|
|
opts, args = getopt.getopt(argv, "hins:f:", ["help", "icons", |
|
|
|
"no-submenu", "pekwm-dynamic", "size=", "format="]) |
|
|
|
except getopt.GetoptError: |
|
|
|
usage() |
|
|
@ -132,6 +144,7 @@ def main(argv): |
|
|
|
usage() |
|
|
|
sys.exit(2) |
|
|
|
|
|
|
|
|
|
|
|
def usage(): |
|
|
|
print('USAGE:', os.path.basename(sys.argv[0]), '[OPTIONS]') |
|
|
|
print() |
|
|
@ -152,7 +165,9 @@ def usage(): |
|
|
|
print(' xdgmenumaker -f windowmaker') |
|
|
|
print(' xdgmenumaker -i -f fluxbox') |
|
|
|
|
|
|
|
|
|
|
|
class MenuEntry: |
|
|
|
|
|
|
|
def __init__(self, category, name, icon, command, path): |
|
|
|
self.category = category |
|
|
|
self.name = name |
|
|
@ -164,6 +179,7 @@ class MenuEntry: |
|
|
|
return repr((self.category, self.name, self.icon, self.command, |
|
|
|
self.path)) |
|
|
|
|
|
|
|
|
|
|
|
def icon_full_path(icon): |
|
|
|
# If the icon path is absolute and exists, leave it alone. |
|
|
|
# This takes care of software that has its own icons stored |
|
|
@ -184,9 +200,10 @@ def icon_full_path(icon): |
|
|
|
icon = icon.get_filename() |
|
|
|
return icon |
|
|
|
|
|
|
|
|
|
|
|
def get_entry_info(desktopfile): |
|
|
|
show = True |
|
|
|
de = dentry.DesktopEntry(filename = desktopfile) |
|
|
|
de = dentry.DesktopEntry(filename=desktopfile) |
|
|
|
name = de.getName().encode('utf-8') |
|
|
|
|
|
|
|
if seticon: |
|
|
@ -208,13 +225,14 @@ def get_entry_info(desktopfile): |
|
|
|
|
|
|
|
terminal = de.getTerminal() |
|
|
|
if terminal: |
|
|
|
command = terminal_app+' -e '+command |
|
|
|
command = terminal_app + ' -e ' + command |
|
|
|
|
|
|
|
path = de.getPath() |
|
|
|
if not path: |
|
|
|
path = None |
|
|
|
|
|
|
|
#cleaning up categories and keeping only registered freedesktop.org main categories |
|
|
|
# cleaning up categories and keeping only registered freedesktop.org main |
|
|
|
# categories |
|
|
|
categories = de.getCategories() |
|
|
|
if 'AudioVideo' in categories: |
|
|
|
category = multimedia |
|
|
@ -256,6 +274,7 @@ def get_entry_info(desktopfile): |
|
|
|
else: |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def sortedcategories(applist): |
|
|
|
categories = [] |
|
|
|
for e in applist: |
|
|
@ -263,6 +282,7 @@ def sortedcategories(applist): |
|
|
|
categories = sorted(set(categories)) |
|
|
|
return categories |
|
|
|
|
|
|
|
|
|
|
|
def desktopfilelist(): |
|
|
|
dirs = [] |
|
|
|
# some directories are mentioned twice in bd.xdg_data_dirs, once |
|
|
@ -274,7 +294,7 @@ def desktopfilelist(): |
|
|
|
filelist = [] |
|
|
|
df_temp = [] |
|
|
|
for d in dirs: |
|
|
|
xdgdir = d+'/applications' |
|
|
|
xdgdir = d + '/applications' |
|
|
|
if os.path.isdir(xdgdir): |
|
|
|
for i in os.listdir(xdgdir): |
|
|
|
if i.endswith('.desktop'): |
|
|
@ -285,9 +305,10 @@ def desktopfilelist(): |
|
|
|
# /usr/share/applications |
|
|
|
if i not in df_temp: |
|
|
|
df_temp.append(i) |
|
|
|
filelist.append(xdgdir+'/'+i) |
|
|
|
filelist.append(xdgdir + '/' + i) |
|
|
|
return filelist |
|
|
|
|
|
|
|
|
|
|
|
def menu(): |
|
|
|
applist = [] |
|
|
|
for desktopfile in desktopfilelist(): |
|
|
@ -310,6 +331,7 @@ def menu(): |
|
|
|
menu.append([c, appsincategory]) |
|
|
|
return menu |
|
|
|
|
|
|
|
|
|
|
|
def category_icon(category): |
|
|
|
if category == accessories: |
|
|
|
icon = accessories_icon |
|
|
@ -337,17 +359,18 @@ def category_icon(category): |
|
|
|
icon = None |
|
|
|
return icon |
|
|
|
|
|
|
|
|
|
|
|
def fluxboxmenu(): |
|
|
|
if submenu: |
|
|
|
spacing = ' ' |
|
|
|
if seticon: |
|
|
|
app_icon = icon_full_path(applications_icon) |
|
|
|
if app_icon is None: |
|
|
|
print('[submenu] ('+applications+')') |
|
|
|
print('[submenu] (' + applications + ')') |
|
|
|
else: |
|
|
|
print('[submenu] ('+applications+') <'+app_icon+'>') |
|
|
|
print('[submenu] (' + applications + ') <' + app_icon + '>') |
|
|
|
else: |
|
|
|
print('[submenu] ('+applications+')') |
|
|
|
print('[submenu] (' + applications + ')') |
|
|
|
else: |
|
|
|
spacing = '' |
|
|
|
for i in menu(): |
|
|
@ -356,11 +379,12 @@ def fluxboxmenu(): |
|
|
|
cat_icon = category_icon(category) |
|
|
|
cat_icon = icon_full_path(cat_icon) |
|
|
|
if cat_icon: |
|
|
|
print(spacing+'[submenu] ('+category+') <'+cat_icon+'>') |
|
|
|
print(spacing + '[submenu] (' + |
|
|
|
category + ') <' + cat_icon + '>') |
|
|
|
else: |
|
|
|
print(spacing+'[submenu] ('+category+')') |
|
|
|
print(spacing + '[submenu] (' + category + ')') |
|
|
|
else: |
|
|
|
print(spacing+'[submenu] ('+category+')') |
|
|
|
print(spacing + '[submenu] (' + category + ')') |
|
|
|
for j in i[1]: |
|
|
|
# closing parentheses need to be escaped, otherwise they are |
|
|
|
# cropped out, along with everything that comes after them |
|
|
@ -369,26 +393,29 @@ def fluxboxmenu(): |
|
|
|
command = j[2] |
|
|
|
path = j[3] |
|
|
|
if path is not None: |
|
|
|
command = 'cd '+path+' ; '+command |
|
|
|
command = 'cd ' + path + ' ; ' + command |
|
|
|
if icon is None: |
|
|
|
print(spacing+' [exec] ('+name+') {'+command+'}') |
|
|
|
print(spacing + ' [exec] (' + name + ') {' + command + '}') |
|
|
|
else: |
|
|
|
print(spacing+' [exec] ('+name+') {'+command+'} <'+icon+'>') |
|
|
|
print(spacing+'[end] # ('+category+')') |
|
|
|
print(spacing + ' [exec] (' + name + |
|
|
|
') {' + command + '} <' + icon + '>') |
|
|
|
print(spacing + '[end] # (' + category + ')') |
|
|
|
if submenu: |
|
|
|
print('[end] # ('+applications+')') |
|
|
|
print('[end] # (' + applications + ')') |
|
|
|
|
|
|
|
|
|
|
|
def windowmakermenu(): |
|
|
|
print('"'+applications+'" MENU') |
|
|
|
print('"' + applications + '" MENU') |
|
|
|
for i in menu(): |
|
|
|
category = i[0] |
|
|
|
print(' "'+category+'" MENU') |
|
|
|
print(' "' + category + '" MENU') |
|
|
|
for j in i[1]: |
|
|
|
name = j[0] |
|
|
|
command = j[2] |
|
|
|
print(' "'+name+'" EXEC '+command) |
|
|
|
print(' "'+category+'" END') |
|
|
|
print('"'+applications+'" END') |
|
|
|
print(' "' + name + '" EXEC ' + command) |
|
|
|
print(' "' + category + '" END') |
|
|
|
print('"' + applications + '" END') |
|
|
|
|
|
|
|
|
|
|
|
def icewmmenu(): |
|
|
|
if submenu: |
|
|
@ -397,9 +424,9 @@ def icewmmenu(): |
|
|
|
app_icon = icon_full_path(applications_icon) |
|
|
|
if app_icon is None: |
|
|
|
app_icon = "_none_" |
|
|
|
print('menu "'+applications+'" '+app_icon+' {') |
|
|
|
print('menu "' + applications + '" ' + app_icon + ' {') |
|
|
|
else: |
|
|
|
print('menu "'+applications+'" _none_ {') |
|
|
|
print('menu "' + applications + '" _none_ {') |
|
|
|
else: |
|
|
|
spacing = '' |
|
|
|
for i in menu(): |
|
|
@ -407,21 +434,23 @@ def icewmmenu(): |
|
|
|
cat_icon = category_icon(category) |
|
|
|
cat_icon = icon_full_path(cat_icon) |
|
|
|
if seticon and cat_icon is not None: |
|
|
|
print(spacing+'menu "'+category+'" '+cat_icon+' {') |
|
|
|
print(spacing + 'menu "' + category + '" ' + cat_icon + ' {') |
|
|
|
else: |
|
|
|
print(spacing+'menu "'+category+'" _none_ {') |
|
|
|
print(spacing + 'menu "' + category + '" _none_ {') |
|
|
|
for j in i[1]: |
|
|
|
name = j[0] |
|
|
|
icon = j[1] |
|
|
|
command = j[2] |
|
|
|
if seticon and icon is not None: |
|
|
|
print(spacing+' prog "'+name+'" '+icon+' '+command) |
|
|
|
print(spacing + ' prog "' + name + |
|
|
|
'" ' + icon + ' ' + command) |
|
|
|
else: |
|
|
|
print(spacing+' prog "'+name+'" _none_ '+command) |
|
|
|
print(spacing+'}') |
|
|
|
print(spacing + ' prog "' + name + '" _none_ ' + command) |
|
|
|
print(spacing + '}') |
|
|
|
if submenu: |
|
|
|
print('}') |
|
|
|
|
|
|
|
|
|
|
|
def pekwmmenu(): |
|
|
|
if pekwmdynamic: |
|
|
|
print("Dynamic {") |
|
|
@ -432,9 +461,10 @@ def pekwmmenu(): |
|
|
|
spacing = ' ' |
|
|
|
if seticon: |
|
|
|
app_icon = icon_full_path(applications_icon) |
|
|
|
print(dspacing+'Submenu = "'+applications+'" { Icon = "'+app_icon+'"') |
|
|
|
print(dspacing + 'Submenu = "' + applications + |
|
|
|
'" { Icon = "' + app_icon + '"') |
|
|
|
else: |
|
|
|
print(dspacing+'Submenu = "'+applications+'" {') |
|
|
|
print(dspacing + 'Submenu = "' + applications + '" {') |
|
|
|
else: |
|
|
|
spacing = '' |
|
|
|
for i in menu(): |
|
|
@ -442,9 +472,10 @@ def pekwmmenu(): |
|
|
|
cat_icon = category_icon(category) |
|
|
|
cat_icon = icon_full_path(cat_icon) |
|
|
|
if seticon and cat_icon is not None: |
|
|
|
print(dspacing+spacing+'Submenu = "'+category+'" { Icon = "'+cat_icon+'"') |
|
|
|
print(dspacing + spacing + 'Submenu = "' + |
|
|
|
category + '" { Icon = "' + cat_icon + '"') |
|
|
|
else: |
|
|
|
print(dspacing+spacing+'Submenu = "'+category+'" {') |
|
|
|
print(dspacing + spacing + 'Submenu = "' + category + '" {') |
|
|
|
for j in i[1]: |
|
|
|
name = j[0] |
|
|
|
icon = j[1] |
|
|
@ -458,17 +489,20 @@ def pekwmmenu(): |
|
|
|
# pekwm doesn't like "cd path ; command", but it works |
|
|
|
# with "&&" and "||", so we'll launch the command even if the |
|
|
|
# path does not exist |
|
|
|
command = 'cd '+path+' && '+command+' || '+command |
|
|
|
command = 'cd ' + path + ' && ' + command + ' || ' + command |
|
|
|
if seticon and icon is not None: |
|
|
|
print(dspacing+spacing+' Entry = "'+name+'" { Icon = "'+icon+'"; Actions = "Exec '+command+' &" }') |
|
|
|
print(dspacing + spacing + ' Entry = "' + name + |
|
|
|
'" { Icon = "' + icon + '"; Actions = "Exec ' + command + ' &" }') |
|
|
|
else: |
|
|
|
print(dspacing+spacing+' Entry = "'+name+'" { Actions = "Exec '+command+' &" }') |
|
|
|
print(dspacing+spacing+'}') |
|
|
|
print(dspacing + spacing + ' Entry = "' + name + |
|
|
|
'" { Actions = "Exec ' + command + ' &" }') |
|
|
|
print(dspacing + spacing + '}') |
|
|
|
if submenu: |
|
|
|
print(dspacing+'}') |
|
|
|
print(dspacing + '}') |
|
|
|
if pekwmdynamic: |
|
|
|
print("}") |
|
|
|
|
|
|
|
|
|
|
|
def jwmmenu(): |
|
|
|
print('<?xml version="1.0"?>') |
|
|
|
print('<JWM>') |
|
|
@ -477,11 +511,12 @@ def jwmmenu(): |
|
|
|
if seticon: |
|
|
|
app_icon = icon_full_path(applications_icon) |
|
|
|
if app_icon is None: |
|
|
|
print('<Menu label="'+applications+'">') |
|
|
|
print('<Menu label="' + applications + '">') |
|
|
|
else: |
|
|
|
print('<Menu icon="'+app_icon+'" label="'+applications+'">') |
|
|
|
print('<Menu icon="' + app_icon + |
|
|
|
'" label="' + applications + '">') |
|
|
|
else: |
|
|
|
print('<Menu label="'+applications+'">') |
|
|
|
print('<Menu label="' + applications + '">') |
|
|
|
else: |
|
|
|
spacing = '' |
|
|
|
for i in menu(): |
|
|
@ -489,21 +524,24 @@ def jwmmenu(): |
|
|
|
cat_icon = category_icon(category) |
|
|
|
cat_icon = icon_full_path(cat_icon) |
|
|
|
if seticon and cat_icon is not None: |
|
|
|
print(spacing+'<Menu icon="'+cat_icon+'" label="'+category+'">') |
|
|
|
print(spacing + '<Menu icon="' + cat_icon + |
|
|
|
'" label="' + category + '">') |
|
|
|
else: |
|
|
|
print(spacing+'<Menu label="'+category+'">') |
|
|
|
print(spacing + '<Menu label="' + category + '">') |
|
|
|
for j in i[1]: |
|
|
|
name = j[0] |
|
|
|
icon = j[1] |
|
|
|
command = j[2] |
|
|
|
path = j[3] |
|
|
|
if path is not None: |
|
|
|
command = 'cd '+path+' ; '+command |
|
|
|
command = 'cd ' + path + ' ; ' + command |
|
|
|
if seticon and icon is not None: |
|
|
|
print(spacing+' <Program icon="'+icon+'" label="'+name+'">'+command+'</Program>') |
|
|
|
print(spacing + ' <Program icon="' + icon + |
|
|
|
'" label="' + name + '">' + command + '</Program>') |
|
|
|
else: |
|
|
|
print(spacing+' <Program label="'+name+'">'+command+'</Program>') |
|
|
|
print(spacing+'</Menu>') |
|
|
|
print(spacing + ' <Program label="' + |
|
|
|
name + '">' + command + '</Program>') |
|
|
|
print(spacing + '</Menu>') |
|
|
|
if submenu: |
|
|
|
print('</Menu>') |
|
|
|
print('</JWM>') |
|
|
|