ffpb_nodeinfo.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. import time
  4. import willie
  5. from ffpb import \
  6. ffpb_findnode_from_botparam, \
  7. ffpb_get_batcave_nodefield, \
  8. mac2ipv6, playitsafe, pretty_date
  9. def setup(bot):
  10. """Called by willie upon loading this plugin."""
  11. pass
  12. def shutdown(bot):
  13. """Called by willie upon unloading this plugin."""
  14. pass
  15. @willie.module.commands('alfred-data')
  16. def ffpb_peerdata(bot, trigger):
  17. """Show ALFRED data of the given node."""
  18. # identify node or bail out
  19. target_name = trigger.group(2)
  20. node = ffpb_findnode_from_botparam(bot, target_name)
  21. if node is None:
  22. return
  23. # query must be a PM or as OP in the channel
  24. if not playitsafe(bot, trigger, via_privmsg=True, node=node):
  25. # the check function already gives a bot reply, just exit here
  26. return
  27. # reply each key in the node's data
  28. for key in node:
  29. # skip some fields
  30. if key in ['hostname']:
  31. continue
  32. bot.say("{0}.{1} = {2}".format(node['hostname'], key, node[key]))
  33. @willie.module.commands('info')
  34. def ffpb_peerinfo(bot, trigger):
  35. """Show information of the given node."""
  36. # identify node or bail out
  37. target_name = trigger.group(2)
  38. node = ffpb_findnode_from_botparam(bot, target_name)
  39. if node is None:
  40. return
  41. # read node information
  42. info_mac = node['network']['mac'] if 'network' in node and 'mac' in node['network'] else '??:??:??:??:??:??'
  43. info_id = node['node_id'] if 'node_id' in node else info_mac.replace(':', '')
  44. info_name = node['hostname'] if 'hostname' in node else '?-' + info_id
  45. info_hw = ""
  46. if "hardware" in node:
  47. if "model" in node["hardware"]:
  48. model = node["hardware"]["model"]
  49. info_hw = " model='" + model + "'"
  50. info_fw = ""
  51. info_update = ""
  52. if "software" in node:
  53. if "firmware" in node["software"]:
  54. if "release" in node["software"]["firmware"]:
  55. info_fw = " firmware=" + str(node["software"]["firmware"]["release"])
  56. else:
  57. info_fw = " unknown firmware"
  58. if "autoupdater" in node["software"]:
  59. autoupdater = node["software"]["autoupdater"]["branch"] if node["software"]["autoupdater"]["enabled"] else "off"
  60. info_update = " (autoupdater="+autoupdater+")"
  61. info_uptime = ""
  62. uptime = -1
  63. if "statistics" in node and "uptime" in node["statistics"]:
  64. uptime = int(float(node["statistics"]["uptime"]))
  65. elif 'uptime' in node:
  66. uptime = int(float(node['uptime']))
  67. if uptime > 0:
  68. days, rem_d = divmod(uptime, 86400)
  69. hours, rem_h = divmod(rem_d, 3600)
  70. minutes, _ = divmod(rem_h, 60)
  71. if days > 0:
  72. info_uptime = ' up {0}d {1}h'.format(days, hours)
  73. elif hours > 0:
  74. info_uptime = ' up {0}h {1}m'.format(hours, minutes)
  75. else:
  76. info_uptime = ' up {0}m'.format(minutes)
  77. info_clients = ""
  78. clientcount = ffpb_get_batcave_nodefield(info_id, 'clientcount')
  79. if not clientcount is None:
  80. clientcount = int(clientcount)
  81. info_clients = ' clients={0}'.format(clientcount)
  82. bot.say('[{1}]{2}{3}{4}{5}{6}'.format(info_mac, info_name, info_hw, info_fw, info_update, info_uptime, info_clients))
  83. @willie.module.commands('last-seen')
  84. @willie.module.commands('last_seen')
  85. @willie.module.commands('lastseen')
  86. def ffpb_lastseen(bot, trigger):
  87. """Display when the given node has last been seen."""
  88. # identify node or bail out
  89. target_name = trigger.group(2)
  90. node = ffpb_findnode_from_botparam(bot, target_name)
  91. if node is None:
  92. return
  93. last_seen = ffpb_get_batcave_nodefield(node['node_id'], '__UPDATED__')
  94. a_value = int(last_seen['alfred']) if (not last_seen is None) and 'alfred' in last_seen else None
  95. a_delta = time.time() - a_value if not a_value is None else None
  96. b_value = int(last_seen['batadv']) if (not last_seen is None) and 'batadv' in last_seen else None
  97. b_delta = time.time() - b_value if not b_value is None else None
  98. if a_value is None and b_value is None:
  99. bot.say('{0} wurde offenbar noch gar nicht gesehen?'.format(node['hostname']))
  100. return
  101. if a_delta < 30 and b_delta < 30:
  102. bot.say('{0} wurde gerade eben gesehen.'.format(node['hostname']))
  103. return
  104. if a_value is not None and b_value is not None and abs(a_value - b_value) < 60:
  105. bot.say('{0} wurde zuletzt gesehen: {1}'.format(
  106. node['hostname'],
  107. pretty_date((a_value + b_value) / 2)))
  108. else:
  109. bot.say('{0} wurde zuletzt gesehen: {1} (ALFRED,) bzw. {2} (BATMAN)'.format(
  110. node['hostname'],
  111. pretty_date(a_value) if not a_value is None else "nie",
  112. pretty_date(b_value) if not b_value is None else "nie"
  113. ))
  114. @willie.module.commands('uptime')
  115. def ffpb_peeruptime(bot, trigger):
  116. """Display the uptime of the given node."""
  117. # identify node or bail out
  118. target_name = trigger.group(2)
  119. node = ffpb_findnode_from_botparam(bot, target_name)
  120. if node is None:
  121. return
  122. # get name and raw uptime from node
  123. info_name = node["hostname"]
  124. info_uptime = ''
  125. u_raw = None
  126. if 'statistics' in node and 'uptime' in node['statistics']:
  127. u_raw = node['statistics']['uptime']
  128. elif 'uptime' in node:
  129. u_raw = node['uptime']
  130. # pretty print uptime
  131. if not u_raw is None:
  132. uptime = int(float(u_raw))
  133. days, rem_d = divmod(uptime, 86400)
  134. hours, rem_h = divmod(rem_d, 3600)
  135. minutes, _ = divmod(rem_h, 60)
  136. if days > 0:
  137. info_uptime += '{0}d '.format(days)
  138. if hours > 0:
  139. info_uptime += '{0}h '.format(hours)
  140. info_uptime += '{0}m'.format(minutes)
  141. info_uptime += ' # raw: \'{0}\''.format(u_raw)
  142. else:
  143. info_uptime += '?'
  144. # reply to user
  145. bot.say('uptime(\'{0}\') = {1}'.format(info_name, info_uptime))
  146. @willie.module.commands('link')
  147. def ffpb_peerlink(bot, trigger):
  148. """Display MAC and link to statuspage for the given node."""
  149. # identify node or bail out
  150. target_name = trigger.group(2)
  151. node = ffpb_findnode_from_botparam(bot, target_name)
  152. if node is None:
  153. return
  154. # get node's MAC
  155. info_mac = node["network"]["mac"]
  156. info_name = node["hostname"]
  157. # get node's v6 address in the mesh (derived from MAC address)
  158. info_v6 = mac2ipv6(info_mac, 'fdca:ffee:ff12:132:')
  159. # reply to user
  160. bot.say('[{1}] mac {0} -> http://[{2}]/'.format(info_mac, info_name, info_v6))