8be0e16
#!/usr/bin/env python
8be0e16
# vim: noexpandtab:ts=4:sts=4
8be0e16
e372ea5
"""Menu Generator for Fluxbox
e372ea5
e372ea5
Generates a menu for Fluxbox using the freedesktop.org standards
e372ea5
8be0e16
Usage: fluxbox-xdg-menu.py [options]
e372ea5
e372ea5
Options:
e372ea5
  -l ..., --lang=...      create the menu using a language. Default = $LANG
e372ea5
  -h, --help              show this help
e372ea5
  -f ..., --file=...      output the menu into a file. Default = ~/.fluxbox/menu
8be0e16
  -t ..., --theme=...     what icon theme you want to use
8be0e16
  --with-icons            put icons for applications in the menu
e372ea5
  --stdout                output the menu to standard output
8be0e16
  --submenu               output to be used as an include/submenu with fluxbox
8be0e16
  --with-backgrounds      creates a background menu. Default background_paths = 
8be0e16
                          ~/.fluxbox/backgrounds, /usr/share/wallpapers,
8be0e16
                          /usr/share/backgrounds
8be0e16
  --backgrounds-only      do not regenerate menu, only do the bg menu.
8be0e16
  --bg-path=              path to location to look for images 
8be0e16
                          example: --bg-path=~/pics  
8be0e16
			  may be used with --backgrounds-only but --bg-path= 
8be0e16
			  must be first: --bg-path=~/some/path --backgrounds-only
e372ea5
8be0e16
A nice example string to use: fluxbox-fdo-menugen.py --with-icons --with-backgrounds --bg-path=~/some/path
8be0e16
To update only the backgrounds: fluxbox-fdo-menugen.py --bg-path=~/some/path --backgrounds-only
e372ea5
"""
e372ea5
8be0e16
__author__ = "Rudolf Kastl , Antonio Gomes, Michael Rice"
8be0e16
__version__ = "$Revision: 1.2 $"
0c73761
__date__ = "$Date: 2006/10/21 09:38:14 $"
e372ea5
__license__ = "GPL"
e372ea5
e372ea5
e372ea5
import os,re,sys,glob,getopt
e372ea5
import xdg.Menu,xdg.DesktopEntry,xdg.IconTheme
8be0e16
from os.path import isfile
e372ea5
e372ea5
def usage():
e372ea5
	print __doc__
e372ea5
e372ea5
def header(wm="fluxbox"):
e372ea5
	return """
e372ea5
[begin] (Fluxbox)
e372ea5
	[exec] (Web Browser) {htmlview}
e372ea5
	[exec] (Email) {evolution}
8be0e16
	[exec] (Terminal) {$TERM}
e372ea5
	[exec] (Irc) {xchat}
e372ea5
	[separator]\n"""
e372ea5
e372ea5
def footer(wm="fluxbox"):
e372ea5
	return """
e372ea5
	[submenu] (Fluxbox Menu)
e372ea5
		[config] (Configure)
e372ea5
		[submenu] (System Styles) {Choose a style...}
e372ea5
			[stylesdir] (/usr/share/fluxbox/styles)
e372ea5
			[stylesdir] (/usr/share/commonbox/styles/)
e372ea5
		[end]
e372ea5
		[submenu] (User Styles) {Choose a style...}
e372ea5
			[stylesdir] (~/.fluxbox/styles)
e372ea5
		[end]
e372ea5
		[workspaces]   (Workspace List)
e372ea5
		[submenu] (Tools)
e372ea5
			[exec] (Window name) {xprop WM_CLASS|cut -d \" -f 2|xmessage -file - -center}
e372ea5
			[exec] (Screenshot - JPG) {import screenshot.jpg && display -resize 50% screenshot.jpg}
e372ea5
			[exec] (Screenshot - PNG) {import screenshot.png && display -resize 50% screenshot.png}
e372ea5
			[exec] (Run) {fbrun }
e372ea5
			[exec] (Regen Menu) {fluxbox-generate_menu --with-icons}
e372ea5
		[end]
e372ea5
		[submenu] (Window)
e372ea5
			[restart] (kde) {startkde}
e372ea5
			[restart] (openbox) {openbox}
e372ea5
			[restart] (gnome) {gnome-session}
e372ea5
		[end]
e372ea5
		[exec] (Lock screen) {xscreensaver-command -lock}
e372ea5
		[commanddialog] (Fluxbox Command)
e372ea5
		[reconfig] (Reload config)
e372ea5
		[restart] (Restart)
e372ea5
		[separator]
e372ea5
		[exit] (Exit)
e372ea5
	[end]
e372ea5
[end]\n"""	
e372ea5
e372ea5
def checkWm(entry, wm="fluxbox"):
e372ea5
	if entry.DesktopEntry.getOnlyShowIn() != []:
