1. #!/usr/bin/python 2. """ 3. USAGE: 4. ./query.py -u[HOST] -i[SERVER_ID] -n[NAME] 5. 6. """ 7. import optparse, os, re, string, sys, urllib, warnings 8. warnings.simplefilter('ignore', DeprecationWarning) 9. from Cookie import Cookie 10. from urlparse import urljoin 11. import MySQLdb 12. 13. import pylib.configobj as COBJ 14. 15. import logging; log=logging.getLogger('ut3_master') 16. 17. file = os.path.abspath( 18. os.path.join(os.path.dirname(__file__), '../', '../', 'config.ini')) 19. config = COBJ.load(file) 20. HOST = config['DB_SERVER'] 21. USER = config['DB_USER'] 22. PASS = config['DB_PASSWD'] 23. DB = config['DB_DB'] 24. 25. def qstr(s): 26. return "'%s'" % s.replace('\\', '\\\\').replace("'", "\'") 27. 28. def dbconn(*a, **k): 29. def new_conn(): 30. conn = MySQLdb.connect(HOST,USER,PASS,DB) 31. try: 32. cursor = conn.cursor(*a, **k) 33. cursor.execute("SHOW TABLES") 34. cursor.execute("SET AUTOCOMMIT=0;") 35. cursor.close() 36. except (MySQLdb.OperationalError, AttributeError): 37. return new_conn() 38. else: 39. return conn 40. return new_conn() 41. 42. 43. def insert(r, server_id, verbose, debug): 44. conn = dbconn() 45. cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) 46. rec = {'name' : qstr(r[0]), 47. 'ip_address' : qstr(r[1]), 48. 'unique_id' : qstr(r[2]), 49. 'hash' : qstr(r[3]), 50. 'server_id' : server_id 51. } 52. if duplicate(rec, verbose, debug): 53. if verbose: 54. print 'DUPLICATE, returning' 55. return 56. else: 57. if verbose: 58. print 'INSERTING NEW PLAYER %s' % rec['name'] 59. sql = '''INSERT INTO hkey 60. (name, ip_address, unique_id, hash, server_id) 61. VALUES 62. (%(name)s, %(ip_address)s, %(unique_id)s, %(hash)s, %(server_id)s)''' % rec 63. cursor.execute(sql) 64. 65. 66. def duplicate(rec, verbose, debug): 67. conn = dbconn() 68. cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) 69. sql = '''SELECT key_id 70. FROM hkey 71. WHERE 72. name = %(name)s AND 73. ip_address = %(ip_address)s AND 74. unique_id = %(unique_id)s AND 75. hash = %(hash)s''' % rec 76. cursor.execute(sql) 77. recs = cursor.fetchall() 78. if recs: 79. 80. if verbose: 81. print 'PLAYER ALREAD EXISTS: %s' % rec['name'] 82. print 'PLAYER EXIST: ', recs 83. print 'QUERIED FOR: ', rec 84. 85. return True 86. else: 87. return False 88. 89. def urlencode(dict, order): 90. l = [] 91. for k in order: 92. v = dict[k] 93. 94. k = quote_plus(str(k)) 95. v = quote_plus(str(v)) 96. l.append(k + '=' + v) 97. return string.join(l, '&') 98. 99. 100. class WebBot(urllib.FancyURLopener): 101. #---------------------------------------------------------------------- 102. """ """ 103. #---------------------------------------------------------------------- 104. 105. USER_AGENT = 'Mozilla/2.02 (OS/2; I)' 106. SITENAME = 'Hedsteem' 107. despace_patt = re.compile('\s+') 108. verbose = False 109. debug = False 110. def despace(self, str): # Collapse Multiple Whitespace into One Blank 111. return WebBot.despace_patt.sub(' ', str) 112. 113. def __init__(self, baseurl='', debug=0): 114. urllib.FancyURLopener.__init__(self) 115. 116. self.delheader('User-agent') 117. self.addheader('User-agent', self.USER_AGENT) 118. self.addheader('HTTP_ACCEPT', 'text/html') 119. 120. self.baseurl = baseurl 121. self.debug = debug 122. self.cookies = Cookie() 123. 124. 125. def clear(self): 126. self.cookies = Cookie() 127. 128. def delheader(self, hdrtype): 129. keepers = [] 130. for h in self.addheaders: 131. if string.lower(h[0]) != string.lower(hdrtype): 132. keepers.append(h) 133. self.addheaders = keepers 134. 135. def webtransact(self, relurl, optdata=None): 136. url = urljoin(self.baseurl, relurl) 137. 138. if len(self.cookies): 139. self.delheader('Cookie') 140. for name, crumble in self.cookies.items(): 141. if string.lower(name) != 'path': 142. self.addheader('Cookie', crumble.OutputString()) 143. 144. 145. if optdata is None: webpage = self.open(url) 146. else: webpage = self.open(url, optdata) 147. 148. # Look For and Parse Any Relevant Headers 149. # -------------------------------------------------- 150. 151. if webpage.info().has_key('Set-cookie'): 152. items = webpage.info().getallmatchingheaders('Set-cookie') 153. 154. for i in items: 155. self.cookies.load(i) 156. 157. return webpage, url 158. 159. def do(self, debug, verbose): 160. self.verbose = verbose 161. self.debug = debug 162. try: 163. webpage, fullurl = self.webtransact('/current/players') 164. loginstr = webpage.read() 165. headers = webpage.info() 166. except Exception, e: 167. print str(e) 168. return [] 169. return self.getPlayers() 170. 171. 172. def http_error_401(self, url, fp, errcode, errmsg, headers, data=None): 173. return None # do nothing 174. 175. def stripToTable(self, input): 176. ret = [] 177. r = False 178. input = input.split('\n') 179. for line in input: 180. if line.startswith(''): r = True 181. if r: 182. ret.append(line) 183. if line.startswith('
'): r = False 184. return ret 185. def getData(self, table): 186. players = [] 187. player = [] 188. version = 1 189. for line in table: 190. if 'td style="background: #4040FF; color: #4040FF;"' in line or 'td style="background: #FF4040; color: #FF4040;"' in line: 191. version = 3 192. if 'value="sessionban">Session Ban' in line: 193. version = 2 194. if version == 1 or version == 2: 195. try: 196. player.append(str(re.search(r'
(.+?)(.+?)', line).group(1)).strip()) 202. except AttributeError: 203. pass 204. 205. if version == 1: 206. plen = 4 207. if version == 2: 208. plen = 5 209. if version == 3: 210. plen = 4 211. if len(player) == plen: 212. if version == 2: 213. del(player[1]) 214. 215. if self.verbose: 216. print 'PLAYER: ', player 217. players.append(player) 218. player = [] 219. if self.verbose: 220. print "ADMIN VERSION", version 221. if player: 222. if self.verbose: 223. print 'PLAYER: ', player 224. players.append(player) 225. if self.debug: 226. print "PLAYERS: ", players 227. return players 228. 229. def getPlayers(self): 230. try: 231. webpage, fullurl = self.webtransact('current/players') 232. html = webpage.read() 233. headers = webpage.info() 234. except: 235. print "URL Did Not Open!" 236. raise 237. table = self.stripToTable(html) 238. return self.getData(table) 239. 240. def run(name, id, url, verbose, debug): 241. if verbose: 242. print 'QUERY -' 243. print ' query.py' 244. print ' NAME:', name 245. print ' ID:', id 246. print ' URL:', url 247. 248. bot = WebBot(url) 249. for player in bot.do(debug, verbose): 250. if verbose: 251. print player 252. insert(player, id, verbose, debug) 253. bot.clear() 254. if verbose: 255. print 256. 257. def main(): 258. """For Help type ./query.py -h """ 259. parser = optparse.OptionParser(description=__doc__) 260. parser.set_usage(main.__doc__) 261. parser.formatter.format_description = lambda s:s 262. 263. parser.add_option("-D", "--debug", action="store_true", 264. default=False, 265. help="Enable debugging.") 266. 267. parser.add_option("-u", "--url", action="store", 268. default=None, 269. help="REQUIRED: Server URL") 270. 271. parser.add_option("-n", "--name", action="store", 272. default=None, 273. help="REQUIRED: Server Name") 274. 275. parser.add_option("-i", "--id", action="store", 276. default=None, 277. help="REQUIRED Server ID") 278. 279. parser.add_option("-v", "--verbose", action="store_true", 280. default=False, 281. help="Be verbose.") 282. 283. (opts, cmd) = parser.parse_args() 284. 285. # Logging Configuration 286. log.setLevel(0) 287. formatter = '%(levelname)-8s %(message)s' 288. 289. verbose = opts.verbose 290. debug = opts.debug 291. 292. if opts.debug: 293. logging.basicConfig() 294. else: 295. logging.basicConfig() 296. 297. 298. print 'VERBOSE IS: %s' % verbose 299. print 'DEBUG IS: %s' % debug 300. if not opts.name: 301. print __doc__ 302. print 'ERROR: The server name must be provided.' 303. sys.exit(1) 304. 305. if not opts.url: 306. print __doc__ 307. print 'ERROR: The server url must be provided.' 308. sys.exit(1) 309. 310. if not opts.id: 311. print __doc__ 312. print 'ERROR: The server id must be provided.' 313. sys.exit(1) 314. 315. if opts.name and opts.id and opts.url: 316. return run(opts.name, opts.id, opts.url, verbose, debug) 317. else: 318. parser.print_help() 319. 320. if __name__ == '__main__': 321. main()