Python Killmail Class
From EVEDev
| Python Killmail Class | |
|---|---|
| Maintainer: | |
| Stable release: | |
| Development release: | |
| OS: | Linux, Windows |
| License: | Open-Source/Common-Use |
| Website: | |
A very simple and explicit KM parsing class in Python. It takes the raw mail loops through and assigns the information to a Kill object. Can easily be interfaced to an ORM layer for use in dynamic environments. Updated with Rev3 working example. Still parses Rev2 without issue.
''' Python Killmail Parser Killmail - Parse raw killmail, store in local kill object. Kill - user friendly representation of a kill Explicit is better; the data from the KMs in guaranteed unless malformed so no need for regex magic. Just a nice hard coded and very fast parser ''' example_mail = '''2007.10.10 10:10 Victim: John Doe Alliance: None Corp: Pator Tech School Destroyed: Armageddon System: Pator Security: 1.0 Involved parties: Name: Minmatar Sentry Gun / Republic Fleet Name: Some Guy (laid the final blow) Security: -0.3 Alliance: Alliance One Corp: Corp One Ship: Cyclone Weapon: 220mm Vulcan AutoCannon II Name: Another Guy Security: -1.3 Alliance: Alliance One Corp: Corp Two Ship: Scimitar Weapon: Hobgoblin II Name: Last Guy Security: -1.7 Alliance: Alliance One Corp: Corp Three Ship: Falcon Weapon: BZ-5 Neutralizing Spatial Destabilizer ECM Destroyed items: Mega Pulse Laser II, Qty: 4 Conflagration L, Qty: 4 Warp Disruptor II X5 Prototype I Engine Enervator Pseudoelectron Containment Field I Extruded Heat Sink I, Qty: 3 1600mm Reinforced Rolled Tungsten Plates I, Qty: 3 Cap Booster 800, Qty: 9 (Cargo) Scorch L, Qty: 4 (Cargo) Acolyte II, Qty: 4 (Drone Bay) Dropped items: Mega Pulse Laser II, Qty: 4 Conflagration L, Qty: 4 Warp Disruptor II X5 Prototype I Engine Enervator Pseudoelectron Containment Field I Extruded Heat Sink I, Qty: 3 1600mm Reinforced Rolled Tungsten Plates I, Qty: 3''' class Kill(object): '''Used by Killmail for storing a clean interface for getting kill data date: simple datetime in CCYY.MM.DD HH:MM:SS format victim: dict - keys are (name, alliance, corp, ship, system, security involved: list of dict - keys are (name, security, alliance, corp, weapon, ship, fb) destroyed_fit: list of tuple - [(item, qty),] destroyed_cargo: list of tuple - [(item,qty),] ''' def __init__(self): self.date = None self.victim = {'name':'', 'alliance':'', 'corp':'', 'ship':'', 'system':'', 'security':'', 'damage':''} self.involved = [] self.destroyed_fit = [] self.destroyed_cargo = [] self.destroyed_drone = [] self.dropped = [] def new_assailant(self): assailant = {'name':'', 'security':'', 'alliance':'', 'corp':'', 'ship':'', 'weapon':'', 'damage':'','fb':False} self.involved.append(assailant) class Killmail(object): def __init__(self, raw_killmail): self.raw_mail = raw_killmail self.kill = Kill() self.parse() def parse(self): lines = self.raw_mail.split('\n') lines = filter(self.notEmpty, lines) self.kill.date = lines[0] # get the datetime list_pos = 1 # move down position on the KM, we will use this to # to keep track of our position in the KM as we parse it # first up, the vic- for line in lines[list_pos:]: field,value = line.split(':') value = value.strip(' ') if field == 'Victim': self.kill.victim['name'] = value elif field == 'Alliance': self.kill.victim['alliance'] = value elif field == 'Corp': self.kill.victim['corp'] = value elif field == 'Destroyed': self.kill.victim['ship']= value elif field == 'Damage Taken': self.kill.victim['damage'] = value elif field == 'System': self.kill.victim['system'] = value elif field == 'Security': self.kill.victim['security'] = value else: break list_pos += 1 # ok, now for the assailants for line in lines[list_pos:]: field,value = line.split(':') value = value.lstrip(' ') if field == 'Name': self.kill.new_assailant() # little hack to deal with things like gate guns isNpc = False if not value.find('/') == -1: isNpc = True try: name, fb = value.split('(') self.kill.involved[-1]['fb'] = True if isNpc == True: npc,corp = name.split('/') self.kill.involved[-1]['name'] = npc self.kill.involved[-1]['corp'] = corp else: self.kill.involved[-1]['name'] = name.strip(' ') except ValueError: # well can't split and unpack to name and fb, but not be the fb if isNpc == True: npc,corp = value.split('/') self.kill.involved[-1]['name'] = npc self.kill.involved[-1]['corp'] = corp else: self.kill.involved[-1]['name'] = value elif field == 'Security': self.kill.involved[-1]['security'] = value elif field == 'Alliance': self.kill.involved[-1]['alliance'] = value elif field == 'Corp': self.kill.involved[-1]['corp'] = value elif field == 'Ship': self.kill.involved[-1]['ship'] = value elif field == 'Weapon': self.kill.involved[-1]['weapon'] = value elif field == 'Damage Done': self.kill.involved[-1]['damage'] = value elif field == 'Destroyed items': # trigger a break, destroyed items happens at the end of the involved list list_pos += 1 break list_pos += 1 # lets see what he lost .. tough break for line in lines[list_pos:]: if line.split(':')[0] == 'Dropped items': # ok, done with what got blow up, lets see what we got! list_pos += 1 break try: item,qty = line.split(',') if not qty.find('(Cargo)') == -1 \ or not qty.find('(Drone Bay)') == -1: qty = int(qty.split(':')[1].split('(')[0].strip(' ')) else: qty = int(qty.split(':')[1].strip(' ')) except ValueError: # we tried to unpack too few values, which means a qty of 1 item = line qty = 1 if not line.find('(Cargo)') == -1: self.kill.destroyed_cargo.append((item,qty)) elif not line.find('(Drone Bay)') == -1: self.kill.destroyed_drone.append((item,qty)) else: self.kill.destroyed_fit.append((item,qty)) list_pos += 1 # lets see what he dropped .. hooray for us for line in lines[list_pos+1:]: try: item,qty = line.split(',') if not qty.find('(Cargo)') == -1 \ or not qty.find('(Drone Bay)') == -1: qty = int(qty.split(':')[1].split('(')[0].strip(' ')) else: qty = int(qty.split(':')[1].strip(' ')) except ValueError: # we tried to unpack too few values, which means a qty of 1 item = line qty = 1 if not line.find('(Cargo)') == -1: self.kill.dropped.append((item,qty)) elif not line.find('(Drone Bay)') == -1: self.kill.dropped.append((item,qty)) else: self.kill.dropped.append((item,qty)) list_pos += 1 def notEmpty(self, c): if c == '' or c == None or c == "": return False else: return True if __name__ == '__main__': km = Killmail(example_mail) print 'Victim',km.kill.victim print 'Involved',km.kill.involved print 'Items Fit',km.kill.destroyed_fit print 'Items Cargo',km.kill.destroyed_cargo print 'Items Dronebay',km.kill.destroyed_drone print 'Items Dropped',km.kill.dropped

