예제 #1
0
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])
예제 #2
0
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])
예제 #3
0
	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)
예제 #4
0
    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)
예제 #5
0
	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"))
예제 #6
0
파일: fetch.py 프로젝트: timdiels/0install
	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)
예제 #7
0
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
예제 #8
0
파일: fetch.py 프로젝트: rammstein/0install
	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)
예제 #9
0
파일: fetch.py 프로젝트: rammstein/0install
	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"))
예제 #10
0
	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)
예제 #11
0
	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)
예제 #12
0
    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)
예제 #13
0
    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)
예제 #14
0
		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)