Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import logging
3from django.conf import settings
4from django.contrib.auth.mixins import LoginRequiredMixin
5from django.core.exceptions import PermissionDenied
6from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
7from django.db.models import F
8from django.http import Http404, HttpResponse
9from django.shortcuts import get_object_or_404, render
10from django.utils.decorators import method_decorator
11from django.utils.translation import gettext as _
12from django.views.generic import View
13from django.views.generic.list import ListView
14from elasticsearch_dsl import Q
15from guardian.core import ObjectPermissionChecker
16from wagtail.core.models import Page
18from discuss_data.core.decorators import dd_tou_accepted
19from discuss_data.core.documents import DataSetDocument, UserDocument
20from discuss_data.core.models import KeywordTagged, LanguageTagged
21from discuss_data.core.helpers import (
22 index_search,
23 split_items_2,
24 split_items_3,
25)
26from discuss_data.dddatasets.models import (
27 Category,
28 CollectionMethodsTagged,
29 AnalysisMethodsTagged,
30 DisciplinesTagged,
31)
32from discuss_data.ddusers.models import Country, User
33from discuss_data.pages.models import LandingPage, ManualPage, TextPage
36logger = logging.getLogger(__name__)
38SLUG_LANDING = getattr(settings, "WAGTAIL_LANDING_PAGE", None)
39SLUG_CONTACTS = getattr(settings, "WAGTAIL_CONTACTS_PAGE", None)
40SLUG_SECURITY = getattr(settings, "WAGTAIL_SECURITY_PAGE", None)
43class SearchUsersAndDatasetsView(ListView):
44 paginate_by = 25
45 template_name = "core/_search_results.html"
47 def get_queryset(self):
48 query = self.request.GET.get("q")
49 countries = self.request.GET.getlist("countries")
50 categories = self.request.GET.getlist("categories")
52 queryset = index_search(
53 "user_index", query, countries=countries, categories=categories
54 )
56 # hide hidden and inactive users
57 filtered = queryset.exclude(profile_accessibility="HID").exclude(
58 is_active=False
59 )
61 if self.request.user.is_authenticated:
62 return filtered
64 # also hide network users by default (when not logged in)
65 return filtered.exclude(profile_accessibility="NET")
68def help_search(request):
69 return core_search_view(request, "help_index", 10)
72@method_decorator(dd_tou_accepted, name="dispatch")
73class ProtectedView(LoginRequiredMixin, View):
74 """ base class for views that require the user to log in and to accept
75 the terms of use
76 """
78 login_url = getattr(settings, "LOGIN_URL", None)
79 redirect_field_name = getattr(settings, "LOGIN_REDIRECT_URL", None)
82def get_search_params(request, order_by_filter=None, category=None):
83 search_params = dict()
84 search_params["q"] = request.GET.get("q")
86 # extract country slugs from GET
87 search_params["countries"] = request.GET.getlist("countries")
88 search_params["countries_all"] = Country.objects.all()
90 # extract category slugs from GET
91 categories = request.GET.getlist("categories")
92 if category:
93 categories.append(category.name)
94 search_params["categories"] = categories
95 search_params["categories_all"] = Category.objects.all()
97 # extract keyword slugs from GET
98 search_params["keywords"] = request.GET.getlist("keywords")
99 search_params["keywords_all"] = KeywordTagged.objects.all()
101 # extract language slugs from GET
102 search_params["languages"] = request.GET.getlist("languages")
103 search_params["languages_all"] = LanguageTagged.objects.all()
105 # extract disciplines slugs from GET
106 search_params["disciplines"] = request.GET.getlist("disciplines")
107 search_params["disciplines_all"] = DisciplinesTagged.objects.all()
109 # extract methods_of_data_collection slugs from GET
110 search_params["methods_of_data_collection"] = request.GET.getlist(
111 "methods_of_data_collection"
112 )
113 search_params[
114 "methods_of_data_collection_all"
115 ] = CollectionMethodsTagged.objects.all()
117 # extract methods_of_data_analysis slugs from GET
118 search_params["methods_of_data_analysis"] = request.GET.getlist(
119 "methods_of_data_analysis"
120 )
121 search_params["methods_of_data_analysis_all"] = AnalysisMethodsTagged.objects.all()
122 try:
123 search_params["orderby"] = [order_by_filter]
124 except UnboundLocalError:
125 pass
126 return search_params
129def core_search_view(request, search_index, objects_on_page, category=None):
130 # search result ordering
131 order_by_filter = request.GET.get("orderby")
132 if order_by_filter == "alpha":
133 order_by = "title"
134 else:
135 order_by = "-publication_date"
137 search_params = get_search_params(request, order_by_filter, category)
138 if search_index == "dataset_index":
139 template = "dddatasets/search_results.html"
140 queryset = index_search(
141 "dataset_index",
142 search_params["q"],
143 countries=search_params["countries"],
144 categories=search_params["categories"],
145 keywords=search_params["keywords"],
146 languages=search_params["languages"],
147 methods_of_data_analysis=search_params["methods_of_data_analysis"],
148 methods_of_data_collection=search_params["methods_of_data_collection"],
149 disciplines=search_params["disciplines"],
150 )
151 # only the dataset with the highest published version per dsmo will be listed in search results
152 # generate SQL join using Django F() expressions
153 # https://docs.djangoproject.com/en/3.0/topics/db/queries/#filters-can-reference-fields-on-the-model
154 queryset = queryset.filter(
155 dataset_management_object__main_published_ds_id=F("id")
156 ).order_by(order_by)
158 elif search_index == "user_index":
159 template = "ddusers/_search_results.html"
160 queryset = (
161 index_search(
162 "user_index",
163 search_params["q"],
164 countries=search_params["countries"],
165 keywords=search_params["keywords"],
166 )
167 .exclude(profile_accessibility="HID") # exclude hidden users from search
168 .order_by("last_name")
169 )
171 elif search_index == "help_index":
172 template = "pages/index_page_search.html"
173 queryset = Page.objects.live().search(search_params["q"])
174 else:
175 logger.debug("no search index given")
177 pagination = False
178 paginator_range = None
179 paginator_last_page = None
180 # deactivate paging by setting objects_on_page to an unrealistic high value
181 objects_on_page = 1000
183 # remove existing GET page key from querydict
184 get_params_without_page = request.GET.copy()
185 if get_params_without_page.get("page"):
186 del get_params_without_page["page"]
188 # if more then 24 users activate pagination
189 if queryset.count() > objects_on_page:
191 paginator = Paginator(queryset, objects_on_page) # Show 25 contacts per page
192 pagination = True
193 page = request.GET.get("page")
194 paginator_range = range(1, paginator.num_pages + 1)
195 paginator_last_page = paginator.num_pages + 1
196 try:
197 objects = paginator.page(page)
198 except PageNotAnInteger:
199 # If page is not an integer, deliver first page.
200 objects = paginator.page(1)
201 except EmptyPage:
202 # If page is out of range (e.g. 9999), deliver last page of results.
203 objects = paginator.page(paginator.num_pages)
204 else:
205 objects = queryset
207 return render(
208 request,
209 template,
210 {
211 "object_list": objects,
212 "pagination": pagination,
213 "paginator_range": paginator_range,
214 "paginator_last_page": paginator_last_page,
215 "search_params": search_params,
216 "query": search_params["q"],
217 "get_params": get_params_without_page,
218 "category": category,
219 },
220 )
223def landing_page(request):
224 """
225 Dashboard User Page
226 """
227 page = get_object_or_404(LandingPage, slug="discuss-data-landingpage")
228 news_items = split_items_2(page.news_item.all())
229 slogan_items = split_items_3(page.slogans_item.all())
230 return render(
231 request,
232 "landingpage/landing_page.html",
233 {"page": page, "news_items": news_items, "slogan_items": slogan_items},
234 )
237def about_page(request):
238 """
239 Platform about page
240 """
241 page = get_object_or_404(LandingPage, slug="discuss-data-landingpage")
242 return render(request, "about.html", {"page": page},)
245def contacts_page(request):
246 """
247 Platform contacts page
248 """
249 page = get_object_or_404(TextPage, slug=SLUG_CONTACTS)
250 return render(request, "pages/text_page.html", {"page": page},)
253def security_page(request):
254 """
255 Platform security page
256 """
257 page = get_object_or_404(TextPage, slug=SLUG_SECURITY)
258 return render(request, "pages/text_page.html", {"page": page},)
261def login_page(request):
262 """
263 Platform login page
264 """
265 page = get_object_or_404(TextPage, slug="discuss-data-loginpage")
266 return render(request, "login.html", {"page": page},)
269def handler404(request):
270 response = render(request, "404.html")
271 response.status_code = 404
272 return response
275def handler403(request):
276 response = render(request, "403.html")
277 response.status_code = 403
278 return response
281def response403(message):
282 response = HttpResponse(_(message))
283 # response.status_code = 403
284 return response
287def handler500(request, *args, **argv):
288 try:
289 from sentry_sdk import last_event_id
290 except ImportError:
291 response = render(request, "500.html")
292 response.status_code = 500
293 return response
294 else:
295 return render(
296 request, "500.html", {"sentry_event_id": last_event_id()}, status=500
297 )
300def get_keyword_tags(request):
301 qs = KeywordTagged.objects.all()
302 query = None
303 if query:
304 return qs.filter(name__istartswith=query)
306 return render(request, "core/_tags.html", {"qs": qs})
309def polling_start(request):
310 response = HttpResponse()
311 response["X-IC-ResumePolling"] = "true"
312 return response
315def polling_stop(request):
316 response = HttpResponse()
317 response["X-IC-CancelPolling"] = "true"
318 return response
321def load(request):
322 # return an empty response when core:load url is called.
323 # needed for js initialisation in _tag_add_control.html
324 response = HttpResponse()
325 return response
328def messages(request):
329 return render(request, "core/_messages.html", {})