alfred.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function
  4. import io
  5. import json
  6. import subprocess
  7. import time
  8. from .exceptions import SanityCheckError
  9. class AlfredParser:
  10. alfred_json = 'alfred-json'
  11. alfred_datatypes = [('static', 158), ('dynamic', 159)]
  12. def __str__(self):
  13. types = ['{1}=>{0}'.format(x[0], x[1]) for x in self.alfred_datatypes]
  14. return 'AlfredParser \'{0}\' {1}'.format(
  15. self.alfred_json,
  16. str.join(' ', types),
  17. )
  18. def sanitycheck(self):
  19. testdata = None
  20. try:
  21. cmd = [self.alfred_json, '-z', '-r', str(int(self.alfred_datatypes[0][1]))]
  22. testdata = subprocess.check_output(cmd)
  23. except Exception as err:
  24. raise SanityCheckError(
  25. self, "alfred-json not found or incompatible", err)
  26. try:
  27. json.loads(testdata)
  28. except Exception as err:
  29. raise SanityCheckError(
  30. self, "alfred-json does not return valid JSON data", err)
  31. return True
  32. def fetch(self, alfred_dump=None, include_rawdata=False):
  33. data = { }
  34. ts = int(time.time())
  35. alfreddata = {}
  36. for datatype in self.alfred_datatypes:
  37. rawdata = subprocess.check_output([self.alfred_json, '-z', '-r', str(int(datatype[1]))])
  38. newdata = json.loads(rawdata)
  39. for item in newdata:
  40. if not item in alfreddata:
  41. alfreddata[item] = {}
  42. alfreddata[item][datatype[0]] = newdata[item]
  43. if not alfred_dump is None:
  44. jsondata = json.dumps(alfreddata, ensure_ascii=False)
  45. dumpfile = io.open(alfred_dump, 'w')
  46. dumpfile.write(jsondata)
  47. dumpfile.close()
  48. for alfredid in alfreddata:
  49. alfredinfo = alfreddata[alfredid]
  50. if 'node_id' in alfredinfo['static']:
  51. myid = alfredinfo['static']['node_id']
  52. else:
  53. alfredid.lower().replace(':', '')
  54. nodeinfo = {
  55. 'hostname': None,
  56. 'mac': None,
  57. 'software': {},
  58. 'statistics': {},
  59. '__UPDATED__': {'alfred': ts,},
  60. '__RAW__': {'alfred': alfredinfo,},
  61. }
  62. data[myid] = nodeinfo
  63. nodestatic = alfredinfo['static']
  64. if 'hostname' in nodestatic:
  65. nodeinfo['hostname'] = nodestatic['hostname']
  66. if 'network' in nodestatic:
  67. if 'mac' in nodestatic['network']:
  68. nodeinfo['mac'] = nodestatic['network']['mac']
  69. if 'mesh_interfaces' in nodestatic['network']:
  70. nodeinfo['macs'] = [x for x in nodestatic['network']['mesh_interfaces']]
  71. else:
  72. nodeinfo['macs'] = []
  73. if 'software' in nodestatic:
  74. sw = nodestatic['software']
  75. nodeinfo['software']['firmware'] = sw['firmware']['release'] if 'firmware' in sw and 'release' in sw['firmware'] else None
  76. nodeinfo['software']['autoupdater'] = sw['autoupdater']['branch'] if sw['autoupdater']['enabled'] else 'off'
  77. nodedyn = alfredinfo['dynamic'] if 'dynamic' in alfredinfo else nodestatic['statistics']
  78. if 'uptime' in nodedyn:
  79. nodeinfo['uptime'] = int(float(nodedyn['uptime']))
  80. if 'gateway' in nodedyn:
  81. nodeinfo['gateway'] = nodedyn['gateway']
  82. traffic = nodedyn["traffic"] if "traffic" in nodedyn else None
  83. if not traffic is None:
  84. if not 'traffic' in nodeinfo['statistics']:
  85. nodeinfo['statistics']['traffic'] = { }
  86. t = nodeinfo['statistics']['traffic']
  87. t['rxbytes'] = int(traffic["rx"]["bytes"])
  88. t['txbytes'] = int(traffic["tx"]["bytes"])
  89. return data
  90. if __name__ == "__main__":
  91. a = AlfredParser()
  92. try:
  93. a.sanitycheck()
  94. except SanityCheckError as err:
  95. print('SANITY-CHECK failed:', str(err))
  96. import sys
  97. sys.exit(1)
  98. adata = a.fetch()
  99. print(json.dumps(adata))