1 """Adding icons and menu items using the freedesktop.org system.
2 (xdg = X Desktop Group)
4 # Copyright (C) 2009, Thomas Leonard
5 # See the README file for details, or visit http://0install.net.
7 from zeroinstall
import _
, logger
8 import shutil
, os
, tempfile
10 from zeroinstall
import SafeException
11 from zeroinstall
.support
import basedir
12 from zeroinstall
.injector
import namespaces
14 _template
= """[Desktop Entry]
15 # This file was generated by 0install.
16 # See the Zero Install project for details: http://0install.net
21 Exec=%(0launch)s -- %(iface)s %%f
22 Categories=Application;%(category)s
25 _icon_template
= """Icon=%s
28 def add_to_menu(iface
, icon_path
, category
, zlaunch
=None):
29 """Write a .desktop file for this application.
30 @param iface: the program being added
31 @param icon_path: the path of the icon, or None
32 @param category: the freedesktop.org menu category"""
33 tmpdir
= tempfile
.mkdtemp(prefix
= 'zero2desktop-')
35 desktop_name
= os
.path
.join(tmpdir
, 'zeroinstall-%s.desktop' % iface
.get_name().lower().replace(os
.sep
, '-').replace(' ', ''))
36 desktop
= open(desktop_name
, 'w')
37 desktop
.write(_template
% {'name': iface
.get_name(),
38 'comment': iface
.summary
,
39 '0launch': zlaunch
or '0launch',
41 'category': category
})
43 desktop
.write(_icon_template
% icon_path
)
44 if len(iface
.get_metadata(namespaces
.XMLNS_IFACE
, 'needs-terminal')):
45 desktop
.write('Terminal=true\n')
47 status
= os
.spawnlp(os
.P_WAIT
, 'xdg-desktop-menu', 'xdg-desktop-menu', 'install', desktop_name
)
52 raise SafeException(_('Failed to run xdg-desktop-menu (error code %d)') % status
)
54 def discover_existing_apps():
55 """Search through the configured XDG datadirs looking for .desktop files created by L{add_to_menu}.
56 @return: a map from application URIs to .desktop filenames"""
57 already_installed
= {}
58 for d
in basedir
.load_data_paths('applications'):
59 for desktop_file
in os
.listdir(d
):
60 if desktop_file
.startswith('zeroinstall-') and desktop_file
.endswith('.desktop'):
61 full
= os
.path
.join(d
, desktop_file
)
63 for line
in open(full
):
65 if line
.startswith('Exec=0launch '):
66 bits
= line
.split(' -- ', 1)
68 uri
= bits
[0].split(' ', 1)[1] # 0launch URI -- %u
70 uri
= bits
[1].split(' ', 1)[0].strip() # 0launch -- URI %u
71 already_installed
[uri
] = full
74 logger
.info(_("Failed to find Exec line in %s"), full
)
75 except Exception as ex
:
76 logger
.warn(_("Failed to load .desktop file %(filename)s: %(exceptions"), {'filename': full
, 'exception': ex
})
77 return already_installed