gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet-python] 02/32: Initial commit.


From: gnunet
Subject: [GNUnet-SVN] [gnunet-python] 02/32: Initial commit.
Date: Sat, 13 Apr 2019 13:20:19 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnunet-python.

commit 7c05570f7a2c7baeecf9fa9c9e9f47acb39b56bd
Author: Andrew Cann <address@hidden>
AuthorDate: Sat May 10 11:36:53 2014 +0000

    Initial commit.
    
    dht.get_start, dht.start and gns.lookup work
---
 example-dht.py        |  22 +++++++++++
 example-gns.py        |  15 ++++++++
 gnunet/__init__.py    |  31 +++++++++++++++
 gnunet/_dbus_utils.py |  65 +++++++++++++++++++++++++++++++
 gnunet/block.py       |  16 ++++++++
 gnunet/crypto.py      |  10 +++++
 gnunet/dht.py         | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gnunet/gns.py         |  48 +++++++++++++++++++++++
 gnunet/gnsrecord.py   |  36 +++++++++++++++++
 gnunet/strings.py     |  97 ++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 445 insertions(+)

diff --git a/example-dht.py b/example-dht.py
new file mode 100755
index 0000000..726e0be
--- /dev/null
+++ b/example-dht.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python3
+
+import gnunet.dht
+import time
+
+key = 
gnunet.HashCode("RMKN0U1JNA3PVCL148D6JI0STVG94A8A65INOK849CF1RT6BGF26AMMT14GMDMNRDFSJRJME6IKJ3LDFBUL2R1TPQJE64I55I32QN5G")
+
+gnunet.dht.put(key, 1, "test", b"hello")
+
+def result_callback(block_type, key, data, expiry, get_path, put_path):
+  print("Got result from DHT")
+  print("  block_type == %s" % repr(block_type))
+  print("  key        == %s" % repr(key))
+  print("  expiry     == %s" % repr(expiry))
+  print("  get_path   == %s" % repr(get_path))
+  print("  put_path   == %s" % repr(put_path))
+  print("  data       == %s" % repr(data))
+
+gnunet.dht.get_start(result_callback, "test", key, 1, record_route=True)
+
+time.sleep(1)
+
diff --git a/example-gns.py b/example-gns.py
new file mode 100755
index 0000000..4b3ea10
--- /dev/null
+++ b/example-gns.py
@@ -0,0 +1,15 @@
+#!/usr/bin/python3
+
+import gnunet.gns
+
+results = gnunet.gns.lookup("www.gnu", 
"JK55QA8JLAL64MBO8UM209KE93M9JBBO7M2UB8M3M03FKRFSUOMG", "A", True)
+
+for r in results:
+  print("Got result from gns")
+  print("  record_type     == %s" % repr(r.record_type))
+  print("  data            == %s" % repr(r.data))
+  print("  expiration_time == %s" % repr(r.expiration_time))
+  print("  private         == %s" % repr(r.private))
+  print("  pending         == %s" % repr(r.pending))
+  print("  shadow          == %s" % repr(r.shadow))
+
diff --git a/gnunet/__init__.py b/gnunet/__init__.py
new file mode 100644
index 0000000..425ab86
--- /dev/null
+++ b/gnunet/__init__.py
@@ -0,0 +1,31 @@
+import gnunet.strings as strings
+
+class GNUNetDaemonError(Exception):
+  pass
+
+class _Key:
+  def __init__(self, arg, subtype, bits):
+    if isinstance(arg, subtype):
+      self._data = arg.data
+    elif isinstance(arg, str):
+      self._data = strings.string_to_data(arg)
+    else:
+      try:
+        self._data = bytearray(arg)
+      except:
+        raise TypeError("'arg' must be a " + type(subtype).__name__ + ", a 
string or an array of bytes. Not a '" + type(arg).__name__ + "'.")
+
+    if len(self._data) * 8 != bits:
+      raise ValueError("'arg' must be a " + bits + " bit hash. Got " + 
len(self._data) + " bits.")
+
+  def __str__(self):
+    return strings.data_to_string(self._data)
+
+
+class HashCode(_Key):
+  def __init__(self, arg):
+    _Key.__init__(self, arg, HashCode, 512)
+
+  def __repr__(self):
+    return "gnunet.HashCode('" + str(self) + "')"
+
diff --git a/gnunet/_dbus_utils.py b/gnunet/_dbus_utils.py
new file mode 100644
index 0000000..4e08c2a
--- /dev/null
+++ b/gnunet/_dbus_utils.py
@@ -0,0 +1,65 @@
+import dbus
+import threading
+import datetime
+from gi.repository import Gtk
+
+from dbus.mainloop.glib import DBusGMainLoop, threads_init
+threads_init()
+DBusGMainLoop(set_as_default=True)
+sysbus = dbus.SystemBus()
+
+class MainLoop(threading.Thread):
+  def __init__(self):
+    threading.Thread.__init__(self)
+    self.daemon = True
+    self.start()
+
+  def run(self):
+    Gtk.main()
+
+MainLoop()
+
+from gnunet import _Key, GNUNetDaemonError
+import gnunet.strings as strings
+
+def pythonize(arg, argtype):
+  if argtype is datetime.datetime:
+    if isinstance(arg, str):
+      return strings.string_to_absolute_time(arg)
+    if isinstance(arg. dbus.UInt64):
+      return datetime.datetime(1970, 1, 1) + 
datetime.timedelta(microseconds=arg)
+    return datatime.datetime(arg)
+
+def dbusize(arg, pretty):
+  if isinstance(arg, _Key):
+    if pretty:
+      return dbus.String(arg, variant_level=1)
+    else:
+      return dbus.Array(arg._data[:], variant_level=1, signature="y")
+
+  #if type(arg) is gnsrecord.Data:
+    #return dbus.Struct([arg._recordtype, 
+
+  if isinstance(arg, datetime.datetime):
+    if pretty:
+      return dbus.String(strings.absolute_time_to_string(arg), variant_level=1)
+    else:
+      return dbus.UInt64((arg - datetime.datetime(1970, 1, 1)).total_seconds() 
* 1000000, variant_level=1)
+      
+def handle_exception(e, daemon, daemon_address):
+  name = e.get_dbus_name()
+  message = e.get_dbus_message()
+  if not name.startswith("org.freedesktop.DBus.Error."):
+    raise e
+  name = name[len("org.freedesktop.DBus.Error."):]
+
+  if name == "Failed" or name == "InvalidArgs":
+    raise GNUNetDaemonError(message)
+  if name == "NoMemory":
+    raise MemoryError(message)
+  if name == "ServiceUnknown" or name == "NameHasNoOwner":
+    raise GNUNetDaemonError("Failed to contact " + daemon + " daemon at " + 
daemon_address)
+  if name == "NoReply" or name == "Timeout":
+    raise GNUNetDaemonError("Did not receive reply from " + daemon + " daemon 
at " + daemon_address + ". Daemon might of crashed")
+  raise e
+
diff --git a/gnunet/block.py b/gnunet/block.py
new file mode 100644
index 0000000..2a2dfec
--- /dev/null
+++ b/gnunet/block.py
@@ -0,0 +1,16 @@
+types = set([
+    "any",
+    "fs_dblock",
+    "fs_iblock",
+    "fs_kblock",
+    "fs_sblock",
+    "fs_nblock",
+    "fs_ondemand",
+    "dht_hello",
+    "test",
+    "fs_ublock",
+    "dns",
+    "gns_namerecord",
+    "regex",
+    "regex_accept"])
+
diff --git a/gnunet/crypto.py b/gnunet/crypto.py
new file mode 100644
index 0000000..b81b49d
--- /dev/null
+++ b/gnunet/crypto.py
@@ -0,0 +1,10 @@
+from gnunet import _Key
+import gnunet.strings as strings
+
+class EcdsaPublicKey(_Key):
+  def __init__(self, arg):
+    _Key.__init__(self, arg, EcdsaPublicKey, 256)
+
+  def __repr__(self):
+    return "gnunet.crypto.EcdsaPublicKey('" + str(self) + "')"
+
diff --git a/gnunet/dht.py b/gnunet/dht.py
new file mode 100644
index 0000000..d26b7f2
--- /dev/null
+++ b/gnunet/dht.py
@@ -0,0 +1,105 @@
+import dbus
+
+import datetime
+
+from gnunet import *
+from gnunet._dbus_utils import *
+
+import gnunet.block as block
+
+get_requests = {}
+requests_lock = threading.Lock()
+
+class GetResult(threading.Thread):
+  def __init__(self, expiry, key, get_path, put_path, block_type, data, path):
+    threading.Thread.__init__(self)
+    self.expiry = expiry
+    self.key = key
+    self.get_path = get_path
+    self.put_path = put_path
+    self.block_type = block_type
+    self.data = data
+    self.path = path
+    self.daemon = True
+    self.start()
+
+  def run(self):
+    request = None
+    with requests_lock:
+      request = get_requests[self.path]
+
+    if request:
+      if request.record_route:
+        request.callback(self.block_type, self.key, self.data, self.expiry, 
get_path=self.get_path, put_path=self.put_path)
+      else:
+        request.callback(self.block_type, self.key, self.data, self.expiry)
+
+def _result(expiry, key, get_path, put_path, block_type, data, path):
+  expiry = pythonize(expiry, datetime.datetime)
+  key = HashCode(key)
+  get_path = list(get_path)
+  put_path = list(put_path)
+  block_type = str(block_type)
+  data = bytearray(data)
+  GetResult(expiry, key, get_path, put_path, block_type, data, path)
+
+sysbus.add_signal_receiver(_result, "result", "gnu.gnunet.dht.get", 
"gnu.gnunet.dht", path_keyword="path")
+
+class GetRequest:
+  def __init__(self, path, callback, record_route):
+    self._path = path
+    self.callback = callback
+    self.record_route = record_route
+
+def put(key, desired_replication_level, block_type, data, expiry=None, 
demultiplex_everywhere=False, record_route=False, bart=False):
+  key = dbusize(HashCode(key), True)
+  desired_replication_level = dbus.UInt32(desired_replication_level)
+  if block_type not in block.types:
+    raise ValueError("'block_type' must be one of %s" % block.types)
+  block_type = dbus.String(block_type, variant_level=1)
+  if expiry is not None:
+    if not isinstance(expiry, datetime.datetime):
+      raise TypeError("'expiry' must be a datetime.datetime")
+    expiry = dbusize(expiry)
+  else:
+    expiry = dbus.String("end of time", variant_level=1)
+  options = dbus.Array([], variant_level=1, signature="s")
+  if demultiplex_everywhere:
+    options += ["demultiplex_everywhere"]
+  if record_route:
+    options += ["record_route"]
+  if bart:
+    options += ["bart"]
+  data = dbus.Array(bytearray(data), signature="y")
+
+  try:
+    sysbus.get_object("gnu.gnunet.dht", "/").put(key, 
desired_replication_level, options, block_type, data, expiry)
+  except dbus.DBusException as e:
+    handle_exception(e, "dht", "gnu.gnunet.dht")
+
+def get_start(callback, block_type, key, desired_replication_level, 
demultiplex_everywhere=False, record_route=False, bart=False):
+  if block_type not in block.types:
+    raise ValueError("'block_type' must be one of %s" % block.types)
+  block_type = dbus.String(block_type, variant_level=1)
+  key = dbusize(HashCode(key), True)
+  desired_replication_level = dbus.UInt32(desired_replication_level)
+  options = dbus.Array([], variant_level=1, signature="s")
+  if demultiplex_everywhere:
+    options += ["demultiplex_everywhere"]
+  if record_route:
+    options += ["record_route"]
+  if bart:
+    options += ["bart"]
+  
+  ret = None
+  try:
+    with requests_lock:
+      path = sysbus.get_object("gnu.gnunet.dht", "/").get_start(block_type, 
key, desired_replication_level, options)
+      ret = GetRequest(path, callback, record_route)
+      get_requests[path] = ret
+  except dbus.DBusException as e:
+    handle_exception(e, "dht", "gnu.gnunet.dht")
+
+  return ret
+
+
diff --git a/gnunet/gns.py b/gnunet/gns.py
new file mode 100644
index 0000000..57c1bd9
--- /dev/null
+++ b/gnunet/gns.py
@@ -0,0 +1,48 @@
+import dbus
+
+from gnunet._dbus_utils import *
+
+from gnunet import *
+import gnunet.crypto as crypto
+import gnunet.gnsrecord as gnsrecord
+
+def lookup(name, zone, record_type, only_cached):
+  name = str(name)
+  zone = dbusize(crypto.EcdsaPublicKey(zone), True)
+  if record_type not in gnsrecord.types:
+    raise ValueError("'record_type' must be one of %s" % gnsrecord.types)
+  #record_type = dbus.UInt32(gnsrecord.types[record_type], variant_level=1)
+  record_type = dbus.String(record_type, variant_level=1)
+  only_cached = dbus.Boolean(only_cached)
+
+  try:
+    results = sysbus.get_object("gnu.gnunet.gns", "/").lookup(name, zone, 
record_type, only_cached)
+  except dbus.DBusException as e:
+    handle_exception(e, "gns", "gnu.gnunet.gns")
+
+  ret = []
+  for r in results:
+    record_type = str(r[0])
+    private = False
+    pending = False
+    shadow = False
+    relative = False
+    for f in r[1]:
+      if f == "private":
+        private = True
+      if f == "pending":
+        pending = True
+      if f == "shadow":
+        shadow = True
+      if f == "relative_expiration":
+        relative = True
+    data = str(r[2])
+    expiration_time = None
+    if relative:
+      expiration_time = pythonize(r[3], datetime.timedelta)
+    else:
+      expiration_time = pythonize(r[3], datetime.datetime)
+    ret.append(gnsrecord.Data(record_type, data, expiration_time, private, 
pending, shadow))
+
+  return ret
+
diff --git a/gnunet/gnsrecord.py b/gnunet/gnsrecord.py
new file mode 100644
index 0000000..4d00139
--- /dev/null
+++ b/gnunet/gnsrecord.py
@@ -0,0 +1,36 @@
+import datetime
+
+dns_types = {
+  "A":      1,
+  "NS":     2,
+  "CNAME":  5,
+  "SOA":    6,
+  "PTR":    12,
+  "MX":     15,
+  "TXT":    16,
+  "AAAA":   28,
+  "TLSA":   52}
+
+gns_types = {
+  "PKEY":     65536,
+  "NICK":     65537,
+  "LEHO":     65538,
+  "VPN":      65539,
+  "GNS2DNS":  65540}
+
+types = dict(list(dns_types.items()) + list(gns_types.items()))
+
+class Data:
+  def __init__(self, record_type, data, expiration_time=None, private=None, 
pending=None, shadow=None):
+    self.record_type = str(record_type)
+    if record_type not in types:
+      raise ValueError("'record_type' must be one of %s" % types)
+    #self.data = bytearray(data)
+    self.data = str(data)
+    if expiration_time is not None and not isinstance(expiration_time, 
datetime.datetime) or isinstance(expiration_time, datetime.timedelta):
+      raise TypeError("'expiration_time' must be a datetime.datetime or a 
datetime.timedelta")
+    self.expiration_time = expiration_time
+    self.private = private
+    self.pending = pending
+    self.shadow = shadow
+
diff --git a/gnunet/strings.py b/gnunet/strings.py
new file mode 100644
index 0000000..cfbdaa5
--- /dev/null
+++ b/gnunet/strings.py
@@ -0,0 +1,97 @@
+import datetime
+
+from gnunet import *
+
+encTable = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
+
+def data_to_string(data):
+  data = bytearray(data)
+  size = len(data)
+  bits = 0
+  rpos = 0
+  vbit = 0
+  ret = ""
+  while rpos < size:
+    while rpos < size and vbit < 5:
+      bits = (bits << 8) | data[rpos]
+      rpos += 1
+      vbit += 8
+    while vbit >= 5:
+      vbit -= 5
+      ret += encTable[(bits >> vbit) & 31]
+  if vbit > 0:
+    ret += encTable[(bits << (5 - vbit)) & 31]
+  return ret
+
+def string_to_data(s):
+  s = str(s)
+  size = len(s)
+  bits = 0
+  rpos = 0
+  vbit = 0
+  ret = bytearray([])
+  try:
+    while rpos < size:
+      while rpos < size and vbit < 8:
+        bits = (bits << 5) | int(s[rpos], 32)
+        rpos += 1
+        vbit += 5
+      while vbit >= 8:
+        vbit -= 8
+        ret.append((bits >> vbit) & 255)
+    if vbit > 0:
+      if bits & ((1 << vbit) - 1) != 0:
+        raise ValueError("")
+  except ValueError:
+    raise ValueError("'" + s + "' is not a valid data-encoding string")
+  return ret
+  
+def absolute_time_to_string(t):
+  return t.strftime("%a %b %d %H:%M:%S %Y")
+
+def string_to_absolute_time(s):
+  if s == "end of time":
+    return None
+  try:
+    return datetime.datetime.strptime(s, "%a %b %d %H:%M:%S %Y")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%c")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Ec")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Y-%m-%d %H:%M")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%x")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Ex")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Y-%m-%d")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Y-%m")
+  except ValueError:
+    pass
+  try:
+    return datetime.datetime.strptime(s, "%Y")
+  except ValueError:
+    pass
+  raise ValueError("%s is not a properly formatted time string" % s)
+
+

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]