From 3273ea0fb9edf32c7ff779f66b34d5459fa61f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zahradn=C3=ADk?= Date: Mon, 28 Oct 2024 10:30:36 +0100 Subject: [PATCH] add primary language to country --- bullet/countries/middleware.py | 97 +++++++++----- .../0008_branchcountry_primary_language.py | 122 ++++++++++++++++++ bullet/countries/models.py | 1 + 3 files changed, 186 insertions(+), 34 deletions(-) create mode 100644 bullet/countries/migrations/0008_branchcountry_primary_language.py diff --git a/bullet/countries/middleware.py b/bullet/countries/middleware.py index 63eadeb3..9be98f93 100644 --- a/bullet/countries/middleware.py +++ b/bullet/countries/middleware.py @@ -2,15 +2,15 @@ from re import Match, Pattern from django.conf import settings -from django.http import HttpRequest, HttpResponseRedirect +from django.http import HttpRequest, HttpResponse, HttpResponseRedirect from django.urls import reverse from django.utils import timezone, translation from countries.logic import country -from countries.logic.cache import get_country_cache from countries.models import BranchCountry country_language_re: Pattern[str] = re.compile(r"^/([a-z]{2})/([^/]+)/") +url_path_re: Pattern[str] = re.compile(r"^/[a-z]{2}/[^/]+/(.*)") def country_language_from_request( @@ -27,47 +27,76 @@ class CountryLanguageMiddleware: def __init__(self, get_response): self.get_response = get_response + def redirect_to_selector(self): + return HttpResponseRedirect(reverse("country_selector")) + def __call__(self, request: HttpRequest): c, lang = country_language_from_request(request) - if c and not request._is_admin_domain: - cache: dict[int, dict[str, list[tuple[str, bool]]]] = get_country_cache() - if request.BRANCH is not None and ( - c not in cache[request.BRANCH.id] - or ( - (lang, True) not in cache[request.BRANCH.id][c] - and (lang, False) not in cache[request.BRANCH.id][c] - ) - ): - return HttpResponseRedirect(reverse("country_selector")) - - country.activate(c) - request.COUNTRY_CODE = c - - branch_country = BranchCountry.objects.get( - branch=request.BRANCH, country=c.upper() - ) - timezone.activate(branch_country.timezone) - - translation.activate(lang) - request.LANGUAGE_CODE = translation.get_language() - else: + if not c or request._is_admin_domain: # Use default settings if not detected. timezone.activate(settings.TIME_ZONE) translation.activate(settings.LANGUAGE_CODE) request.LANGUAGE_CODE = translation.get_language() + return self.get_response(request) + + redirect = self.set_country_language(request, c, lang) + if redirect: + return redirect response = self.get_response(request) + self.set_cookies(request, response) + return response + + def get_url_part(self, request) -> str | None: + match = url_path_re.match(request.path_info) + if not match: + return None + + return match.groups()[0] - if c and not request._is_admin_domain: - ckie = request.COOKIES.get("bullet_country", "") - expected = f"{c}|{lang}" - if ckie != expected: - response.set_cookie( - "bullet_country", - expected, - expires=365 * 24 * 60 * 60, - samesite="Lax", + def set_country_language( + self, request: HttpRequest, country_name, language + ) -> HttpResponse | None: + branch_country: BranchCountry = BranchCountry.objects.filter( + branch=request.BRANCH, country=country_name.upper() + ).first() + + if branch_country is None: + return self.redirect_to_selector() + + if language not in branch_country.languages: + url_part = self.get_url_part(request) + if branch_country.primary_language and url_part: + new_url = ( + f"/{country_name}/{branch_country.primary_language}/{url_part}" ) + return HttpResponseRedirect(new_url) + return self.redirect_to_selector() - return response + timezone.activate(branch_country.timezone) + + country.activate(country_name) + request.COUNTRY_CODE = country_name + + translation.activate(language) + request.LANGUAGE_CODE = translation.get_language() + + return None + + def set_cookies(self, request, response): + country = request.COUNTRY_CODE + language = request.LANGUAGE_CODE + + if not country or not language: + return + + ckie = request.COOKIES.get("bullet_country", "") + expected = f"{country}|{language}" + if ckie != expected: + response.set_cookie( + "bullet_country", + expected, + expires=365 * 24 * 60 * 60, + samesite="Lax", + ) diff --git a/bullet/countries/migrations/0008_branchcountry_primary_language.py b/bullet/countries/migrations/0008_branchcountry_primary_language.py new file mode 100644 index 00000000..dcfafa96 --- /dev/null +++ b/bullet/countries/migrations/0008_branchcountry_primary_language.py @@ -0,0 +1,122 @@ +# Generated by Django 5.1 on 2024-10-28 08:36 + +import web.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("countries", "0007_branchcountry_hidden_languages_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="branchcountry", + name="primary_language", + field=web.fields.LanguageField( + blank=True, + choices=[ + ("af", "Afrikaans"), + ("ar", "Arabic"), + ("ar-dz", "Algerian Arabic"), + ("ast", "Asturian"), + ("az", "Azerbaijani"), + ("bg", "Bulgarian"), + ("be", "Belarusian"), + ("bn", "Bengali"), + ("br", "Breton"), + ("bs", "Bosnian"), + ("ca", "Catalan"), + ("ckb", "Central Kurdish (Sorani)"), + ("cs", "Czech"), + ("cy", "Welsh"), + ("da", "Danish"), + ("de", "German"), + ("dsb", "Lower Sorbian"), + ("el", "Greek"), + ("en", "English"), + ("en-au", "Australian English"), + ("en-gb", "British English"), + ("eo", "Esperanto"), + ("es", "Spanish"), + ("es-ar", "Argentinian Spanish"), + ("es-co", "Colombian Spanish"), + ("es-mx", "Mexican Spanish"), + ("es-ni", "Nicaraguan Spanish"), + ("es-ve", "Venezuelan Spanish"), + ("et", "Estonian"), + ("eu", "Basque"), + ("fa", "Persian"), + ("fi", "Finnish"), + ("fr", "French"), + ("fy", "Frisian"), + ("ga", "Irish"), + ("gd", "Scottish Gaelic"), + ("gl", "Galician"), + ("he", "Hebrew"), + ("hi", "Hindi"), + ("hr", "Croatian"), + ("hsb", "Upper Sorbian"), + ("hu", "Hungarian"), + ("hy", "Armenian"), + ("ia", "Interlingua"), + ("id", "Indonesian"), + ("ig", "Igbo"), + ("io", "Ido"), + ("is", "Icelandic"), + ("it", "Italian"), + ("ja", "Japanese"), + ("ka", "Georgian"), + ("kab", "Kabyle"), + ("kk", "Kazakh"), + ("km", "Khmer"), + ("kn", "Kannada"), + ("ko", "Korean"), + ("ky", "Kyrgyz"), + ("lb", "Luxembourgish"), + ("lt", "Lithuanian"), + ("lv", "Latvian"), + ("mk", "Macedonian"), + ("ml", "Malayalam"), + ("mn", "Mongolian"), + ("mr", "Marathi"), + ("ms", "Malay"), + ("my", "Burmese"), + ("nb", "Norwegian Bokmål"), + ("ne", "Nepali"), + ("nl", "Dutch"), + ("nn", "Norwegian Nynorsk"), + ("os", "Ossetic"), + ("pa", "Punjabi"), + ("pl", "Polish"), + ("pt", "Portuguese"), + ("pt-br", "Brazilian Portuguese"), + ("ro", "Romanian"), + ("ru", "Russian"), + ("sk", "Slovak"), + ("sl", "Slovenian"), + ("sq", "Albanian"), + ("sr", "Serbian"), + ("sr-latn", "Serbian Latin"), + ("sv", "Swedish"), + ("sw", "Swahili"), + ("ta", "Tamil"), + ("te", "Telugu"), + ("tg", "Tajik"), + ("th", "Thai"), + ("tk", "Turkmen"), + ("tr", "Turkish"), + ("tt", "Tatar"), + ("udm", "Udmurt"), + ("ug", "Uyghur"), + ("uk", "Ukrainian"), + ("ur", "Urdu"), + ("uz", "Uzbek"), + ("vi", "Vietnamese"), + ("zh-hans", "Simplified Chinese"), + ("zh-hant", "Traditional Chinese"), + ], + max_length=8, + ), + ), + ] diff --git a/bullet/countries/models.py b/bullet/countries/models.py index e4fee24e..a2df8b0e 100644 --- a/bullet/countries/models.py +++ b/bullet/countries/models.py @@ -8,6 +8,7 @@ class BranchCountry(models.Model): branch = BranchField() country = CountryField() + primary_language = LanguageField(blank=True) languages = ChoiceArrayField(LanguageField()) timezone = TimeZoneField() email = models.EmailField()