Example #1
0
    def post(self, request, *args, **kwargs):
        # validate request parameters and prepare search
        serializer = SearchSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        data["drilldown_names"] = filters_app.metadata.get_filter_field_names()

        client = SearchApiClient()

        res = client.search(**data)
        records = res["records"]
        records = add_extra_parameters_to_materials(filters_app.metadata,
                                                    records)

        filter_categories = MpttFilterItemSerializer(
            filters_app.metadata.tree,
            many=True,
            context={'drilldowns': res["drilldowns"]})

        if data['page'] == 1 and data["search_text"]:
            add_search_query_to_log(res["recordcount"], data["search_text"],
                                    data["filters"])

        rv = dict(records=records,
                  records_total=res["recordcount"],
                  filter_categories=filter_categories.data,
                  page=data["page"],
                  page_size=data["page_size"],
                  did_you_mean=res["did_you_mean"])
        return Response(rv)
Example #2
0
    def get(self, request, *args, **kwargs):
        # validate request parameters
        serializer = MaterialsRequestSerializer(data=request.GET)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        # default is false in the serializer
        count_view = data["count_view"]
        if "external_id" in kwargs:
            return self.get_material(request,
                                     kwargs["external_id"],
                                     count_view=count_view,
                                     shared=data.get("shared"))

        if "external_id" in data:
            res = _get_material_by_external_id(request,
                                               data["external_id"],
                                               shared=data.get("shared"))

        else:
            # return overview of newest Materials
            client = SearchApiClient()
            res = client.search('',
                                ordering="-publisher_date",
                                page_size=_MATERIALS_COUNT_IN_OVERVIEW)
            res = add_extra_parameters_to_materials(filters_app.metadata,
                                                    res["records"])
        return Response(res)
Example #3
0
 def get_object(self):
     serializer = self.get_serializer(data=self.request.GET)
     serializer.is_valid(raise_exception=True)
     author_name = serializer.validated_data["author_name"]
     client = SearchApiClient()
     result = client.author_suggestions(author_name)
     result["results"] = add_extra_parameters_to_materials(
         filters_app.metadata, result["results"])
     return result
Example #4
0
    def get(self, request, *args, **kwargs):
        serializer = MaterialShortSerializer(data=request.GET)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        results = _get_material_by_external_id(request, data['external_id'])
        parts = results[0]['has_parts']

        client = SearchApiClient()
        api_response = client.get_materials_by_id(parts, page_size=100)
        return Response(api_response)
Example #5
0
 def get_object(self):
     serializer = self.get_serializer(data=self.request.GET)
     serializer.is_valid(raise_exception=True)
     external_id = serializer.validated_data["external_id"]
     language = serializer.validated_data["language"]
     client = SearchApiClient()
     result = client.more_like_this(external_id, language)
     result["results"] = add_extra_parameters_to_materials(
         filters_app.metadata, result["results"])
     return result
Example #6
0
    def get(self, request, *args, **kwargs):
        # validate request parameters
        serializer = KeywordsRequestSerializer(data=request.GET)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        client = SearchApiClient()

        res = client.autocomplete(**data)
        return Response(res)
Example #7
0
    def sync_info(self):
        assert self.external_id, "Can't sync info if instance doesn't have an external id"

        # Fetch data from search engine
        client = SearchApiClient()
        response = client.get_materials_by_id([self.external_id])
        records = response.get("records", [])
        if not records:
            if not self.deleted_at:
                self.delete()
            return

        # Update the model
        if self.deleted_at:  # we restore materials if they reappear in an index
            self.deleted_at = None
        self.save()
    def setUpClass(cls):
        super().setUpClass()

        math_and_education_studies = [
            "7afbb7a6-c29b-425c-9c59-6f79c845f5f0",  # math
            "0861c43d-1874-4788-b522-df8be575677f"  # onderwijskunde
        ]
        biology_studies = ["2b363227-8633-4652-ad57-c61f1efc02c8"]
        biology_and_education_studies = biology_studies + [
            "0861c43d-1874-4788-b522-df8be575677f"
        ]

        cls.instance = SearchApiClient()
        cls.search.index(
            index=settings.OPENSEARCH_NL_INDEX,
            body=generate_nl_material(educational_levels=["HBO"],
                                      source="surfsharekit",
                                      studies=math_and_education_studies),
        )
        cls.search.index(id="abc",
                         index=settings.OPENSEARCH_NL_INDEX,
                         body=generate_nl_material(
                             educational_levels=["HBO"],
                             source="surfsharekit",
                             studies=math_and_education_studies,
                             external_id="abc",
                             title="De wiskunde van Jezus",
                             description="Groots zijn zijn getallen"))
        cls.search.index(
            index=settings.OPENSEARCH_NL_INDEX,
            body=generate_nl_material(
                educational_levels=["HBO"],
                source="surfsharekit",
                copyright="cc-by-40",
                topic="biology",
                publisher_date="2018-04-16T22:35:09+02:00",
                studies=biology_and_education_studies),
        )
        cls.search.index(
            index=settings.OPENSEARCH_NL_INDEX,
            body=generate_nl_material(
                educational_levels=["HBO"],
                source="surfsharekit",
                topic="biology",
                publisher_date="2019-04-16T22:35:09+02:00",
                studies=biology_and_education_studies),
        )
        cls.search.index(
            index=settings.OPENSEARCH_NL_INDEX,
            body=generate_nl_material(educational_levels=["HBO"],
                                      technical_type="video",
                                      source="surfsharekit",
                                      topic="biology",
                                      studies=biology_studies),
            refresh=True  # always put refresh on the last material
        )
