Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 25/04/2015, à 09:08

papy88140

[Script / Python] À tester : sauvegarde facile ... où pas ;-)

Bonjour les ubunteros,

Je vous propose de tester la sauvegarde "nouvelle génération" wink. j'ai créé un paquet .deb pour l'installation facile, il est disponible sur ce lien : https://drive.google.com/file/d/0B0ChFm … sp=sharing
Il suffit de l'enregistrer et de l'installer.

Pour lancer le programme de sauvegarde, c'est : Applications / Accessoires / Sauvegarde automatique facile (un icône coffre fort jaune apparaît dans la zone de notification).

Pour initialiser une sauvegarde : clic droit sur l’icône, Créer / Modifier une sauvegarde. un pop-up vous demande d'insérer un support de sauvegarde, connectez votre support (carte SD, clé USB, disque externe, ...)

Une fenêtre apparaît avec la liste de vos dossiers personnels, cochez ceux que vous voulez sauvegarder et validez. Une fois fini, il suffit de retirer le support.

Pour les prochaines sauvegardes, si le programme est déjà lancé (icône coffre fort jaune), il suffit d'insérer le support et le retirer quand indiqué.

J'ai essayé d'enlever le maximum d'erreurs mais je soupçonne certaines de s'être malicieusement cachées dans des endroits impossibles,
aussi n'utilisez ce programme que dans le cadre de tests pour le moment. Le programme ne fait encore pas de roulement dans les sauvegardes (il crée un nouveau dossier horodaté à chaque fois) et il est prévu pour fonctionner sur des supports formatés en NTFS, même si l'utilisation de FAT32 ne semble pas (trop) le déranger.

J'attends d'éventuels retours.

A bientôt


Linux à Contrexéville ?
http://leclug.free.fr/forum/

Hors ligne

#2 Le 25/04/2015, à 09:13

Shanx

Re : [Script / Python] À tester : sauvegarde facile ... où pas ;-)

Salut,
ce ne serait pas possible d'avoir les sources plutôt ?


Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied

Hors ligne

#3 Le 25/04/2015, à 10:40

papy88140

Re : [Script / Python] À tester : sauvegarde facile ... où pas ;-)

Il suffit d'ouvrir le paquet .deb comme une archive et d'extraire le script safe.py
sinon, le script c'est :

#!/usr/bin/env python
# -*- coding: utf8 -*-


import subprocess,string,pyinotify, getpass, time
import appindicator,os,shutil
from PyQt4 import QtCore, QtGui
from datetime import datetime
import dbus