e372ea5
		entry.Show = False
e372ea5
	if entry.DesktopEntry.getNotShowIn() != []:
e372ea5
		if isinstance(entry, xdg.Menu.MenuEntry):
e372ea5
			if wm in entry.DesktopEntry.getNotShowIn():
e372ea5
				entry.Show = False
e372ea5
			else:
e372ea5
				entry.Show = True 
e372ea5
	
8be0e16
def findIcon(icon, theme):
e372ea5
	"""Finds the path and filename for the given icon name
e372ea5
		e.g. gaim --> /usr/share/pixmaps/gaim.png
e372ea5
		e.g. fart.png --> /usr/share/pixmaps/fart.png
e372ea5
	"""
8be0e16
	retval=str(xdg.IconTheme.getIconPath(icon, 48, theme))
8be0e16
	if retval == "None":
8be0e16
		retval=""
e372ea5
8be0e16
	return (retval + "").encode('utf8')
e372ea5
8be0e16
def parseMenu(menu,wm,use_icons,theme,depth=1):
e372ea5
	if use_icons:
8be0e16
		print "%s[submenu] (%s) <%s> " % ( (depth*"\t"), menu.getName().encode('utf8'),  findIcon(menu.getIcon(), theme) )
e372ea5
	else:
e372ea5
		print "%s[submenu] (%s) " % ( (depth*"\t"), menu.getName().encode('utf8'), )
e372ea5
	depth += 1
e372ea5
	for entry in menu.getEntries():
e372ea5
		if isinstance(entry, xdg.Menu.Menu):
8be0e16
			parseMenu(entry,wm,use_icons,theme,depth)
e372ea5
		elif isinstance(entry, xdg.Menu.MenuEntry):
e372ea5
			checkWm(entry,wm)
0c73761
			if entry.Show == False: continue			
0c73761
			appname = entry.DesktopEntry.getName().encode("utf8");
0c73761
			appname = appname.replace(")","\)");
e372ea5
			if use_icons:
0c73761
				print "%s[exec] (%s) {%s} <%s> " % ( (depth*"\t"), appname, entry.DesktopEntry.getExec().split()[0], findIcon(entry.DesktopEntry.getIcon(), theme) )
e372ea5
			else:
0c73761
				print "%s[exec] (%s) {%s} " % ( (depth*"\t"), appname, entry.DesktopEntry.getExec().split()[0] )
e372ea5
		elif isinstance(entry,xdg.Menu.Separator):
e372ea5
			print "%s[separator]" % (depth*"\t")
e372ea5
		elif isinstance(entry.xdg.Menu.Header):
e372ea5
			print "%s%s" % ( (depth*"\t"), entry.Name )
e372ea5
	depth -= 1
e372ea5
	print "%s[end]" % (depth*"\t")
e372ea5
8be0e16
def get_bgimgs_and_parse(xPath):
8be0e16
    try:
8be0e16
        if isfile(os.path.expanduser("~/.fluxbox/bgmenu")) == True:
8be0e16
            os.unlink(os.path.expanduser("~/.fluxbox/bgmenu"))
8be0e16
    except OSError:
8be0e16
        pass
8be0e16
    h = {}
8be0e16
    bg_paths =["~/.fluxbox/backgrounds","/usr/share/wallpapers",
8be0e16
		"/usr/share/backgrounds","/usr/share/backgrounds/images"]
8be0e16
    try:
8be0e16
        if xPath == None:
8be0e16
           pass
8be0e16
        else:
8be0e16
            bg_paths.append(xPath)
8be0e16
    except(TypeError):
8be0e16
        pass
8be0e16
    for dir in bg_paths:
8be0e16
        for imgpth in bg_paths:
8be0e16
            try:
8be0e16
                imgs = os.listdir(os.path.expanduser(imgpth))
8be0e16
                for i in imgs:
8be0e16
                    h[i] = imgpth
8be0e16
            except (OSError):
8be0e16
                pass
8be0e16
    bgMenu = open(os.path.expanduser("~/.fluxbox/bgmenu"),'w+')
8be0e16
    num = len(h)
8be0e16
    countNum = 1
8be0e16
    bgPagCk = 1
8be0e16
    bgPgNum = 1
8be0e16
    bgMenu.write( "[submenu] (Backgrounds)\n" )
8be0e16
    bgMenu.write( "[submenu] (Backgrounds) {Set Your Background}\n" )
8be0e16
    bgMenu.write("\t[exec]  (Random Image)  {fbsetbg -r ~/.fluxbox/backgrounds}\n")
