#!/usr/bin/python2
"""Menu Generator for Fluxbox
Generates a menu for Fluxbox using the freedesktop.org standards
Usage: fluxbox-fdo-menugen.py [options]
Options:
-l ..., --lang=... create the menu using a language. Default = $LANG
-h, --help show this help
-f ..., --file=... output the menu into a file. Default = ~/.fluxbox/menu
--with-icons do not put icons for applications in the menu
--stdout output the menu to standard output
"""
__author__ = "Rudolf Kastl , Antonio Gomes"
__version__ = "$Revision: 1.0 $"
__date__ = "$Date: 2005/04/09 17:46:19 $"
__license__ = "GPL"
import os,re,sys,glob,getopt
import xdg.Menu,xdg.DesktopEntry,xdg.IconTheme
def usage():
print __doc__
def header(wm="fluxbox"):
return """
[begin] (Fluxbox)
[exec] (Web Browser) {htmlview}
[exec] (Email) {evolution}
[exec] (Terminal) {gnome-terminal}
[exec] (Irc) {xchat}
[separator]\n"""
def footer(wm="fluxbox"):
return """
[submenu] (Fluxbox Menu)
[config] (Configure)
[submenu] (System Styles) {Choose a style...}
[stylesdir] (/usr/share/fluxbox/styles)
[stylesdir] (/usr/share/commonbox/styles/)
[end]
[submenu] (User Styles) {Choose a style...}
[stylesdir] (~/.fluxbox/styles)
[end]
[workspaces] (Workspace List)
[submenu] (Tools)
[exec] (Window name) {xprop WM_CLASS|cut -d \" -f 2|xmessage -file - -center}
[exec] (Screenshot - JPG) {import screenshot.jpg && display -resize 50% screenshot.jpg}
[exec] (Screenshot - PNG) {import screenshot.png && display -resize 50% screenshot.png}
[exec] (Run) {fbrun }
[exec] (Regen Menu) {fluxbox-generate_menu --with-icons}
[end]
[submenu] (Window)
[restart] (kde) {startkde}
[restart] (openbox) {openbox}
[restart] (gnome) {gnome-session}
[end]
[exec] (Lock screen) {xscreensaver-command -lock}
[commanddialog] (Fluxbox Command)
[reconfig] (Reload config)
[restart] (Restart)
[separator]
[exit] (Exit)
[end]
[end]\n"""
def checkWm(entry, wm="fluxbox"):
if entry.DesktopEntry.getOnlyShowIn() != []:
entry.Show = False
if entry.DesktopEntry.getNotShowIn() != []:
if isinstance(entry, xdg.Menu.MenuEntry):
if wm in entry.DesktopEntry.getNotShowIn():
entry.Show = False
else:
entry.Show = True
#def findIcon(icon):
# """Finds the path and filename for the given icon name
# e.g. gaim --> /usr/share/pixmaps/gaim.png
# e.g. fart.png --> /usr/share/pixmaps/fart.png
# """
# if os.path.isfile(icon): return icon
# paths = ["~/.icons","/usr/share/pixmaps","/usr/share/icons"]
# for path in paths:
# for dirpath , dirnames, filenames in os.walk(os.path.expanduser(path)):
# for filename in filenames:
# pattern = '^%s\.(png|jpg|gif|xpm)' % icon # matches <filename>.<something>
# if icon == filename or re.search(pattern, filename):
# return os.path.join(dirpath,filename)
def findIcon(icon):
"""Finds the path and filename for the given icon name
e.g. gaim --> /usr/share/pixmaps/gaim.png
e.g. fart.png --> /usr/share/pixmaps/fart.png
"""
global paths
global locs
# Case Icon=/path/to/file.extension
if os.path.isfile(icon): return icon
# Case Icon=file.extension
if re.search("^\w+.*\.\w{3}$",icon):
names=[icon]
# Case Icon=file
elif re.search("^\w+.*$",icon):
names=[icon+".png",icon+".xpm",icon+".jpg"]
else:
names=[]
for path in paths:
for name in names:
if (os.path.isfile(path+name)):
locs.append(path)
return (path+name).encode('utf8')
def parseMenu(menu,depth=1):
global wm
global use_icons
if use_icons:
print "%s[submenu] (%s) <%s> " % ( (depth*"\t"), menu.getName().encode('utf8'), findIcon(menu.getIcon()) )
else:
print "%s[submenu] (%s) " % ( (depth*"\t"), menu.getName().encode('utf8'), )
depth += 1
for entry in menu.getEntries():
if isinstance(entry, xdg.Menu.Menu):
parseMenu(entry,depth)
elif isinstance(entry, xdg.Menu.MenuEntry):
checkWm(entry,wm)
if entry.Show == False: continue
if use_icons:
print "%s[exec] (%s) {%s} <%s> " % ( (depth*"\t"), entry.DesktopEntry.getName().encode("utf8"), entry.DesktopEntry.getExec().split()[0], findIcon(entry.DesktopEntry.getIcon()) )
else:
print "%s[exec] (%s) {%s} " % ( (depth*"\t"), entry.DesktopEntry.getName().encode("utf8"), entry.DesktopEntry.getExec().split()[0] )
elif isinstance(entry,xdg.Menu.Separator):
print "%s[separator]" % (depth*"\t")
elif isinstance(entry.xdg.Menu.Header):
print "%s%s" % ( (depth*"\t"), entry.Name )
depth -= 1
print "%s[end]" % (depth*"\t")
def main(argv):
# Setting the default values
global locs
locs=[]
global wm
wm = "fluxbox"
global file
file = "~/.fluxbox/menu"
global use_icons
use_icons = False
lang = os.getenv("LANG","C")
file = os.path.expanduser("~/.fluxbox/menu")
try:
opts, args = getopt.getopt(argv, "hf:dl:d", ["help","lang=","file=","with-icons","stdout"])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-l", "--lang"):
lang = arg
elif opt in ("-f", "--file"):
file = os.path.expanduser(arg)
elif opt == '--with-icons':
use_icons = True
global paths
locations = \
['/usr/share/pixmaps/', \
'/usr/share/icons/hicolor/24x24/apps/', \
'/usr/share/icons/hicolor/32x32/apps/', \
'/usr/share/icons/hicolor/48x48/apps/', \
'/usr/share/icons/hicolor/24x24/stock/generic/', \
'/usr/share/icons/HighContrastLargePrintInverse/48x48/apps/', \
'/usr/share/icons/crystalsvg/16x16/apps/', \
'/usr/share/icons/crystalsvg/32x32/apps/', \
'/usr/share/icons/crystalsvg/48x48/apps/', \
'/usr/share/icons/crystalsvg/48x48/devices/', \
'/usr/share/icons/', \
'/usr/share/icons/hicolor/32x32/apps/', \
'/usr/share/icons/Bluecurve/24x24/stock/', \
'/usr/share/icons/Bluecurve/48x48/filesystems/']
paths=locations
# for path in locations:
# paths+=glob.glob(path+"/*/")+glob.glob(path+"/*/*/")
# print paths
elif opt == '--stdout':
file = sys.stdout
fsock = open(file,'w')
saveout = sys.stdout
sys.stdout = fsock
menu=xdg.Menu.parse()
# is done automatically now
# menu.setLocale(lang)
print header()
parseMenu(menu)
print footer()
sys.stdout = saveout
# print menu
if __name__ == "__main__":
main(sys.argv[1:])
#WindowMaker Reminder
#>>> p=re.compile("(\).*),(\s*\))")
#>>> p.search("((ola),(ola),)").groups()
#('),(ola)', ')')