diff --git a/apps/account/serializers/web.py b/apps/account/serializers/web.py index d325cea6..8d6fadf7 100644 --- a/apps/account/serializers/web.py +++ b/apps/account/serializers/web.py @@ -1,6 +1,5 @@ """Serializers for account web""" from django.contrib.auth import password_validation as password_validators -from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from account import models @@ -25,7 +24,7 @@ class PasswordResetSerializer(serializers.Serializer): if not user.is_authenticated: if not username_or_email: - raise serializers.ValidationError(_('username or email not in request body.')) + raise utils_exceptions.UserNotFoundError() filters = {} if username_validator(username_or_email): diff --git a/apps/authorization/views/common.py b/apps/authorization/views/common.py index 98f79bd9..4231ed7a 100644 --- a/apps/authorization/views/common.py +++ b/apps/authorization/views/common.py @@ -116,7 +116,7 @@ class OAuth2SignUpView(OAuth2ViewMixin, JWTGenericViewMixin): source = serializer.validated_data.get('source') request_data.update({ 'grant_type': settings.OAUTH2_SOCIAL_AUTH_GRANT_TYPE, - 'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME + 'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME, }) # Use the rest framework `.data` to fake the post body of the django request. diff --git a/apps/location/models.py b/apps/location/models.py index 7d7cd8a2..7084385f 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -104,6 +104,11 @@ class Address(models.Model): def longitude(self): return self.coordinates.x + @property + def location_field_indexing(self): + return {'lat': self.latitude, + 'lon': self.longitude} + # todo: Make recalculate price levels @receiver(post_save, sender=Country) diff --git a/apps/search_indexes/__init__.py b/apps/search_indexes/__init__.py index e69de29b..f610ac3f 100644 --- a/apps/search_indexes/__init__.py +++ b/apps/search_indexes/__init__.py @@ -0,0 +1 @@ +from search_indexes.signals import update_document \ No newline at end of file diff --git a/apps/search_indexes/documents/establishment.py b/apps/search_indexes/documents/establishment.py index a12e23c8..b82bc579 100644 --- a/apps/search_indexes/documents/establishment.py +++ b/apps/search_indexes/documents/establishment.py @@ -14,13 +14,42 @@ EstablishmentIndex.settings(number_of_shards=1, number_of_replicas=1) class EstablishmentDocument(Document): """Establishment document.""" - description = fields.ObjectField(properties=OBJECT_FIELD_PROPERTIES) + description = fields.ObjectField(attr='description_indexing', + properties=OBJECT_FIELD_PROPERTIES) tags = fields.ObjectField( properties={ 'id': fields.IntegerField(attr='id'), 'label': fields.ObjectField(attr='label') }, multi=True) + address = fields.ObjectField( + properties={ + 'id': fields.IntegerField(), + 'street_name_1': fields.TextField( + fields={'raw': fields.KeywordField()} + ), + 'street_name_2': fields.TextField( + fields={'raw': fields.KeywordField()} + ), + 'number': fields.IntegerField(), + 'location': fields.GeoPointField(attr='location_field_indexing'), + 'city': fields.ObjectField( + properties={ + 'id': fields.IntegerField(), + 'name': fields.KeywordField(), + 'is_island': fields.BooleanField(), + 'country': fields.ObjectField( + properties={ + 'id': fields.IntegerField(), + 'name': fields.ObjectField(attr='name_indexing', + properties=OBJECT_FIELD_PROPERTIES), + 'code': fields.KeywordField(), + } + ), + } + ), + } + ) class Django: @@ -28,13 +57,9 @@ class EstablishmentDocument(Document): fields = ( 'id', 'name', - 'public_mark', 'toque_number', 'price_level', ) - def prepare_description(self, instance): - return instance.description - def prepare_tags(self, instance): return instance.tags_indexing diff --git a/apps/search_indexes/serializers.py b/apps/search_indexes/serializers.py index f4c27c9b..ed8b65eb 100644 --- a/apps/search_indexes/serializers.py +++ b/apps/search_indexes/serializers.py @@ -40,6 +40,7 @@ class NewsDocumentSerializer(DocumentSerializer): return get_translated_value(obj.description) +# todo: country_name_translated class EstablishmentDocumentSerializer(DocumentSerializer): """Establishment document serializer.""" @@ -58,6 +59,7 @@ class EstablishmentDocumentSerializer(DocumentSerializer): 'price_level', 'description_translated', 'tags', + 'address', ) @staticmethod diff --git a/apps/search_indexes/signals.py b/apps/search_indexes/signals.py new file mode 100644 index 00000000..21618155 --- /dev/null +++ b/apps/search_indexes/signals.py @@ -0,0 +1,33 @@ +"""Search indexes app signals.""" +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver +from django_elasticsearch_dsl.registries import registry + + +@receiver(post_save) +def update_document(sender, **kwargs): + from establishment.models import Establishment + app_label = sender._meta.app_label + model_name = sender._meta.model_name + instance = kwargs['instance'] + + if app_label == 'location': + if model_name == 'country': + establishments = Establishment.objects.filter( + address__city__country=instance) + for establishment in establishments: + registry.update(establishment) + + if model_name == 'city': + establishments = Establishment.objects.filter( + address__city=instance) + for establishment in establishments: + registry.update(establishment) + + if model_name == 'Address': + establishments = Establishment.objects.filter( + address=instance) + for establishment in establishments: + registry.update(establishment) + +# todo: delete document diff --git a/apps/search_indexes/utils.py b/apps/search_indexes/utils.py index a3cfac87..93be9e81 100644 --- a/apps/search_indexes/utils.py +++ b/apps/search_indexes/utils.py @@ -7,6 +7,7 @@ from utils.models import get_current_language OBJECT_FIELD_PROPERTIES = { 'en-GB': fields.TextField(analyzer='english'), 'ru-RU': fields.TextField(analyzer='russian'), + 'fr-FR': fields.TextField(analyzer='french'), } diff --git a/apps/search_indexes/views.py b/apps/search_indexes/views.py index 5dbaf8fd..31d982a4 100644 --- a/apps/search_indexes/views.py +++ b/apps/search_indexes/views.py @@ -66,6 +66,7 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet): constants.LOOKUP_QUERY_GTE, constants.LOOKUP_QUERY_LT, constants.LOOKUP_QUERY_LTE, + constants.LOOKUP_QUERY_IN, ] }, 'price_level': { @@ -76,6 +77,13 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet): constants.LOOKUP_QUERY_GTE, constants.LOOKUP_QUERY_LT, constants.LOOKUP_QUERY_LTE, + constants.LOOKUP_QUERY_IN, ] }, + 'country_id': { + 'field': 'address.city.country.id' + }, + 'country': { + 'field': 'address.city.country.code' + } } diff --git a/apps/utils/models.py b/apps/utils/models.py index 22a7de98..92db5c47 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -55,6 +55,24 @@ def translate_field(self, field_name): return translate +# todo: refactor this +class IndexJSON: + + def __getattr__(self, item): + return None + + +def index_field(self, field_name): + def index(self): + field = getattr(self, field_name) + obj = IndexJSON() + if isinstance(field, dict): + for key, value in field.items(): + setattr(obj, key, value) + return obj + return index + + class TranslatedFieldsMixin: """Translated Fields mixin""" @@ -69,6 +87,8 @@ class TranslatedFieldsMixin: if isinstance(field, TJSONField): setattr(cls, f'{field.name}_translated', property(translate_field(self, field_name))) + setattr(cls, f'{field_name}_indexing', + property(index_field(self, field_name))) def __str__(self): """Overrided __str__ method.""" diff --git a/apps/utils/views.py b/apps/utils/views.py index 9af89360..8333b34a 100644 --- a/apps/utils/views.py +++ b/apps/utils/views.py @@ -67,7 +67,7 @@ class JWTGenericViewMixin(generics.GenericAPIView): # todo: remove config for develop from os import environ configuration = environ.get('SETTINGS_CONFIGURATION', None) - if configuration == 'development': + if configuration == 'development' or configuration == 'stage': response.set_cookie(key=cookie.key, value=cookie.value, secure=cookie.secure, diff --git a/project/settings/base.py b/project/settings/base.py index 71fbf147..1a54b1b7 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -256,6 +256,10 @@ OAUTH2_PROVIDER_APPLICATION_MODEL = 'authorization.Application' # Facebook configuration SOCIAL_AUTH_FACEBOOK_KEY = '386843648701452' SOCIAL_AUTH_FACEBOOK_SECRET = 'a71cf0bf3980843a8f1ea74c6d805fd7' +SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', ] +SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { + 'fields': 'id, name, email', +} # SMS Settings SMS_EXPIRATION = 5 diff --git a/project/templates/account/change_email.html b/project/templates/account/change_email.html index 40c1b227..0a257ed6 100644 --- a/project/templates/account/change_email.html +++ b/project/templates/account/change_email.html @@ -3,7 +3,7 @@ {% trans "Please go to the following page for confirmation new email address:" %} -https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %} diff --git a/project/templates/account/password_reset_email.html b/project/templates/account/password_reset_email.html index ee84fd0b..9fb3fbf3 100644 --- a/project/templates/account/password_reset_email.html +++ b/project/templates/account/password_reset_email.html @@ -3,7 +3,7 @@ {% trans "Please go to the following page and choose a new password:" %} -https://{{ country_code }}.{{ domain_uri }}/recovery/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/recovery/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %} diff --git a/project/templates/authorization/confirm_email.html b/project/templates/authorization/confirm_email.html index f3bbd50e..3e51add7 100644 --- a/project/templates/authorization/confirm_email.html +++ b/project/templates/authorization/confirm_email.html @@ -2,8 +2,7 @@ {% blocktrans %}You're receiving this email because you trying to register new account at {{ site_name }}.{% endblocktrans %} {% trans "Please confirm your email address to complete the registration:" %} - -https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %}