"""Main app methods.""" import logging from django.conf import settings from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception from geoip2.models import City from typing import Union, Tuple, Optional import pycountry from main import models logger = logging.getLogger(__name__) def site_url(schema, subdomain, domain): return f'{schema}://{subdomain}.{domain}' def get_user_ip(request): """Get user ip from request.""" META = request.META x_forwarded_for = META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = META.get('REMOTE_ADDR') return ip def determine_country_code(request): """Determine country code.""" META = request.META country_code = META.get('X-GeoIP-Country-Code', META.get('HTTP_X_GEOIP_COUNTRY_CODE')) if isinstance(country_code, str): return country_code.lower() def determine_country_name(request): """Determine country name.""" META = request.META return META.get('X-GeoIP-Country-Name', META.get('HTTP_X_GEOIP_COUNTRY_NAME')) def determine_coordinates(request): META = request.META longitude = META.get('X-GeoIP-Longitude', META.get('HTTP_X_GEOIP_LONGITUDE')) latitude = META.get('X-GeoIP-Latitude', META.get('HTTP_X_GEOIP_LATITUDE')) try: return float(longitude), float(latitude) except (TypeError, ValueError): return None, None def determine_user_site_url(country_code): """Determine user's site url.""" try: if country_code is None: raise ValueError # search localized site site = models.SiteSettings.objects.filter( country__code=country_code).first() # search default site if not site: site = models.SiteSettings.objects.filter(default_site=True).first() if not site: raise ValueError except Exception: return site_url(schema=settings.SCHEMA_URI, subdomain=settings.DEFAULT_SUBDOMAIN, domain=settings.SITE_DOMAIN_URI) else: return site.site_url def determine_user_city(request): META = request.META city = META.get('X-GeoIP-City', META.get('HTTP_X_GEOIP_CITY')) return city def determine_subdivision( country_alpha2_code: str, subdivision_code: Union[str, int] ) -> pycountry.Subdivision: """ :param country_alpha2_code: country code according to ISO 3166-1 alpha-2 standard :param subdivision_code: subdivision code according to ISO 3166-2 without country code prefix :return: subdivision """ iso3166_2_subdivision_code = f'{country_alpha2_code}-{subdivision_code}' return pycountry.subdivisions.get(code=iso3166_2_subdivision_code)