Removed debugging prints.
[AddApp.git] / AddApp / launcher.py
blobeab143846e165afd7335891840260512401a50d9
1 from zeroinstall.injector import policy
2 import os, shutil
3 import rox
4 from rox import saving
5 from xml.dom import minidom
6 import urllib2
7 import tempfile, shutil
9 addapp_uri = "http://rox.sourceforge.net/2005/interfaces/AddApp"
11 class Policy(policy.Policy):
12 pass
14 class AppLauncher(saving.Saveable):
15 def __init__(self, uri):
16 self.uri = uri
17 self.icon = None
19 self.policy = Policy(uri)
20 self.policy.recalculate()
21 iface = self.policy.get_interface(uri)
22 if not iface.main:
23 rox.alert("Interface '%s' cannot be executed directly; it is just a library "
24 "to be used by other programs (or missing 'main' attribute on the "
25 "root <interface> element)." % iface.name)
27 def save_to_file(self, path):
28 os.mkdir(path)
29 assert "'" not in self.uri
30 apprun = os.fdopen(os.open(os.path.join(path, 'AppRun'), os.O_CREAT | os.O_WRONLY, 0777), 'w')
31 if self.uri == 'http://rox.sourceforge.net/2005/interfaces/AddApp':
32 # Funky special case: AddApp behaves differently when run through AppRun
33 apprun.write("""#!/bin/sh
34 if [ "$*" = "--versions" ]; then
35 exec 0launch -gd '%s' "$@"
36 elif [ "$*" = "" ]; then
37 exec 0launch '%s' --prompt
38 elif [ "$*" = "--help" ]; then
39 exec 0launch '%s' --show-help '%s'
40 else
41 exec 0launch '%s' "$@"
42 fi""" % (self.uri, self.uri, addapp_uri, self.uri, self.uri))
43 else:
44 apprun.write("""#!/bin/sh
45 if [ "$*" = "--versions" ]; then
46 exec 0launch -gd '%s' "$@"
47 elif [ "$*" = "--help" ]; then
48 exec 0launch '%s' --show-help '%s'
49 else
50 exec 0launch '%s' "$@"
51 fi""" % (self.uri, addapp_uri, self.uri, self.uri))
53 apprun.close()
54 if self.icon:
55 shutil.copyfile(self.icon.name, os.path.join(path, '.DirIcon'))
57 iface = self.policy.get_interface(self.uri)
58 if iface.name and iface.summary and \
59 isinstance(iface.name, basestring) and \
60 isinstance(iface.summary, basestring):
61 tooltip = ''.join([iface.name, " -- ", iface.summary,
62 "\n(", self.uri, ")"])
63 elif iface.name and isinstance(iface.name, basestring):
64 tooltip = ''.join([iface.name, " (", self.uri, ")"])
65 else:
66 tooltip = self.uri
68 doc = minidom.parseString("""<?xml version="1.0"?>
69 <AppInfo>
70 <AppMenu>
71 <Item option='--help'>
72 <Label xml:lang="en">Help</Label>
73 </Item>
74 <Item option='--versions'>
75 <Label xml:lang="en">Versions...</Label>
76 </Item>
77 </AppMenu>
78 <Summary xml:lang="en"/>
79 </AppInfo>
80 """)
81 summary, = doc.documentElement.getElementsByTagName('Summary')
82 summary.appendChild(doc.createTextNode(tooltip))
83 info_file = file(os.path.join(path, 'AppInfo.xml'), 'w')
84 doc.writexml(info_file)
85 info_file.close()
87 if self.is_applet(iface):
88 appletrun = os.fdopen(os.open(os.path.join(path, 'AppletRun'),
89 os.O_CREAT | os.O_WRONLY, 0777), 'w')
90 appletrun.write("""#!/bin/sh
91 exec 0launch --main=AppletRun '%s' "$@"
92 """ % self.uri)
93 appletrun.close()
95 def is_applet(self, iface):
96 impl = self.policy.implementation[iface]
97 assert impl
98 impl_path = self.policy.get_implementation_path(impl)
99 assert impl_path
101 applet_run = os.path.join(impl_path, os.path.dirname(iface.main), 'AppletRun')
102 return os.path.exists(applet_run)
105 def get_icon(self):
106 """Returns a GdkPixbuf icon for the app (downloading it first), or None."""
107 from zeroinstall.injector import reader, model, basedir, namespaces
108 cached = basedir.load_first_cache(namespaces.config_site, 'interfaces', model.escape(self.uri))
109 if not cached:
110 print >>sys.stderr, "Internal error: interface '%s' still not cached!" % self.uri
111 return None
112 from xml.dom import minidom
113 doc = minidom.parse(cached)
114 names = doc.documentElement.getElementsByTagNameNS(namespaces.XMLNS_IFACE, 'icon')
115 for x in names:
116 type = x.getAttribute('type')
117 if str(type) != 'image/png':
118 print "Skipping unknown icon type '%s'" % type
119 continue
120 icon_uri = x.getAttribute('href')
121 print "Downloading icon from", icon_uri
122 try:
123 icon_data = urllib2.urlopen(icon_uri)
124 except:
125 rox.report_exception()
126 return
127 tmp = tempfile.NamedTemporaryFile()
128 shutil.copyfileobj(icon_data, tmp)
129 icon_data.close()
130 tmp.flush()
132 self.icon = tmp
134 def delete_icon(self):
135 """Remove the temporary icon file, if any"""
136 self.icon = None