def journal_entry(cmdr, is_beta, system, station, entry, state): if this.system != system: this.system = system write_file('EDMC System.txt', this.system) if 'StarPos' in entry and this.starpos != tuple(entry['StarPos']): this.starpos = tuple(entry['StarPos']) write_file( 'EDMC StarPos.txt', '%s %s %s' % (Locale.stringFromNumber(this.starpos[0], 5), Locale.stringFromNumber(this.starpos[1], 5), Locale.stringFromNumber(this.starpos[2], 5))) if this.station != station: this.station = station write_file('EDMC Station.txt', this.station) if entry['event'] in [ 'FSDJump', 'LeaveBody', 'Location', 'SupercruiseEntry', 'SupercruiseExit' ] and entry.get('BodyType') in [None, 'Station']: if this.body: this.body = None write_file('EDMC Body.txt') elif 'Body' in entry: # StartUp, ApproachBody, Location, SupercruiseExit if this.body != entry['Body']: this.body = entry['Body'] write_file('EDMC Body.txt', this.body) elif entry['event'] == 'StartUp': this.body = None write_file('EDMC Body.txt') if this.stationorbody != (this.station or this.body): this.stationorbody = (this.station or this.body) write_file('EDMC Station or Body.txt', this.stationorbody) if this.stationorbodyorsystem != (this.station or this.body or this.system): this.stationorbodyorsystem = (this.station or this.body or this.system) write_file('EDMC Station or Body or System.txt', this.stationorbodyorsystem) if this.shiptype != state['ShipType']: this.shiptype = state['ShipType'] write_file('EDMC ShipType.txt', ship_map.get(this.shiptype, this.shiptype)) if this.shipname != (state['ShipName'] or this.shiptype): this.shipname = (state['ShipName'] or this.shiptype) write_file( 'EDMC ShipName.txt', state['ShipName'] and state['ShipName'] or ship_map.get(this.shiptype, this.shiptype)) if this.shipident != state['ShipIdent']: this.shipident = state['ShipIdent'] write_file('EDMC ShipID.txt', ship_map.get(this.shipident, this.shipident))
def ships(data): ships = companion.listify(data.get('ships')) current = data['commander'].get('currentShipId') if isinstance(current, int) and ships[current]: ships.insert(0, ships.pop(current)) # Put current ship first if not data['commander'].get('docked'): # Set current system, not last docked return [ [ship_map.get(ships[0]['name'].lower(), ships[0]['name']), data['lastSystem']['name'], ''] ] + [ [ship_map.get(ship['name'].lower(), ship['name']), ship['starsystem']['name'], ship['station']['name']] for ship in ships[1:] if ship] return [ [ship_map.get(ship['name'].lower(), ship['name']), ship['starsystem']['name'], ship['station']['name']] for ship in ships if ship]
def ships(data): ships = companion.listify(data.get('ships')) current = data['commander'].get('currentShipId') if isinstance(current, int) and current < len(ships) and ships[current]: ships.insert(0, ships.pop(current)) # Put current ship first if not data['commander'].get('docked'): # Set current system, not last docked return ([ (str(ships[0]['id']), ship_map.get(ships[0]['name'].lower(), ships[0]['name']), ships[0].get('shipName', ''), data['lastSystem']['name'], '', credits(ships[0]['value']['total'])) ] + [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], credits(ship['value']['total'])) for ship in ships[1:] if ship]) return [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], credits(ship['value']['total'])) for ship in ships if ship]
def export_ship(self, filename=None): string = json.dumps(self.ship(False), ensure_ascii=False, indent=2, separators=(',', ': ')).encode('utf-8') # pretty print if filename: with open(filename, 'wt') as h: h.write(string) return ship = self.state['ShipName'] or ship_map.get(self.state['ShipType'], self.state['ShipType']) regexp = re.compile( re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted( [x for x in listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join( config.get('outdir'), '%s.%s.txt' % (ship, strftime('%Y-%m-%dT%H.%M.%S', localtime(time())))) with open(filename, 'wt') as h: h.write(string)
def export(data): def elapsed(game_time): return '%3d:%02d:%02d' % ((game_time // 3600) % 3600, (game_time // 60) % 60, game_time % 60) querytime = config.getint('querytime') or int(time.time()) openlog() commodities = defaultdict(int) for item in data['ship'].get('cargo', {}).get('items', []): if item['commodity'] != 'drones': commodities[commodity_map.get(item['commodity'], item['commodity'])] += item['qty'] logfile.write( '%s,%s,%s,%s,%s,%s\r\n' % (time.strftime('%Y-%m-%d', time.localtime(querytime)), time.strftime('%H:%M:%S', time.localtime(querytime)), data['lastSystem']['name'], data['commander']['docked'] and data['lastStarport']['name'] or '', ship_map.get(data['ship']['name'], data['ship']['name']), ','.join( [('%d %s' % (commodities[k], k)) for k in sorted(commodities)]))) logfile.flush()
def updateshipyard(self, entry: Dict[str, Any], state: Dict[str,Any]) -> None: logger.trace("Updating Shipyard") keep: List[Optional[int]] = [] # Update the current ship shipid: str = str(state["ShipID"]) loadout: Optional[Dict[str, Any]] = None n: str = "" if shipid in self.shipdata.keys(): loadout = self.shipdata[shipid]["loadout"] n = self.shipdata[shipid]["Name"] if "ShipName" in state.keys() and state["ShipName"]: n = state["ShipName"] elif "ShipType" in state.keys() and (not n or n == state["ShipType"]): n = ship_map.get(state["ShipType"].lower(), state["ShipType"]) elif not n: n = "Unknown" logger.debug("Unknown Ship Name/Type") logger.debug(s) self.shipdata[shipid] = {"Name":n,"loadout":loadout} keep.append(shipid) # Update all local and remote ships from the journal entry for s in (entry["ShipsHere"] + entry["ShipsRemote"]): loadout = None shipid = str(s["ShipID"]) n = "" if shipid in self.shipdata.keys(): loadout = self.shipdata[shipid]["loadout"] n = self.shipdata[shipid]["Name"] if "Name" in s.keys() and s["Name"]: n = s["Name"] elif "ShipType" in s.keys() and (not n or n == s["ShipType"]): n = ship_map.get(s["ShipType"].lower(), s["ShipType"]) elif not n: n = "Unknown" logger.debug("Unknown Ship Name/Type") logger.debug(s) self.shipdata[shipid] = {"Name":n,"loadout":loadout} keep.append(shipid) # Remove any extra entries that the shipyard + state didn't contain self.shipdata = dict([(k,v) for k,v in self.shipdata.items() if k in set(keep)]) self.updateships() self.saveshipdata()
def ships(data): ships = companion.listify(data.get("ships")) current = data["commander"].get("currentShipId") if isinstance(current, int) and ships[current]: ships.insert(0, ships.pop(current)) # Put current ship first if not data["commander"].get("docked"): # Set current system, not last docked return [[ship_map.get(ships[0]["name"].lower(), ships[0]["name"]), data["lastSystem"]["name"], ""]] + [ [ship_map.get(ship["name"].lower(), ship["name"]), ship["starsystem"]["name"], ship["station"]["name"]] for ship in ships[1:] if ship ] return [ [ship_map.get(ship["name"].lower(), ship["name"]), ship["starsystem"]["name"], ship["station"]["name"]] for ship in ships if ship ]
def cmdr_data(data): timestamp = config.getint('querytime') or int(time.time()) commodities = defaultdict(int) for item in data['ship'].get('cargo', {}).get('items', []): if item['commodity'] != 'drones': commodities[item['commodity']] += item['qty'] writelog(timestamp, data['lastSystem']['name'], data['commander']['docked'] and data['lastStarport']['name'], ship_map.get(data['ship']['name'].lower(), data['ship']['name']), commodities)
def export(data): querytime = config.getint("querytime") or int(time.time()) commodities = defaultdict(int) for item in data["ship"].get("cargo", {}).get("items", []): if item["commodity"] != "drones": commodities[commodity_map.get(item["commodity"], item["commodity"])] += item["qty"] writelog( querytime, data["lastSystem"]["name"], data["commander"]["docked"] and data["lastStarport"]["name"], ship_map.get(data["ship"]["name"].lower(), data["ship"]["name"]), commodities, )
def updateloadout(self, entry: Dict[str, Any], state: Dict[str,Any]) -> None: logger.trace("Updating loadout") shipid = str(entry["ShipID"]) n: str = "" if shipid in self.shipdata.keys(): n = self.shipdata[shipid]["Name"] if "ShipName" in state.keys() and state["ShipName"]: n = state["ShipName"] elif "ShipName" in state.keys() and not n: n = ship_map.get(state["ShipType"], state["ShipType"]) self.shipdata[shipid] = {"Name": n, "loadout": entry} # Cleanup the placeholder if it's still there, and we've just added a new ship. if shipid != "0" and "0" in self.shipdata.keys() and self.shipdata["0"]["Name"] == self.shipdata_default["0"]["Name"]: del self.shipdata["0"] self.updateships() self.saveshipdata()
def export(data, filename): querytime = config.getint('querytime') or int(time.time()) assert data['lastSystem'].get('name') assert data['lastStarport'].get('name') assert data['lastStarport'].get('ships') header = 'System,Station,Ship,FDevID,Date\n' rowheader = '%s,%s' % (data['lastSystem']['name'], data['lastStarport']['name']) h = open(filename, 'wt') h.write(header) for (name,fdevid) in [(ship_map.get(ship['name'].lower(), ship['name']), ship['id']) for ship in (data['lastStarport']['ships'].get('shipyard_list') or {}).values() + data['lastStarport']['ships'].get('unavailable_list')]: h.write('%s,%s,%s,%s\n' % (rowheader, name, fdevid, data['timestamp'])) h.close()
def export(data): def elapsed(game_time): return '%3d:%02d:%02d' % ((game_time // 3600) % 3600, (game_time // 60) % 60, game_time % 60) querytime = config.getint('querytime') or int(time.time()) openlog() logfile.write('%s,%s,%s,%s,%s,%s\r\n' % ( time.strftime('%Y-%m-%d', time.localtime(querytime)), time.strftime('%H:%M:%S', time.localtime(querytime)), data['lastSystem']['name'], data['commander']['docked'] and data['lastStarport']['name'] or '', ship_map.get(data['ship']['name'], data['ship']['name']), ','.join([('%d %s' % (x['qty'], commodity_map.get(x['commodity'],x['commodity']))) for x in data['ship']['cargo']['items'] if x['commodity']!='drones']))) logfile.flush()
def addships(data): if not data['lastStarport'].get('ships'): return shipfile = 'shipyard.csv' ships = {} # slurp existing if isfile(shipfile): with open(shipfile) as csvfile: reader = csv.DictReader(csvfile) for row in reader: ships[int(row['id'])] = row['name'] # index by int for easier lookup and sorting size_pre = len(ships) for ship in (data['lastStarport']['ships'].get('shipyard_list') or {}).values() + data['lastStarport']['ships'].get('unavailable_list'): # sanity check key = ship['id'] new = ship_map.get(ship['name'].lower()) if new: old = ships.get(int(key)) if old: # check consistency with existing data if new != old: raise AssertionError('%s: "%s"!="%s"' % (key, new, old)) else: ships[int(key)] = new if len(ships) > size_pre: if isfile(shipfile): if isfile(shipfile+'.bak'): os.unlink(shipfile+'.bak') os.rename(shipfile, shipfile+'.bak') with open(shipfile, 'wb') as csvfile: writer = csv.DictWriter(csvfile, ['id', 'name']) writer.writeheader() for key in sorted(ships): row = { 'id': key, 'name': ships[key] } writer.writerow(row) print 'Added %d new ships' % (len(ships) - size_pre)
def export(data, filename): querytime = config.getint('querytime') or int(time.time()) assert data['lastSystem'].get('name') assert data['lastStarport'].get('name') assert data['lastStarport'].get('ships') header = 'System,Station,Ship,FDevID,Date\n' rowheader = '%s,%s' % (data['lastSystem']['name'], data['lastStarport']['name']) h = open(filename, 'wt') h.write(header) for (name, fdevid) in [ (ship_map.get(ship['name'].lower(), ship['name']), ship['id']) for ship in list((data['lastStarport']['ships'].get( 'shipyard_list') or {}).values()) + data['lastStarport']['ships'].get('unavailable_list') ]: h.write('%s,%s,%s,%s\n' % (rowheader, name, fdevid, data['timestamp'])) h.close()
def export(data): def elapsed(game_time): return '%3d:%02d:%02d' % ((game_time // 3600) % 3600, (game_time // 60) % 60, game_time % 60) querytime = config.getint('querytime') or int(time.time()) openlog() commodities = defaultdict(int) for item in data['ship'].get('cargo',{}).get('items',[]): if item['commodity'] != 'drones': commodities[commodity_map.get(item['commodity'], item['commodity'])] += item['qty'] logfile.write('%s,%s,%s,%s,%s,%s\r\n' % ( time.strftime('%Y-%m-%d', time.localtime(querytime)), time.strftime('%H:%M:%S', time.localtime(querytime)), data['lastSystem']['name'], data['commander']['docked'] and data['lastStarport']['name'] or '', ship_map.get(data['ship']['name'], data['ship']['name']), ','.join([('%d %s' % (commodities[k], k)) for k in sorted(commodities)]))) logfile.flush()
def lookup(module): # if not module.get('category'): raise AssertionError('%s: Missing category' % module['id']) # only present post 1.3, and not present in ship loadout if not module.get('name'): raise AssertionError('%s: Missing name' % module['id']) name = module['name'].split('_') new = {} # Armour - e.g. Federation_Dropship_Armour_Grade2 if name[-2] == 'Armour': name = module['name'].rsplit('_', 2) # Armour is ship-specific, and ship names can have underscores new['category'] = 'standard' new['name'] = armour_map[name[2]] new['ship'] = ship_map.get(name[0], name[0]) new['class'] = '1' new['rating'] = 'I' # Skip uninteresting stuff elif name[0].lower() in ['decal', 'paintjob']: # Have seen "paintjob" and "PaintJob" return None # Skip PP-specific modules in outfitting which have an sku like ELITE_SPECIFIC_V_POWER_100100 elif module.get('category') == 'powerplay': return None # Shouldn't be listing player-specific paid stuff elif module.get('sku'): raise AssertionError('%s: Unexpected sku "%s"' % (module['id'], module['sku'])) # Hardpoints - e.g. Hpt_Slugshot_Fixed_Medium elif name[0]=='Hpt' and name[1] in weapon_map: if name[2] not in weaponmount_map: raise AssertionError('%s: Unknown weapon mount "%s"' % (module['id'], name[2])) if name[3] not in weaponclass_map: raise AssertionError('%s: Unknown weapon class "%s"' % (module['id'], name[3])) new['category'] = 'hardpoint' if len(name)>4: if name[4] in weaponoldvariant_map: # Old variants e.g. Hpt_PulseLaserBurst_Turret_Large_OC new['name'] = weapon_map[name[1]] + ' ' + weaponoldvariant_map[name[4]] new['rating'] = '?' else: # PP faction-specific weapons e.g. Hpt_Slugshot_Fixed_Large_Range new['name'] = weapon_map[(name[1],name[4])] new['rating'] = weaponrating_map.get(('_').join(name[:4]), '?') # assumes same rating as base weapon else: new['name'] = weapon_map[name[1]] new['rating'] = weaponrating_map.get(module['name'], '?') # no obvious rule - needs lookup table new['mount'] = weaponmount_map[name[2]] if name[1] in missiletype_map: # e.g. Hpt_DumbfireMissileRack_Fixed_Small new['guidance'] = missiletype_map[name[1]] new['class'] = weaponclass_map[name[3]] # Utility - e.g. Hpt_CargoScanner_Size0_Class1 elif name[0]=='Hpt' and name[1] in utility_map: new['category'] = 'utility' new['name'] = utility_map[len(name)>4 and (name[1],name[4]) or name[1]] if name[-1] in weaponclass_map: # e.g. Hpt_PlasmaPointDefence_Turret_Tiny new['class'] = weaponclass_map[name[-1]] new['rating'] = 'I' else: if not name[2].startswith('Size') or not name[3].startswith('Class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] elif name[0]=='Hpt': raise AssertionError('%s: Unknown weapon "%s"' % (module['id'], name[1])) # Stellar scanners - e.g. Int_StellarBodyDiscoveryScanner_Standard elif name[1] in ['StellarBodyDiscoveryScanner', 'DetailedSurfaceScanner']: new['category'] = 'internal' new['name'], new['rating'] = stellar_map[name[2]] new['class'] = '1' # Docking Computer - e.g. Int_DockingComputer_Standard elif name[1] == 'DockingComputer' and name[2] == 'Standard': new['category'] = 'internal' new['name'] = 'Standard Docking Computer' new['class'] = '1' new['rating'] = 'E' # Standard & Internal else: # Reported category is not necessarily helpful. e.g. "Int_DockingComputer_Standard" has category "utility" if name[0] != 'Int': raise AssertionError('%s: Unknown prefix "%s"' % (module['id'], name[0])) if name[1] == 'DroneControl': # e.g. Int_DroneControl_Collection_Size1_Class1 name.pop(0) if name[1] in standard_map: # e.g. Int_Engine_Size2_Class1 new['category'] = 'standard' new['name'] = standard_map[len(name)>4 and (name[1],name[4]) or name[1]] elif name[1] in internal_map: # e.g. Int_CargoRack_Size8_Class1 new['category'] = 'internal' new['name'] = internal_map[len(name)>4 and (name[1],name[4]) or name[1]] else: raise AssertionError('%s: Unknown module "%s"' % (module['id'], name[1])) if not name[2].startswith('Size') or not name[3].startswith('Class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] # check we've filled out mandatory fields for thing in ['category', 'name', 'class', 'rating']: if not new.get('name'): raise AssertionError('%s: failed to set %s' % (module['id'], thing)) return new
def lookup(module): # if not module.get('category'): raise AssertionError('%s: Missing category' % module['id']) # only present post 1.3, and not present in ship loadout if not module.get('name'): raise AssertionError('%s: Missing name' % module['id']) name = module['name'].split('_') new = {} # Armour - e.g. Federation_Dropship_Armour_Grade2 if name[-2] == 'Armour': name = module['name'].rsplit( '_', 2) # Armour is ship-specific, and ship names can have underscores new['category'] = 'standard' new['name'] = armour_map[name[2]] new['ship'] = ship_map.get(name[0], name[0]) new['class'] = '1' new['rating'] = 'I' # Skip uninteresting stuff elif name[0].lower() in ['decal', 'paintjob' ]: # Have seen "paintjob" and "PaintJob" return None # Shouldn't be listing player-specific paid stuff elif module.get('sku'): raise AssertionError('%s: Unexpected sku "%s"' % (module['id'], module['sku'])) # Hardpoints - e.g. Hpt_Slugshot_Fixed_Medium elif name[0] == 'Hpt' and name[1] in weapon_map: # Skip PP faction-specific weapons e.g. Hpt_Slugshot_Fixed_Large_Range if len(name) > 4: raise AssertionError('%s: Skipping weapon variant "%s"' % (module['id'], name[4])) if name[2] not in weaponmount_map: raise AssertionError('%s: Unknown weapon mount "%s"' % (module['id'], name[2])) if name[3] not in weaponclass_map: raise AssertionError('%s: Unknown weapon class "%s"' % (module['id'], name[3])) # if module['name'] not in weaponrating_map: raise AssertionError('%s: Unknown rating for this weapon' % module['id']) new['category'] = 'hardpoint' new['name'] = weapon_map[name[1]] new['mount'] = weaponmount_map[name[2]] if name[1] in missiletype_map: # e.g. Hpt_DumbfireMissileRack_Fixed_Small new['guidance'] = missiletype_map[name[1]] new['class'] = weaponclass_map[name[3]] new['rating'] = weaponrating_map.get( module['name'], '?') # no obvious rule - needs lookup table # Utility - e.g. Hpt_CargoScanner_Size0_Class1 elif name[0] == 'Hpt' and name[1] in utility_map: # Skip PP faction-specific modules (none atm) if len(name) > 4: raise AssertionError('%s: Skipping utility variant "%s"' % (module['id'], name[4])) new['category'] = 'utility' new['name'] = utility_map[name[1]] if name[-1] in weaponclass_map: # e.g. Hpt_PlasmaPointDefence_Turret_Tiny new['class'] = weaponclass_map[name[-1]] new['rating'] = 'I' else: if not name[2].startswith('Size') or not name[3].startswith( 'Class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] elif name[0] == 'Hpt': raise AssertionError('%s: Unknown weapon "%s"' % (module['id'], name[1])) # Stellar scanners - e.g. Int_StellarBodyDiscoveryScanner_Standard elif name[1] in ['StellarBodyDiscoveryScanner', 'DetailedSurfaceScanner']: new['category'] = 'internal' new['name'], new['rating'] = stellar_map[name[2]] new['class'] = '1' # Docking Computer - e.g. Int_DockingComputer_Standard elif name[1] == 'DockingComputer' and name[2] == 'Standard': new['category'] = 'internal' new['name'] = 'Standard Docking Computer' new['class'] = '1' new['rating'] = 'E' # Standard & Internal else: # Reported category is not necessarily helpful. e.g. "Int_DockingComputer_Standard" has category "utility" if name[0] != 'Int': raise AssertionError('%s: Unknown prefix "%s"' % (module['id'], name[0])) if name[1] == 'DroneControl': # e.g. Int_DroneControl_Collection_Size1_Class1 name.pop(0) # Skip PP faction-specific modules e.g. Int_ShieldGenerator_Size1_Class5_Strong if len(name) > 4: raise AssertionError('%s: Skipping module variant "%s"' % (module['id'], name[4])) if name[1] in standard_map: # e.g. Int_Engine_Size2_Class1 new['category'] = 'standard' new['name'] = standard_map[name[1]] elif name[1] in internal_map: # e.g. Int_CargoRack_Size8_Class1 new['category'] = 'internal' new['name'] = internal_map[name[1]] else: raise AssertionError('%s: Unknown module "%s"' % (module['id'], name[1])) if not name[2].startswith('Size') or not name[3].startswith('Class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] # check we've filled out mandatory fields for thing in ['category', 'name', 'class', 'rating']: if not new.get('name'): raise AssertionError('%s: failed to set %s' % (module['id'], thing)) return new
def lookup(module): # if not module.get('category'): raise AssertionError('%s: Missing category' % module['id']) # only present post 1.3, and not present in ship loadout if not module.get('name'): raise AssertionError('%s: Missing name' % module['id']) name = module['name'].lower().split('_') new = {} # Armour - e.g. Federation_Dropship_Armour_Grade2 if name[-2] == 'armour': name = module['name'].lower().rsplit( '_', 2) # Armour is ship-specific, and ship names can have underscores new['category'] = 'standard' new['name'] = armour_map[name[2]] new['ship'] = ship_map.get(name[0], name[0]) new['class'] = '1' new['rating'] = 'I' # Skip uninteresting stuff elif name[0] in ['decal', 'paintjob']: return None # Skip PP-specific modules in outfitting which have an sku like ELITE_SPECIFIC_V_POWER_100100 elif 'category' in module and module['category'].lower() == 'powerplay': return None # Shouldn't be listing player-specific paid stuff elif module.get('sku'): raise AssertionError('%s: Unexpected sku "%s"' % (module['id'], module['sku'])) # Hardpoints - e.g. Hpt_Slugshot_Fixed_Medium elif name[0] == 'hpt' and name[1] in weapon_map: if name[2] not in weaponmount_map: raise AssertionError('%s: Unknown weapon mount "%s"' % (module['id'], name[2])) if name[3] not in weaponclass_map: raise AssertionError('%s: Unknown weapon class "%s"' % (module['id'], name[3])) new['category'] = 'hardpoint' if len(name) > 4: if name[4] in weaponoldvariant_map: # Old variants e.g. Hpt_PulseLaserBurst_Turret_Large_OC new['name'] = weapon_map[name[1]] + ' ' + weaponoldvariant_map[ name[4]] new['rating'] = '?' else: # PP faction-specific weapons e.g. Hpt_Slugshot_Fixed_Large_Range new['name'] = weapon_map[(name[1], name[4])] new['rating'] = weaponrating_map.get( ('_').join(name[:4]), '?') # assumes same rating as base weapon else: new['name'] = weapon_map[name[1]] new['rating'] = weaponrating_map.get( module['name'].lower(), '?') # no obvious rule - needs lookup table new['mount'] = weaponmount_map[name[2]] if name[1] in missiletype_map: # e.g. Hpt_DumbfireMissileRack_Fixed_Small new['guidance'] = missiletype_map[name[1]] new['class'] = weaponclass_map[name[3]] # Countermeasures - e.g. Hpt_PlasmaPointDefence_Turret_Tiny elif name[0] == 'hpt' and name[1] in countermeasure_map: new['category'] = 'utility' new['name'], new['rating'] = countermeasure_map[ len(name) > 4 and (name[1], name[4]) or name[1]] new['class'] = weaponclass_map[name[-1]] # Utility - e.g. Hpt_CargoScanner_Size0_Class1 elif name[0] == 'hpt' and name[1] in utility_map: new['category'] = 'utility' new['name'] = utility_map[len(name) > 4 and (name[1], name[4]) or name[1]] if not name[2].startswith('size') or not name[3].startswith('class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] elif name[0] == 'hpt': raise AssertionError('%s: Unknown weapon "%s"' % (module['id'], name[1])) # Stellar scanners - e.g. Int_StellarBodyDiscoveryScanner_Standard elif name[1] in ['stellarbodydiscoveryscanner', 'detailedsurfacescanner']: new['category'] = 'internal' new['name'], new['rating'] = stellar_map[name[2]] new['class'] = '1' # Docking Computer - e.g. Int_DockingComputer_Standard elif name[1] == 'dockingcomputer' and name[2] == 'standard': new['category'] = 'internal' new['name'] = 'Standard Docking Computer' new['class'] = '1' new['rating'] = 'E' # Standard & Internal else: # Reported category is not necessarily helpful. e.g. "Int_DockingComputer_Standard" has category "utility" if name[0] != 'int': raise AssertionError('%s: Unknown prefix "%s"' % (module['id'], name[0])) if name[1] == 'dronecontrol': # e.g. Int_DroneControl_Collection_Size1_Class1 name.pop(0) if name[1] in standard_map: # e.g. Int_Engine_Size2_Class1 new['category'] = 'standard' new['name'] = standard_map[len(name) > 4 and (name[1], name[4]) or name[1]] elif name[1] in internal_map: # e.g. Int_CargoRack_Size8_Class1 new['category'] = 'internal' new['name'] = internal_map[len(name) > 4 and (name[1], name[4]) or name[1]] else: raise AssertionError('%s: Unknown module "%s"' % (module['id'], name[1])) if not name[2].startswith('size') or not name[3].startswith('class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) new['class'] = name[2][4:] new['rating'] = rating_map[name[3][5:]] # Disposition of fitted modules if 'on' in module and 'priority' in module: new['enabled'], new['priority'] = module['on'], module[ 'priority'] # priority is zero-based # check we've filled out mandatory fields for thing in ['category', 'name', 'class', 'rating']: if not new.get(thing): raise AssertionError('%s: failed to set %s' % (module['id'], thing)) if new['category'] == 'hardpoint' and not new.get('mount'): raise AssertionError('%s: failed to set %s' % (module['id'], 'mount')) return new
def export(data): def send(msg): r = requests.post(upload, data=json.dumps(msg), timeout=timeout) if __debug__ and r.status_code != requests.codes.ok: print 'Status\t%s' % r.status_code print 'URL\t%s' % r.url print 'Headers\t%s' % r.headers print ('Content:\n%s' % r.text).encode('utf-8') r.raise_for_status() querytime = config.getint('querytime') or int(time.time()) header = { 'softwareName' : '%s [%s]' % (applongname, platform=='darwin' and "Mac OS" or system()), 'softwareVersion' : appversion, 'uploaderID' : config.getint('anonymous') and hashlib.md5(data['commander']['name'].strip().encode('utf-8')).hexdigest() or data['commander']['name'].strip(), } # Don't send empty commodities list - schema won't allow it if data['lastStarport'].get('commodities'): commodities = [] for commodity in data['lastStarport'].get('commodities', []): commodities.append({ 'name' : commodity['name'], 'buyPrice' : commodity['buyPrice'], 'supply' : int(commodity['stock']), 'sellPrice' : commodity['sellPrice'], 'demand' : int(commodity['demand']), }) if commodity['stockBracket']: commodities[-1]['supplyLevel'] = bracketmap[commodity['stockBracket']] if commodity['demandBracket']: commodities[-1]['demandLevel'] = bracketmap[commodity['demandBracket']] send({ '$schemaRef' : 'http://schemas.elite-markets.net/eddn/commodity/2', 'header' : header, 'message' : { 'systemName' : data['lastSystem']['name'].strip(), 'stationName' : data['lastStarport']['name'].strip(), 'timestamp' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), 'commodities' : commodities, } }) # EDDN doesn't yet accept an outfitting schema # # *Do* send empty modules list - implies station has no outfitting # modules = [] # for v in data['lastStarport'].get('modules', {}).itervalues(): # try: # module = outfitting.lookup(v) # if module: # modules.append(module) # except AssertionError as e: # if __debug__: print 'Outfitting: %s' % e # Silently skip unrecognized modules # except: # if __debug__: raise # send({ # '$schemaRef' : 'http://schemas.elite-markets.net/eddn/outfitting/1', # 'header' : header, # 'message' : { # 'systemName' : data['lastSystem']['name'].strip(), # 'stationName' : data['lastStarport']['name'].strip(), # 'timestamp' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), # 'modules' : modules, # } # }) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. if data['lastStarport'].get('ships'): send({ '$schemaRef' : 'http://schemas.elite-markets.net/eddn/shipyard/1', 'header' : header, 'message' : { 'systemName' : data['lastSystem']['name'].strip(), 'stationName' : data['lastStarport']['name'].strip(), 'timestamp' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), 'ships' : [ship_map.get(ship['name'],ship['name']) for ship in (data['lastStarport']['ships'].get('shipyard_list') or {}).values() + data['lastStarport']['ships'].get('unavailable_list')], } })
def lookup(module): # if not module.get('category'): raise AssertionError('%s: Missing category' % module['id']) # only present post 1.3, and not present in ship loadout if not module.get("name"): raise AssertionError("%s: Missing name" % module["id"]) name = module["name"].split("_") new = {} # Armour - e.g. Federation_Dropship_Armour_Grade2 if name[-2] == "Armour": name = module["name"].rsplit("_", 2) # Armour is ship-specific, and ship names can have underscores new["category"] = "standard" new["name"] = armour_map[name[2]] new["ship"] = ship_map.get(name[0], name[0]) new["class"] = "1" new["rating"] = "I" # Skip uninteresting stuff elif name[0].lower() in ["decal", "paintjob"]: # Have seen "paintjob" and "PaintJob" return None # Shouldn't be listing player-specific paid stuff elif module.get("sku"): raise AssertionError('%s: Unexpected sku "%s"' % (module["id"], module["sku"])) # Hardpoints - e.g. Hpt_Slugshot_Fixed_Medium elif name[0] == "Hpt" and name[1] in weapon_map: # Skip PP faction-specific weapons e.g. Hpt_Slugshot_Fixed_Large_Range if len(name) > 4: raise AssertionError('%s: Skipping weapon variant "%s"' % (module["id"], name[4])) if name[2] not in weaponmount_map: raise AssertionError('%s: Unknown weapon mount "%s"' % (module["id"], name[2])) if name[3] not in weaponclass_map: raise AssertionError('%s: Unknown weapon class "%s"' % (module["id"], name[3])) # if module['name'] not in weaponrating_map: raise AssertionError('%s: Unknown rating for this weapon' % module['id']) new["category"] = "hardpoint" new["name"] = weapon_map[name[1]] new["mount"] = weaponmount_map[name[2]] if name[1] in missiletype_map: # e.g. Hpt_DumbfireMissileRack_Fixed_Small new["guidance"] = missiletype_map[name[1]] new["class"] = weaponclass_map[name[3]] new["rating"] = weaponrating_map.get(module["name"], "?") # no obvious rule - needs lookup table # Utility - e.g. Hpt_CargoScanner_Size0_Class1 elif name[0] == "Hpt" and name[1] in utility_map: # Skip PP faction-specific modules (none atm) if len(name) > 4: raise AssertionError('%s: Skipping utility variant "%s"' % (module["id"], name[4])) new["category"] = "utility" new["name"] = utility_map[name[1]] if name[-1] in weaponclass_map: # e.g. Hpt_PlasmaPointDefence_Turret_Tiny new["class"] = weaponclass_map[name[-1]] new["rating"] = "I" else: if not name[2].startswith("Size") or not name[3].startswith("Class"): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module["id"], name[2], name[3])) new["class"] = name[2][4:] new["rating"] = rating_map[name[3][5:]] elif name[0] == "Hpt": raise AssertionError('%s: Unknown weapon "%s"' % (module["id"], name[1])) # Stellar scanners - e.g. Int_StellarBodyDiscoveryScanner_Standard elif name[1] in ["StellarBodyDiscoveryScanner", "DetailedSurfaceScanner"]: new["category"] = "internal" new["name"], new["rating"] = stellar_map[name[2]] new["class"] = "1" # Docking Computer - e.g. Int_DockingComputer_Standard elif name[1] == "DockingComputer" and name[2] == "Standard": new["category"] = "internal" new["name"] = "Standard Docking Computer" new["class"] = "1" new["rating"] = "E" # Standard & Internal else: # Reported category is not necessarily helpful. e.g. "Int_DockingComputer_Standard" has category "utility" if name[0] != "Int": raise AssertionError('%s: Unknown prefix "%s"' % (module["id"], name[0])) if name[1] == "DroneControl": # e.g. Int_DroneControl_Collection_Size1_Class1 name.pop(0) # Skip PP faction-specific modules e.g. Int_ShieldGenerator_Size1_Class5_Strong if len(name) > 4: raise AssertionError('%s: Skipping module variant "%s"' % (module["id"], name[4])) if name[1] in standard_map: # e.g. Int_Engine_Size2_Class1 new["category"] = "standard" new["name"] = standard_map[name[1]] elif name[1] in internal_map: # e.g. Int_CargoRack_Size8_Class1 new["category"] = "internal" new["name"] = internal_map[name[1]] else: raise AssertionError('%s: Unknown module "%s"' % (module["id"], name[1])) if not name[2].startswith("Size") or not name[3].startswith("Class"): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module["id"], name[2], name[3])) new["class"] = name[2][4:] new["rating"] = rating_map[name[3][5:]] # check we've filled out mandatory fields for thing in ["category", "name", "class", "rating"]: if not new.get("name"): raise AssertionError("%s: failed to set %s" % (module["id"], thing)) return new
def export(data): def class_rating(module): if 'guidance' in module: return module['class'] + module['rating'] + '/' + module.get('mount', 'F')[0] + module['guidance'][0] + ' ' elif 'mount' in module: return module['class'] + module['rating'] + '/' + module['mount'][0] + ' ' else: return module['class'] + module['rating'] + ' ' querytime = config.getint('querytime') or int(time.time()) ship = ship_map.get(data['ship']['name'], data['ship']['name']) loadout = defaultdict(list) for slot in sorted(data['ship']['modules']): v = data['ship']['modules'][slot] if not v or not v.get('module'): continue try: module = outfitting.lookup(v['module']) if not module: continue except AssertionError as e: if __debug__: print 'Loadout: %s' % e continue # Silently skip unrecognized modules except: if __debug__: raise cr = class_rating(module) # Specials if module['name'] in ['Fuel Tank', 'Cargo Rack']: name = '%s (Capacity: %d)' % (module['name'], 2**int(module['class'])) else: name = module['name'] for s in slot_map: if slot.startswith(s): loadout[slot_map[s]].append(cr + name) break else: if slot.startswith('Slot'): loadout[slot[-1]].append(cr + name) elif __debug__: print 'Loadout: Unknown slot %s' % slot # Construct description string = '[%s]\n' % ship for slot in ['L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, '9', '8', '7', '6', '5', '4', '3', '2', '1']: if not slot: string += '\n' elif slot in loadout: for name in loadout[slot]: string += '%s: %s\n' % (slot, name) string += '---\nCargo : %d T\nFuel : %d T\n' % (data['ship']['cargo']['capacity'], data['ship']['fuel']['capacity']) # Look for last ship of this type regexp = re.compile(re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted([x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join(config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string)
def export(data): def send(msg): r = requests.post(upload, data=json.dumps(msg), timeout=timeout) if __debug__ and r.status_code != requests.codes.ok: print 'Status\t%s' % r.status_code print 'URL\t%s' % r.url print 'Headers\t%s' % r.headers print('Content:\n%s' % r.text).encode('utf-8') r.raise_for_status() querytime = config.getint('querytime') or int(time.time()) header = { 'softwareName': '%s [%s]' % (applongname, platform == 'darwin' and "Mac OS" or system()), 'softwareVersion': appversion, 'uploaderID': config.getint('anonymous') and hashlib.md5( data['commander']['name'].strip().encode('utf-8')).hexdigest() or data['commander']['name'].strip(), } # Don't send empty commodities list - schema won't allow it if data['lastStarport'].get('commodities'): commodities = [] for commodity in data['lastStarport'].get('commodities', []): commodities.append({ 'name': commodity['name'], 'buyPrice': commodity['buyPrice'], 'supply': int(commodity['stock']), 'sellPrice': commodity['sellPrice'], 'demand': int(commodity['demand']), }) if commodity['stockBracket']: commodities[-1]['supplyLevel'] = bracketmap[ commodity['stockBracket']] if commodity['demandBracket']: commodities[-1]['demandLevel'] = bracketmap[ commodity['demandBracket']] send({ '$schemaRef': 'http://schemas.elite-markets.net/eddn/commodity/2', 'header': header, 'message': { 'systemName': data['lastSystem']['name'].strip(), 'stationName': data['lastStarport']['name'].strip(), 'timestamp': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), 'commodities': commodities, } }) # EDDN doesn't yet accept an outfitting schema # # *Do* send empty modules list - implies station has no outfitting # modules = [] # for v in data['lastStarport'].get('modules', {}).itervalues(): # try: # module = outfitting.lookup(v) # if module: # modules.append(module) # except AssertionError as e: # if __debug__: print 'Outfitting: %s' % e # Silently skip unrecognized modules # except: # if __debug__: raise # send({ # '$schemaRef' : 'http://schemas.elite-markets.net/eddn/outfitting/1', # 'header' : header, # 'message' : { # 'systemName' : data['lastSystem']['name'].strip(), # 'stationName' : data['lastStarport']['name'].strip(), # 'timestamp' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), # 'modules' : modules, # } # }) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. if data['lastStarport'].get('ships'): send({ '$schemaRef': 'http://schemas.elite-markets.net/eddn/shipyard/1', 'header': header, 'message': { 'systemName': data['lastSystem']['name'].strip(), 'stationName': data['lastStarport']['name'].strip(), 'timestamp': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), 'ships': [ ship_map.get(ship['name'], ship['name']) for ship in data['lastStarport']['ships'].get( 'shipyard_list', {}).values() + data['lastStarport']['ships'].get('unavailable_list', []) ], } })