Browse Source

fix issues identified by pylint

* change tabs to spaces
* fix several too long lines if readability is improved
* avoid too short variable names
* several other syntactical changes
Helge Jung 9 years ago
parent
commit
349818c3d9
6 changed files with 1049 additions and 933 deletions
  1. 586 535
      modules/ffpb.py
  2. 31 28
      modules/ffpb_fun.py
  3. 44 33
      modules/ffpb_hamburg.py
  4. 127 107
      modules/ffpb_monitoring.py
  5. 134 115
      modules/ffpb_netstatus.py
  6. 127 115
      modules/ffpb_nodeinfo.py

File diff suppressed because it is too large
+ 586 - 535
modules/ffpb.py


+ 31 - 28
modules/ffpb_fun.py

@@ -4,65 +4,68 @@ import willie
 
 import random
 
-coffee_rule='(make[_-]me[_-](a[_-])?)?coffee'
+COFFEE_RULE = '(make[_-]me[_-](a[_-])?)?coffee'
 
 def setup(bot):
-	pass
+    """Called by willie upon loading this plugin."""
+
+    pass
 
 def shutdown(bot):
-	pass
+    """Called by willie upon unloading this plugin."""
+
+    pass
 
 @willie.module.rule(r'(?i)(hi|hallo|moin|morgen|guten morgen|re)[ \t]*$')
 def ffpb_greeting(bot, trigger):
-	stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
+    stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
 
-	if stats is None:
-		print("ffpb_greeting: stats is None -> keine Antwort")
-		return
+    if stats is None:
+        print("ffpb_greeting: stats is None -> keine Antwort")
+        return
 
-	greeting = random.choice((
-		'Hi {0}, bist du einer der {2} Clients an unseren {1} Knoten?',
-		'Hey {0}, schön dich zu sehen. Gerade sind übrigens {1} Knoten mit {2} Clients online.',
-		'{1} Knoten online, {2} Clients im Netz und {0} gibt uns die Ehre - Herzlich Willkommen :)'))
-	bot.say(greeting.format(trigger.nick, stats["nodes_active"], stats["clients"]))
+    greeting = random.choice((
+        'Hi {0}, bist du einer der {2} Clients an unseren {1} Knoten?',
+        'Hey {0}, schön dich zu sehen. Gerade sind übrigens {1} Knoten mit {2} Clients online.',
+        '{1} Knoten online, {2} Clients im Netz und {0} gibt uns die Ehre - Herzlich Willkommen :)'))
+    bot.say(greeting.format(trigger.nick, stats["nodes_active"], stats["clients"]))
 
 @willie.module.rule(r'(?i)(alles )?fake[?!]?')
 def ffpb_nofake(bot, trigger):
-	msg = random.choice((
-		u'zweifelt {0}s Glaubwürdigkeit an.',
-		'glaubt nicht, dass {0} echt ist.',
-	))
-	bot.action(msg.format(trigger.nick))
+    msg = random.choice((
+        u'zweifelt {0}s Glaubwürdigkeit an.',
+        'glaubt nicht, dass {0} echt ist.',
+    ))
+    bot.action(msg.format(trigger.nick))
 
 @willie.module.commands('fake')
 def ffpb_fakecmd(bot, trigger):
-	bot.say('Public Service Announcement: {0} ist ein Fake.'.format(trigger.nick))
+    bot.say('Public Service Announcement: {0} ist ein Fake.'.format(trigger.nick))
 
 @willie.module.rule(r'(?i)!(sudo )?rm -rf (--no-preserve-root )?/')
 def ffpb_rmrf(bot, trigger):
-	bot.action("liest dann mal sehr schnell " + trigger.nick + "s Mails o.O")
+    bot.action("liest dann mal sehr schnell " + trigger.nick + "s Mails o.O")
 
-@willie.module.rule(r'(?i)!' + coffee_rule)
+@willie.module.rule(r'(?i)!' + COFFEE_RULE)
 def ffpb_kaffee(bot, trigger):
-	bot.say("Kein sudo, kein Kaffee.")
+    bot.say("Kein sudo, kein Kaffee.")
 
-@willie.module.rule(r'(?i)!sudo ' + coffee_rule)
+@willie.module.rule(r'(?i)!sudo ' + COFFEE_RULE)
 def ffpb_sudokaffee(bot, trigger):
-	bot.action("reicht " + trigger.nick + " eine dampfende, aromatisch duftende Tasse Kaffee.")
+    bot.action("reicht " + trigger.nick + " eine dampfende, aromatisch duftende Tasse Kaffee.")
 
 @willie.module.rule(r'(?i).*(teurer|besser|neuer|cooler|geiler|mehr|weniger) wie')
 def ffpb_grammarnazi_als(bot, trigger):
-	bot.say("*als")
+    bot.say("*als")
 
 @willie.module.rule(r'(?i).*(genauso|genau so) als')
 def ffpb_grammarnazi_wie(bot, trigger):
-	bot.say("*wie")
+    bot.say("*wie")
 
 @willie.module.rule(r'(?i).*als wie')
 def ffpb_grammarnazi_alswie(bot, trigger):
-	bot.action("denkt spontan an seine Deutschlehrerin")
+    bot.action("denkt spontan an seine Deutschlehrerin")
 
 @willie.module.rule(r'(?i)gi(ve |m)me the key to your heart')
 def ffpb_botkey(bot, trigger):
-	bot.reply('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJfsG/myO4y9WzJSP+ixluHFmkIMJJRsvRT8t5h4y/5A7QzovOw1GpCmWJWnZ6GKXilTxb8ycqVfDcFPB2NRkdJUjYL+v4IMriPeBigAjc6FoUZXOS3TOZVhaTlNT4XxXKOYF/Rpgscv5f0iu1SG0Tp4mb2TX04pZjbnLNBABbjn592abEuMG5bH/g9odi50S0MoU/qCH9AZvkoc8vGu+flOBrKfFi+7g2GxF/w66mMvCJfK27QFSPOiFV3CT6ZfSZM138OCdC1SOi89X9+oCEQ3LB9A+bJgyYnxqp8eVpRPui6K9sPkax71tMimRJA5Xgdvqt9HpcgtNYxKJ4gYMR ffpb-statusbot')
-
+    bot.reply('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJfsG/myO4y9WzJSP+ixluHFmkIMJJRsvRT8t5h4y/5A7QzovOw1GpCmWJWnZ6GKXilTxb8ycqVfDcFPB2NRkdJUjYL+v4IMriPeBigAjc6FoUZXOS3TOZVhaTlNT4XxXKOYF/Rpgscv5f0iu1SG0Tp4mb2TX04pZjbnLNBABbjn592abEuMG5bH/g9odi50S0MoU/qCH9AZvkoc8vGu+flOBrKfFi+7g2GxF/w66mMvCJfK27QFSPOiFV3CT6ZfSZM138OCdC1SOi89X9+oCEQ3LB9A+bJgyYnxqp8eVpRPui6K9sPkax71tMimRJA5Xgdvqt9HpcgtNYxKJ4gYMR ffpb-statusbot')

+ 44 - 33
modules/ffpb_hamburg.py

@@ -5,51 +5,62 @@ import willie
 from ffpb import ffpb_fetch_stats
 
 def setup(bot):
-	try:
-		ffpb_hamburg_fetch(bot)
-	except:
-		pass
+    """Called by willie upon loading this plugin."""
+
+    try:
+        ffpb_hamburg_fetch(bot)
+    except:
+        pass
 
 def shutdown(bot):
-	pass
+    """Called by willie upon unloading this plugin."""
+
+    pass
 
 @willie.module.interval(60)
 def ffpb_hamburg_fetch(bot):
-	ffpb_fetch_stats(bot, 'http://hamburg.freifunk.net/nodes_ffhh/nodes.json', 'ffhh_stats')
+    ffpb_fetch_stats(bot, 'http://hamburg.freifunk.net/nodes_ffhh/nodes.json', 'ffhh_stats')
 
-	if 'ffhh_rueckspiegel' in bot.memory and bot.memory['ffhh_rueckspiegel'] == True:
-		return
+    if 'ffhh_rueckspiegel' in bot.memory and bot.memory['ffhh_rueckspiegel'] == True:
+        return
 
-	stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
-	hamburg_data = bot.memory['ffhh_stats'] if 'ffhh_stats' in bot.memory else None
-	if not (stats is None or hamburg_data is None):
-		if hamburg_data['nodes_active'] < stats['nodes_active']:
-			print('HAMBURG überholt: {0}<{1}'.format(hamburg_data['nodes_active'], stats['nodes_active']))
-			bot.memory['ffhh_rueckspiegel'] = True
+    stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
+    hamburg_data = bot.memory['ffhh_stats'] if 'ffhh_stats' in bot.memory else None
+    if not (stats is None or hamburg_data is None):
+        if hamburg_data['nodes_active'] < stats['nodes_active']:
+            print('HAMBURG überholt: {0}<{1}'.format(hamburg_data['nodes_active'], stats['nodes_active']))
+            bot.memory['ffhh_rueckspiegel'] = True
 
-			action_msg = u'schaut in den Rückspiegel und erblickt HAMBURG!'
-			action_target = bot.config.ffpb.msg_target
-			if not bot.config.ffpb.msg_target_public is None: action_target = bot.config.ffpb.msg_target_public
-			bot.msg(action_target, '\x01ACTION %s\x01' % action_msg)
+            action_msg = u'schaut in den Rückspiegel und erblickt ... HAMBURG!'
+            action_target = bot.config.ffpb.msg_target
+            if not bot.config.ffpb.msg_target_public is None:
+                action_target = bot.config.ffpb.msg_target_public
+            bot.msg(action_target, '\x01ACTION %s\x01' % action_msg)
 
 @willie.module.commands('hamburg')
 def ffpb_hamburg(bot, trigger):
