botbrain.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from collections import defaultdict
  2. import webwriter
  3. import bf3api
  4. import time
  5. import logger
  6. import datetime
  7. import battlelog
  8. import urllib2
  9. import json
  10. from urlparse import urlparse, parse_qsl
  11. import re
  12. from xml.dom.minidom import parseString
  13. import db
  14. from datetime import datetime, timedelta
  15. import sys
  16. import os
  17. api = bf3api.API(None, '360')
  18. bf3players = {'tarehart': ('tarehart', '360'),
  19. #'hlmtre': ('hellmitre', '360'),
  20. 'willfro': ('fro4thought', '360'),
  21. 'BoneKin': ('BoneKin', '360'),
  22. 'Lucifer7': ('Lucifer7', '360'),
  23. 'i7': ('Infinite Se7en', '360')}
  24. def getbf3stats(message, platform):
  25. # global bf3players
  26. global api
  27. gt = message.split(None, 2)[2].strip() # grab gamertag off the end and strip it of terminators
  28. command = message.split(None, 2)[1].strip()
  29. data = api.player(gt, platform, "clear,ranking")
  30. l = logger.Logger()
  31. date = str(time.strftime("%Y-%m-%d %H:%M:%S"))
  32. string = "getting " + command + " for player " + gt + " at " + date + '\n'
  33. l.write(string)
  34. return formatbf3data(gt, command, data)
  35. def formatbf3data(player, command, data):
  36. if data.status == "data":
  37. if command == "spm":
  38. return [player + "'s SPM: " + str(data.Stats.Ranking.Spm.v)[:6]]
  39. elif command == "kdr":
  40. return [player + "'s KDR: " + str(data.Stats.Ranking.Kdr.v)[:6]]
  41. elif command == "wlr":
  42. return [player + "'s WLR: " + str(data.Stats.Ranking.Wlr.v)[:6]]
  43. elif command == "stats":
  44. l = [player+"'s stats: ", "KDR: "+str(data.Stats.Ranking.Kdr.v)[:6], "SPM: "+str(data.Stats.Ranking.Spm.v)[:6], "Headshots/kill: "+str(data.Stats.Ranking.Hskillperc.v)[:6], "win/loss: "+str(data.Stats.Ranking.Wlr.v)[:6]]
  45. return l
  46. elif data.status == "notfound":
  47. return [player + " not found "]
  48. else:
  49. return ["ERROR"]
  50. def getbf3last(message):
  51. global api
  52. command = message.split(None, 2)[1].strip()
  53. gt = message.split(None, 2)[2].strip() # grab gamertag off the end and strip it of terminators
  54. fact = battlelog.getLatestGameFact(api, gt, command)
  55. return gt + "'s latest " + command + " is " + str(fact)[:6]
  56. class BotBrain:
  57. BRAINDEBUG = False
  58. def __init__(self, microphone, bot=None):
  59. # get time for uptime start
  60. self.starttime = time.time()
  61. # get time for current length of uptime
  62. self.localtime = time.localtime()
  63. # get handle on output
  64. self.microphone = microphone
  65. self.bot = bot
  66. yth = dict()
  67. self.db = db.DB(self.bot)
  68. self.ww = webwriter.WebWriter()
  69. def _isAdmin(self, username):
  70. if self.db._isAdmin(username):
  71. return True
  72. return False
  73. def getMicrophone(self):
  74. return self.microphone
  75. def _updateSeen(self, user, statement, event):
  76. self.db.updateSeen(user, statement, event)
  77. def _insertImg(self, user, url, channel):
  78. self.db._insertImg(user, url, channel)
  79. def __bareSay(self, thing):
  80. self.microphone(thing + '\n')
  81. def say(self, channel, thing):
  82. self.microphone('PRIVMSG ' + channel + ' :' + str(thing) + '\n')
  83. def notice(self, channel, thing):
  84. self.microphone('NOTICE ' + channel + ' :' + str(thing) + '\n')
  85. # now implemented as a module
  86. #def _weather(self, channel, zipcode):
  87. # now implemented as a module
  88. # def _getyoutubetitle(self, line, channel):
  89. def _ctof(self, channel, c_temp):
  90. c = float(c_temp)
  91. f = (c * 1.8)+32
  92. self.say(channel, str(f) + "* F")
  93. def _ftoc(self, channel, f_temp):
  94. f = float(f_temp)
  95. c = (f - 32)*(.5555)
  96. self.say(channel, str(c) + "* C")
  97. def _uptime(self, channel):
  98. self.say(channel,"I've been up " +str(timedelta(seconds=time.time() - self.starttime))[:7] + ", since "+time.strftime("%a, %d %b %Y %H:%M:%S -0800", self.localtime))
  99. def _speak(self, user, target, message):
  100. if target.startswith("#"):
  101. self.say(target, message)
  102. else:
  103. target = "#" + target
  104. self.say(target, message)
  105. def _onstat(self, channel):
  106. self.say(channel, "Yep, I'm on. Idiot.")
  107. def _help(self, user):
  108. self.microphone('PRIVMSG ' + user + ' :' + ".bf3 [spm, kdr, wlr, stats],\n")
  109. self.microphone('PRIVMSG ' + user + ' :' + ".uptime,\n")
  110. self.microphone('PRIVMSG ' + user + ' :' + ".imgs,\n")
  111. self.microphone('PRIVMSG ' + user + ' :' + ".ctof [celsius],\n")
  112. self.microphone('PRIVMSG ' + user + ' :' + ".ftoc [fahrenheit],\n")
  113. def _join(self, usr, message):
  114. if self._isAdmin(usr):
  115. if len(message.split()) is 3:
  116. channel = message.split()[1]
  117. extraArg = message.split()[-1]
  118. self.__bareSay("JOIN " + channel + " " + extraArg)
  119. else:
  120. channel = message.split()[-1] # second word (join #channel password)
  121. self.__bareSay("JOIN " + channel)
  122. def __quit(self, usr):
  123. if self._isAdmin(usr):
  124. self.__bareSay("QUIT :quitting")
  125. print "quitting as per " + usr
  126. sys.exit()
  127. def respond(self, usr, channel, message):
  128. # this bit is not a command
  129. if (".png" in message or ".gif" in message or ".jpg" in message or ".jpeg" in message) and ("http:" in message) or ("imgur.com" in message and "gallery" in message):
  130. url = re.search("(?P<url>https?://[^\s]+)", message).group("url")
  131. if url:
  132. self._insertImg(usr, url, channel)
  133. # this bit is
  134. if message.startswith("join"):
  135. self._join(usr, message)
  136. if message.startswith("quit"):
  137. self.__quit(usr)
  138. if message.startswith(".imgs"):
  139. self.ww._generate(self.db._getImgs())
  140. # hackish TODO
  141. if os.getenv('USER') == 'pybot':
  142. self.say(channel, "http://pybot.zero9f9.com/img/")
  143. else:
  144. self.say(channel, "http://zero9f9.com/~"+os.getenv('USER')+"/img/")
  145. if message.startswith(".seen"):
  146. self._seen(message.split()[-1], channel)
  147. if message.startswith(".ctof"):
  148. last = message.split()
  149. if last[-1] != "":
  150. self._ctof(channel, last[-1])
  151. if message.startswith(".ftoc"):
  152. last = message.split()
  153. if last[-1] != "":
  154. self._ftoc(channel, last[-1])
  155. if message.startswith(".help"):
  156. self._help(usr)
  157. if message.startswith(".bf3pc"):
  158. stats = getbf3stats(message, 'pc')
  159. try:
  160. for line in stats:
  161. self.say(channel, line)
  162. except TypeError:
  163. self.say(channel, "WOOPS")
  164. elif message.startswith(".bf3"):
  165. stats = getbf3stats(message, '360')
  166. try:
  167. for line in stats:
  168. self.say(channel, line)
  169. except TypeError:
  170. self.say(channel, "WOOPS")
  171. if message.startswith(".lastbf3"):
  172. last = getbf3last(message)
  173. self.say(channel, last)
  174. if message.startswith(".uptime"):
  175. self._uptime(channel)
  176. if message.startswith(".onstat"):
  177. self._onstat(channel)
  178. if message.startswith(".speak"):
  179. tmp = message.split(" ",2)
  180. chnl = tmp[1]
  181. msg = tmp[2]
  182. self._speak(usr, chnl, msg)
  183. # utility function
  184. def __prettyDate(self,time):
  185. now = datetime.now()
  186. if type(time) is int:
  187. diff = now - datetime.fromtimestamp(time)
  188. elif isinstance(time,datetime):
  189. diff = now - time
  190. elif not time:
  191. diff = now - now
  192. second_diff = diff.seconds
  193. day_diff = diff.days
  194. if day_diff < 0:
  195. return ''
  196. if day_diff == 0:
  197. if second_diff < 10:
  198. return "just now"
  199. if second_diff < 60:
  200. return str(second_diff) + " seconds ago"
  201. if second_diff < 120:
  202. return "a minute ago"
  203. if second_diff < 3600:
  204. return str( second_diff / 60 ) + " minutes ago"
  205. if second_diff < 7200:
  206. return "an hour ago"
  207. if second_diff < 86400:
  208. return str( second_diff / 3600 ) + " hours ago"
  209. if day_diff == 1:
  210. return "Yesterday"
  211. if day_diff < 7:
  212. return str(day_diff) + " days ago"
  213. if day_diff < 31:
  214. return str(day_diff/7) + " weeks ago"
  215. if day_diff < 365:
  216. return str(day_diff/30) + " months ago"
  217. return str(day_diff/365) + " years ago"