forked from Diastro/pyBot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpyBot.py
361 lines (288 loc) · 13 KB
/
pyBot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
import traceback
import sys
import socket
import string
import urllib2
import signal
import re
import ConfigParser
import os
#import psutil
import platform
import gdata.youtube # Install gdata and elementtree modules
import gdata.youtube.service
from bs4 import BeautifulSoup
from time import sleep
#
# Command definitions
#
def REDDIT(keyword):
chat = str(keyword)
url = "http://www.reddit.com"
data = urllib2.urlopen(url).read()
bs = BeautifulSoup(data)
siteTable = bs.find("div", {"id": "siteTable"})
vote = siteTable.find("div", {"class": "score unvoted"})
firstArticle = siteTable.div.find("p", {"class": "title"})
tagline = siteTable.find("p", {"class": "tagline"})
subreddit = tagline.find("a", {"class": "subreddit hover"})
s.send("PRIVMSG %s :Sujet: %s, votes: %s, %s \r\n" % (chat, firstArticle.get_text(), vote.get_text(), subreddit.get_text()))
def BI(keyword):
chat = str(keyword)
url = "http://www.businessinsider.com"
data = urllib2.urlopen(url).read()
bs = BeautifulSoup(data)
stories = bs.find("div", {"class": "river"})
titles = stories.find_all("a", {"class": "title"})
print("Sending BI top stories.")
for index, title in enumerate(titles):
if index >= 5:
break
s.send("PRIVMSG %s :%s\r\n" % (chat, (title.get_text()).encode('ascii', 'ignore')))
def UD(keyword):
chat = str(keyword)
url = "http://www.urbandictionary.com/random.php"
data = urllib2.urlopen(url).read()
bs = BeautifulSoup(data)
body = bs.find("td", {"id": "middle_column"})
word = body.find("td", {"class": "word"})
word = word.find("span").get_text()
definition = body.find("div",{"class": "definition"}).get_text()
word = word.strip()
definition = definition.strip()
s.send("PRIVMSG %s :%s : %s\r\n" % (chat, word, definition))
def UDD(keyword):
if(str(keyword) is None):
keyword = "pwned"
if(str(keyword) == "pag"):
keyword = "pwned"
keyword = keyword.replace(" ", "+")
url = "http://www.urbandictionary.com/define.php?term=" + str(keyword)
print(url) #temp log
data = urllib2.urlopen(url, timeout=3).read()
bs = BeautifulSoup(data)
body = bs.find("td", {"id": "middle_column"})
word = body.find("td", {"class": "word"})
if word is None:
s.send("PRIVMSG %s :No definition found.\r\n" % LOBBY)
return
else:
word = word.find("span").get_text()
definition = body.find("div",{"class": "definition"}).get_text()
word = word.strip()
definition = definition.strip()
s.send("PRIVMSG %s :%s : %s\r\n" % (LOBBY, word, definition))
def ABOUT(keyword):
chat = str(keyword)
pid = os.getpid()
p = psutil.Process(pid)
cpu = p.get_cpu_percent(interval=1.0)
mem = p.get_memory_percent()
sys = platform.system()
ver = platform.version()
layout = platform.machine()
s.send("PRIVMSG %s : %s v%s\r\n" % (chat, NICK, VERSION))
s.send("PRIVMSG %s : I'm running on %s (%s).\r\n" % (chat, sys, layout))
s.send("PRIVMSG %s : Currently using %0.2f%% of the CPU and %0.2f%% of RAM.\r\n" % (LOBBY, cpu, mem))
def HELP(keyword):
chat = str(keyword)
#BI
command = "~BI"
s.send("PRIVMSG %s : Top Business Insider Stories. %s\r\n" % (chat, command))
#UD
command = "~UD"
s.send("PRIVMSG %s : Gives a random Urban Dictionary definition. %s\r\n" % (chat, command))
#UDD
command = "~UDD _keyword_"
s.send("PRIVMSG %s : Returns the Urban Dictionary Definition of a specific word. %s\r\n" % (chat, command))
#JOIN
command = "~JOIN"
s.send("PRIVMSG %s : Joins the specified channel. %s\r\n" % (chat, command))
#PART
command = "~PART"
s.send("PRIVMSG %s : Parts the channel in which the command was typed. %s\r\n" % (chat, command))
def JOIN(keyword): # Join a channel
if(str(keyword) is None):
keyword = LOBBY
# Join lobby
print("Joining: %s" % keyword)
s.send("JOIN %s\r\n" % keyword)
def PART(keyword): # Join a channel
# TODO: Do nothing if keyword is empty.. but this should never happen.
# Part channel where command was typed. Unless it's the lobby or a user chat.
if(str(keyword)!=LOBBY):
print("Parting: %s" % keyword)
s.send("PART %s\r\n" % keyword)
def YOUTUBE(fullLine, nickname, chat):
print("Youtube reference from " + nickname + " in chat with " + chat)
# Get starting position of the video ID
youtubeRefPos = string.find(fullLine, "youtu.be/") # youtu.be/videoID
if(youtubeRefPos != -1): # Found youtu.be/ link
youtubeRefPos = youtubeRefPos + 9 # Get ID after the /
else:
youtubeRefPos = string.find(fullLine, "watch?v=") # youtube.com/watch?v=videoID&potential_other=stuff
if(youtubeRefPos != -1): # Found youtube.com/ link
youtubeRefPos = youtubeRefPos + 8 # Get ID after the watch?v=
if(youtubeRefPos == -1):
print("Youtube: couldn't find starting position of video ID. Aborting.")
return # If we can't find the starting position of the ID, let's just abort now...
# Get ending position of the video ID
youtubeEndOfIDPos = string.find(fullLine, " ", youtubeRefPos)
youtubeEndOfIDPosAlt = string.find(fullLine, "&", youtubeRefPos)
if(youtubeEndOfIDPosAlt == -1): # There is no other information after watch?v=
if(youtubeEndOfIDPos == -1):
youtubeID = fullLine[youtubeRefPos:] # The eol delimits the video ID
else:
youtubeID = fullLine[youtubeRefPos:youtubeEndOfIDPos] # A space char delimits the video ID
else:
youtubeID = fullLine[youtubeRefPos:youtubeEndOfIDPosAlt] # A & char delimits the video ID
# Retreive video information on youtube
yt_service = gdata.youtube.service.YouTubeService()
entry = yt_service.GetYouTubeVideoEntry(video_id=youtubeID)
print("Youtube: reference found. Parsing video ID " + youtubeID + ".")
# TODO: Error catching to display error message of invalid video ID
# Print video information
#print("Video title: %s" % entry.media.title.text)
#print("Video length: %s" % entry.media.duration.seconds)
#print("Video desc: %s" % entry.media.description.text[:75])
s.send("PRIVMSG %s :Youtube: [Title] %s [Length] %ss [Desc] %s (...) \r\n" % (chat, entry.media.title.text, entry.media.duration.seconds, entry.media.description.text[:75])) # entry.media.description.text
#
# Connection definitions
#
def signal_handler(signal, frame):
print("ByeBye")
sys.exit(0)
def connect():
print("Connecting to : %s on port %i" % (HOST, PORT))
global s
s=socket.socket()
s.connect((HOST, PORT))
print("Setting USER")
s.send("USER %s %s bla :%s\r\n" % (IDENT, HOST, REALNAME))
print("Setting NICK")
s.send("NICK %s\r\n" % NICK)
# Check incoming socket buffer to see if the nickname has already been used.
readbuffer=s.recv(1024)
sBuff=string.split(readbuffer, "\n")
readbuffer=sBuff.pop( )
for line in sBuff:
line=string.rstrip(line)
line=string.split(line)
if(line[0]=="PING"):
s.send("PONG %s\r\n" % line[1])
print("Sending initial pong")
if(len(line) >= 5):
if(line[4]==":Nickname"):
s.send("NICK %s\r\n" % NICKALTER)
print("Nickname " + NICK + " already taken. Trying alternate nickname " + NICKALTER + ".")
# Re-Check the buffer for a new ping and an answer from our potential NICK change
readbuffer=s.recv(1024)
sBuff=string.split(readbuffer, "\n")
readbuffer=sBuff.pop( )
for line in sBuff:
line=string.rstrip(line)
line=string.split(line)
if(line[0]=="PING"):
s.send("PONG %s\r\n" % line[1])
print("Sending initial pong")
# Join lobby
print("Joining: %s" % LOBBY)
s.send("JOIN %s\r\n" % LOBBY)
def get_commands():
while 1:
try:
readbuffer=s.recv(1024)
sBuff=string.split(readbuffer, "\n")
readbuffer=sBuff.pop( )
for line in sBuff:
fullLine = line # Save a copy of the full line for parsing references to things
line=string.rstrip(line)
line=string.split(line)
#print(line)
if(line[0] == "PING"):
print("Sending pong")
s.send("PONG %s\r\n" % line[1])
if(line[1] == "PRIVMSG"):
# Get command string
command = line[3]
command = command.replace(":","")
command = command.upper()
# Get nickname of user who typed the command
nickname = line[0]
nickname = nickname.replace(":", "")
nickname = nickname[:nickname.find("!")]
# Get channel or username of chat in which the command was entered
chat = line[2]
if(command == "~HELP"):
print("Help command from " + nickname + " in chat with " + chat)
HELP(chat)
continue
if(command == "~BI"):
print("BI command from " + nickname + " in chat with " + chat)
BI(chat)
continue
if(command == "~UD"):
print("UD command from " + nickname + " in chat with " + chat)
UD(chat)
continue
if(command == "~ABOUT"):
print("ABOUT command from " + nickname + " in chat with " + chat)
ABOUT(chat)
continue
if(command == "~UDD"):
if(len(line) >= 5):
print("UDD command with arg \"" + line[4] + "\" from " + nickname + " in chat with " + chat)
UDD(' '.join(line[4:]).strip())
else:
print("UDD command with no arg from " + nickname + " in chat with " + chat)
s.send("PRIVMSG %s :No keyword entered. Try again.\r\n" % chat)
# NOTE: Could simply merge UD and UDD user commands so that if the user puts an argument to ~UD, he gets the definition, and no argument gets a random definition.
continue
if(command == "~JOIN"):
if(len(line) >= 5):
print("JOIN command with arg \"" + line[4] + "\" from " + nickname + " in chat with " + chat)
JOIN(' '.join(line[4:]).strip())
else:
print("JOIN command with no arg from " + nickname + " in chat with " + chat)
s.send("PRIVMSG %s :No channel name entered. Try again.\r\n" % chat)
continue
if(command == "~PART"):
print("PART command from " + nickname + " in chat with " + chat)
PART(chat)
continue
if(command == "~REDDIT"):
print("REDDIT command from " + nickname + " in chat with " + chat)
REDDIT(chat)
continue
youtubeURLs = ["youtu.be/", "youtube.com/"]
if any(x in fullLine for x in youtubeURLs):
YOUTUBE(fullLine, nickname, chat)
continue
except SystemExit:
s.send("QUIT :(error 0xO0p51D13d) System Exit.\r\n")
sys.exit(0)
except:
print("Error - ", sys.exc_info()[0], sys.exc_info()[1])
s.send("PRIVMSG %s :(error 0x2381ff64) Look at that pipe, it's broken. Try again.\r\n" % LOBBY)
#
# Main
#
def read_config():
config = ConfigParser.RawConfigParser()
config.read('bot.cfg')
global HOST, PORT, LOBBY, NICK, NICKALTER, IDENT, REALNAME, VERSION
HOST=config.get('Bot', 'host')
PORT=config.getint('Bot', 'port')
LOBBY=config.get('Bot', 'lobby')
NICK=config.get('Bot', 'nick')
NICKALTER=config.get('Bot', 'nickAlternate')
IDENT=config.get('Bot', 'ident')
REALNAME=config.get('Bot', 'realname')
VERSION=config.get('Bot', 'version')
def main():
signal.signal(signal.SIGINT, signal_handler)
read_config()
connect()
get_commands()
if __name__=="__main__":
main()