def do_add(args): """add DIGEST (DIRECTORY | (ARCHIVE [EXTRACT]))""" from zeroinstall.zerostore import unpack if len(args) < 2: raise UsageError(_("Missing arguments")) digest = args[0] if os.path.isdir(args[1]): if len(args) > 2: raise UsageError(_("Too many arguments")) stores.add_dir_to_cache(digest, args[1]) elif os.path.isfile(args[1]): if len(args) > 3: raise UsageError(_("Too many arguments")) if len(args) > 2: extract = args[2] else: extract = None type = unpack.type_from_url(args[1]) if not type: raise SafeException( _("Unknown extension in '%s' - can't guess MIME type") % args[1]) unpack.check_type_ok(type) with open(args[1], 'rb') as stream: stores.add_archive_to_cache(digest, stream, args[1], extract, type=type) else: try: os.stat(args[1]) except OSError as ex: if ex.errno != errno.ENOENT: # No such file or directory raise UsageError(str(ex)) # E.g. permission denied raise UsageError(_("No such file or directory '%s'") % args[1])
def do_add(args): """add DIGEST (DIRECTORY | (ARCHIVE [EXTRACT]))""" from zeroinstall.zerostore import unpack if len(args) < 2: raise UsageError(_("Missing arguments")) digest = args[0] if os.path.isdir(args[1]): if len(args) > 2: raise UsageError(_("Too many arguments")) stores.add_dir_to_cache(digest, args[1]) elif os.path.isfile(args[1]): if len(args) > 3: raise UsageError(_("Too many arguments")) if len(args) > 2: extract = args[2] else: extract = None type = unpack.type_from_url(args[1]) if not type: raise SafeException(_("Unknown extension in '%s' - can't guess MIME type") % args[1]) unpack.check_type_ok(type) with open(args[1], 'rb') as stream: stores.add_archive_to_cache(digest, stream, args[1], extract, type = type) else: try: os.stat(args[1]) except OSError as ex: if ex.errno != errno.ENOENT: # No such file or directory raise UsageError(str(ex)) # E.g. permission denied raise UsageError(_("No such file or directory '%s'") % args[1])
def download_archive(self, download_source, force = False, impl_hint = None, may_use_mirror = False): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too. It is the caller's responsibility to ensure that the returned stream is closed. If impl_hint is from a local feed and the url is relative, just opens the existing file for reading. @type download_source: L{model.DownloadSource} @type force: bool @type may_use_mirror: bool @rtype: (L{Blocker} | None, file)""" from zeroinstall.zerostore import unpack mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException(_("No 'type' attribute on archive, and I can't guess from the name (%s)") % download_source.url) if not self.external_store: unpack.check_type_ok(mime_type) if '://' not in download_source.url: return self._download_local_file(download_source, impl_hint) if may_use_mirror: mirror = self._get_archive_mirror(download_source) else: mirror = None if self.config.handler.dry_run: print(_("[dry-run] downloading archive {url}").format(url = download_source.url)) dl = self.download_url(download_source.url, hint = impl_hint, mirror_url = mirror) if download_source.size is not None: dl.expected_size = download_source.size + (download_source.start_offset or 0) # (else don't know sizes for mirrored archives) return (dl.downloaded, dl.tempfile)
def download_archive(self, download_source, force=False, impl_hint=None, may_use_mirror=False): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too. It is the caller's responsibility to ensure that the returned stream is closed. """ from zeroinstall.zerostore import unpack url = download_source.url if not (url.startswith("http:") or url.startswith("https:") or url.startswith("ftp:")): raise SafeException(_("Unknown scheme in download URL '%s'") % url) mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException( _("No 'type' attribute on archive, and I can't guess from the name (%s)") % download_source.url ) if not self.external_store: unpack.check_type_ok(mime_type) if may_use_mirror: mirror = self._get_archive_mirror(download_source) else: mirror = None dl = self.download_url(download_source.url, hint=impl_hint, mirror_url=mirror) if download_source.size is not None: dl.expected_size = download_source.size + (download_source.start_offset or 0) # (else don't know sizes for mirrored archives) return (dl.downloaded, dl.tempfile)
def _add_to_external_store(self, required_digest, steps, streams): """@type required_digest: str""" from zeroinstall.zerostore.unpack import type_from_url # combine archive path, extract directory and MIME type arguments in an alternating fashion paths = map(lambda stream: stream.name, streams) extracts = map(lambda step: step.extract or "", steps) types = map(lambda step: step.type or type_from_url(step.url), steps) args = [None]*(len(paths)+len(extracts)+len(types)) args[::3] = paths args[1::3] = extracts args[2::3] = types # close file handles to allow external processes access for stream in streams: stream.close() # delegate extracting archives to external tool import subprocess retval = subprocess.call([self.external_store, "add", required_digest] + args) # delete temp files for path in paths: os.remove(path) if retval != 0: raise SafeException(_("Extracting with external store failed"))
def download_archive(self, download_source, force = False, impl_hint = None, may_use_mirror = False): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too. It is the caller's responsibility to ensure that the returned stream is closed. """ from zeroinstall.zerostore import unpack url = download_source.url if not (url.startswith('http:') or url.startswith('https:') or url.startswith('ftp:')): raise SafeException(_("Unknown scheme in download URL '%s'") % url) mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException(_("No 'type' attribute on archive, and I can't guess from the name (%s)") % download_source.url) if not self.external_store: unpack.check_type_ok(mime_type) if may_use_mirror: mirror = self._get_archive_mirror(download_source) else: mirror = None dl = self.download_url(download_source.url, hint = impl_hint, mirror_url = mirror) if download_source.size is not None: dl.expected_size = download_source.size + (download_source.start_offset or 0) # (else don't know sizes for mirrored archives) return (dl.downloaded, dl.tempfile)
def unpack_to_tmp(url, archive_file, mime_type): """Creates a temporary directory and unpacks the archive to it in "unpacked". Permissions are correct for importing into the cache. Returns the tmpdir.""" if not mime_type: mime_type = unpack.type_from_url(url) assert mime_type, "Can't guess MIME type from {url}".format(url = url) tmpdir = tempfile.mkdtemp('-0template') try: # Must be readable to helper process running as 'zeroinst'... old_umask = os.umask(0o022) try: unpack_dir = os.path.join(tmpdir, 'unpacked') os.mkdir(unpack_dir) with open(archive_file, 'rb') as stream: unpack.unpack_archive(url, stream, unpack_dir, type = mime_type, start_offset = 0) manifest.fixup_permissions(unpack_dir) finally: os.umask(old_umask) except: support.ro_rmtree(tmpdir) raise return tmpdir
def download_archive(self, download_source, force = False, impl_hint = None, may_use_mirror = False): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too. It is the caller's responsibility to ensure that the returned stream is closed. If impl_hint is from a local feed and the url is relative, just opens the existing file for reading. @type download_source: L{model.DownloadSource} @type force: bool @type may_use_mirror: bool @rtype: (L{Blocker} | None, file)""" from zeroinstall.zerostore import unpack mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException(_("No 'type' attribute on archive, and I can't guess from the name (%s)") % download_source.url) if not self.external_store: unpack.check_type_ok(mime_type) if '://' not in download_source.url: # Relative path if impl_hint is None or not impl_hint.feed.local_path: raise SafeException(_("Relative URL '{url}' in non-local feed '{feed}'").format( url = download_source.url, feed = impl_hint.feed)) archive_file = os.path.join(os.path.dirname(impl_hint.feed.local_path), download_source.url) try: size = os.path.getsize(archive_file) if size != download_source.size: raise SafeException(_("Wrong size for {path}: feed says {expected}, but actually {actual} bytes").format( path = archive_file, expected = download_source.size, actual = size)) return (None, open(archive_file, 'rb')) except OSError as ex: raise SafeException(str(ex)) # (error already includes path) if may_use_mirror: mirror = self._get_archive_mirror(download_source) else: mirror = None if self.config.handler.dry_run: print(_("[dry-run] downloading archive {url}").format(url = download_source.url)) dl = self.download_url(download_source.url, hint = impl_hint, mirror_url = mirror) if download_source.size is not None: dl.expected_size = download_source.size + (download_source.start_offset or 0) # (else don't know sizes for mirrored archives) return (dl.downloaded, dl.tempfile)
def download_archive(self, download_source, force = False, impl_hint = None): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too.""" from zeroinstall.zerostore import unpack url = download_source.url if not (url.startswith('http:') or url.startswith('https:') or url.startswith('ftp:')): raise SafeException(_("Unknown scheme in download URL '%s'") % url) mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException(_("No 'type' attribute on archive, and I can't guess from the name (%s)") % download_source.url) unpack.check_type_ok(mime_type) dl = self.download_url(download_source.url, hint = impl_hint) dl.expected_size = download_source.size + (download_source.start_offset or 0) return (dl.downloaded, dl.tempfile)
def download_archive(self, download_source, force=False, impl_hint=None): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too.""" from zeroinstall.zerostore import unpack url = download_source.url if not (url.startswith('http:') or url.startswith('https:') or url.startswith('ftp:')): raise SafeException(_("Unknown scheme in download URL '%s'") % url) mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException( _("No 'type' attribute on archive, and I can't guess from the name (%s)" ) % download_source.url) unpack.check_type_ok(mime_type) dl = self.download_url(download_source.url, hint=impl_hint) dl.expected_size = download_source.size + (download_source.start_offset or 0) return (dl.downloaded, dl.tempfile)
def download_archive(self, download_source, force=False, impl_hint=None, may_use_mirror=False): """Fetch an archive. You should normally call L{download_impl} instead, since it handles other kinds of retrieval method too. It is the caller's responsibility to ensure that the returned stream is closed. If impl_hint is from a local feed and the url is relative, just opens the existing file for reading. @type download_source: L{model.DownloadSource} @type force: bool @type may_use_mirror: bool @rtype: (L{Blocker} | None, file)""" from zeroinstall.zerostore import unpack mime_type = download_source.type if not mime_type: mime_type = unpack.type_from_url(download_source.url) if not mime_type: raise SafeException( _("No 'type' attribute on archive, and I can't guess from the name (%s)" ) % download_source.url) if not self.external_store: unpack.check_type_ok(mime_type) if '://' not in download_source.url: # Relative path if impl_hint is None or not impl_hint.feed.local_path: raise SafeException( _("Relative URL '{url}' in non-local feed '{feed}'"). format(url=download_source.url, feed=impl_hint.feed)) archive_file = os.path.join( os.path.dirname(impl_hint.feed.local_path), download_source.url) try: size = os.path.getsize(archive_file) if size != download_source.size: raise SafeException( _("Wrong size for {path}: feed says {expected}, but actually {actual} bytes" ).format(path=archive_file, expected=download_source.size, actual=size)) return (None, open(archive_file, 'rb')) except OSError as ex: raise SafeException(str(ex)) # (error already includes path) if may_use_mirror: mirror = self._get_archive_mirror(download_source) else: mirror = None if self.config.handler.dry_run: print( _("[dry-run] downloading archive {url}").format( url=download_source.url)) dl = self.download_url(download_source.url, hint=impl_hint, mirror_url=mirror) if download_source.size is not None: dl.expected_size = download_source.size + ( download_source.start_offset or 0) # (else don't know sizes for mirrored archives) return (dl.downloaded, dl.tempfile)
def local_archive_changed(chooser): model.clear() path = chooser.get_filename() widgets.get_widget('subdirectory_frame').set_sensitive(False) self.destroy_tmp() if not path: return if mime_type.get_active() == 0: type = None else: type = mime_type.get_active_text() archive_url = widgets.get_widget('archive_url') url = archive_url.get_text() if not url: url = 'http://SITE/' + os.path.basename(path) archive_url.set_text(url) start_offset = 0 if not type: if url.endswith('.package'): type = 'Autopackage' else: type = unpack.type_from_url(url) if type == 'Autopackage': # Autopackage isn't a real type. Examine the .package file # and find out what it really is. start_offset, type = autopackage_get_details(path) self.tmpdir = tempfile.mkdtemp('-0publish-gui') try: # Must be readable to helper process running as 'zeroinst'... old_umask = os.umask(0022) try: unpack_dir = os.path.join(self.tmpdir, 'unpacked') os.mkdir(unpack_dir) dialog.window.set_cursor(watch) gtk.gdk.flush() try: unpack.unpack_archive(url, file(path), unpack_dir, type = type, start_offset = start_offset) manifest.fixup_permissions(unpack_dir) finally: dialog.window.set_cursor(None) finally: os.umask(old_umask) except: chooser.unselect_filename(path) self.destroy_tmp() raise iter = model.append(None, ['Everything']) items = os.listdir(unpack_dir) for f in items: model.append(iter, [f]) tree.expand_all() # Choose a sensible default iter = model.get_iter_root() if len(items) == 1 and \ os.path.isdir(os.path.join(unpack_dir, items[0])) and \ items[0] not in ('usr', 'opt', 'bin', 'etc', 'sbin', 'doc', 'var'): iter = model.iter_children(iter) selection.select_iter(iter) self.mime_type = type self.start_offset = start_offset widgets.get_widget('subdirectory_frame').set_sensitive(True)