# Copyright (c) 2008-2011 by Enthought, Inc.
# All rights reserved.
"""
The menu will be installed to both Gnome and KDE desktops if they are
available.
Note that the information required is sufficient to install application
menus on systems that follow the format of the Desktop Entry Specification
by freedesktop.org. See:
http://freedesktop.org/Standards/desktop-entry-spec
"""
import re
import os
import shutil
import sys
import time
import xml.etree.ElementTree as ET
from os.path import abspath, dirname, exists, expanduser, isdir, isfile, join
from utils import rm_rf, get_executable
from freedesktop import make_desktop_entry, make_directory_entry
# datadir: contains the desktop and directory entries
# confdir: contains the XML menu files
sys_menu_file = '/etc/xdg/menus/applications.menu'
if os.getuid() == 0:
mode = 'system'
datadir = '/usr/share'
confdir = '/etc/xdg'
else:
mode = 'user'
datadir = os.environ.get('XDG_DATA_HOME',
abspath(expanduser('~/.local/share')))
confdir = os.environ.get('XDG_CONFIG_HOME',
abspath(expanduser('~/.config')))
appdir = join(datadir, 'applications')
menu_file = join(confdir, 'menus/applications.menu')
def indent(elem, level=0):
"""
adds whitespace to the tree, so that it results in a pretty printed tree
"""
XMLindentation = " " # 4 spaces, just like in Python!
i = "\n" + level * XMLindentation
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + XMLindentation
for e in elem:
indent(e, level+1)
if not e.tail or not e.tail.strip():
e.tail = i + XMLindentation
if not e.tail or not e.tail.strip():
e.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
def add_child(parent, tag, text=None):
"""
Add a child element of specified tag type to parent.
The new child element is returned.
"""
elem = ET.SubElement(parent, tag)
if text is not None:
elem.text = text
return elem
def is_valid_menu_file():
try:
root = ET.parse(menu_file).getroot()
assert root is not None and root.tag == 'Menu'
return True
except:
return False
def write_menu_file(tree):
indent(tree.getroot())
fo = open(menu_file, 'w')
fo.write("""\
""")
tree.write(fo)
fo.write('\n')
fo.close()
def ensure_menu_file():
# ensure any existing version is a file
if exists(menu_file) and not isfile(menu_file):
rm_rf(menu_file)
# ensure any existing file is actually a menu file
if isfile(menu_file):
# make a backup of the menu file to be edited
cur_time = time.strftime('%Y-%m-%d_%Hh%Mm%S')
backup_menu_file = "%s.%s" % (menu_file, cur_time)
shutil.copyfile(menu_file, backup_menu_file)
if not is_valid_menu_file():
os.remove(menu_file)
# create a new menu file if one doesn't yet exist
if not isfile(menu_file):
fo = open(menu_file, 'w')
if mode == 'user':
merge = '