Blob Blame History Raw
#!/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)', ')')