def skill(self, server, event, bot): credentials = self.get_credentials(server.server_name, event.source.nick) if credentials is None: server.privmsg( event.target, "%s isn't in the database, see the %seve-add command" % (event.source.nick, server.cmdchar)) return (eve_id, eve_vcode) = credentials api = eveapi.EVEAPIConnection(cacheHandler=EveCache()) auth = api.auth(keyID=eve_id, vCode=eve_vcode) result = auth.account.Characters() skills = api.eve.SkillTree() for character in result.characters: server.privmsg(event.target, "Training queue for %s" % character.name) queue = auth.char.SkillQueue(characterID=character.characterID) for training_skill in queue.skillqueue: # Oh boy, this is going to be horrible. for group in skills.skillGroups: for skill in group.skills: if skill.typeID == training_skill.typeID: time_str = time.strftime( "%B %d %H:%M:%S Central", time.localtime(training_skill.endTime)) server.privmsg( event.target, "%s: %s to level %s. Ends %s." % (group.groupName, skill.typeName, training_skill.level, time_str))
def retrieve_full_notification_text(accounts, notifications): # [account][characterID][notificationID] = { # 'notificationID': notid, # 'typeID': typeid, # 'senderID': senderid, # 'sentDate': sentdate, # 'read': read ## 'text': "blah blah blah" # } api = eveapi.EVEAPIConnection() for account in notifications: auth = api.auth(keyID=accounts[account]["key_id"], vCode=accounts[account]["v_code"]) for character in notifications[account]: if len(notifications[account][character].keys()) > 0: comma_sep_ids = ",".join([str(b) for b in notifications[account][character].keys()]) result = auth.char.NotificationTexts(characterID=character, IDs=comma_sep_ids) result_rowset = result.notifications for notid in notifications[account][character]: result_row = result_rowset.Get(int(notid)) notifications[account][character][notid]['text'] = result_row['data'] return notifications
def get_notification_headers(accounts): api = eveapi.EVEAPIConnection() notifications = {} for account in accounts: auth = api.auth( keyID=accounts[account]["key_id"], vCode=accounts[account]["v_code"]) result2 = auth.account.Characters() notifications[account] = {} for character in result2.characters: notifications[account][character.characterID] = {} result = auth.char.Notifications( characterID=character.characterID) result = result.notifications for notid, typeid, senderid, sentdate, read in result.Select( 'notificationID', 'typeID', 'senderID', 'sentDate', 'read'): notifications[account][character.characterID][notid] = { 'notificationID': notid, 'typeID': typeid, 'senderID': senderid, 'sentDate': sentdate, 'read': read } return notifications
def wallet(self, server, event, bot): """ List all character wallets """ credentials = self.get_credentials(server.server_name, event.source.nick) if credentials is None: server.privmsg( event.target, "%s isn't in the database, see the %seve-add command" % (event.source.nick, server.cmdchar)) return (eve_id, eve_vcode) = credentials api = eveapi.EVEAPIConnection(cacheHandler=EveCache()) auth = api.auth(keyID=eve_id, vCode=eve_vcode) result = auth.account.Characters() for character in result.characters: wallet = auth.char.AccountBalance( characterID=character.characterID) isk = wallet.accounts[0].balance server.privmsg(event.target, "Character: %s has %s ISK" % (character.name, isk))
def updateApiKey(api, session=getSession()): eveapi.set_user_agent("eveapi.py/1.3") eve = eveapi.EVEAPIConnection() # Open our main rollback try try: # Check that the API is still active... try: keyinfo = eve.account.APIKeyInfo(keyID=api.keyID, vCode=api.vCode) except eveapi.Error as e: # ...and delete the api if it isn't if e.code == 403: apiLog( "\tDeleting API ID %d as it has been deleted or expired" % api.id) session.delete(api) session.commit() else: apiLog( "The XMLAPI returned an error [%d] checking API ID %d, lets try again later" % (e.code, api.id)) return except Exception as e: apiLog("Generic Exception checking API ID %d: %s" % (api.id, str(e))) return # Grab AccountStatus too accStatus = eve.account.AccountStatus(keyID=api.keyID, vCode=api.vCode) # Update the key info api.accessMask = keyinfo.key.accessMask api.type = keyinfo.key.type api.paidUntil = datetime.datetime.fromtimestamp(accStatus.paidUntil) api.createDate = datetime.datetime.fromtimestamp(accStatus.createDate) api.logonCount = accStatus.logonCount api.logonMinutes = accStatus.logonMinutes api.lastUpdated = datetime.datetime.now() if keyinfo.key.expires == "": api.expires = None else: api.expires = datetime.datetime.fromtimestamp(keyinfo.key.expires) key = keyinfo.key # Purge characters from database that aren't on the API for dbChar in api.characters: if dbChar.characterID not in map(lambda x: x.characterID, key.characters): apiLog( "Deleted character as they were no longer on the API characterID=%d, characterName=%s" % (dbChar.characterID, dbChar.characterName)) session.delete(dbChar) # Add or update characters from the API into the database for apiChar in key.characters: if apiChar.characterID not in map(lambda x: x.characterID, api.characters): dbChar = Character() dbChar.characterID = apiChar.characterID dbChar.apiId = api.id session.add(dbChar) else: for dbChar in api.characters: if dbChar.characterID == apiChar.characterID: # Suppresed this check as it doesn't make logical sense to limit it this far down stream # Check its not been updated within the last 119 mins #if (dbChar.lastUpdated + datetime.timedelta(0, 7140)) > datetime.datetime.now(): # return break # Get the CharacterSheet charSheet = eve.char.CharacterSheet( keyID=api.keyID, vCode=api.vCode, characterID=apiChar.characterID) charInfo = eve.eve.CharacterInfo(keyID=api.keyID, vCode=api.vCode, characterID=apiChar.characterID) # Upsert the corporation if not upsertCorporation(eve=eve, corporationID=charSheet.corporationID): apiLog( "An error occurred upserting corporationID=%d, so we'll rollback and try later" % charSheet.corporationID) session.rollback() return # Update the characters values dbChar.characterName = apiChar.characterName dbChar.corporationID = apiChar.corporationID dbChar.factionID = apiChar.factionID dbChar.balance = charSheet.balance dbChar.cloneJumpDate = datetime.datetime.fromtimestamp( charSheet.cloneJumpDate) dbChar.jumpActivation = datetime.datetime.fromtimestamp( charSheet.jumpActivation) dbChar.jumpFatigue = datetime.datetime.fromtimestamp( charSheet.jumpFatigue) dbChar.jumpLastUpdate = datetime.datetime.fromtimestamp( charSheet.jumpLastUpdate) dbChar.DoB = datetime.datetime.fromtimestamp(charSheet.DoB) dbChar.remoteStationDate = datetime.datetime.fromtimestamp( charSheet.remoteStationDate) dbChar.homeStationID = charSheet.homeStationID dbChar.shipTypeID = charInfo.shipTypeID dbChar.shipName = charInfo.shipName dbChar.lastKnownLocation = charInfo.lastKnownLocation dbChar.lastUpdated = datetime.datetime.now() # Get the Asset List assetList = eve.char.AssetList(keyID=api.keyID, vCode=api.vCode, characterID=apiChar.characterID, flat=1) apiAssetsById = assetList.assets.IndexedBy("itemID") # Purge assets from the database that aren't on the API for dbAsset in session.query(Asset).filter( Asset.characterID == apiChar.characterID).all(): try: apiAssetsById.Get(dbAsset.itemID) except: session.delete(dbAsset) # Add or update assets from the API into the database dbAssets = session.query(Asset).filter( Asset.characterID == apiChar.characterID).all() dbAssetsDict = {} for dbAsset in dbAssets: dbAssetsDict[dbAsset.itemID] = dbAsset newAssets = [] dbAssetSet = frozenset(frozenset(map(lambda x: x.itemID, dbAssets))) for apiAsset in assetList.assets: if apiAsset.itemID not in dbAssetSet: dbAsset = Asset() dbAsset.itemID = apiAsset.itemID dbAsset.characterID = apiChar.characterID newAssets.append(dbAsset) else: dbAsset = dbAssetsDict[apiAsset.itemID] # Update the asset values dbAsset.locationID = apiAsset.locationID dbAsset.typeID = apiAsset.typeID dbAsset.quantity = apiAsset.quantity dbAsset.flag = apiAsset.flag dbAsset.singleton = apiAsset.singleton # Add the assets to the session session.add_all(newAssets) # Add or update skills from the API into the database newSkills = [] dbSkillsDict = {} for dbSkill in dbChar.skills: dbSkillsDict[dbSkill.typeID] = dbSkill dbSkillSet = frozenset( map(lambda x: "%d:%d" % (x.characterID, x.typeID), dbChar.skills)) for apiSkill in charSheet.skills: if "%d:%d" % (apiChar.characterID, apiSkill.typeID) not in dbSkillSet: dbSkill = Skill() dbSkill.characterID = apiChar.characterID dbSkill.typeID = apiSkill.typeID newSkills.append(dbSkill) else: dbSkill = dbSkillsDict[apiSkill.typeID] # Update the skills values dbSkill.level = apiSkill.level dbSkill.skillpoints = apiSkill.skillpoints # Add the skills to the session session.add_all(newSkills) # Purge jump clones from the database that aren't on the API jumpClonesById = charSheet.jumpClones.IndexedBy("jumpCloneID") for dbJumpClone in session.query(JumpClone).filter( JumpClone.characterID == dbChar.characterID).all(): try: jumpClonesById.Get(dbJumpClone.jumpCloneID) except: session.delete(dbJumpClone) # Add or update jump clones from the API into the database newJumpClones = [] dbJumpClonesDict = {} dbJumpClones = session.query(JumpClone).filter( JumpClone.characterID == dbChar.characterID).all() for x in dbJumpClones: dbJumpClonesDict[x.jumpCloneID] = x dbJumpCloneSet = frozenset( map(lambda x: x.jumpCloneID, dbJumpClones)) for apiJumpClone in charSheet.jumpClones: if apiJumpClone.jumpCloneID not in dbJumpCloneSet: dbJumpClone = JumpClone() dbJumpClone.jumpCloneID = apiJumpClone.jumpCloneID dbJumpClone.characterID = charSheet.characterID newJumpClones.append(dbJumpClone) else: dbJumpClone = dbJumpClonesDict[apiJumpClone.jumpCloneID] # Update the values dbJumpClone.cloneName = apiJumpClone.cloneName dbJumpClone.locationID = apiJumpClone.locationID dbJumpClone.typeID = apiJumpClone.typeID # Add the new jump clones to the session session.add_all(newJumpClones) # Handle current implants apiCurrImplants = frozenset( map(lambda x: x.typeID, charSheet.implants)) for x in session.query(Implant).filter( Implant.characterID == dbChar.characterID).filter( Implant.jumpCloneID == None).all(): if x.typeID not in apiCurrImplants: session.delete(x) dbImplantSet = frozenset( map( lambda x: x.typeID, session.query(Implant).filter( Implant.characterID == dbChar.characterID).filter( Implant.jumpCloneID == None).all())) for x in charSheet.implants: if x.typeID not in dbImplantSet: dbImplant = Implant() dbImplant.characterID = dbChar.characterID dbImplant.jumpCloneID = None dbImplant.typeID = x.typeID session.add(dbImplant) # Handle Jump Clone implants apiJCImplants = frozenset( map(lambda x: "%d:%d" % (x.jumpCloneID, x.typeID), charSheet.jumpCloneImplants)) for x in session.query(Implant).filter( Implant.characterID == dbChar.characterID).filter( Implant.jumpCloneID != None).all(): if "%d:%d" % (x.jumpCloneID, x.typeID) not in apiJCImplants: session.delete(x) dbImplantSet = frozenset( map( lambda x: "%d:%d" % (x.jumpCloneID, x.typeID), session.query(Implant).filter( Implant.characterID == dbChar.characterID).filter( Implant.jumpCloneID != None).all())) for x in charSheet.jumpCloneImplants: if "%d:%d" % (x.jumpCloneID, x.typeID) not in dbImplantSet: dbImplant = Implant() dbImplant.characterID = dbChar.characterID dbImplant.jumpCloneID = x.jumpCloneID dbImplant.typeID = x.typeID session.add(dbImplant) # Log line apiLog("\tUpdated characterID=%d, characterName='%s'" % (dbChar.characterID, dbChar.characterName)) # Commit all of the updates to the database session.commit() # Exceptions for our main rollback try except eveapi.Error as e: if e.code == 403: session.rollback() session.delete(api) session.commit() apiLog( "\tDeleted API as it has lost permissions we need, into the trash you go" ) else: apiLog("\tXMLAPI returned the following error: [%d] '%s'" % (e.code, e.message)) session.rollback()
def addApi(user, keyID, vCode, name, session=getSession()): try: if session.query(Api).filter(Api.keyID == keyID, Api.vCode == vCode).count() > 0: return "This API Key is already in the database" # We NEED APIKeyInfo, AccountStatus, CharacterSheet and AssetList eveapi.set_user_agent("eveapi.py/1.3") eve = eveapi.EVEAPIConnection() try: keyInfo = eve.account.APIKeyInfo(keyID=keyID, vCode=vCode) if keyInfo.key.type == "Corporation": return "This is a corp API, it's need to be a Character or Account API" except eveapi.Error as e: return "This API key is invalid or expired" try: accStatus = eve.account.AccountStatus(keyID=keyID, vCode=vCode) apiChar = eve.char.CharacterSheet( keyID=keyID, vCode=vCode, characterID=keyInfo.key.characters[0].characterID) assetList = eve.char.AssetList( keyID=keyID, vCode=vCode, characterID=keyInfo.key.characters[0].characterID, flat=1) charInfo = eve.eve.CharacterInfo( keyID=keyID, vCode=vCode, characterID=keyInfo.key.characters[0].characterID) except eveapi.Error as e: return "Your API key doesn't have enough permissions, at minimum it needs to be an active key with AccountStatus and CharacterInfo" # Build the key object api = Api() api.userId = user.id api.keyID = keyID api.vCode = vCode api.accessMask = keyInfo.key.accessMask api.type = keyInfo.key.type api.paidUntil = datetime.datetime.fromtimestamp(accStatus.paidUntil) api.createDate = datetime.datetime.fromtimestamp(accStatus.createDate) api.logonCount = accStatus.logonCount api.logonMinutes = accStatus.logonMinutes api.name = name api.lastUpdated = datetime.datetime.now() api.added = datetime.datetime.now() session.add(api) session.commit() # Now update the api key updateApiKey(session=session, api=api) return api except eveapi.Error as e: session.rollback() return "An error occurred on the EVE API, it's probably not your fault, try again later" except Exception as e: session.rollback() return "An error occurred querying this key: %s" % str(e)
def buildReport(sqlFile="candidate_US.sql", outFile="candidates.csv"): api = eveapi.EVEAPIConnection() NPC_corps = [] query_command = open(sqlFile, 'r').read() cursor.execute("SELECT corporationID FROM crpnpccorporations") for row in cursor.fetchall(): NPC_corps.append(int(row[0])) cursor.execute(query_command) results = cursor.fetchall() report_data = [] report_header = ("characterName", "characterID", "current corp", "kills", "losses", "latest activity", "zkb address", "total solo", "total kills", "total losses", "birthday", "estimated age (mo)", "total age (mo)") report_data.append(report_header) for character_entry in results: #report_line = [] character_id = character_entry[0] losses = character_entry[1] kills = character_entry[2] latest_activity = character_entry[3] character_info = api.eve.CharacterInfo(characterID=character_id) character_name = character_info.characterName corporation_name = character_info.corporation corp_history = character_info.employmentHistory #parse corp history to estimate character age total_age = 0 estimated_age = 0 print "%s:%s" % (character_id, datetime.fromtimestamp( character_info.corporationDate)) earliest_corp_date = datetime.fromtimestamp( character_info.corporationDate) previous_corp_date = earliest_corp_date for corpinfo in corp_history: join_date = datetime.fromtimestamp(corpinfo.startDate) corp_id = int(corpinfo.corporationID) if corp_id in NPC_corps: previous_corp_date = join_date if join_date < previous_corp_date: earliest_corp_date = join_date continue else: delta = previous_corp_date - join_date if join_date < previous_corp_date: earliest_corp_date = join_date previous_corp_date = join_date if delta.days > corp_length_ceiling: #6mo corp life? Assume inactive estimated_age += corp_length_ceiling continue estimated_age += delta.days total_time = datetime.utcnow() - earliest_corp_date total_age = round(total_time.days / 30) #months estimated_age = round(estimated_age / 30) #months birthday = earliest_corp_date.strftime("%Y-%m-%d") #Fetch individual kill stats query_length = datetime.utcnow() - timedelta(weeks=52) characterQuery = zkb.Query(query_length.strftime("%Y-%m-%d")) characterQuery.api_only characterQuery.characterID(int(character_id)) total_kills = 0 total_losses = 0 for zkbreturn in characterQuery: print "%s: fetching kills for %s" % (time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime()), character_name) for kill in zkbreturn: if int(kill["victim"]["characterID"]) == int(character_id): total_losses += 1 else: total_kills += 1 characterSoloQuery = zkb.Query(query_length.strftime("%Y-%m-%d")) characterSoloQuery.api_only characterSoloQuery.characterID(int(character_id)) characterSoloQuery.solo characterSoloQuery.kills solo_kills = 0 for zkbsolo in characterSoloQuery: solo_kills += len(zkbsolo) report_line = (character_name, character_id, corporation_name, kills, losses, latest_activity, "https://zkillboard.com/character/%s/" % character_id, solo_kills, total_kills, total_losses, birthday, estimated_age, total_age) report_data.append(report_line) result_file = open(outFile, 'w') for row in report_data: row_str = ','.join(str(item) for item in row) result_file.write("%s\n" % row_str)
import ConfigParser import eve_characters from eveapi import eveapi #import eveapi conf = ConfigParser.ConfigParser() conf.read(["init.ini","tmp_init.ini"]) api_file = conf.get("EVE_ACCOUNTS","api_list") backup_path = conf.get("EVE_ACCOUNTS","char_backup_path") api_basepath = conf.get("GLOBALS","api_basepath") user_agent = conf.get("GLOBALS","user_agent") api = eveapi.EVEAPIConnection() class KeyInfo: def __init__ (self,keyID,vCode): self.keyID = keyID self.vCode = vCode self.accessMask = 0 self.type = "" self.expires = "" self.auth=api.auth(keyID = self.keyID, vCode = self.vCode) self.fetch_keyInfo() def fetch_keyInfo(self): apiauth = self.auth try: apikeyinfo = apiauth.account.APIKeyInfo() except eveapi.Error, e: #regular eveapi errors