def complete(self): repos = self.link.repos text_deltas = True depth = None print "XX: %s" % self.args if len(self.args[0]) == 0: rev = repos.get_latest_rev() else: rev = int(self.args[0][0]) path = parse.string(self.args[1]) recurse = parse.bool(self.args[2]) ignore_ancestry = parse.bool(self.args[3]) url = parse.string(self.args[4]) if len(self.args) > 5: ignore_ancestry = parse.bool(self.args[5]) if len(self.args) > 6: depth = self.args[6] self.link.send_msg(gen.tuple('target-rev', rev)) self.send_response(path, url, rev)
def send_response(self, path, url, rev): repos = self.link.repos self.sendq = Queue.Queue() self.waitq = Queue.Queue() thread = threading.Thread(target=send_thread, args=(self.link, self.sendq, self.waitq)) thread.start() import time t1 = time.time() print "get contents" contents = repos.get_files(url, rev) print len(contents) t2 = time.time() print t2 - t1 print "start sending" self.update_dir('', rev, path, [], contents) print "all sends now queued" t3 = time.time() print t3 - t2 print t3 - t1 self.sendq.put(None) print "wait for sending thread" self.waitq.get() print "send close-edit message" self.link.send_msg(gen.tuple('close-edit')) msg = parse.msg(self.link.read_msg()) if msg[0] != 'success': errno = msg[1][0][0] errmsg = parse.string(msg[1][0][1]) self.link.send_msg(gen.tuple('abort-edit')) self.link.send_msg(gen.error(errno, errmsg)) else: self.link.send_msg(gen.success())
def complete(self): repos = self.link.repos url = self.link.url depth = None send_copyfrom = False print "XX: %s" % self.args if len(self.args[0]) == 0: rev = repos.get_latest_rev() else: rev = int(self.args[0][0]) path = parse.string(self.args[1]) recurse = self.args[2] == 'true' if len(self.args) > 3: depth = self.args[3] send_copyfrom = parse.bool(self.args[4]) self.link.send_msg(gen.tuple('target-rev', rev)) self.send_response(path, url, rev)
def update_dir(self, path, rev, want, props, contents, parent_token=None): repos = self.link.repos url = '/'.join((self.link.url, path)) newurl = '/'.join((self.newurl, path)) if '/' in want: want_head, want_tail = want.split('/', 1) else: want_head, want_tail = want, '' new_dir = True token = self.get_token(path) prev_rev, start_empty = self.get_prev(path) if prev_rev is None: new_dir = True elif not repos.paths_different(newurl, rev, url, prev_rev) \ and not self.get_prev_subpath_empty(path): return else: stat = repos.stat(url, prev_rev) new_dir = stat[0] is None if parent_token is None: self.send(gen.tuple('open-root', gen.list(rev), gen.string(token))) props = repos.get_props(url, rev) contents = contents[3] elif new_dir: self.send(gen.tuple('add-dir', gen.string(path), gen.string(parent_token), gen.string(token), '( )')) prev_rev = None else: self.send(gen.tuple('open-dir', gen.string(path), gen.string(parent_token), gen.string(token), gen.list(rev))) prev_props = {} if prev_rev is not None and not start_empty: for name, value in repos.get_props(url, prev_rev): prev_props[name] = value for name, value in props: if name in prev_props: if prev_props[name] == value: del prev_props[name] continue del prev_props[name] self.send(gen.tuple('change-dir-prop', gen.string(token), gen.string(name), gen.list(gen.string(value)))) for name in prev_props.keys(): self.send(gen.tuple('change-dir-prop', gen.string(token), gen.string(name), gen.list())) current_names = [] for name, kind, props, content in contents: if len(want_head) > 0 and want_head != name: continue current_names.append(name) entry_path = name if len(path) > 0: entry_path = '/'.join((path, name)) if kind == 'dir': self.update_dir(entry_path, rev, want_tail, props, content, token) elif kind == 'file': self.update_file(entry_path, rev, props, content, token) else: raise foo if prev_rev is not None and not start_empty: for entry in repos.ls(url, prev_rev, include_changed=False): name, kind, size, last_rev, last_author, last_date = entry if len(want_head) > 0 and want_head != name: continue if name not in current_names: entry_path = name if len(path) > 0: entry_path = '/'.join((path, name)) if entry_path in self.deleted_paths: continue self.send(gen.tuple('delete-entry', gen.string(entry_path), gen.list(prev_rev), gen.string(token))) self.send(gen.tuple('close-dir', gen.string(token)))
def update_file(self, path, rev, props, contents, parent_token): repos = self.link.repos url = '/'.join((self.link.url, path)) newurl = '/'.join((self.newurl, path)) token = self.get_token(path) prev_rev, start_empty = self.get_prev(path) if prev_rev is None: prev_pl = [] prev_contents = None elif not repos.paths_different(newurl, rev, url, prev_rev): contents.close() return else: prev_rev, prev_pl, prev_contents = repos.get_file(url, prev_rev) new_file = prev_contents is None if new_file: self.send(gen.tuple('add-file', gen.string(path), gen.string(parent_token), gen.string(token), '( )')) else: self.send(gen.tuple('open-file', gen.string(path), gen.string(parent_token), gen.string(token), gen.list(rev))) self.send(gen.tuple('apply-textdelta', gen.string(token), '( )')) diff_version = 0 if 'svndiff1' in self.link.client_caps: diff_version = 1 encoder = svndiff.Encoder(contents, prev_contents, version=diff_version) diff_chunk = encoder.get_chunk() count = 0 while diff_chunk is not None: count += 1 self.send(gen.tuple('textdelta-chunk', gen.string(token), gen.string(diff_chunk))) if count > 2: print "send chunk %d %d" % (count, len(diff_chunk)) diff_chunk = encoder.get_chunk() csum = encoder.get_md5() if prev_contents: prev_contents.close() contents.close() self.send(gen.tuple('textdelta-end', gen.string(token))) prev_props = {} for name, value in prev_pl: prev_props[name] = value for name, value in props: if name in prev_props: if prev_props[name] == value: del prev_props[name] continue del prev_props[name] self.send(gen.tuple('change-file-prop', gen.string(token), gen.string(name), gen.list(gen.string(value)))) for name in prev_props.keys(): self.send(gen.tuple('change-file-prop', gen.string(token), gen.string(name), gen.list())) self.send(gen.tuple('close-file', gen.string(token), gen.list(gen.string(csum))))
def update_dir(self, path, rev, want, props, contents, parent_token=None): repos = self.link.repos url = '/'.join((self.link.url, path)) newurl = '/'.join((self.newurl, path)) if '/' in want: want_head, want_tail = want.split('/', 1) else: want_head, want_tail = want, '' new_dir = True token = self.get_token(path) prev_rev, start_empty = self.get_prev(path) if prev_rev is None: new_dir = True elif not repos.paths_different(newurl, rev, url, prev_rev) \ and not self.get_prev_subpath_empty(path): return else: stat = repos.stat(url, prev_rev) new_dir = stat[0] is None if parent_token is None: self.send(gen.tuple('open-root', gen.list(rev), gen.string(token))) props = repos.get_props(url, rev) contents = contents[3] elif new_dir: self.send( gen.tuple('add-dir', gen.string(path), gen.string(parent_token), gen.string(token), '( )')) prev_rev = None else: self.send( gen.tuple('open-dir', gen.string(path), gen.string(parent_token), gen.string(token), gen.list(rev))) prev_props = {} if prev_rev is not None and not start_empty: for name, value in repos.get_props(url, prev_rev): prev_props[name] = value for name, value in props: if name in prev_props: if prev_props[name] == value: del prev_props[name] continue del prev_props[name] self.send( gen.tuple('change-dir-prop', gen.string(token), gen.string(name), gen.list(gen.string(value)))) for name in prev_props.keys(): self.send( gen.tuple('change-dir-prop', gen.string(token), gen.string(name), gen.list())) current_names = [] for name, kind, props, content in contents: if len(want_head) > 0 and want_head != name: continue current_names.append(name) entry_path = name if len(path) > 0: entry_path = '/'.join((path, name)) if kind == 'dir': self.update_dir(entry_path, rev, want_tail, props, content, token) elif kind == 'file': self.update_file(entry_path, rev, props, content, token) else: raise foo if prev_rev is not None and not start_empty: for entry in repos.ls(url, prev_rev, include_changed=False): name, kind, size, last_rev, last_author, last_date = entry if len(want_head) > 0 and want_head != name: continue if name not in current_names: entry_path = name if len(path) > 0: entry_path = '/'.join((path, name)) if entry_path in self.deleted_paths: continue self.send( gen.tuple('delete-entry', gen.string(entry_path), gen.list(prev_rev), gen.string(token))) self.send(gen.tuple('close-dir', gen.string(token)))
def update_file(self, path, rev, props, contents, parent_token): repos = self.link.repos url = '/'.join((self.link.url, path)) newurl = '/'.join((self.newurl, path)) token = self.get_token(path) prev_rev, start_empty = self.get_prev(path) if prev_rev is None: prev_pl = [] prev_contents = None elif not repos.paths_different(newurl, rev, url, prev_rev): contents.close() return else: prev_rev, prev_pl, prev_contents = repos.get_file(url, prev_rev) new_file = prev_contents is None if new_file: self.send( gen.tuple('add-file', gen.string(path), gen.string(parent_token), gen.string(token), '( )')) else: self.send( gen.tuple('open-file', gen.string(path), gen.string(parent_token), gen.string(token), gen.list(rev))) self.send(gen.tuple('apply-textdelta', gen.string(token), '( )')) diff_version = 0 if 'svndiff1' in self.link.client_caps: diff_version = 1 encoder = svndiff.Encoder(contents, prev_contents, version=diff_version) diff_chunk = encoder.get_chunk() count = 0 while diff_chunk is not None: count += 1 self.send( gen.tuple('textdelta-chunk', gen.string(token), gen.string(diff_chunk))) if count > 2: print "send chunk %d %d" % (count, len(diff_chunk)) diff_chunk = encoder.get_chunk() csum = encoder.get_md5() if prev_contents: prev_contents.close() contents.close() self.send(gen.tuple('textdelta-end', gen.string(token))) prev_props = {} for name, value in prev_pl: prev_props[name] = value for name, value in props: if name in prev_props: if prev_props[name] == value: del prev_props[name] continue del prev_props[name] self.send( gen.tuple('change-file-prop', gen.string(token), gen.string(name), gen.list(gen.string(value)))) for name in prev_props.keys(): self.send( gen.tuple('change-file-prop', gen.string(token), gen.string(name), gen.list())) self.send( gen.tuple('close-file', gen.string(token), gen.list(gen.string(csum))))