ffpb_nodeinfo.py 6.0 KB

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