ScolaSync 1.0
ownedUsbDisk.py
Aller à la documentation de ce fichier.
00001 # -*- coding: utf-8 -*-    
00002 #       $Id: ownedUsbDisk.py 47 2011-06-13 10:20:14Z georgesk $ 
00003 
00004 licence={}
00005 licence['en']="""
00006     file ownedUsbDisk.py
00007     this file is part of the project scolasync
00008     
00009     Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>
00010 
00011     This program is free software: you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version3 of the License, or
00014     (at your option) any later version.
00015 
00016     This program is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU General Public License for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 """
00024 
00025 
00026 import usbDisk, db
00027 import os.path, dbus, subprocess, time
00028 from PyQt4.QtCore import *
00029 from PyQt4.QtGui import *
00030 from globaldef import markFileName
00031 
00032 """
00033 liste statique pour éviter de demander chaque seconde le nom d'un
00034 propriétaire de clé si on n'a pas souhaité le donner.
00035 """
00036 
00037 ##
00038 # 
00039 #     édition de la base de données
00040 #     @param owd une instance de ownedUsbDisk
00041 #     @param prompt chaîne vide par défaut. Peut être le nom de l'ancien propriétaire
00042 #     
00043 def editRecord(owd, prompt=""):
00044     newStudent, ok = QInputDialog.getText(None,
00045                                           u"Choix du propriétaire",
00046                                           u"Nouveau nom du propriétaire de la clé",
00047                                           text=prompt
00048                                           )
00049     if ok:
00050         newStudent=u"%s" %newStudent
00051         db.writeStudent(owd.stickid, owd.getFatUuid(), owd.tattoo(), newStudent)
00052 
00053 ##
00054 # 
00055 #     une classe qui ajoute un nom de propriétaire aux disque USB,
00056 #     et qui en même temps ajoute des particularités selon le nom du
00057 #     vendeur et le modèle.
00058 #     
00059 class uDisk(usbDisk.uDisk,QObject):
00060     ##
00061     # 
00062     #         @param path un chemin dans le système dbus
00063     #         @param bus un objet dbus.BusSystem
00064     #         @param checkable vrai si on fera usage de self.selected
00065     #         
00066     def __init__(self, path, bus, checkable=False):
00067         usbDisk.uDisk.__init__(self,path, bus, checkable)
00068         QObject.__init__(self)
00069         self.owner="" # le propriétaire est déterminé plus tard
00070         self.vendor=self.getProp("drive-vendor")
00071         self.model=self.getProp("drive-model")
00072         self.visibleDirs=self.readQuirks()
00073 
00074     ##
00075     # 
00076     #         @return un identifiant unique, composé du nom du propriétaire
00077     #         suivi du tatouage
00078     #         
00079     def uniqueId(self):
00080         return "%s~%s" %(self.owner, self.tattoo())
00081 
00082     ##
00083     # 
00084     #         Renvoie un tatouage présent sur la clé, quitte à le créer.
00085     #         @result un tatouage, supposément unique.
00086     #         
00087     def tattoo(self):
00088         ff=self.getFirstFat()
00089         if ff:
00090             fatPath=ff.ensureMounted()
00091             tattooFileName=os.path.join(fatPath,".scolasync-tattoo")
00092             if os.path.exists(tattooFileName):
00093                 tattoo_=open(tattooFileName,"r").read()
00094                 # on vérifie par acquis de conscience, qu'il n'existe pas
00095                 # un tatouage identique dans la base de données
00096                 # s'il est déjà présent : on le change. Il faudrait
00097                 # probablement aussi prévenir le prof !!!
00098                 if tattoo_ in db.tattooList():
00099                     tattoo_="%12.2f" %time.time()
00100                     time.sleep(0.05)
00101             else:
00102                 tattoo_="%12.2f" %time.time()
00103                 time.sleep(0.05)
00104                 outfile=open(tattooFileName,"w")
00105                 outfile.write(tattoo_)
00106                 outfile.close()
00107             return tattoo_
00108         else:
00109             return ""
00110     
00111     ##
00112     # 
00113     #         Lit un dictionnaire indexé par le noms de vendeurs et les noms de modèle
00114     #         pour associer à ces modèles particuliers un répertoire visible.
00115     #         voir la fonction visibleDir. Ce dictionnaire est dans le fichier
00116     #         /usr/share/scolasync/marques.py ou dans ${HOME}/.scolasync/marques.py,
00117     #         (sous Linux) cette dernière place étant prépondérante.
00118     #         
00119     def readQuirks (self):
00120         f1="/usr/share/scolasync/marques.py"
00121         f2=os.path.expanduser(markFileName)
00122         if os.path.exists(f2):
00123             f=f2
00124         else:
00125             f=f1
00126         result=eval(open(f,"r").read())
00127         return result
00128         
00129     ##
00130     # 
00131     #         Renvoie le répertoire particulier de la partition qui sera visible
00132     #         quand le baladeur est utilisé par son interface utilisateur. Ce
00133     #         répertoire peut varier selon les vendeurs et les modèles.
00134     #         
00135     def visibleDir(self):
00136         k=self.vendor+":"+self.model
00137         if k in self.visibleDirs.keys():
00138             return self.visibleDirs[k]
00139         else:
00140             return "."
00141 
00142     ##
00143     # 
00144     #         Méthode statique
00145     #         renvoie des titres pour les items obtenus par __getitem__
00146     #         la deuxième colonne sera toujours le propriétaire
00147     #         @param checkable vrai si le premier en-tête correspond à une colonne de cases à cocher
00148     #         @param locale la locale, pour traduire les titres
00149     #         @return une liste de titres de colonnes
00150     #         
00151     def headers(checkable=False,locale="C"):
00152         result=usbDisk.uDisk.headers(checkable, locale)
00153         ownerProp=QApplication.translate("uDisk","owner",None, QApplication.UnicodeUTF8)
00154         result.insert(1,ownerProp)
00155         return result
00156 
00157     ##
00158     # 
00159     #         renvoie un nom de propriétaire dans tous les cas.
00160     #         
00161     def ownerByDb(self):
00162         if self.owner != "":
00163             return self.owner
00164         else:
00165             s=db.readStudent(self.stickid, self.getFatUuid(), self.tattoo())
00166             if s != None:
00167                 self.owner=s
00168                 return s
00169             else:
00170                 return QApplication.translate("Dialog","inconnu",None, QApplication.UnicodeUTF8)
00171 
00172     ##
00173     # 
00174     #         renvoie un élément de listage de données internes au disque
00175     #         Fait en sorte que la deuxième colonne soit toujours le propriétaire
00176     #         @param n un nombre
00177     #         @param checkable vrai si on doit renvoyer une propriété supplémentaire pour n==0
00178     #         @return si n==-1, renvoie self ; si checkable est vrai, renvoie un élément si n>0, et le drapeau self.selected si n==0 ; sinon un élément de façon ordinaire. Les noms des éléments sont dans la liste self.itemNames
00179     #         
00180     def __getitem__(self,n):
00181         propListe=usbDisk.uDisk.headers()
00182         if n == -1:
00183             return self # pour accéder à toutes les données d'une partition
00184         if self.checkable:
00185             if n==0:
00186                 return self.selected
00187             elif n==1:
00188                 return self.ownerByDb()
00189             elif n==2:
00190                 return self.unNumberProp(0)
00191             else:
00192                 return self.unNumberProp(n-1)
00193         else:
00194             if n==0:
00195                 return self.unNumberProp(0)
00196             elif n==1:
00197                 return self.ownerByDb()
00198             else:
00199                 return self.unNumberProp(n)
00200     
00201     
00202     headers = staticmethod(headers)
00203 
00204     ##
00205     # 
00206     #         Demande un nom de propriétaire si celui-ci n'est pas encore défini
00207     #         pour cette clé USB
00208     #         @param noLoop si True : ne fait pas de dialogue interactif
00209     #         @return un nom de propriétaire si c'est un disque, sinon None
00210     #         
00211     def ensureOwner(self, noLoop):
00212         if self.getProp("device-is-drive") and self.isUsbDisk():
00213             if noLoop==False and not db.knowsId(self.stickid, self.getFatUuid(), self.tattoo()) :
00214                 prompt=QApplication.translate("Dialog","La cle %1<br>n'est pas identifiee, donnez le nom du proprietaire",None, QApplication.UnicodeUTF8).arg(self.stickid)
00215                 title=QApplication.translate("Dialog","Entrer un nom",None, QApplication.UnicodeUTF8)
00216                 text,ok = QInputDialog.getText(None, title, prompt)
00217                 text = u"%s" %text.toUtf8()
00218                 if ok and len(text)>0 and not db.hasStudent(text):
00219                     db.writeStudent(self.stickid, self.getFatUuid(), self.tattoo(), text)
00220         return db.readStudent(self.stickid, self.getFatUuid(), self.tattoo())
00221         
00222 ##
00223 # 
00224 #     Une classe qui fournit une collection de disques USB connectés,
00225 #     avec leurs propriétaires. Les propriétaires sont recensés juste
00226 #     avant le montage des partions FAT.
00227 #     
00228 class Available(usbDisk.Available):
00229 
00230     ##
00231     # 
00232     #         Le constructeur est un proxy pour usbDisk.Available.__init__
00233     #         qui force la classe de disques à utiliser : en effet ici
00234     #         uDisk désigne ownedUsbDisk.uDisk
00235     #         @param checkable True si on veut pouvoir sélectionner des disques en cochant
00236     #         @param access le mode d'accès : 'disk' ou 'firstFat'
00237     #         @param diskClass la classe d'objets à créer pour chaque disque
00238     #         @param diskDict un dictionnaire des disque maintenu par deviceListener
00239     #         @param noLoop doit être True pour éviter de lancer un dialogue
00240     #         
00241     def __init__(self, checkable=False, access="disk", diskClass=uDisk, diskDict=None, noLoop=False):
00242         self.noLoop=noLoop
00243         usbDisk.Available.__init__(self, checkable, access, diskClass, diskDict)
00244         
00245     ##
00246     # 
00247     #         Fin de l'initialisation : trouve les propriétaires des disques
00248     #         puis identifie les partitions FAT et les monte
00249     #         
00250     def finishInit(self):
00251         self.getFirstFats() # premier passage, pour repérer chaque partition FAT
00252         for d in self.disks.keys():
00253             d.owner=d.ensureOwner(self.noLoop)
00254         self.mountFirstFats()
00255 
00256 
 Tout Classes Espaces de nommage Fichiers Fonctions Variables