<commit_before># -*- coding: utf-8 -*-
from datetime import timedelta
from json import dumps
import socket
import struct
from collections import Iterator
import os
from functools import wraps
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import models
from djing.settings import PAGINATION_ITEMS_PER_PAGE, DEBUG


ip_addr_regex = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'


def ip2int(addr):
    try:
        return struct.unpack("!I", socket.inet_aton(addr))[0]
    except:
        return 0


def int2ip(addr):
    try:
        return socket.inet_ntoa(struct.pack("!I", addr))
    except:
        return ''


def safe_float(fl):
    try:
        return 0.0 if fl is None or fl == '' else float(fl)
    except ValueError:
        return 0.0


def safe_int(i):
    try:
        return 0 if i is None or i == '' else int(i)
    except ValueError:
        return 0


def res_success(request, redirect_to='/'):
    if request.is_ajax():
        return HttpResponse(dumps({'errnum': 0}))
    else:
        return redirect(redirect_to)


def res_error(request, text):
    if request.is_ajax():
        return HttpResponse(dumps({'errnum': 1, 'errtext': text}))
    else:
        raise Http404(text)


# Pagination
def pag_mn(request, objs, count_per_page=PAGINATION_ITEMS_PER_PAGE):
    page = request.GET.get('p')
    pgn = Paginator(objs, count_per_page)
    try:
        objs = pgn.page(page)
    except PageNotAnInteger:
        objs = pgn.page(1)
    except EmptyPage:
        objs = pgn.page(pgn.num_pages)
    return objs


class MyGenericIPAddressField(models.GenericIPAddressField):
    description = "Int32 notation ip address"

    def __init__(self, protocol='ipv4', *args, **kwargs):
        super().__init__(protocol=protocol, *args, **kwargs)
        self.max_length = 8

    def get_prep_value(self, value):
        # strIp to Int
        value = super().get_prep_value(value)
        return ip2int(value)

    def to_python(self, addr):
        return addr

    def get_internal_type(self):
        return 'PositiveIntegerField'

    @staticmethod
    def from_db_value(value, expression, connection, context):
        return int2ip(value)


# Предназначен для Django CHOICES чтоб можно было передавать классы вместо просто описания поля,
# классы передавать для того чтоб по значению кода из базы понять какой класс нужно взять для нужной функциональности.
# Например по коду в базе вам нужно определять как считать тариф абонента, что реализовано в возвращаемом классе.
class MyChoicesAdapter(Iterator):
    chs = tuple()
    current_index = 0
    _max_index = 0

    # На вход принимает кортеж кортежей, вложенный из 2х элементов: кода и класса, как: TARIFF_CHOICES
    def __init__(self, choices):
        self._max_index = len(choices)
        self.chs = choices

    def __next__(self):
        if self.current_index >= self._max_index:
            raise StopIteration
        else:
            e = self.chs
            ci = self.current_index
            res = e[ci][0], e[ci][1].description()
            self.current_index += 1
            return res


# Для сортировки таблиц
# через get должно быть передано order_by=<поле в бд> а в dir=<up|down> направление сортировки
# возвращает новое направление сортировки и поле для сортировки с направлением
def order_helper(request):
    dr = request.GET.get('dir')
    dfx = ''
    if dr == 'down':
        dr = 'up'
        dfx = '-'
    else:
        dr = 'down'

    orby = request.GET.get('order_by')
    if orby:
        return dr, dfx + orby
    else:
        return dr, orby


# Декоратор проверяет аккаунт, чтоб не пускать клиентов в страницы администрации
def only_admins(fn):
    @wraps(fn)
    def wrapped(request, *args, **kwargs):
        if request.user.is_admin:
            return fn(request, *args, **kwargs)
        else:
            return redirect('client_side:home')

    return wrapped


def ping(hostname):
    response = os.system("`which ping` -c 1 %s > /dev/null" % hostname)
    return True if response == 0 else False


# Русифицированный вывод timedelta
class RuTimedelta(timedelta):

    def __new__(cls, tm):
        if isinstance(tm, timedelta):
            return timedelta.__new__(
                cls,
                days=tm.days,
                seconds=tm.seconds,
                microseconds=tm.microseconds
            )

    def __str__(self):
        hours, remainder = divmod(self.seconds, 3600)
        minutes, seconds = divmod(remainder, 60)
        text_date = "%d:%d:%d" % (
            hours,
            minutes,
            seconds
        )
        if self.days > 1:
            ru_days = 'дней'
            if 5 > self.days > 1:
                ru_days = 'дня'
            elif self.days == 1:
                ru_days = 'день'
            text_date = '%d %s %s' % (self.days, ru_days, text_date)
        return text_date


def require_ssl(view):
    """
    Decorator that requires an SSL connection. If the current connection is not SSL, we redirect to the SSL version of
    the page.
    from: https://gist.github.com/ckinsey/9709984
    """
    @wraps(view)
    def wrapper(request, *args, **kwargs):
        if not DEBUG and not request.is_secure():
            target_url = "https://" + request.META['HTTP_HOST'] + request.path_info
            return HttpResponseRedirect(target_url)
        return view(request, *args, **kwargs)
    return wrapper


class MultipleException(Exception):

    def __init__(self, err_list):
        if not isinstance(err_list, list):
            raise TypeError
        self.err_list = err_list
<commit_msg>добавил метод для возвращения ip integer<commit_after># -*- coding: utf-8 -*-
from datetime import timedelta
from json import dumps
import socket
import struct
from collections import Iterator
import os
from functools import wraps
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import models
from djing.settings import PAGINATION_ITEMS_PER_PAGE, DEBUG


