A copyright violation detector running on Wikimedia Cloud Services https://tools.wmflabs.org/copyvios/
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 

150 řádky
4.5 KiB

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from functools import wraps
  4. from hashlib import md5
  5. from json import dumps
  6. from logging import DEBUG, INFO, getLogger
  7. from logging.handlers import TimedRotatingFileHandler
  8. from os import path
  9. from time import asctime
  10. from traceback import format_exc
  11. from earwigbot.bot import Bot
  12. from earwigbot.wiki.copyvios import globalize
  13. from flask import Flask, g, make_response, request
  14. from flask.ext.mako import MakoTemplates, render_template, TemplateError
  15. from copyvios.api import format_api_error, handle_api_request
  16. from copyvios.checker import do_check
  17. from copyvios.cookies import parse_cookies
  18. from copyvios.misc import cache, get_notice
  19. from copyvios.settings import process_settings
  20. from copyvios.sites import update_sites
  21. app = Flask(__name__)
  22. MakoTemplates(app)
  23. hand = TimedRotatingFileHandler("logs/app.log", when="midnight", backupCount=7)
  24. hand.setLevel(DEBUG)
  25. app.logger.addHandler(hand)
  26. app.logger.info(u"Flask server started " + asctime())
  27. app._hash_cache = {}
  28. def catch_errors(func):
  29. @wraps(func)
  30. def inner(*args, **kwargs):
  31. try:
  32. return func(*args, **kwargs)
  33. except TemplateError as exc:
  34. app.logger.error(u"Caught exception:\n{0}".format(exc.text))
  35. return render_template("error.mako", traceback=exc.text)
  36. except Exception:
  37. app.logger.exception(u"Caught exception:")
  38. return render_template("error.mako", traceback=format_exc())
  39. return inner
  40. @app.before_first_request
  41. def setup_app():
  42. cache.bot = Bot(".earwigbot", 100)
  43. cache.langs, cache.projects = [], []
  44. cache.last_sites_update = 0
  45. cache.background_data = {}
  46. cache.last_background_updates = {}
  47. getLogger("earwigbot.wiki.cvworker").setLevel(INFO)
  48. globalize()
  49. @app.before_request
  50. def prepare_request():
  51. g._db = None
  52. g.cookies = parse_cookies(
  53. request.script_root, request.environ.get("HTTP_COOKIE"))
  54. g.new_cookies = []
  55. @app.after_request
  56. def add_new_cookies(response):
  57. for cookie in g.new_cookies:
  58. response.headers.add("Set-Cookie", cookie)
  59. return response
  60. @app.after_request
  61. def write_access_log(response):
  62. msg = u"%s %s %s %s -> %s"
  63. app.logger.debug(msg, asctime(), request.method, request.path,
  64. request.values.to_dict(), response.status_code)
  65. return response
  66. @app.teardown_appcontext
  67. def close_databases(error):
  68. if g._db:
  69. g._db.close()
  70. def external_url_handler(error, endpoint, values):
  71. if endpoint == "static" and "file" in values:
  72. fpath = path.join(app.static_folder, values["file"])
  73. mtime = path.getmtime(fpath)
  74. cache = app._hash_cache.get(fpath)
  75. if cache and cache[0] == mtime:
  76. hashstr = cache[1]
  77. else:
  78. with open(fpath, "rb") as f:
  79. hashstr = md5(f.read()).hexdigest()
  80. app._hash_cache[fpath] = (mtime, hashstr)
  81. return "/static/{0}?v={1}".format(values["file"], hashstr)
  82. raise error
  83. app.url_build_error_handlers.append(external_url_handler)
  84. @app.route("/")
  85. @catch_errors
  86. def index():
  87. notice = get_notice()
  88. update_sites()
  89. query = do_check()
  90. return render_template(
  91. "index.mako", notice=notice, query=query, result=query.result,
  92. turnitin_result=query.turnitin_result)
  93. @app.route("/settings", methods=["GET", "POST"])
  94. @catch_errors
  95. def settings():
  96. status = process_settings() if request.method == "POST" else None
  97. update_sites()
  98. default = cache.bot.wiki.get_site()
  99. kwargs = {"status": status, "default_lang": default.lang,
  100. "default_project": default.project}
  101. return render_template("settings.mako", **kwargs)
  102. @app.route("/api")
  103. @catch_errors
  104. def api():
  105. return render_template("api.mako", help=True)
  106. @app.route("/api.json")
  107. @catch_errors
  108. def api_json():
  109. if not request.args:
  110. return render_template("api.mako", help=True)
  111. format = request.args.get("format", "json")
  112. if format in ["json", "jsonfm"]:
  113. update_sites()
  114. try:
  115. result = handle_api_request()
  116. except Exception as exc:
  117. result = format_api_error("unhandled_exception", exc)
  118. else:
  119. errmsg = u"Unknown format: '{0}'".format(format)
  120. result = format_api_error("unknown_format", errmsg)
  121. if format == "jsonfm":
  122. return render_template("api.mako", help=False, result=result)
  123. resp = make_response(dumps(result))
  124. resp.mimetype = "application/json"
  125. resp.headers["Access-Control-Allow-Origin"] = "*"
  126. return resp
  127. if __name__ == '__main__':
  128. app.run()