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.
 
 
 
 
 

86 lignes
2.9 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, url_for
  7. from flask_mako import render_template, TemplateError
  8. from .exceptions import AccessDeniedError, EVEAPIError
  9. from .messages import Messages
  10. __all__ = [
  11. "try_func", "make_error_catcher", "make_route_restricter",
  12. "set_up_asset_versioning"]
  13. def try_func(inner):
  14. """Evaluate inner(), catching subclasses of CalefactionError.
  15. If nothing was caught, return (inner(), False). Otherwise, flash an
  16. appropriate error message and return (False, True).
  17. """
  18. try:
  19. result = inner()
  20. return (result, False)
  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. def make_error_catcher(app, error_template):
  28. """Wrap a route to display and log any uncaught exceptions."""
  29. def callback(func):
  30. @wraps(func)
  31. def inner(*args, **kwargs):
  32. try:
  33. return func(*args, **kwargs)
  34. except TemplateError as exc:
  35. app.logger.error("Caught exception:\n{0}".format(exc.text))
  36. return render_template(error_template, traceback=exc.text)
  37. except Exception:
  38. app.logger.exception("Caught exception:")
  39. return render_template(error_template, traceback=format_exc())
  40. return inner
  41. return callback
  42. def make_route_restricter(auth, on_failure):
  43. """Wrap a route to ensure the user is authenticated."""
  44. def callback(func):
  45. @wraps(func)
  46. def inner(*args, **kwargs):
  47. success, caught = try_func(auth.is_authenticated)
  48. if success:
  49. return func(*args, **kwargs)
  50. if not caught:
  51. flash(Messages.LOG_IN_FIRST, "error")
  52. return on_failure()
  53. return inner
  54. return callback
  55. def set_up_asset_versioning(app):
  56. """Add a staticv endpoint that adds hash versioning to static assets."""
  57. def callback(app, error, endpoint, values):
  58. if endpoint == "staticv":
  59. filename = values["filename"]
  60. fpath = path.join(app.static_folder, filename)
  61. try:
  62. mtime = path.getmtime(fpath)
  63. except OSError:
  64. return url_for("static", filename=filename)
  65. cache = app._hash_cache.get(fpath)
  66. if cache and cache[0] == mtime:
  67. hashstr = cache[1]
  68. else:
  69. with open(fpath, "rb") as fp:
  70. hashstr = md5(fp.read()).hexdigest()
  71. app._hash_cache[fpath] = (mtime, hashstr)
  72. return url_for("static", filename=filename, v=hashstr)
  73. raise error
  74. app._hash_cache = {}
  75. app.url_build_error_handlers.append(lambda a, b, c: callback(app, a, b, c))