Alien-SVN
view release on metacpan or search on metacpan
src/subversion/tools/server-side/svnpubsub/svnpubsub/server.py view on Meta::CPAN
obj = {'commit': {}}
obj['commit'].update(self.__dict__)
return json.dumps(obj)
def render_log(self):
try:
paths_changed = " %d paths changed" % len(self.changed)
except:
paths_changed = ""
return "%s:%s repo '%s' id '%s'%s" % (self.type,
self.format,
self.repository,
self.id,
paths_changed)
HEARTBEAT_TIME = 15
class Client(object):
def __init__(self, pubsub, r, type, repository):
self.pubsub = pubsub
r.notifyFinish().addErrback(self.finished)
self.r = r
self.type = type
self.repository = repository
self.alive = True
log.msg("OPEN: %s:%d (%d clients online)"% (r.getClientIP(), r.client.port, pubsub.cc()+1))
def finished(self, reason):
self.alive = False
log.msg("CLOSE: %s:%d (%d clients online)"% (self.r.getClientIP(), self.r.client.port, self.pubsub.cc()))
try:
self.pubsub.remove(self)
except ValueError:
pass
def interested_in(self, commit):
if self.type and self.type != commit.type:
return False
if self.repository and self.repository != commit.repository:
return False
return True
def notify(self, data):
self.write(data)
def start(self):
self.write_start()
reactor.callLater(HEARTBEAT_TIME, self.heartbeat, None)
def heartbeat(self, args):
if self.alive:
self.write_heartbeat()
reactor.callLater(HEARTBEAT_TIME, self.heartbeat, None)
def write_data(self, data):
self.write(data + "\n\0")
""" "Data must not be unicode" is what the interfaces.ITransport says... grr. """
def write(self, input):
self.r.write(str(input))
def write_start(self):
self.r.setHeader('X-SVNPubSub-Version', '1')
self.r.setHeader('content-type', 'application/vnd.apache.vc-notify+json')
self.write('{"svnpubsub": {"version": 1}}\n\0')
def write_heartbeat(self):
self.write(json.dumps({"stillalive": time.time()}) + "\n\0")
class SvnPubSub(resource.Resource):
isLeaf = True
clients = []
def cc(self):
return len(self.clients)
def remove(self, c):
self.clients.remove(c)
def render_GET(self, request):
log.msg("REQUEST: %s" % (request.uri))
request.setHeader('content-type', 'text/plain')
repository = None
type = None
uri = request.uri.split('/')
uri_len = len(uri)
if uri_len < 2 or uri_len > 4:
request.setResponseCode(400)
return "Invalid path\n"
if uri_len >= 3:
type = uri[2]
if uri_len == 4:
repository = uri[3]
# Convert wild card to None.
if type == '*':
type = None
if repository == '*':
repository = None
c = Client(self, request, type, repository)
self.clients.append(c)
c.start()
return twisted.web.server.NOT_DONE_YET
def notifyAll(self, commit):
data = commit.render_commit()
log.msg("COMMIT: %s (%d clients)" % (commit.render_log(), self.cc()))
for client in self.clients:
if client.interested_in(commit):
client.write_data(data)
( run in 0.435 second using v1.01-cache-2.11-cpan-8644d7adfcd )