22from re import Match , Pattern
33
44from django .conf import settings
5- from django .http import HttpRequest , HttpResponseRedirect
5+ from django .http import HttpRequest , HttpResponse , HttpResponseRedirect
66from django .urls import reverse
77from django .utils import timezone , translation
88
99from countries .logic import country
10- from countries .logic .cache import get_country_cache
1110from countries .models import BranchCountry
1211
1312country_language_re : Pattern [str ] = re .compile (r"^/([a-z]{2})/([^/]+)/" )
13+ url_path_re : Pattern [str ] = re .compile (r"^/[a-z]{2}/[^/]+/(.*)" )
1414
1515
1616def country_language_from_request (
@@ -27,47 +27,76 @@ class CountryLanguageMiddleware:
2727 def __init__ (self , get_response ):
2828 self .get_response = get_response
2929
30+ def redirect_to_selector (self ):
31+ return HttpResponseRedirect (reverse ("country_selector" ))
32+
3033 def __call__ (self , request : HttpRequest ):
3134 c , lang = country_language_from_request (request )
3235
33- if c and not request ._is_admin_domain :
34- cache : dict [int , dict [str , list [tuple [str , bool ]]]] = get_country_cache ()
35- if request .BRANCH is not None and (
36- c not in cache [request .BRANCH .id ]
37- or (
38- (lang , True ) not in cache [request .BRANCH .id ][c ]
39- and (lang , False ) not in cache [request .BRANCH .id ][c ]
40- )
41- ):
42- return HttpResponseRedirect (reverse ("country_selector" ))
43-
44- country .activate (c )
45- request .COUNTRY_CODE = c
46-
47- branch_country = BranchCountry .objects .get (
48- branch = request .BRANCH , country = c .upper ()
49- )
50- timezone .activate (branch_country .timezone )
51-
52- translation .activate (lang )
53- request .LANGUAGE_CODE = translation .get_language ()
54- else :
36+ if not c or request ._is_admin_domain :
5537 # Use default settings if not detected.
5638 timezone .activate (settings .TIME_ZONE )
5739 translation .activate (settings .LANGUAGE_CODE )
5840 request .LANGUAGE_CODE = translation .get_language ()
41+ return self .get_response (request )
42+
43+ redirect = self .set_country_language (request , c , lang )
44+ if redirect :
45+ return redirect
5946
6047 response = self .get_response (request )
48+ self .set_cookies (request , response )
49+ return response
50+
51+ def get_url_part (self , request ) -> str | None :
52+ match = url_path_re .match (request .path_info )
53+ if not match :
54+ return None
55+
56+ return match .groups ()[0 ]
6157
62- if c and not request ._is_admin_domain :
63- ckie = request .COOKIES .get ("bullet_country" , "" )
64- expected = f"{ c } |{ lang } "
65- if ckie != expected :
66- response .set_cookie (
67- "bullet_country" ,
68- expected ,
69- expires = 365 * 24 * 60 * 60 ,
70- samesite = "Lax" ,
58+ def set_country_language (
59+ self , request : HttpRequest , country_name , language
60+ ) -> HttpResponse | None :
61+ branch_country : BranchCountry = BranchCountry .objects .filter (
62+ branch = request .BRANCH , country = country_name .upper ()
63+ ).first ()
64+
65+ if branch_country is None :
66+ return self .redirect_to_selector ()
67+
68+ if language not in branch_country .languages :
69+ url_part = self .get_url_part (request )
70+ if branch_country .primary_language and url_part :
71+ new_url = (
72+ f"/{ country_name } /{ branch_country .primary_language } /{ url_part } "
7173 )
74+ return HttpResponseRedirect (new_url )
75+ return self .redirect_to_selector ()
7276
73- return response
77+ timezone .activate (branch_country .timezone )
78+
79+ country .activate (country_name )
80+ request .COUNTRY_CODE = country_name
81+
82+ translation .activate (language )
83+ request .LANGUAGE_CODE = translation .get_language ()
84+
85+ return None
86+
87+ def set_cookies (self , request , response ):
88+ country = request .COUNTRY_CODE
89+ language = request .LANGUAGE_CODE
90+
91+ if not country or not language :
92+ return
93+
94+ ckie = request .COOKIES .get ("bullet_country" , "" )
95+ expected = f"{ country } |{ language } "
96+ if ckie != expected :
97+ response .set_cookie (
98+ "bullet_country" ,
99+ expected ,
100+ expires = 365 * 24 * 60 * 60 ,
101+ samesite = "Lax" ,
102+ )
0 commit comments