Browse Source

Extend ZKill killmail data to include entity names.

master
Ben Kurtovic 6 years ago
parent
commit
9a8ddeee6f
3 changed files with 68 additions and 14 deletions
  1. +51
    -2
      calefaction/eve/zkill.py
  2. +9
    -8
      calefaction/modules/campaigns/database.py
  3. +8
    -4
      calefaction/modules/campaigns/update.py

+ 51
- 2
calefaction/eve/zkill.py View File

@@ -2,6 +2,7 @@


import time import time


from flask import g
import requests import requests


from ..exceptions import ZKillboardError from ..exceptions import ZKillboardError
@@ -20,6 +21,45 @@ class ZKillboard:
self._base_url = "https://zkillboard.com/api" self._base_url = "https://zkillboard.com/api"
self._last_query = 0 self._last_query = 0


def _extend_killmail(self, kill):
"""Extend a killmail object to match the old ZKill format.

Requires ESI API calls to fill in entity names. If we can't do them,
we'll just set the names to be empty.
"""
esi = g.eve.esi()
victim = kill["victim"]

if "character_id" in victim:
char_info = esi.v4.characters(victim["character_id"]).get()
victim["character_name"] = char_info["name"]
else:
victim["character_id"] = 0
victim["character_name"] = ""

if "corporation_id" in victim:
corp_info = esi.v3.corporations(victim["corporation_id"]).get()
victim["corporation_name"] = corp_info["corporation_name"]
else:
victim["corporation_id"] = 0
victim["corporation_name"] = ""

if "alliance_id" in victim:
alliance_info = esi.v2.alliances(victim["alliance_id"]).get()
victim["alliance_name"] = alliance_info["alliance_name"]
else:
victim["alliance_id"] = 0
victim["alliance_name"] = ""

if "faction_id" in victim:
factions = esi.v1.universe.factions.get()
matches = [fac["faction_name"] for fac in factions
if fac["faction_id"] == victim["faction_id"]]
victim["faction_name"] = matches[0] if matches else ""
else:
victim["faction_id"] = 0
victim["faction_name"] = ""

def query(self, *args): def query(self, *args):
"""Make an API query using the given arguments.""" """Make an API query using the given arguments."""
query = "/" + "".join(str(arg) + "/" for arg in args) query = "/" + "".join(str(arg) + "/" for arg in args)
@@ -47,10 +87,15 @@ class ZKillboard:
self._last_query = time.time() self._last_query = time.time()
return result return result


def iter_killmails(self, *args):
def iter_killmails(self, *args, extended=False):
"""Return an iterator over killmails using the given API arguments. """Return an iterator over killmails using the given API arguments.


Automagically follows pagination as far as possible. (Be careful.) Automagically follows pagination as far as possible. (Be careful.)

If extended is True, we will provide extra information for each kill
(names of entities instead of just IDs), which requires ESI API calls.
This matches the original API format of ZKill before it was, er,
"simplified".
""" """
page = 1 page = 1
while True: while True:
@@ -60,7 +105,11 @@ class ZKillboard:
result = self.query(*args) result = self.query(*args)


if result: if result:
yield from result
if extended:
for kill in result:
yield self._extend_killmail(kill)
else:
yield from result
page += 1 page += 1
else: else:
break break

+ 9
- 8
calefaction/modules/campaigns/database.py View File

@@ -94,10 +94,10 @@ class CampaignDB:
def add_kill(self, kill): def add_kill(self, kill):
"""Insert a killmail into the database.""" """Insert a killmail into the database."""
try: try:
datetime.strptime(kill["killTime"], "%Y-%m-%d %H:%M:%S")
datetime.strptime(kill["killmail_time"], "%Y-%m-%d %H:%M:%S")
except ValueError: except ValueError:
raise RuntimeError("Invalid kill_date=%s for kill_id=%d" % ( raise RuntimeError("Invalid kill_date=%s for kill_id=%d" % (
kill["killTime"], kill["killID"]))
kill["killmail_time"], kill["killmail_id"]))


query = """INSERT OR REPLACE INTO kill ( query = """INSERT OR REPLACE INTO kill (
kill_id, kill_date, kill_system, kill_victim_shipid, kill_id, kill_date, kill_system, kill_victim_shipid,
@@ -108,12 +108,13 @@ class CampaignDB:
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"""
victim = kill["victim"] victim = kill["victim"]
args = ( args = (
int(kill["killID"]), kill["killTime"], int(kill["solarSystemID"]),
int(victim["shipTypeID"]), int(victim["characterID"]),
victim["characterName"], int(victim["corporationID"]),
victim["corporationName"], int(victim["allianceID"]),
victim["allianceName"], int(victim["factionID"]),
victim["factionName"], float(kill["zkb"]["totalValue"]))
int(kill["killmail_id"]), kill["killmail_time"],
int(kill["solar_system_id"]), int(victim["ship_type_id"]),
int(victim["character_id"]), victim["character_name"],
int(victim["corporation_id"]), victim["corporation_name"],
int(victim["alliance_id"]), victim["alliance_name"],
int(victim["faction_id"]), victim["faction_name"],
float(kill["zkb"]["totalValue"]))
with self._conn as conn: with self._conn as conn:
conn.execute(query, args) conn.execute(query, args)




+ 8
- 4
calefaction/modules/campaigns/update.py View File

@@ -33,7 +33,7 @@ def _build_filter(qualifiers, arg):


def _store_kill(cname, opnames, kill): def _store_kill(cname, opnames, kill):
"""Store the given kill and its associations into the database.""" """Store the given kill and its associations into the database."""
kid = kill["killID"]
kid = kill["killmail_id"]
if g.campaign_db.has_kill(kid): if g.campaign_db.has_kill(kid):
current = g.campaign_db.get_kill_associations(cname, kid) current = g.campaign_db.get_kill_associations(cname, kid)
opnames -= set(current) opnames -= set(current)
@@ -59,12 +59,16 @@ def _update_killboard_operations(cname, opnames, min_kill_id):
"no-attackers", "orderDirection", "desc"] "no-attackers", "orderDirection", "desc"]


max_kill_id = min_kill_id max_kill_id = min_kill_id
for kill in g.eve.zkill.iter_killmails(*args):
kid = kill["killID"]
for kill in g.eve.zkill.iter_killmails(*args, extended=True):
kid = kill["killmail_id"]
if min_kill_id > 0 and kid == min_kill_id: if min_kill_id > 0 and kid == min_kill_id:
# TODO: This fails if ZKill receives kills out of order.
# Should look ahead for kills within, say, 12 hours of the
# min_kill_id, and extend code below to ignore kills aleady
# included instead of re-adding.
break break


ktime = kill["killTime"]
ktime = kill["killmail_time"]
logger.debug("Evaluating kill date=%s id=%d for campaign=%s " logger.debug("Evaluating kill date=%s id=%d for campaign=%s "
"operations=%s", ktime, kid, cname, ",".join(opnames)) "operations=%s", ktime, kid, cname, ",".join(opnames))
max_kill_id = max(max_kill_id, kid) max_kill_id = max(max_kill_id, kid)


Loading…
Cancel
Save