A copyright violation detector running on Wikimedia Cloud Services https://tools.wmflabs.org/copyvios/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

117 lines
4.2 KiB

  1. # -*- coding: utf-8 -*-
  2. from .checker import do_check, T_POSSIBLE, T_SUSPECT
  3. from .misc import Query
  4. from .sites import get_sites
  5. __all__ = ["format_api_error", "handle_api_request"]
  6. _CHECK_ERRORS = {
  7. "no search method": "Either 'use_engine' or 'use_links' must be true",
  8. "no URL": "The parameter 'url' is required for URL comparisons",
  9. "bad URI": "The given URI scheme is unsupported",
  10. "no data": "No text could be found in the given URL (note that only HTML "
  11. "and plain text pages are supported, and content generated by "
  12. "JavaScript or found inside iframes is ignored)",
  13. "timeout": "The given URL timed out before any data could be retrieved",
  14. "search error": "An error occurred while using the search engine; try "
  15. "reloading or setting 'use_engine' to 0",
  16. }
  17. def _serialize_page(page):
  18. return {"title": page.title, "url": page.url}
  19. def _serialize_source(source, show_skip=True):
  20. if not source:
  21. return {"url": None, "confidence": 0.0, "violation": "none"}
  22. conf = source.confidence
  23. data = {
  24. "url": source.url,
  25. "confidence": conf,
  26. "violation": "suspected" if conf >= T_SUSPECT else
  27. "possible" if conf >= T_POSSIBLE else "none"
  28. }
  29. if show_skip:
  30. data["skipped"] = source.skipped
  31. return data
  32. def format_api_error(code, info):
  33. if isinstance(info, BaseException):
  34. info = type(info).__name__ + ": " + str(info)
  35. elif isinstance(info, unicode):
  36. info = info.encode("utf8")
  37. return {"status": "error", "error": {"code": code, "info": info}}
  38. def _hook_default(query):
  39. info = u"Unknown action: '{0}'".format(query.action.lower())
  40. return format_api_error("unknown_action", info)
  41. def _hook_check(query):
  42. do_check(query)
  43. if not query.submitted:
  44. info = ("The query parameters 'project', 'lang', and either 'title' "
  45. "or 'oldid' are required for checks")
  46. return format_api_error("missing_params", info)
  47. if query.error:
  48. info = _CHECK_ERRORS.get(query.error, "An unknown error occurred")
  49. return format_api_error(query.error.replace(" ", "_"), info)
  50. elif not query.site:
  51. info = (u"The given site (project={0}, lang={1}) either doesn't exist,"
  52. u" is closed, or is private").format(query.project, query.lang)
  53. return format_api_error("bad_site", info)
  54. elif not query.result:
  55. if query.oldid:
  56. info = u"The given revision ID doesn't seem to exist: {0}"
  57. return format_api_error("bad_oldid", info.format(query.oldid))
  58. else:
  59. info = u"The given page doesn't seem to exist: {0}"
  60. return format_api_error("bad_title", info.format(query.page.title))
  61. result = query.result
  62. data = {
  63. "status": "ok",
  64. "meta": {
  65. "time": result.time,
  66. "queries": result.queries,
  67. "cached": result.cached,
  68. "redirected": bool(query.redirected_from)
  69. },
  70. "page": _serialize_page(query.page),
  71. "best": _serialize_source(result.best, show_skip=False),
  72. "sources": [_serialize_source(source) for source in result.sources]
  73. }
  74. if result.cached:
  75. data["meta"]["cache_time"] = result.cache_time
  76. if query.redirected_from:
  77. data["original_page"] = _serialize_page(query.redirected_from)
  78. return data
  79. def _hook_sites(query):
  80. langs, projects = get_sites()
  81. return {"status": "ok", "langs": langs, "projects": projects}
  82. _HOOKS = {
  83. "compare": _hook_check,
  84. "search": _hook_check,
  85. "sites": _hook_sites,
  86. }
  87. def handle_api_request():
  88. query = Query()
  89. if query.version:
  90. try:
  91. query.version = int(query.version)
  92. except ValueError:
  93. info = "The version string is invalid: {0}".format(query.version)
  94. return format_api_error("invalid_version", info)
  95. else:
  96. query.version = 1
  97. if query.version == 1:
  98. action = query.action.lower() if query.action else ""
  99. return _HOOKS.get(action, _hook_default)(query)
  100. info = "The API version is unsupported: {0}".format(query.version)
  101. return format_api_error("unsupported_version", info)