-	hamburg_data = bot.memory['ffhh_stats'] if 'ffhh_stats' in bot.memory else None
-	if hamburg_data is None:
-		bot.say('Hamburg, was ist schon Hamburg ... zumindest habe ich gerade keine Daten.')
-		return
-
-	if (not trigger.group(2) is None) and trigger.group(2).lower() in ['rules','rulez','ist besser','siegt','ist cool','ist die nummer 1','vor','vorne','nr. 1']:
-		bot.msg(trigger.sender, '\x01ACTION %s\x01' % 'bezweifelt das.')
-		return
+    hamburg_data = bot.memory['ffhh_stats'] if 'ffhh_stats' in bot.memory else None
+    if hamburg_data is None:
+        bot.say('Hamburg, was ist schon Hamburg ... zumindest habe ich gerade keine Daten.')
+        return
 
-	stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
-	if stats is None:
-		bot.say('Bitte später nochmal fragen :)')
-		return
+    if not trigger.group(2) is None:
+        insane_suffixes = ['rules', 'rulez', 'ist besser', 'siegt', 'ist cool', 'ist die nummer 1', 'vor', 'vorne', 'nr. 1']
+        if trigger.group(2).lower() in insane_suffixes:
+            bot.msg(trigger.sender, '\x01ACTION %s\x01' % 'bezweifelt das.')
+            return
 
-	diff_nodes = hamburg_data['nodes_active'] - stats['nodes_active']
-	diff_clients = hamburg_data['clients'] - stats['clients']
+    stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
+    if stats is None:
+        bot.say('Bitte später nochmal fragen :)')
+        return
 
-	bot.say('Hamburg: {0} Knoten (= PB{1:+g}), {2} Clients (= PB{3:+g})'.format(hamburg_data['nodes_active'], diff_nodes, hamburg_data['clients'], diff_clients))
+    diff_nodes = hamburg_data['nodes_active'] - stats['nodes_active']
+    diff_clients = hamburg_data['clients'] - stats['clients']
 
+    bot.say('Hamburg: {0} Knoten (= PB{1:+g}), {2} Clients (= PB{3:+g})'.format(
+        hamburg_data['nodes_active'],
+        diff_nodes,
+        hamburg_data['clients'],
+        diff_clients,
+    ))

+ 127 - 107
modules/ffpb_monitoring.py

@@ -5,124 +5,144 @@ import willie
 import shelve
 import time
 
-from ffpb import ffpb_ping, pretty_date
+from ffpb import ffpb_ping, playitsafe, pretty_date
 
 monitored_nodes = None
 
 def setup(bot):
-	global monitored_nodes
+    """Called by willie upon loading this plugin."""
 
-	# load list of monitored nodes and their last status from disk
-	monitored_nodes = shelve.open('nodes.monitored', writeback=True)
+    global monitored_nodes
+
+    # load list of monitored nodes and their last status from disk
+    monitored_nodes = shelve.open('nodes.monitored', writeback=True)
 
 def shutdown(bot):
-	global monitored_nodes
+    """Called by willie upon unloading this plugin."""
+
+    global monitored_nodes
 
-	# store monitored nodes
-	if not monitored_nodes is None:
-		monitored_nodes.sync()
-		monitored_nodes.close()
-		monitored_nodes = None
+    # store monitored nodes
+    if not monitored_nodes is None:
+        monitored_nodes.sync()
+        monitored_nodes.close()
+        monitored_nodes = None
 
 @willie.module.interval(3*60)
 def ffpb_monitor_ping(bot):
