ScolaSync: Fichier source de src/ownedUsbDisk.py

ScolaSync 5.1 |

ownedUsbDisk.py
Aller à la documentation de ce fichier.
1 # $Id: ownedUsbDisk.py 47 2011-06-13 10:20:14Z georgesk $
2
3 licence={}
4 licence['en']="""
5 file ownedUsbDisk.py
6 this file is part of the project scolasync
7
8 Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 """
23
24 import usbDisk2, db
25 import os.path, dbus, subprocess, time, random
26 from PyQt5.QtCore import *
27 from PyQt5.QtWidgets import *
28 from globaldef import markFileName
29
30 """
31 liste statique pour éviter de demander chaque seconde le nom d'un
32 propriétaire de clé si on n'a pas souhaité le donner.
33 """
34
35 # Renvoie le tatouage pour un point de montage donné, quitte à le créer
36 # si nécessaire.
37 # @param mountPoint un point de montage de partition
38 # @return le tatouage
39 #
40
41 def tattooInDir(mountPoint):
42 tattooFileName = os.path.join(mountPoint,".scolasync-tattoo")
43 tattoo_=""
44 if os.path.exists(tattooFileName):
45 tattoo_=open(tattooFileName,"r").readlines()[0].strip()
46 if tattoo_ != "" :
47 # le tatouage existe déjà, on renvoie sa valeur
48 return tattoo_
49 else:
50 tattoo_="%12.2f" %time.time()
51 time.sleep(0.05)
52 # si on espace deux créations de tatouages de 50 millisecondes
53 # il est impossible d'avoir deux tatouages identiques générés
54 # par le même ordinateur. Les chances que ça arrive avec des
55 # ordinateurs distincts sont minimes
56 outfile=open(tattooFileName,"w")
57 outfile.write(tattoo_)
58 outfile.close()
59 # on renvoie le nouveau tatouage
60 return tattoo_
61
62
66
67 def editRecord(owd, hint=""):
68 ud=owd.getFat()
69 title=QApplication.translate("Dialog", "Choix du propriétaire", None)
70 prompt=QApplication.translate("Dialog", "Nouveau nom du propriétaire du baladeur", None)
71 newStudent, ok = QInputDialog.getText(None, title, prompt, text=hint)
72 if ok:
73 newStudent="%s" %newStudent
74 assert (ud.parent) # ud est une partition de type vfat
75 db.writeStudent(ud.stickid, ud.uuid, ud.tattoo(), newStudent)
76
77 # une classe qui ajoute un nom de propriétaire aux disque USB,
78 # et qui en même temps ajoute des particularités selon le nom du
79 # vendeur et le modèle.
80 #
81
82 class uDisk2(usbDisk2.uDisk2,QObject):
83
100
101 def __init__(self, path, mp='', isUsb=False, vendor='', model='', parent=None,
102 fstype='', serial='', uuid='',
103 free=0, capacity=0, device='', firstFat=None, selected=True):
104 usbDisk2.uDisk2.__init__(self, path=path, mp=mp, isUsb=isUsb, vendor=vendor,
105 model=model, parent=parent, fstype=fstype, serial=serial,
106 uuid=uuid, free=free, capacity=capacity, device=device,
107 firstFat=firstFat, selected=selected)
108 QObject.__init__(self)
109 self.owner="" # le propriétaire est déterminé plus tard
110 self.visibleDirs=self.readQuirks()
111
112
115
116 def getOwner(self):
117 return self.getFat().owner
118
119
122
123 def getFat(self):
124 if self.parent:
125 return self
126 else:
127 return self.firstFat
128
129
132
133 def valuableProperties(self,indent=4):
134 prefix="\n"+" "*indent
135 r=""
136 props=["mp", "parent", "fstype", "stickid", "uuid", "vendor", "model", "devStuff", "free", "capacity", "owner"]
137 for prop in props:
138 r+=prefix+"%s = %s" %(prop, getattr(self,prop))
139 return r
140
141 # @return un identifiant unique, composé du nom du propriétaire
142 # suivi du tatouage
143 #
144
145 def uniqueId(self):
146 return "%s~%s" %(self.owner, self.tattoo())
147
148
151
152 def tattoo(self):
153 ud=self.getFat()
154 if ud and ud.mp:
155 return tattooInDir(ud.mp)
156 else:
157 return ""
158
159 # Lit un dictionnaire indexé par le noms de vendeurs et les noms de modèle
160 # pour associer à ces modèles particuliers un répertoire visible.
161 # voir la fonction visibleDir. Ce dictionnaire est dans le fichier
162 # /usr/share/scolasync/marques.py ou dans ${HOME}/.scolasync/marques.py,
163 # (sous Linux) cette dernière place étant prépondérante.
164 #
165
166 def readQuirks (self):
167 f1="/usr/share/scolasync/marques.py"
168 f2=os.path.expanduser(markFileName)
169 if os.path.exists(f2):
170 f=f2
171 else:
172 f=f1
173 result={}
174 try:
175 result=eval(open(f,"r", encoding="utf-8").read())
176 except:
177 pass
178 return result
179
180 # Renvoie le répertoire particulier de la partition qui sera visible
181 # quand le baladeur est utilisé par son interface utilisateur. Ce
182 # répertoire peut varier selon les vendeurs et les modèles.
183 #
184
185 def visibleDir(self):
186 k=self.vendor+":"+self.model
187 if k in self.visibleDirs.keys():
188 return self.visibleDirs[k]
189 else:
190 return "."
191
192 # Méthode statique
193 # renvoie des titres pour les items obtenus par __getitem__
194 # la deuxième colonne sera toujours le propriétaire
195 # @param locale la locale, pour traduire les titres
196 # @return une liste de titres de colonnes
197 #
198
199 def headers(locale="C"):
200 result=usbDisk2.uDisk2.headers(locale)
201 ownerProp=QApplication.translate("uDisk","owner",None)
202 result.insert(1,ownerProp)
203 return result
204
205
207
208 def ownerByDb(self):
209 s=db.readStudent(self.stickid, self.uuid, self.tattoo())
210 if s != None:
211 return s
212 else:
213 return QApplication.translate("Dialog","inconnu",None)
214
215 # renvoie un élément de listage de données internes au disque
216 # Fait en sorte que la deuxième colonne soit toujours le propriétaire
217 # @param n un nombre
218 # @return si n==-1, renvoie self ; renvoie un élément si n>0, et le drapeau self.selected si n==0. Les noms des éléments sont dans la liste self.itemNames
219 #
220
221 def __getitem__(self,n):
222 propListe=usbDisk2.uDisk2.headers()
223 if n == -1:
224 return self # pour accéder à toutes les données d'une partition
225 elif n==0:
226 return self.selected
227 elif n==1:
228 return self.ownerByDb()
229 else:
230 return self.unNumberProp(n)
231
232
233 headers = staticmethod(headers)
234
235 # Demande un nom de propriétaire si celui-ci n'est pas encore défini
236 # pour cette clé USB. Enregistre au passage le nom du propriétaire
237 # dans les instances du disque et de sa partiton vfat
238 # @param ownerDialog si vrai : fait dialogue interactif
239 # @return un nom de propriétaire
240 #
241
242 def ensureOwner(self, ownerDialog):
243 if self.parent and not self.mp : # partiton non montée
244 return
245 ud=self.getFat()
246 assert (ud.parent) # ud désigne une partition vfat
247 if not db.knowsId(ud.stickid, ud.uuid, ud.tattoo()) :
248 text=self.randomOwner(6)
249 if ownerDialog:
250 prompt=QApplication.translate("Dialog","La cle {id}<br>n'est pas identifiee, donnez le nom du proprietaire",None).format(id=ud.stickid)
251 title=QApplication.translate("Dialog","Entrer un nom",None)
252 text,ok = QInputDialog.getText(None, title, prompt)
253 db.writeStudent(ud.stickid, ud.uuid, ud.tattoo(), text)
254 o=db.readStudent(ud.stickid, ud.uuid, ud.tattoo())
255 self.owner=o
256 ud.owner=o
257 return o
258
259
263
264 def randomOwner(self,length):
265 result="inconnu_"
266 for i in range(length):
267 result+=random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
268 return result
269
270 # Une classe qui fournit une collection de disques USB connectés,
271 # avec leurs propriétaires. Les propriétaires sont recensés juste
272 # avant le montage des partions FAT.
273 #
274
275 class Available(usbDisk2.Available):
276
277 # Le constructeur est un proxy pour usbDisk.Available.__init__
278 # qui force la classe de disques à utiliser : en effet ici
279 # uDisk désigne ownedUsbDisk.uDisk
280 # @param access le mode d'accès : 'disk' ou 'firstFat'
281 # @param diskClass la classe d'objets à créer pour chaque disque
282 # @param ownerDialog vrai si on veut qu'il y ait un dialogue automatique
283 # pour déterminer le propriétaire des disques non reconnus
284 #
285
286 def __init__(self, access="disk", diskClass=uDisk2, ownerDialog=False):
287 self.ownerDialog=ownerDialog
288 usbDisk2.Available.__init__(self, access, diskClass)
289 # self.finishInit() # non! cette routine est déjà appelée par usbDisk2.Available.__init__
290
291 # Fin de l'initialisation : trouve les propriétaires des disques
292 # puis identifie les partitions FAT et les monte
293 #
294
295 def finishInit(self):
296 self.getFirstFats() # repère chaque partition FAT dans les instances des disques
297 for d in self.disks_ud():
298 d.owner=d.ensureOwner(self.ownerDialog)
299 self.mountFirstFats()
300
301
302 if __name__=="__main__":
303 from PyQt5.QtCore import *
304 from PyQt5.QtWidgets import *
305 import sys
306 class MainWindow(QMainWindow):
307 def __init__(self):
308 QMainWindow.__init__(self)
309
310 # The only thing in the app is a quit button
311 quitbutton = QPushButton('Examinez le terminal\nbranchez et débranchez des clés USB, puis\nQuittez', self)
312 quitbutton.clicked.connect(self.close)
313 self.setCentralWidget(quitbutton)
314
315 machin=Available()
316 print (machin)
317 def print_targets_if_modif(man, obj):
318 if machin.modified:
319 print([s.split("/")[-1] for s in machin.targets.keys()])
320 for t in machin.targets:
321 machin.targets[t].owner=machin.targets[t].ownerByDb()
322 print (machin.targets[t].owner,":", t)
323 machin.modified=False
324 machin.addHook('object-added', print_targets_if_modif)
325 machin.addHook('object-removed', print_targets_if_modif)
326
327 app = QApplication(sys.argv)
328 main = MainWindow()
329 main.show()
330 sys.exit(app.exec_())
331
src.usbDisk2.uDisk2.unNumberProp
def unNumberProp(self, n)
Definition: usbDisk2.py:523
src.ownedUsbDisk.uDisk2.owner
owner
Definition: ownedUsbDisk.py:107
QObject
src.usbDisk2.uDisk2.uuid
uuid
Definition: usbDisk2.py:419
src.ownedUsbDisk.uDisk2.getFat
def getFat(self)
Renvoie à coup sûr la partition vfat d'un disque.
Definition: ownedUsbDisk.py:123
src.usbDisk2.Available.getFirstFats
def getFirstFats(self)
Definition: usbDisk2.py:734
src.ownedUsbDisk.print_targets_if_modif
def print_targets_if_modif(man, obj)
Definition: ownedUsbDisk.py:317
src.usbDisk2.uDisk2.stickid
stickid
Definition: usbDisk2.py:418
src.ownedUsbDisk.uDisk2.visibleDir
def visibleDir(self)
Definition: ownedUsbDisk.py:185
src.usbDisk2.Available
une classe pour représenter la collection des disques USB connectés
Definition: usbDisk2.py:583
src.ownedUsbDisk.Available.__init__
def __init__(self, access="disk", diskClass=uDisk2, ownerDialog=False)
Definition: ownedUsbDisk.py:286
src.ownedUsbDisk.Available
Definition: ownedUsbDisk.py:275
src.ownedUsbDisk.uDisk2.readQuirks
def readQuirks(self)
Definition: ownedUsbDisk.py:166
src.ownedUsbDisk.uDisk2.__getitem__
def __getitem__(self, n)
Renvoie un élément de listage de données internes au disque.
Definition: ownedUsbDisk.py:221
src.ownedUsbDisk.Available.finishInit
def finishInit(self)
Fin de l'initialisation.
Definition: ownedUsbDisk.py:295
src.usbDisk2.Available.disks_ud
def disks_ud(self)
Récolte les enregistrements de niveau supérieur de self.targets.
Definition: usbDisk2.py:657
src.ownedUsbDisk.uDisk2.uniqueId
def uniqueId(self)
Definition: ownedUsbDisk.py:145
src.usbDisk2.uDisk2.parent
parent
Definition: usbDisk2.py:416
src.usbDisk2.uDisk2.model
model
Definition: usbDisk2.py:415
src.ownedUsbDisk.uDisk2
Definition: ownedUsbDisk.py:82
src.usbDisk2.Available.mountFirstFats
def mountFirstFats(self)
Definition: usbDisk2.py:608
src.ownedUsbDisk.uDisk2.valuableProperties
def valuableProperties(self, indent=4)
Facilite l'accès aux propriétés intéressantes d'une instance.
Definition: ownedUsbDisk.py:133
src.ownedUsbDisk.uDisk2.ownerByDb
def ownerByDb(self)
renvoie un nom de propriétaire dans tous les cas.
Definition: ownedUsbDisk.py:208
src.ownedUsbDisk.uDisk2.randomOwner
def randomOwner(self, length)
fabrique un texte aléatoire de longueur donnée
Definition: ownedUsbDisk.py:264
src.ownedUsbDisk.Available.ownerDialog
ownerDialog
Definition: ownedUsbDisk.py:287
src.ownedUsbDisk.uDisk2.tattoo
def tattoo(self)
Renvoie un tatouage présent sur la clé, quitte à le créer.
Definition: ownedUsbDisk.py:152
QMainWindow
src.usbDisk2.uDisk2.mp
mp
Definition: usbDisk2.py:412
src.ownedUsbDisk.MainWindow
Definition: ownedUsbDisk.py:306
src.ownedUsbDisk.uDisk2.ensureOwner
def ensureOwner(self, ownerDialog)
Definition: ownedUsbDisk.py:242
src.usbDisk2.uDisk2.vendor
vendor
Definition: usbDisk2.py:414
src.usbDisk2.uDisk2.firstFat
firstFat
Definition: usbDisk2.py:423
src.ownedUsbDisk.tattooInDir
def tattooInDir(mountPoint)
Definition: ownedUsbDisk.py:41
QtCore
src.ownedUsbDisk.uDisk2.__init__
def __init__(self, path, mp='', isUsb=False, vendor='', model='', parent=None, fstype='', serial='', uuid='', free=0, capacity=0, device='', firstFat=None, selected=True)
Le constructeur.
Definition: ownedUsbDisk.py:101
src.usbDisk2.uDisk2
une classe pour représenter un disque ou une partition.
Definition: usbDisk2.py:390
src.ownedUsbDisk.editRecord
def editRecord(owd, hint="")
édition de la base de données.
Definition: ownedUsbDisk.py:67
src.ownedUsbDisk.uDisk2.visibleDirs
visibleDirs
Definition: ownedUsbDisk.py:108
src.usbDisk2.uDisk2.selected
selected
Definition: usbDisk2.py:424
src.ownedUsbDisk.uDisk2.headers
headers
Definition: ownedUsbDisk.py:233
QtWidgets
src.ownedUsbDisk.MainWindow.__init__
def __init__(self)
Definition: ownedUsbDisk.py:307
src.ownedUsbDisk.uDisk2.getOwner
def getOwner(self)
Renvoie le propriétaire.
Definition: ownedUsbDisk.py:116