class Safe(QtCore.QObject):

	# hostname : le nom de la machine
	# user: nom de l'utilisateur courant

	signalOpenConfig = QtCore.pyqtSignal()
	signalOpenAttente = QtCore.pyqtSignal()
	signalCloseConfig = QtCore.pyqtSignal()
	signalCloseAttente = QtCore.pyqtSignal()
	signalOpenFini = QtCore.pyqtSignal()
	signalCloseFini = QtCore.pyqtSignal()

	def handler(self, event):
        
		time.sleep(2)

		self.spath=event.pathname
		mtab=open("/etc/mtab")
		lignes=mtab.readlines()
		# print lignes
		self.partname=string.split(lignes[len(lignes)-1], " ",)[0]
		mtab.close
		self.diskname=self.partname[:-1]
		print self.spath, "   ", self.partname,self.diskname		
		configFileName="%s/.safe/%s/%s.safe" % (self.spath,self.hostname,self.user)

		# nouvelle sauvegarde ?

		if self.action == "config" :

			self.signalCloseConfig.emit()
			# on liste les dossiers personnels
			home="/home/%s" % getpass.getuser()

			try :
				fichier=open(configFileName)
				dossiersConfig=string.split(fichier.read(),"\n")
				fichier.close()
			except :
				dossiersConfig=[]

			dossiers=os.listdir(home)
			## print dossiers
			dossiersPerso=[]

			for dossier in dossiers:
				if dossier[0] != "." and os.path.isdir("%s/%s" % (home,dossier)):
					dossiersPerso = dossiersPerso + [dossier]

			## print dossiersPerso

			commande = ['zenity','--height','800','--width','400','--list','--text','Sélectionnez les dossiers à sauvegarder\n','--checklist','--column','Sél.','--column','Dossiers']
			for ligne in dossiersPerso :
				if ligne in dossiersConfig:
					commande=commande+['TRUE',ligne]
				else :
					commande=commande+['FALSE',ligne]
			commande=commande+['--separator=:']

			try :

				dossiers=subprocess.check_output(commande)
				subprocess.call(["mkdir","-p","%s/.safe/%s" % (self.spath,self.hostname)])
				fichierConfig = open(configFileName,"w")
				for dossier in string.split(dossiers,":") :
					fichierConfig.write("%s\n"%(dossier))
				fichierConfig.close()
				self.action="backup"

			except subprocess.CalledProcessError, e:

				print "configuration annulée"
				# ejection du support
				subprocess.call(["udisksctl","unmount","-b","%s" % (self.partname)])
				subprocess.call(["udisksctl","power-off","-b","%s" % (self.diskname)])				
				os.system('notify-send -t 3000 -i /opt/safe/safe-icon.svg "Sauvegarde Automatique Facile" "Vous pouvez retirer votre support de sauvegarde"')
				return


		# analyse du support inséré

		# recherche de la configuration de l'utilisateur actuel
		# .safe/hostname/utilisateur.conf

		## configFileName="%s/.safe/%s/%s.safe" % (self.spath,self.hostname,self.user)
		## print os.path.exists(configFileName)
		## print configFileName

		if os.path.exists(configFileName) :
			fichier=open(configFileName)
			dossiers=string.split(fichier.read(),"\n")
			fichier.close()
			## print dossiers

			# os.system('notify-send -t 3000 -i /opt/safe/safe-icon.svg "Sauvegarde Automatique Facile" "Sauvegarde en cours,\nveuillez patienter svp ..."')
			self.signalOpenAttente.emit()

			# code de la sauvegarde
			dossierHost="%s/.safe/%s" % (self.spath,self.hostname)
			dossierUser="%s/%s" % (dossierHost,self.user)
			## print dossierUser

			if not(os.path.exists(dossierUser)):
				try:
					os.mkdir(dossierUser)
				except:
					pass

			if not(os.path.exists("%s/%s@%s" % (self.spath,self.user,self.hostname))):
				try:
					os.symlink(".safe/%s/%s" % (self.hostname,self.user),"%s/%s@%s" % (self.spath,self.user,self.hostname))
				except:
					pass

			# dernière sauvegarde et roulement

			try:
				sauvegardes=os.listdir(dossierUser)
				## print len(sauvegardes)
				## print sauvegardes
				last = sauvegardes[-1]
				if len(sauvegardes) == 5:
					shutil.rmtree("%s/.safe/%s/%s/%s" % (self.spath,self.hostname,self.user,sauvegardes[0]))
			except:
				last="none"

			## print last

			# date actuelle

			date=datetime.now()
			date="%.4d.%.2d.%.2d-%.2d.%.2d.%.2d" % (date.year,date.month,date.day,date.hour,date.minute,date.second)
			try:
				os.mkdir("%s/%s" % (dossierUser,date))
			except:
				pass

			for dossier in dossiers :
				dossier=string.lstrip(string.rstrip(dossier))
				if os.path.exists("/home/%s/%s" % (self.user,dossier)) and len(dossier)>0 :
					try:
						commande=["rsync","-r","-t","-q","--safe-links","--link-dest=%s/.safe/%s/%s/%s" % (self.spath,self.hostname,self.user,last),"/home/%s/%s" % (self.user,dossier),"%s/.safe/%s/%s/%s" % (self.spath,self.hostname,self.user,date)]
						subprocess.check_output(commande)

					except:
						commande=["rsync","-r","-t","-q","--safe-links","/home/%s/%s" % (self.user,dossier),"%s/.safe/%s/%s/%s" % (self.spath,self.hostname,self.user,date)]
						subprocess.check_output(commande)

					print commande


			# ejection du support
			subprocess.call(["udisksctl","unmount","-b","%s" % (self.partname)])
			subprocess.call(["udisksctl","power-off","-b","%s" % (self.diskname)])

			# notification de fin

			self.signalCloseAttente.emit()
			self.signalOpenFini.emit()
			time.sleep(3)
			self.signalCloseFini.emit()

	def quit(self):
		self.notifier.stop()
		QtGui.qApp.quit()
		exit(0)

	def safeConfig(self):


		# on redéfini l'action à exécuter à l'insertion du support
		self.action="config"

		# on demande le support
		self.signalOpenConfig.emit()


	def __init__(self):

		QtCore.QObject.__init__(self)

		## Initialisation : pour connaitre la machine sur laquelle on travaille


		self.hostname=subprocess.check_output(["hostname"])[:-1]
		self.user=getpass.getuser()
		
		## print self.user

		# mise en place de la surveillance de l'insertion d'un support de stockage

		self.wm=pyinotify.WatchManager()

		wmpath='/media/%s' % (self.user)

		# action à exécuter lors de l'insertion du support

		self.action="backup"

		self.wm.add_watch(wmpath,pyinotify.IN_CREATE)
		self.notifier=pyinotify.ThreadedNotifier(self.wm, self.handler)
		self.notifier.start()

		#
		# indicateur
		# et interface grapĥique
		#

		self.app = QtGui.QApplication([])
		self.icon = QtGui.QSystemTrayIcon(QtGui.QIcon("/opt/safe/safeGold.png"), self.app)
		self.menu = QtGui.QMenu()
		self.menu.addAction("Creer/Modifier une sauvegarde", self.safeConfig)
		self.menu.addAction("Quit", self.quit)
		self.icon.setContextMenu(self.menu)
		self.icon.show()

		self.imageSplashAttente = QtGui.QPixmap('/opt/safe/splashAttente.png')
		self.splashAttente = QtGui.QSplashScreen(self.imageSplashAttente, QtCore.Qt.WindowStaysOnTopHint)
		self.signalCloseAttente.connect(self.splashAttente.close)
		self.signalOpenAttente.connect(self.splashAttente.show)

		self.imageSplashFini = QtGui.QPixmap('/opt/safe/splashFini.png')
		self.splashFini = QtGui.QSplashScreen(self.imageSplashFini, QtCore.Qt.WindowStaysOnTopHint)
		self.signalCloseFini.connect(self.splashFini.close)
		self.signalOpenFini.connect(self.splashFini.show)


		self.imageSplashConfig = QtGui.QPixmap('/opt/safe/splashConfig.png')
		self.splashConfig = QtGui.QSplashScreen(self.imageSplashConfig, QtCore.Qt.WindowStaysOnTopHint)
		self.signalCloseConfig.connect(self.splashConfig.close)
		self.signalOpenConfig.connect(self.splashConfig.show)

		self.app.exec_()

		#
		#
		#



if __name__=='__main__':

    mySafe=Safe()

Il a été empaqueté car il utilise quelques images / icones


Linux à Contrexéville ?
http://leclug.free.fr/forum/

Hors ligne