313 lines
		
	
	
		
			No EOL
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			No EOL
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import datetime
 | 
						||
import os
 | 
						||
import uuid
 | 
						||
 | 
						||
from django.core.validators import RegexValidator
 | 
						||
from django.utils import timezone
 | 
						||
from django.utils.text import slugify
 | 
						||
 | 
						||
from . import jalali
 | 
						||
 | 
						||
__jmonths = [
 | 
						||
    "فروردین", "اردیبهشت", "خرداد",
 | 
						||
    "تیر", "مرداد", "شهریور",
 | 
						||
    "مهر", "آبان", "آذر",
 | 
						||
    "دی", "بهمن", "اسفند",
 | 
						||
]
 | 
						||
 | 
						||
 | 
						||
def persian_numbers_converter(mystr):
 | 
						||
    numbers = {
 | 
						||
        "0": "۰",
 | 
						||
        "1": "۱",
 | 
						||
        "2": "۲",
 | 
						||
        "3": "۳",
 | 
						||
        "4": "۴",
 | 
						||
        "5": "۵",
 | 
						||
        "6": "۶",
 | 
						||
        "7": "۷",
 | 
						||
        "8": "۸",
 | 
						||
        "9": "۹",
 | 
						||
    }
 | 
						||
 | 
						||
    for e, p in numbers.items():
 | 
						||
        mystr = mystr.replace(e, p)
 | 
						||
 | 
						||
    return mystr
 | 
						||
 | 
						||
 | 
						||
def jalali_converter(time):
 | 
						||
    try:
 | 
						||
        time = timezone.localtime(time)
 | 
						||
    except:
 | 
						||
        time = time
 | 
						||
 | 
						||
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
 | 
						||
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
 | 
						||
    time_to_list = list(time_to_tuple)
 | 
						||
 | 
						||
    for index, month in enumerate(__jmonths):
 | 
						||
        if time_to_list[1] == index + 1:
 | 
						||
            time_to_list[1] = month
 | 
						||
            break
 | 
						||
 | 
						||
    output = "{} {} {}, ساعت {}:{}".format(
 | 
						||
        time_to_list[2],
 | 
						||
        time_to_list[1],
 | 
						||
        time_to_list[0],
 | 
						||
        time.hour,
 | 
						||
        time.minute,
 | 
						||
    )
 | 
						||
    return persian_numbers_converter(output)
 | 
						||
 | 
						||
 | 
						||
def get_client_ip(request):
 | 
						||
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
 | 
						||
    if x_forwarded_for:
 | 
						||
        ip = x_forwarded_for.split(',')[0]
 | 
						||
    else:
 | 
						||
        ip = request.META.get('REMOTE_ADDR')
 | 
						||
    return ip
 | 
						||
 | 
						||
 | 
						||
def jalali_converter21(time):
 | 
						||
    time = timezone.localtime(time)
 | 
						||
 | 
						||
    year, month, day = jalali.Gregorian(time.strftime("%Y-%m-%d")).persian_tuple()[:3]
 | 
						||
    hour, minute = time.strftime("%H:%M").split(':')
 | 
						||
 | 
						||
    return f"{day} {__jmonths[month - 1]} {year}, ساعت {hour}:{minute}"
 | 
						||
 | 
						||
 | 
						||
def jalali_converter2(time):
 | 
						||
    try:
 | 
						||
        time = timezone.localdate(time)
 | 
						||
    except:
 | 
						||
        time = time
 | 
						||
 | 
						||
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
 | 
						||
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
 | 
						||
    time_to_list = list(time_to_tuple)
 | 
						||
 | 
						||
    for index, month in enumerate(__jmonths):
 | 
						||
        if time_to_list[1] == index + 1:
 | 
						||
            time_to_list[1] = month
 | 
						||
            break
 | 
						||
 | 
						||
    output = "{} {} {}".format(
 | 
						||
        time_to_list[2],
 | 
						||
        time_to_list[1],
 | 
						||
        time_to_list[0],
 | 
						||
    )
 | 
						||
    return persian_numbers_converter(output)
 | 
						||
 | 
						||
 | 
						||
def gregorian_converter(time):
 | 
						||
    time_to_list = time.split('/')
 | 
						||
    time_to_str = "{},{},{}".format(time_to_list[0], time_to_list[1], time_to_list[2])
 | 
						||
    return jalali.Persian(time_to_str).gregorian_string()
 | 
						||
 | 
						||
 | 
						||
