5 this file is part of the project scolasync
7 Copyright (C) 2010-2012 Georges Khaznadar <georgesk@ofset.org>
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import subprocess, threading, re, os, os.path, shutil
24 import time, glob, shlex, io
35 os.path.isdir(destpath)
or os.makedirs(destpath, mode=0o755)
52 return "ThreadRegister: %s" %self.
dico
60 def push(self, ud, thread):
61 if ud.getOwner()
not in self.dico.keys():
62 self.
dico[ud.getOwner()]=[thread]
64 self.
dico[ud.getOwner()].append(thread)
72 def pop(self, ud, thread):
73 self.
dico[ud.getOwner()].remove(thread)
82 if owner
in self.dico.keys():
83 return self.
dico[owner]
92 for o
in self.dico.keys():
93 for t
in self.
dico[o]:
104 def _sanitizePath(path):
105 pattern=re.compile(
".*([^/]+)")
106 m=pattern.match(str(path))
110 return str(path).replace(
'/',
'_')
121 if hasattr(ud,
"path"):
122 name=
"th_%04d_%s" %(_threadNumber,_sanitizePath(ud.path))
124 name=
"th_%04d_%s" %(_threadNumber,
"dummy")
134 return time.strftime(
"%Y/%m/%d-%H:%M:%S")
162 def __init__(self,ud, fileList, subdir, dest=None, logfile="/dev/null",
164 threading.Thread.__init__(self, name=_threadName(ud))
165 self.
_args=(ud, fileList, subdir, dest, logfile)
167 if hasattr(ud,
"threadRunning"): ud.threadRunning=
True
184 open(os.path.expanduser(self.
logfile),
"a").write(msg+
"\n")
200 def copytree(self,src, dst, symlinks=False, ignore=None, erase=False, errors=[]):
201 names = os.listdir(src)
202 if ignore
is not None:
203 ignored_names = ignore(src, names)
205 ignored_names = set()
209 except OSError
as err:
212 if name
in ignored_names:
214 srcname = os.path.join(src, name)
215 dstname = os.path.join(dst, name)
217 if symlinks
and os.path.islink(srcname):
218 linkto = os.readlink(srcname)
219 os.symlink(linkto, dstname)
220 if not errors
and erase:
222 elif os.path.isdir(srcname):
223 errors=self.
copytree(srcname, dstname,
224 symlinks=symlinks, ignore=ignore,
225 erase=erase, errors=errors)
226 if not errors
and erase:
229 shutil.copy2(srcname, dstname)
230 if not errors
and erase:
233 except IOError
as why:
234 errors.append((srcname, dstname, str(why)))
237 except os.error
as why:
238 errors.append((srcname, dstname, str(why)))
241 except Exception
as err:
242 errors.extend(err.args[0])
253 result+=
" ud = %s\n" %self.
ud
254 result+=
" fileList = %s\n" %self.
fileList
255 result+=
" subdir = %s\n" %self.
subdir
256 result+=
" dest = %s\n" %self.
dest
257 result+=
" logfile = %s\n" %self.
logfile
267 return "abstractThreadUSB"
278 def toDo(self, ud, fileList, subdir, dest, logfile):
286 class threadCopyToUSB(abstractThreadUSB):
298 def __init__(self,ud, fileList, subdir, logfile="/dev/null",
300 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None, logfile=logfile, parent=parent)
307 return "threadCopyToUSB"
321 def toDo(self, ud, fileList, subdir, dest, logfile):
322 while subdir[0]==
'/':
324 destpath=os.path.join(ud.ensureMounted(),ud.visibleDir(),subdir)
328 cmd=
"Copie de {0} vers {1}".format(f, destpath)
330 self.parent.pushCmdSignal.emit(ud.getOwner(), cmd)
331 destpath1=os.path.join(destpath, os.path.basename(f))
338 shutil.copy2(f, destpath1)
339 except Exception
as err:
340 errors.append([f, destpath1, str(err)])
349 msg+=
" <%s>" %str(e)
351 self.parent.popCmdSignal.emit(ud.getOwner(), cmd)
372 def __init__(self,ud, fileList, subdir=".", dest="/tmp",
373 rootPath=
"/", logfile=
"/dev/null", parent=
None):
374 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
375 logfile=logfile, parent=parent)
389 def toDo(self, ud, fileList, subdir, dest, logfile):
392 fromPath=os.path.join(ud.ensureMounted(), f)
395 newName=
"%s_%s" %(owner,os.path.dirname(f))
397 toPath=os.path.join(dest,newName)
400 cmd=
"Copie de {0} vers {1}".format(fromPath, toPath)
402 self.parent.pushCmdSignal.emit(ud.getOwner(), cmd)
403 destpath1=os.path.join(toPath, os.path.basename(f))
404 if os.path.isdir(fromPath):
405 errors=self.
copytree(fromPath, destpath1)
409 shutil.copy2(fromPath, destpath1)
410 except Exception
as err:
411 errors.extend((fromPath, destpath1, str(err)))
422 self.parent.popCmdSignal.emit(ud.getOwner(), msg)
443 def __init__(self,ud, fileList, subdir=".", dest="/tmp",
444 rootPath=
"/", logfile=
"/dev/null", parent=
None):
445 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
446 logfile=logfile, parent=parent)
461 def toDo(self, ud, fileList, subdir, dest, logfile):
464 fromPath=os.path.join(ud.ensureMounted(), f)
467 newName=
"%s_%s" %(owner,os.path.dirname(f))
469 toPath=os.path.join(dest,newName)
472 cmd=
"copying %s to %s" %(fromPath, toPath)
474 self.parent.pushCmdSignal.emit(ud.getOwner(), cmd)
475 destpath1=os.path.join(toPath, os.path.basename(f))
476 if os.path.isdir(fromPath):
477 errors=self.
copytree(fromPath, destpath1, erase=
True)
480 except Exception
as err:
481 errors.extend((fromPath, destpath1, str(err)))
485 shutil.copy2(fromPath, destpath1)
487 except Exception
as err:
488 errors.extend((fromPath, destpath1, str(err)))
499 self.parent.popCmdSignal.emit(ud.getOwner(), msg)
518 def __init__(self,ud, fileList, subdir, logfile="/dev/null",
520 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None,
521 logfile=logfile, parent=parent)
536 def toDo(self, ud, fileList, subdir, dest, logfile):
538 toDel=os.path.join(ud.ensureMounted(), f)
539 cmd=
"Effacement de {0}".format(toDel)
542 self.parent.pushCmdSignal.emit(ud.getOwner(), cmd)
543 if os.path.isdir(toDel):
545 for root, dirs, files
in os.walk(toDel, topdown=
False):
547 os.remove(os.path.join(root, name))
549 os.rmdir(os.path.join(root, name))
551 except Exception
as err:
552 errors.expand((toDel,str(err)))
556 except Exception
as err:
557 errors.expand((toDel,str(err)))
567 self.parent.popCmdSignal.emit(ud.getOwner(), msg)
570 if __name__==
"__main__":
571 import sys, ownedUsbDisk, subprocess
577 if len(sys.argv) < 3:
578 print(
"Usage : %s répertoire_source répertoire_destination" %sys.argv[0])
579 print(
"Ça doit créer sous répertoire_destination la même arborescence que sous répertoire_source")
580 print(
"et ça crée répertoire_destination à la volée si nécessaire.")
582 errors=t.copytree(sys.argv[1],sys.argv[2])
583 print(
"Erreurs = %s" %errors)
584 subprocess.call (
"diff -ruN %s %s" %(sys.argv[1],sys.argv[2]), shell=
True)
585 print (
"Ne pas oublier d'effacer %s si nécessaire" %sys.argv[2])
593 if len(sys.argv) < 3:
594 print(
"Usage : %s fichier répertoire_destination" %sys.argv[0])
595 print(
"Ça doit créer sous répertoire_destination une copie du fichier")
596 print(
"et ça crée répertoire_destination à la volée si nécessaire.")
599 dstname=os.path.join(sys.argv[2],sys.argv[1])
600 shutil.copy2(srcname, dstname)
601 print (
"fin de la copie de %s vers %s, listing de %s" %(sys.argv[1],sys.argv[2],sys.argv[2]))
602 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