views.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import os
  2. import mimetypes
  3. from itertools import chain
  4. from django.contrib.auth.decorators import login_required
  5. from django.contrib.contenttypes.models import ContentType
  6. from django.core.paginator import Paginator
  7. from django.http import Http404, HttpResponse
  8. from django.shortcuts import render
  9. from wagtail.core.models import Page
  10. from wagtail.search.backends import db, get_search_backend
  11. from wagtail.search.models import Query
  12. from coderedcms import utils
  13. from coderedcms.forms import SearchForm
  14. from coderedcms.models import CoderedPage, get_page_models, GeneralSettings
  15. from coderedcms.settings import cr_settings
  16. def search(request):
  17. """
  18. Searches pages across the entire site.
  19. """
  20. search_form = SearchForm(request.GET)
  21. pagetypes = []
  22. results = None
  23. results_paginated = None
  24. if search_form.is_valid():
  25. search_query = search_form.cleaned_data['s']
  26. search_model = search_form.cleaned_data['t']
  27. # get all codered models
  28. pagemodels = sorted(get_page_models(), key=lambda k: k.search_name)
  29. # get filterable models
  30. for model in pagemodels:
  31. if model.search_filterable:
  32. pagetypes.append(model)
  33. # get backend
  34. backend = get_search_backend()
  35. # DB search. Since this backend can't handle inheritance or scoring,
  36. # search specified page types in the desired order and chain the results together.
  37. # This provides better search results than simply searching limited fields on CoderedPage.
  38. db_models = []
  39. if backend.__class__ == db.SearchBackend:
  40. for model in get_page_models():
  41. if model.search_db_include:
  42. db_models.append(model)
  43. db_models = sorted(db_models, reverse=True, key=lambda k: k.search_db_boost)
  44. if backend.__class__ == db.SearchBackend and db_models:
  45. for model in db_models:
  46. # if search_model is provided, only search on that model
  47. if not search_model or search_model == ContentType.objects.get_for_model(model).model:
  48. curr_results = model.objects.live().search(search_query)
  49. if results:
  50. results = list(chain(results, curr_results))
  51. else:
  52. results = curr_results
  53. # Fallback for any other search backend
  54. else:
  55. if search_model:
  56. try:
  57. model = ContentType.objects.get(model=search_model).model_class()
  58. results = model.objects.live().search(search_query)
  59. except:
  60. results = None
  61. else:
  62. results = CoderedPage.objects.live().search(search_query)
  63. # paginate results
  64. if results:
  65. paginator = Paginator(results, GeneralSettings.for_site(request.site).search_num_results)
  66. page = request.GET.get('p', 1)
  67. try:
  68. results_paginated = paginator.page(page)
  69. except:
  70. results_paginated = paginator.page(1)
  71. # Log the query so Wagtail can suggest promoted results
  72. Query.get(search_query).add_hit()
  73. # Render template
  74. return render(request, 'coderedcms/pages/search.html', {
  75. 'request': request,
  76. 'pagetypes': pagetypes,
  77. 'form': search_form,
  78. 'results': results,
  79. 'results_paginated': results_paginated
  80. })
  81. @login_required
  82. def serve_protected_file(request, path):
  83. """
  84. Function that serves protected files uploaded from forms.
  85. """
  86. fullpath = os.path.join(cr_settings['PROTECTED_MEDIA_ROOT'], path)
  87. if os.path.isfile(fullpath):
  88. mimetype, encoding = mimetypes.guess_type(fullpath)
  89. with open(fullpath, 'rb') as f:
  90. response = HttpResponse(f.read(), content_type=mimetype)
  91. if encoding:
  92. response["Content-Encoding"] = encoding
  93. return response
  94. else:
  95. raise Http404()
  96. @login_required
  97. def clear_cache(request):
  98. utils.clear_cache()
  99. return HttpResponse("Cache has been cleared.")
  100. def robots(request):
  101. robots = GeneralSettings.for_site(request.site).robots
  102. return render(
  103. request,
  104. 'robots.txt',
  105. {'robots': robots},
  106. content_type='text/plain'
  107. )