Example #1
0
	def ajax_api_view(self, request, slug, extra_context=None):
		"""
		Returns a JSON object containing the following variables:
		
		search
			Contains the slug for the search.
		results
			Contains the results of :meth:`.Result.get_context` for each result.
		rendered
			Contains the results of :meth:`.Result.render` for each result.
		hasMoreResults
			``True`` or ``False`` whether the search has more results according to :meth:`BaseSearch.has_more_results`
		moreResultsURL
			Contains ``None`` or a querystring which, once accessed, will note the :class:`Click` and redirect the user to a page containing more results.
		
		"""
		search_string = request.GET.get(SEARCH_ARG_GET_KEY)
		
		if not request.is_ajax() or not self.enable_ajax_api or slug not in registry or slug not in self.searches or search_string is None:
			raise Http404
		
		search_instance = get_search_instance(slug, search_string)
		
		return HttpResponse(json.dumps({
			'search': search_instance.slug,
			'results': [result.get_context() for result in search_instance.results],
			'hasMoreResults': search_instance.has_more_results,
			'moreResultsURL': search_instance.more_results_url,
		}), mimetype="application/json")
Example #2
0
    def ajax_api_view(self, request, slug, extra_context=None):
        """
		Returns a JSON object containing the following variables:
		
		search
			Contains the slug for the search.
		results
			Contains the results of :meth:`.Result.get_context` for each result.
		rendered
			Contains the results of :meth:`.Result.render` for each result.
		hasMoreResults
			``True`` or ``False`` whether the search has more results according to :meth:`BaseSearch.has_more_results`
		moreResultsURL
			Contains ``None`` or a querystring which, once accessed, will note the :class:`Click` and redirect the user to a page containing more results.
		
		"""
        search_string = request.GET.get(SEARCH_ARG_GET_KEY)

        if not request.is_ajax(
        ) or not self.enable_ajax_api or slug not in registry or slug not in self.searches or search_string is None:
            raise Http404

        search_instance = get_search_instance(slug, search_string)

        return HttpResponse(json.dumps({
            'search':
            search_instance.slug,
            'results':
            [result.get_context() for result in search_instance.results],
            'hasMoreResults':
            search_instance.has_more_results,
            'moreResultsURL':
            search_instance.more_results_url,
        }),
                            mimetype="application/json")
Example #3
0
	def results_view(self, request, extra_context=None):
		"""
		Renders :attr:`results_page` with a context containing an instance of :attr:`search_form`. If the form was submitted and was valid, then one of two things has happened:
		
		* A search has been initiated. In this case, a list of search instances will be added to the context as ``searches``. If :attr:`enable_ajax_api` is enabled, each instance will have an ``ajax_api_url`` attribute containing the url needed to make an AJAX request for the search results.
		* A link has been chosen. In this case, corresponding :class:`Search`, :class:`ResultURL`, and :class:`Click` instances will be created and the user will be redirected to the link's actual url.
		
		"""
		results = None
		
		context = self.get_context()
		context.update(extra_context or {})
		
		if SEARCH_ARG_GET_KEY in request.GET:
			form = self.search_form(request.GET)
			
			if form.is_valid():
				search_string = request.GET[SEARCH_ARG_GET_KEY].lower()
				url = request.GET.get(URL_REDIRECT_GET_KEY)
				hash = request.GET.get(HASH_REDIRECT_GET_KEY)
				
				if url and hash:
					if check_redirect_hash(hash, search_string, url):
						# Create the necessary models
						search = Search.objects.get_or_create(string=search_string)[0]
						result_url = search.result_urls.get_or_create(url=url)[0]
						result_url.clicks.create(datetime=datetime.datetime.now())
						return HttpResponseRedirect(url)
					else:
						messages.add_message(request, messages.INFO, "The link you followed had been tampered with. Here are all the results for your search term instead!")
						# TODO: Should search_string be escaped here?
						return HttpResponseRedirect("%s?%s=%s" % (request.path, SEARCH_ARG_GET_KEY, search_string))
				
				search_instances = []
				for slug in self.searches:
					if slug in registry:
						search_instance = get_search_instance(slug, search_string)
						search_instances.append(search_instance)
					
						if self.enable_ajax_api:
							search_instance.ajax_api_url = "%s?%s=%s" % (self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node), SEARCH_ARG_GET_KEY, search_string)
				
				if eventlet and not self.enable_ajax_api:
					pool = eventlet.GreenPool()
					for instance in search_instances:
						pool.spawn_n(lambda x: x.results, search_instance)
					pool.waitall()
				
				context.update({
					'searches': search_instances,
					'favored_results': []
				})
				
				try:
					search = Search.objects.get(string=search_string)
				except Search.DoesNotExist:
					pass
				else:
					context['favored_results'] = [r.url for r in search.get_favored_results()]
		else:
			form = SearchForm()
		
		context.update({
			'form': form
		})
		return self.results_page.render_to_response(request, extra_context=context)
