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