4 from xml
.dom
import minidom
6 import tempfile
, shutil
7 from zeroinstall
.injector
.model
import EnvironmentBinding
8 from zeroinstall
.injector
.iface_cache
import iface_cache
11 def iface_to_dir_name(iface
):
12 """Pick a directory name for this interface's implementation."""
13 return iface
.get_name().replace(' ', '_').replace('/', '-')
15 class BundleMaker(saving
.Saveable
):
16 def __init__(self
, policy
):
20 iface
= self
.policy
.get_interface(policy
.root
)
21 self
.icon
= iface_cache
.get_icon_path(iface
)
23 self
.impl
= self
.policy
.implementation
[iface
]
24 if hasattr(self
.impl
, 'main'):
25 self
.main
= self
.impl
.main
27 self
.main
= iface
.main
29 rox
.alert("Interface '%s' cannot be executed directly; it is just a library "
30 "to be used by other programs (or missing 'main' attribute on the "
31 "root <interface> element)." % iface
.name
)
33 def save_to_file(self
, path
):
35 assert "'" not in self
.policy
.root
37 apprun
= os
.fdopen(os
.open(os
.path
.join(path
, 'AppRun'), os
.O_CREAT | os
.O_WRONLY
, 0777), 'w')
38 apprun
.write("""#!/bin/sh
39 # This script was created automatically by Zero2Bundle
40 APP_DIR=`dirname "$0"`
43 iface
= self
.policy
.get_interface(self
.policy
.root
)
45 # Copy each implementation into the bundle and set any
46 # environment variables required to find it
48 for needed_iface
in self
.policy
.implementation
:
49 impl
= self
.policy
.implementation
[needed_iface
]
50 impl_copy
= os
.path
.join(path
, iface_to_dir_name(needed_iface
))
52 shutil
.copytree(self
.policy
.get_implementation_path(impl
), impl_copy
)
54 for dep
in impl
.dependencies
.values():
55 for b
in dep
.bindings
:
56 bindings
.append((dep
, b
))
58 for (dep
, binding
) in bindings
:
59 dep_iface
= self
.policy
.get_interface(dep
.interface
)
60 if isinstance(b
, EnvironmentBinding
):
61 dep_name
= os
.path
.join(iface_to_dir_name(dep_iface
), b
.insert
)
63 if [ "x$%s" = x ]; then
69 """ % (b
.name
, b
.name
, dep_name
, b
.name
, dep_name
, b
.name
, b
.name
))
70 dep_impl
= self
.policy
.get_implementation(dep_iface
)
72 print >>sys
.stderr
, "Warning: unknown binding type " + b
74 root_iface
= self
.policy
.get_interface(self
.policy
.root
)
75 root_impl
= self
.policy
.get_implementation(root_iface
)
77 impl_apprun
= os
.path
.join(iface_to_dir_name(root_iface
), root_impl
.main
)
78 apprun
.write('exec "$APP_DIR/%s" "$@"\n' % impl_apprun
)
83 shutil
.copyfile(self
.icon
, os
.path
.join(path
, '.DirIcon'))
85 if self
.is_applet(root_iface
):
86 os
.symlink('AppRun', os
.path
.join(path
, 'AppletRun'))
88 appinfo
= os
.path
.join(os
.path
.dirname(impl_apprun
), 'AppInfo.xml')
89 if os
.path
.exists(os
.path
.join(path
, appinfo
)):
90 os
.symlink(appinfo
, os
.path
.join(path
, 'AppInfo.xml'))
92 help = os
.path
.join(os
.path
.dirname(impl_apprun
), 'Help')
93 if os
.path
.exists(os
.path
.join(path
, help)):
94 os
.symlink(help, os
.path
.join(path
, 'Help'))
96 def add_item(self
, menu
, option
, labels
):
97 doc
= menu
.ownerDocument
98 item
= doc
.createElement('Item')
99 kids
= menu
.childNodes
101 menu
.insertBefore(item
, kids
[0])
103 menu
.appendChild(item
)
104 item
.setAttribute('option', option
)
107 label
= doc
.createElement('Label')
108 item
.appendChild(label
)
109 label
.setAttribute('xml:lang', lang
)
110 label
.appendChild(doc
.createTextNode(labels
[lang
]))
112 def get_item(self
, parent
, name
):
113 items
= parent
.getElementsByTagName(name
)
116 item
= parent
.ownerDocument
.createElement(name
)
117 parent
.appendChild(item
)
120 def is_applet(self
, iface
):
121 impl_path
= self
.policy
.get_implementation_path(self
.impl
)
124 applet_run
= os
.path
.join(impl_path
, os
.path
.dirname(self
.main
), 'AppletRun')
125 return os
.path
.exists(applet_run
)