def _upgrade(self, callback): """ Met à jour l'application Arguments : callback : fonction de signature def callback(application, type, progress, message, end=False) application : application installée type : type d'opération progress : Avancement (sur 100) message : message décrivant l'opération en cours end : True si l'opération est terminée, False sinon """ if self.is_installed() and not self.is_up_to_date(): logger.info(u"Mise à jour du paquet %s." % (self.id,)) current_step = 0 if os.path.isfile(self.uri): # Le paquet est un fichier local filename = self.uri steps = 3 else: steps = 4 filename = "./cache/tmp/" + self.id + ".fmk.zip" logger.debug(u"Téléchargement du paquet.") try: urllib.urlretrieve( self.uri, filename, lambda c, b, t: callback( self, "upgrade", 100 * (current_step * t + c * b) / (t * steps), u"Téléchargement du paquet" ), ) except (urllib2.URLError, urllib2.HTTPError) as e: logger.error(u"Erreur lors du téléchargement:\n" u"".join(traceback.format_exc())) raise PackageDownloadError(self, e) current_step += 1 logger.debug(u"Suppression de l'ancienne version.") callback(self, "upgrade", 100 * current_step / steps, u"Suppression de l'ancienne version") # TODO (?) : Progression try: infos = self._get_installation_infos(filename) except Exception as e: logger.error(u"Le paquet %s est invalide:\n" % (self.id,) + u"".join(traceback.format_exc())) raise InvalidPackage(self, e) for f in infos["remove"]["files"]: os.remove(os.path.join(self.database.get_config("rootpath"), infos["application_root"], f)) for f in infos["preserve"]["files"]: src = os.path.join(self.database.get_config("rootpath"), infos["application_root"], f) dst = os.path.join("./cache/tmp", self.id, f) if os.path.isfile(src): if not os.path.isdir(os.path.dirname(dst)): os.makedirs(os.path.dirname(dst)) os.rename(src, dst) for d in infos["remove"]["dirs"]: rmtree(os.path.join(self.database.get_config("rootpath"), infos["application_root"], d)) for d in infos["preserve"]["dirs"]: src = os.path.join(self.database.get_config("rootpath"), infos["application_root"], d) dst = os.path.join("./cache/tmp", self.id, d) if os.path.isfile(src): if not os.path.isdir(os.path.dirname(dst)): os.makedirs(os.path.dirname(dst)) os.rename(src, dst) for d in infos["remove"]["main"]: rmtree(os.path.join(self.database.get_config("rootpath"), infos["application_root"], d)) logger.debug(u"Extraction du paquet.") current_step += 1 backupfiles = [] for root, dirnames, filenames in os.walk(os.path.join("./cache/tmp", self.id)): for f in filenames: backupfiles.append(os.path.relpath(os.path.join(root, f), os.path.join("./cache/tmp", self.id))) try: zipextractall( filename, os.path.join(self.database.get_config("rootpath"), infos["install_dir"]), lambda c, t: callback( self, "upgrade", 100 * (current_step * t + c) / (t * steps), u"Extraction du paquet" ), exclude=backupfiles, ) except Exception as e: logger.error(u"Le paquet %s est invalide:\n" % (self.id,) + u"".join(traceback.format_exc())) raise InvalidPackage(self, e) logger.debug(u"Copie de la sauvegarde") current_step += 1 for f in backupfiles: src = os.path.join("./cache/tmp", self.id, f) dst = os.path.join(self.database.get_config("rootpath"), infos["application_root"], f) if os.path.isfile(src): if not os.path.isdir(os.path.dirname(dst)): os.makedirs(os.path.dirname(dst)) os.rename(src, dst) rmtree(os.path.join("./cache/tmp", self.id)) logger.debug(u"Suppression du paquet.") os.remove(filename) logger.debug(u"Copie des informations dans le cache.") cache = os.path.join("./cache/installed/", self.id) appinfo = os.path.join(self.database.get_config("rootpath"), infos["application_root"], "App", "AppInfo") installed_as = self.get_installed_as() # Copie dans le cache rmtree(cache) os.mkdir(cache) if os.path.isdir(appinfo): for i in os.listdir(appinfo): shutil.copy(os.path.join(appinfo, i), cache) # Modification du fichier installer.ini self._set_installed_as(installed_as) callback(self, "upgrade", 100, u"Mise à jour terminée", True)
def _install(self, callback, explicit): """ Installe l'application (sans dépendances, sans vérifications) Arguments : callback : fonction de signature def callback(application, type, progress, message, end=False) application : application installée type : type d'opération progress : Avancement (sur 100) message : message décrivant l'opération en cours end : True si l'opération est terminée, False sinon explicit : True si l'application est installée explicitement, False si elle est installée en tant que dépendance. """ if not self.is_installed(): logger.info(u"Installation du paquet %s." % (self.id,)) current_step = 0 if os.path.isfile(self.uri): # Le paquet est un fichier local filename = self.uri steps = 1 else: steps = 2 filename = "./cache/tmp/" + self.id + ".fmk.zip" logger.debug(u"Téléchargement du paquet.") try: urllib.urlretrieve( self.uri, filename, lambda c, b, t: callback( self, "install", 100 * (current_step * t + c * b) / (t * steps), u"Téléchargement du paquet" ), ) except (urllib2.URLError, urllib2.HTTPError) as e: logger.error(u"Erreur lors du téléchargement:\n" u"".join(traceback.format_exc())) raise PackageDownloadError(self, e) current_step += 1 logger.debug(u"Extraction du paquet.") try: infos = self._get_installation_infos(filename) zipextractall( filename, os.path.join(self.database.get_config("rootpath"), infos["install_dir"]), lambda c, t: callback( self, "install", 100 * (current_step * t + c) / (t * steps), u"Extraction du paquet" ), ) except Exception as e: logger.error(u"Le paquet %s est invalide:\n" % (self.id,) + u"".join(traceback.format_exc())) raise InvalidPackage(self, e) logger.debug(u"Suppression du paquet.") os.remove(filename) logger.debug(u"Copie des informations dans le cache.") cache = os.path.join("./cache/installed/", self.id) appinfo = os.path.join(self.database.get_config("rootpath"), infos["application_root"], "App", "AppInfo") # Copie dans le cache os.mkdir(cache) if os.path.isdir(appinfo): for i in os.listdir(appinfo): shutil.copy(os.path.join(appinfo, i), cache) # Modification du fichier installer.ini if explicit: self._set_installed_as("explicit") else: self._set_installed_as("depend") callback(self, "install", 100, u"Installation terminée", True)