00001
00002
00003
00004 licenceEn="""
00005 file usbThread.py
00006 this file is part of the project scolasync
00007
00008 Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>
00009
00010 This program is free software: you can redistribute it and/or modify
00011 it under the terms of the GNU General Public License as published by
00012 the Free Software Foundation, either version3 of the License, or
00013 (at your option) any later version.
00014
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 GNU General Public License for more details.
00019
00020 You should have received a copy of the GNU General Public License
00021 along with this program. If not, see <http://www.gnu.org/licenses/>.
00022 """
00023
00024 import subprocess, threading, re, os.path, time
00025
00026 _threadNumber=0
00027
00028
00029
00030
00031
00032 class ThreadRegister:
00033
00034
00035
00036
00037
00038 def __init__(self):
00039 self.dico={}
00040
00041 def __str__(self):
00042 return "ThreadRegister: %s" %self.dico
00043
00044
00045
00046
00047
00048
00049
00050 def push(self, ud, thread):
00051 if ud.owner not in self.dico.keys():
00052 self.dico[ud.owner]=[thread]
00053 else:
00054 self.dico[ud.owner].append(thread)
00055
00056
00057
00058
00059
00060
00061
00062 def pop(self, ud, thread):
00063 self.dico[ud.owner].remove(thread)
00064
00065
00066
00067
00068
00069
00070
00071 def busy(self, owner):
00072 if owner in self.dico.keys():
00073 return self.dico[owner]
00074 return []
00075
00076
00077
00078
00079
00080 def threadSet(self):
00081 result=set()
00082 for o in self.dico.keys():
00083 for t in self.dico[o]:
00084 result.add(t)
00085 return result
00086
00087 globalThreads=ThreadRegister()
00088
00089
00090
00091
00092
00093
00094
00095
00096 def _sanitizePath(path):
00097 pattern=re.compile(".*([^/]+)")
00098 m=pattern.match(str(path))
00099 if m:
00100 return m.group(1)
00101 else:
00102 return str(path).replace('/','_')
00103
00104
00105
00106
00107
00108
00109
00110
00111 def _threadName(ud):
00112 global _threadNumber
00113 name="th_%04d_%s" %(_threadNumber,_sanitizePath(ud.path))
00114 _threadNumber+=1
00115 return name
00116
00117
00118
00119
00120
00121
00122 def _date():
00123 return time.strftime("%Y/%m/%d-%H:%M:%S")
00124
00125
00126
00127
00128
00129
00130
00131 def _call(cmd, logfile):
00132 for command in cmd.split(";"):
00133 okToLog="echo [%s] Success: %s >> %s" %(_date(), command, logfile)
00134 koToLog="echo [%s] Error: %s >> %s" %(_date(), command, logfile)
00135 cmd1="(%s && %s) || %s" %(command, okToLog, koToLog)
00136 subprocess.call(cmd1, shell=True)
00137
00138
00139
00140
00141
00142
00143
00144 class abstractThreadUSB(threading.Thread):
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 def __init__(self,ud, fileList, subdir, dest=None, logfile="/dev/null"):
00156 threading.Thread.__init__(self,target=self.toDo,
00157 args=(ud, fileList, subdir, dest, logfile),
00158 name=_threadName(ud))
00159 self.cmd=u"echo This is an abstract method, don't call it"
00160 self.ud=ud
00161 ud.threadRunning=True
00162 self.fileList=fileList
00163 self.subdir=subdir
00164 self.dest=dest
00165 self.logfile=logfile
00166
00167
00168
00169
00170
00171
00172
00173 def __str__(self):
00174 result="%s(\n" %self.threadType()
00175 result+=" ud = %s\n" %self.ud
00176 result+=" fileList = %s\n" %self.fileList
00177 result+=" subdir = %s\n" %self.subdir
00178 result+=" dest = %s\n" %self.dest
00179 result+=" logfile = %s\n" %self.logfile
00180 result+=" cmd = %s\n" %self.cmd
00181 result+="\n"
00182 return result
00183
00184
00185
00186
00187
00188 def threadType(self):
00189 return "abstractThreadUSB"
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 def toDo(self, ud, fileList, subdir, dest, logfile):
00201
00202 pass
00203
00204
00205
00206
00207
00208 class threadCopyToUSB(abstractThreadUSB):
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 def __init__(self,ud, fileList, subdir, logfile="/dev/null"):
00219 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=None, logfile=logfile)
00220 self.cmd=u"mkdir -p '{toDir}'; cp -R '{fromFile}' '{toFile}'"
00221
00222
00223
00224
00225
00226 def threadType(self):
00227 return "threadCopyToUSB"
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 def toDo(self, ud, fileList, subdir, dest, logfile):
00242 global globalThreads
00243 globalThreads.push(ud, self)
00244 while subdir[0]=='/':
00245 subdir=subdir[1:]
00246 destpath=os.path.join(ud.ensureMounted(),ud.visibleDir(),subdir)
00247 for f in fileList:
00248 fileName=os.path.basename(f)
00249 cmd=self.cmd.format(fromFile=f,
00250 toDir=destpath,
00251 toFile=os.path.join(destpath,fileName))
00252 _call(cmd,logfile)
00253 globalThreads.pop(ud, self)
00254
00255
00256
00257
00258
00259 class threadCopyFromUSB(abstractThreadUSB):
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 def __init__(self,ud, fileList, subdir=".", dest="/tmp",
00272 rootPath="/", logfile="/dev/null"):
00273 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=dest,
00274 logfile=logfile)
00275 self.rootPath=rootPath
00276 self.cmd=u"mkdir -p '{toDir}'; cp -R '{fromPath}' '{toPath}'"
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 def toDo(self, ud, fileList, subdir, dest, logfile):
00290 global globalThreads
00291 globalThreads.push(ud, self)
00292 for f in fileList:
00293
00294 fromPath=os.path.join(ud.ensureMounted(), f)
00295 owner=ud.ownerByDb()
00296
00297 newName=u"%s_%s" %(owner,f)
00298
00299 toPath=os.path.join(dest,newName)
00300 toDir=os.path.dirname(toPath)
00301 cmd=self.cmd.format(fromPath=fromPath, toPath=toPath, toDir=toDir)
00302 _call(cmd,logfile)
00303 globalThreads.pop(ud, self)
00304
00305
00306
00307
00308
00309 class threadDeleteInUSB(abstractThreadUSB):
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 def __init__(self,ud, fileList, subdir, logfile="/dev/null"):
00320 abstractThreadUSB.__init__(self,ud, fileList, subdir, dest=None, logfile=logfile)
00321 self.cmd=u"rm -rf '{toDel}'"
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 def toDo(self, ud, fileList, subdir, dest, logfile):
00337 global globalThreads
00338 globalThreads.push(ud, self)
00339 for f in fileList:
00340 toDel=os.path.join(ud.ensureMounted(), f)
00341 cmd=self.cmd.format(toDel=toDel)
00342 _call(cmd,logfile)
00343 globalThreads.pop(ud, self)
00344