예제 #1
0
def geocode(str, max_size=DEFAULT_RESULT_MAX_SIZE, add_geohash=True, resolve_to_ids=False, constrain_to_city=None):
    """
    default geocoder
    """
    from common.models import City, Country

    results = telmap_geocode(str, max_size, constrain_to_city)
    logging.info(u"geocoding results for %s: %s\n" % (str, results))

    if add_geohash or resolve_to_ids:
        for result in results:
            if add_geohash:
                result["geohash"] = geohash_encode(result["lon"], result["lat"])

            if resolve_to_ids:
                result["country"] = Country.get_id_by_code(result["country"])

                if is_in_hebrew(result["city"]):
                    result["city"] = City.get_id_by_name_and_country(
                        result["city"], result["country"], add_if_not_found=True
                    )
                else:
                    # try to reverse geocode to get city name in Hebrew
                    reverse_geocode_result = reverse_geocode(result["lat"], result["lon"])
                    if reverse_geocode_result:
                        result["city"] = reverse_geocode_result["city"]
                    else:
                        logging.error("failed to get Hebrew city name from reverse geocode")
                        result["city"] = City.get_id_by_name_and_country(
                            result["city"], result["country"], add_if_not_found=True
                        )

    return results
예제 #2
0
    def create(self, request, *args, **kwargs):
        api_user = kwargs["api_user"]
        request_data = request.data.get("request")
        if not request_data:
            return rc.BAD_REQUEST

        language_code = request_data.get("language_code")
        translation.activate(language_code)

        passenger = None
        phone_number = request_data.get("phone_number")
        login_token = request_data.get("login_token")

        try:
            if login_token: #TODO_WB: merge needed to make this work
                passenger = Passenger.objects.get(login_token=login_token)
            elif phone_number and not api_user.phone_validation_required:
                passenger = Passenger.objects.get(phone=phone_number) 
        except Passenger.DoesNotExist:
            pass

        if not passenger:
            return rc.NOT_FOUND #TODO_WB: is this the right response

        order_data = {}
        for address_type in ('from', 'to'):
            for att, val in request_data[address_type].items():
                order_data[address_type + "_" + att] = val or ""

            if not is_valid_address(order_data, address_type):
                res = rc.BAD_REQUEST
                res.write(" %s\n" % ErrorCodes.INVALID_ADDRESS)
                return res

            order_data[address_type + "_country"] = Country.get_id_by_code(order_data[address_type + "_country"])
            order_data[address_type + "_city"] = City.get_id_by_name_and_country(order_data[address_type + "_city"], order_data[address_type + "_country"], add_if_not_found=True)

        order_form = OrderForm(data=order_data, passenger=passenger)
        if order_form.is_valid():

            order = order_form.save()
            order.api_user = api_user
            order.passenger = passenger
            order.language_code = language_code
            order.save()
            book_order_async(order)
            log_event(EventType.ORDER_BOOKED, order=order)
            return rc.CREATED
        else:
            response = rc.BAD_REQUEST
            response.write(" %s\n" % order_form.errors.as_text())
            return response
예제 #3
0
def reverse_geocode(latitude, longitude):
    from common.models import Country, City

    result = telmap_reverse_geocode(latitude, longitude)
    if result:
        house_number = result.get("house_number")
        if not house_number or not house_number.isdigit():
            return None

        result["country_name"] = result["country"]
        result["country"] = Country.get_id_by_code(result["country"])
        result["city_name"] = result["city"]
        result["city"] = City.get_id_by_name_and_country(result["city"], result["country"], add_if_not_found=True)
        result["geohash"] = geohash_encode(longitude, latitude)

    return result
