rendered paste body#!/usr/bin/python pseudoserver.py# psm_erepublik.py# module for pypseudoserver# written by B (ben@rizon.net) and ZionI (jahprotector@gmail.com)# helpful erepublik bot!#Version 1.1b''' TODO: Right now this is skeleton what once might become fully functional all data fetching eRepublik bot. .info - this is more less done, need to see what people think about it, and add some changes accroding to them .bestprice - show valute in gold, to do that need to parse out country name, fetch another feed, calculate and return, not as simple as it seems .battle - partly done, need to add second function that will show list of all active battles, search battle by region name, search battles by country name, after battle is expired timer is bugged, need to fix that after i figure how - timeout funtion to threads, this is quite important, since eRepublik.com is not quite stable, long waiting time might confuse people .countryinfo - shows current info about given country .regioninfo - shows current info about given region .exchange - shows current value of given currency in gold or other currency according to market .company - gives info about current company etc... '''from psmodule import *import timeimport urllibfrom xml.dom import minidomimport os.pathfrom string import replacefrom twisted.internet import threadsclass PSModule_erepublik(PSModule): VERSION = 2 def listspeak(self,target,list): for line in list: self.parent.privMsg(target, "got valid request from %s to add eRepublik to %s" % (founder, chan), self.uid) def startup(self): if not PSModule.startup(self): return False self.sublogstatus = True try: self.uid, user = self.parent.createFakeUser( self.config.get('erepublik', 'nick'), self.config.get('erepublik', 'user'), self.config.get('erepublik', 'host'), self.config.get('erepublik', 'gecos'), self.config.get('erepublik', 'modes'), self.config.get('erepublik', 'nspass'), version="PyPsd erepublik v%d" % self.VERSION ) except Exception, err: self.logger.log("Error creating erepublik module user: %s" % err, L_ERROR) raise Exception("Error, config invalid for erepublik module- no user defined", L_ERROR) try: self.dbp.execute("CREATE TABLE IF NOT EXISTS `erepublik` (`id` int(9) NOT NULL auto_increment, \ `chan` varchar(51) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `chan` (`chan`))") except Exception, err: self.logger.log("Error creating table for erepublik module (%s)" % err, L_ERROR) raise Exception("Unable to create table for erepublik module") try: self.channels = [] self.dbp.execute("SELECT chan FROM erepublik") tmpchans = self.dbp.fetchall () #self.channels = ["#Zion"] for c in tmpchans: self.channels.append(c[0].lower()) now = self.parent.mkts() for chan in self.channels: self.parent.privMsg(self.logchan, "Joined %s" % chan, self.uid) self.parent.sendMessage("JOIN", "%d" % now, chan, "+", prefix=self.uid) self.parent.join_channel(self.uid, chan) except Exception, err: self.logger.log("Error loading channel list for erepublik module (%s)" % err, L_ERROR) raise Exception("Unable to load channel ist for erepublik module") try: self.sublog = "#e.out" self.parent.privMsg(self.logchan, "Joined %s for sublogging" % self.sublog, self.uid) self.parent.sendMessage("JOIN", "%d" % now, self.sublog, "+", prefix=self.uid) self.parent.join_channel(self.uid, self.sublog) except Exception, err: self.logger.log("Error connecting to sublog channel (%s)" % err, L_ERROR) raise Exception("Unable to connect to sublog channel") return True def shutdown(self): PSModule.shutdown(self) self.parent.quitFakeUser(self.uid) def erepublik_NOTICE(self, prefix, params): uid, user = self.parent.get_user(params[0]) poo, nick = self.parent.get_user(prefix) if uid != self.uid: return #ignore stuff not for this module if(nick['nick'] == 'ChanServ'): self.parent.privMsg(self.logchan, "got from chanserv: %s" % (params[1]), self.uid) else: return text = params[1].split(" ") status = text[2].strip("\002") founder = text[0].strip("\002") chan = text[5].strip(".") if "Founder" != status: return now = self.parent.mkts() try: if chan in self.channels: self.parent.privMsg(self.logchan, "got valid request from %s to remove eRepublik to %s" % (founder, chan), self.uid) self.parent.privMsg(self.logchan, "Left %s" % chan, self.uid) self.parent.sendMessage("PART", chan, prefix=self.uid) self.parent.part_channel(self.uid, chan) self.channels.remove(chan,) self.dbp.execute("DELETE FROM erepublik WHERE chan=%s;", (chan,)) else: self.parent.privMsg(self.logchan, "got valid request from %s to add eRepublik to %s" % (founder, chan), self.uid) self.channels.append(chan,) self.parent.privMsg(self.logchan, "Joined %s" % chan, self.uid) self.parent.sendMessage("JOIN", "%d %s %s" % (now, chan, "+"), prefix=self.uid) self.parent.join_channel(self.uid, chan) self.dbp.execute("INSERT INTO erepublik (id,chan) VALUES(NULL,%s);", (chan,)) except Exception, err: self.logger.log("Error add/remove chan for erepublik module (%s)" % err, L_ERROR) raise Exception("Error add/remove chan for erepublik module") ######### # PRIV MESSAGE PARSING STARTS HERE ######### def erepublik_PRIVMSG(self, prefix, params): uid, user = self.parent.get_user(params[0]) poo, nick = self.parent.get_user(prefix) #Begin XML and HTML parsing def battleParser(raw_data): for valute in raw_data.split("\n"): if "current" in valute: battle_current = valute.split(" ")[len(valute.split(" ")) - 1][:-1] if "original" in valute: battle_original = valute.split(" ")[len(valute.split(" ")) - 1][:-1] if "server_time" in valute: server_date = valute.split("'")[1].split()[1] server_time = valute.split("'")[1].split()[4].split(":") if "battle_critical_at" in valute: battle_date = valute.split("'")[1].split()[1] battle_time = valute.split("'")[1].split()[4].split(":") if server_date == battle_date: if int(battle_time[1]) < int(server_time[1]): return str(battle_current), str(battle_original), str(int(battle_time[0]) - int(server_time[0]) - 1), str(int(battle_time[1]) - int(server_time[1]) + 60) else: return str(battle_current), str(battle_original), str(int(battle_time[0]) - int(server_time[0])), str(int(battle_time[1]) - int(server_time[1])) else: if int(battle_time[1]) < int(server_time[1]): return str(battle_current), str(battle_original), str(int(battle_time[0]) - int(server_time[0]) + 23), str(int(battle_time[1]) - int(server_time[1]) + 60) else: return str(battle_current), str(battle_original), str(int(battle_time[0]) - int(server_time[0]) + 23), str(int(battle_time[1]) - int(server_time[1]) + 24) def priceParser(raw_data): extract = raw_data.firstChild.childNodes[1] price = extract.getElementsByTagName('price')[0].toxml()[7:-8] seller = extract.getElementsByTagName('name')[0].toxml()[6:-7] quantity = extract.getElementsByTagName('quantity')[0].toxml()[25:-11] return seller, quantity, price def infoParser(raw_data): name = raw_data.getElementsByTagName('name')[0].toxml()[6:-7] wellness = raw_data.getElementsByTagName('wellness')[0].toxml()[10:-11] strength = raw_data.getElementsByTagName('strength')[0].toxml()[10:-11] country = raw_data.getElementsByTagName('country')[0].toxml()[9:-10] region = raw_data.getElementsByTagName('region')[0].toxml()[8:-9] rank = raw_data.getElementsByTagName('military-rank')[0].toxml()[15:-16] level = raw_data.getElementsByTagName('level')[0].toxml()[7:-8] return name, country, region, level, wellness, strength, rank #Begin Connection Threads def figthCalcConn(): counter = 0 name = [] for value in params[1].split(): if counter < 1: pass else: name.append(value) counter = counter + 1 dom = minidom.parse(urllib.urlopen("http://api.erepublik.com/v1/feeds/citizens/%s?by_username=true" % "%20".join(name))) if "html" in dom.firstChild.toxml(): self.parent.privMsg(params[0], "That citizen don't exist or it's not included in eRepublik API", self.uid) else: if infoParser(dom)[6] == "Private": R = 1.2 if infoParser(dom)[6] == "Corporal": R = 1.4 if infoParser(dom)[6] == "Sergeant": R = 1.6 if infoParser(dom)[6] == "Lieutenant": R = 1.8 if infoParser(dom)[6] == "Captain": R = 2.0 if infoParser(dom)[6] == "Colonel": R = 2.2 if infoParser(dom)[6] == "General": R = 2.4 if infoParser(dom)[6] == "Field Marshal" : R = 2.6 dmg0 = round(R * float(infoParser(dom)[5]) * 1.75 * 0.5 * 2, 0) dmg1 = round(R * float(infoParser(dom)[5]) * 1.75 * 1.2 * 2, 0) dmg2 = round(R * float(infoParser(dom)[5]) * 1.75 * 1.4 * 2, 0) dmg3 = round(R * float(infoParser(dom)[5]) * 1.75 * 1.6 * 2, 0) dmg4 = round(R * float(infoParser(dom)[5]) * 1.75 * 1.8 * 2, 0) dmg5 = round(R * float(infoParser(dom)[5]) * 1.75 * 2 * 2, 0) self.parent.privMsg(params[0], "Q0: %i, Q1: %i, Q2: %i, Q3: %i, Q4: %i, Q5: %i" % (dmg0, dmg1, dmg2, dmg3, dmg4, dmg5), self.uid) def infoConnection(): counter = 0 name = [] for value in params[1].split(): if counter < 1: pass else: name.append(value) counter = counter + 1 dom = minidom.parse(urllib.urlopen("http://api.erepublik.com/v1/feeds/citizens/%s?by_username=true" % "%20".join(name))) if "html" in dom.firstChild.toxml(): self.parent.privMsg(params[0], "That citizen don't exist or it's not included in eRepublik API", self.uid) else: self.parent.privMsg(params[0], "%s - Country: %s - Region: %s - Level: %s - Wellness: %s - Strength: %s - Rank: %s" % (infoParser(dom)[0], infoParser(dom)[1], infoParser(dom)[2], infoParser(dom)[3], infoParser(dom)[4], infoParser(dom)[5], infoParser(dom)[6]),self.uid) def battleConnection(): connection = urllib.urlopen("http://www.erepublik.com/en/battles/show/" + str(params[1].split()[1])) raw_data = connection.read() connection.close() if "current" in raw_data: #self.parent.privMsg(self.logchan, ".battle envoked with param %s. Battle existing" % (params[1].split()[1]), self.uid) #logchannel? self.parent.privMsg(params[0], "%s, %s/%s" %( raw_data.split("\n")[9][7:-8], battleParser(raw_data)[0], battleParser(raw_data)[1]), self.uid) self.parent.privMsg(params[0], "http://www.erepublik.com/en/battles/show/%s - Battle expires in %s hours and %s minutes" %(str(params[1].split()[1]), battleParser(raw_data)[2], battleParser(raw_data)[3]), self.uid) else: #self.parent.privMsg(self.logchan, ".battle envoked with param %s. Battle nonexisting" %(params[1].split()[1]), self.uid) #logchannel self.parent.privMsg(params[0], "Battle %s is not active." % (params[1].split()[1]), self.uid) #return to channel def bestpriceConnection(): counter = 0 countryname = [] for value in params[1].split(): if counter < 3: pass else: countryname.append(value) counter = counter + 1 dom2 = minidom.parse(urllib.urlopen("http://api.erepublik.com/v1/feeds/market/%s/%s/%s" % (params[1].split()[1], params[1].split()[2], "-".join(countryname)))) if "html" in dom2.firstChild.toxml(): self.parent.privMsg(params[0], "Input is wrong...", self.uid) else: if "nil-classes" in dom2.firstChild.toxml(): self.parent.privMsg(params[0], "There is no any products on selected market.", self.uid) else: self.parent.privMsg(params[0], "Best price of %s Q%s in %s - Seller: %s - Quantity: %s - Price: %s" %(params[1].split()[1].capitalize(), params[1].split()[2], " ".join(countryname).title(), priceParser(dom2)[0], priceParser(dom2)[1], priceParser(dom2)[2]), self.uid) #Listener if params[0].lower() in self.channels: #self.parent.privMsg(self.logchan, "%s:%s:%s" % (params[0], nick['nick'], params[1]), self.uid) text = params[1].split(" ") if ".help" in text: self.sublogging(nick['nick'], params[0], params[1], self.sublogstatus) self.parent.privMsg(params[0], "eRepublik Bot V1 Help Menu", self.uid) self.parent.privMsg(params[0], ".lookup - Gives info about given citizen. Example: .lookup Zion I", self.uid) self.parent.privMsg(params[0], ".battle - Gives info about given battle. Example: .battle 7232 (last four numbers on battle's URL)", self.uid) self.parent.privMsg(params[0], ".bestprice - Gives info about cheapes product for given market and type. Example: .bestprice weapon 1 Bosnia Herzegovina", self.uid) self.parent.privMsg(params[0], ".fightcalc - Gives info about given citizen's damage. Example: .fightcalc Zion I", self.uid) self.parent.privMsg(params[0], "Note: Citizens that have more than 500 000 damage done are not included in eRepublik API.", self.uid) elif params[1].split()[0] == ".bestprice": self.sublogging(nick['nick'], params[0], params[1], self.sublogstatus) threads.deferToThread(bestpriceConnection) elif params[1].split()[0] == ".lookup": self.sublogging(nick['nick'], params[0], params[1], self.sublogstatus) threads.deferToThread(infoConnection) elif params[1].split()[0] == ".battle": self.sublogging(nick['nick'], params[0], params[1], self.sublogstatus) if len(params[1].split()) == 2: threads.deferToThread(battleConnection) elif params[1].split()[0] == ".fightcalc": self.sublogging(nick['nick'], params[0], params[1], self.sublogstatus) threads.deferToThread(figthCalcConn) if params[0] in self.sublog: if params[1].split()[0] == "--silent": if params[1].split()[1] == "1": self.sublogstatus = False self.parent.privMsg(self.sublog, "Silent mode ON", self.uid) else: self.parent.privMsg(self.sublog, "Silent mode OFF", self.uid) self.sublogstatus = True elif params[1].split()[0] == "--list": for chan in self.channels: self.parent.privMsg(self.sublog, ">> %s" % chan, self.uid) elif params[1].split()[0] == "--global": for chan in self.channels: self.parent.privMsg(chan, "%s" % params[1].lstrip("--global "), self.uid) if uid != self.uid: return self.parent.privMsg(self.logchan, "got message to %s saying %s from %s" % (params[0], params[1], nick['nick']), self.uid) if (params[1][0:9] == 'request #'): self.parent.privMsg("ChanServ", "why %s %s" % (params[1][8:], nick['nick']), self.uid) elif (params[1][0:8] == 'remove #'): self.parent.privMsg("ChanServ", "why %s %s" % (params[1][7:], nick['nick']), self.uid) ## Begin event hooks def getHooks(self): return (('privmsg', self.erepublik_PRIVMSG),('notice', self.erepublik_NOTICE))## Command Hooks def sublogging(self, nick, channel, command, status): if status: self.parent.privMsg(self.sublog, ">> %s:%s > %s" % (nick, channel, command), self.uid) else: return