From 32de6f7705aae63f33bf50391c37d54f54183a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Wed, 16 Oct 2019 15:54:15 +0300 Subject: [PATCH 1/4] Readme --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 62dc8dc5..3cb1c6b9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ # gm-backend +## Build + +1. ``git clone ssh://git@gl.id-east.ru:222/gm/gm-backend.git`` +1. ``cd ./gm-backend`` +1. ``git checkout develop`` +1. ``docker-compose build`` +1. First start database: ``docker-compose up db`` +1. ``docker-compose up -d`` +### Migrate data + +1.Connect to container with django ``docker exec -it gm-backend_gm_app_1 bash`` + +#### In docker container(django) + +1. Migrate ``python manage.py migrate`` +1. Create super-user ``python manage.py createsuperuser`` + +Backend is available at localhost:8000 or 0.0.0.0:8000 + +URL for admin http://0.0.0.0:8000/admin +URL for swagger http://0.0.0.0:8000/docs/ +URL for redocs http://0.0.0.0:8000/redocs/ + +## Start and stop backend containers + +Demonize start ``docker-compose up -d`` +Stop ``docker-compose down`` +Stop and remove volumes ``docker-compose down -v`` \ No newline at end of file From 5176a455c1c4a9dde1c40af9397390ded946e12c Mon Sep 17 00:00:00 2001 From: Semyon Yekhmenin Date: Thu, 17 Oct 2019 07:03:48 +0000 Subject: [PATCH 2/4] Added method for getting coordinates and city by ip --- apps/main/methods.py | 22 ++++++++++++++++------ apps/main/urls.py | 1 + apps/main/views.py | 23 +++++++++++++++++++++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/apps/main/methods.py b/apps/main/methods.py index 67da3480..845a99a4 100644 --- a/apps/main/methods.py +++ b/apps/main/methods.py @@ -1,8 +1,10 @@ """Main app methods.""" import logging +from typing import Tuple, Optional from django.conf import settings from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception +from geoip2.models import City from main import models @@ -39,17 +41,16 @@ def determine_country_code(ip_addr): return country_code -def determine_coordinates(ip_addr): - longitude, latitude = None, None +def determine_coordinates(ip_addr: str) -> Tuple[Optional[float], Optional[float]]: if ip_addr: try: geoip = GeoIP2() - longitude, latitude = geoip.coords(ip_addr) + return geoip.coords(ip_addr) except GeoIP2Exception as ex: - logger.info(f'GEOIP Exception: {ex}. ip: {ip_addr}') + logger.warning(f'GEOIP Exception: {ex}. ip: {ip_addr}') except Exception as ex: - logger.error(f'GEOIP Base exception: {ex}') - return longitude, latitude + logger.warning(f'GEOIP Base exception: {ex}') + return None, None def determine_user_site_url(country_code): @@ -73,3 +74,12 @@ def determine_user_site_url(country_code): return site.site_url +def determine_user_city(ip_addr: str) -> Optional[City]: + try: + geoip = GeoIP2() + return geoip.city(ip_addr) + except GeoIP2Exception as ex: + logger.warning(f'GEOIP Exception: {ex}. ip: {ip_addr}') + except Exception as ex: + logger.warning(f'GEOIP Base exception: {ex}') + return None diff --git a/apps/main/urls.py b/apps/main/urls.py index a74c0b49..12a98c84 100644 --- a/apps/main/urls.py +++ b/apps/main/urls.py @@ -6,6 +6,7 @@ app = 'main' urlpatterns = [ path('determine-site/', views.DetermineSiteView.as_view(), name='determine-site'), + path('determine-location/', views.DetermineLocation.as_view(), name='determine-location'), path('sites/', views.SiteListView.as_view(), name='site-list'), path('site-settings//', views.SiteSettingsView.as_view(), name='site-settings'), path('awards/', views.AwardView.as_view(), name='awards_list'), diff --git a/apps/main/views.py b/apps/main/views.py index d7d1fa2c..ee06160e 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -3,6 +3,7 @@ from rest_framework import generics, permissions from rest_framework.response import Response from main import methods, models, serializers from utils.serializers import EmptySerializer +from django.http import Http404 class DetermineSiteView(generics.GenericAPIView): @@ -18,6 +19,22 @@ class DetermineSiteView(generics.GenericAPIView): return Response(data={'url': url}) +class DetermineLocation(generics.GenericAPIView): + """Determine user's location.""" + + permission_classes = (permissions.AllowAny,) + serializer_class = EmptySerializer + + def get(self, request, *args, **kwargs): + user_ip = methods.get_user_ip(request) + longitude, latitude = methods.determine_coordinates(user_ip) + city = methods.determine_user_city(user_ip) + if longitude and latitude and city: + return Response(data={'latitude': latitude, 'longitude': longitude, 'city': city}) + else: + raise Http404 + + class SiteSettingsView(generics.RetrieveAPIView): """Site settings View.""" @@ -34,6 +51,8 @@ class SiteListView(generics.ListAPIView): permission_classes = (permissions.AllowAny,) queryset = models.SiteSettings.objects.with_country() serializer_class = serializers.SiteSerializer + + # # class FeatureViewMixin: # """Feature view mixin.""" @@ -76,7 +95,7 @@ class AwardView(generics.ListAPIView): """Awards list view.""" serializer_class = serializers.AwardSerializer queryset = models.Award.objects.all() - permission_classes = (permissions.AllowAny, ) + permission_classes = (permissions.AllowAny,) class AwardRetrieveView(generics.RetrieveAPIView): @@ -90,5 +109,5 @@ class CarouselListView(generics.ListAPIView): """Return list of carousel items.""" queryset = models.Carousel.objects.all() serializer_class = serializers.CarouselListSerializer - permission_classes = (permissions.AllowAny, ) + permission_classes = (permissions.AllowAny,) pagination_class = None From e2c27bd2e1e7db6ed7e2c6092c050320c140c276 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 17 Oct 2019 13:40:52 +0300 Subject: [PATCH 3/4] switched broker storage from rabbtimq to redis --- project/settings/base.py | 5 ++++- project/settings/local.py | 7 +++++-- requirements/base.txt | 9 ++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/project/settings/base.py b/project/settings/base.py index 5c32f263..f89eff8d 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -317,7 +317,10 @@ REDOC_SETTINGS = { } # CELERY -BROKER_URL = 'amqp://rabbitmq:5672' +# RabbitMQ +# BROKER_URL = 'amqp://rabbitmq:5672' +# Redis +BROKER_URL = 'redis://base:6379/1' CELERY_RESULT_BACKEND = BROKER_URL CELERY_BROKER_URL = BROKER_URL CELERY_ACCEPT_CONTENT = ['application/json'] diff --git a/project/settings/local.py b/project/settings/local.py index a644e9b8..31fe88c2 100644 --- a/project/settings/local.py +++ b/project/settings/local.py @@ -6,7 +6,7 @@ ALLOWED_HOSTS = ['*', ] SEND_SMS = False SMS_CODE_SHOW = True -USE_CELERY = False +USE_CELERY = True SCHEMA_URI = 'http' DEFAULT_SUBDOMAIN = 'www' @@ -14,7 +14,10 @@ SITE_DOMAIN_URI = 'testserver.com:8000' DOMAIN_URI = '0.0.0.0:8000' # CELERY -BROKER_URL = 'amqp://rabbitmq:5672' +# RabbitMQ +# BROKER_URL = 'amqp://rabbitmq:5672' +# Redis +BROKER_URL = 'redis://redis:6379/1' CELERY_RESULT_BACKEND = BROKER_URL CELERY_BROKER_URL = BROKER_URL diff --git a/requirements/base.txt b/requirements/base.txt index 716d21c6..5c734322 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -15,8 +15,6 @@ djangorestframework==3.9.4 markdown django-filter==2.1.0 djangorestframework-xml -celery -amqp>=2.4.0 geoip2==2.9.0 django-phonenumber-field[phonenumbers]==2.1.0 @@ -33,4 +31,9 @@ djangorestframework-simplejwt==4.3.0 django-elasticsearch-dsl>=7.0.0,<8.0.0 django-elasticsearch-dsl-drf==0.20.2 -sentry-sdk==0.11.2 \ No newline at end of file +sentry-sdk==0.11.2 + +# temp solution +redis==3.2.0 +amqp>=2.4.0 +celery==4.3.0rc2 \ No newline at end of file From 8066d5607b0f324dae374a5effd5291bc13ef0d0 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 17 Oct 2019 13:41:40 +0300 Subject: [PATCH 4/4] comment all rabbitmq dependencies added redis to docker compose file --- docker-compose.yml | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7c4e49d2..3b446101 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: - "5436:5432" volumes: - gm-db:/var/lib/postgresql/data/ + elasticsearch: image: elasticsearch:7.3.1 volumes: @@ -27,11 +28,18 @@ services: - discovery.type=single-node - xpack.security.enabled=false - # RabbitMQ - rabbitmq: - image: rabbitmq:latest + # Redis + redis: + image: redis:2.8.23 ports: - - "5672:5672" + - "6379:6379" + + # RabbitMQ + #rabbitmq: + # image: rabbitmq:latest + # ports: + # - "5672:5672" + # Celery worker: build: . @@ -47,7 +55,9 @@ services: - .:/code links: - db - - rabbitmq +# - rabbitmq + - redis + worker_beat: build: . command: ./run_celery_beat.sh @@ -62,7 +72,8 @@ services: - .:/code links: - db - - rabbitmq +# - rabbitmq + - redis # App: G&M gm_app: build: . @@ -76,7 +87,8 @@ services: - DB_PASSWORD=postgres depends_on: - db - - rabbitmq +# - rabbitmq + - redis - worker - worker_beat - elasticsearch