예제 #4
0
class StationProfileForm(forms.Form, Id2Model):
    name = forms.CharField(label=_("Station name"))
    password = forms.CharField(label=_("Change password"), widget=forms.PasswordInput(), required=False)
    password2 = forms.CharField(label=_("Re-enter password"), widget=forms.PasswordInput(), required=False)
    country_id = forms.IntegerField(widget=forms.Select(choices=Country.country_choices()), label=_("Country"))
    city_id = forms.IntegerField(widget=forms.Select(choices=[("", "-------------")]), label=_("City"))
    address = forms.CharField(label=_("Address"))
    number_of_taxis = forms.RegexField(regex=r'^\d+$',
                                       max_length=4,
                                       widget=forms.TextInput(),
                                       label=_("Number of taxis"),
                                       error_messages={'invalid': _("The value must contain only numbers.")})

    website_url = forms.CharField(label=_("Website URL"), required=False)
    #    language = form.
    email = forms.EmailField(label=_("Email"))
    #    logo = AppEngineImageField(label=_("Logo"), required=False)
    description = forms.CharField(label=_("Description"), widget=forms.Textarea, required=False)
    lon = forms.FloatField(widget=forms.HiddenInput(), required=False)
    lat = forms.FloatField(widget=forms.HiddenInput(), required=False)

    class Ajax:
        rules = [
                ('password2', {'equal_to_field': 'password'}),
                ]
        messages = [
                ('password2', {'equal_to_field': _("The two password fields didn't match.")}),
                ]

    def clean_address(self):
        if not INITIAL_DATA in self.data:
            if not (self.data['lon'] and self.data['lat']):
                raise forms.ValidationError(_("Invalid address"))

        return self.cleaned_data['address']


    def clean(self):
        """
        """
        self.id_field_to_model('country_id', Country)
        self.id_field_to_model('city_id', City)

        self.cleaned_data['city'] = self.cleaned_data['city_id']
        self.cleaned_data['country'] = self.cleaned_data['country_id']

        return self.cleaned_data
예제 #5
0
def reverse_geocode(latitude, longitude):
    from common.models import Country, City

    result = telmap_reverse_geocode(latitude, longitude)
    if result:
        house_number = result.get("house_number")
        if not house_number or not house_number.isdigit():
            return None

        result["country_name"] = result["country"]
        result["country"] = Country.get_id_by_code(result["country"])
        result["city_name"] = result["city"]
        result["city"] = City.get_id_by_name_and_country(result["city"],
                                                         result["country"],
                                                         add_if_not_found=True)
        result["geohash"] = geohash_encode(longitude, latitude)

    return result
예제 #6
0
def is_phone_registered(local_phone):
    """
    checks if the given phone already registered (belongs to a registered user)
    """
    phone_registered = False

    passengers = Passenger.objects.filter(phone=local_phone).filter(country=Country.get_id_by_code("IL"))
    if passengers.count() > 0:
        try:
            user = passengers[0].user
        except User.DoesNotExist:
            user = None

        phone_registered = user is not None
    else:
        phone_registered = False

    return phone_registered
예제 #7
0
def geocode(str,
            max_size=DEFAULT_RESULT_MAX_SIZE,
            add_geohash=True,
            resolve_to_ids=False,
            constrain_to_city=None):
    """
    default geocoder
    """
    from common.models import City, Country

    results = telmap_geocode(str, max_size, constrain_to_city)
    logging.info(u"geocoding results for %s: %s\n" % (str, results))

    if add_geohash or resolve_to_ids:
        for result in results:
            if add_geohash:
                result["geohash"] = geohash_encode(result["lon"],
                                                   result["lat"])

            if resolve_to_ids:
                result["country"] = Country.get_id_by_code(result["country"])

                if is_in_hebrew(result["city"]):
                    result["city"] = City.get_id_by_name_and_country(
                        result["city"],
                        result["country"],
                        add_if_not_found=True)
                else:
                    # try to reverse geocode to get city name in Hebrew
                    reverse_geocode_result = reverse_geocode(
                        result["lat"], result["lon"])
                    if reverse_geocode_result:
                        result["city"] = reverse_geocode_result["city"]
                    else:
                        logging.error(
                            "failed to get Hebrew city name from reverse geocode"
                        )
                        result["city"] = City.get_id_by_name_and_country(
                            result["city"],
                            result["country"],
                            add_if_not_found=True)

    return results