-	"""Ping each node currently under surveillance."""
-
-	# determine where-to to send alerts
-	notify_target = bot.config.core.owner
-	if (not bot.config.ffpb.msg_target is None):
-		notify_target = bot.config.ffpb.msg_target
-
-	# check each node under surveillance
-	for node in monitored_nodes:
-		mon = monitored_nodes[node]
-		last_status = mon['status']
-		last_check = mon['last_check']
-		last_success = mon['last_success']
-
-		current_status = ffpb_ping(bot=bot, target_name=node, reply_directly=False)
-		if current_status is None: current_status = False
-		mon['status'] = current_status
-		mon['last_check'] = time.time()
-		if current_status == True: mon['last_success'] = time.time()
-		print("Monitoring ({0}) {1} (last: {2} at {3})".format(node, current_status, last_status, time.strftime('%Y-%m-%d %H:%M', time.localtime(last_check))))
-		if last_status != current_status and (last_status or current_status):
-			if last_check is None:
-				# erster Check, keine Ausgabe
-				continue
-
-			if current_status == True:
-				bot.msg(notify_target, 'Monitoring: Knoten \'{0}\' pingt wieder (zuletzt {1})'.format(node, pretty_date(last_success) if not last_success is None else '[nie]'))
-			else:
-				bot.msg(notify_target, 'Monitoring: Knoten \'{0}\' DOWN'.format(node))
+    """Ping each node currently under surveillance."""
+
+    # determine where-to to send alerts
+    notify_target = bot.config.core.owner
+    if not bot.config.ffpb.msg_target is None:
+        notify_target = bot.config.ffpb.msg_target
+
+    # check each node under surveillance
+    for node in monitored_nodes:
+        mon = monitored_nodes[node]
+        last_status = mon['status']
+        last_check = mon['last_check']
+        last_success = mon['last_success']
+
+        current_status = ffpb_ping(bot=bot, target_name=node, reply_directly=False)
+
+        if current_status is None:
+            current_status = False
+
+        mon['status'] = current_status
+        mon['last_check'] = time.time()
+
+        if current_status == True:
+            mon['last_success'] = time.time()
+
+        print("Monitoring ({0}) {1} (last: {2} at {3})".format(
+            node,
+            current_status,
+            last_status,
+            time.strftime('%Y-%m-%d %H:%M', time.localtime(last_check))),
+        )
+        if last_status != current_status and (last_status or current_status):
+            if last_check is None:
+                # erster Check, keine Ausgabe
+                continue
+
+            if current_status == True:
+                msg = 'Monitoring: Knoten \'{0}\' pingt wieder (zuletzt {1})'
+            else:
+                msg = 'Monitoring: Knoten \'{0}\' DOWN'
+            bot.msg(notify_target, msg.format(
+                node,
+                pretty_date(last_success) if not last_success is None else '[nie]',
+            ))
 
 @willie.module.commands('monitor')
 def ffpb_monitor(bot, trigger):
-	"""Monitoring capability of the bot, try subcommands add, del, info and list."""
-
-	# command is restricted to bot admins
-	if not trigger.admin:
-		bot.say('Ich ping hier nicht für jeden durch die Weltgeschichte.')
-		return
-
-	# ensure the user gave arguments (group 2 is the concatenation of all following groups)
-	if trigger.group(2) is None or len(trigger.group(2)) == 0:
-		bot.say('Das Monitoring sagt du hast doofe Ohren.')
-		return
-
-	# read additional arguments
-	cmd = trigger.group(3)
-	node = trigger.group(4)
-	if not node is None: node = str(node)
-
-	# subcommand 'add': add a node to monitoring
-	if cmd == "add":
-		if node in monitored_nodes:
-			bot.say('Knoten \'{0}\' wird bereits gemonitored.'.format(node))
-			return
-
-		monitored_nodes[node] = {
-			'added': trigger.sender, 
-			'status': None,
-			'last_check': None,
-			'last_success': None,
-		}
-
-		bot.say('Knoten \'{0}\' wird jetzt ganz genau beobachtet.'.format(node))
-		return
-
-	# subcommand 'del': remote a node from monitoring
-	if cmd == "del":
-		if not node in monitored_nodes:
-			bot.say('Knoten \'{0}\' war gar nicht im Monitoring?!?'.format(node))
-			return
-		del monitored_nodes[node]
-		bot.say('Okidoki, \'{0}\' lasse ich jetzt links liegen.'.format(node))
-		return
-
-	# subcommand 'info': monitoring status of a node
-	if cmd == "info":
-		if node in monitored_nodes:
-			info = monitored_nodes[node]
-			bot.say('Knoten \'{0}\' wurde zuletzt {1} gepingt (Ergebnis: {2})'.format(node, pretty_date(info['last_check']) if not info['last_check'] is None else "^W noch nie", info['status']))
-		else:
-			bot.say('Knoten \'{0}\' ist nicht im Monitoring.'.format(node))
-		return
-
-	# subcommand 'list': enumerate all monitored nodes
-	if cmd == "list":
-		nodes = ""
-		for node in monitored_nodes:
-			nodes = nodes + " " + node
-		bot.say('Monitoring aktiv für:' + nodes)
-		return
-
-	# subcommand 'help': give some hints what the user can do
-	if cmd == "help":
-		bot.say('Entweder "!monitor list" oder "!monitor {add|del|info} <node>"')
-		return
-
-	# no valid subcommand given: complain
-	bot.say('Mit "' + str(cmd) + '" kann ich nix anfangen, probier doch mal "!monitor help".')
-
-
+    """
+    Monitoring capability of the bot.
+    Try subcommands add, del, info and list.
+    """
+
+    # command is restricted to bot admins
+    if not playitsafe(bot, trigger, botadmin=True):
+        return
+
+    # ensure the user gave arguments
+    if trigger.group(2) is None or len(trigger.group(2)) == 0:
+        bot.say('Das Monitoring sagt du hast doofe Ohren.')
+        return
+
+    # read additional arguments
+    cmd = trigger.group(3)
+    node = trigger.group(4)
+    if not node is None:
+        node = str(node)
+
+    # subcommand 'add': add a node to monitoring
+    if cmd == "add":
+        if node in monitored_nodes:
+            bot.say('Knoten \'{0}\' wird bereits gemonitored.'.format(node))
+            return
+
+        monitored_nodes[node] = {
+            'added': trigger.sender,
+            'status': None,
+            'last_check': None,
+            'last_success': None,
+        }
+
+        bot.say('Knoten \'{0}\' wird jetzt ganz genau beobachtet.'.format(node))
+        return
+
+    # subcommand 'del': remote a node from monitoring
+    if cmd == "del":
+        if not node in monitored_nodes:
+            bot.say('Knoten \'{0}\' war gar nicht im Monitoring?!?'.format(node))
+            return
+        del monitored_nodes[node]
+        bot.say('Okidoki, \'{0}\' lasse ich jetzt links liegen.'.format(node))
+        return
+
+    # subcommand 'info': monitoring status of a node
+    if cmd == "info":
+        if node in monitored_nodes:
+            info = monitored_nodes[node]
+            bot.say('Knoten \'{0}\' wurde zuletzt {1} gepingt (Ergebnis: {2})'.format(node, pretty_date(info['last_check']) if not info['last_check'] is None else "^W noch nie", info['status']))
+        else:
+            bot.say('Knoten \'{0}\' ist nicht im Monitoring.'.format(node))
+        return
+
+    # subcommand 'list': enumerate all monitored nodes
+    if cmd == "list":
+        nodes = ""
+        for node in monitored_nodes:
+            nodes = nodes + " " + node
+        bot.say('Monitoring aktiv für:' + nodes)
+        return
+
+    # subcommand 'help': give some hints what the user can do
+    if cmd == "help":
+        bot.say('Entweder "!monitor list" oder "!monitor {add|del|info} <node>"')
+        return
+
+    # no valid subcommand given: complain
+    bot.say('Mit "' + str(cmd) + '" kann ich nix anfangen, probier doch mal "!monitor help".')

