diff --git a/plugins/disabled-Zeroname-local/SiteManagerPlugin.py b/plugins/disabled-Zeroname-local/SiteManagerPlugin.py deleted file mode 100644 index c43e792a..00000000 --- a/plugins/disabled-Zeroname-local/SiteManagerPlugin.py +++ /dev/null @@ -1,68 +0,0 @@ -import logging, json, os, re, sys, time -import gevent -from Plugin import PluginManager -from Config import config -from Debug import Debug -from .domainLookup import lookupDomain - -allow_reload = False # No reload supported - -log = logging.getLogger("Zeroname-localPlugin") - - -@PluginManager.registerTo("SiteManager") -class SiteManagerPlugin(object): - def load(self): - super(SiteManagerPlugin, self).load() - - # Checks if its a valid address - def isAddress(self, address): - if self.isDomain(address): - return True - else: - return super(SiteManagerPlugin, self).isAddress(address) - - - # Return: True if the address is domain - def isDomain(self, address): - return re.match(r"(.*?)([A-Za-z0-9_-]+\.[A-Za-z0-9]+)$", address) - - - # Resolve domain - # Return: The address or None - def resolveDomain(self, domain): - return lookupDomain(domain) - - - # Return or create site and start download site files - # Return: Site or None if dns resolve failed - def need(self, address, all_file=True): - if self.isDomain(address): # Its looks like a domain - address_resolved = self.resolveDomain(address) - if address_resolved: - address = address_resolved - else: - return None - - return super(SiteManagerPlugin, self).need(address, all_file) - - - # Return: Site object or None if not found - def get(self, address): - if self.sites == None: # Not loaded yet - self.load() - if self.isDomain(address): # Its looks like a domain - address_resolved = self.resolveDomain(address) - if address_resolved: # Domain found - site = self.sites.get(address_resolved) - if site: - site_domain = site.settings.get("domain") - if site_domain != address: - site.settings["domain"] = address - else: # Domain not found - site = self.sites.get(address) - - else: # Access by site address - site = self.sites.get(address) - return site - diff --git a/plugins/disabled-Zeroname-local/bitcoinrpc/__init__.py b/plugins/disabled-Zeroname-local/bitcoinrpc/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py b/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py deleted file mode 100644 index facf2c41..00000000 --- a/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py +++ /dev/null @@ -1,190 +0,0 @@ - -""" - Copyright 2011 Jeff Garzik - - AuthServiceProxy has the following improvements over python-jsonrpc's - ServiceProxy class: - - - HTTP connections persist for the life of the AuthServiceProxy object - (if server supports HTTP/1.1) - - sends protocol 'version', per JSON-RPC 1.1 - - sends proper, incrementing 'id' - - sends Basic HTTP authentication headers - - parses all JSON numbers that look like floats as Decimal - - uses standard Python json lib - - Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: - - Copyright (c) 2007 Jan-Klaas Kollhof - - This file is part of jsonrpc. - - jsonrpc is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this software; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -""" - -try: - import http.client as httplib -except ImportError: - import http.client -import base64 -import decimal -import json -import logging -try: - import urllib.parse as urlparse -except ImportError: - import urllib.parse - -USER_AGENT = "AuthServiceProxy/0.1" - -HTTP_TIMEOUT = 30 - -log = logging.getLogger("BitcoinRPC") - -class JSONRPCException(Exception): - def __init__(self, rpc_error): - parent_args = [] - try: - parent_args.append(rpc_error['message']) - except: - pass - Exception.__init__(self, *parent_args) - self.error = rpc_error - self.code = rpc_error['code'] if 'code' in rpc_error else None - self.message = rpc_error['message'] if 'message' in rpc_error else None - - def __str__(self): - return '%d: %s' % (self.code, self.message) - - def __repr__(self): - return '<%s \'%s\'>' % (self.__class__.__name__, self) - - -def EncodeDecimal(o): - if isinstance(o, decimal.Decimal): - return float(round(o, 8)) - raise TypeError(repr(o) + " is not JSON serializable") - -class AuthServiceProxy(object): - __id_count = 0 - - def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): - self.__service_url = service_url - self.__service_name = service_name - self.__url = urllib.parse.urlparse(service_url) - if self.__url.port is None: - port = 80 - else: - port = self.__url.port - (user, passwd) = (self.__url.username, self.__url.password) - try: - user = user.encode('utf8') - except AttributeError: - pass - try: - passwd = passwd.encode('utf8') - except AttributeError: - pass - authpair = user + b':' + passwd - self.__auth_header = b'Basic ' + base64.b64encode(authpair) - - self.__timeout = timeout - - if connection: - # Callables re-use the connection of the original proxy - self.__conn = connection - elif self.__url.scheme == 'https': - self.__conn = http.client.HTTPSConnection(self.__url.hostname, port, - timeout=timeout) - else: - self.__conn = http.client.HTTPConnection(self.__url.hostname, port, - timeout=timeout) - - def __getattr__(self, name): - if name.startswith('__') and name.endswith('__'): - # Python internal stuff - raise AttributeError - if self.__service_name is not None: - name = "%s.%s" % (self.__service_name, name) - return AuthServiceProxy(self.__service_url, name, self.__timeout, self.__conn) - - def __call__(self, *args): - AuthServiceProxy.__id_count += 1 - - log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self.__service_name, - json.dumps(args, default=EncodeDecimal))) - postdata = json.dumps({'version': '1.1', - 'method': self.__service_name, - 'params': args, - 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - self.__conn.sock.settimeout(self.__timeout) - - response = self._get_response() - if response.get('error') is not None: - raise JSONRPCException(response['error']) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}) - - return response['result'] - - def batch_(self, rpc_calls): - """Batch RPC call. - Pass array of arrays: [ [ "method", params... ], ... ] - Returns array of results. - """ - batch_data = [] - for rpc_call in rpc_calls: - AuthServiceProxy.__id_count += 1 - m = rpc_call.pop(0) - batch_data.append({"jsonrpc":"2.0", "method":m, "params":rpc_call, "id":AuthServiceProxy.__id_count}) - - postdata = json.dumps(batch_data, default=EncodeDecimal) - log.debug("--> "+postdata) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - results = [] - responses = self._get_response() - for response in responses: - if response['error'] is not None: - raise JSONRPCException(response['error']) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}) - else: - results.append(response['result']) - return results - - def _get_response(self): - http_response = self.__conn.getresponse() - if http_response is None: - raise JSONRPCException({ - 'code': -342, 'message': 'missing HTTP response from server'}) - - responsedata = http_response.read().decode('utf8') - response = json.loads(responsedata, parse_float=decimal.Decimal) - if "error" in response and response["error"] is None: - log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) - else: - log.debug("<-- "+responsedata) - return response diff --git a/plugins/disabled-Zeroname-local/domainLookup.py b/plugins/disabled-Zeroname-local/domainLookup.py deleted file mode 100644 index 0521d233..00000000 --- a/plugins/disabled-Zeroname-local/domainLookup.py +++ /dev/null @@ -1,78 +0,0 @@ -from .bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException -import time, json, os, sys, re, socket - -# Connecting to RPC -def initRpc(config): - """Initialize Namecoin RPC""" - rpc_data = { - 'connect': '127.0.0.1', - 'port': '8336', - 'user': 'PLACEHOLDER', - 'password': 'PLACEHOLDER', - 'clienttimeout': '900' - } - try: - fptr = open(config, 'r') - lines = fptr.readlines() - fptr.close() - except: - return None # Or take some other appropriate action - - for line in lines: - if not line.startswith('rpc'): - continue - key_val = line.split(None, 1)[0] - (key, val) = key_val.split('=', 1) - if not key or not val: - continue - rpc_data[key[3:]] = val - - url = 'http://%(user)s:%(password)s@%(connect)s:%(port)s' % rpc_data - - return url, int(rpc_data['clienttimeout']) - -# Either returns domain's address or none if it doesn't exist -# Supports subdomains and .bit on the end -def lookupDomain(domain): - domain = domain.lower() - - #remove .bit on end - if domain[-4:] == ".bit": - domain = domain[0:-4] - - #check for subdomain - if domain.find(".") != -1: - subdomain = domain[0:domain.find(".")] - domain = domain[domain.find(".")+1:] - else: - subdomain = "" - - try: - domain_object = rpc.name_show("d/"+domain) - except: - #domain doesn't exist - return None - - domain_json = json.loads(domain_object["value"]) - - try: - domain_address = domain_json["zeronet"][subdomain] - except: - #domain exists but doesn't have any zeronet value - return None - - return domain_address - -# Loading config... - -# Check whether platform is on windows or linux -# On linux namecoin is installed under ~/.namecoin, while on on windows it is in %appdata%/Namecoin - -if sys.platform == "win32": - namecoin_location = os.getenv('APPDATA') + "/Namecoin/" -else: - namecoin_location = os.path.expanduser("~/.namecoin/") - -# Initialize rpc connection -rpc_auth, rpc_timeout = initRpc(namecoin_location + "namecoin.conf") -rpc = AuthServiceProxy(rpc_auth, timeout=rpc_timeout) diff --git a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py new file mode 100644 index 00000000..579e31c1 --- /dev/null +++ b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py @@ -0,0 +1,180 @@ +import logging, json, os, re, sys, time, socket +from Plugin import PluginManager +from Config import config +from Debug import Debug +from http.client import HTTPSConnection, HTTPConnection, HTTPException +from base64 import b64encode + +allow_reload = False # No reload supported + +@PluginManager.registerTo("SiteManager") +class SiteManagerPlugin(object): + def load(self, *args, **kwargs): + super(SiteManagerPlugin, self).load(*args, **kwargs) + self.log = logging.getLogger("ZeronetLocal Plugin") + self.error_message = None + if not config.namecoin_host or not config.namecoin_rpcport or not config.namecoin_rpcuser or not config.namecoin_rpcpassword: + self.error_message = "Missing parameters" + self.log.error("Missing parameters to connect to namecoin node. Please check all the arguments needed with '--help'. Zeronet will continue working without it.") + return + + url = "%(host)s:%(port)s" % {"host": config.namecoin_host, "port": config.namecoin_rpcport} + self.c = HTTPConnection(url, timeout=3) + user_pass = "%(user)s:%(password)s" % {"user": config.namecoin_rpcuser, "password": config.namecoin_rpcpassword} + userAndPass = b64encode(bytes(user_pass, "utf-8")).decode("ascii") + self.headers = {"Authorization" : "Basic %s" % userAndPass, "Content-Type": " application/json " } + + payload = json.dumps({ + "jsonrpc": "2.0", + "id": "zeronet", + "method": "ping", + "params": [] + }) + + try: + self.c.request("POST", "/", payload, headers=self.headers) + response = self.c.getresponse() + data = response.read() + self.c.close() + if response.status == 200: + result = json.loads(data.decode())["result"] + else: + raise Exception(response.reason) + except Exception as err: + self.log.error("The Namecoin node is unreachable. Please check the configuration value are correct. Zeronet will continue working without it.") + self.error_message = err + self.cache = dict() + + # Checks if it's a valid address + def isAddress(self, address): + return self.isBitDomain(address) or super(SiteManagerPlugin, self).isAddress(address) + + # Return: True if the address is domain + def isDomain(self, address): + return self.isBitDomain(address) or super(SiteManagerPlugin, self).isDomain(address) + + # Return: True if the address is .bit domain + def isBitDomain(self, address): + return re.match(r"(.*?)([A-Za-z0-9_-]+\.bit)$", address) + + # Return: Site object or None if not found + def get(self, address): + if self.isBitDomain(address): # Its looks like a domain + address_resolved = self.resolveDomain(address) + if address_resolved: # Domain found + site = self.sites.get(address_resolved) + if site: + site_domain = site.settings.get("domain") + if site_domain != address: + site.settings["domain"] = address + else: # Domain not found + site = self.sites.get(address) + + else: # Access by site address + site = super(SiteManagerPlugin, self).get(address) + return site + + # Return or create site and start download site files + # Return: Site or None if dns resolve failed + def need(self, address, *args, **kwargs): + if self.isBitDomain(address): # Its looks like a domain + address_resolved = self.resolveDomain(address) + if address_resolved: + address = address_resolved + else: + return None + + return super(SiteManagerPlugin, self).need(address, *args, **kwargs) + + # Resolve domain + # Return: The address or None + def resolveDomain(self, domain): + domain = domain.lower() + + #remove .bit on end + if domain[-4:] == ".bit": + domain = domain[0:-4] + + domain_array = domain.split(".") + + if self.error_message: + self.log.error("Not able to connect to Namecoin node : {!s}".format(self.error_message)) + return None + + if len(domain_array) > 2: + self.log.error("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") + return None + + subdomain = "" + if len(domain_array) == 1: + domain = domain_array[0] + else: + subdomain = domain_array[0] + domain = domain_array[1] + + if domain in self.cache: + delta = time.time() - self.cache[domain]["time"] + if delta < 3600: + # Must have been less than 1hour + return self.cache[domain]["addresses_resolved"][subdomain] + + payload = json.dumps({ + "jsonrpc": "2.0", + "id": "zeronet", + "method": "name_show", + "params": ["d/"+domain] + }) + + try: + self.c.request("POST", "/", payload, headers=self.headers) + response = self.c.getresponse() + data = response.read() + self.c.close() + domain_object = json.loads(data.decode())["result"] + except Exception as err: + #domain doesn't exist + return None + + if "zeronet" in domain_object["value"]: + zeronet_domains = json.loads(domain_object["value"])["zeronet"] + + if isinstance(zeronet_domains, str): + # { + # "zeronet":"19rXKeKptSdQ9qt7omwN82smehzTuuq6S9" + # } is valid + zeronet_domains = {"": zeronet_domains} + + self.cache[domain] = {"addresses_resolved": zeronet_domains, "time": time.time()} + + elif "map" in domain_object["value"]: + # Namecoin standard use {"map": { "blog": {"zeronet": "1D..."} }} + data_map = json.loads(domain_object["value"])["map"] + + zeronet_domains = dict() + for subdomain in data_map: + if "zeronet" in data_map[subdomain]: + zeronet_domains[subdomain] = data_map[subdomain]["zeronet"] + if "zeronet" in data_map and isinstance(data_map["zeronet"], str): + # {"map":{ + # "zeronet":"19rXKeKptSdQ9qt7omwN82smehzTuuq6S9", + # }} + zeronet_domains[""] = data_map["zeronet"] + + self.cache[domain] = {"addresses_resolved": zeronet_domains, "time": time.time()} + + else: + # No Zeronet address registered + return None + + return self.cache[domain]["addresses_resolved"][subdomain] + +@PluginManager.registerTo("ConfigPlugin") +class ConfigPlugin(object): + def createArguments(self): + group = self.parser.add_argument_group("Zeroname Local plugin") + group.add_argument('--namecoin_host', help="Host to namecoin node (eg. 127.0.0.1)") + group.add_argument('--namecoin_rpcport', help="Port to connect (eg. 8336)") + group.add_argument('--namecoin_rpcuser', help="RPC user to connect to the namecoin node (eg. nofish)") + group.add_argument('--namecoin_rpcpassword', help="RPC password to connect to namecoin node") + + return super(ConfigPlugin, self).createArguments() diff --git a/plugins/disabled-Zeroname-local/UiRequestPlugin.py b/plugins/disabled-ZeronameLocal/UiRequestPlugin.py similarity index 99% rename from plugins/disabled-Zeroname-local/UiRequestPlugin.py rename to plugins/disabled-ZeronameLocal/UiRequestPlugin.py index df37e066..0ccfb530 100644 --- a/plugins/disabled-Zeroname-local/UiRequestPlugin.py +++ b/plugins/disabled-ZeronameLocal/UiRequestPlugin.py @@ -37,4 +37,3 @@ class UiRequestPlugin(object): return True else: # Invalid referer return False - diff --git a/plugins/disabled-Zeroname-local/__init__.py b/plugins/disabled-ZeronameLocal/__init__.py similarity index 100% rename from plugins/disabled-Zeroname-local/__init__.py rename to plugins/disabled-ZeronameLocal/__init__.py