def get_client_ip(request):
 | 
						||
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
 | 
						||
    if x_forwarded_for:
 | 
						||
        ip = x_forwarded_for.split(',')[0]
 | 
						||
    else:
 | 
						||
        ip = request.META.get('REMOTE_ADDR')
 | 
						||
    return ip
 | 
						||
 | 
						||
 | 
						||
def persian_converter(time):
 | 
						||
    time = time + datetime.timedelta(days=1)
 | 
						||
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
 | 
						||
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
 | 
						||
    time_to_list = list(time_to_tuple)
 | 
						||
    return time_to_list
 | 
						||
 | 
						||
 | 
						||
def persian_converter2(time):
 | 
						||
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
 | 
						||
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
 | 
						||
    time_to_list = list(time_to_tuple)
 | 
						||
 | 
						||
    for index, month in enumerate(__jmonths):
 | 
						||
        if time_to_list[1] == index + 1:
 | 
						||
            time_to_list[1] = month
 | 
						||
            break
 | 
						||
 | 
						||
    output = "{} {} {}".format(
 | 
						||
        time_to_list[2],
 | 
						||
        time_to_list[1],
 | 
						||
        time_to_list[0],
 | 
						||
    )
 | 
						||
    return persian_numbers_converter(output)
 | 
						||
 | 
						||
 | 
						||
def persian_converter3(time):
 | 
						||
    time = time
 | 
						||
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
 | 
						||
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
 | 
						||
    time_to_list = list(time_to_tuple)
 | 
						||
    time_to_list = [str(item) for item in time_to_list]
 | 
						||
    return '/'.join(time_to_list)
 | 
						||
 | 
						||
 | 
						||
def delete_file(path):
 | 
						||
    """ Deletes file from filesystem. """
 | 
						||
    if os.path.isfile(path):
 | 
						||
        os.remove(path)
 | 
						||
 | 
						||
 | 
						||
def get_phone_number_validator():
 | 
						||
    return RegexValidator(
 | 
						||
        regex=r'^[0]{1}[9]{1}[0-9]{9}',
 | 
						||
        message='مقدار وارد شده صحیح نمیباشد',
 | 
						||
    )
 | 
						||
 | 
						||
 | 
						||
def generate_unique_slug(text: str) -> str:
 | 
						||
    """
 | 
						||
    Generates a unique slug from received text
 | 
						||
    """
 | 
						||
    slug = slugify(text)
 | 
						||
    unique_id = str(uuid.uuid4())[:8]
 | 
						||
    unique_slug = f"{slug}-{unique_id}"
 | 
						||
 | 
						||
    return unique_slug
 | 
						||
 | 
						||
 | 
						||
def normalize_size(size: int) -> str:
 | 
						||
    """
 | 
						||
    Normalizes file or volume sizes and returns it with the proper suffix,
 | 
						||
    showing the decimal only if it's non-zero.
 | 
						||
    """
 | 
						||
    size = float(size)
 | 
						||
    if size < 1024:
 | 
						||
        return f"{int(size)} B" if size.is_integer() else f"{size:.1f} B"
 | 
						||
    elif size < 1024 * 1024:
 | 
						||
        size_kb = size / 1024
 | 
						||
        return f"{int(size_kb)} KB" if size_kb.is_integer() else f"{size_kb:.1f} KB"
 | 
						||
    elif size < 1024 * 1024 * 1024:
 | 
						||
        size_mb = size / (1024 * 1024)
 | 
						||
        return f"{int(size_mb)} MB" if size_mb.is_integer() else f"{size_mb:.1f} MB"
 | 
						||
    else:
 | 
						||
        size_gb = size / (1024 * 1024 * 1024)
 | 
						||
        return f"{int(size_gb)} GB" if size_gb.is_integer() else f"{size_gb:.1f} GB"
 | 
						||
 | 
						||
 | 
						||
