alfred.py 3.2 KB

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