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.
 
 
 
 
 

102 lignes
3.4 KiB

  1. # -*- coding: utf-8 -*-
  2. from functools import wraps
  3. from hashlib import md5
  4. from os import path
  5. from traceback import format_exc
  6. from flask import flash, g, request, url_for
  7. from flask_mako import render_template, TemplateError
  8. from werkzeug.exceptions import HTTPException
  9. from .exceptions import AccessDeniedError, EVEAPIError
  10. from .messages import Messages
  11. __all__ = [
  12. "try_func", "make_error_catcher", "make_route_restricter",
  13. "set_up_asset_versioning"]
  14. def try_func(inner):
  15. """Evaluate inner(), catching subclasses of CalefactionError.
  16. If nothing was caught, return (inner(), False). Otherwise, flash an
  17. appropriate error message and return (False, True).
  18. """
  19. try:
  20. result = inner()
  21. except EVEAPIError:
  22. flash(Messages.EVE_API_ERROR, "error")
  23. return (False, True)
  24. except AccessDeniedError:
  25. flash(Messages.ACCESS_DENIED, "error")
  26. return (False, True)
  27. if getattr(g, "_session_expired", False):
  28. flash(Messages.SESSION_EXPIRED, "error")
  29. return (result, True)
  30. return (result, False)
  31. def make_error_catcher(app, error_template):
  32. """Wrap a route to display and log any uncaught exceptions."""
  33. def callback(func):
  34. @wraps(func)
  35. def inner(*args, **kwargs):
  36. try:
  37. return func(*args, **kwargs)
  38. except HTTPException:
  39. raise
  40. except TemplateError as exc:
  41. app.logger.error("Caught exception:\n{0}".format(exc.text))
  42. trace = exc.text
  43. except Exception:
  44. app.logger.exception("Caught exception:")
  45. trace = format_exc()
  46. return render_template(error_template, traceback=trace), 500
  47. return inner
  48. return callback
  49. def make_route_restricter(auth, on_failure):
  50. """Wrap a route to ensure the user is authenticated."""
  51. def callback(func):
  52. @wraps(func)
  53. def inner(*args, **kwargs):
  54. success, caught = try_func(auth.is_authenticated)
  55. if success:
  56. return func(*args, **kwargs)
  57. if not caught:
  58. flash(Messages.LOG_IN_FIRST, "error")
  59. return on_failure()
  60. return inner
  61. return callback
  62. def set_up_asset_versioning(app):
  63. """Add a staticv endpoint that adds hash versioning to static assets."""
  64. def callback(app, error, endpoint, values):
  65. if endpoint == "staticv":
  66. filename = values["filename"]
  67. fpath = path.join(app.static_folder, filename)
  68. try:
  69. mtime = path.getmtime(fpath)
  70. except OSError:
  71. return url_for("static", filename=filename)
  72. cache = app._hash_cache.get(fpath)
  73. if cache and cache[0] == mtime:
  74. hashstr = cache[1]
  75. else:
  76. with open(fpath, "rb") as fp:
  77. hashstr = md5(fp.read()).hexdigest()
  78. app._hash_cache[fpath] = (mtime, hashstr)
  79. return url_for("static", filename=filename, v=hashstr)
  80. raise error
  81. old_get_max_age = app.get_send_file_max_age
  82. def extend_max_age(filename):
  83. if "v" in request.args:
  84. return 60 * 60 * 24 * 365 # 1 year
  85. return old_get_max_age(filename)
  86. app._hash_cache = {}
  87. app.url_build_error_handlers.append(lambda a, b, c: callback(app, a, b, c))
  88. app.get_send_file_max_age = extend_max_age