1 """Adding icons and menu items using the freedesktop.org system.
2 (xdg = X Desktop Group)
4 # Copyright (C) 2008, Thomas Leonard
5 # See the README file for details, or visit http://0install.net.
7 import shutil
, os
, tempfile
8 from logging
import info
, warn
10 from zeroinstall
import SafeException
11 from zeroinstall
.support
import basedir
13 _template
= """[Desktop Entry]
14 # This file was generated by zero2desktop.
15 # See the Zero Install project for details: http://0install.net
20 Exec=0launch -- %s %%f
21 Categories=Application;%s
24 _icon_template
= """Icon=%s
27 def add_to_menu(iface
, icon_path
, category
):
28 """Write a .desktop file for this application.
29 @param iface: the program being added
30 @param icon_path: the path of the icon, or None
31 @param category: the freedesktop.org menu category"""
32 tmpdir
= tempfile
.mkdtemp(prefix
= 'zero2desktop-')
34 desktop_name
= os
.path
.join(tmpdir
, 'zeroinstall-%s.desktop' % iface
.get_name().lower().replace(' ', ''))
35 desktop
= file(desktop_name
, 'w')
36 desktop
.write(_template
% (iface
.get_name(), iface
.summary
, iface
.uri
, category
))
38 desktop
.write(_icon_template
% icon_path
)
40 status
= os
.spawnlp(os
.P_WAIT
, 'xdg-desktop-menu', 'xdg-desktop-menu', 'install', desktop_name
)
45 raise SafeException('Failed to run xdg-desktop-menu (error code %d)' % status
)
47 def discover_existing_apps():
48 """Search through the configured XDG datadirs looking for .desktop files created by L{add_to_menu}.
49 @return: a map from application URIs to .desktop filenames"""
50 already_installed
= {}
51 for d
in basedir
.load_data_paths('applications'):
52 for desktop_file
in os
.listdir(d
):
53 if desktop_file
.startswith('zeroinstall-') and desktop_file
.endswith('.desktop'):
54 full
= os
.path
.join(d
, desktop_file
)
56 for line
in file(full
):
58 if line
.startswith('Exec=0launch '):
59 bits
= line
.split(' -- ', 1)
61 uri
= bits
[0].split(' ', 1)[1] # 0launch URI -- %u
63 uri
= bits
[1].split(' ', 1)[0].strip() # 0launch -- URI %u
64 already_installed
[uri
] = full
67 info("Failed to find Exec line in %s", full
)
69 warn("Failed to load .desktop file %s: %s", full
, ex
)
70 return already_installed