Example #9
0
def get_material_details_by_id(external_id):
    """
    Request from ES and return details of material by its id

    :param external_id: id of material
    :return: list containing updated material
    """
    client = SearchApiClient()
    response = client.get_materials_by_id([external_id])
    records = response.get("records", [])
    if not records:
        return records

    material = records[0]
    details = Material.objects.filter(external_id=external_id,
                                      deleted_at=None).first()
    material["number_of_collections"] = details.collections.filter(
        deleted_at=None).count() if details else 0
    return [material]
Example #10
0
def add_search_query_to_log(number_of_results, query, filters):
    api_client = SearchApiClient()
    if not api_client.client.indices.exists(index='search-results'):
        create_search_results_index(api_client.client)

    document = {
        'timestamp':
        datetime.datetime.utcnow().replace(
            tzinfo=datetime.timezone.utc).isoformat(),
        'number_of_results':
        number_of_results,
        'query':
        query,
        'filters':
        _get_translated_filters(filters)
    }
    api_client.client.index('search-results', body=document)
Example #11
0
    def materials(self, request, pk=None, **kwargs):
        instance = self.get_object()

        if request.method == "GET":
            # validate request parameters
            serializer = CollectionMaterialsRequestSerializer(data=request.GET)
            serializer.is_valid(raise_exception=True)
            data = serializer.validated_data
            ids = [
                m.external_id
                for m in instance.materials.order_by("id").filter()
            ]

            rv = dict(records=[],
                      records_total=0,
                      filters=[],
                      page=data["page"],
                      page_size=data["page_size"])

            if ids:
                client = SearchApiClient()

                res = client.get_materials_by_id(ids, 1, len(ids))
                records = res.get("records", [])
                records = add_extra_parameters_to_materials(
                    filters_app.metadata, records)

                collection_materials = CollectionMaterial.objects.filter(
                    collection=instance,
                    material__external_id__in=[
                        r['external_id'] for r in records
                    ])

                for collection_material in collection_materials:
                    record = next(r for r in records if r['external_id'] ==
                                  collection_material.material.external_id)
                    record['featured'] = collection_material.featured
                    record['position'] = collection_material.position

                rv["records"] = records
                rv["records_total"] = res["recordcount"]

            return Response(rv)

        data = []
        for d in request.data:
            # validate request parameters
            if request.method == "POST":
                serializer = CollectionMaterialPositionSerializer(data=d)
            elif request.method == "DELETE":
                serializer = MaterialShortSerializer(data=d)
            else:
                raise MethodNotAllowed(request.method,
                                       detail="Method not supported")

            serializer.is_valid(raise_exception=True)
            data.append(serializer.validated_data)

        if request.method == "POST":
            self._add_materials(instance, data)

        elif request.method == "DELETE":
            self._delete_materials(instance, data)

        res = MaterialShortSerializer(many=True).to_representation(
            instance.materials.filter(deleted_at=None))
        return Response(res)
Example #12
0
 def get_object(self):
     client = SearchApiClient()
     return {"documents": client.stats()}
Example #13
0
 def all_materials(self, request, **kwargs):
     """
     Returns the number of all available materials
     """
     client = SearchApiClient()
     return Response(dict(value=client.stats()))