262 lines
8.4 KiB
Python
262 lines
8.4 KiB
Python
import datetime
|
|
import hashlib
|
|
import random
|
|
import re
|
|
from hashlib import md5
|
|
from typing import Any
|
|
import uuid
|
|
from calendar import timegm
|
|
|
|
from rest_framework_jwt.serializers import jwt_encode_handler
|
|
from rest_framework_jwt.settings import api_settings
|
|
|
|
|
|
def convert_to_relative_time(time_string):
|
|
# 将时间字符串转换为datetime对象
|
|
if not isinstance(time_string, datetime.datetime):
|
|
time = datetime.datetime.strptime(time_string, "%Y-%m-%d %H:%M:%S")
|
|
else:
|
|
time = time_string
|
|
|
|
# 获取当前时间
|
|
current_time = datetime.datetime.now()
|
|
|
|
# 计算时间差
|
|
time_difference = current_time - time
|
|
|
|
# 提取相对时间的各个单位
|
|
days = time_difference.days
|
|
seconds = time_difference.seconds
|
|
minutes = seconds // 60
|
|
hours = minutes // 60
|
|
|
|
# 根据时间差生成相对时间字符串
|
|
if days > 0:
|
|
return f"{days}天前"
|
|
elif hours > 0:
|
|
return f"{hours}小时前"
|
|
elif minutes > 0:
|
|
return f"{minutes}分钟前"
|
|
else:
|
|
return "刚刚"
|
|
|
|
|
|
def generate_options_by_choices(choices):
|
|
data = []
|
|
for value, label in choices:
|
|
data.append({
|
|
'value': value,
|
|
'label': label,
|
|
})
|
|
return data
|
|
|
|
|
|
def jwt_payload_handler(user):
|
|
username_field = 'username'
|
|
username = user.username
|
|
|
|
payload = {
|
|
'user_id': user.pk,
|
|
'username': username,
|
|
'exp': datetime.datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA
|
|
}
|
|
if hasattr(user, 'email'):
|
|
payload['email'] = user.email
|
|
if isinstance(user.pk, uuid.UUID):
|
|
payload['user_id'] = str(user.pk)
|
|
|
|
payload[username_field] = username
|
|
|
|
# Include original issued at time for a brand new token,
|
|
# to allow token refresh
|
|
if api_settings.JWT_ALLOW_REFRESH:
|
|
payload['orig_iat'] = timegm(
|
|
datetime.datetime.utcnow().utctimetuple()
|
|
)
|
|
|
|
if api_settings.JWT_AUDIENCE is not None:
|
|
payload['aud'] = api_settings.JWT_AUDIENCE
|
|
|
|
if api_settings.JWT_ISSUER is not None:
|
|
payload['iss'] = api_settings.JWT_ISSUER
|
|
|
|
return payload
|
|
|
|
|
|
def create_jwt(user):
|
|
payload = jwt_payload_handler(user)
|
|
return jwt_encode_handler(payload)
|
|
|
|
|
|
def generate_columns(model):
|
|
columns = []
|
|
fields = model._meta.fields
|
|
for field in fields:
|
|
column = {
|
|
"title": field.verbose_name,
|
|
"dataIndex": field.name,
|
|
"align": 'center',
|
|
"slots": {"customRender": field.name},
|
|
}
|
|
columns.append(column)
|
|
return columns
|
|
|
|
|
|
def md5_obj(byte_obj: Any):
|
|
md = md5()
|
|
md.update(byte_obj)
|
|
|
|
return md.hexdigest()
|
|
|
|
|
|
class InviteCode:
|
|
r1 = ["Z", "X", "9", "L", "C", "7", "P", "Q", "W", "E", "8", "S", "2", "D", "5", "K", "3", "M", "J", "U", "F", "R",
|
|
"4", "V", "Y", "T", "N", "6", "B", "G", "H"]
|
|
r2 = ["C", "P", "K", "M", "Q", "W", "E", "S", "D", "Z", "X", "L", "J", "U", "F", "R", "V", "Y", "T", "N", "B", "G",
|
|
"H", "A"]
|
|
r3 = ["P", "5", "K", "3", "M", "J", "U", "F", "Q", "L", "W", "E", "8", "S", "2", "D", "Z", "X", "9", "Y", "T", "N",
|
|
"6", "B", "G", "H", "C", "7", "R", "4", "V"]
|
|
r4 = ["J", "U", "F", "R", "V", "Y", "Q", "W", "E", "S", "L", "K", "M", "D", "Z", "X", "A", "C", "P", "G", "H", "T",
|
|
"N", "B"]
|
|
r5 = ["M", "J", "U", "F", "R", "4", "Q", "W", "E", "8", "S", "2", "D", "Z", "X", "9", "L", "C", "7", "P", "5", "K",
|
|
"3", "V", "Y", "T", "N", "6", "B", "G", "H"]
|
|
r6 = ["Y", "T", "N", "B", "G", "H", "L", "C", "P", "Q", "W", "E", "S", "D", "Z", "X", "R", "V", "K", "M", "J", "U",
|
|
"F", "A"]
|
|
r7 = ["X", "9", "L", "C", "7", "P", "5", "K", "3", "Q", "W", "E", "8", "S", "2", "D", "Z", "M", "J", "U", "F", "R",
|
|
"4", "V", "Y", "T", "N", "6", "B", "G", "H"]
|
|
|
|
@staticmethod
|
|
def create_code(id):
|
|
bin_len = 31
|
|
ind = 0
|
|
i = 1
|
|
builder = []
|
|
while id / bin_len > 0:
|
|
ind = int(id % bin_len)
|
|
if ind != 0 or (ind == 0 and id == bin_len) or (ind == 0 or i == 1):
|
|
if i == 1:
|
|
builder.append(InviteCode.r7[ind])
|
|
id = int(id / len(InviteCode.r7))
|
|
bin_len = len(InviteCode.r6)
|
|
elif i == 2:
|
|
builder.append(InviteCode.r6[ind])
|
|
id = int(id / len(InviteCode.r6))
|
|
bin_len = len(InviteCode.r5)
|
|
elif i == 3:
|
|
builder.append(InviteCode.r5[ind])
|
|
id = int(id / len(InviteCode.r5))
|
|
bin_len = len(InviteCode.r4)
|
|
elif i == 4:
|
|
builder.append(InviteCode.r4[ind])
|
|
id = int(id / len(InviteCode.r4))
|
|
bin_len = len(InviteCode.r3)
|
|
elif i == 5:
|
|
builder.append(InviteCode.r3[ind])
|
|
id = int(id / len(InviteCode.r3))
|
|
bin_len = len(InviteCode.r2)
|
|
elif i == 6:
|
|
builder.append(InviteCode.r2[ind])
|
|
id = int(id / len(InviteCode.r2))
|
|
bin_len = len(InviteCode.r1)
|
|
elif i == 7:
|
|
builder.append(InviteCode.r1[ind])
|
|
id = int(id / len(InviteCode.r1))
|
|
bin_len = len(InviteCode.r1)
|
|
i += 1
|
|
|
|
index = 0
|
|
first_index = id if id > 0 and id / bin_len == 0 else 0
|
|
if i == 1:
|
|
builder.append(
|
|
InviteCode.r7[id] + InviteCode.r6[index] + InviteCode.r5[index] + InviteCode.r4[index] + InviteCode.r3[
|
|
index] + InviteCode.r2[index] + InviteCode.r1[index])
|
|
elif i == 2:
|
|
builder.append(
|
|
InviteCode.r6[first_index] + InviteCode.r5[index] + InviteCode.r4[index] + InviteCode.r3[index] +
|
|
InviteCode.r2[index] + InviteCode.r1[index])
|
|
elif i == 3:
|
|
builder.append(
|
|
InviteCode.r5[first_index] + InviteCode.r4[index] + InviteCode.r3[index] + InviteCode.r2[index] +
|
|
InviteCode.r1[index])
|
|
elif i == 4:
|
|
builder.append(
|
|
InviteCode.r4[first_index] + InviteCode.r3[index] + InviteCode.r2[index] + InviteCode.r1[index])
|
|
elif i == 5:
|
|
builder.append(InviteCode.r3[first_index] + InviteCode.r2[index] + InviteCode.r1[index])
|
|
elif i == 6:
|
|
builder.append(InviteCode.r2[first_index] + InviteCode.r1[index])
|
|
elif i == 7:
|
|
builder.append(InviteCode.r1[first_index])
|
|
|
|
str = ''.join(builder)
|
|
res = str[::-1]
|
|
code = res
|
|
return code
|
|
|
|
@staticmethod
|
|
def decode(code):
|
|
chs = list(code)
|
|
res = 0
|
|
c1 = chs[0]
|
|
index_of_c1 = InviteCode.r1.index(c1)
|
|
if index_of_c1 > 0:
|
|
temp = 24 * 31 * 24 * 31 * 24 * 31
|
|
res += index_of_c1 * temp
|
|
c2 = chs[1]
|
|
index_of_c2 = InviteCode.r2.index(c2)
|
|
if index_of_c2 > 0:
|
|
temp = 31 * 24 * 31 * 24 * 31
|
|
res += index_of_c2 * temp
|
|
c3 = chs[2]
|
|
index_of_c3 = InviteCode.r3.index(c3)
|
|
if index_of_c3 > 0:
|
|
temp = 24 * 31 * 24 * 31
|
|
res += index_of_c3 * temp
|
|
c4 = chs[3]
|
|
index_of_c4 = InviteCode.r4.index(c4)
|
|
if index_of_c4 > 0:
|
|
temp = 31 * 24 * 31
|
|
res += index_of_c4 * temp
|
|
c5 = chs[4]
|
|
index_of_c5 = InviteCode.r5.index(c5)
|
|
if index_of_c5 > 0:
|
|
temp = 24 * 31
|
|
res += index_of_c5 * temp
|
|
c6 = chs[5]
|
|
index_of_c6 = InviteCode.r6.index(c6)
|
|
if index_of_c6 > 0:
|
|
temp = 31
|
|
res += index_of_c6 * temp
|
|
c7 = chs[6]
|
|
index_of_c7 = InviteCode.r7.index(c7)
|
|
if index_of_c7 > 0:
|
|
res += index_of_c7 * 1
|
|
return res
|
|
|
|
|
|
def is_mobile(mobile):
|
|
return bool(re.match(r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$', mobile))
|
|
|
|
|
|
def generate_phone_code(length=6) -> str:
|
|
""" 生成手机验证码 """
|
|
number_list = range(0, 10)
|
|
return ''.join(map(lambda i: str(i), random.choices(number_list, k=length)))
|
|
|
|
|
|
def sha1_encoder(data):
|
|
sha1 = hashlib.sha1()
|
|
sha1.update(data.encode('utf-8'))
|
|
return sha1.hexdigest()
|
|
|
|
|
|
def get_attribute(obj, field):
|
|
if obj is None:
|
|
return
|
|
return getattr(obj, field)
|
|
|
|
|
|
def camel_to_snake(name):
|
|
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
|
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|