|
@@ -0,0 +1,149 @@
|
|
|
+"""Parsing library for the dn42 registry.
|
|
|
+
|
|
|
+All data is parsed as python dictionaries, and can be exported as JSON.
|
|
|
+Example usage:
|
|
|
+
|
|
|
+ from registry import Dns
|
|
|
+ dns = Dns("/home/example/net.dn42.registry")
|
|
|
+ print(dns.data["internal.dn42"])
|
|
|
+ with open("/tmp/dns.json", "w") as f:
|
|
|
+ dns.write_json(f)
|
|
|
+
|
|
|
+There are several classes available: Inetnum, AutNum, etc (see below).
|
|
|
+They follow the naming convention of the folders in data/, using
|
|
|
+CamelCase.
|
|
|
+
|
|
|
+There is also a big class containing all relevant data from the registry,
|
|
|
+in case you're not afraid of the performance penalty of parsing 1145 small
|
|
|
+files:
|
|
|
+
|
|
|
+ from registry import Registry
|
|
|
+ dn42 = Registry("/home/example/net.dn42.registry")
|
|
|
+ print(dn42.dns.data)
|
|
|
+ print(dn42.inetnum.data)
|
|
|
+
|
|
|
+"""
|
|
|
+
|
|
|
+import os
|
|
|
+import json
|
|
|
+
|
|
|
+def parse_record(stream):
|
|
|
+ """General parsing of the "key: value" syntax. Returns a key -> [values]
|
|
|
+ dictionary.
|
|
|
+ """
|
|
|
+ d = dict()
|
|
|
+ for entry in stream.readlines():
|
|
|
+ try:
|
|
|
+ key, value = [s.strip() for s in entry.split(':', 1)]
|
|
|
+ if not key in d:
|
|
|
+ d[key] = list()
|
|
|
+ d[key].append(value)
|
|
|
+ except ValueError: pass
|
|
|
+ return d
|
|
|
+
|
|
|
+
|
|
|
+def parse_records(records_dir, replace_underscore=None):
|
|
|
+ """Takes a directory containing records, and builds a dictionary mapping
|
|
|
+ the filename of each record to its parsed data. If requested, we
|
|
|
+ transform '_' by [replace_underscore] in the name of the records.
|
|
|
+
|
|
|
+ """
|
|
|
+ records = dict()
|
|
|
+ for record in os.listdir(records_dir):
|
|
|
+ record_path = os.path.join(records_dir, record)
|
|
|
+ record_key = record.replace('_', replace_underscore) if replace_underscore else record
|
|
|
+ with open(record_path, "r") as f:
|
|
|
+ records[record_key] = parse_record(f)
|
|
|
+ return records
|
|
|
+
|
|
|
+
|
|
|
+class Dn42Entry(object):
|
|
|
+ """Should not be used directly, use one of the sub-classes below."""
|
|
|
+ directory = ""
|
|
|
+ data = dict()
|
|
|
+
|
|
|
+ def __init__(self, registrypath, replace_underscore=None):
|
|
|
+ fullpath = os.path.join(registrypath, "data", self.directory)
|
|
|
+ self.data = parse_records(fullpath, replace_underscore)
|
|
|
+
|
|
|
+ def write_json(self, stream):
|
|
|
+ json.dump(self.data, stream)
|
|
|
+
|
|
|
+ def get_json(self):
|
|
|
+ return json.dumps(self.data)
|
|
|
+
|
|
|
+
|
|
|
+class Dns(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "dns"
|
|
|
+ super(Dns, self).__init__(registrypath)
|
|
|
+
|
|
|
+
|
|
|
+class Inetnum(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "inetnum"
|
|
|
+ super(Inetnum, self).__init__(registrypath, '/')
|
|
|
+
|
|
|
+class Inet6num(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "inet6num"
|
|
|
+ super(Inet6num, self).__init__(registrypath, '/')
|
|
|
+
|
|
|
+
|
|
|
+class Route(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "route"
|
|
|
+ super(Route, self).__init__(registrypath, '/')
|
|
|
+
|
|
|
+class Route6(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "route6"
|
|
|
+ super(Route6, self).__init__(registrypath, '/')
|
|
|
+
|
|
|
+
|
|
|
+class Person(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "person"
|
|
|
+ super(Person, self).__init__(registrypath)
|
|
|
+
|
|
|
+class Organisation(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "organisation"
|
|
|
+ super(Organisation, self).__init__(registrypath)
|
|
|
+
|
|
|
+class Mntner(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "mntner"
|
|
|
+ super(Mntner, self).__init__(registrypath)
|
|
|
+
|
|
|
+
|
|
|
+class AsBlock(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "as-block"
|
|
|
+ super(AsBlock, self).__init__(registrypath, '-')
|
|
|
+
|
|
|
+class AsSet(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "as-set"
|
|
|
+ super(AsSet, self).__init__(registrypath)
|
|
|
+
|
|
|
+class AutNum(Dn42Entry):
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.directory = "aut-num"
|
|
|
+ super(AutNum, self).__init__(registrypath)
|
|
|
+
|
|
|
+
|
|
|
+class Registry(Dn42Entry):
|
|
|
+ """Big class that provides all available data from the registry."""
|
|
|
+ def __init__(self, registrypath):
|
|
|
+ self.dns = Dns(registrypath)
|
|
|
+ self.inetnum = Inetnum(registrypath)
|
|
|
+ self.inet6num = Inet6num(registrypath)
|
|
|
+ self.route = Route(registrypath)
|
|
|
+ self.route6 = Route6(registrypath)
|
|
|
+ self.person = Person(registrypath)
|
|
|
+ self.organisation = Organisation(registrypath)
|
|
|
+ self.mntner = Mntner(registrypath)
|
|
|
+ self.asblock = AsBlock(registrypath)
|
|
|
+ self.asset = AsSet(registrypath)
|
|
|
+ self.autnum = AutNum(registrypath)
|