+ 134 - 115
modules/ffpb_netstatus.py

@@ -12,141 +12,160 @@ from ffpb import ffpb_fetch_stats, get_alfred_data, pretty_date
 highscores = None
 
 def setup(bot):
-	global highscores
+    """Called by willie upon loading this plugin."""
 
-	# load highscores from disk
-	highscores = shelve.open('highscoredata', writeback=True)
-	if not 'nodes' in highscores:
-		highscores['nodes'] = 0
-		highscores['nodes_ts'] = time.time()
-	if not 'clients' in highscores:
-		highscores['clients'] = 0
-		highscores['clients_ts'] = time.time()
+    global highscores
+
+    # load highscores from disk
+    highscores = shelve.open('highscoredata', writeback=True)
+    if not 'nodes' in highscores:
+        highscores['nodes'] = 0
+        highscores['nodes_ts'] = time.time()
+    if not 'clients' in highscores:
+        highscores['clients'] = 0
+        highscores['clients_ts'] = time.time()
 
 def shutdown(bot):
-	global highscores
+    """Called by willie upon loading this plugin."""
+
+    global highscores
 
-	# store highscores
-	if not highscores is None:
-		highscores.sync()
-		highscores.close()
-		highscores = None
+    # store highscores
+    if not highscores is None:
+        highscores.sync()
+        highscores.close()
+        highscores = None
 
 @willie.module.interval(15)
 def ffpb_get_stats(bot):
-	"""Fetch current statistics, if the highscore changes signal this."""
-
-	(nodes_active, nodes_total, clients_count) = ffpb_fetch_stats(bot, 'http://map.paderborn.freifunk.net/nodes.json', 'ffpb_stats')
-
-	highscore_changed = False
-	if nodes_active > highscores['nodes']:
-		highscores['nodes'] = nodes_active
-		highscores['nodes_ts'] = time.time()
-		highscore_changed = True
-
-	if clients_count > highscores['clients']:
-		highscores['clients'] = clients_count
-		highscores['clients_ts'] = time.time()
-		highscore_changed = True
-
-	if highscore_changed:
-		print('HIGHSCORE changed: {0} nodes ({1}), {2} clients ({3})'.format(highscores['nodes'], highscores['nodes_ts'], highscores['clients'], highscores['clients_ts']))
-		if not (bot.config.ffpb.msg_target is None):
-			action_msg = 'notiert sich den neuen Highscore: {0} Knoten ({1}), {2} Clients ({3})'.format(highscores['nodes'], pretty_date(int(highscores['nodes_ts'])), highscores['clients'], pretty_date(int(highscores['clients_ts'])))
-			action_target = bot.config.ffpb.msg_target
-			if (not bot.config.ffpb.msg_target_public is None):
-				action_target = bot.config.ffpb.msg_target_public
-			bot.msg(action_target, '\x01ACTION %s\x01' % action_msg)
+    """Fetch current statistics, if the highscore changes signal this."""
+
+    (nodes_active, nodes_total, clients_count) = \
+        ffpb_fetch_stats(bot, 'http://map.paderborn.freifunk.net/nodes.json', 'ffpb_stats')
+
+    highscore_changed = False
+    if nodes_active > highscores['nodes']:
+        highscores['nodes'] = nodes_active
+        highscores['nodes_ts'] = time.time()
+        highscore_changed = True
+
+    if clients_count > highscores['clients']:
+        highscores['clients'] = clients_count
+        highscores['clients_ts'] = time.time()
+        highscore_changed = True
+
+    if highscore_changed:
+        print('HIGHSCORE changed: {0} nodes ({1}), {2} clients ({3})'.format(
+            highscores['nodes'],
+            highscores['nodes_ts'],
+            highscores['clients'],
+            highscores['clients_ts'],
+        ))
+        if not bot.config.ffpb.msg_target is None:
+            action_msg = 'notiert sich den neuen Highscore: {0} Knoten ({1}), {2} Clients ({3})'
+
+            action_target = bot.config.ffpb.msg_target
+            if not bot.config.ffpb.msg_target_public is None:
+                action_target = bot.config.ffpb.msg_target_public
+
+            bot.msg(action_target, '\x01ACTION %s\x01' % action_msg.format(
+                highscores['nodes'], pretty_date(int(highscores['nodes_ts'])),
+                highscores['clients'], pretty_date(int(highscores['clients_ts'])),
+            ))
 
 @willie.module.commands('status')
 def ffpb_status(bot, trigger):
