bot.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. #! /usr/bin/env python2
  2. # This file is part of the anontwi project, http://anontwi.03c8.net
  3. # Copyright (c) 2012/2013/2014/2015 by psy <epsylon@riseup.net>
  4. # AnonTwiIRCBot v0.1 - 2012 - GPLv3.0
  5. # pancake <nopcode.org>
  6. # psy <nopcode.org>
  7. import os
  8. import sys
  9. import socket
  10. import string
  11. import time
  12. import HTMLParser
  13. from core.wrapper import WrapperAnontwi
  14. def getuser(user):
  15. return user.split('!')[0][1:]
  16. HELPMSG = """
  17. -----------------------
  18. AnonTwiIRCbot commands:
  19. !home [num] : view account 'home' timeline
  20. !public [user] [num] : view public timeline of a user
  21. !private [num] : view private timeline
  22. -----------------------
  23. !gen : generate secret
  24. !pin [secret] : active encryption
  25. !nopin : deactive encryption
  26. !dec [pin] [msg] : decrypt a message
  27. -----------------------
  28. !m [msg] : send a public message
  29. !d [user] [msg] : send a private message
  30. !rt [ID] : retweet a message
  31. !tt : view trending topics
  32. !search [term] : search a term
  33. -----------------------
  34. !kill : kill bot!
  35. -----------------------
  36. """
  37. HELLO = """Hello, I am an AnonTwi-IRCbot (http://anontwi.03c8.net). Use: !help for options."""
  38. class AnonTwiIrcBot():
  39. def runcmd(self, who, args):
  40. a = args[0].lower ()
  41. if (a=="!gen\r"):
  42. print "Generating secret!"
  43. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  44. try:
  45. key = self.wrapper.generate_key()
  46. self.s.send ( 'PRIVMSG ' + who + " :" + "Secret(PIN): " + key + "\n")
  47. except:
  48. self.s.send ( 'PRIVMSG ' + who + " :" + "Random secret generation failed :( " + "\n")
  49. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  50. if (a=="!pin"):
  51. print "Encryption: ON"
  52. key = string.join(args[1:2]," ") + "\n"
  53. key = key.rstrip("\n\r")
  54. enc = { 'enc' : True,
  55. 'pin' : key, }
  56. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  57. self.s.send ( 'PRIVMSG ' + who + " :" + "Encryption is ON using secret: " + key + "\n")
  58. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  59. self.enc = enc
  60. if (a=="!nopin\r"):
  61. print "Encryption: OFF"
  62. enc = { 'enc' : False,
  63. 'pin' : None, }
  64. key = None
  65. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  66. self.s.send ( 'PRIVMSG ' + who + " :" + "Encryption is OFF! (secret removed!)" + "\n")
  67. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  68. self.enc = enc
  69. if (a=="!dec"):
  70. print "Decrypting message"
  71. h = HTMLParser.HTMLParser()
  72. key = string.join(args[1:2]," ") + "\n"
  73. messages = string.join(args[2:]," ") + "\n"
  74. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  75. if not key:
  76. self.s.send ( 'PRIVMSG ' + who + " :" + "Error: Pin is empty!" + "\n")
  77. elif not messages:
  78. self.s.send ( 'PRIVMSG ' + who + " :" + "Error: Message is empty!" + "\n")
  79. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  80. try:
  81. msg = self.wrapper.decrypt(messages, key)
  82. m = h.unescape(msg)
  83. self.s.send ( 'PRIVMSG ' + who + " :" + "Message(Decrypted): " + m + "\n")
  84. except:
  85. self.s.send ( 'PRIVMSG ' + who + " :" + "Descryption failed :( " + "\n")
  86. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  87. # if (a=="!proxy"):
  88. # print "Proxy: ON"
  89. # proxy_irc = string.join(args[1:2]," ") + "\n"
  90. # proxy_irc = proxy_irc.rstrip("\n\r")
  91. # if proxy_irc.startswith("http://"): # better parse required
  92. # proxy_prefix = "http://"
  93. # proxy_irc = proxy_irc.strip("http://")
  94. # if proxy_irc.startswith("https://"):
  95. # proxy_prefix = "https://"
  96. # proxy_irc = proxy_irc.strip("https://")
  97. # [host, port] = proxy_irc.rsplit(':')
  98. # proxy = { 'proxy' : True,
  99. # 'ip_address' : host,
  100. # 'port' : proxy_prefix + port, }
  101. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  102. # self.s.send ( 'PRIVMSG ' + who + " :" + "Proxy is ON!" + "\n")
  103. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  104. # self.proxy = proxy
  105. # if (a=="!noproxy\r"):
  106. # print "Proxy: OFF"
  107. # proxy = { 'proxy' : False,
  108. # 'ip_address' : None,
  109. # 'port' : None }
  110. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  111. # self.s.send ( 'PRIVMSG ' + who + " :" + "Proxy is OFF!" + "\n")
  112. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  113. # self.proxy = proxy
  114. if (a=="!m"):
  115. print "Sending public message!"
  116. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  117. tweet = string.join(args[1:]," ")+"\n"
  118. pm = { 'pm' : False,
  119. 'user' : None, }
  120. try:
  121. if self.enc["enc"] is True: # encryption activated
  122. self.wrapper.send_tweet (tweet, pm, True, None, self.enc) #msg, fake GPS, enc
  123. else:
  124. self.wrapper.send_tweet (tweet, pm, True, True, None) #msg, fake GPS, waves
  125. self.s.send ( 'PRIVMSG ' + who + " :" + "Public message sent!" + "\n")
  126. except:
  127. self.s.send ( 'PRIVMSG ' + who + " :" + "Public message failed :(" + "\n")
  128. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  129. if (a=="!d"):
  130. print "Sending private message"
  131. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  132. user = string.join(args[1:2]," ") + "\n"
  133. tweet = string.join(args[2:]," ") + "\n"
  134. pm = { 'pm' : True,
  135. 'user' : user, }
  136. try:
  137. if self.enc["enc"] is True: # encryption activated
  138. self.wrapper.send_tweet (tweet, pm, None, None, self.enc, None) #msg, private, enc
  139. else:
  140. self.wrapper.send_tweet (tweet, pm, None, None, None, None) #msg, private
  141. self.s.send ( 'PRIVMSG ' + who + " :" + "Private message sent!" + "\n")
  142. except:
  143. self.s.send ( 'PRIVMSG ' + who + " :" + "Private message failed :(" + "\n")
  144. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  145. if (a=="!rt"):
  146. print "Retweeting message"
  147. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  148. ID = string.join(args[1:]," ") + "\n"
  149. if not ID:
  150. self.s.send ( 'PRIVMSG ' + who + " :" + "You must enter a correct ID to Retweet this message " + "\n")
  151. try:
  152. self.wrapper.retweet_tweet(ID)
  153. self.s.send ( 'PRIVMSG ' + who + " :" + "Retweet sent! " + "\n")
  154. except:
  155. self.s.send ( 'PRIVMSG ' + who + " :" + "Retweet failed :( " + "\n")
  156. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  157. # if (a=="!reply"):
  158. # print "Replying message"
  159. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  160. # ID = string.join(args[1:2]," ") + "\n"
  161. # msg = string.join(args[2:]," ") + "\n"
  162. # print ID
  163. # print msg
  164. # if not ID:
  165. # self.s.send ( 'PRIVMSG ' + who + " :" + "You must enter a correct ID to Replying this message " + "\n")
  166. # try:
  167. # replies = self.wrapper.reply(ID, msg, None, None)
  168. # self.s.send ( 'PRIVMSG ' + who + " :" + "Reply sent! " + "\n")
  169. # except:
  170. # self.s.send ( 'PRIVMSG ' + who + " :" + "Reply failed :( " + "\n")
  171. # self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  172. if (a=="!tt\r"):
  173. print "Showing Trending Topics"
  174. h = HTMLParser.HTMLParser()
  175. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  176. try:
  177. trendingtopics = self.wrapper.search_topics()
  178. if len(trendingtopics) <= 0:
  179. print "Not trending topics.\n"
  180. self.s.send ( 'PRIVMSG ' + who + " :" + "Not trending topics. " + "\n")
  181. else:
  182. for line in trendingtopics.split("\n"):
  183. line = line.encode("utf-8")
  184. self.s.send ( 'PRIVMSG ' + who + " :" + str(line) + "\n")
  185. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  186. except:
  187. print "Something wrong getting trending topics... Aborting!\n"
  188. if (a=="!search"):
  189. print "Searching..."
  190. h = HTMLParser.HTMLParser()
  191. try:
  192. textsearch = string.join(args[1:]," ") + "\n"
  193. num_ocurrences = "4" # fix this to provide a num of results
  194. searches = self.wrapper.search_messages(textsearch, num_ocurrences)
  195. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  196. self.s.send ( 'PRIVMSG ' + who + " :" + "Results for: " + textsearch + "\n")
  197. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  198. if len(searches) <= 0:
  199. print "Not searching results.\n"
  200. self.s.send ( 'PRIVMSG ' + who + " :" + "Not searching results. " + "\n")
  201. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  202. else:
  203. for s in searches:
  204. t = h.unescape(s.user.screen_name)
  205. self.s.send ( 'PRIVMSG ' + who + " :" + "Nick: " + str(t) + "\n")
  206. try:
  207. t = h.unescape(s.user.screen_name)
  208. self.s.send ( 'PRIVMSG ' + who + " :" + "Nick: " + str(t) + "\n")
  209. except:
  210. try:
  211. t = t.encode("utf-8")
  212. self.s.send ( 'PRIVMSG ' + who + " :" + "Nick: " + str(t) + "\n")
  213. except:
  214. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This nickname contains invalid parameters. Sorry!" + "\n")
  215. self.s.send ( 'PRIVMSG ' + who + " :" + "ID: " + str(s.id) + "\n")
  216. self.s.send ( 'PRIVMSG ' + who + " :" + str(s.created_at) + "\n")
  217. try:
  218. m = h.unescape(s.text)
  219. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  220. except:
  221. try:
  222. m = m.encode("utf-8")
  223. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  224. except:
  225. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This message contains invalid parameters. Sorry!" + "\n")
  226. if s.place:
  227. self.s.send ( 'PRIVMSG ' + who + " :" + "Location " + str(s.place["full_name"]) + "\n")
  228. else:
  229. pass
  230. time.sleep(5) #irc breathing
  231. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  232. except:
  233. print "Something wrong searching... Aborting!\n"
  234. if (a=="!home") or (a=="!home\r"):
  235. print "Showing Home Timeline..."
  236. try:
  237. num_ocurrences = int(string.join(args[1:]," ").replace("[","").replace("]","").replace("\r",""))
  238. except:
  239. num_ocurrences = 2
  240. h = HTMLParser.HTMLParser()
  241. try:
  242. if num_ocurrences is None or num_ocurrences <=0:
  243. num_ocurrences = 2
  244. (timelines, num) = self.wrapper.show_public(num_ocurrences, None)
  245. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  246. self.s.send ( 'PRIVMSG ' + who + " :" + "Home Timeline: " + "\n")
  247. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  248. if len(timelines) <= 0:
  249. self.s.send ( 'PRIVMSG ' + who + " :" + "You haven't any message, yet." + "\n")
  250. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  251. return
  252. else:
  253. if int(len(timelines)) < int(num):
  254. num = int(len(timelines))
  255. for i in range(int(num)):
  256. try:
  257. t = h.unescape(timelines[i].user.screen_name)
  258. self.s.send ( 'PRIVMSG ' + who + " :" + str(t) + "\n")
  259. except:
  260. try:
  261. t = t.encode("utf-8")
  262. self.s.send ( 'PRIVMSG ' + who + " :" + str(t) + "\n")
  263. except:
  264. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This nickname contains invalid parameters. Sorry!" + "\n")
  265. self.s.send ( 'PRIVMSG ' + who + " :" + "ID: " + str(timelines[i].id) + "\n")
  266. self.s.send ( 'PRIVMSG ' + who + " :" + str(timelines[i].created_at) + "\n")
  267. try:
  268. m = h.unescape(timelines[i].text)
  269. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  270. except:
  271. try:
  272. m = m.encode("utf-8")
  273. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  274. except:
  275. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This message contains invalid parameters. Sorry!" + "\n")
  276. if timelines[i].place is not None:
  277. self.s.send ( 'PRIVMSG ' + who + " :" + "Location: " + str(timelines[i].place["full_name"]) + "\n")
  278. else:
  279. pass
  280. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  281. time.sleep(5) #irc breathing
  282. except:
  283. print "Something wrong showing 'Home' Timeline... Aborting!\n"
  284. if (a=="!public") or (a=="!public\r"):
  285. print "Showing Public Timeline..."
  286. h = HTMLParser.HTMLParser()
  287. try:
  288. params = string.join(args[1:]).replace("[","").replace("]","").replace("\r","").split(" ")
  289. user = params[0]
  290. num_ocurrences = params[1]
  291. try:
  292. num_ocurrences = int(num_ocurrences)
  293. if num_ocurrences < 1:
  294. num_ocurrences = 4
  295. except:
  296. num_ocurrences = 4
  297. ps = self.wrapper.home_timeline(user, num_ocurrences)
  298. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  299. self.s.send ( 'PRIVMSG ' + who + " :" + "Public Timeline of: " + user + "\n")
  300. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  301. for p in ps[0]:
  302. try:
  303. u = h.unescape(p.user.screen_name)
  304. self.s.send ( 'PRIVMSG ' + who + " :" + "Nick: " + str(u) + "\n")
  305. except:
  306. try:
  307. u = u.encode("utf-8")
  308. self.s.send ( 'PRIVMSG ' + who + " :" + str(u) + "\n")
  309. except:
  310. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This nickname contains invalid parameters. Sorry!" + "\n")
  311. self.s.send ( 'PRIVMSG ' + who + " :" + "ID: " + str(p.id) + "\n")
  312. self.s.send ( 'PRIVMSG ' + who + " :" + str(p.created_at) + "\n")
  313. try:
  314. #TODO Fix ExcessFlood by waving?
  315. m = h.unescape(p.text)
  316. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  317. except:
  318. try:
  319. m = m.encode("utf-8")
  320. self.s.send ( 'PRIVMSG ' + who + " :" + str(m) + "\n")
  321. except:
  322. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This message contains invalid parameters. Sorry!" + "\n")
  323. if p.place is not None:
  324. self.s.send ( 'PRIVMSG ' + who + " :" + "Location: " + str(p.place["full_name"]) + "\n")
  325. else:
  326. pass
  327. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  328. time.sleep(5) #irc breathing
  329. except:
  330. print "Something wrong showing Public Timeline... Aborting!\n"
  331. if (a=="!private") or (a=="!private\r"):
  332. print "Showing Private Timeline..."
  333. try:
  334. params = string.join(args[1:]).replace("[","").replace("]","").replace("\r","").split(" ")
  335. num_ocurrences = params[0]
  336. num_ocurrences = int(num_ocurrences)
  337. if num_ocurrences < 1:
  338. num_ocurrences = 4
  339. except:
  340. num_ocurrences = 2
  341. h = HTMLParser.HTMLParser()
  342. try:
  343. (privates, num) = self.wrapper.show_private(str(num_ocurrences))
  344. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  345. self.s.send ( 'PRIVMSG ' + who + " :" + "Private Timeline: " + "\n")
  346. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  347. if len(privates) <= 0:
  348. self.s.send ( 'PRIVMSG ' + who + " :" + "You haven't any private, yet." + "\n")
  349. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  350. return
  351. else:
  352. if int(len(privates)) < int(num):
  353. num = int(len(privates))
  354. for i in range(int(num)):
  355. self.s.send ( 'PRIVMSG ' + who + " :" + "ID: " + str(privates[i].id) + "\n")
  356. self.s.send ( 'PRIVMSG ' + who + " :" + str(privates[i].created_at) + "\n")
  357. u = h.unescape(privates[i].sender_screen_name)
  358. self.s.send ( 'PRIVMSG ' + who + " :" + "From: " + str(u) + "\n")
  359. try:
  360. s = h.unescape(privates[i].text)
  361. self.s.send ( 'PRIVMSG ' + who + " :" + str(s) + "\n")
  362. except:
  363. try:
  364. s = s.encode("utf-8")
  365. self.s.send ( 'PRIVMSG ' + who + " :" + str(s) + "\n")
  366. except:
  367. self.s.send ( 'PRIVMSG ' + who + " :" + "ERROR: This message contains invalid parameters. Sorry!" + "\n")
  368. self.s.send ( 'PRIVMSG ' + who + " :" + "------------------------------" + "\n")
  369. time.sleep(5) #irc breathing
  370. except:
  371. print "Something wrong showing Public Timeline... Aborting!\n"
  372. if (a=="!help\r"):
  373. for line in HELPMSG.split("\n"):
  374. time.sleep(1) #irc breathing
  375. self.s.send ( 'PRIVMSG ' + who + " :" + str(line) + "\n")
  376. if (a=="!kill\r"):
  377. print "Killing bot"
  378. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  379. self.s.send ( 'PRIVMSG ' + who + " :" + "Bot killed!" + "\n")
  380. self.s.send ( 'PRIVMSG ' + who + " :" + "===================" + "\n")
  381. self.s.send ( 'QUIT\r\n' )
  382. sys.exit()
  383. def __init__(self):
  384. self.wrapper = WrapperAnontwi()
  385. # checking if 'temp' tokens are on correct position
  386. if os.getenv("ANONTWI_TOKEN_KEY") is None and os.getenv("ANONTWI_TOKEN_SECRET") is None:
  387. print "\nWarning: AnonTwi cannot authenticate you correctly!", "There is a problem with your tokens.\n\n You must provide a correct 'ANONTWI_TOKEN_KEY' and 'ANONTWI_TOKEN_SECRET' environment variables to the shell that launchs this GTK interface.\n\n - On Unix: \n export ANONTWI_TOKEN_KEY=Value\n export ANONTWI_TOKEN_SECRET=Value \n\n - On Win32: \n set ANONTWI_TOKEN_KEY=Value\n set ANONTWI_TOKEN_SECRET=Value\n\nTry: anontwi --tokens on shell mode, if you don't understand this error.\n"
  388. sys.exit()
  389. if os.getenv("ANONTWI_TOKEN_KEY") is None:
  390. print("\nWarning: AnonTwi cannot authenticate you correctly!", "There is a problem with tokens. You must provide a correct 'ANONTWI_TOKEN_KEY' environment variable to the shell that launchs this GTK interface.\n\n - On Unix: \n export ANONTWI_TOKEN_KEY=Value \n\n - On Win32: \n set ANONTWI_TOKEN_KEY=Value\n\nTry: anontwi --tokens on shell mode, if you don't understand this error.\n")
  391. sys.exit()
  392. elif os.getenv("ANONTWI_TOKEN_SECRET") is None:
  393. GuiUtils.Warning("\nWarning: AnonTwi cannot authenticate you correctly!", "There is a problem with tokens. You must provide a correct 'ANONTWI_TOKEN_SECRET' environment variable to the shell that launchs this GTK interface.\n\n - On Unix: \n export ANONTWI_TOKEN_SECRET=Value \n\n - On Win32: \n set ANONTWI_TOKEN_SECRET=Value\n\nTry: anontwi --tokens on shell mode, if you don't understand this error.\n")
  394. sys.exit()
  395. self.enc = { 'enc' : False,
  396. 'pin' : None, }
  397. def get_reply_user(self, id):
  398. status = self.wrapper.get_reply_user(id)
  399. user = status.user.screen_name
  400. return user
  401. def run(self, nick, host, port, channel):
  402. print "Connecting to: " + host + "," + port
  403. self.s = s = socket.socket ()
  404. s.connect ((host, int(port)))
  405. s.send ("NICK %s\r\n" % nick)
  406. s.send ("USER %s %s bla :%s\r\n" % (nick, host, nick))
  407. if channel != "":
  408. s.send ("JOIN #" + channel + "\r\n")
  409. for line in HELLO.split("\n"):
  410. self.s.send ( 'PRIVMSG #' + channel + " :" + str(line) + "\n")
  411. rb = ""
  412. while 1:
  413. rb = rb + s.recv(4096)
  414. temp = rb.split("\n")
  415. rb = temp.pop ()
  416. for line in temp:
  417. args = line.split(' ')
  418. print ">>>> " + line
  419. if (args[1] == "PRIVMSG"):
  420. user = getuser (args[0])
  421. msg = string.join (args[3:]," ")[1:]
  422. msgargs = msg.split(' ')
  423. print "<" + user + "> " + msg
  424. self.runcmd(user, msgargs)
  425. elif (args[1] == "PING\r"):
  426. s.send("PONG %s\r\n" % args[2])
  427. if __name__=="__main__":
  428. print "TODO: irc test"