123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- # -*- coding: utf-8 -*-
- from __future__ import print_function
- import time
- import willie
- from ffpb import \
- ffpb_findnode_from_botparam, \
- mac2ipv6, playitsafe, pretty_date
- from batcave import BatcaveClient
- __batcave = None
- def setup(bot):
- """Called by willie upon loading this plugin."""
- global __batcave, highscores
- __batcave = BatcaveClient(bot.config.ffpb.batcave_url)
- pass
- def shutdown(bot):
- """Called by willie upon unloading this plugin."""
- pass
- @willie.module.commands('identify')
- def ffpb_identify(bot, trigger):
- """Identify node."""
- # query must be as OP in the channel
- if not playitsafe(bot, trigger, via_channel=True, need_op=True):
- # the check function already gives a bot reply, just exit here
- return
- ident = trigger.group(2) or ""
- ident = ident.lower()
- result = __batcave.identify(ident)
- if result is None:
- bot.say('Mist, ich erreiche den Detektiv nicht.')
- return
- if not ident in result:
- bot.say('Mein Detektiv hat getrunken und erzählt Blödsinn.')
- return
- if len(result[ident]) == 0:
- bot.say('"%s" konnte nicht zugeordnet werden :/' % ident)
- elif len(result[ident]) == 1:
- bot.say('"%s" ist eindeutig: %s' % (ident, result[ident][0]))
- else:
- bot.say('"{0}" ist mehrdeutig: {1}'.format(
- ident, str.join(', ', result[ident])))
- @willie.module.commands('raw-data')
- def ffpb_peerdata(bot, trigger):
- """Show ALFRED data of the given node."""
- # identify node or bail out
- target_name = trigger.group(2)
- node = ffpb_findnode_from_botparam(bot, target_name)
- if node is None:
- return
- # query must be a PM or as OP in the channel
- if not playitsafe(bot, trigger, via_privmsg=True, node=node):
- # the check function already gives a bot reply, just exit here
- return
- # reply each key in the node's data
- for key in node:
- # skip some fields
- if key in ['hostname']:
- continue
- bot.say("{0}.{1} = {2}".format(
- node.get('hostname', '?-' + target_name),
- key, node[key]))
- @willie.module.commands('info')
- def ffpb_peerinfo(bot, trigger):
- """Show information of the given node."""
- # identify node or bail out
- target_name = trigger.group(2)
- node = ffpb_findnode_from_botparam(bot, target_name)
- if node is None:
- return
- output = []
- # read node information
- info_mac = node.get('network', {}).get('mac', '??:??:??:??:??:??')
- info_id = node.get('node_id', info_mac.replace(':', ''))
- info_name = node.get('hostname', '?-' + info_id)
- output.append("[" + info_name + "]")
- if "hardware" in node:
- model = node["hardware"]
- output.append("model='" + model + "'")
- if "software" in node:
- if "firmware" in node["software"]:
- output.append("firmware=" + str(node["software"]["firmware"]))
- if "autoupdater" in node["software"]:
- autoupdater = node["software"]["autoupdater"]
- output.append("(autoupdater="+autoupdater+")")
- uptime = node.get('uptime', -1)
- if uptime > 0:
- days, rem_d = divmod(uptime, 86400)
- hours, rem_h = divmod(rem_d, 3600)
- minutes, _ = divmod(rem_h, 60)
- if days > 0:
- output.append('up {0}d {1}h'.format(days, hours))
- elif hours > 0:
- output.append('up {0}h {1}m'.format(hours, minutes))
- else:
- output.append('up {0}m'.format(minutes))
- clientcount = node.get('clientcount')
- if not clientcount is None:
- clientcount = int(clientcount)
- output.append('clients={0}'.format(clientcount))
- nodestatus = node.get('status', 'unknown')
- if nodestatus != 'active':
- output.append("[" + nodestatus.upper() + "]")
- bot.say(str.join(" ", output))
- @willie.module.commands('last-seen')
- @willie.module.commands('last_seen')
- @willie.module.commands('lastseen')
- def ffpb_lastseen(bot, trigger):
- """Display when the given node has last been seen."""
- # identify node or bail out
- target_name = trigger.group(2)
- node = ffpb_findnode_from_botparam(bot, target_name)
- if node is None:
- return
- node_name = node.get('hostname')
- last_seen = node.get('__UPDATED__')
- if last_seen is not None:
- a_value = int(last_seen.get('alfred'))
- b_value = int(last_seen.get('batadv'))
- else:
- a_value = b_value = None
- a_delta = time.time() - a_value if a_value is not None else None
- b_delta = time.time() - b_value if b_value is not None else None
- if a_value is None and b_value is None:
- bot.say('{0} wurde offenbar noch gar nicht gesehen?'.format(node_name))
- return
- if a_delta < 30 and b_delta < 30:
- bot.say('{0} wurde gerade eben gesehen.'.format(node_name))
- return
- if a_value is not None and b_value is not None and \
- abs(a_value - b_value) < 60:
- bot.say('{0} wurde zuletzt gesehen: {1}'.format(
- node_name,
- pretty_date((a_value + b_value) / 2)))
- else:
- bot.say('{0} wurde zuletzt gesehen: {1} (ALFRED,) bzw. {2} (BATMAN)'.format(
- node_name,
- pretty_date(a_value) if not a_value is None else "nie",
- pretty_date(b_value) if not b_value is None else "nie"
- ))
- @willie.module.commands('uptime')
- def ffpb_peeruptime(bot, trigger):
- """Display the uptime of the given node."""
- # identify node or bail out
- target_name = trigger.group(2)
- node = ffpb_findnode_from_botparam(bot, target_name)
- if node is None:
- return
- # get name and raw uptime from node
- info_name = node["hostname"]
- info_uptime = ''
- u_raw = None
- if 'statistics' in node and 'uptime' in node['statistics']:
- u_raw = node['statistics']['uptime']
- elif 'uptime' in node:
- u_raw = node['uptime']
- # pretty print uptime
- if not u_raw is None:
- uptime = int(float(u_raw))
- days, rem_d = divmod(uptime, 86400)
- hours, rem_h = divmod(rem_d, 3600)
- minutes, _ = divmod(rem_h, 60)
- if days > 0:
- info_uptime += '{0}d '.format(days)
- if hours > 0:
- info_uptime += '{0}h '.format(hours)
- info_uptime += '{0}m'.format(minutes)
- info_uptime += ' # raw: \'{0}\''.format(u_raw)
- else:
- info_uptime += '?'
- # reply to user
- bot.say('uptime(\'{0}\') = {1}'.format(info_name, info_uptime))
- @willie.module.commands('link')
- def ffpb_peerlink(bot, trigger):
- """Display MAC and link to statuspage for the given node."""
- # identify node or bail out
- target_name = trigger.group(2)
- node = ffpb_findnode_from_botparam(bot, target_name)
- if node is None:
- return
- # get node's MAC
- info_mac = node.get('mac')
- info_name = node.get('hostname')
- # get node's v6 address in the mesh (derived from MAC address)
- info_v6 = mac2ipv6(info_mac, 'fdca:ffee:ff12:132:')
- # reply to user
- bot.say('[{1}] mac {0} -> http://[{2}]/'.format(
- info_mac, info_name, info_v6))
|