Difference between revisions of "IRC ACKspace-statusbot"

From Hackerspace ACKspace
Jump to: navigation, search
(Created page with "{{Project |State=Completed |Members=StefandeVries |Description=Een IRC-bot die op commando de status van de space aangeeft. }} ACKbot zit in ons IRC-kanaal #ackspace op irc.free...")
 
m (Changing history: Freenode never existed..)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Project
 
{{Project
 +
|Featured=No
 
|State=Completed
 
|State=Completed
|Members=StefandeVries
+
|Members=StefandeVries,xopr
|Description=Een IRC-bot die op commando de status van de space  aangeeft.
+
|Description=An IRC-bot that provides SpaceAPI (and other) information upon request
 +
|GitHub=ACKbot
 +
|Picture=ACKbot.png
 
}}
 
}}
ACKbot zit in ons IRC-kanaal #ackspace op irc.freenode.org. Met het commando !status geeft het aan of de space gesloten of geopend is. De broncode (Python):<br>
+
=== synopsis ===
<pre># -*- coding: utf-8 -*-
+
ACKbot is on {{#show: Hackerspace_ACKspace:Communication | ?IRC }} for a while now. The following commands are implemented:
 +
*'''!help''':  displays the text you're looking at
 +
*'''!about''':  Shows about information
 +
*'''!status''' (or '''!state'''):  displays spaceAPI space state
 +
*'''!temp''':  displays spaceAPI temperature sensor info
 +
*'''!locate''':  find the whereabouts of the beacon
 +
*'''!wiki''':  displays last edit and newest wiki page info
 +
*'''!github''':  displays last github activity
 +
 
 +
=== update september 2016 ===
 +
The new ACKbot (written for nodejs) is running for a while now and recently, its source has been put online.
 +
 
 +
=== software ===
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-ACKbot_v12_py">
 +
==== ACKbot_v1.2.py ====
 +
Inmiddels is de bot een tijdje offline geweest en heeft [[User:Xopr|xopr]] proberen nieuw leven in de bot te blazen. Samen met de code van de [[mobile Spacestate Indicator]] om de JSON te parsen, en de vernieude [[SpaceAPI]] zijn temperatuursensors toegevoegd en is het makkelijker om de bot uit te breiden met nieuwe commando's.
 +
 
 +
De ge&uuml;pdate versie van [[User:Xopr|xopr]].
 +
Deze kan ook naar priv&eacute;berichten luisteren ('''/msg''')
 +
De commando's zijn:
 +
:'''!status''' of '''!state''': laat de status van de space zien en het tijdstip waarom deze gewijzigd is
 +
:'''!temp''': laat de laatst gemeten temperaturen zien en wanneer deze gemeten zijn
 +
:'''!help''': geeft een kort overzicht van de commando's
 +
 
 +
<div class="mw-customtoggle-ACKbot_v12_py mw-code">Click here to view the source code</div>
 +
<pre class="mw-collapsible-content">
 +
#!/usr/bin/python3
 +
# -*- coding: utf-8 -*-
 +
#      ACKbot.py
 +
#
 +
#      Copyright 2013 Stefan de Vries <stefandevries1994@gmail.com>
 +
#                2015 xopr <xopr@ackspace.nl>
 +
#                      fixed for python3 URI,urlib
 +
#                      restructured code, using JSON and added !temp command
 +
#
 +
#      This program is free software; you can redistribute it and/or modify
 +
#      it under the terms of the GNU General Public License as published by
 +
#      the Free Software Foundation; either version 2 of the License, or
 +
#      (at your option) any later version.
 +
#
 +
#      This program is distributed in the hope that it will be useful,
 +
#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 +
#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +
#      GNU General Public License for more details.
 +
#
 +
#      You should have received a copy of the GNU General Public License
 +
#      along with this program; if not, write to the Free Software
 +
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 +
#      MA 02110-1301, USA.
 +
#
 +
 
 +
import socket
 +
import urllib.request
 +
import json
 +
import time
 +
 
 +
def fetch_space_api():
 +
    with urllib.request.urlopen('https://ackspace.nl/spaceAPI/') as response:
 +
        spaceapi_json = json.loads(response.read().decode('utf8'))
 +
    return spaceapi_json
 +
 
 +
def space_open():
 +
    print( "Space state called for." )
 +
 
 +
    spaceapi_json = fetch_space_api()
 +
 
 +
    print( spaceapi_json )
 +
 
 +
    state = "probleem met uitlezen"
 +
 
 +
    if spaceapi_json is None:
 +
        return state,-1
 +
 
 +
    #if spaceapi_json['state']['open'] is None:
 +
    #    state = "onbekend"
 +
    #elif spaceapi_json['state']['open']:
 +
    #    state = "open"
 +
    #else:
 +
    #    state = "gesloten"
 +
    #return state,spaceapi_json['state']['lastchange']
 +
    return spaceapi_json['state']['message'],spaceapi_json['state']['lastchange']
 +
 
 +
def space_temp():
 +
    print( "Space temp called for." )
 +
 
 +
    spaceapi_json = fetch_space_api()
 +
 
 +
    print( spaceapi_json )
 +
 
 +
    state = "probleem met uitlezen"
 +
 
 +
    if spaceapi_json is None:
 +
        return state,-1
 +
 
 +
    return spaceapi_json['sensors']['temperature']
 +
 
 +
class IRC:
 +
    def __init__(self, host="irc.libera.chat", port=6667, nick="ACKbot", ident="ACKbot", realname="ACKbot"):
 +
        self.conn = socket.socket()
 +
        self.chan = "#ACKspace"
 +
        self.conn.settimeout(300.0)
 +
        self.conn.connect((host, port))
 +
        self.conn.send(bytes("NICK %s\r\n" % nick,'utf-8'))
 +
        self.conn.send(bytes("USER %s %s bla :%s\r\n" % (ident, host, realname),'utf-8'))
 +
        self.conn.send(bytes("JOIN :%s\r\n:" % self.chan,'utf-8'))
 +
 
 +
    def mainLoop(self):
 +
        readbuffer = ""
 +
        while 1:
 +
            try:
 +
                readbuffer = readbuffer + str(self.conn.recv(1024),'utf-8')
 +
 
 +
                message = readbuffer.split("\n")
 +
                readbuffer = message.pop()
 +
                for line in message:
 +
                    line = line.rstrip()
 +
                    line = line.split()
 +
                    print( line )
 +
                    if line[0] == "PING":
 +
                        self.conn.send(bytes("PONG %s\r\n" % line[1],'utf-8'))
 +
                    elif len(line) >= 4:
 +
                        target = self.chan
 +
                        if line[2].lower() != target.lower():
 +
                            target = line[0].split("!")[0][1:]
 +
 
 +
                        command = line[3].split("!")
 +
                        if len( command ) == 1:
 +
                            break
 +
 
 +
                        command = command[1]
 +
                        if command == "status" or command == "state":
 +
                            state, lastchange = space_open()
 +
                            # note: time.gmtime is without timezone, time.localtime() is with
 +
                            self.conn.send(bytes(" PRIVMSG %s :%s since %s\r\n" % (target, state, time.strftime('%m/%d/%Y %H:%M:%S', time.gmtime(lastchange))), 'utf-8' ))
 +
                        elif command == "temp":
 +
                            temperatures = space_temp()
 +
                            for temp in temperatures:
 +
                                # note: time.gmtime is without timezone, time.localtime() is with
 +
                                self.conn.send(bytes(" PRIVMSG %s :%s value is %s\N{DEGREE SIGN}C at %s\r\n" % (target, temp["description"], temp["value"], time.strftime('%m/%d/%Y %H:%M:%S', time.gmtime(temp["ext_lastchange"]))), 'utf-8' ))
 +
                        elif command == "help":
 +
                            self.conn.send(bytes(" PRIVMSG %s :ACKbot voor !status en !temp\r\n" % (target), 'utf-8' ))
 +
 
 +
                        print( "Sent response." )
 +
 
 +
            except socket.timeout:
 +
                raise Exception('Socket timeout!')
 +
 
 +
 
 +
if __name__ == '__main__':
 +
    instance = IRC()
 +
    instance.mainLoop()
 +
</pre>
 +
</div>
 +
 
 +
 
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-ACKbot_v10_py">
 +
==== ACKbot_v1.0.py ====
 +
De originele broncode van Stefan (in Python):
 +
<div class="mw-customtoggle-ACKbot_v10_py mw-code">Click here to view the source code</div>
 +
<pre class="mw-collapsible-content">
 +
# -*- coding: utf-8 -*-
 
#      ACKbot.py
 
#      ACKbot.py
 
#       
 
#       
Line 39: Line 202:
  
 
class IRC:
 
class IRC:
def __init__(self, host="irc.freenode.org", port=6667, nick="ACKbot", ident="ACKbot", realname="ACKbot"):
+
def __init__(self, host="irc.libera.chat", port=6667, nick="ACKbot", ident="ACKbot", realname="ACKbot"):
 
self.conn = socket.socket()
 
self.conn = socket.socket()
 
self.conn.settimeout(300.0)
 
self.conn.settimeout(300.0)
try:
+
self.conn.connect((host, port))
self.conn.connect((host, port))
 
except socket.gaierror:
 
raise ConnError()
 
 
self.conn.send("NICK %s\r\n" % nick)
 
self.conn.send("NICK %s\r\n" % nick)
 
self.conn.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
 
self.conn.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
Line 76: Line 236:
  
 
if __name__ == '__main__':
 
if __name__ == '__main__':
instance = False
+
instance = IRC()
while instance == False:
 
instance = IRC()
 
 
instance.mainLoop()
 
instance.mainLoop()
 
 
 
</pre>
 
</pre>
Op dit moment draait het op de VPS van StefandeVries. Wellicht kan in de toekomst gezocht worden naar eigen hosting.<br>
+
</div>
 +
<s>Op dit moment draait het op de VPS van StefandeVries. Wellicht kan in de toekomst gezocht worden naar eigen hosting.</s>

Latest revision as of 07:51, 29 June 2021

Project: IRC ACKspace-statusbot
Featured: No
State Completed
Members StefandeVries, xopr
GitHub ACKbot
Description An IRC-bot that provides SpaceAPI (and other) information upon request
Picture
ACKbot.png

synopsis

ACKbot is on ircs://irc.libera.chat:6697/ACKspace for a while now. The following commands are implemented:

  • !help: displays the text you're looking at
  • !about: Shows about information
  • !status (or !state): displays spaceAPI space state
  • !temp: displays spaceAPI temperature sensor info
  • !locate: find the whereabouts of the beacon
  • !wiki: displays last edit and newest wiki page info
  • !github: displays last github activity

update september 2016

The new ACKbot (written for nodejs) is running for a while now and recently, its source has been put online.

software

ACKbot_v1.2.py

Inmiddels is de bot een tijdje offline geweest en heeft xopr proberen nieuw leven in de bot te blazen. Samen met de code van de mobile Spacestate Indicator om de JSON te parsen, en de vernieude SpaceAPI zijn temperatuursensors toegevoegd en is het makkelijker om de bot uit te breiden met nieuwe commando's.

De geüpdate versie van xopr. Deze kan ook naar privéberichten luisteren (/msg) De commando's zijn:

!status of !state: laat de status van de space zien en het tijdstip waarom deze gewijzigd is
!temp: laat de laatst gemeten temperaturen zien en wanneer deze gemeten zijn
!help: geeft een kort overzicht van de commando's
Click here to view the source code
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#       ACKbot.py
#
#       Copyright 2013 Stefan de Vries <stefandevries1994@gmail.com>
#                 2015 xopr <xopr@ackspace.nl>
#                      fixed for python3 URI,urlib
#                      restructured code, using JSON and added !temp command
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
#

import socket
import urllib.request
import json
import time

def fetch_space_api():
    with urllib.request.urlopen('https://ackspace.nl/spaceAPI/') as response:
        spaceapi_json = json.loads(response.read().decode('utf8'))
    return spaceapi_json

def space_open():
    print( "Space state called for." )

    spaceapi_json = fetch_space_api()

    print( spaceapi_json )

    state = "probleem met uitlezen"

    if spaceapi_json is None:
        return state,-1

    #if spaceapi_json['state']['open'] is None:
    #    state = "onbekend"
    #elif spaceapi_json['state']['open']:
    #    state = "open"
    #else:
    #    state = "gesloten"
    #return state,spaceapi_json['state']['lastchange']
    return spaceapi_json['state']['message'],spaceapi_json['state']['lastchange']

def space_temp():
    print( "Space temp called for." )

    spaceapi_json = fetch_space_api()

    print( spaceapi_json )

    state = "probleem met uitlezen"

    if spaceapi_json is None:
        return state,-1

    return spaceapi_json['sensors']['temperature']

class IRC:
    def __init__(self, host="irc.libera.chat", port=6667, nick="ACKbot", ident="ACKbot", realname="ACKbot"):
        self.conn = socket.socket()
        self.chan = "#ACKspace"
        self.conn.settimeout(300.0)
        self.conn.connect((host, port))
        self.conn.send(bytes("NICK %s\r\n" % nick,'utf-8'))
        self.conn.send(bytes("USER %s %s bla :%s\r\n" % (ident, host, realname),'utf-8'))
        self.conn.send(bytes("JOIN :%s\r\n:" % self.chan,'utf-8'))

    def mainLoop(self):
        readbuffer = ""
        while 1:
            try:
                readbuffer = readbuffer + str(self.conn.recv(1024),'utf-8')

                message = readbuffer.split("\n")
                readbuffer = message.pop()
                for line in message:
                    line = line.rstrip()
                    line = line.split()
                    print( line )
                    if line[0] == "PING":
                        self.conn.send(bytes("PONG %s\r\n" % line[1],'utf-8'))
                    elif len(line) >= 4:
                        target = self.chan
                        if line[2].lower() != target.lower():
                            target = line[0].split("!")[0][1:]

                        command = line[3].split("!")
                        if len( command ) == 1:
                            break

                        command = command[1]
                        if command == "status" or command == "state":
                            state, lastchange = space_open()
                            # note: time.gmtime is without timezone, time.localtime() is with
                            self.conn.send(bytes(" PRIVMSG %s :%s since %s\r\n" % (target, state, time.strftime('%m/%d/%Y %H:%M:%S', time.gmtime(lastchange))), 'utf-8' ))
                        elif command == "temp":
                            temperatures = space_temp()
                            for temp in temperatures:
                                # note: time.gmtime is without timezone, time.localtime() is with
                                self.conn.send(bytes(" PRIVMSG %s :%s value is %s\N{DEGREE SIGN}C at %s\r\n" % (target, temp["description"], temp["value"], time.strftime('%m/%d/%Y %H:%M:%S', time.gmtime(temp["ext_lastchange"]))), 'utf-8' ))
                        elif command == "help":
                            self.conn.send(bytes(" PRIVMSG %s :ACKbot voor !status en !temp\r\n" % (target), 'utf-8' ))

                        print( "Sent response." )

            except socket.timeout:
                raise Exception('Socket timeout!')


if __name__ == '__main__':
    instance = IRC()
    instance.mainLoop()


ACKbot_v1.0.py

De originele broncode van Stefan (in Python):

Click here to view the source code
# -*- coding: utf-8 -*-
#       ACKbot.py
#       
#       Copyright 2013 Stefan de Vries <stefandevries1994@gmail.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
# 
import socket
import urllib2 

def space_open():
	print "Space state called for."
	website = urllib2.urlopen("https://ackspace.nl/spacestate.php") 
	website_html = website.read() 
	if website_html.count("Closed"):
		return 0
	else:
		return 1
			

class IRC:
	def __init__(self, host="irc.libera.chat", port=6667, nick="ACKbot", ident="ACKbot", realname="ACKbot"):		
		self.conn = socket.socket()
		self.conn.settimeout(300.0)	
		self.conn.connect((host, port))
		self.conn.send("NICK %s\r\n" % nick)
		self.conn.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
		self.conn.send("JOIN :#ackspace\r\n:")
				
	def mainLoop(self):
		readbuffer = ""
		while 1:			
			try:
				readbuffer = readbuffer + self.conn.recv(1024)
			except socket.timeout:
				raise ConnError()
				
			message = readbuffer.split("\n")
			readbuffer = message.pop()
			for line in message:
				line = line.rstrip()
				line = line.split()	
				print line
				if line[0] == "PING":
					self.conn.send("PONG %s\r\n" % line[1])
				elif len(line) == 4:
					if line[3] == ":!status":
						ret = space_open()
						if ret:
							self.conn.send("PRIVMSG #ackspace :De space is open!\r\n")
						else:
							self.conn.send("PRIVMSG #ackspace :De space is dicht.\r\n")
						print "Sent response."	

if __name__ == '__main__':
	instance = IRC()
	instance.mainLoop()	

Op dit moment draait het op de VPS van StefandeVries. Wellicht kan in de toekomst gezocht worden naar eigen hosting.