Start development series 0.42.1-post
[zeroinstall/zeroinstall-rsl.git] / zeroinstall / gtkui / xdgutils.py
blob42f6fc54cb58a532f6f842d22156df78dfe9a436
1 """Adding icons and menu items using the freedesktop.org system.
2 (xdg = X Desktop Group)
3 """
4 # Copyright (C) 2009, Thomas Leonard
5 # See the README file for details, or visit http://0install.net.
7 from zeroinstall import _
8 import shutil, os, tempfile
9 from logging import info, warn
11 from zeroinstall import SafeException
12 from zeroinstall.support import basedir
13 from zeroinstall.injector import namespaces
15 _template = """[Desktop Entry]
16 # This file was generated by zero2desktop.
17 # See the Zero Install project for details: http://0install.net
18 Type=Application
19 Version=1.0
20 Name=%s
21 Comment=%s
22 Exec=0launch -- %s %%f
23 Categories=Application;%s
24 """
26 _icon_template = """Icon=%s
27 """
29 def add_to_menu(iface, icon_path, category):
30 """Write a .desktop file for this application.
31 @param iface: the program being added
32 @param icon_path: the path of the icon, or None
33 @param category: the freedesktop.org menu category"""
34 tmpdir = tempfile.mkdtemp(prefix = 'zero2desktop-')
35 try:
36 desktop_name = os.path.join(tmpdir, 'zeroinstall-%s.desktop' % iface.get_name().lower().replace(' ', ''))
37 desktop = file(desktop_name, 'w')
38 desktop.write(_template % (iface.get_name(), iface.summary, iface.uri, category))
39 if icon_path:
40 desktop.write(_icon_template % icon_path)
41 if len(iface.get_metadata(namespaces.XMLNS_IFACE, 'needs-terminal')):
42 desktop.write('Terminal=true\n')
43 desktop.close()
44 status = os.spawnlp(os.P_WAIT, 'xdg-desktop-menu', 'xdg-desktop-menu', 'install', desktop_name)
45 finally:
46 shutil.rmtree(tmpdir)
48 if status:
49 raise SafeException(_('Failed to run xdg-desktop-menu (error code %d)') % status)
51 def discover_existing_apps():
52 """Search through the configured XDG datadirs looking for .desktop files created by L{add_to_menu}.
53 @return: a map from application URIs to .desktop filenames"""
54 already_installed = {}
55 for d in basedir.load_data_paths('applications'):
56 for desktop_file in os.listdir(d):
57 if desktop_file.startswith('zeroinstall-') and desktop_file.endswith('.desktop'):
58 full = os.path.join(d, desktop_file)
59 try:
60 for line in file(full):
61 line = line.strip()
62 if line.startswith('Exec=0launch '):
63 bits = line.split(' -- ', 1)
64 if ' ' in bits[0]:
65 uri = bits[0].split(' ', 1)[1] # 0launch URI -- %u
66 else:
67 uri = bits[1].split(' ', 1)[0].strip() # 0launch -- URI %u
68 already_installed[uri] = full
69 break
70 else:
71 info(_("Failed to find Exec line in %s"), full)
72 except Exception, ex:
73 warn(_("Failed to load .desktop file %(filename)s: %(exceptions"), {'filename': full, 'exception': ex})
74 return already_installed