def remoteInstall(self, forcedUpdate=False, showMessages=False): """ Install the extension from the remote. This will call `extensionNeedsUpdate()` Optional set `forcedUpdate` to `True` if its needed to install the extension anyhow """ if self.isExtensionInstalled( ) and not self.extensionNeedsUpdate() and not forcedUpdate: # dont download and install if the current intall is newer (only when it forced) return # get the zip path zipPath = self.remoteZipPath() try: # try to download the zip file # and fail silently with a custom error message contents = getDataFromURL(zipPath) except Exception as e: message = "Could not download the extension zip file for: '%s'" % self.extensionName( ) logger.error(message) logger.error(e) raise ExtensionRepoError(message) # create a temp folder tempFolder = tempfile.mkdtemp() try: # try to extract the zip # and fail silently with a custom message with zipfile.ZipFile(BytesIO(contents)) as z: z.extractall(tempFolder) except Exception as e: message = "Could not extract the extension zip file for: '%s'" % self.extensionName( ) logger.error(message) logger.error(e) raise ExtensionRepoError(message) # find the extension path extensionPath = findExtensionInRoot( os.path.basename(self.extensionPath), tempFolder) if extensionPath: # if found get the bundle and install it bundle = ExtensionBundle(path=extensionPath) bundle.install(showMessages=showMessages) self.resetRemembered() else: # raise an custom error when the extension is not found in the zip message = "Could not find the extension: '%s'" % self.extensionPath logger.error(message) raise ExtensionRepoError(message) # remove the temp folder with the extracted zip shutil.rmtree(tempFolder)
def _remoteInstallCallback(self, url, data, error): if error: message = "Could not download the extension zip file for: '%s' at url: '%s'" % ( self.extensionName(), url) logger.error(message) logger.error(error) raise ExtensionRepoError(message) # create a temp folder tempFolder = tempfile.mkdtemp() try: # try to extract the zip # and fail silently with a custom message with zipfile.ZipFile(io.BytesIO(data.bytes())) as z: z.extractall(tempFolder) except Exception as e: message = "Could not extract the extension zip file for: '%s' at url: '%s'" % ( self.extensionName(), url) logger.error(message) logger.error(e) raise ExtensionRepoError(message) # find the extension path extensionPath = findExtensionInRoot( os.path.basename(self.extensionPath), tempFolder) if extensionPath: # if found get the bundle and install it bundle = ExtensionBundle(path=extensionPath) bundle.install(showMessages=self._showMessages) self.resetRemembered() else: # raise an custom error when the extension is not found in the zip message = "Could not find the extension: '%s'" % self.extensionPath logger.error(message) raise ExtensionRepoError(message) # remove the temp folder with the extracted zip shutil.rmtree(tempFolder) # clear the cache for this extension icon so it may be reloaded if self.extensionIconURL(): CachingURLReader.invalidate_cache_for_url(self.extensionIconURL()) self._extensionIcon = None self._needsUpdate = False postEvent(EXTENSION_DID_REMOTE_INSTALL_EVENT_KEY, item=self)
class Extension(object): """Facilitates loading the configuration from and updating extensions.""" @classmethod def all(cls): return [cls(name=n) for n in ExtensionBundle.allExtensions()] @classmethod def install_remote(cls, repository, filename): remote = GithubRepository(repository, filename) path = remote.download() extension = cls(path=path).install() shutil.rmtree(path) # TODO: removing the tree should happen after download somehow return extension def __init__(self, name=None, path=None): self.name = name self.bundle = ExtensionBundle(name=self.name, path=path) @evented() def update(self, path=None): """Download and install the latest version of the extension.""" if path is None: path = self.remote.download() Extension(path=path).install() @evented() def install(self): self.bundle.install() @evented() def uninstall(self): self.bundle.deinstall() @lazy_property def configuration(self): return Configuration(self.configuration_path) @lazy_property def remote(self): return GithubRepository(self.repository, self.filename) @property def is_current_version(self): """Return if extension is at curent version""" return self.remote.version <= self.version @property def is_ignored(self): return self.bundle.name in Storage.get('ignore') @property def is_configured(self): return self.repository is not None @property def is_installed(self): return self.bundle.bundleExists() @property def may_update(self): return not self.is_ignored and self.is_configured @property def should_update(self): return self.may_update and not self.is_current_version @property def configuration_path(self): return os.path.join(self.path, 'info.plist') @property def path(self): return self.bundle.bundlePath() @property def repository(self): return self.configuration.namespaced('repository') or \ self.configuration.deprecated('repository') @property def version(self): return Version(self.configuration['version']) @property def filename(self): return os.path.basename(self.bundle.bundlePath())