importer.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/env python3
  2. import json
  3. import operator
  4. import sys
  5. import time
  6. import oursql
  7. import requests
  8. import db
  9. def insert_kill(c, kill):
  10. try:
  11. db.execute(c, 'INSERT INTO kills (kill_id, solar_system_id, kill_time, moon_id) VALUES(?, ?, ?, ?)',
  12. kill['killID'], kill['solarSystemID'], kill['killTime'], kill['moonID'])
  13. except oursql.IntegrityError as e:
  14. if e.args[0] == oursql.errnos['ER_DUP_ENTRY']:
  15. return False
  16. raise
  17. victim = kill['victim']
  18. parambatch = [(
  19. kill['killID'], 1, victim['characterID'], victim['characterName'], victim['shipTypeID'],
  20. victim['allianceID'], victim['allianceName'], victim['corporationID'], victim['corporationName'], victim['factionID'], victim['factionName'],
  21. victim['damageTaken'], None, None, None,
  22. )]
  23. for attacker in kill['attackers']:
  24. parambatch.append((
  25. kill['killID'], 0, attacker['characterID'], attacker['characterName'], attacker['shipTypeID'],
  26. attacker['allianceID'], attacker['allianceName'], attacker['corporationID'], attacker['corporationName'], attacker['factionID'], attacker['factionName'],
  27. attacker['damageDone'], attacker['finalBlow'], attacker['securityStatus'], attacker['weaponTypeID'],
  28. ))
  29. c.executemany('''
  30. INSERT INTO characters (
  31. kill_id, victim, character_id, character_name, ship_type_id,
  32. alliance_id, alliance_name, corporation_id, corporation_name, faction_id, faction_name,
  33. damage, final_blow, security_status, weapon_type_id
  34. ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  35. ''', parambatch
  36. )
  37. parambatch = []
  38. for item in kill['items']:
  39. parambatch.append((kill['killID'], item['typeID'], item['flag'],
  40. item['qtyDropped'], item['qtyDestroyed'], item['singleton']))
  41. c.executemany('''
  42. INSERT INTO items (
  43. kill_id, type_id, flag, dropped, destroyed, singleton
  44. ) VALUES(?, ?, ?, ?, ?, ?)
  45. ''', parambatch
  46. )
  47. try:
  48. result = db.get(c, 'SELECT cost FROM item_costs WHERE type_id = ?', (victim['shipTypeID']))
  49. cost = result['cost']
  50. except db.NoRowsException:
  51. cost = 0
  52. result = db.get(c, '''
  53. SELECT SUM(cost * (dropped + destroyed)) AS item_cost
  54. FROM items
  55. JOIN item_costs ON items.type_id = item_costs.type_id
  56. WHERE kill_id = ?
  57. ''', kill['killID'])
  58. if result['item_cost'] is not None:
  59. cost += result['item_cost']
  60. db.execute(c, 'INSERT INTO kill_costs (kill_id, cost) VALUES(?, ?)', kill['killID'], cost)
  61. return True
  62. def main():
  63. rs = requests.session()
  64. with db.cursor() as c:
  65. if len(sys.argv) == 2:
  66. kill_id = sys.argv[1]
  67. response = rs.get('http://api.whelp.gg/kill/' + kill_id)
  68. character_id = response.json()['victim']['character_id']
  69. url = 'https://zkillboard.com/api/losses/characterID/{}/beforeKillID/{}/limit/1'
  70. response = rs.get(url.format(character_id, int(kill_id) + 1))
  71. data = response.json()
  72. if len(data) != 1:
  73. raise Exception('got {} kills'.format(len(data)))
  74. if insert_kill(c, data[0]):
  75. print('inserted!')
  76. else:
  77. print('duplicate')
  78. return
  79. groups = db.query(c, 'SELECT groupID FROM eve.invGroups WHERE categoryID = ?', 6)
  80. groups = list(map(operator.itemgetter('groupID'), groups))
  81. last_kill_ids = {}
  82. for i in range(0, len(groups), 10):
  83. query_groups = ','.join(map(str, groups[i:i+10]))
  84. last_kill_ids[query_groups] = None
  85. last_request_time = 0
  86. while True:
  87. for query_group in last_kill_ids:
  88. path = '/api/losses/api-only/groupID/' + query_group
  89. last_kill_id = last_kill_ids[query_group]
  90. if last_kill_id is not None:
  91. path += '/beforeKillID/' + str(last_kill_id)
  92. now = time.time()
  93. if now - last_request_time < 12:
  94. sleep_secs = 12 - (now - last_request_time)
  95. print('sleeping', sleep_secs)
  96. time.sleep(sleep_secs)
  97. last_request_time = time.time()
  98. try:
  99. r = rs.get('https://zkillboard.com' + path)
  100. kills = r.json()
  101. except Exception as e:
  102. print(repr(e))
  103. break
  104. print('inserting', len(kills), 'kills', end='... ')
  105. sys.stdout.flush()
  106. inserted = 0
  107. try:
  108. for kill in kills:
  109. if insert_kill(c, kill):
  110. inserted += 1
  111. except TypeError as e:
  112. print(repr(e), kills)
  113. break
  114. db.conn.commit()
  115. print(len(kills) - inserted, 'dupes')
  116. last_kill_id = kills[-1]['killID']
  117. last_kill_ids[query_group] = last_kill_id
  118. if __name__ == '__main__':
  119. main()