"""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(ip_addr): """Determine country code.""" country_code = None if ip_addr: try: geoip = GeoIP2() country_code = geoip.country_code(ip_addr) country_code = country_code.lower() except GeoIP2Exception as ex: logger.info(f'GEOIP Exception: {ex}. ip: {ip_addr}') except Exception as ex: logger.error(f'GEOIP Base exception: {ex}') return country_code def determine_coordinates(ip_addr: str) -> Tuple[Optional[float], Optional[float]]: if ip_addr: try: geoip = GeoIP2() return geoip.coords(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, 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(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 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)