GNUSocialIRCBot socializando desde el IRC

Este bot esta dirigido a los IRC Lovers y a los administradores de nodos de GNUSocial, como un servidor. Ya miraré de subirlo a un github para que la gente aporte. De momento ahí van esas 150 líneas de python.

#!/bin/python
#Written by foo@gnusocial.net https://elbinario.net
#Under GNU GPL License
import sys
from sys import exit
import time
import socket
import threading
import ssl
import ConfigParser 
import json
import pycurl
from StringIO import StringIO
try:
    # python 3
    from urllib.parse import urlencode
except ImportError:
    # python 2
    from urllib import urlencode
    
    
class GNUSocialIRCBot():

    def __init__(self):
        self.cfg = ConfigParser.ConfigParser()
        self.cfg.read("gnusocialircbot.cfg") 
        self.botnick = self.cfg.get("irc", "nickname")
        self.channel = self.cfg.get("irc", "channel")
        self.owner = self.cfg.get("irc", "owner")
        self.server = self.cfg.get("irc", "ip")
        self.port = int(self.cfg.get("irc", "port"))
        self.socialname = self.cfg.get("social" , "botname")
        self.socialpass = self.cfg.get("social" , "password")
        self.socialnode = self.cfg.get("social", "node")
        self.commands = [".quit", ".join", ".part", ".say", ".social"]
        self.olds = []
        self.ircmsg = ""
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.ircsock = ssl.wrap_socket(self.s)
        self.url_status = "https://" + self.socialnode + "/api/statuses/friends.json"
        self.url_update = "https://" + self.socialnode + "/api/statuses/update.xml"           
        #init functions
        self.connect()
        self.joinchan(self.channel)
        self.sendowner("Im ready master")
        self.listen()
    
    def connect(self):
        self.ircsock.connect((self.server, self.port))
        self.ircsock.send("USER " + self.botnick + " " + self.botnick + " " + self.botnick + "  :\r\n")
        self.ircsock.send("NICK " + self.botnick + "\r\n")

    def ping(self):
        self.ircsock.send("PONG :pingis \n")
        self.news()
        
    def sendnews(self, list):
        try:
            for item in list:
                if item not in self.olds:
                    aux = '' + item['screen_name'] + "-> "
                    msg = item['status']['text']
                    aux = aux + msg
                    try:
                        self.olds.append(item)
                        self.sendmsg(aux)
                        time.sleep(1)
                    except:
                        pass
        except Exception as e:
            self.sendowner("error on send news")
            pass
                  
    def sendmsg(self, msg):
        self.ircsock.send("PRIVMSG " + self.channel + " :" + msg.encode('utf-8') + "\r\n")
        
    def sendowner(self,msg):
        self.ircsock.send("PRIVMSG " + self.owner + " :" + msg + "\r\n")
      
    def joinchan(self, chan):
        self.ircsock.send("JOIN " + chan + "\n")
        
    def social_status(self, msg):
        try:
            curl = pycurl.Curl()
            curl.setopt(pycurl.SSL_VERIFYPEER, False)
            curl.setopt(pycurl.SSL_VERIFYHOST, False)
            curl.setopt(pycurl.USERPWD, self.socialname + ":" + self.socialpass)
            curl.setopt(pycurl.POST, 1)
            post_data = {"status" : msg}
            postfields = urlencode(post_data)
            curl.setopt(pycurl.POSTFIELDS, postfields)
            curl.setopt(curl.URL, self.url_update)
            curl.perform()
            curl.close()
        except:
            self.sendowner("error on status social")   
            
    def news(self):
        try:
            buffer = StringIO()
            curl = pycurl.Curl()
            curl.setopt(pycurl.SSL_VERIFYPEER, False)
            curl.setopt(pycurl.SSL_VERIFYHOST, False)
            curl.setopt(pycurl.USERPWD, self.socialname + ":" + self.socialpass)
            curl.setopt(curl.URL, self.url_status)
            curl.setopt(pycurl.WRITEFUNCTION, buffer.write)
            curl.perform()
            curl.close()
            data = json.loads(buffer.getvalue())
            t = threading.Thread(target=self.sendnews, args=([data]))
            t.start() 
        except:
            self.sendowner("error on news")

            
    def exitchat(self):
        self.sendowner("ByezzZzzZzz master")
        self.s.close()
        self.ircsock.close()
        exit()
    
    def analize_ircmsg(self): 
        if self.ircmsg.find("PING :") != -1:
            self.ping()
        for com in self.commands:
            if self.ircmsg.find(com) != -1:
                if self.ircmsg.find(self.botnick) != -1:
                    message = self.ircmsg.split('!')
                    if message[0] == (":" + self.owner):
                        command = self.ircmsg.split(com)
                        param = command[1]
                        param = param.strip()
                        if com == ".quit":
                            self.exitchat()
                        if com == ".say":
                            self.sendmsg(param)
                        if com == ".join":
                            self.joinchan(param)
                        if com == ".social":
                            self.social_status(param)
                        
    def listen(self):
        while 1:
            self.ircmsg = self.ircsock.recv(512)
            self.ircmsg = self.ircmsg.strip('\n\r')
            self.analize_ircmsg()
            
if __name__ == "__main__":
    ircbot = GNUSocialIRCBot()

Y el archivo de config

[irc]
nickname    = social
channel     = #social 
owner       = foo
ip          = freenode.net
port        = 6697

[social]
botname     = imabot
password    = foo@gnusocial.net
node        = gnusocial.net

Subido a git lab https://gitlab.com/barfoo/GNUSocialIRCBot

10 Comments

  1. Gracias por semejante motivación a la hora de meterme de lleno en los IRC. Ahora ando metido en los canales de Freenode relacionados con Parabola, Archlinux y Debian.

  2. Genial foo +1000 los IRC lovers te lo agradecemos ;)

    Por cierto un apunte, tal vez seria necesario indicar en el post que la conf tiene que ir en un fichero llamado gnusocialircbot.cfg por el C&P ya tu sabes XDDD

  3. Hola, muy buen material. puedes mencionar los a seguir para poder utilizar en irssi, por favor.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax