Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
utils.py 2.78 KiB
# coding=utf-8
import datetime
from datetime import timedelta
from typing import List, Set

from django.contrib.admin.utils import NestedObjects
from django.db import models
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.text import capfirst

from web.algorithm import VerhoeffAlgorithm, LuhnAlgorithm


def strtobool(val):
    """Convert a string representation of truth to true (1) or false (0).

    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.

    From distutils lib.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return 1
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return 0
    else:
        raise ValueError(f"invalid truth value {val}")


def get_deleted_objects(objs: List[models.Model]):
    collector = NestedObjects(using='default')
    collector.collect(objs)

    #
    def format_callback(obj):
        opts = obj._meta
        no_edit_link = f'{capfirst(opts.verbose_name)}: {force_text(obj)}'
        return no_edit_link
        #

    to_delete = collector.nested(format_callback)
    protected = [format_callback(obj) for obj in collector.protected]
    model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()}
    #
    return to_delete, model_count, protected


def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip_address = x_forwarded_for.split(',')[0]
    else:
        ip_address = request.META.get('REMOTE_ADDR')
    return ip_address


def is_valid_social_security_number(number):
    if number is not None and number != '':
        if len(number) != 13:
            return False
        if not number.isdigit():
            return False
        if not LuhnAlgorithm.is_luhn_valid(number[:12]):
            return False
        if not VerhoeffAlgorithm.is_valid_verhoeff(number[:11] + number[12]):
            return False

    return True


def get_today_midnight_date():
    today = timezone.now()
    today_midnight = datetime.datetime(
        today.year,
        today.month,
        today.day,
        tzinfo=today.tzinfo
    )
    return today_midnight


def get_weekdays_in_period(from_date: datetime, to_date: datetime) -> Set[int]:
    """
    to_date is not included in the range

    Weekdays are returned as isoweekdays like the form described in week_choices from constants.py (starting at 1)
    """
    if to_date < from_date:
        return set([])
    day_generator = (from_date + timedelta(day)
                     for day in range((to_date - from_date).days))
    weekdays = {date.isoweekday() for date in day_generator}
    return weekdays