-	"""State of the network: count of nodes + clients"""
+    """State of the network: count of nodes + clients"""
 
-	stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
-	if stats is None:
-		bot.say('Uff, kein Plan wo der Zettel ist. Fragst du später nochmal?')
-		return
+    stats = bot.memory['ffpb_stats'] if 'ffpb_stats' in bot.memory else None
+    if stats is None:
+        bot.say('Uff, kein Plan wo der Zettel ist. Fragst du später nochmal?')
+        return
 
-	bot.say('Es sind {0} Knoten und ca. {1} Clients online.'.format(stats["nodes_active"], stats["clients"]))
+    bot.say('Es sind {0} Knoten und ca. {1} Clients online.'.format(stats["nodes_active"], stats["clients"]))
 
 @willie.module.commands('highscore')
 def ffpb_highscore(bot, trigger):
-	bot.say('Highscore: {0} Knoten ({1}), {2} Clients ({3})'.format(
-		highscores['nodes'], pretty_date(int(highscores['nodes_ts'])),
-		highscores['clients'], pretty_date(int(highscores['clients_ts']))))
+    """Print current highscores (nodes + clients)."""
+
+    bot.say('Highscore: {0} Knoten ({1}), {2} Clients ({3})'.format(
+        highscores['nodes'], pretty_date(int(highscores['nodes_ts'])),
+        highscores['clients'], pretty_date(int(highscores['clients_ts']))))
 
 @willie.module.commands('rollout-status')
 def ffpb_rolloutstatus(bot, trigger):
