simple changelog

This commit is contained in:
j 2017-06-03 22:50:14 +02:00
commit e966256fa2
15 changed files with 267 additions and 103 deletions

View file

@ -2,7 +2,6 @@
# vi:si:et:sw=4:sts=4:ts=4
from changelog import Changelog
from user.models import User
from websocket import trigger_event
import state
@ -11,20 +10,6 @@ import settings
import logging
logger = logging.getLogger(__name__)
def api_pullChanges(remote_id, user_id=None, from_=None, to=None):
if user_id and not from_ and not to:
from_ = user_id
user_id = None
if user_id and from_ and not to:
if isinstance(user_id, int):
to = from_
from_ = user_id
user_id = None
from_ = from_ or 0
if user_id:
return []
return Changelog.aggregated_changes(from_)
def api_requestPeering(user_id, username, message):
event = 'peering.request'
user = User.get_or_create(user_id)

View file

@ -25,6 +25,7 @@ import db
import settings
import state
import user
from changelog import changelog_size, changelog_path
from websocket import trigger_event
from . import nodeapi
@ -78,10 +79,6 @@ class NodeServer(ThreadingMixIn, TLSTCPServer):
def api_call(action, user_id, args):
with db.session():
u = user.models.User.get(user_id)
if u and action in ('pullChanges', ) and not u.peered and u.pending == 'sent':
u.update_peering(True)
state.nodes.queue('add', u.id, True)
trigger_event('peering.accept', u.json())
if action in (
'requestPeering', 'acceptPeering', 'rejectPeering',
'removePeering', 'cancelPeering'
@ -172,6 +169,8 @@ class Handler(http.server.SimpleHTTPRequestHandler):
self.write_with_limit(content, content_length)
else:
self.write_file_with_limit(path, content_length)
elif len(parts) == 2 and parts[1] == 'log':
self._changelog()
else:
self.send_response(200, 'OK')
self.send_header('Content-type', 'text/plain')
@ -179,6 +178,53 @@ class Handler(http.server.SimpleHTTPRequestHandler):
self.end_headers()
self.wfile.write('Open Media Library\n'.encode())
def _denied(self):
self.send_response(403, 'denied')
self.end_headers()
def _changelog(self):
x509 = self.connection.get_peer_certificate()
user_id = get_service_id(x509.get_pubkey()) if x509 else None
with db.session():
u = user.models.User.get(user_id)
if not u:
return self._denied()
if u.pending:
logger.debug('ignore request from pending peer[%s] %s (%s)',
user_id, action, args)
return self._denied()
if not u.peered and u.pending == 'sent':
u.update_peering(True)
state.nodes.queue('add', u.id, True)
trigger_event('peering.accept', u.json())
if not u.peered:
return self._denied()
path = changelog_path()
content_length = changelog_size()
with open(path, 'rb') as log:
request_range = self.headers.get('Range', '')
if request_range:
r = request_range.split('=')[-1].split('-')
start = int(r[0])
end = int(r[1]) if r[1] else (content_length - 1)
if start == content_length:
content_length = 0
else:
content_length = end - start + 1
if content_length < 0:
content_length = os.path.getsize(path)
self.send_response(200, 'OK')
else:
log.seek(start)
self.send_response(206, 'OK')
else:
self.send_response(200, 'OK')
self.send_header('Content-type', 'text/json')
self.send_header('X-Node-Protocol', settings.NODE_PROTOCOL)
self.send_header('Content-Length', str(content_length))
self.end_headers()
self.write_fd_with_limit(log, content_length)
def gzip_data(self, data):
encoding = self.headers.get('Accept-Encoding')
if encoding.find('gzip') != -1:
@ -203,7 +249,6 @@ class Handler(http.server.SimpleHTTPRequestHandler):
def do_POST(self):
'''
API
pullChanges [userid] from [to]
requestPeering username message
acceptPeering username message
rejectPeering message
@ -287,17 +332,26 @@ class Handler(http.server.SimpleHTTPRequestHandler):
self.wfile.write(data)
position += chunk_size
def write_file_with_limit(self, path, content_length):
def write_fd_with_limit(self, f, content_length):
chunk_size = self.chunk_size(content_length)
position = 0
while True:
data = f.read(chunk_size)
if not data:
break
self.wfile.write(data)
position += chunk_size
if position + chunk_size > content_length:
chunk_size = content_length - position
if chunk_size <= 0:
break
if state.bandwidth:
while not state.bandwidth.upload(chunk_size) and self.server._running:
time.sleep(0.1)
def write_file_with_limit(self, path, content_length):
with open(path, 'rb') as f:
while True:
data = f.read(chunk_size)
if not data:
break
self.wfile.write(data)
if state.bandwidth:
while not state.bandwidth.upload(chunk_size) and self.server._running:
time.sleep(0.1)
self.write_fd_with_limit(f, content_length)
class Server(Thread):
http_server = None