From 8e6541c456360f6f093c4e8ab8d50bbdd7fed89d Mon Sep 17 00:00:00 2001 From: Daniel Roberts Date: Tue, 4 Feb 2014 21:10:24 -0800 Subject: [PATCH 1/4] Initial commit of pluggable DNS system with proof-of-concept namecoin implementation. --- namecoin.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 namecoin.py diff --git a/namecoin.py b/namecoin.py new file mode 100644 index 0000000..795b59a --- /dev/null +++ b/namecoin.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python2 + +import json +from bitcoin.rpc import Proxy + +import httplib +import os.path + +import platform + +def get_proxy(user, password, port=8336): + return Proxy(service_url="http://{0}:{1}@localhost:{2}".format(user, password, port)) + +class NameTakenError(ValueError): + pass + +class Namecoin(object): + def __init__(self, proxy): + self.proxy = proxy + + def get_secret(self, name): + dns_record = self.proxy._call('name_show', 'd/' + name) # throws if the name doesn't exist, iirc + name_info = json.loads(dns_record['value']) + return name_info['syncnet']['secret'] # of course this could throw a KeyError + + def validate_address(self, name): + try: + self.clean_address(name) + except ValueError: + return False + else: + return True + + def clean_address(self, address): + name, suffix = address.rsplit('.', 1) + if suffix != 'bit': + raise ValueError("Address {0} ends with suffix .{1} instead of .bit".format(address, suffix)) + else: + return name + + def name_exists(self, name): + dns_record = self.proxy._call('name_show', 'd/' + name) # throws if the name doesn't exist, iirc + try: + name_info = json.loads(dns_record['value']) + except ValueError: + return False + else: + return bool(name_info.get('syncnet', {}).get('secret')) # of course this could throw a KeyError + + def register_name(self, name): + if self.name_exists(name): + raise NameTakenError("Name {0}.bit taken!".format(name)) # XXX: we might own this name though + + txid, rnd = self.proxy._call("name_new", 'd/' + name) + + # XXX: Store txid and/or rnd for name_firstupdate, poll at/around expected time + + def test_connection(self): + try: + self.proxy._call('help') + return True + except: + return False + + def _build_json_value(self, secret, existing=None): + existing = dict(existing) or {} + existing['syncnet'] = existing.get('syncnet', {}) + existing['syncnet']['secret'] = secret + return existing From cda30e41aabbd07c3ce15478b1c612fbf89bf481 Mon Sep 17 00:00:00 2001 From: Daniel Roberts Date: Wed, 5 Feb 2014 16:05:11 -0800 Subject: [PATCH 2/4] Plugged in DNS to syncnet. UNTESTED CODE --- syncnet.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/syncnet.py b/syncnet.py index cab0415..3f8993f 100644 --- a/syncnet.py +++ b/syncnet.py @@ -133,9 +133,20 @@ def _address_changed(self, change): a valid secret. If so, attempt to load that secret. """ - address = self.address.upper() - if self.is_valid_secret(address): - self.load_secret(address) + address = self.address.lower() + + try: + name = self.dns.clean_address(address) + except ValueError: + secret = self.address.upper() + else: + try: + secret = self.dns.get_secret(address.rsplit('.', 1)[-1]) + except (IndexError, KeyError, IOError): + secret = self.address.upper() + + if self.is_valid_secret(secret): + self.load_secret(secret) def on_directory_changed(self, dirname): """ Slot connected to the `QFileSystemWatcher.directoryChanged` Signal. @@ -222,6 +233,15 @@ def _update_address_bar(self, url): with enaml.imports(): from syncnet_view import SyncNetView syncnet = SyncNet() + + from namecoin import get_proxy, Namecoin + namecoin = Namecoin(get_proxy('asdf', 'asdf')) + + if namecoin.test_connection(): + syncnet.dns = namecoin + else: + logger.warn('Failed to initialize connection to local namecoin instance.') + app = QtApplication() view = SyncNetView(model=syncnet) view.show() From 139db9bf852db46ff86741739ba657f6fe177330 Mon Sep 17 00:00:00 2001 From: Daniel Roberts Date: Thu, 6 Feb 2014 18:13:00 -0800 Subject: [PATCH 3/4] Added dns value to alleviate an error. --- syncnet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/syncnet.py b/syncnet.py index 3f8993f..17c789b 100644 --- a/syncnet.py +++ b/syncnet.py @@ -6,7 +6,7 @@ import enaml from enaml.qt.qt_application import QtApplication from PyQt4.QtCore import QFileSystemWatcher -from atom.api import Atom, Unicode, observe, Typed, Property, Int +from atom.api import Atom, Unicode, observe, Typed, Property, Int, Value from btsync import BTSync @@ -34,6 +34,8 @@ class SyncNet(Atom): # Instance of the BTSync API wrapper. btsync = Typed(BTSync, ()) + dns = Value() + # The QUrl object referencing the currently displayed resource. It must be # replaced wholesale for the UI to react. url = Unicode() From b5f208fbb785ccfba31efb91023f8a8af034e5c1 Mon Sep 17 00:00:00 2001 From: ippisl Date: Sat, 22 Mar 2014 16:51:15 +0200 Subject: [PATCH 4/4] Correct packaging, from ademan And fixing a small bug in namecoin fetching. --- setup.py | 8 ++++---- syncnet/main.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 78a4607..cadb27c 100644 --- a/setup.py +++ b/setup.py @@ -8,12 +8,14 @@ README = f.read() requires = [ + 'python-bitcoinlib', 'atom', 'enaml', 'BTSync', ] dependency_links=[ + "https://github.com/petertodd/python-bitcoinlib/archive/pythonize.zip#egg=python-bitcoinlib", "https://github.com/ademan/python-btsync/archive/packaging.zip#egg=BTSync", ] @@ -25,9 +27,7 @@ "Programming Language :: Python", ], packages=find_packages(), - package_data={ - 'syncnet': ['*.enaml'], - }, + include_package_data=True, install_requires=requires, dependency_links=dependency_links, - ) + ) \ No newline at end of file diff --git a/syncnet/main.py b/syncnet/main.py index 95b30c8..6ef2938 100644 --- a/syncnet/main.py +++ b/syncnet/main.py @@ -149,7 +149,7 @@ def _address_changed(self, change): secret = self.address.upper() else: try: - secret = self.dns.get_secret(address.rsplit('.', 1)[-1]) + secret = self.dns.get_secret(name) except (IndexError, KeyError, IOError): secret = self.address.upper() @@ -245,14 +245,14 @@ def _update_address_bar(self, url): with enaml.imports(): from syncnet_view import SyncNetView syncnet = SyncNet() -<<<<<<< HEAD:syncnet/main.py + if getattr(sys, 'frozen', False): HERE = os.path.dirname(sys.executable) btsync_path = os.path.join( HERE, 'BitTorrent\ Sync.app/Contents/MacOS/BitTorrent\ Sync') syncnet.btsync.btsync_path = btsync_path syncnet.btsync.start() -======= + from namecoin import get_proxy, Namecoin namecoin = Namecoin(get_proxy('asdf', 'asdf')) @@ -262,7 +262,7 @@ def _update_address_bar(self, url): else: logger.warn('Failed to initialize connection to local namecoin instance.') ->>>>>>> refs/remotes/Ademan-syncnet/namecoin:syncnet.py + app = QtApplication() view = SyncNetView(model=syncnet) view.show()