Note: I tried to not repeat the files too much so you can use the .plug file from the first example for all the other ones.
2015-10-04
Errbot recipes
Note: I tried to not repeat the files too much so you can use the .plug file from the first example for all the other ones.
2012-09-11
Quick hack to plot data on a map in python
I wanted to share a cool code mash up I did to show some stats about Err usage in the world.
The result is here, in blue roughly after a non reliable homebrew datamining from the apache logs:
I applied this tip
As dependencies you gonna need :
Here is the full snippet :
#! /usr/bin/python
import matplotlib
matplotlib.use('Qt4Agg')
from datetime import datetime
import os
DIR = 'data/'
dirList=os.listdir(DIR)
unzip = lambda l:tuple(zip(*l))
all_dates = {}
for fname in dirList:
if fname.startswith('gootz-access'):
counts = {}
d = datetime.strptime(fname.split('.')[1], '%Y-%m-%d')
with open(DIR+fname) as f:
data = f.readlines()
for line in data:
if line.find('err/version') != -1:
addr = line.split('-')[0].strip()
if counts.has_key(addr):
counts[addr] += 1
else:
counts[addr] = 1
all_dates[d] = counts
sorted_dates = sorted(all_dates.keys())
import GeoIP
gi = GeoIP.open('GeoLiteCity.dat',GeoIP.GEOIP_STANDARD)
insts_pos = {}
devs_pos = {}
for date in sorted_dates:
for ip, count in all_dates[date].iteritems():
record = gi.record_by_name(ip)
if record and record['latitude']:
lon = record['longitude']
lat = record['latitude']
toinc = devs_pos if count > 5 else insts_pos
if toinc.has_key((lon,lat)):
toinc[(lon,lat)] += 1
else:
toinc[(lon,lat)] = 1
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
# lon_0 is central longitude of robinson projection.
# resolution = 'c' means use crude resolution coastlines.
m = Basemap(projection='robin',lon_0=0,resolution='c')
#set a background colour
m.drawmapboundary(fill_color='#85A6D9')
# draw coastlines, country boundaries, fill continents.
m.fillcontinents(color='white',lake_color='#85A6D9')
m.drawcoastlines(color='#6D5F47', linewidth=.4)
m.drawcountries(color='#6D5F47', linewidth=.4)
# draw lat/lon grid lines every 30 degrees.
m.drawmeridians(np.arange(-180, 180, 30), color='#bbbbbb')
m.drawparallels(np.arange(-90, 90, 30), color='#bbbbbb')
inst_lngs = [entry[0][0] for entry in insts_pos.iteritems()]
inst_lats = [entry[0][1] for entry in insts_pos.iteritems()]
inst_count = [entry[1] for entry in insts_pos.iteritems()]
inst_x,inst_y = m(inst_lngs,inst_lats)
s_inst_count = [p * p for p in inst_count]
m.scatter(
inst_x,
inst_y,
s=s_inst_count, #size
c='blue', #color
marker='o', #symbol
alpha=0.25, #transparency
zorder = 2, #plotting order
)
for population, xpt, ypt in zip(inst_count, inst_x, inst_y):
label_txt = int(round(population, 0)) #round to 0 dp and display as integer
plt.text(
xpt,
ypt,
label_txt,
color = 'blue',
size='small',
horizontalalignment='center',
verticalalignment='center',
zorder = 3,
)
devs_lngs = [entry[0][0] for entry in devs_pos.iteritems()]
devs_lats = [entry[0][1] for entry in devs_pos.iteritems()]
devs_count = [entry[1] for entry in devs_pos.iteritems()]
devs_x,devs_y = m(devs_lngs,devs_lats)
s_devs_count = [p * p for p in devs_count]
m.scatter(
devs_x,
devs_y,
s=s_devs_count, #size
c='red', #color
marker='o', #symbol
alpha=0.25, #transparency
zorder = 4, #plotting order
)
for population, xpt, ypt in zip(devs_count, devs_x, devs_y):
label_txt = int(round(population, 0)) #round to 0 dp and display as integer
plt.text(
xpt,
ypt,
label_txt,
color = 'red',
size='small',
horizontalalignment='center',
verticalalignment='center',
zorder = 5,
)
#add a title and display the map on screen
plt.title('From where Err is used.')
plt.show()
2012-09-07
Setup a plugin development environment for Err
Err makes your life as easy as possible to extend it. Here I present you a quick walk-through to get you started.
First, clone err from git. I assume you are somewhere in your work/projects directory
. ⚫ gbin@sal work % git clone git://github.com/gbin/err.git Cloning into 'err'... remote: Counting objects: 1742, done. remote: Compressing objects: 100% (638/638), done. remote: Total 1742 (delta 1177), reused 1626 (delta 1061) Receiving objects: 100% (1742/1742), 897.87 KiB | 552 KiB/s, done. Resolving deltas: 100% (1177/1177), done. ⚫ gbin@sal work %
Cool now, just copy the config template and prepare a data directory:
. ⚫ gbin@sal work % cd err ⚫ gbin@sal err % cp errbot/config-template.py config.py ⚫ gbin@sal err % mkdir data
Then change the config to point the data directory and the log to this newly created directory in your config.py :
. BOT_LOG_FILE = './data/err.log' # or an absolute path BOT_DATA_DIR = './data/' # or an absolute path
You know what ? you can already start your bot instance in development mode :
. ⚫ gbin@sal err % ./scripts/err.py -T INFO:Config check passed... INFO:Activate internal commands INFO:Activating all the plugins... INFO:Activate plugin: Webserver INFO:Activating Webserver with min_err_version = 1.6.4 and max_version = 1.6.4 INFO:Webserver is not configured. Forbid activation INFO:Activate plugin: VersionChecker INFO:Activating VersionChecker with min_err_version = 1.6.4 and max_version = 1.6.4 INFO:Activate plugin: ChatRoom INFO:Activating ChatRoom with min_err_version = 1.6.4 and max_version = 1.6.4 INFO: INFO:Notifying connection to all the plugins... INFO:Callback_connect INFO:Plugin activation done. Talk to me >>
Note : do a ctrl-C or ctrl-D to quit
If you want to get even fancier, do a -G instead of -T (provided you have installed pyside), if not the bot will tell you how to do that.
. ⚫ gbin@sal err % ./scripts/err.py -G
So now, let's get a template of a plugin and tell err to take it into consideration
go to your work / projects directory and for example clone the helloworld project
. ⚫ gbin@sal err % cd .. ⚫ gbin@sal work % git clone git://github.com/gbin/err-helloworld.git Cloning into 'err-helloworld'... remote: Counting objects: 7, done. remote: Compressing objects: 100% (6/6), done. remote: Total 7 (delta 1), reused 7 (delta 1) Receiving objects: 100% (7/7), done. Resolving deltas: 100% (1/1), done.
go back to your err directory and change the config.py to point to this template
. BOT_EXTRA_PLUGIN_DIR = '../err-helloworld' # or an absolute path
From there you see that the plugin is loaded and works:
.
INFO:Config check passed...
INFO:Activate internal commands
INFO:Activating all the plugins...
INFO:Activate plugin: Webserver
INFO:Activating Webserver with min_err_version = 1.6.4 and max_version = 1.6.4
INFO:Webserver is not configured. Forbid activation
INFO:Activate plugin: VersionChecker
INFO:Activating VersionChecker with min_err_version = 1.6.4 and max_version = 1.6.4
INFO:Activate plugin: ChatRoom
INFO:Activating ChatRoom with min_err_version = 1.6.4 and max_version = 1.6.4
INFO:Activate plugin: HelloWorld
INFO:Activating HelloWorld with min_err_version = None and max_version = None
INFO:
INFO:Notifying connection to all the plugins...
INFO:Callback_connect
INFO:Plugin activation done.
Talk to me >>!status
INFO:received command = status matching [status] with parameters []
Yes I am alive...
With those plugins (L=Loaded, E=Error, B=Blacklisted/Unloaded), C=Needs to be configured) :
[L] ChatRoom
[L] HelloWorld
[L] VersionChecker
[C] Webserver
Load 0.07, 0.24, 0.28
GC 0->301 1->5 2->4
Talk to me >>!hello
INFO:received command = hello matching [hello] with parameters []
Hello World !
Talk to me >>!help hello
INFO:received command = help matching [help] with parameters [hello]
this command says hello
So now, you just have to rename everything to your plugin name, and get started !
For deeper information, go to the plugin development docs.
Note: You can run err.py under debugger without any problem. I personally use pycharm and it works really well. I might make another tutorial for it in the future.
Enjoy !
2012-08-25
For those who were wondering what this Err is about
So now there is a public demo accessible directly from your browser.
It is a chatroom so if somebody else is there at the same time you can discuss and experiment Err together.
Enjoy !
http://gbin.github.com/err/
Feel free to contact me if you have questions about it.
2012-06-06
Track git repos in chatrooms with err-gitbot
It allows you to follow specific heads of git repos and get notifications in your chat. This is awesome for teams that work with a chatroom and want to follow the current development progress.
Every time somebody commits to the repo for a specifiy project and branch, err will say something like that in the chat :
djmt:
Branch master:
4807cc Emile Raoul 2012-06-06T14:43:45 -- WHITELABEL-4226 improve getAccountLimits
android_client_app:
Branch master:
554d9e Jack Bougnazal 2012-06-06T14:44:12 -- Add string for mobile data
2012-05-24
Fresh new plugins for err
err-stalkerbot
A plugin that tells you when the bot saw somebody for the last time. For example : !seen bidule
err-calcbot
A smart calculator based on qalculator, Examples: !calc 5+2 !calc x²+x+1=5 !calc 5 in² = x cm²
err-dictbot
It can give you the definition/synonymous of a word. Example !define fish
err-weatherbot
It can give you the weather at the given location for the next few days. Example: !weather san francisco, CA
And now err provides a public plugins repository so in order to install a public one just install it by name :
!install err-calcbot
2012-05-21
"err" a plugin-based XMPP chatbot
It is based on the long tradition of IRC bots but for a more modern media (Jabber/XMPP).
It has been tested under openfire and hipchat, but it probably runs on any jabber service. It can be used 1on1 or with MUCs (chatrooms).
We love it and the development team uses it daily at mondial telecom with a bunch of custom plugins.
It that can download and start plugins on the fly from git repos / tar.gz urls and developing plugins is quite entertaining so feel free to send me the link to your creations !
The core is there :
https://github.com/gbin/err
A first batch of plugins examples has been published so far, more gonna come as we are cleaning them up.
https://github.com/gbin/err-codebot
https://github.com/gbin/err-elizabot
https://github.com/gbin/err-pollbot
https://github.com/gbin/err-devops_borat
Enjoy !