예제 #8
0
def is_phone_registered(local_phone):
    """
    checks if the given phone already registered (belongs to a registered user)
    """
    phone_registered = False

    passengers = Passenger.objects.filter(phone=local_phone).filter(
        country=Country.get_id_by_code("IL"))
    if passengers.count() > 0:
        try:
            user = passengers[0].user
        except User.DoesNotExist:
            user = None

        phone_registered = user is not None
    else:
        phone_registered = False

    return phone_registered
예제 #9
0
class StationRegistrationForm(forms.Form):
    """
    Form for registering a new user account.

    Validates that the requested username is not already in use, and
    requires the password to be entered twice to catch typos.

    Subclasses should feel free to add any additional validation they
    need, but should avoid defining a ``save()`` method -- the actual
    saving of collected user data is delegated to the active
    registration backend.

    """
    first_name = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=30)),
        label=_("first name"))
    last_name = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=30)),
        label=_("last name"))
    name = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=50)),
        label=_("station name"))

    license_number = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=30)),
        label=_("license number"))

    username = forms.RegexField(
        regex=r'^\w+$',
        max_length=30,
        widget=forms.TextInput(attrs=attrs_dict),
        label=_("username"),
        error_messages={
            'invalid':
            _("This value must contain only letters, numbers and underscores.")
        })

    password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict,
                                                           render_value=False),
                                label=_("password"))

    password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict,
                                                           render_value=False),
                                label=_("password (again)"))
    email = forms.EmailField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=75)),
        label=_("email address"))

    default_country = Country.objects.get(code=settings.DEFAULT_COUNTRY_CODE)
    country = forms.IntegerField(widget=forms.Select(
        attrs=attrs_dict, choices=Country.country_choices()),
                                 label=_("country"))
    country.initial = default_country.id

    city_choices = [(c.id, c.name)
                    for c in City.objects.filter(country=default_country)]
    city = forms.IntegerField(widget=forms.Select(attrs=attrs_dict,
                                                  choices=city_choices),
                              label=_("City"))

    address = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=80)),
        label=_("address"))
    language_choice = LANGUAGE_CHOICES
    language = forms.IntegerField(widget=forms.Select(attrs=attrs_dict,
                                                      choices=language_choice),
                                  label=_("language"))

    website_url = forms.CharField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=255)),
        label=_("website url"),
        required=False)

    local_phone = forms.RegexField(
        regex=r'^\d+$',
        max_length=20,
        widget=forms.TextInput(attrs=attrs_dict),
        label=_("local phone number"),
        error_messages={'invalid': _("The value must contain only numbers.")})

    logo = forms.FileField(widget=BlobWidget(attrs=dict(attrs_dict)),
                           label=_("logo"),
                           required=False)

    number_of_taxis = forms.IntegerField(
        widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=30)),
        label=_("number of taxis"))

    description = forms.CharField(
        widget=forms.Textarea(attrs=dict(attrs_dict, maxlength=80)),
        label=_("description"),
        required=False)

    def clean_username(self):
        """
        Validate that the username is alphanumeric and is not already
        in use.
        
        """
        try:
            user = User.objects.get(username=self.cleaned_data['username'])
        except User.DoesNotExist:
            return self.cleaned_data['username']
        raise forms.ValidationError(
            _("A user with that username already exists."))

    def clean(self):
        """
        Verifiy that the values entered into the two password fields
        match. Note that an error here will end up in
        ``non_field_errors()`` because it doesn't apply to a single
        field.
        
        """
        if 'city' in self.cleaned_data:
            city = City.objects.get(id=self.cleaned_data['city'])
            self.cleaned_data['city'] = city

        if 'country' in self.cleaned_data:
            country = Country.objects.get(id=self.cleaned_data['country'])
            self.cleaned_data['country'] = country

        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
                raise forms.ValidationError(
                    _("The two password fields didn't match."))
        return self.cleaned_data