registry.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. """Parsing library for the dn42 registry.
  2. All data is parsed as python dictionaries, and can be exported as JSON.
  3. Example usage:
  4. from registry import Dns
  5. dns = Dns("/home/example/net.dn42.registry")
  6. print(dns.data["internal.dn42"])
  7. with open("/tmp/dns.json", "w") as f:
  8. dns.write_json(f)
  9. There are several classes available: Inetnum, AutNum, etc (see below).
  10. They follow the naming convention of the folders in data/, using
  11. CamelCase.
  12. There is also a big class containing all relevant data from the registry,
  13. in case you're not afraid of the performance penalty of parsing 1145 small
  14. files:
  15. from registry import Registry
  16. dn42 = Registry("/home/example/net.dn42.registry")
  17. print(dn42.dns.data)
  18. print(dn42.inetnum.data)
  19. """
  20. import os
  21. import json
  22. def parse_record(stream):
  23. """General parsing of the "key: value" syntax. Returns a key -> [values]
  24. dictionary.
  25. """
  26. d = dict()
  27. for entry in stream.readlines():
  28. try:
  29. key, value = [s.strip() for s in entry.split(':', 1)]
  30. if not key in d:
  31. d[key] = list()
  32. d[key].append(value)
  33. except ValueError: pass
  34. return d
  35. def parse_records(records_dir, replace_underscore=None):
  36. """Takes a directory containing records, and builds a dictionary mapping
  37. the filename of each record to its parsed data. If requested, we
  38. transform '_' by [replace_underscore] in the name of the records.
  39. """
  40. records = dict()
  41. for record in os.listdir(records_dir):
  42. record_path = os.path.join(records_dir, record)
  43. record_key = record.replace('_', replace_underscore) if replace_underscore else record
  44. with open(record_path, "r") as f:
  45. records[record_key] = parse_record(f)
  46. return records
  47. class Dn42Entry(object):
  48. """Should not be used directly, use one of the sub-classes below."""
  49. directory = ""
  50. data = dict()
  51. def __init__(self, registrypath, replace_underscore=None):
  52. fullpath = os.path.join(registrypath, "data", self.directory)
  53. self.data = parse_records(fullpath, replace_underscore)
  54. def write_json(self, stream):
  55. json.dump(self.data, stream)
  56. def get_json(self):
  57. return json.dumps(self.data)
  58. class Dns(Dn42Entry):
  59. def __init__(self, registrypath):
  60. self.directory = "dns"
  61. super(Dns, self).__init__(registrypath)
  62. class Inetnum(Dn42Entry):
  63. def __init__(self, registrypath):
  64. self.directory = "inetnum"
  65. super(Inetnum, self).__init__(registrypath, '/')
  66. class Inet6num(Dn42Entry):
  67. def __init__(self, registrypath):
  68. self.directory = "inet6num"
  69. super(Inet6num, self).__init__(registrypath, '/')
  70. class Route(Dn42Entry):
  71. def __init__(self, registrypath):
  72. self.directory = "route"
  73. super(Route, self).__init__(registrypath, '/')
  74. class Route6(Dn42Entry):
  75. def __init__(self, registrypath):
  76. self.directory = "route6"
  77. super(Route6, self).__init__(registrypath, '/')
  78. class Person(Dn42Entry):
  79. def __init__(self, registrypath):
  80. self.directory = "person"
  81. super(Person, self).__init__(registrypath)
  82. class Organisation(Dn42Entry):
  83. def __init__(self, registrypath):
  84. self.directory = "organisation"
  85. super(Organisation, self).__init__(registrypath)
  86. class Mntner(Dn42Entry):
  87. def __init__(self, registrypath):
  88. self.directory = "mntner"
  89. super(Mntner, self).__init__(registrypath)
  90. class AsBlock(Dn42Entry):
  91. def __init__(self, registrypath):
  92. self.directory = "as-block"
  93. super(AsBlock, self).__init__(registrypath, '-')
  94. class AsSet(Dn42Entry):
  95. def __init__(self, registrypath):
  96. self.directory = "as-set"
  97. super(AsSet, self).__init__(registrypath)
  98. class AutNum(Dn42Entry):
  99. def __init__(self, registrypath):
  100. self.directory = "aut-num"
  101. super(AutNum, self).__init__(registrypath)
  102. class Registry(Dn42Entry):
  103. """Big class that provides all available data from the registry."""
  104. def __init__(self, registrypath):
  105. self.dns = Dns(registrypath)
  106. self.inetnum = Inetnum(registrypath)
  107. self.inet6num = Inet6num(registrypath)
  108. self.route = Route(registrypath)
  109. self.route6 = Route6(registrypath)
  110. self.person = Person(registrypath)
  111. self.organisation = Organisation(registrypath)
  112. self.mntner = Mntner(registrypath)
  113. self.asblock = AsBlock(registrypath)
  114. self.asset = AsSet(registrypath)
  115. self.autnum = AutNum(registrypath)