version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
import os, msgpack, shutil, gevent
|
2015-01-12 02:03:45 +01:00
|
|
|
from Site import SiteManager
|
|
|
|
from cStringIO import StringIO
|
2015-01-17 18:50:56 +01:00
|
|
|
from Debug import Debug
|
2015-01-21 12:58:26 +01:00
|
|
|
from Config import config
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
FILE_BUFF = 1024*512
|
|
|
|
|
|
|
|
# Request from me
|
|
|
|
class FileRequest:
|
|
|
|
def __init__(self, server = None):
|
|
|
|
if server:
|
|
|
|
self.server = server
|
|
|
|
self.log = server.log
|
|
|
|
self.sites = SiteManager.list()
|
|
|
|
|
|
|
|
|
|
|
|
def send(self, msg):
|
|
|
|
if not isinstance(msg, dict): # If msg not a dict create a {"body": msg}
|
|
|
|
msg = {"body": msg}
|
|
|
|
self.server.socket.send(msgpack.packb(msg, use_bin_type=True))
|
|
|
|
|
|
|
|
|
|
|
|
# Route file requests
|
|
|
|
def route(self, cmd, params):
|
|
|
|
if cmd == "getFile":
|
|
|
|
self.actionGetFile(params)
|
|
|
|
elif cmd == "update":
|
|
|
|
self.actionUpdate(params)
|
|
|
|
elif cmd == "ping":
|
|
|
|
self.actionPing()
|
|
|
|
else:
|
|
|
|
self.actionUnknown(cmd, params)
|
|
|
|
|
|
|
|
|
|
|
|
# Update a site file request
|
|
|
|
def actionUpdate(self, params):
|
|
|
|
site = self.sites.get(params["site"])
|
|
|
|
if not site or not site.settings["serving"]: # Site unknown or not serving
|
|
|
|
self.send({"error": "Unknown site"})
|
|
|
|
return False
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
if site.settings["own"] and params["inner_path"].endswith("content.json"):
|
|
|
|
self.log.debug("Someone trying to push a file to own site %s, reload local %s first" % (site.address, params["inner_path"]))
|
|
|
|
site.content_manager.loadContent(params["inner_path"])
|
2015-01-12 02:03:45 +01:00
|
|
|
buff = StringIO(params["body"])
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
valid = site.content_manager.verifyFile(params["inner_path"], buff)
|
2015-01-12 02:03:45 +01:00
|
|
|
if valid == True: # Valid and changed
|
2015-01-15 23:24:51 +01:00
|
|
|
self.log.debug("Update for %s looks valid, saving..." % params["inner_path"])
|
2015-01-12 02:03:45 +01:00
|
|
|
buff.seek(0)
|
|
|
|
file = open(site.getPath(params["inner_path"]), "wb")
|
|
|
|
shutil.copyfileobj(buff, file) # Write buff to disk
|
|
|
|
file.close()
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
site.onFileDone(params["inner_path"]) # Trigger filedone
|
2015-01-12 02:03:45 +01:00
|
|
|
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
if params["inner_path"].endswith("content.json"): # Download every changed file from peer
|
2015-01-12 02:03:45 +01:00
|
|
|
peer = site.addPeer(*params["peer"], return_peer = True) # Add or get peer
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
site.onComplete.once(lambda: site.publish(inner_path=params["inner_path"])) # On complete publish to other peers
|
|
|
|
gevent.spawn(
|
|
|
|
lambda: site.downloadContent(params["inner_path"], peer=peer)
|
|
|
|
) # Load new content file and download changed files in new thread
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
self.send({"ok": "Thanks, file %s updated!" % params["inner_path"]})
|
|
|
|
|
|
|
|
elif valid == None: # Not changed
|
|
|
|
peer = site.addPeer(*params["peer"], return_peer = True) # Add or get peer
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
if peer:
|
|
|
|
self.log.debug("Same version, adding new peer for locked files: %s, tasks: %s" % (peer.key, len(site.worker_manager.tasks)) )
|
|
|
|
for task in site.worker_manager.tasks: # New peer add to every ongoing task
|
|
|
|
if task["peers"]: site.needFile(task["inner_path"], peer=peer, update=True, blocking=False) # Download file from this peer too if its peer locked
|
2015-01-12 02:03:45 +01:00
|
|
|
|
2015-01-15 23:24:51 +01:00
|
|
|
self.send({"ok": "File not changed"})
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
else: # Invalid sign or sha1 hash
|
2015-01-15 23:24:51 +01:00
|
|
|
self.log.debug("Update for %s is invalid" % params["inner_path"])
|
2015-01-12 02:03:45 +01:00
|
|
|
self.send({"error": "File invalid"})
|
|
|
|
|
|
|
|
|
|
|
|
# Send file content request
|
|
|
|
def actionGetFile(self, params):
|
|
|
|
site = self.sites.get(params["site"])
|
|
|
|
if not site or not site.settings["serving"]: # Site unknown or not serving
|
|
|
|
self.send({"error": "Unknown site"})
|
|
|
|
return False
|
|
|
|
try:
|
2015-01-21 12:58:26 +01:00
|
|
|
file_path = site.getPath(params["inner_path"])
|
|
|
|
if config.debug_socket: self.log.debug("Opening file: %s" % file_path)
|
|
|
|
file = open(file_path, "rb")
|
2015-01-12 02:03:45 +01:00
|
|
|
file.seek(params["location"])
|
|
|
|
back = {}
|
|
|
|
back["body"] = file.read(FILE_BUFF)
|
|
|
|
back["location"] = file.tell()
|
|
|
|
back["size"] = os.fstat(file.fileno()).st_size
|
2015-01-21 12:58:26 +01:00
|
|
|
if config.debug_socket: self.log.debug("Sending file %s from position %s to %s" % (file_path, params["location"], back["location"]))
|
2015-01-12 02:03:45 +01:00
|
|
|
self.send(back)
|
2015-01-21 12:58:26 +01:00
|
|
|
if config.debug_socket: self.log.debug("File %s sent" % file_path)
|
2015-01-12 02:03:45 +01:00
|
|
|
except Exception, err:
|
2015-01-17 18:50:56 +01:00
|
|
|
self.send({"error": "File read error: %s" % Debug.formatException(err)})
|
2015-01-12 02:03:45 +01:00
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# Send a simple Pong! answer
|
|
|
|
def actionPing(self):
|
|
|
|
self.send("Pong!")
|
|
|
|
|
|
|
|
|
|
|
|
# Unknown command
|
|
|
|
def actionUnknown(self, cmd, params):
|
|
|
|
self.send({"error": "Unknown command: %s" % cmd})
|