-	"""Display statistic on how many nodes have installed the given firmware version."""
-
-	# initialize results dictionary
-	result = { }
-	skipped = 0
-
-	# inform users about changed command parameters
-	if not trigger.group(2) is None:
-		bot.reply('Dieses Kommando nimmt keinen Parameter mehr an.')
-		return
-
-	# get ALFRED data (and ensure it is current)
-	alfred_data = get_alfred_data(bot, True)
-	if alfred_data is None:
-		bot.say('Ich habe irgendein Memo verpasst, sorry - bitte später nochmal fragen.')
-		return
-
-	# check each node in ALFRED data
-	for nodeid in alfred_data:
-		item = alfred_data[nodeid]
-		if (not 'software' in item) or (not 'firmware' in item['software']) or (not 'autoupdater' in item['software']):
-			skipped+=1
-			continue
-
-		release = item['software']['firmware']['release']
-		branch = item['software']['autoupdater']['branch']
-		enabled = item['software']['autoupdater']['enabled']
-		if not release in result or result[release] is None:
-			result[release] = { 'stable': None, 'testing': None }
-		if not branch in result[release] or result[release][branch] is None:
-			result[release][branch] = { 'auto': 0, 'manual': 0, 'total': 0 }
-
-		result[release][branch]['total'] += 1
-		mode = 'auto' if enabled else 'manual'
-		result[release][branch][mode] += 1
-
-	# respond to user
-	releases = sorted([x for x in result])
-	for release in releases:
-		output = 'Rollout von \'{0}\':'.format(release)
-		branches = sorted([x for x in result[release]])
-		first = True
-		for branch in branches:
-			item = result[release][branch]
-			if item is None: continue
-
-			if not first:
-				output += ','
-			first = False
-
-			total = item['total']
-			auto_count = item['auto']
-			manual_count = item['manual']
-
-			output += ' {2} {0}'.format(branch, total, auto_count, manual_count)
-			if manual_count > 0:
-				output += ' (+{3} manuell)'.format(branch, total, auto_count, manual_count)
-
-		bot.say(output)
-
-	# output count of nodes for which the autoupdater's branch and/or 
-	# firmware version could not be retrieved
-	if skipped > 0:
-		bot.say('plus {0} Knoten deren Status gerade nicht abfragbar war'.format(skipped))
+    """Display statistic on how many nodes have installed the given firmware version."""
+
+    # initialize results dictionary
+    result = {}
+    skipped = 0
+
+    # inform users about changed command parameters
+    if not trigger.group(2) is None:
+        bot.reply('Dieses Kommando nimmt keinen Parameter mehr an.')
+        return
+
+    # get ALFRED data (and ensure it is current)
+    alfred_data = get_alfred_data(bot, True)
+    if alfred_data is None:
+        bot.say('Ich habe irgendein Memo verpasst, sorry - bitte später nochmal fragen.')
+        return
+
+    # check each node in ALFRED data
+    for nodeid in alfred_data:
+        item = alfred_data[nodeid]
+        if (not 'software' in item) or (not 'firmware' in item['software']) or (not 'autoupdater' in item['software']):
+            skipped += 1
+            continue
+
+        release = item['software']['firmware']['release']
+        branch = item['software']['autoupdater']['branch']
+        enabled = item['software']['autoupdater']['enabled']
+        if not release in result or result[release] is None:
+            result[release] = {'stable': None, 'testing': None,}
+        if not branch in result[release] or result[release][branch] is None:
+            result[release][branch] = {'auto': 0, 'manual': 0, 'total': 0,}
+
+        result[release][branch]['total'] += 1
+        mode = 'auto' if enabled else 'manual'
+        result[release][branch][mode] += 1
+
+    # respond to user
+    releases = sorted([x for x in result])
+    for release in releases:
+        output = 'Rollout von \'{0}\':'.format(release)
+        branches = sorted([x for x in result[release]])
+        first = True
+        for branch in branches:
+            item = result[release][branch]
+            if item is None:
+                continue
+
+            if not first:
+                output += ','
+            first = False
+
+            total = item['total']
+            auto_count = item['auto']
+            manual_count = item['manual']
+
+            output += ' {2} {0}'.format(branch, total, auto_count, manual_count)
+            if manual_count > 0:
+                output += ' (+{3} manuell)'.format(branch, total, auto_count, manual_count)
+
+        bot.say(output)
+
+    # output count of nodes for which the autoupdater's branch and/or
+    # firmware version could not be retrieved
+    if skipped > 0:
+        bot.say('plus {0} Knoten deren Status gerade nicht abfragbar war'.format(skipped))
 
 @willie.module.commands('providers')
 def ffpb_providers(bot, trigger):
-	"""Fetch the top 5 providers from BATCAVE."""
+    """Fetch the top 5 providers from BATCAVE."""
 
-	providers = json.load(urllib2.urlopen('http://[fdca:ffee:ff12:a255::253]:8888/providers?format=json'))
-	providers.sort(key=lambda x: x['count'], reverse=True)
-	bot.say('Unsere Top 5 Provider: ' + ', '.join(['{0} ({1:.0f}%)'.format(x['name'], x['percentage']) for x in providers[:5]]))
+    providers = json.load(urllib2.urlopen('http://[fdca:ffee:ff12:a255::253]:8888/providers?format=json'))
+    providers.sort(key=lambda x: x['count'], reverse=True)
 
+    top5 = ['{0} ({1:.0f}%)'.format(x['name'], x['percentage']) for x in providers[:5]]
+    bot.say('Unsere Top 5 Provider: ' + ', '.join(top5))

+ 127 - 115
modules/ffpb_nodeinfo.py

@@ -5,139 +5,151 @@ import willie
 from ffpb import ffpb_findnode_from_botparam, ffpb_get_batcave_nodefield, mac2ipv6, playitsafe
 
 def setup(bot):
-	pass
+    """Called by willie upon loading this plugin."""
+
+    pass
 
 def shutdown(bot):
-	pass
+    """Called by willie upon unloading this plugin."""
+
+    pass
 
 @willie.module.commands('alfred-data')
 def ffpb_peerdata(bot, trigger):
