6 this file is part of the project scolasync
8 Copyright (C) 2010-2012 Georges Khaznadar <georgesk@ofset.org>
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.
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.
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/>.
24 import subprocess, threading, re, os, os.path, shutil
25 import time, glob, shlex, io
36 os.path.isdir(destpath)
or os.makedirs(destpath, mode=0o755)
53 return "ThreadRegister: %s" %self.
dico
61 def push(self, ud, thread):
62 if ud.getOwner()
not in self.dico.keys():
63 self.
dico[ud.getOwner()]=[thread]
65 self.
dico[ud.getOwner()].append(thread)
73 def pop(self, ud, thread):
74 self.
dico[ud.getOwner()].remove(thread)
83 if owner
in self.dico.keys():
84 return self.
dico[owner]
93 for o
in self.dico.keys():
94 for t
in self.
dico[o]:
105 def _sanitizePath(path):
106 pattern=re.compile(
".*([^/]+)")
107 m=pattern.match(str(path))
111 return str(path).replace(
'/',
'_')
122 if hasattr(ud,
"path"):
123 name=
"th_%04d_%s" %(_threadNumber,_sanitizePath(ud.path))
125 name=
"th_%04d_%s" %(_threadNumber,
"dummy")
135 return time.strftime(
"%Y/%m/%d-%H:%M:%S")
163 def __init__(self,ud, fileList, subdir, dest=None, logfile="/dev/null",
165 threading.Thread.__init__(self, name=_threadName(ud))
166 self.
_args=(ud, fileList, subdir, dest, logfile)
168 if hasattr(ud,
"threadRunning"): ud.threadRunning=
True
185 open(os.path.expanduser(self.
logfile),
"a").write(msg+
"\n")
201 def copytree(self,src, dst, symlinks=False, ignore=None, erase=False, errors=[]):
202 names = os.listdir(src)
203 if ignore
is not None:
204 ignored_names = ignore(src, names)
206 ignored_names = set()
210 except OSError
as err:
213 if name
in ignored_names:
215 srcname = os.path.join(src, name)
216 dstname = os.path.join(dst, name)
218 if symlinks
and os.path.islink(srcname):
219 linkto = os.readlink(srcname)
220 os.symlink(linkto, dstname)
221 if not errors
and erase:
223 elif os.path.isdir(srcname):
224 errors=self.
copytree(srcname, dstname,
225 symlinks=symlinks, ignore=ignore,
226 erase=erase, errors=errors)
227 if not errors
and erase:
230 shutil.copy2(srcname, dstname)
231 if not errors
and erase:
234 except IOError
as why:
235 errors.append((srcname, dstname, str(why)))
238 except os.error
as why:
239 errors.append((srcname, dstname, str(why)))
242 except Exception
as err:
243 errors.extend(err.args[0])
254 result+=
" ud = %s\n" %self.
ud
255 result+=
" fileList = %s\n" %self.
fileList
256 result+=
" subdir = %s\n" %self.
subdir
257 result+=
" dest = %s\n" %self.
dest
258 result+=
" logfile = %s\n" %self.
logfile
268 return "abstractThreadUSB"
279 def toDo(self, ud, fileList, subdir, dest, logfile):
287 class threadCopyToUSB(abstractThreadUSB):
299 def __init__(self,ud, fileList, subdir, logfile="/dev/null",
301 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None, logfile=logfile, parent=parent)
308 return "threadCopyToUSB"
322 def toDo(self, ud, fileList, subdir, dest, logfile):
323 while subdir[0]==
'/':
325 destpath=os.path.join(ud.ensureMounted(),ud.visibleDir(),subdir)
329 cmd=
"Copie de {0} vers {1}".format(f, destpath)
331 self.parent.emit(SIGNAL(
"pushCmd(QString, QString)"), ud.getOwner(), cmd)
332 destpath1=os.path.join(destpath, os.path.basename(f))
339 shutil.copy2(f, destpath1)
340 except Exception
as err:
341 errors.append([f, destpath1, str(err)])
350 msg+=
" <%s>" %str(e)
352 self.parent.emit(SIGNAL(
"popCmd(QString, QString)"), ud.getOwner(), cmd)
373 def __init__(self,ud, fileList, subdir=".", dest="/tmp",
374 rootPath=
"/", logfile=
"/dev/null", parent=
None):
375 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
376 logfile=logfile, parent=parent)
390 def toDo(self, ud, fileList, subdir, dest, logfile):
393 fromPath=os.path.join(ud.ensureMounted(), f)
396 newName=
"%s_%s" %(owner,os.path.dirname(f))
398 toPath=os.path.join(dest,newName)
401 cmd=
"Copie de {0} vers {1}".format(fromPath, toPath)
403 self.parent.emit(SIGNAL(
"pushCmd(QString, QString)"), ud.getOwner(), cmd)
404 destpath1=os.path.join(toPath, os.path.basename(f))
405 if os.path.isdir(fromPath):
406 errors=self.
copytree(fromPath, destpath1)
410 shutil.copy2(fromPath, destpath1)
411 except Exception
as err:
412 errors.extend((fromPath, destpath1, str(err)))
423 self.parent.emit(SIGNAL(
"popCmd(QString, QString)"), ud.getOwner(), msg)
444 def __init__(self,ud, fileList, subdir=".", dest="/tmp",
445 rootPath=
"/", logfile=
"/dev/null", parent=
None):
446 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
447 logfile=logfile, parent=parent)
462 def toDo(self, ud, fileList, subdir, dest, logfile):
465 fromPath=os.path.join(ud.ensureMounted(), f)
468 newName=
"%s_%s" %(owner,os.path.dirname(f))
470 toPath=os.path.join(dest,newName)
473 cmd=
"copying %s to %s" %(fromPath, toPath)
475 self.parent.emit(SIGNAL(
"pushCmd(QString, QString)"), ud.getOwner(), cmd)
476 destpath1=os.path.join(toPath, os.path.basename(f))
477 if os.path.isdir(fromPath):
478 errors=self.
copytree(fromPath, destpath1, erase=
True)
481 except Exception
as err:
482 errors.extend((fromPath, destpath1, str(err)))
486 shutil.copy2(fromPath, destpath1)
488 except Exception
as err:
489 errors.extend((fromPath, destpath1, str(err)))
500 self.parent.emit(SIGNAL(
"popCmd(QString, QString)"), ud.getOwner(), msg)
519 def __init__(self,ud, fileList, subdir, logfile="/dev/null",
521 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None,
522 logfile=logfile, parent=parent)
537 def toDo(self, ud, fileList, subdir, dest, logfile):
539 toDel=os.path.join(ud.ensureMounted(), f)
540 cmd=
"Effacement de {0}".format(toDel)
543 self.parent.emit(SIGNAL(
"pushCmd(QString, QString)"), ud.getOwner(), cmd)
544 if os.path.isdir(toDel):
546 for root, dirs, files
in os.walk(toDel, topdown=
False):
548 os.remove(os.path.join(root, name))
550 os.rmdir(os.path.join(root, name))
552 except Exception
as err:
553 errors.expand((toDel,str(err)))
557 except Exception
as err:
558 errors.expand((toDel,str(err)))
568 self.parent.emit(SIGNAL(
"popCmd(QString, QString)"), ud.getOwner(), msg)
571 if __name__==
"__main__":
572 import sys, ownedUsbDisk, subprocess
578 if len(sys.argv) < 3:
579 print(
"Usage : %s répertoire_source répertoire_destination" %sys.argv[0])
580 print(
"Ça doit créer sous répertoire_destination la même arborescence que sous répertoire_source")
581 print(
"et ça crée répertoire_destination à la volée si nécessaire.")
583 errors=t.copytree(sys.argv[1],sys.argv[2])
584 print(
"Erreurs = %s" %errors)
585 subprocess.call (
"diff -ruN %s %s" %(sys.argv[1],sys.argv[2]), shell=
True)
586 print (
"Ne pas oublier d'effacer %s si nécessaire" %sys.argv[2])
594 if len(sys.argv) < 3:
595 print(
"Usage : %s fichier répertoire_destination" %sys.argv[0])
596 print(
"Ça doit créer sous répertoire_destination une copie du fichier")
597 print(
"et ça crée répertoire_destination à la volée si nécessaire.")
600 dstname=os.path.join(sys.argv[2],sys.argv[1])
601 shutil.copy2(srcname, dstname)
602 print (
"fin de la copie de %s vers %s, listing de %s" %(sys.argv[1],sys.argv[2],sys.argv[2]))
603 subprocess.call(
"ls %s" %sys.argv[2], shell=
True)
def __init__
Constructeur Crée un thread pour copier une liste de fichiers depuis une clé USB vers un répertoire d...
def __str__(self)
Renvoie une chaîne informative sur le thread.
def __init__
Constructeur Crée un thread pour supprimer une liste de fichiers dans une clé USB.
def test_copy2()
Teste la copie d'un fichier vers une destination telle qu'elle est pratiquée dans la méthode copytree...
Classe pour les threads déplaçant des fichiers depuis les clés USB.
def copytree
Une version modifiée de shutil.copytree qui accepte que les repertoires destination soient déjà exist...
def __init__(self)
Le constructure met en place un dictionnaire.
def __init__
Constructeur Crée un thread pour copier une liste de fichiers vers une clé USB.
def __init__
Constructeur Crée un thread pour copier une liste de fichiers vers une clé USB.
def __init__
Constructeur Crée un thread pour déplacer une liste de fichiers depuis une clé USB vers un répertoire...
def toDo(self, ud, fileList, subdir, dest, logfile)
Copie une liste de fichiers d'une clé USB sous un répertoire donné.
def push(self, ud, thread)
def toDo(self, ud, fileList, subdir, dest, logfile)
La fonction abstraite pour les choses à faire.
Une classe pour tenir un registre des threads concernant les baladeurs.
def threadType(self)
information sur le thread.
def toDo(self, ud, fileList, subdir, dest, logfile)
Copie une liste de fichiers d'une clé USB sous un répertoire donné.
def toDo(self, ud, fileList, subdir, dest, logfile)
Copie une liste de fichiers vers une clé USB sous un répertoire donné.
def ensureDirExists(destpath)
force l'existence d'un répertoire, récursivement si nécessaire
def pop(self, ud, thread)
Une classe abstraite, qui sert de creuset pour les classe servant aux copies et aux effacements...
def test_copytree()
Teste la fonction copytree.
def busy(self, owner)
Indique si le disque est occupé par des threads.
Classe pour les threads copiant depuis les clés USB.
def writeToLog(self, msg)
Écrit un message dans le fichier de journalisation.
def toDo(self, ud, fileList, subdir, dest, logfile)
Supprime une liste de fichiers dans une clé USB.
Classe pour les threads effaçant des sous-arbres dans les clés USB.
def threadSet(self)
renvoie l'ensemble des threads actifs