ip_addr_regex = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'


def ip2int(addr):
    try:
        return struct.unpack("!I", socket.inet_aton(addr))[0]
    except:
        return 0


def int2ip(addr):
    try:
        return socket.inet_ntoa(struct.pack("!I", addr))
    except:
        return ''


def safe_float(fl):
    try:
        return 0.0 if fl is None or fl == '' else float(fl)
    except ValueError:
        return 0.0


def safe_int(i):
    try:
        return 0 if i is None or i == '' else int(i)
    except ValueError:
        return 0


def res_success(request, redirect_to='/'):
    if request.is_ajax():
        return HttpResponse(dumps({'errnum': 0}))
    else:
        return redirect(redirect_to)


def res_error(request, text):
    if request.is_ajax():
        return HttpResponse(dumps({'errnum': 1, 'errtext': text}))
    else:
        raise Http404(text)


# Pagination
def pag_mn(request, objs, count_per_page=PAGINATION_ITEMS_PER_PAGE):
    page = request.GET.get('p')
    pgn = Paginator(objs, count_per_page)
    try:
        objs = pgn.page(page)
    except PageNotAnInteger:
        objs = pgn.page(1)
    except EmptyPage:
        objs = pgn.page(pgn.num_pages)
    return objs


class MyGenericIPAddressField(models.GenericIPAddressField):
    description = "Int32 notation ip address"

    def __init__(self, protocol='ipv4', *args, **kwargs):
        super().__init__(protocol=protocol, *args, **kwargs)
        self.max_length = 8

    def get_prep_value(self, value):
        # strIp to Int
        value = super().get_prep_value(value)
        return ip2int(value)

    def to_python(self, addr):
        return addr

    def get_internal_type(self):
        return 'PositiveIntegerField'

    @staticmethod
    def from_db_value(value, expression, connection, context):
        return int2ip(value)

    def int_ip(self):
        return ip2int(self)


# Предназначен для Django CHOICES чтоб можно было передавать классы вместо просто описания поля,
# классы передавать для того чтоб по значению кода из базы понять какой класс нужно взять для нужной функциональности.
# Например по коду в базе вам нужно определять как считать тариф абонента, что реализовано в возвращаемом классе.
class MyChoicesAdapter(Iterator):
    chs = tuple()
    current_index = 0
    _max_index = 0

    # На вход принимает кортеж кортежей, вложенный из 2х элементов: кода и класса, как: TARIFF_CHOICES
    def __init__(self, choices):
        self._max_index = len(choices)
        self.chs = choices

    def __next__(self):
        if self.current_index >= self._max_index:
            raise StopIteration
        else:
            e = self.chs
            ci = self.current_index
            res = e[ci][0], e[ci][1].description()
            self.current_index += 1
            return res


# Для сортировки таблиц
# через get должно быть передано order_by=<поле в бд> а в dir=<up|down> направление сортировки
# возвращает новое направление сортировки и поле для сортировки с направлением
def order_helper(request):
    dr = request.GET.get('dir')
    dfx = ''
    if dr == 'down':
        dr = 'up'
        dfx = '-'
    else:
        dr = 'down'

    orby = request.GET.get('order_by')
    if orby:
        return dr, dfx + orby
    else:
        return dr, orby


# Декоратор проверяет аккаунт, чтоб не пускать клиентов в страницы администрации
def only_admins(fn):
    @wraps(fn)
    def wrapped(request, *args, **kwargs):
        if request.user.is_admin:
            return fn(request, *args, **kwargs)
        else:
            return redirect('client_side:home')

    return wrapped


def ping(hostname):
    response = os.system("`which ping` -c 1 %s > /dev/null" % hostname)
    return True if response == 0 else False


# Русифицированный вывод timedelta
class RuTimedelta(timedelta):

    def __new__(cls, tm):
        if isinstance(tm, timedelta):
            return timedelta.__new__(
                cls,
                days=tm.days,
                seconds=tm.seconds,
                microseconds=tm.microseconds
            )

    def __str__(self):
        hours, remainder = divmod(self.seconds, 3600)
        minutes, seconds = divmod(remainder, 60)
        text_date = "%d:%d:%d" % (
            hours,
            minutes,
            seconds
        )
        if self.days > 1:
            ru_days = 'дней'
            if 5 > self.days > 1:
                ru_days = 'дня'
            elif self.days == 1:
                ru_days = 'день'
            text_date = '%d %s %s' % (self.days, ru_days, text_date)
        return text_date


def require_ssl(view):
    """
    Decorator that requires an SSL connection. If the current connection is not SSL, we redirect to the SSL version of
    the page.
    from: https://gist.github.com/ckinsey/9709984
    """
    @wraps(view)
    def wrapper(request, *args, **kwargs):
        if not DEBUG and not request.is_secure():
            target_url = "https://" + request.META['HTTP_HOST'] + request.path_info
            return HttpResponseRedirect(target_url)
        return view(request, *args, **kwargs)
    return wrapper


class MultipleException(Exception):

    def __init__(self, err_list):
        if not isinstance(err_list, list):
            raise TypeError
        self.err_list = err_list

{'fraction_non_alphanumeric': 0.11008002724331688, 'fraction_numerical': 0.018985186446449854, 'mean_word_length': 2.5672638931065896, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5024530', 'n_tokens_mistral': 4091, 'n_tokens_neox': 4065, 'n_words': 1021}