-	"""Show ALFRED data of the given node."""
+    """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
+    # 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
+    # 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:
-		if key in [ 'hostname' ]: continue
-		bot.say("{0}.{1} = {2}".format(node['hostname'], key, str(node[key])))
+    # 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['hostname'], 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
-
-	# read node information
-	info_mac = node['network']['mac'] if 'network' in node and 'mac' in node['network'] else '??:??:??:??:??:??'
-	info_id = node['node_id'] if 'node_id' in node else info_mac.replace(':','')
-	info_name = node['hostname'] if 'hostname' in node else '?-' + info_id
-
-	info_hw = ""
-	if "hardware" in node:
-		if "model" in node["hardware"]:
-			model = node["hardware"]["model"]
-			info_hw = " model='" + model + "'"
-
-	info_fw = ""
-	info_update = ""
-	if "software" in node:
-		if "firmware" in node["software"]:
-			fwinfo = str(node["software"]["firmware"]["release"]) if "release" in node["software"]["firmware"] else "unknown"
-			info_fw = " firmware=" + fwinfo
-
-		if "autoupdater" in node["software"]:
-			autoupdater = node["software"]["autoupdater"]["branch"] if node["software"]["autoupdater"]["enabled"] else "off"
-			info_update = " (autoupdater="+autoupdater+")"
-
-	info_uptime = ""
-	u = -1
-	if "statistics" in node and "uptime" in node["statistics"]:
-		u = int(float(node["statistics"]["uptime"]))
-	elif 'uptime' in node:
-		u = int(float(node['uptime']))
-
-	if u > 0:
-		d, r1 = divmod(u, 86400)
-		h, r2 = divmod(r1, 3600)
-		m, s = divmod(r2, 60)
-		if d > 0:
-			info_uptime = ' up {0}d {1}h'.format(d,h)
-		elif h > 0:
-			info_uptime = ' up {0}h {1}m'.format(h,m)
-		else:
-			info_uptime = ' up {0}m'.format(m)
-
-	info_clients = ""
-	clientcount = ffpb_get_batcave_nodefield(info_id, 'clientcount')
-	if not clientcount is None:
-		clientcount = int(clientcount)
-		info_clients = ' clients={0}'.format(clientcount)
-
-	bot.say('[{1}]{2}{3}{4}{5}{6}'.format(info_mac, info_name, info_hw, info_fw, info_update, info_uptime, info_clients))
+    """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
+
+    # read node information
+    info_mac = node['network']['mac'] if 'network' in node and 'mac' in node['network'] else '??:??:??:??:??:??'
+    info_id = node['node_id'] if 'node_id' in node else info_mac.replace(':', '')
+    info_name = node['hostname'] if 'hostname' in node else '?-' + info_id
+
+    info_hw = ""
+    if "hardware" in node:
+        if "model" in node["hardware"]:
+            model = node["hardware"]["model"]
+            info_hw = " model='" + model + "'"
+
+    info_fw = ""
+    info_update = ""
+    if "software" in node:
+        if "firmware" in node["software"]:
+            if "release" in node["software"]["firmware"]:
+                info_fw = " firmware=" + str(node["software"]["firmware"]["release"])
+            else:
+                info_fw = " unknown firmware"
+
+        if "autoupdater" in node["software"]:
+            autoupdater = node["software"]["autoupdater"]["branch"] if node["software"]["autoupdater"]["enabled"] else "off"
+            info_update = " (autoupdater="+autoupdater+")"
+
+    info_uptime = ""
+    uptime = -1
+    if "statistics" in node and "uptime" in node["statistics"]:
+        uptime = int(float(node["statistics"]["uptime"]))
+    elif 'uptime' in node:
+        uptime = int(float(node['uptime']))
+
+    if uptime > 0:
+        days, rem_d = divmod(uptime, 86400)
+        hours, rem_h = divmod(rem_d, 3600)
+        minutes, _ = divmod(rem_h, 60)
+        if days > 0:
+            info_uptime = ' up {0}d {1}h'.format(days, hours)
+        elif hours > 0:
+            info_uptime = ' up {0}h {1}m'.format(hours, minutes)
+        else:
+            info_uptime = ' up {0}m'.format(minutes)
+
+    info_clients = ""
+    clientcount = ffpb_get_batcave_nodefield(info_id, 'clientcount')
+    if not clientcount is None:
+        clientcount = int(clientcount)
+        info_clients = ' clients={0}'.format(clientcount)
+
+    bot.say('[{1}]{2}{3}{4}{5}{6}'.format(info_mac, info_name, info_hw, info_fw, info_update, info_uptime, info_clients))
 
 @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:
-		u = int(float(u_raw))
-		d, r1 = divmod(u, 86400)
-		h, r2 = divmod(r1, 3600)
-		m, s = divmod(r2, 60)
-		if d > 0:
-			info_uptime += '{0}d '.format(d)
-		if h > 0:
-			info_uptime += '{0}h '.format(h)
-		info_uptime += '{0}m'.format(m)
-		info_uptime += ' # raw: \'{0}\''.format(u_raw)
-	else:
-		info_uptime += '?'
-
-	# reply to user
-	bot.say('uptime(\'{0}\') = {1}'.format(info_name, info_uptime))
+    """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
+    """Display MAC and link to statuspage for the given node."""
 
-	# get node's MAC
-	info_mac = node["network"]["mac"]
-	info_name = node["hostname"]
+    # 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 v6 address in the mesh (derived from MAC address)
-	info_v6 = mac2ipv6(info_mac, 'fdca:ffee:ff12:132:')
+    # get node's MAC
+    info_mac = node["network"]["mac"]
+    info_name = node["hostname"]
 
-	# reply to user
-	bot.say('[{1}] mac {0} -> http://[{2}]/'.format(info_mac, info_name, info_v6))
+    # 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))

Some files were not shown because too many files changed in this diff