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.
 
 
 
 
 

97 lignes
3.3 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, 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. return (result, False)
  22. except EVEAPIError:
  23. flash(Messages.EVE_API_ERROR, "error")
  24. return (False, True)
  25. except AccessDeniedError:
  26. flash(Messages.ACCESS_DENIED, "error")
  27. return (False, True)
  28. def make_error_catcher(app, error_template):
  29. """Wrap a route to display and log any uncaught exceptions."""
  30. def callback(func):
  31. @wraps(func)
  32. def inner(*args, **kwargs):
  33. try:
  34. return func(*args, **kwargs)
  35. except HTTPException:
  36. raise
  37. except TemplateError as exc:
  38. app.logger.error("Caught exception:\n{0}".format(exc.text))
  39. return render_template(error_template, traceback=exc.text)
  40. except Exception:
  41. app.logger.exception("Caught exception:")
  42. return render_template(error_template, traceback=format_exc())
  43. return inner
  44. return callback
  45. def make_route_restricter(auth, on_failure):
  46. """Wrap a route to ensure the user is authenticated."""
  47. def callback(func):
  48. @wraps(func)
  49. def inner(*args, **kwargs):
  50. success, caught = try_func(auth.is_authenticated)
  51. if success:
  52. return func(*args, **kwargs)
  53. if not caught:
  54. flash(Messages.LOG_IN_FIRST, "error")
  55. return on_failure()
  56. return inner
  57. return callback
  58. def set_up_asset_versioning(app):
  59. """Add a staticv endpoint that adds hash versioning to static assets."""
  60. def callback(app, error, endpoint, values):
  61. if endpoint == "staticv":
  62. filename = values["filename"]
  63. fpath = path.join(app.static_folder, filename)
  64. try:
  65. mtime = path.getmtime(fpath)
  66. except OSError:
  67. return url_for("static", filename=filename)
  68. cache = app._hash_cache.get(fpath)
  69. if cache and cache[0] == mtime:
  70. hashstr = cache[1]
  71. else:
  72. with open(fpath, "rb") as fp:
  73. hashstr = md5(fp.read()).hexdigest()
  74. app._hash_cache[fpath] = (mtime, hashstr)
  75. return url_for("static", filename=filename, v=hashstr)
  76. raise error
  77. old_get_max_age = app.get_send_file_max_age
  78. def extend_max_age(filename):
  79. if "v" in request.args:
  80. return 60 * 60 * 24 * 365 # 1 year
  81. return old_get_max_age(filename)
  82. app._hash_cache = {}
  83. app.url_build_error_handlers.append(lambda a, b, c: callback(app, a, b, c))
  84. app.get_send_file_max_age = extend_max_age