def number_to_persian_words(number):
 | 
						||
    """
 | 
						||
    تبدیل عدد به حروف فارسی
 | 
						||
    مثال: 12345 -> دوازده هزار و سیصد و چهل و پنج
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        # تبدیل به عدد صحیح (در صورت نیاز)
 | 
						||
        from decimal import Decimal
 | 
						||
        if isinstance(number, Decimal):
 | 
						||
            number = int(number)
 | 
						||
        elif isinstance(number, float):
 | 
						||
            number = int(number)
 | 
						||
        elif isinstance(number, str):
 | 
						||
            number = int(float(number.replace(',', '')))
 | 
						||
        
 | 
						||
        if number == 0:
 | 
						||
            return "صفر"
 | 
						||
        
 | 
						||
        if number < 0:
 | 
						||
            return "منفی " + number_to_persian_words(abs(number))
 | 
						||
        
 | 
						||
        # اعداد یک رقمی
 | 
						||
        ones = [
 | 
						||
            "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه"
 | 
						||
        ]
 | 
						||
        
 | 
						||
        # اعداد ده تا نوزده
 | 
						||
        teens = [
 | 
						||
            "ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده",
 | 
						||
            "شانزده", "هفده", "هجده", "نوزده"
 | 
						||
        ]
 | 
						||
        
 | 
						||
        # اعداد بیست تا نود
 | 
						||
        tens = [
 | 
						||
            "", "", "بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود"
 | 
						||
        ]
 | 
						||
        
 | 
						||
        # اعداد صد تا نهصد
 | 
						||
        hundreds = [
 | 
						||
            "", "یکصد", "دویست", "سیصد", "چهارصد", "پانصد",
 | 
						||
            "ششصد", "هفتصد", "هشتصد", "نهصد"
 | 
						||
        ]
 | 
						||
        
 | 
						||
        # مراتب بزرگتر
 | 
						||
        scale = [
 | 
						||
            "", "هزار", "میلیون", "میلیارد", "بیلیون", "بیلیارد"
 | 
						||
        ]
 | 
						||
        
 | 
						||
        def convert_group(num):
 | 
						||
            """تبدیل گروه سه رقمی به حروف"""
 | 
						||
            if num == 0:
 | 
						||
                return ""
 | 
						||
            
 | 
						||
            result = []
 | 
						||
            
 | 
						||
            # صدها
 | 
						||
            h = num // 100
 | 
						||
            if h > 0:
 | 
						||
                result.append(hundreds[h])
 | 
						||
            
 | 
						||
            # دهگان و یکان
 | 
						||
            remainder = num % 100
 | 
						||
            
 | 
						||
            if remainder >= 10 and remainder < 20:
 | 
						||
                # اعداد 10 تا 19
 | 
						||
                result.append(teens[remainder - 10])
 | 
						||
            else:
 | 
						||
                # دهگان
 | 
						||
                t = remainder // 10
 | 
						||
                if t > 0:
 | 
						||
                    result.append(tens[t])
 | 
						||
                
 | 
						||
                # یکان
 | 
						||
                o = remainder % 10
 | 
						||
                if o > 0:
 | 
						||
                    result.append(ones[o])
 | 
						||
            
 | 
						||
            return " و ".join(result)
 | 
						||
        
 | 
						||
        # تقسیم عدد به گروههای سه رقمی
 | 
						||
        groups = []
 | 
						||
        scale_index = 0
 | 
						||
        
 | 
						||
        while number > 0:
 | 
						||
            group = number % 1000
 | 
						||
            if group != 0:
 | 
						||
                group_text = convert_group(group)
 | 
						||
                if scale_index > 0:
 | 
						||
                    group_text += " " + scale[scale_index]
 | 
						||
                groups.append(group_text)
 | 
						||
            
 | 
						||
            number //= 1000
 | 
						||
            scale_index += 1
 | 
						||
        
 | 
						||
        # معکوس کردن و ترکیب گروهها
 | 
						||
        groups.reverse()
 | 
						||
        result = " و ".join(groups)
 | 
						||
        
 | 
						||
        return result
 | 
						||
    
 | 
						||
    except Exception:
 | 
						||
        return ""
 | 
						||
 | 
						||
 | 
						||
def amount_to_persian_words(amount):
 | 
						||
    """
 | 
						||
    تبدیل مبلغ به حروف فارسی با واحد ریال
 | 
						||
    مثال: 12345 -> دوازده هزار و سیصد و چهل و پنج ریال
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        words = number_to_persian_words(amount)
 | 
						||
        if words:
 | 
						||
            return words + " ریال"
 | 
						||
        return ""
 | 
						||
    except Exception:
 | 
						||
        return "" |