__init__.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from typing import List, Union
  2. from pathlib import Path
  3. from importlib import import_module
  4. from django.db.models import QuerySet
  5. from archivebox.index.schema import Link
  6. from archivebox.util import enforce_types
  7. from archivebox.config import stderr, OUTPUT_DIR, USE_INDEXING_BACKEND, USE_SEARCHING_BACKEND, SEARCH_BACKEND_ENGINE
  8. from .utils import get_indexable_content, log_index_started
  9. def indexing_enabled():
  10. return USE_INDEXING_BACKEND
  11. def search_backend_enabled():
  12. return USE_SEARCHING_BACKEND
  13. def get_backend():
  14. return f'search.backends.{SEARCH_BACKEND_ENGINE}'
  15. def import_backend():
  16. backend_string = get_backend()
  17. try:
  18. backend = import_module(backend_string)
  19. except Exception as err:
  20. raise Exception("Could not load '%s' as a backend: %s" % (backend_string, err))
  21. return backend
  22. @enforce_types
  23. def write_search_index(link: Link, texts: Union[List[str], None]=None, out_dir: Path=OUTPUT_DIR, skip_text_index: bool=False) -> None:
  24. if not indexing_enabled():
  25. return
  26. if not skip_text_index and texts:
  27. from core.models import Snapshot
  28. snap = Snapshot.objects.filter(url=link.url).first()
  29. backend = import_backend()
  30. if snap:
  31. try:
  32. backend.index(snapshot_id=str(snap.id), texts=texts)
  33. except Exception as err:
  34. stderr()
  35. stderr(
  36. f'[X] The search backend threw an exception={err}:',
  37. color='red',
  38. )
  39. @enforce_types
  40. def query_search_index(query: str, out_dir: Path=OUTPUT_DIR) -> QuerySet:
  41. from core.models import Snapshot
  42. if search_backend_enabled():
  43. backend = import_backend()
  44. try:
  45. snapshot_ids = backend.search(query)
  46. except Exception as err:
  47. stderr()
  48. stderr(
  49. f'[X] The search backend threw an exception={err}:',
  50. color='red',
  51. )
  52. raise
  53. else:
  54. # TODO preserve ordering from backend
  55. qsearch = Snapshot.objects.filter(pk__in=snapshot_ids)
  56. return qsearch
  57. return Snapshot.objects.none()
  58. @enforce_types
  59. def flush_search_index(snapshots: QuerySet):
  60. if not indexing_enabled() or not snapshots:
  61. return
  62. backend = import_backend()
  63. snapshot_ids=(str(pk) for pk in snapshots.values_list('pk',flat=True))
  64. try:
  65. backend.flush(snapshot_ids)
  66. except Exception as err:
  67. stderr()
  68. stderr(
  69. f'[X] The search backend threw an exception={err}:',
  70. color='red',
  71. )
  72. @enforce_types
  73. def index_links(links: Union[List[Link],None], out_dir: Path=OUTPUT_DIR):
  74. if not links:
  75. return
  76. from core.models import Snapshot, ArchiveResult
  77. for link in links:
  78. snap = Snapshot.objects.filter(url=link.url).first()
  79. if snap:
  80. results = ArchiveResult.objects.indexable().filter(snapshot=snap)
  81. log_index_started(link.url)
  82. try:
  83. texts = get_indexable_content(results)
  84. except Exception as err:
  85. stderr()
  86. stderr(
  87. f'[X] An Exception ocurred reading the indexable content={err}:',
  88. color='red',
  89. )
  90. else:
  91. write_search_index(link, texts, out_dir=out_dir)