Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Idealcoder 2015-06-18 19:53:06 +01:00
commit c0c29ff3a0
13 changed files with 1287 additions and 1291 deletions

View File

@ -4,7 +4,7 @@ import ConfigParser
class Config(object):
def __init__(self):
self.version = "0.3.1"
self.rev = 242
self.rev = 245
self.parser = self.createArguments()
argv = sys.argv[:] # Copy command line arguments
argv = self.parseConfig(argv) # Add arguments from config file

View File

@ -3,18 +3,17 @@ from Debug import Debug
from Crypt import CryptHash
from Config import config
class ContentManager:
class ContentManager(object):
def __init__(self, site):
self.site = site
self.log = self.site.log
self.contents = {} # Known content.json (without files and includes)
self.loadContent(add_bad_files = False)
self.loadContent(add_bad_files=False)
self.site.settings["size"] = self.getTotalSize()
# Load content.json to self.content
# Return: Changed files ["index.html", "data/messages.json"]
def loadContent(self, content_inner_path = "content.json", add_bad_files = True, load_includes = True):
def loadContent(self, content_inner_path="content.json", add_bad_files=True, load_includes=True):
content_inner_path = content_inner_path.strip("/") # Remove / from begning
old_content = self.contents.get(content_inner_path)
content_path = self.site.storage.getPath(content_inner_path)
@ -31,7 +30,6 @@ class ContentManager:
self.log.error("Content.json not exist: %s" % content_path)
return False # Content.json not exist
try:
# Get the files where the sha512 changed
changed = []
@ -83,7 +81,6 @@ class ContentManager:
return changed
# Get total size of site
# Return: 32819 (size of files in kb)
def getTotalSize(self, ignore=None):
@ -95,7 +92,6 @@ class ContentManager:
total_size += info["size"]
return total_size
# Find the file info line from self.contents
# Return: { "sha512": "c29d73d30ee8c9c1b5600e8a84447a6de15a3c3db6869aca4a2a578c1721f518", "size": 41 , "content_inner_path": "content.json"}
def getFileInfo(self, inner_path):
@ -112,7 +108,8 @@ class ContentManager:
if content and "user_contents" in content: # User dir
back = content["user_contents"]
back["content_inner_path"] = re.sub("(.*)/.*?$", "\\1/content.json", inner_path) # Content.json is in the users dir
# Content.json is in the users dir
back["content_inner_path"] = re.sub("(.*)/.*?$", "\\1/content.json", inner_path)
return back
# No inner path in this dir, lets try the parent dir
@ -121,8 +118,8 @@ class ContentManager:
else: # No more parent dirs
break
return False # Not found
# Not found
return False
# Get rules for the file
# Return: The rules for the file or False if not allowed
@ -157,9 +154,9 @@ class ContentManager:
user_address = re.match(".*/([A-Za-z0-9]*?)/.*?$", inner_path).group(1) # Delivered for directory
try:
if not content: content = self.site.storage.loadJson(inner_path) # Read the file if no content specificed
except: # Content.json not exist
return { "signers": [user_address], "user_address": user_address } # Return information that we know for sure
if not content: content = self.site.storage.loadJson(inner_path) # Read the file if no content specified
except (Exception, ): # Content.json not exist
return {"signers": [user_address], "user_address": user_address} # Return information that we know for sure
"""if not "cert_user_name" in content: # New file, unknown user
content["cert_auth_type"] = "unknown"
@ -168,8 +165,10 @@ class ContentManager:
user_urn = "%s/%s" % (content["cert_auth_type"], content["cert_user_id"]) # web/nofish@zeroid.bit
rules = copy.copy(user_contents["permissions"].get(content["cert_user_id"], {})) # Default rules by username
if rules == False: return False # User banned
if "signers" in rules: rules["signers"] = rules["signers"][:] # Make copy of the signers
if not rules:
return False # User banned
if "signers" in rules:
rules["signers"] = rules["signers"][:] # Make copy of the signers
for permission_pattern, permission_rules in user_contents["permission_rules"].items(): # Regexp rules
if not re.match(permission_pattern, user_urn): continue # Rule is not valid for user
# Update rules if its better than current recorded ones
@ -180,7 +179,8 @@ class ContentManager:
else:
rules[key] = val
elif type(val) is int: # Int, update if larger
if val > rules[key]: rules[key] = val
if val > rules[key]:
rules[key] = val
elif hasattr(val, "startswith"): # String, update if longer
if len(val) > len(rules[key]): rules[key] = val
elif type(val) is list: # List, append
@ -191,19 +191,16 @@ class ContentManager:
rules["signers"].append(user_address) # Add user as valid signer
rules["user_address"] = user_address
return rules
# Create and sign a content.json
# Return: The new content if filewrite = False
def sign(self, inner_path = "content.json", privatekey=None, filewrite=True, update_changed_files=False, extend=None):
def sign(self, inner_path="content.json", privatekey=None, filewrite=True, update_changed_files=False, extend=None):
content = self.contents.get(inner_path)
if not content: # Content not exist yet, load default one
self.log.info("File %s not exist yet, loading default values..." % inner_path)
content = {"files": {}, "signs": {}} # Default content.json
if inner_path == "content.json": # Its the root content.json, add some more fields
if inner_path == "content.json": # It's the root content.json, add some more fields
content["title"] = "%s - ZeroNet_" % self.site.address
content["description"] = ""
content["signs_required"] = 1
@ -234,7 +231,6 @@ class ContentManager:
if file_inner_path in content["files"].keys() and hashed_files[file_inner_path]["sha512"] != content["files"][file_inner_path].get("sha512"):
changed_files.append(file_path)
self.log.debug("Changed files: %s" % changed_files)
if update_changed_files:
for file_path in changed_files:
@ -294,7 +290,6 @@ class ContentManager:
else: # Return the new content
return new_content
# The valid signers of content.json file
# Return: ["1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6", "13ReyhCsjhpuCVahn1DHdf6eMqqEVev162"]
def getValidSigners(self, inner_path, content=None):
@ -307,15 +302,14 @@ class ContentManager:
if rules and "signers" in rules:
valid_signers += rules["signers"]
if self.site.address not in valid_signers: valid_signers.append(self.site.address) # Site address always valid
if self.site.address not in valid_signers:
valid_signers.append(self.site.address) # Site address always valid
return valid_signers
# Return: The required number of valid signs for the content.json
def getSignsRequired(self, inner_path, content=None):
return 1 # Todo: Multisig
def verifyCert(self, inner_path, content):
from Crypt import CryptBitcoin
@ -329,7 +323,6 @@ class ContentManager:
return False
return CryptBitcoin.verify("%s#%s/%s" % (rules["user_address"], content["cert_auth_type"], name), cert_address, content["cert_sign"])
# Checks if the content.json content is valid
# Return: True or False
def validContent(self, inner_path, content):
@ -375,8 +368,6 @@ class ContentManager:
return True # All good
# Verify file validity
# Return: None = Same as before, False = Invalid, True = Valid
def verifyFile(self, inner_path, file, ignore_same = True):
@ -443,7 +434,8 @@ class ContentManager:
else:
hash_valid = False
if file_info["size"] != file.tell():
self.log.error("%s file size does not match %s <> %s, Hash: %s" % (inner_path, file.tell(), file_info["size"], hash_valid))
self.log.error("%s file size does not match %s <> %s, Hash: %s" % (inner_path, file.tell(),
file_info["size"], hash_valid))
return False
return hash_valid
@ -460,8 +452,6 @@ class ContentManager:
return file_dir
def testSign():
global config
from Config import config

View File

@ -1,8 +1,13 @@
import sys, logging, os
import sys
import logging
import os
import ssl
from Config import config
import gevent
from util import SslPatch
class CryptConnectionManager:
def __init__(self):
# OpenSSL params
@ -30,9 +35,9 @@ class CryptConnectionManager:
if crypt == "tls-rsa":
ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK"
if server:
return gevent.ssl.wrap_socket(sock, server_side=server, keyfile='%s/key-rsa.pem' % config.data_dir, certfile='%s/cert-rsa.pem' % config.data_dir, ciphers=ciphers)
return ssl.wrap_socket(sock, server_side=server, keyfile='%s/key-rsa.pem' % config.data_dir, certfile='%s/cert-rsa.pem' % config.data_dir, ciphers=ciphers)
else:
return gevent.ssl.wrap_socket(sock, ciphers=ciphers)
return ssl.wrap_socket(sock, ciphers=ciphers)
else:
return sock
@ -43,7 +48,7 @@ class CryptConnectionManager:
if os.path.isfile(file_path): os.unlink(file_path)
# Loand and create cert files is necessary
# Load and create cert files is necessary
def loadCerts(self):
if config.disable_encryption: return False

View File

@ -1,5 +1,12 @@
import os, msgpack, shutil, gevent, socket, struct, random
# Included modules
import socket
import struct
import os
from cStringIO import StringIO
# Third party modules
import gevent
from Debug import Debug
from Config import config
from util import RateLimit, StreamingMsgpack
@ -19,16 +26,13 @@ class FileRequest(object):
self.log = server.log
self.responded = False # Responded to the request
def unpackAddress(self, packed):
return (socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0])
return socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0]
def send(self, msg, streaming=False):
if not self.connection.closed:
self.connection.send(msg, streaming)
def response(self, msg, streaming=False):
if self.responded:
self.log.debug("Req id %s already responded" % self.req_id)
@ -40,7 +44,6 @@ class FileRequest(object):
self.responded = True
self.send(msg, streaming=streaming)
# Route file requests
def route(self, cmd, req_id, params):
self.req_id = req_id
@ -49,9 +52,10 @@ class FileRequest(object):
self.actionGetFile(params)
elif cmd == "update":
event = "%s update %s %s" % (self.connection.id, params["site"], params["inner_path"])
if not RateLimit.isAllowed(event): # There was already an updat for this file in the last 10 second
if not RateLimit.isAllowed(event): # There was already an update for this file in the last 10 second
self.response({"ok": "File update queued"})
RateLimit.callAsync(event, 10, self.actionUpdate, params) # If called more than once within 10 sec only keep the last update
# If called more than once within 10 sec only keep the last update
RateLimit.callAsync(event, 10, self.actionUpdate, params)
elif cmd == "pex":
self.actionPex(params)
@ -62,7 +66,6 @@ class FileRequest(object):
else:
self.actionUnknown(cmd, params)
# Update a site file request
def actionUpdate(self, params):
site = self.sites.get(params["site"])
@ -105,7 +108,6 @@ class FileRequest(object):
self.log.debug("Update for %s is invalid" % params["inner_path"])
self.response({"error": "File invalid"})
# Send file content request
def actionGetFile(self, params):
site = self.sites.get(params["site"])
@ -118,13 +120,17 @@ class FileRequest(object):
with StreamingMsgpack.FilePart(file_path, "rb") as file:
file.seek(params["location"])
file.read_bytes = FILE_BUFF
back = {}
back["body"] = file
back["size"] = os.fstat(file.fileno()).st_size
back["location"] = min(file.tell()+FILE_BUFF, back["size"])
if config.debug_socket: self.log.debug("Sending file %s from position %s to %s" % (file_path, params["location"], back["location"]))
back = {"body": file,
"size": os.fstat(file.fileno()).st_size,
"location": min(file.tell()+FILE_BUFF, os.fstat(file.fileno()).st_size)
}
if config.debug_socket:
self.log.debug("Sending file %s from position %s to %s" % (file_path,
params["location"],
back["location"]))
self.response(back, streaming=True)
if config.debug_socket: self.log.debug("File %s sent" % file_path)
if config.debug_socket:
self.log.debug("File %s sent" % file_path)
# Add peer to site if not added before
connected_peer = site.addPeer(self.connection.ip, self.connection.port)
@ -136,7 +142,6 @@ class FileRequest(object):
self.response({"error": "File read error: %s" % Debug.formatException(err)})
return False
# Peer exchange request
def actionPex(self, params):
site = self.sites.get(params["site"])
@ -148,7 +153,7 @@ class FileRequest(object):
added = 0
connected_peer = site.addPeer(self.connection.ip, self.connection.port) # Add requester peer to site
if connected_peer: # Just added
added +=1
added += 1
connected_peer.connect(self.connection) # Assign current connection to peer
for peer in params["peers"]: # Add sent peers to site
@ -162,14 +167,15 @@ class FileRequest(object):
self.log.debug("Added %s peers to %s using pex, sending back %s" % (added, site, len(packed_peers)))
self.response({"peers": packed_peers})
# Get modified content.json files since
def actionListModified(self, params):
site = self.sites.get(params["site"])
if not site or not site.settings["serving"]: # Site unknown or not serving
self.response({"error": "Unknown site"})
return False
modified_files = {inner_path: content["modified"] for inner_path, content in site.content_manager.contents.iteritems() if content["modified"] > params["since"]}
modified_files = {inner_path: content["modified"]
for inner_path, content in site.content_manager.contents.iteritems()
if content["modified"] > params["since"]}
# Add peer to site if not added before
connected_peer = site.addPeer(self.connection.ip, self.connection.port)
@ -178,13 +184,10 @@ class FileRequest(object):
self.response({"modified_files": modified_files})
# Send a simple Pong! answer
def actionPing(self):
self.response("Pong!")
# Unknown command
def actionUnknown(self, cmd, params):
self.response({"error": "Unknown command: %s" % cmd})

View File

@ -5,7 +5,8 @@ from Debug import Debug
# Communicate remote peers
class Peer(object):
__slots__ = ("ip", "port", "site", "key", "connection_server", "connection", "last_found", "last_response", "last_ping", "added", "connection_error", "hash_failed", "download_bytes", "download_time")
__slots__ = ("ip", "port", "site", "key", "connection_server", "connection", "last_found", "last_response",
"last_ping", "added", "connection_error", "hash_failed", "download_bytes", "download_time")
def __init__(self, ip, port, site=None):
self.ip = ip
@ -16,7 +17,7 @@ class Peer(object):
self.connection = None
self.last_found = None # Time of last found in the torrent tracker
self.last_response = None # Time of last successfull response from peer
self.last_response = None # Time of last successful response from peer
self.last_ping = None # Last response time for ping
self.added = time.time()
@ -25,23 +26,21 @@ class Peer(object):
self.download_bytes = 0 # Bytes downloaded
self.download_time = 0 # Time spent to download
def log(self, text):
if self.site:
self.site.log.debug("%s:%s %s" % (self.ip, self.port, text))
else:
logging.debug("%s:%s %s" % (self.ip, self.port, text))
# Connect to host
def connect(self, connection = None):
def connect(self, connection=None):
if self.connection:
self.log("Getting connection (Closing %s)..." % self.connection)
self.connection.close()
else:
self.log("Getting connection...")
if connection: # Connection specificed
if connection: # Connection specified
self.connection = connection
else: # Try to find from connection pool or create new connection
self.connection = None
@ -53,7 +52,6 @@ class Peer(object):
self.log("Getting connection error: %s (connection_error: %s, hash_failed: %s)" % (Debug.formatException(err), self.connection_error, self.hash_failed))
self.connection = None
# Check if we have connection to peer
def findConnection(self):
if self.connection and self.connection.connected: # We have connection to peer
@ -62,30 +60,25 @@ class Peer(object):
self.connection = self.connection_server.getConnection(self.ip, self.port, create=False) # Do not create new connection if not found
return self.connection
def __str__(self):
return "Peer %-12s" % self.ip
def __repr__(self):
return "<%s>" % self.__str__()
# Peer ip:port to packed 6byte format
def packAddress(self):
return socket.inet_aton(self.ip)+struct.pack("H", self.port)
def unpackAddress(self, packed):
return (socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0])
return socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0]
# Found a peer on tracker
def found(self):
self.last_found = time.time()
# Send a command to peer
def request(self, cmd, params = {}):
def request(self, cmd, params={}):
if not self.connection or self.connection.closed:
self.connect()
if not self.connection:
@ -99,7 +92,8 @@ class Peer(object):
#if config.debug_socket: self.log.debug("sendCmd: %s %s" % (cmd, params.get("inner_path")))
try:
response = self.connection.request(cmd, params)
if not response: raise Exception("Send error")
if not response:
raise Exception("Send error")
#if config.debug_socket: self.log.debug("Got response to: %s" % cmd)
if "error" in response:
self.log("%s error: %s" % (cmd, response["error"]))
@ -109,23 +103,24 @@ class Peer(object):
self.last_response = time.time()
return response
except Exception, err:
if type(err).__name__ == "Notify": # Greenlet kill by worker
if type(err).__name__ == "Notify": # Greenlet killed by worker
self.log("Peer worker got killed: %s, aborting cmd: %s" % (err.message, cmd))
break
else:
self.onConnectionError()
self.log("%s (connection_error: %s, hash_failed: %s, retry: %s)" % (Debug.formatException(err), self.connection_error, self.hash_failed, retry))
self.log("%s (connection_error: %s, hash_failed: %s, retry: %s)" % (Debug.formatException(err),
self.connection_error,
self.hash_failed, retry))
time.sleep(1*retry)
self.connect()
return None # Failed after 4 retry
# Get a file content from peer
def getFile(self, site, inner_path):
location = 0
buff = StringIO()
s = time.time()
while 1: # Read in 512k parts
while True: # Read in 512k parts
back = self.request("getFile", {"site": site, "inner_path": inner_path, "location": location}) # Get file content from last location
if not back or "body" not in back: # Error
return False
@ -141,13 +136,12 @@ class Peer(object):
buff.seek(0)
return buff
# Send a ping request
def ping(self):
response_time = None
for retry in range(1,3): # Retry 3 times
for retry in range(1, 3): # Retry 3 times
s = time.time()
with gevent.Timeout(10.0, False): # 10 sec timeout, dont raise exception
with gevent.Timeout(10.0, False): # 10 sec timeout, don't raise exception
response = self.request("ping")
if response and "body" in response and response["body"] == "Pong!":
@ -165,29 +159,28 @@ class Peer(object):
self.last_ping = response_time
return response_time
# Request peer exchange from peer
def pex(self, site=None, need_num=5):
if not site: site = self.site # If no site definied request peers for this site
packed_peers = [peer.packAddress() for peer in self.site.getConnectablePeers(5)] # give him/her 5 connectable peers
if not site:
site = self.site # If no site defined request peers for this site
# give him/her 5 connectible peers
packed_peers = [peer.packAddress() for peer in self.site.getConnectablePeers(5)]
response = self.request("pex", {"site": site.address, "peers": packed_peers, "need": need_num})
if not response or "error" in response:
return False
added = 0
for peer in response.get("peers", []):
address = self.unpackAddress(peer)
if (site.addPeer(*address)): added += 1
if site.addPeer(*address):
added += 1
if added:
self.log("Added peers using pex: %s" % added)
return added
# List modified files since the date
# Return: {inner_path: modification date,...}
def listModified(self, since):
response = self.request("listModified", {"since": since, "site": self.site.address})
return response
return self.request("listModified", {"since": since, "site": self.site.address})
# Stop and remove from site
def remove(self):
@ -196,7 +189,6 @@ class Peer(object):
if self.connection:
self.connection.close()
# - EVENTS -
# On connection error
@ -205,7 +197,6 @@ class Peer(object):
if self.connection_error >= 3: # Dead peer
self.remove()
# Done working with peer
def onWorkerDone(self):
pass

View File

@ -131,7 +131,7 @@
<div style="clear: both"></div>
<script type="text/javascript" src="js/all.js" asyc></script>
<script type="text/javascript" src="js/all.js" async></script>
</body>
</html>

View File

@ -57,7 +57,7 @@ permissions = {permissions}
show_loadingscreen = {show_loadingscreen}
server_url = '{server_url}'
</script>
<script type="text/javascript" src="{server_url}/uimedia/all.js?rev={rev}" asyc></script>
<script type="text/javascript" src="{server_url}/uimedia/all.js?rev={rev}"></script>
</body>
</html>

View File

@ -21,11 +21,11 @@ class User(object):
self.log = logging.getLogger("User:%s" % self.master_address)
# Save to data/users.json
def save(self):
users = json.load(open("%s/users.json" % config.data_dir))
if not self.master_address in users: users[self.master_address] = {} # Create if not exist
if self.master_address not in users:
users[self.master_address] = {} # Create if not exist
user_data = users[self.master_address]
if self.master_seed: user_data["master_seed"] = self.master_seed
user_data["sites"] = self.sites
@ -33,15 +33,13 @@ class User(object):
open("%s/users.json" % config.data_dir, "w").write(json.dumps(users, indent=2, sort_keys=True))
self.log.debug("Saved")
def getAddressAuthIndex(self, address):
return int(address.encode("hex"), 16)
# Get user site data
# Return: {"auth_address": "xxx", "auth_privatekey": "xxx"}
def getSiteData(self, address, create=True):
if not address in self.sites: # Genreate new BIP32 child key based on site address
if address not in self.sites: # Generate new BIP32 child key based on site address
if not create: return {"auth_address": None, "auth_privatekey": None} # Dont create user yet
s = time.time()
address_id = self.getAddressAuthIndex(address) # Convert site address to int
@ -54,7 +52,6 @@ class User(object):
self.log.debug("Added new site: %s in %.3fs" % (address, time.time()-s))
return self.sites[address]
# Get data for a new, unique site
# Return: [site_address, bip32_index, {"auth_address": "xxx", "auth_privatekey": "xxx", "privatekey": "xxx"}]
def getNewSiteData(self):
@ -69,7 +66,6 @@ class User(object):
self.save()
return site_address, bip32_index, self.sites[site_address]
# Get BIP32 address from site address
# Return: BIP32 auth address
def getAuthAddress(self, address, create=True):
@ -79,7 +75,6 @@ class User(object):
else:
return self.getSiteData(address, create)["auth_address"]
def getAuthPrivatekey(self, address, create=True):
cert = self.getCert(address)
if cert:
@ -87,7 +82,6 @@ class User(object):
else:
return self.getSiteData(address, create)["auth_privatekey"]
# Add cert for the user
def addCert(self, auth_address, domain, auth_type, auth_user_name, cert_sign):
domain = domain.lower()
@ -109,7 +103,6 @@ class User(object):
self.save()
return True
def setCert(self, address, domain):
site_data = self.getSiteData(address)
if domain:
@ -119,7 +112,6 @@ class User(object):
self.save()
return site_data
# Get cert for the site address
# Return: { "auth_address": ..., "auth_privatekey":..., "auth_type": "web", "auth_user_name": "nofish", "cert_sign": ... } or None
def getCert(self, address):
@ -127,7 +119,6 @@ class User(object):
if not site_data or not "cert" in site_data: return None # Site dont have cert
return self.certs.get(site_data["cert"])
# Get cert user name for the site address
# Return: user@certprovider.bit or None
def getCertUserId(self, address):

View File

@ -1,4 +1,9 @@
import json, logging, os
# Included modules
import os
import json
import logging
# ZeroNet Modules
from User import User
from Plugin import PluginManager
from Config import config
@ -9,10 +14,10 @@ class UserManager(object):
def __init__(self):
self.users = {}
# Load all user from data/users.json
def load(self):
if not self.users: self.users = {}
if not self.users:
self.users = {}
user_found = []
added = 0
@ -30,8 +35,8 @@ class UserManager(object):
del(self.users[master_address])
logging.debug("Removed user: %s" % master_address)
if added: logging.debug("UserManager added %s users" % added)
if added:
logging.debug("UserManager added %s users" % added)
# Create new user
# Return: User
@ -43,7 +48,6 @@ class UserManager(object):
user.save()
return user
# List all users from data/users.json
# Return: {"usermasteraddr": User}
def list(self):
@ -51,7 +55,6 @@ class UserManager(object):
self.load()
return self.users
# Get user based on master_address
# Return: User or None
def get(self, master_address=None):
@ -62,7 +65,8 @@ class UserManager(object):
return None
user_manager = UserManager() # Singletone
user_manager = UserManager() # Singleton
# Debug: Reload User.py
def reloadModule():

View File

@ -2,7 +2,7 @@ import gevent, time, logging, shutil, os
from Peer import Peer
from Debug import Debug
class Worker:
class Worker(object):
def __init__(self, manager, peer):
self.manager = manager
self.peer = peer

View File

@ -1,4 +1,15 @@
import os, sys
# Included modules
import os
import sys
import time
import logging
# Third party modules
import gevent
from gevent import monkey
update_after_shutdown = False # If set True then update and restart zeronet after main loop ended
# Load config
@ -7,19 +18,23 @@ from Config import config
# Create necessary files and dirs
if not os.path.isdir(config.log_dir): os.mkdir(config.log_dir)
if not os.path.isdir(config.data_dir): os.mkdir(config.data_dir)
if not os.path.isfile("%s/sites.json" % config.data_dir): open("%s/sites.json" % config.data_dir, "w").write("{}")
if not os.path.isfile("%s/users.json" % config.data_dir): open("%s/users.json" % config.data_dir, "w").write("{}")
if not os.path.isfile("%s/sites.json" % config.data_dir):
open("%s/sites.json" % config.data_dir, "w").write("{}")
if not os.path.isfile("%s/users.json" % config.data_dir):
open("%s/users.json" % config.data_dir, "w").write("{}")
# Setup logging
import logging
if config.action == "main":
if os.path.isfile("%s/debug.log" % config.log_dir): # Simple logrotate
if os.path.isfile("%s/debug-last.log" % config.log_dir): os.unlink("%s/debug-last.log" % config.log_dir)
if os.path.isfile("%s/debug-last.log" % config.log_dir):
os.unlink("%s/debug-last.log" % config.log_dir)
os.rename("%s/debug.log" % config.log_dir, "%s/debug-last.log" % config.log_dir)
logging.basicConfig(format='[%(asctime)s] %(levelname)-8s %(name)s %(message)s', level=logging.DEBUG, filename="%s/debug.log" % config.log_dir)
logging.basicConfig(format='[%(asctime)s] %(levelname)-8s %(name)s %(message)s',
level=logging.DEBUG, filename="%s/debug.log" % config.log_dir)
else:
logging.basicConfig(level=logging.DEBUG, stream=open(os.devnull,"w")) # No file logging if action is not main
logging.basicConfig(level=logging.DEBUG, stream=open(os.devnull, "w")) # No file logging if action is not main
# Console logger
console_log = logging.StreamHandler()
@ -39,9 +54,9 @@ if config.debug:
else:
console_log.setLevel(logging.INFO) # Display only important info to console
from gevent import monkey; monkey.patch_all(thread=False, ssl=False) # Make time, socket gevent compatible. Not thread: pyfilesystem and system tray icon not compatible, Not ssl: broken in 2.7.9
import gevent
import time
monkey.patch_all(thread=False) # Make time, socket gevent compatible. Not thread: pyfilesystem and system tray icon not compatible
# Log current config
logging.debug("Config: %s" % config)
@ -64,7 +79,7 @@ PluginManager.plugin_manager.loadPlugins()
# -- Actions --
@PluginManager.acceptPlugins
class Actions:
class Actions(object):
# Default action: Start serving UiServer and FileServer
def main(self):
logging.info("Version: %s r%s, Python %s, Gevent: %s" % (config.version, config.rev, sys.version, gevent.__version__))
@ -84,7 +99,6 @@ class Actions:
logging.info("Starting servers....")
gevent.joinall([gevent.spawn(ui_server.start), gevent.spawn(file_server.start)])
# Site commands
def siteCreate(self):
@ -115,7 +129,6 @@ class Actions:
logging.info("Site created!")
def siteSign(self, address, privatekey=None, inner_path="content.json", publish=False):
from Site import Site
logging.info("Signing site: %s..." % address)
@ -128,7 +141,6 @@ class Actions:
if succ and publish:
self.sitePublish(address, inner_path=inner_path)
def siteVerify(self, address):
import time
from Site import Site
@ -152,7 +164,6 @@ class Actions:
else:
logging.error("[ERROR] Error during verifying site files!")
def dbRebuild(self, address):
from Site import Site
logging.info("Rebuilding site sql cache: %s..." % address)
@ -161,7 +172,6 @@ class Actions:
site.storage.rebuildDb()
logging.info("Done in %.3fs" % (time.time()-s))
def dbQuery(self, address, query):
from Site import Site
import json
@ -171,7 +181,6 @@ class Actions:
result.append(dict(row))
print json.dumps(result, indent=4)
def siteAnnounce(self, address):
from Site.Site import Site
logging.info("Announcing site %s to tracker..." % address)
@ -215,10 +224,7 @@ class Actions:
else:
logging.info("No peers found for this site, sitePublish command only works if you already have peers serving your site")
# Crypto commands
def cryptPrivatekeyToAddress(self, privatekey=None):
from Crypt import CryptBitcoin
if not privatekey: # If no privatekey in args then ask it now
@ -227,14 +233,11 @@ class Actions:
print CryptBitcoin.privatekeyToAddress(privatekey)
def cryptSign(self, message, privatekey):
from Crypt import CryptBitcoin
print CryptBitcoin.sign(message, privatekey)
# Peer
def peerPing(self, peer_ip, peer_port=None):
if not peer_port:
peer_port = config.fileserver_port
@ -252,7 +255,6 @@ class Actions:
print "Response time: %.3fs (crypt: %s)" % (time.time()-s, peer.connection.crypt)
time.sleep(1)
def peerGetFile(self, peer_ip, peer_port, site, filename):
logging.info("Opening a simple connection server")
global file_server
@ -266,7 +268,6 @@ class Actions:
print peer.getFile(site, filename).read()
print "Response time: %.3fs" % (time.time()-s)
def peerCmd(self, peer_ip, peer_port, cmd, parameters):
logging.info("Opening a simple connection server")
global file_server

View File

@ -1,7 +1,13 @@
#!/usr/bin/env python
# Included modules
import sys
# ZeroNet Modules
import zeronet
def main():
sys.argv += ["--open_browser", "default_browser"]
zeronet.main()

View File

@ -1,15 +1,21 @@
#!/usr/bin/env python
# Included modules
import os
import sys
def main():
print "- Starting ZeroNet..."
import sys, os
main = None
try:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src")) # Imports relative to src
import main
main.start()
if main.update_after_shutdown: # Updater
import update, sys, os, gc
import gc
import update
# Try cleanup openssl
try:
if "lib.opensslVerify" in sys.modules:
@ -28,7 +34,7 @@ def main():
handler.close()
logger.removeHandler(handler)
except Exception, err: # Prevent closing
except (Exception, ): # Prevent closing
import traceback
traceback.print_exc()
traceback.print_exc(file=open("log/error.log", "a"))
@ -46,4 +52,3 @@ def main():
if __name__ == '__main__':
main()