def fetch(self,srcbox,dryrun=True): print "ltr: pull ", srcbox.fspath queue=[] updates = [] wanted = [] import datetime time = datetime.datetime.now() queue.append((srcbox,self)) targetfilter = lambda n: n.boxname == self.id sourcefilter = lambda n: n.boxname == srcbox.id while len(queue): (source,target)= queue.pop(0) source = dictbyname(filter(sourcefilter,source.children())) target = dictbyname(filter(targetfilter,target.children())) srcunique = set(source.keys()) - set(target.keys()) common = set(target.keys()) & set(source.keys()) for filename in common: #fixme, query DB for matching size,hash tuples current = source[filename] updating = target[filename] if LtrNode.SKIP_FLAG in updating.flags: continue diff = updating.diff(current) if diff != []: show("M %s %s\n" %(current.getVolPath(),diff)) wanted.append((current,updating)) if updating.ftype == "dir": queue.append((current,updating)) # nodes absent but wanted for filename in srcunique: current = source[filename] absent = LtrNode().new() absent.name = current.name absent.path = current.path absent.boxname = self.id absent.addtime = time show("w %s\n" %(absent.getVolPath())) if current.ftype == "dir": queue.append((current,absent)) wanted.append((current,absent)) print "ltr: copying %d files" % len(wanted) for (current,updating) in wanted: src = os.path.join(srcbox.fspath,current.getVolPath().strip("/")) dst = os.path.join(self.fspath,updating.getVolPath().strip("/")) if current.ftype != "dir": print "cp %s %s " % (src,dst) if not dryrun: shutil.copy2(src,dst) try: shutil.copy2(src,dst) except: print "error" else: print "mkdir %s " % dst if not dryrun: os.mkdir(dst) if not LtrNode.COPY_FLAG in updating.flags: updating.flags.append(LtrNode.COPY_FLAG) if LtrNode.SKIP_FLAG in updating.flags: updating.flags.remove(LtrNode.SKIP_FLAG) updating.log.append({"dt": time, "etype": "pull", "old":current.id}) updating.updateDrop(current) updates.append(updating) if not dryrun: print "." * len(updates) self.space.records.update(updates) if len(updates): #import pprint #pprint.pprint(updates) return True else: return False