From e36d51cc0bc43f3b8d8da3ab08d4ac8240d6ccc2 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:23:41 +0800 Subject: [PATCH] perf: country code api (#13672) * perf: remove notification migrations * perf: country code api --------- Co-authored-by: ibuler --- apps/common/api/common.py | 19 ++++++--- apps/common/const/choices.py | 62 ++++++++++++++++++++++------- apps/common/urls/api_urls.py | 1 + apps/settings/api/public.py | 3 +- apps/settings/serializers/public.py | 1 - poetry.lock | 13 +++++- pyproject.toml | 1 + 7 files changed, 76 insertions(+), 24 deletions(-) diff --git a/apps/common/api/common.py b/apps/common/api/common.py index 8dfbc1ca9..988e85361 100644 --- a/apps/common/api/common.py +++ b/apps/common/api/common.py @@ -5,18 +5,18 @@ import uuid from django.core.cache import cache from django.views.decorators.csrf import csrf_exempt - -from rest_framework.views import APIView -from rest_framework.response import Response from rest_framework import generics, serializers +from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from rest_framework.views import APIView +from common.const import KEY_CACHE_RESOURCE_IDS, COUNTRY_CALLING_CODES from common.permissions import IsValidUser -from common.views.http import HttpResponseTemporaryRedirect from common.utils import get_logger -from common.const import KEY_CACHE_RESOURCE_IDS +from common.views.http import HttpResponseTemporaryRedirect __all__ = [ - 'LogTailApi', 'ResourcesIDCacheApi' + 'LogTailApi', 'ResourcesIDCacheApi', 'CountryListApi' ] logger = get_logger(__file__) @@ -96,6 +96,13 @@ class ResourcesIDCacheApi(APIView): return Response({'spm': spm}) +class CountryListApi(APIView): + permission_classes = (AllowAny,) + + def get(self, request, *args, **kwargs): + return Response(COUNTRY_CALLING_CODES) + + @csrf_exempt def redirect_plural_name_api(request, *args, **kwargs): resource = kwargs.get("resource", "") diff --git a/apps/common/const/choices.py b/apps/common/const/choices.py index aa30b1d1d..3eb0f2a58 100644 --- a/apps/common/const/choices.py +++ b/apps/common/const/choices.py @@ -1,11 +1,58 @@ +import phonenumbers +import pycountry from django.db import models from django.utils.translation import gettext_lazy as _ +from phonenumbers import PhoneMetadata ADMIN = 'Admin' USER = 'User' AUDITOR = 'Auditor' +def get_country_phone_codes(): + phone_codes = [] + for region_code in phonenumbers.SUPPORTED_REGIONS: + phone_metadata = PhoneMetadata.metadata_for_region(region_code) + if phone_metadata: + phone_codes.append((region_code, phone_metadata.country_code)) + return phone_codes + + +def get_country(region_code): + country = pycountry.countries.get(alpha_2=region_code) + if country: + return country + else: + return None + + +def get_country_phone_choices(): + codes = get_country_phone_codes() + choices = [] + for code, phone in codes: + country = get_country(code) + if not country: + continue + country_name = country.name + flag = country.flag + + if country.name == 'China': + country_name = _('China') + + if code == 'TW': + country_name = 'Taiwan' + flag = get_country('CN').flag + choices.append({ + 'name': country_name, + 'phone_code': f'+{phone}', + 'flag': flag, + 'code': code, + }) + + choices.sort(key=lambda x: x['name']) + return choices + + class Trigger(models.TextChoices): manual = 'manual', _('Manual trigger') timing = 'timing', _('Timing trigger') @@ -28,17 +75,4 @@ class Language(models.TextChoices): jp = 'ja', '日本語', -COUNTRY_CALLING_CODES = [ - {'name': 'China(中国)', 'value': '+86'}, - {'name': 'HongKong(中国香港)', 'value': '+852'}, - {'name': 'Macao(中国澳门)', 'value': '+853'}, - {'name': 'Taiwan(中国台湾)', 'value': '+886'}, - {'name': 'America(America)', 'value': '+1'}, - {'name': 'Russia(Россия)', 'value': '+7'}, - {'name': 'France(français)', 'value': '+33'}, - {'name': 'Britain(Britain)', 'value': '+44'}, - {'name': 'Germany(Deutschland)', 'value': '+49'}, - {'name': 'Japan(日本)', 'value': '+81'}, - {'name': 'Korea(한국)', 'value': '+82'}, - {'name': 'India(भारत)', 'value': '+91'} -] +COUNTRY_CALLING_CODES = get_country_phone_choices() diff --git a/apps/common/urls/api_urls.py b/apps/common/urls/api_urls.py index 452e47540..923a5f54b 100644 --- a/apps/common/urls/api_urls.py +++ b/apps/common/urls/api_urls.py @@ -9,4 +9,5 @@ app_name = 'common' urlpatterns = [ path('resources/cache/', api.ResourcesIDCacheApi.as_view(), name='resources-cache'), + path('countries/', api.CountryListApi.as_view(), name='resources-cache'), ] diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index 804ac470b..0c2568a39 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -3,7 +3,7 @@ from rest_framework import generics from rest_framework.permissions import AllowAny from authentication.permissions import IsValidUserOrConnectionToken -from common.const.choices import COUNTRY_CALLING_CODES, Language +from common.const.choices import Language from common.utils import get_logger, lazyproperty from common.utils.timezone import local_now from .. import serializers @@ -26,7 +26,6 @@ class OpenPublicSettingApi(generics.RetrieveAPIView): return { "XPACK_ENABLED": settings.XPACK_ENABLED, "INTERFACE": self.interface_setting, - "COUNTRY_CALLING_CODES": COUNTRY_CALLING_CODES, "LANGUAGES": [ { 'name': title, diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index 8c0031b29..32ab1e61c 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -11,7 +11,6 @@ __all__ = [ class PublicSettingSerializer(serializers.Serializer): XPACK_ENABLED = serializers.BooleanField() INTERFACE = serializers.DictField() - COUNTRY_CALLING_CODES = serializers.ListField() LANGUAGES = serializers.ListField() diff --git a/poetry.lock b/poetry.lock index 0d6ee74a1..1d6801644 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4258,6 +4258,17 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.7.0" +[[package]] +name = "pycountry" +version = "24.6.1" +description = "ISO country, subdivision, language, currency and script definitions and their translations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycountry-24.6.1-py3-none-any.whl", hash = "sha256:f1a4fb391cd7214f8eefd39556d740adcc233c778a27f8942c8dca351d6ce06f"}, + {file = "pycountry-24.6.1.tar.gz", hash = "sha256:b61b3faccea67f87d10c1f2b0fc0be714409e8fcdcc1315613174f6466c10221"}, +] + [[package]] name = "pycparser" version = "2.21" @@ -6474,4 +6485,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "663cfb5f4a5c53f2d667e7eb5436ed81ceebf97521008e7118e3db47f6ce20bf" +content-hash = "750e14deaf075de2d69164d39ea3d7908de2bb60b75e28a8702077dbf5eb60f1" diff --git a/pyproject.toml b/pyproject.toml index fb8e52a4b..acbce761e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -167,6 +167,7 @@ elasticsearch8 = "8.13.2" polib = "^1.2.0" # psycopg2 = "2.9.6" psycopg2-binary = "2.9.6" +pycountry = "^24.6.1" [tool.poetry.group.xpack] optional = true