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
 
   37     os.path.isdir(destpath) 
or os.makedirs(destpath, mode=0o755)
 
   52         return "ThreadRegister: %s" %self.
dico 
   59     def push(self, ud, thread):
 
   60         if ud.getOwner() 
not in self.
dico.keys():
 
   61             self.
dico[ud.getOwner()]=[thread]
 
   63             self.
dico[ud.getOwner()].append(thread)
 
   70     def pop(self, ud, thread):
 
   71         self.
dico[ud.getOwner()].remove(thread)
 
   79         if owner 
in self.
dico.keys():
 
   80             return self.
dico[owner]
 
   88         for o 
in self.
dico.keys():
 
   89             for t 
in self.
dico[o]:
 
  101 def _sanitizePath(path):
 
  102     pattern=re.compile(
".*([^/]+)")
 
  103     m=pattern.match(str(path))
 
  107         return str(path).replace(
'/',
'_')
 
  119     if hasattr(ud, 
"path"):
 
  120         name=
"th_%04d_%s" %(_threadNumber,_sanitizePath(ud.path))
 
  122         name=
"th_%04d_%s" %(_threadNumber,
"dummy")
 
  133     return time.strftime(
"%Y/%m/%d-%H:%M:%S")
 
  159     def __init__(self,ud, fileList, subdir, dest=None, logfile="/dev/null",
 
  161         threading.Thread.__init__(self, name=_threadName(ud))
 
  162         self.
_args=(ud, fileList, subdir, dest, logfile)
 
  164         if hasattr(ud,
"threadRunning"): ud.threadRunning=
True 
  180         open(os.path.expanduser(self.
logfile),
"a").write(msg+
"\n")
 
  195     def copytree(self,src, dst, symlinks=False, ignore=None, erase=False, errors=[]):
 
  196         names = os.listdir(src)
 
  197         if ignore 
is not None:
 
  198             ignored_names = ignore(src, names)
 
  200             ignored_names = set()
 
  204         except OSError 
as err:
 
  207             if name 
in ignored_names:
 
  209             srcname = os.path.join(src, name)
 
  210             dstname = os.path.join(dst, name)
 
  212                 if symlinks 
and os.path.islink(srcname):
 
  213                     linkto = os.readlink(srcname)
 
  214                     os.symlink(linkto, dstname)
 
  215                     if not errors 
and erase:
 
  217                 elif os.path.isdir(srcname):
 
  218                     errors=self.
copytree(srcname, dstname,
 
  219                                          symlinks=symlinks, ignore=ignore,
 
  220                                          erase=erase, errors=errors)
 
  221                     if not errors 
and erase:
 
  224                     shutil.copy2(srcname, dstname)
 
  225                     if not errors 
and erase:
 
  228             except IOError 
as why:
 
  229                 errors.append((srcname, dstname, str(why)))
 
  232             except os.error 
as why:
 
  233                 errors.append((srcname, dstname, str(why)))
 
  236             except Exception 
as err:
 
  237                 errors.extend(err.args[0])
 
  247         result+=
"  ud       = %s\n" %self.
ud 
  248         result+=
"  fileList = %s\n" %self.
fileList 
  249         result+=
"  subdir   = %s\n" %self.
subdir 
  250         result+=
"  dest     = %s\n" %self.
dest 
  251         result+=
"  logfile  = %s\n" %self.
logfile 
  260         return "abstractThreadUSB" 
  270     def toDo(self, ud, fileList, subdir, dest, logfile):
 
  277 class threadCopyToUSB(abstractThreadUSB):
 
  288     def __init__(self,ud, fileList, subdir, logfile="/dev/null",
 
  290         abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None, logfile=logfile, parent=parent)
 
  296         return "threadCopyToUSB" 
  309     def toDo(self, ud, fileList, subdir, dest, logfile):
 
  310         while subdir[0]==
'/':
 
  312         destpath=os.path.join(ud.ensureMounted(),ud.visibleDir(),subdir)
 
  316             cmd=
"Copie de {0} vers {1}".format(f, destpath)
 
  318                 self.
parent.pushCmdSignal.emit(ud.getOwner(), cmd)
 
  319             destpath1=os.path.join(destpath, os.path.basename(f))
 
  326                     shutil.copy2(f, destpath1)
 
  327                 except Exception 
as err:
 
  328                     errors.append([f, destpath1, str(err)])
 
  337                 msg+= 
" <%s>" %str(e)
 
  339                 self.
parent.popCmdSignal.emit(ud.getOwner(), cmd)
 
  358     def __init__(self,ud, fileList, subdir=".", dest="/tmp",
 
  359                  rootPath="/", logfile="/dev/null", parent=None):
 
  360         abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
 
  361                                    logfile=logfile, parent=parent)
 
  374     def toDo(self, ud, fileList, subdir, dest, logfile):
 
  377             fromPath=os.path.join(ud.ensureMounted(), f)
 
  380             newName=
"%s_%s" %(owner,os.path.dirname(f))
 
  382             toPath=os.path.join(dest,newName)
 
  385             cmd=
"Copie de {0} vers {1}".format(fromPath, toPath)
 
  387                 self.
parent.pushCmdSignal.emit(ud.getOwner(), cmd)
 
  388             destpath1=os.path.join(toPath, os.path.basename(f))
 
  389             if os.path.isdir(fromPath):
 
  390                 errors=self.
copytree(fromPath, destpath1)
 
  394                     shutil.copy2(fromPath, destpath1)
 
  395                 except Exception 
as err:
 
  396                     errors.extend((fromPath, destpath1, str(err)))
 
  407                 self.
parent.popCmdSignal.emit(ud.getOwner(), msg)
 
  426     def __init__(self,ud, fileList, subdir=".", dest="/tmp",
 
  427                  rootPath="/", logfile="/dev/null", parent=None):
 
  428         abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
 
  429                                    logfile=logfile, parent=parent)
 
  443     def toDo(self, ud, fileList, subdir, dest, logfile):
 
  446             fromPath=os.path.join(ud.ensureMounted(), f)
 
  449             newName=
"%s_%s" %(owner,os.path.dirname(f))
 
  451             toPath=os.path.join(dest,newName)
 
  454             cmd=
"copying %s to %s" %(fromPath, toPath)
 
  456                 self.
parent.pushCmdSignal.emit(ud.getOwner(), cmd)
 
  457             destpath1=os.path.join(toPath, os.path.basename(f))
 
  458             if os.path.isdir(fromPath):
 
  459                 errors=self.
copytree(fromPath, destpath1, erase=
True)
 
  462                 except Exception 
as err:
 
  463                     errors.extend((fromPath, destpath1, str(err)))
 
  467                     shutil.copy2(fromPath, destpath1)
 
  469                 except Exception 
as err:
 
  470                     errors.extend((fromPath, destpath1, str(err)))
 
  481                 self.
parent.popCmdSignal.emit(ud.getOwner(), msg)
 
  498     def __init__(self,ud, fileList, subdir, logfile="/dev/null",
 
  500         abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=
None,
 
  501                                    logfile=logfile, parent=parent)
 
  515     def toDo(self, ud, fileList, subdir, dest, logfile):
 
  517             toDel=os.path.join(ud.ensureMounted(), f)
 
  518             cmd=
"Effacement de {0}".format(toDel)
 
  521                 self.
parent.pushCmdSignal.emit(ud.getOwner(), cmd)
 
  522             if os.path.isdir(toDel):
 
  524                     for root, dirs, files 
in os.walk(toDel, topdown=
False):
 
  526                             os.remove(os.path.join(root, name))
 
  528                             os.rmdir(os.path.join(root, name))
 
  530                 except Exception 
as err:
 
  531                     errors.expand((toDel,str(err)))
 
  535                 except Exception 
as err:
 
  536                     errors.expand((toDel,str(err)))
 
  546                 self.
parent.popCmdSignal.emit(ud.getOwner(), msg)
 
  549 if __name__==
"__main__":
 
  550     import sys, ownedUsbDisk, subprocess
 
  555         if len(sys.argv) < 3:
 
  556             print(
"Usage : %s répertoire_source répertoire_destination" %sys.argv[0])
 
  557             print(
"Ça doit créer sous répertoire_destination la même arborescence que sous répertoire_source")
 
  558             print(
"et ça crée répertoire_destination à la volée si nécessaire.")
 
  560         errors=t.copytree(sys.argv[1],sys.argv[2])
 
  561         print(
"Erreurs = %s" %errors)
 
  562         subprocess.call (
"diff -ruN %s %s" %(sys.argv[1],sys.argv[2]), shell=
True)
 
  563         print (
"Ne pas oublier d'effacer %s si nécessaire" %sys.argv[2])
 
  570         if len(sys.argv) < 3:
 
  571             print(
"Usage : %s fichier répertoire_destination" %sys.argv[0])
 
  572             print(
"Ça doit créer sous répertoire_destination une copie du fichier")
 
  573             print(
"et ça crée répertoire_destination à la volée si nécessaire.")
 
  576         dstname=os.path.join(sys.argv[2],sys.argv[1])
 
  577         shutil.copy2(srcname, dstname)
 
  578         print (
"fin de la copie de %s vers %s, listing de %s" %(sys.argv[1],sys.argv[2],sys.argv[2]))
 
  579         subprocess.call(
"ls %s" %sys.argv[2], shell=
True)