#!/usr/bin/env python
# vim: noexpandtab:ts=4:sts=4
"""Menu Generator for Fluxbox
Generates a menu for Fluxbox using the freedesktop.org standards
Usage: fluxbox-xdg-menu.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
-t ..., --theme=... what icon theme you want to use
--with-icons put icons for applications in the menu
--stdout output the menu to standard output
--submenu output to be used as an include/submenu with fluxbox
--with-backgrounds creates a background menu. Default background_paths =
~/.fluxbox/backgrounds, /usr/share/wallpapers,
/usr/share/backgrounds
--backgrounds-only do not regenerate menu, only do the bg menu.
--bg-path= path to location to look for images
example: --bg-path=~/pics
may be used with --backgrounds-only but --bg-path=
must be first: --bg-path=~/some/path --backgrounds-only
A nice example string to use: fluxbox-fdo-menugen.py --with-icons --with-backgrounds --bg-path=~/some/path
To update only the backgrounds: fluxbox-fdo-menugen.py --bg-path=~/some/path --backgrounds-only
"""
__author__ = "Rudolf Kastl , Antonio Gomes, Michael Rice"
__version__ = "$Revision: 1.2 $"
__date__ = "$Date: 2006/10/21 09:38:14 $"
__license__ = "GPL"
import os,re,sys,glob,getopt
import xdg.Menu,xdg.DesktopEntry,xdg.IconTheme
from os.path import isfile
def usage():
print __doc__
def header(wm="fluxbox"):
return """
[begin] (Fluxbox)
[exec] (Web Browser) {htmlview}
[exec] (Email) {evolution}
[exec] (Terminal) {$TERM}
[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, theme):
"""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
"""
retval=str(xdg.IconTheme.getIconPath(icon, 48, theme))
if retval == "None":
retval=""
return (retval + "").encode('utf8')
def parseMenu(menu,wm,use_icons,theme,depth=1):
if use_icons:
print "%s[submenu] (%s) <%s> " % ( (depth*"\t"), menu.getName().encode('utf8'), findIcon(menu.getIcon(), theme) )
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,wm,use_icons,theme,depth)
elif isinstance(entry, xdg.Menu.MenuEntry):
checkWm(entry,wm)
if entry.Show == False: continue
appname = entry.DesktopEntry.getName().encode("utf8");
appname = appname.replace(")","\)");
if use_icons:
print "%s[exec] (%s) {%s} <%s> " % ( (depth*"\t"), appname, entry.DesktopEntry.getExec().split()[0], findIcon(entry.DesktopEntry.getIcon(), theme) )
else:
print "%s[exec] (%s) {%s} " % ( (depth*"\t"), appname, 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 get_bgimgs_and_parse(xPath):
try:
if isfile(os.path.expanduser("~/.fluxbox/bgmenu")) == True:
os.unlink(os.path.expanduser("~/.fluxbox/bgmenu"))
except OSError:
pass
h = {}
bg_paths =["~/.fluxbox/backgrounds","/usr/share/wallpapers",
"/usr/share/backgrounds","/usr/share/backgrounds/images"]
try:
if xPath == None:
pass
else:
bg_paths.append(xPath)
except(TypeError):
pass
for dir in bg_paths:
for imgpth in bg_paths:
try:
imgs = os.listdir(os.path.expanduser(imgpth))
for i in imgs:
h[i] = imgpth
except (OSError):
pass
bgMenu = open(os.path.expanduser("~/.fluxbox/bgmenu"),'w+')
num = len(h)
countNum = 1
bgPagCk = 1
bgPgNum = 1
bgMenu.write( "[submenu] (Backgrounds)\n" )
bgMenu.write( "[submenu] (Backgrounds) {Set Your Background}\n" )
bgMenu.write("\t[exec] (Random Image) {fbsetbg -r ~/.fluxbox/backgrounds}\n")
types = ["png","jpg","jpeg","gif"]
for i in h.keys():
try:
t = i.split(".")[-1].lower()
if t in types:
print "Hello"
bgMenu.write( "\t[exec]\t("+ i +") {fbsetbg -f "+ h[i] + "/" + i +"}\n" )
countNum = countNum + 1
num = num - 1
bgPagCk = bgPagCk + 1
if bgPagCk == 26:
bgPgNum = bgPgNum + 1
bgMenu.write("[end]\n[submenu] (Backgrounds " + str(bgPgNum) +") \
{Set Your Background}\n")
bgPagCk = 1
if num == 0:
bgMenu.write( "[end]\n[end]\n" )
bgMenu.close()
except(KeyError):
print h[i]
pass
def main(argv):
# Setting the default values
wm = "fluxbox"
file = "~/.fluxbox/menu"
use_icons = False
use_bg = False
bg_Xpath = False
theme = "gnome"
lang = os.getenv("LANG","C")
file = os.path.expanduser("~/.fluxbox/menu")
do_submenu = False
use_stdout = False
try:
opts, args = getopt.getopt(argv, "hf:dl:d", ["help","lang=","file=","with-icons","stdout",\
"theme=","submenu","with-backgrounds","backgrounds-only","bg-path="])
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
elif opt in ("-t", "--theme"):
theme = arg
elif opt == '--stdout':
use_stdout = True
elif opt == '--stdout':
file = sys.stdout
elif opt == '--bg-path':
bg_Xpath = True
xPath = os.path.expanduser(arg)
elif opt == '--with-backgrounds':
use_bg = True
elif opt == '--backgrounds-only':
if bg_Xpath:
get_bgimgs_and_parse(xPath)
else:
get_bgimgs_and_parse(None)
raise SystemExit
elif opt == '--submenu':
do_submenu = True
if not use_stdout:
fsock = open(file,'w')
saveout = sys.stdout
sys.stdout = fsock
menu=xdg.Menu.parse()
# is done automatically now
# menu.setLocale(lang)
if not do_submenu:
print header()
parseMenu(menu,wm,use_icons,theme)
if not do_submenu and use_bg and bg_Xpath:
get_bgimgs_and_parse(xPath)
print "[include] (~/.fluxbox/bgmenu)"
if not do_submenu and use_bg and not bg_Xpath:
print "[include] (~/.fluxbox/bgmenu)"
get_bgimgs_and_parse(None)
if not do_submenu:
print footer()
if not use_stdout:
sys.stdout = saveout
# print menu
if __name__ == "__main__":
main(sys.argv[1:])