Example #4
0
    def results_view(self, request, extra_context=None):
        """
		Renders :attr:`results_page` with a context containing an instance of :attr:`search_form`. If the form was submitted and was valid, then one of two things has happened:
		
		* A search has been initiated. In this case, a list of search instances will be added to the context as ``searches``. If :attr:`enable_ajax_api` is enabled, each instance will have an ``ajax_api_url`` attribute containing the url needed to make an AJAX request for the search results.
		* A link has been chosen. In this case, corresponding :class:`Search`, :class:`ResultURL`, and :class:`Click` instances will be created and the user will be redirected to the link's actual url.
		
		"""
        results = None

        context = self.get_context()
        context.update(extra_context or {})

        if SEARCH_ARG_GET_KEY in request.GET:
            form = self.search_form(request.GET)

            if form.is_valid():
                search_string = request.GET[SEARCH_ARG_GET_KEY].lower()
                url = request.GET.get(URL_REDIRECT_GET_KEY)
                hash = request.GET.get(HASH_REDIRECT_GET_KEY)

                if url and hash:
                    if check_redirect_hash(hash, search_string, url):
                        # Create the necessary models
                        search = Search.objects.get_or_create(
                            string=search_string)[0]
                        result_url = search.result_urls.get_or_create(
                            url=url)[0]
                        result_url.clicks.create(
                            datetime=datetime.datetime.now())
                        return HttpResponseRedirect(url)
                    else:
                        messages.add_message(
                            request, messages.INFO,
                            "The link you followed had been tampered with. Here are all the results for your search term instead!"
                        )
                        # TODO: Should search_string be escaped here?
                        return HttpResponseRedirect(
                            "%s?%s=%s" %
                            (request.path, SEARCH_ARG_GET_KEY, search_string))

                search_instances = []
                for slug in self.searches:
                    if slug in registry:
                        search_instance = get_search_instance(
                            slug, search_string)
                        search_instances.append(search_instance)

                        if self.enable_ajax_api:
                            search_instance.ajax_api_url = "%s?%s=%s" % (
                                self.reverse('ajax_api_view',
                                             kwargs={'slug': slug},
                                             node=request.node),
                                SEARCH_ARG_GET_KEY, search_string)

                if eventlet and not self.enable_ajax_api:
                    pool = eventlet.GreenPool()
                    for instance in search_instances:
                        pool.spawn_n(lambda x: x.results, search_instance)
                    pool.waitall()

                context.update({
                    'searches': search_instances,
                    'favored_results': []
                })

                try:
                    search = Search.objects.get(string=search_string)
                except Search.DoesNotExist:
                    pass
                else:
                    context['favored_results'] = [
                        r.url for r in search.get_favored_results()
                    ]
        else:
            form = SearchForm()

        context.update({'form': form})
        return self.results_page.render_to_response(request,
                                                    extra_context=context)