📄 launcher.py
字号:
from zeroinstall.injector import policy, namespacesimport os, shutil, sysimport roxfrom rox import savingfrom xml.dom import minidomimport urllib2import tempfile, shutiladdapp_uri = "http://rox.sourceforge.net/2005/interfaces/AddApp"class Policy(policy.Policy): passclass NoMain(Exception): passclass AppLauncher(saving.Saveable): def __init__(self, uri): self.uri = uri self.icon = None self._icon_tmp = None self.policy = Policy(uri) self.policy.freshness = 0 # No further updates self.policy.recalculate() iface = self.policy.get_interface(uri) self.impl = self.policy.implementation[iface] if hasattr(self.impl, 'main'): self.main = self.impl.main else: self.main = iface.main if not self.main: raise NoMain("Interface '%s' cannot be executed directly; it is just a library " "to be used by other programs (or missing 'main' attribute on the " "root <interface> element)." % iface.name) def save_to_file(self, path): os.mkdir(path) assert "'" not in self.uri iface = self.policy.get_interface(self.uri) apprun = os.fdopen(os.open(os.path.join(path, 'AppRun'), os.O_CREAT | os.O_WRONLY, 0777), 'w') if self.uri == 'http://rox.sourceforge.net/2005/interfaces/AddApp': # Funky special case: AddApp behaves differently when run through AppRun apprun.write("""#!/bin/shif [ "$*" = "--versions" ]; then exec 0launch -gd '%s'elif [ "$*" = "" ]; then exec 0launch '%s' --promptelif [ "$*" = "--help" ]; then exec 0launch '%s' --show-help '%s'else exec 0launch '%s' -- "$@"fi""" % (self.uri, self.uri, addapp_uri, self.uri, self.uri)) else: if len(iface.get_metadata(namespaces.XMLNS_IFACE, 'needs-terminal')): xterm = addapp_uri + ' --run-in-terminal ' else: xterm = '' apprun.write("""#!/bin/shif [ "$*" = "--versions" ]; then exec 0launch -gd '%(uri)s'elif [ "$*" = "--help" ]; then exec 0launch '%(addapp)s' --show-help '%(uri)s'else exec 0launch %(xterm)s'%(uri)s' "$@"fi""" % {'uri': self.uri, 'addapp': addapp_uri, 'xterm': xterm}) apprun.close() if self.icon: shutil.copyfile(self.icon, os.path.join(path, '.DirIcon')) doc = self.get_appinfo(iface) info_file = file(os.path.join(path, 'AppInfo.xml'), 'w') doc.writexml(info_file) info_file.close() if self.is_applet(iface): appletrun = os.fdopen(os.open(os.path.join(path, 'AppletRun'), os.O_CREAT | os.O_WRONLY, 0777), 'w') appletrun.write("""#!/bin/shexec 0launch --main=AppletRun '%s' "$@"""" % self.uri) appletrun.close() def get_appinfo(self, iface): impl_path = self.get_impl_path(self.impl) if impl_path: appinfo = os.path.join(impl_path, os.path.dirname(self.main), 'AppInfo.xml') else: appinfo = None if appinfo and os.path.exists(appinfo): doc = minidom.parse(appinfo) else: doc = minidom.parseString("<?xml version='1.0'?>\n<AppInfo/>") root = doc.documentElement appmenu = self.get_item(root, 'AppMenu') self.add_item(appmenu, '--versions', {'en': 'Versions...'}) self.add_item(appmenu, '--help', {'en': 'Help'}) if not root.getElementsByTagName('Summary'): summary = doc.createElement('Summary') summary.appendChild(doc.createTextNode('%s -- %s' % (iface.name, iface.summary))) root.appendChild(summary) for summary in root.getElementsByTagName('Summary'): summary.appendChild(doc.createTextNode('\n(%s)' % iface.uri)) for about in root.getElementsByTagName('About'): for version in about.getElementsByTagName('Version'): if not version.childNodes: continue for c in version.childNodes: version.removeChild(c) version.appendChild(doc.createTextNode('(launcher)')) return doc def add_item(self, menu, option, labels): doc = menu.ownerDocument item = doc.createElement('Item') kids = menu.childNodes if kids: menu.insertBefore(item, kids[0]) else: menu.appendChild(item) item.setAttribute('option', option) for lang in labels: label = doc.createElement('Label') item.appendChild(label) label.setAttribute('xml:lang', lang) label.appendChild(doc.createTextNode(labels[lang])) def get_item(self, parent, name): items = parent.getElementsByTagName(name) if items: return items[0] item = parent.ownerDocument.createElement(name) parent.appendChild(item) return item def get_impl_path(self, impl): if impl.id.startswith('.') or impl.id.startswith('/'): return impl.id elif impl.id.startswith('package:'): return None else: impl_path = self.policy.get_implementation_path(impl) assert impl_path return impl_path def is_applet(self, iface): impl_path = self.get_impl_path(self.impl) if impl_path: applet_run = os.path.join(impl_path, os.path.dirname(self.main), 'AppletRun') return os.path.exists(applet_run) else: return False def get_icon(self): """Sets self.icon to a filename of an icon for the app (downloading it first), or None.""" from zeroinstall.injector.iface_cache import iface_cache if hasattr(iface_cache, 'get_icon_path'): iface = self.policy.get_interface(self.uri) path = iface_cache.get_icon_path(iface) if path: self.icon = path return from zeroinstall.injector import reader, model, basedir, namespaces if self.uri.startswith('/'): cached = self.uri else: cached = basedir.load_first_cache(namespaces.config_site, 'interfaces', model.escape(self.uri)) if not cached: print >>sys.stderr, "Internal error: interface '%s' still not cached!" % self.uri return from xml.dom import minidom doc = minidom.parse(cached) names = doc.documentElement.getElementsByTagNameNS(namespaces.XMLNS_IFACE, 'icon') for x in names: type = x.getAttribute('type') if str(type) != 'image/png': print "Skipping unknown icon type '%s'" % type continue icon_uri = x.getAttribute('href') print "Downloading icon from", icon_uri try: icon_data = urllib2.urlopen(icon_uri) except: rox.report_exception() return tmp = tempfile.NamedTemporaryFile() shutil.copyfileobj(icon_data, tmp) icon_data.close() tmp.flush() self._icon_tmp = tmp self.icon = tmp.name def delete_icon(self): """Remove the temporary icon file, if any""" self._icon_tmp = None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -