[py-svn] r36441 - py/dist/py/test/rsession
fijal at codespeak.net
fijal at codespeak.net
Wed Jan 10 22:39:43 CET 2007
Author: fijal
Date: Wed Jan 10 22:39:39 2007
New Revision: 36441
Added:
py/dist/py/test/rsession/rsync_remote.py
Modified:
py/dist/py/test/rsession/rsync.py
Log:
Move remote part of rsync to separate file.
Modified: py/dist/py/test/rsession/rsync.py
==============================================================================
--- py/dist/py/test/rsession/rsync.py (original)
+++ py/dist/py/test/rsession/rsync.py Wed Jan 10 22:39:39 2007
@@ -6,7 +6,7 @@
def __init__(self, **options):
for name in options:
- assert name in ('delete',)
+ assert name in ('delete','callback',)
self.options = options
self.channels = {}
self.receivequeue = Queue()
@@ -32,16 +32,7 @@
# send modified file to clients
while self.channels:
channel, req = self.receivequeue.get()
- if req == 42:
- for link in self.links:
- channel.send(link)
- # completion marker, this host is done
- channel.send(42)
- elif req == 41:
- finishedcallback = self.channels.pop(channel)
- if finishedcallback:
- finishedcallback()
- elif req is None:
+ if req is None:
# end-of-channel
if channel in self.channels:
# too early! we must have got an error
@@ -50,21 +41,36 @@
raise IOError('connection unexpectedly closed: %s ' % (
channel.gateway,))
else:
- modified_rel_path, checksum = req
- modifiedpath = os.path.join(self.sourcedir, *modified_rel_path)
- f = open(modifiedpath, 'rb')
- data = f.read()
- f.close()
- if checksum is not None and checksum == md5.md5(data).digest():
- data = None # not really modified
+ command, data = req
+ if command == "links":
+ for link in self.links:
+ channel.send(link)
+ # completion marker, this host is done
+ channel.send(42)
+ elif command == "done":
+ finishedcallback = self.channels.pop(channel)
+ if finishedcallback:
+ finishedcallback()
+ elif command == "ack":
+ pass
+ elif command == "send":
+ modified_rel_path, checksum = data
+ modifiedpath = os.path.join(self.sourcedir, *modified_rel_path)
+ f = open(modifiedpath, 'rb')
+ data = f.read()
+ f.close()
+ if checksum is not None and checksum == md5.md5(data).digest():
+ data = None # not really modified
+ else:
+ # ! there is a reason for the interning:
+ # sharing multiple copies of the file's data
+ data = intern(data)
+ #print channel.gateway.getremoteaddress(),
+ #print '/'.join(modified_rel_path)
+ channel.send(data)
+ del data
else:
- # ! there is a reason for the interning:
- # sharing multiple copies of the file's data
- data = intern(data)
- #print channel.gateway.getremoteaddress(),
- #print '/'.join(modified_rel_path)
- channel.send(data)
- del data
+ assert "Unknown command %s" % command
def _broadcast(self, msg):
for channel in self.channels:
@@ -104,87 +110,6 @@
else:
raise ValueError, "cannot sync %r" % (path,)
+REMOTE_SOURCE = py.path.local(__file__).dirpath().\
+ join('rsync_remote.py').open().read()
-REMOTE_SOURCE = """
- import os, stat, shutil, md5
- destdir, options = channel.receive()
- modifiedfiles = []
-
- def remove(path):
- assert path.startswith(destdir)
- try:
- os.unlink(path)
- except OSError:
- # assume it's a dir
- shutil.rmtree(path)
-
- def receive_directory_structure(path, relcomponents):
- try:
- st = os.lstat(path)
- except OSError:
- st = None
- msg = channel.receive()
- if isinstance(msg, list):
- if st and not stat.S_ISDIR(st.st_mode):
- os.unlink(path)
- st = None
- if not st:
- os.makedirs(path)
- entrynames = {}
- for entryname in msg:
- receive_directory_structure(os.path.join(path, entryname),
- relcomponents + [entryname])
- entrynames[entryname] = True
- if options.get('delete'):
- for othername in os.listdir(path):
- if othername not in entrynames:
- otherpath = os.path.join(path, othername)
- remove(otherpath)
- elif msg is not None:
- checksum = None
- if st:
- if stat.S_ISREG(st.st_mode):
- msg_mtime, msg_size = msg
- if msg_size != st.st_size:
- pass
- elif msg_mtime != st.st_mtime:
- f = open(path, 'rb')
- checksum = md5.md5(f.read()).digest()
- f.close()
- else:
- return # already fine
- else:
- remove(path)
- channel.send((relcomponents, checksum))
- modifiedfiles.append((path, msg))
- receive_directory_structure(destdir, [])
-
- STRICT_CHECK = False # seems most useful this way for py.test
-
- for path, (time, size) in modifiedfiles:
- data = channel.receive()
- if data is not None:
- if STRICT_CHECK and len(data) != size:
- raise IOError('file modified during rsync: %r' % (path,))
- f = open(path, 'wb')
- f.write(data)
- f.close()
- os.utime(path, (time, time))
- del data
- channel.send(42)
-
- msg = channel.receive()
- while msg is not 42:
- # we get symlink
- _type, relpath, linkpoint = msg
- assert _type == "link"
- path = os.path.join(destdir, relpath)
- try:
- os.unlink(path)
- except OSError:
- pass
-
- os.symlink(os.path.join(destdir, linkpoint), path)
- msg = channel.receive()
- channel.send(41)
-"""
Added: py/dist/py/test/rsession/rsync_remote.py
==============================================================================
--- (empty file)
+++ py/dist/py/test/rsession/rsync_remote.py Wed Jan 10 22:39:39 2007
@@ -0,0 +1,82 @@
+import os, stat, shutil, md5
+destdir, options = channel.receive()
+modifiedfiles = []
+
+def remove(path):
+ assert path.startswith(destdir)
+ try:
+ os.unlink(path)
+ except OSError:
+ # assume it's a dir
+ shutil.rmtree(path)
+
+def receive_directory_structure(path, relcomponents):
+ try:
+ st = os.lstat(path)
+ except OSError:
+ st = None
+ msg = channel.receive()
+ if isinstance(msg, list):
+ if st and not stat.S_ISDIR(st.st_mode):
+ os.unlink(path)
+ st = None
+ if not st:
+ os.makedirs(path)
+ entrynames = {}
+ for entryname in msg:
+ receive_directory_structure(os.path.join(path, entryname),
+ relcomponents + [entryname])
+ entrynames[entryname] = True
+ if options.get('delete'):
+ for othername in os.listdir(path):
+ if othername not in entrynames:
+ otherpath = os.path.join(path, othername)
+ remove(otherpath)
+ elif msg is not None:
+ checksum = None
+ if st:
+ if stat.S_ISREG(st.st_mode):
+ msg_mtime, msg_size = msg
+ if msg_size != st.st_size:
+ pass
+ elif msg_mtime != st.st_mtime:
+ f = open(path, 'rb')
+ checksum = md5.md5(f.read()).digest()
+ f.close()
+ else:
+ return # already fine
+ else:
+ remove(path)
+ channel.send(("send", (relcomponents, checksum)))
+ modifiedfiles.append((path, msg))
+receive_directory_structure(destdir, [])
+
+STRICT_CHECK = False # seems most useful this way for py.test
+
+for path, (time, size) in modifiedfiles:
+ data = channel.receive()
+ channel.send(("ack", path))
+ if data is not None:
+ if STRICT_CHECK and len(data) != size:
+ raise IOError('file modified during rsync: %r' % (path,))
+ f = open(path, 'wb')
+ f.write(data)
+ f.close()
+ os.utime(path, (time, time))
+ del data
+channel.send(("links", None))
+
+msg = channel.receive()
+while msg is not 42:
+ # we get symlink
+ _type, relpath, linkpoint = msg
+ assert _type == "link"
+ path = os.path.join(destdir, relpath)
+ try:
+ os.unlink(path)
+ except OSError:
+ pass
+
+ os.symlink(os.path.join(destdir, linkpoint), path)
+ msg = channel.receive()
+channel.send(("done", None))
More information about the py-svn
mailing list