eric6/MicroPython/MicroPythonFileManager.py

changeset 7174
de8175253dfc
parent 7139
9bb36ec2d1b5
child 7229
53054eb5b15a
equal deleted inserted replaced
7173:f611c3b7313f 7174:de8175253dfc
174 self.deleteFileDone.emit(deviceFileName) 174 self.deleteFileDone.emit(deviceFileName)
175 except Exception as exc: 175 except Exception as exc:
176 self.error.emit("delete", str(exc)) 176 self.error.emit("delete", str(exc))
177 177
178 def __rsync(self, hostDirectory, deviceDirectory, mirror=True, 178 def __rsync(self, hostDirectory, deviceDirectory, mirror=True,
179 localDevice=False): 179 localDevice=False, indentLevel=0):
180 """ 180 """
181 Private method to synchronize a local directory to the device. 181 Private method to synchronize a local directory to the device.
182 182
183 @param hostDirectory name of the local directory 183 @param hostDirectory name of the local directory
184 @type str 184 @type str
187 @param mirror flag indicating to mirror the local directory to 187 @param mirror flag indicating to mirror the local directory to
188 the device directory 188 the device directory
189 @type bool 189 @type bool
190 @param localDevice flag indicating device access via local file system 190 @param localDevice flag indicating device access via local file system
191 @type bool 191 @type bool
192 @param indentLevel indentation level for progress messages
193 @type int
192 @return list of errors 194 @return list of errors
193 @rtype list of str 195 @rtype list of str
194 """ 196 """
197 indent = 4 * " "
195 errors = [] 198 errors = []
196 199
197 if not os.path.isdir(hostDirectory): 200 if not os.path.isdir(hostDirectory):
198 return [self.tr( 201 return [self.tr(
199 "The given name '{0}' is not a directory or does not exist.") 202 "The given name '{0}' is not a directory or does not exist.")
200 .format(hostDirectory) 203 .format(hostDirectory)
201 ] 204 ]
202 205
206 indentStr = indentLevel * indent
203 self.rsyncProgressMessage.emit( 207 self.rsyncProgressMessage.emit(
204 self.tr("Synchronizing <b>{0}</b>.").format(deviceDirectory) 208 self.tr("{1}Synchronizing <b>{0}</b>.")
209 .format(deviceDirectory, indentStr)
205 ) 210 )
206 211
207 doneMessage = self.tr("Done synchronizing <b>{0}</b>.").format( 212 doneMessage = self.tr("{1}Done synchronizing <b>{0}</b>.").format(
208 deviceDirectory) 213 deviceDirectory, indentStr)
209 214
210 sourceDict = {} 215 sourceDict = {}
211 sourceFiles = listdirStat(hostDirectory) 216 sourceFiles = listdirStat(hostDirectory)
212 for name, nstat in sourceFiles: 217 for name, nstat in sourceFiles:
213 sourceDict[name] = nstat 218 sourceDict[name] = nstat
242 destinationSet = set(destinationDict.keys()) 247 destinationSet = set(destinationDict.keys())
243 sourceSet = set(sourceDict.keys()) 248 sourceSet = set(sourceDict.keys())
244 toAdd = sourceSet - destinationSet # add to dev 249 toAdd = sourceSet - destinationSet # add to dev
245 toDelete = destinationSet - sourceSet # delete from dev 250 toDelete = destinationSet - sourceSet # delete from dev
246 toUpdate = destinationSet.intersection(sourceSet) # update files 251 toUpdate = destinationSet.intersection(sourceSet) # update files
252 indentStr = (indentLevel + 1) * indent
247 253
248 if localDevice: 254 if localDevice:
249 for sourceBasename in toAdd: 255 for sourceBasename in toAdd:
250 # name exists in source but not in device 256 # name exists in source but not in device
251 sourceFilename = os.path.join(hostDirectory, sourceBasename) 257 sourceFilename = os.path.join(hostDirectory, sourceBasename)
252 destFilename = os.path.join(deviceDirectory, sourceBasename) 258 destFilename = os.path.join(deviceDirectory, sourceBasename)
253 self.rsyncProgressMessage.emit( 259 self.rsyncProgressMessage.emit(
254 self.tr("Adding <b>{0}</b>...").format(destFilename)) 260 self.tr("{1}Adding <b>{0}</b>...")
261 .format(destFilename, indentStr))
255 if os.path.isfile(sourceFilename): 262 if os.path.isfile(sourceFilename):
256 shutil.copy2(sourceFilename, destFilename) 263 shutil.copy2(sourceFilename, destFilename)
257 elif os.path.isdir(sourceFilename): 264 elif os.path.isdir(sourceFilename):
258 # recurse 265 # recurse
259 errs = self.__rsync(sourceFilename, destFilename, 266 errs = self.__rsync(sourceFilename, destFilename,
260 mirror=mirror, localDevice=localDevice) 267 mirror=mirror, localDevice=localDevice,
268 indentLevel=indentLevel + 1)
261 # just note issues but ignore them otherwise 269 # just note issues but ignore them otherwise
262 errors.extend(errs) 270 errors.extend(errs)
263 271
264 if mirror: 272 if mirror:
265 for destBasename in toDelete: 273 for destBasename in toDelete:
280 if os.path.isdir(sourceFilename): 288 if os.path.isdir(sourceFilename):
281 if os.path.isdir(destFilename): 289 if os.path.isdir(destFilename):
282 # both are directories => recurs 290 # both are directories => recurs
283 errs = self.__rsync(sourceFilename, destFilename, 291 errs = self.__rsync(sourceFilename, destFilename,
284 mirror=mirror, 292 mirror=mirror,
285 localDevice=localDevice) 293 localDevice=localDevice,
294 indentLevel=indentLevel + 1)
286 # just note issues but ignore them otherwise 295 # just note issues but ignore them otherwise
287 errors.extend(errs) 296 errors.extend(errs)
288 else: 297 else:
289 self.rsyncProgressMessage.emit( 298 self.rsyncProgressMessage.emit(
290 self.tr("Source <b>{0}</b> is a directory and" 299 self.tr("Source <b>{0}</b> is a directory and"
309 shutil.copy2(sourceFilename, destFilename) 318 shutil.copy2(sourceFilename, destFilename)
310 else: 319 else:
311 for sourceBasename in toAdd: 320 for sourceBasename in toAdd:
312 # name exists in source but not in device 321 # name exists in source but not in device
313 sourceFilename = os.path.join(hostDirectory, sourceBasename) 322 sourceFilename = os.path.join(hostDirectory, sourceBasename)
314 destFilename = deviceDirectory + "/" + sourceBasename 323 if deviceDirectory == "/":
324 destFilename = "/" + sourceBasename
325 else:
326 destFilename = deviceDirectory + "/" + sourceBasename
315 self.rsyncProgressMessage.emit( 327 self.rsyncProgressMessage.emit(
316 self.tr("Adding <b>{0}</b>...").format(destFilename)) 328 self.tr("{1}Adding <b>{0}</b>...")
329 .format(destFilename, indentStr))
317 if os.path.isfile(sourceFilename): 330 if os.path.isfile(sourceFilename):
318 try: 331 try:
319 self.__commandsInterface.put(sourceFilename, 332 self.__commandsInterface.put(sourceFilename,
320 destFilename) 333 destFilename)
321 except Exception as exc: 334 except Exception as exc:
322 # just note issues but ignore them otherwise 335 # just note issues but ignore them otherwise
323 errors.append(str(exc)) 336 errors.append(str(exc))
324 elif os.path.isdir(sourceFilename): 337 elif os.path.isdir(sourceFilename):
325 # recurse 338 # recurse
326 errs = self.__rsync(sourceFilename, destFilename, 339 errs = self.__rsync(sourceFilename, destFilename,
327 mirror=mirror) 340 mirror=mirror,
341 indentLevel=indentLevel + 1)
328 # just note issues but ignore them otherwise 342 # just note issues but ignore them otherwise
329 errors.extend(errs) 343 errors.extend(errs)
330 344
331 if mirror: 345 if mirror:
332 for destBasename in toDelete: 346 for destBasename in toDelete:
333 # name exists in device but not local, delete 347 # name exists in device but not local, delete
334 destFilename = deviceDirectory + "/" + destBasename 348 if deviceDirectory == "/":
349 destFilename = "/" + sourceBasename
350 else:
351 destFilename = deviceDirectory + "/" + destBasename
335 self.rsyncProgressMessage.emit( 352 self.rsyncProgressMessage.emit(
336 self.tr("Removing <b>{0}</b>...").format(destFilename)) 353 self.tr("{1}Removing <b>{0}</b>...")
354 .format(destFilename, indentStr))
337 try: 355 try:
338 self.__commandsInterface.rmrf(destFilename, 356 self.__commandsInterface.rmrf(destFilename,
339 recursive=True, 357 recursive=True,
340 force=True) 358 force=True)
341 except Exception as exc: 359 except Exception as exc:
345 for sourceBasename in toUpdate: 363 for sourceBasename in toUpdate:
346 # names exist in both; do an update 364 # names exist in both; do an update
347 sourceStat = sourceDict[sourceBasename] 365 sourceStat = sourceDict[sourceBasename]
348 destStat = destinationDict[sourceBasename] 366 destStat = destinationDict[sourceBasename]
349 sourceFilename = os.path.join(hostDirectory, sourceBasename) 367 sourceFilename = os.path.join(hostDirectory, sourceBasename)
350 destFilename = deviceDirectory + "/" + sourceBasename 368 if deviceDirectory == "/":
369 destFilename = "/" + sourceBasename
370 else:
371 destFilename = deviceDirectory + "/" + sourceBasename
351 destMode = destStat[0] 372 destMode = destStat[0]
352 if os.path.isdir(sourceFilename): 373 if os.path.isdir(sourceFilename):
353 if stat.S_ISDIR(destMode): 374 if stat.S_ISDIR(destMode):
354 # both are directories => recurs 375 # both are directories => recurs
355 errs = self.__rsync(sourceFilename, destFilename, 376 errs = self.__rsync(sourceFilename, destFilename,
356 mirror=mirror) 377 mirror=mirror,
378 indentLevel=indentLevel + 1)
357 # just note issues but ignore them otherwise 379 # just note issues but ignore them otherwise
358 errors.extend(errs) 380 errors.extend(errs)
359 else: 381 else:
360 self.rsyncProgressMessage.emit( 382 self.rsyncProgressMessage.emit(
361 self.tr("Source <b>{0}</b> is a directory and" 383 self.tr("Source <b>{0}</b> is a directory and"
372 .format(sourceFilename, destFilename) 394 .format(sourceFilename, destFilename)
373 ) 395 )
374 else: 396 else:
375 if sourceStat[8] > destStat[8]: # mtime 397 if sourceStat[8] > destStat[8]: # mtime
376 self.rsyncProgressMessage.emit( 398 self.rsyncProgressMessage.emit(
377 self.tr("Updating <b>{0}</b>...") 399 self.tr("{1}Updating <b>{0}</b>...")
378 .format(destFilename) 400 .format(destFilename, indentStr)
379 ) 401 )
380 try: 402 try:
381 self.__commandsInterface.put(sourceFilename, 403 self.__commandsInterface.put(sourceFilename,
382 destFilename) 404 destFilename)
383 except Exception as exc: 405 except Exception as exc:

eric ide

mercurial