Пример #1
0
def home(request):
    """
        The main page of Goose. Shows the search form, validate it
        and redirect to "results" if it's correct.
    """
    base_template = "base.html"
    if request.method == "POST":
        form = SearchForm(request.POST)
        if form.is_valid():
            form.clean()
            user_latitude = form.cleaned_data["latitude"]
            user_longitude = form.cleaned_data["longitude"]
            calculated_address = form.cleaned_data["calculated_address"]
            request.session["search_form"] = {
                "user_latitude": user_latitude,
                "user_longitude": user_longitude,
                "user_address": calculated_address,
                "radius": form.cleaned_data["radius"],
                "search_preset_id": form.cleaned_data["search_preset"].id,
                "no_private": form.cleaned_data["no_private"],
            }
            return redirect("results")
    else:
        form = SearchForm()
    return render(request, "search/home.html", locals())
Пример #2
0
 def test_form_validation_invalid(self):
     # Address and coordinates.
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "Fridtjof Nansens plass, Oslo",
         "radius": "800",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     self.assertFalse(form.is_valid())
     # Neither address nor coordinates.
     form_data = {
         "user_latitude": "",
         "user_longitude": "",
         "user_address": "",
         "radius": "800",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     # No radius.
     form_data = {
         "user_latitude": "",
         "user_longitude": "",
         "user_address": "Fridtjof Nansens plass, Oslo",
         "radius": "",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     self.assertFalse(form.is_valid())
     # Invalid search preset.
     form_data = {
         "user_latitude": "",
         "user_longitude": "",
         "user_address": "Fridtjof Nansens plass, Oslo",
         "radius": "500",
         "search_preset": "9999",
         "no_private": "on"
     }
     form = SearchForm(form_data)
     self.assertFalse(form.is_valid())
     # Invalid address.
     form_data = {
         "user_latitude": "",
         "user_longitude": "",
         "user_address": "Fridof Nansens plass, Oslo",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     form.is_valid()
     with self.assertRaises(ValidationError):
         form.clean(mocking_parameters="invalid_address")
     return
Пример #3
0
 def test_light_search(self):
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("Validation of the form failed.")
     form.clean()
     response = self.client.post('/light/', data=form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     self.assertTemplateUsed(response, "base_light.html")
     self.assertContains(response, "Voici votre localisation ")
     self.assertContains(response, "Latitude : 64.14624")
     self.assertContains(response, "Longitude : -21.94259")
     self.assertContains(response, "Adresse : ")
     self.assertContains(
         response, 'Recherche : "Boulangerie / Pâtisserie"')
     self.assertContains(response, " dans un rayon de 500 mètres.")
     self.assertContains(response, "Exclusion des résultats à accès privé.")
     self.assertContains(response, "Nom : City Hall of Reykjavik")
     self.assertContains(response, "Distance : 11990937 mètres")
     self.assertContains(response, "Direction : 107,6° E →")
     self.assertContains(response,
                         ('Téléphone : <a href="tel:+354 411 1111">'
                          '+354 411 1111</a>'))
     self.assertContains(response, 'Adresse estimée : ')
     # Same test, but including private results.
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "False"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("Validation of the form failed.")
     form.clean()
     response = self.client.post('/light/', data=form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     self.assertTemplateUsed(response, "base_light.html")
     self.assertContains(response, "Inclusion des résultats à accès privé.")
     return
Пример #4
0
 def test_results_page(self):
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("La validation du formulaire a échoué.")
     form.clean()
     response = self.client.post('/', data=form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     self.assertTemplateUsed(response, "base.html")
     self.assertContains(response, "Voici votre localisation ")
     self.assertContains(response, "Latitude : 64.14624")
     self.assertContains(response, "Longitude : -21.94259")
     self.assertContains(response, "Adresse : ")
     self.assertContains(
         response, 'Recherche : &quot;Boulangerie / Pâtisserie&quot;')
     self.assertContains(response, " dans un rayon de 500 mètres.")
     self.assertContains(response, "Exclusion des résultats à accès privé.")
     # Same test, but including private results.
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "False"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("La validation du formulaire a échoué.")
     form.clean()
     response = self.client.post('/', data=form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     self.assertTemplateUsed(response, "base.html")
     self.assertContains(response, "Voici votre localisation ")
     self.assertContains(response, "Latitude : 64.14624")
     self.assertContains(response, "Longitude : -21.94259")
     self.assertContains(response, "Adresse : ")
     self.assertContains(
         response, 'Recherche : &quot;Boulangerie / Pâtisserie&quot;')
     self.assertContains(response, " dans un rayon de 500 mètres.")
     self.assertContains(response, "Inclusion des résultats à accès privé.")
     return
Пример #5
0
 def test_js_variables(self):
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("Validation of the form failed.")
     form.clean()
     response = self.client.post('/', data=form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     self.assertContains(response, "var userLatitude = 64.14624;")
     self.assertContains(response, "var userLongitude = -21.94259;")
     self.assertContains(response, "var radius = 500;")
     self.assertContains(
         response, "var searchPresetId = {};".format(self.search_preset_id))
     self.assertContains(response, "var noPrivate = true;")
     return
Пример #6
0
 def test_session_data(self):
     form_data = {
         "user_latitude": "64.14624",
         "user_longitude": "-21.94259",
         "user_address": "",
         "radius": "500",
         "search_preset": self.search_preset_id,
         "no_private": "on"
     }
     form = SearchForm(form_data)
     if not form.is_valid():
         self.fail("Validation of the form failed.")
     form.clean()
     response = self.client.post('/', form_data, follow=True)
     self.assertEqual(response.status_code, 200)
     session = self.client.session
     self.assertEqual(type(session["search_form"]["user_latitude"]), float)
     self.assertEqual(type(session["search_form"]["user_longitude"]), float)
     self.assertEqual(type(session["search_form"]["user_address"]), str)
     self.assertEqual(session["search_form"]["radius"], 500)
     self.assertEqual(session["search_form"]["search_preset_id"],
                      self.search_preset_id)
     self.assertEqual(session["search_form"]["no_private"], True)
     return
Пример #7
0
def light_home(request):
    """
        The main page of the light version of Goose.
        The results are displayed on the same page
        to avoid a redirection.
    """
    base_template = "base_light.html"
    get_params = (
        request.GET.get("sp"),
        request.GET.get("lat"),
        request.GET.get("lon"),
        request.GET.get("radius"),
        request.GET.get("no_private")
    )
    if request.method != "POST" and not all(get_params):
        form = SearchForm()
        return render(request, "search/home.html", locals())
    if not all(get_params):
        form = SearchForm(request.POST)
        if not form.is_valid():
            return render(request, "search/home.html", locals())
        form.clean()
    was_limited = getattr(request, 'limited', False)
    errors = []
    if all(get_params):
        use_get_params = True
        get_params_valid = True
        try:
            search_preset_id = int(get_params[0])
            search_preset = SearchPreset.objects.get(id=search_preset_id)
        except (SearchPreset.DoesNotExist, ValueError):
            get_params_valid = False
            errors.append(_("L'ID de l'objet de votre recherche est invalide."))
            search_preset_id = 0
            search_preset = None
        try:
            user_latitude = float(get_params[1])
            user_longitude = float(get_params[2])
        except ValueError:
            get_params_valid = False
            errors.append(_("Vos coordonnées sont invalides."))
            user_latitude = 0.0
            user_longitude = 0.0
        if settings.TESTING:
            mocking_parameters = request.GET.get("mocking_parameters")
        else:
            mocking_parameters = None
        user_address = user_address = utils.get_address(
            coords=(float(user_latitude), float(user_longitude)),
            mocking_parameters=mocking_parameters
        )
        if user_address:
            user_address = escape(user_address[1])
        else:
            user_address = _("Adresse inconnue")
            # Does not set "get_params_valid" to False, because
            # the address is not useful for searching.
            errors.append(_(
                "Vos coordonnées n'ont pas permis de trouver votre "
                "adresse actuelle."
            ))
        try:
            radius = int(get_params[3])
            radius_extreme_values = settings.GOOSE_META["radius_extreme_values"]
            if radius % 10 != 0 or not (
                radius_extreme_values[0] <= radius <= radius_extreme_values[1]
            ):
                raise ValueError
        except ValueError:
            get_params_valid = False
            errors.append(_("Le rayon de recherche demandé est invalide."))
            radius = 0
        no_private = get_params[4] == '1'
    else:
        use_get_params = False
        get_params_valid = None
        search_preset = form.cleaned_data["search_preset"]
        user_latitude = form.cleaned_data["latitude"]
        user_longitude = form.cleaned_data["longitude"]
        user_address = escape(form.cleaned_data["calculated_address"])
        radius = form.cleaned_data["radius"]
        no_private = form.cleaned_data["no_private"]
    user_coords = (user_latitude, user_longitude)
    
    if search_preset:
        if no_private:
            search_description = (_(
                '"{search_preset}" dans un rayon de {radius} mètres. '
                'Exclusion des résultats à accès privé.'
            ))
        else:
            search_description = (_(
                '"{search_preset}" dans un rayon de {radius} mètres. '
                'Inclusion des résultats à accès privé.'
            ))
        search_description = search_description.format(
            search_preset=search_preset.name, radius=radius
        )
    else:
        search_description = _("Paramètres invalides.")
    
    if was_limited:
        error.append('\n' + _(
            "Trop de requêtes ont été faites en trop peu de temps. "
            "Merci d'attendre quelques secondes avant de raffraichir la page."
        ))
    error_msg = '<br/>\n'.join(errors)
    
    permalink = utils.get_permalink(request, use_get_params, search_preset.id, user_latitude, user_longitude, radius, no_private)
    if use_get_params and not get_params_valid:
        return render(request, "search/light_results.html", {
            "user_coords": user_coords,
            "user_address": user_address,
            "search_description": search_description,
            "permalink": permalink,
            "error_msg": error_msg
        })
    
    timezone_name = tf.timezone_at(lat=user_latitude, lng=user_longitude)
    if timezone_name is None:
        timezone_name = tf.closest_timezone_at(lat=user_latitude, lng=user_longitude)
    if timezone_name is None:
        timezone_name = 'UTC'
    
    results = []
    error_msg = ''
    try:
        results = utils.get_results(
            search_preset, user_coords, radius,
            no_private, timezone_name
        )
        utils.get_all_addresses(results)
        debug_logger.debug("Request successfull!")
    except geopy.exc.GeopyError as e:
        error_msg = _(
            "Une erreur s'est produite lors de l'acquisition "
            "de vos coordonnées. Vous pouvez essayer de recharger "
            "la page dans quelques instants."
        )
        debug_msg = str(e)
        debug_logger.debug("Geopy error: {}".format(str(e)))
    except overpass.OverpassError as e:
        error_msg = _(
            "Une erreur s'est produite lors de la requête vers "
            "les serveurs d'OpenStreetMap. Vous pouvez essayer "
            "de recharger la page dans quelques instants."
        )
        debug_msg = str(e)
        debug_logger.debug("Overpass error: {}".format(str(e)))
    except Exception as e:
        error_msg = _("Une erreur non prise en charge s'est produite.")
        debug_msg = str(e)
        debug_logger.debug("Unhandled error: {}".format(str(e)))
        raise e
    # Logs the request to make statistics.
    # Doesn't logs if the request comes from an authenticated user,
    # as it is probably an admin.
    if not request.user.is_authenticated():
        logger = logging.getLogger("statistics")
        logger.info(
            "search:{id}:{radius}:{lat}:{lon}".format(
                id=search_preset.id,
                radius=radius,
                # Rounds the stored coordinates for privacy's sake.
                lat=round(user_latitude),
                lon=round(user_longitude)
            )
        )
    
    return render(request, "search/light_results.html", {
        "results": results,
        "user_coords": user_coords,
        "user_address": user_address,
        "search_description": search_description,
        "permalink": permalink,
        "error_msg": error_msg
    })