8be0e16
	types = ["png","jpg","jpeg","gif"]
8be0e16
    for i in h.keys():
8be0e16
	    try:
8be0e16
		    t = i.split(".")[-1].lower()
8be0e16
			if t in types:
8be0e16
			    print "Hello"
8be0e16
			    bgMenu.write( "\t[exec]\t("+ i +") {fbsetbg -f "+ h[i] + "/" + i +"}\n" )
8be0e16
				countNum = countNum + 1
8be0e16
				num = num - 1
8be0e16
				bgPagCk = bgPagCk + 1
8be0e16
				if bgPagCk == 26:
8be0e16
				    bgPgNum = bgPgNum + 1
8be0e16
					bgMenu.write("[end]\n[submenu] (Backgrounds " + str(bgPgNum) +") \
8be0e16
						{Set Your Background}\n")
8be0e16
					bgPagCk = 1
8be0e16
				if num == 0:
8be0e16
				    bgMenu.write( "[end]\n[end]\n" )
8be0e16
					bgMenu.close()
8be0e16
		except(KeyError):
8be0e16
		    print h[i]
8be0e16
		    pass
e372ea5
e372ea5
def main(argv):
e372ea5
# Setting the default values
e372ea5
	wm = "fluxbox"
e372ea5
	file = "~/.fluxbox/menu"
e372ea5
	use_icons = False
8be0e16
    use_bg = False
8be0e16
    bg_Xpath = False
8be0e16
	theme = "gnome"
e372ea5
	lang = os.getenv("LANG","C")
e372ea5
	file = os.path.expanduser("~/.fluxbox/menu")
8be0e16
	do_submenu = False
8be0e16
	use_stdout = False
e372ea5
	
e372ea5
	try:
8be0e16
		opts, args = getopt.getopt(argv, "hf:dl:d", ["help","lang=","file=","with-icons","stdout",\
8be0e16
			"theme=","submenu","with-backgrounds","backgrounds-only","bg-path="])
8be0e16
e372ea5
	except getopt.GetoptError:
e372ea5
		usage()
e372ea5
		sys.exit(2)
e372ea5
	for opt, arg in opts:
e372ea5
		if opt in ("-h", "--help"):
e372ea5
			usage()
e372ea5
			sys.exit()
e372ea5
		elif opt in ("-l", "--lang"):
e372ea5
			lang = arg
e372ea5
		elif opt in ("-f", "--file"):
e372ea5
			file = os.path.expanduser(arg)
e372ea5
		elif opt == '--with-icons':
8be0e16
			use_icons = True
8be0e16
		elif opt in ("-t", "--theme"):
8be0e16
			theme = arg
8be0e16
		elif opt == '--stdout':
8be0e16
			use_stdout = True
e372ea5
		elif opt == '--stdout':
e372ea5
			file = sys.stdout
8be0e16
		elif opt == '--bg-path':
8be0e16
		    bg_Xpath = True
8be0e16
			xPath = os.path.expanduser(arg)
8be0e16
		elif opt == '--with-backgrounds':
8be0e16
		    use_bg = True
8be0e16
		elif opt == '--backgrounds-only':
8be0e16
		    if bg_Xpath:
8be0e16
			    get_bgimgs_and_parse(xPath)
8be0e16
			else:
8be0e16
			    get_bgimgs_and_parse(None)
8be0e16
				raise SystemExit
8be0e16
			  
8be0e16
		elif opt == '--submenu':
8be0e16
			do_submenu = True
e372ea5
8be0e16
	if not use_stdout:
8be0e16
		fsock = open(file,'w')
8be0e16
		saveout = sys.stdout
8be0e16
		sys.stdout = fsock
e372ea5
e372ea5
	menu=xdg.Menu.parse()
e372ea5
# is done automatically now
e372ea5
#	menu.setLocale(lang)
e372ea5
8be0e16
	if not do_submenu:
8be0e16
        print header()
8be0e16
	parseMenu(menu,wm,use_icons,theme)
8be0e16
	if not do_submenu and use_bg and bg_Xpath:
8be0e16
	    get_bgimgs_and_parse(xPath) 
8be0e16
	    print "[include] (~/.fluxbox/bgmenu)"
8be0e16
	if not do_submenu and use_bg and not bg_Xpath:
8be0e16
	    print "[include] (~/.fluxbox/bgmenu)"
8be0e16
		get_bgimgs_and_parse(None)
8be0e16
    if not do_submenu:
8be0e16
        print footer()
8be0e16
	if not use_stdout:
8be0e16
		sys.stdout = saveout
e372ea5
e372ea5
#	print menu
e372ea5
if __name__ == "__main__":
e372ea5
	main(sys.argv[1:])