home · contact · privacy
Initial commit.
[plomlombot-irc.git] / plomlombot.py
1 import socket
2 import datetime 
3 import select
4 import time
5 import re
6 import urllib.request
7 import html
8
9 servername = ""
10 timeout = 480
11 username = "plomlombot"
12 nickname = username
13 channel = "#zrolaps"
14
15 class IO:
16     def __init__(self, server, port):
17         self.socket = socket.socket()
18         self.socket.connect((server, port))
19         self.socket.setblocking(0)
20         self.line_buffer = []
21         self.rune_buffer = ""
22         self.last_pong = time.time()
23     def _pingtest(self):
24         if self.last_pong + timeout < time.time():
25             raise RuntimeError("server not answering")
26         self.send_line("PING " + nickname + " " + servername)
27     def send_line(self, msg_orig):
28         msg = msg_orig + "\r\n"
29         msg_len = len(msg)
30         total_sent_len = 0
31         while total_sent_len < msg_len:
32             sent_len = self.socket.send(bytes(msg[total_sent_len:], "UTF-8"))
33             if sent_len == 0:
34                 raise RuntimeError("socket connection broken")
35             total_sent_len += sent_len
36         print("LINE TO SERVER: "
37             + str(datetime.datetime.now()) + ": " + msg_orig)
38     def recv_line_wrapped(self):
39         if len(self.line_buffer) > 0:
40             return self.line_buffer.pop(0)
41         while True:
42             ready = select.select([self.socket], [], [], int(timeout / 2))
43             if not ready[0]:
44                 self._pingtest()
45                 return None
46             self.last_pong = time.time()
47             received_runes = self.socket.recv(1024).decode("UTF-8")
48             if len(received_runes) == 0:
49                 raise RuntimeError("socket connection broken")
50             self.rune_buffer += received_runes 
51             lines_split = str.split(self.rune_buffer, "\r\n")
52             self.line_buffer += lines_split[:-1]
53             self.rune_buffer = lines_split[-1]
54             if len(self.line_buffer) > 0:
55                 return self.line_buffer.pop(0)
56     def recv_line(self):
57         line = self.recv_line_wrapped()
58         if line:
59             print("LINE FROM SERVER " + str(datetime.datetime.now()) + ": " +
60             line)
61         return line
62
63 io = IO("irc.freenode.net", 6667)
64 io.send_line("NICK " + nickname)
65 io.send_line("USER " + username + " 0 * : ")
66 io.send_line("JOIN " + channel)
67 servername = io.recv_line().split(" ")[0][1:]
68 while 1:
69     line = io.recv_line()
70     if not line:
71         continue
72     tokens = line.split(" ")
73     if len(tokens) > 1:
74         if tokens[1] == "PRIVMSG":
75             sender = ""
76             for rune in tokens[0]:
77                 if rune == "!":
78                     break
79                 if rune != ":":
80                     sender += rune
81             receiver = ""
82             for rune in tokens[2]:
83                 if rune == "!":
84                     break
85                 if rune != ":":
86                     receiver += rune
87             target = sender
88             if receiver != nickname:
89                 target = receiver
90             msg = str.join(" ", tokens[3:])[1:]
91             matches = re.findall("(https?://[^\s]+)", msg)
92             for i in range(len(matches)):
93                 url = matches[i]
94                 webpage = urllib.request.urlopen(url)
95                 charset = webpage.info().get_content_charset()
96                 content = webpage.read().decode(charset)
97                 title = str(content).split('<title>')[1].split('</title>')[0]
98                 title = html.unescape(title)
99                 io.send_line("PRIVMSG "
100                     + target + " :page title for url: " + title)
101         if tokens[0] == "PING":
102             io.send_line("PONG " + tokens[1])