A corporation manager and dashboard for EVE Online
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

122 lignes
4.7 KiB

  1. # -*- coding: utf-8 -*-
  2. import sys
  3. import textwrap
  4. from flask import g
  5. from .._provided import config, logger
  6. __all__ = ["update_operation"]
  7. def _save_operation(cname, opname, primary, secondary, key=None):
  8. """Save the given campaign/operation overview info in the database."""
  9. secstr = "" if secondary is None else (" secondary=%d" % secondary)
  10. logger.debug("Setting overview primary=%d%s campaign=%s operation=%s",
  11. primary, secstr, cname, opname)
  12. g.campaign_db.set_overview(cname, opname, primary, secondary)
  13. g.campaign_db.touch_operation(cname, opname, key=key)
  14. def _build_filter(qualifiers):
  15. """Given a qualifiers string from the config, return a filter function.
  16. This function is extremely sensitive since it executes arbitrary Python
  17. code. It should never be run with a user-provided argument! We trust the
  18. contents of a config file because it originates from a known place on the
  19. filesystem.
  20. """
  21. namespace = {}
  22. body = "def _func(kill):\n" + textwrap.indent(qualifiers, " " * 4)
  23. exec(body, namespace)
  24. return namespace["_func"]
  25. def _store_kill(cname, opnames, kill):
  26. """Store the given kill and its associations into the database."""
  27. kid = kill["killID"]
  28. if g.campaign_db.has_kill(kid):
  29. current = g.campaign_db.get_kill_associations(cname, kid)
  30. opnames -= set(current)
  31. if opnames:
  32. logger.debug("Adding operations=%s to kill id=%d campaign=%s",
  33. ",".join(opnames), kid, cname)
  34. else:
  35. logger.debug("Adding kill id=%d campaign=%s operations=%s", kid, cname,
  36. ",".join(opnames))
  37. g.campaign_db.add_kill(kill)
  38. g.campaign_db.associate_kill(cname, kid, opnames)
  39. def _update_killboard_operations(cname, opnames, min_kill_id):
  40. """Update all killboard-type operations in the given campaign subset."""
  41. operations = config["campaigns"][cname]["operations"]
  42. filters = []
  43. for opname in opnames:
  44. qualif = operations[opname]["qualifiers"]
  45. filters.append((_build_filter(qualif), opname))
  46. args = ["kills", "corporationID", g.config.get("corp.id"), "no-items",
  47. "no-attackers", "orderDirection", "asc"]
  48. if min_kill_id > 0:
  49. args += ["afterKillID", min_kill_id]
  50. max_kill_id = min_kill_id
  51. for kill in g.eve.zkill.iter_killmails(*args):
  52. kid = kill["killID"]
  53. ktime = kill["killTime"]
  54. logger.debug("Evaluating kill date=%s id=%d for campaign=%s "
  55. "operations=%s", ktime, kid, cname, ",".join(opnames))
  56. max_kill_id = max(max_kill_id, kid)
  57. ops = set()
  58. for filt, opname in filters:
  59. if filt(kill):
  60. ops.add(opname)
  61. if ops:
  62. _store_kill(cname, ops, kill)
  63. for opname in opnames:
  64. primary, secondary = g.campaign_db.count_kills(cname, opname)
  65. show_isk = operations[opname].get("isk", True)
  66. if not show_isk:
  67. secondary = None
  68. _save_operation(cname, opname, primary, secondary, key=max_kill_id)
  69. def _update_collection_operations(cname, opnames):
  70. """Update all collection-type operations in the given campaign subset."""
  71. campaign = config["campaigns"][cname]
  72. for opname in opnames:
  73. operation = campaign["operations"][opname]
  74. show_isk = operation.get("isk", True)
  75. # store per-user counts; update for all users in corp who have fresh
  76. # API keys and leave other data stale
  77. ...
  78. primary = __import__("random").randint(10, 99)
  79. secondary = __import__("random").randint(10000000, 5000000000) / 100 \
  80. if show_isk else None
  81. _save_operation(cname, opname, primary, secondary)
  82. def update_operation(cname, opname, new=False):
  83. """Update a campaign/operation. Assumes a thread-exclusive lock is held."""
  84. campaign = config["campaigns"][cname]
  85. operations = campaign["operations"]
  86. optype = operations[opname]["type"]
  87. opnames = [opn for opn in campaign["enabled"]
  88. if operations[opn]["type"] == optype]
  89. if optype == "killboard":
  90. opsubset = []
  91. min_key = 0 if new else sys.maxsize
  92. for opname in opnames:
  93. last_updated, key = g.campaign_db.check_operation(cname, opname)
  94. if new and last_updated is None:
  95. opsubset.append(opname)
  96. elif not new and last_updated is not None:
  97. min_key = min(min_key, key)
  98. opsubset.append(opname)
  99. _update_killboard_operations(cname, opsubset, min_key)
  100. elif optype == "collection":
  101. _update_collection_operations(cname, opnames)
  102. else:
  103. raise RuntimeError("Unknown operation type: %s" % optype)