You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

201 lines
5.5 KiB

import datetime
from pprint import pprint
import natsort
import re
import pydash as _;
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.storage import FileSystemStorage
from django.shortcuts import _get_queryset
from django.utils import timezone
from django.db.models import Q
_.map = _.map_;
_.filter = _.filter_
import random
import string
def take(coll, n):
chunk = coll[0:n]
del coll[0:n]
return chunk
def take_random(coll, n):
if n == 0:
return []
chunk = _.sample(coll, n)
for item in chunk:
coll.remove(item)
return chunk
def take_one_random(coll):
if len(coll) == 0:
return None
return coll.pop(_.random(0, len(coll) - 1))
def random_phone():
return '+7' + str(_.sample((917, 964, 965, 987, 912, 935))) + str(_.random(1000000, 9999999))
def random_date():
return timezone.utc.localize(timezone.datetime(_.random(2012, 2018), _.random(1, 12), _.random(1, 28)))
def random_amount():
return random.random() * random.choice((100, 1000, 10000))
def get_or_none(klass, *args, **kwargs):
queryset = _get_queryset(klass)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
return None
def get_related_or_none(obj, attr):
try:
rel = getattr(obj, attr)
except ObjectDoesNotExist:
rel = None
return rel
def has_related(obj, attr):
try:
return bool(getattr(obj, attr))
except ObjectDoesNotExist:
return False
def get_attr_or_none(klass, *args, attr=None, **kwargs):
object = get_or_none(klass, *args, **kwargs)
if object and attr and isinstance(attr, str):
return getattr(object, attr, None)
def model_fields(model, width=200):
fields = natsort.natsorted(model._meta.get_fields(), key=lambda f: f.name)
pprint([(
f.name,
'Relation? %s' % f.is_relation,
'Null? %s' % getattr(f, 'null', None),
'Blank? %s' % getattr(f, 'blank', None),
) for f in fields], width=width)
def lorem(words=None, sentences=5):
vocab = _.split((
'a ac adipiscing amet ante arcu at auctor augue bibendum commodo condimentum consectetur consequat convallis curabitur'
'cursus diam dictum dignissim dolor donec duis efficitur eget eleifend elit enim erat et eu ex facilisis faucibus feugiat'
'finibus gravida iaculis id imperdiet in integer ipsum lacinia lacus laoreet lectus leo libero ligula lobortis lorem'
'luctus maecenas mauris metus mi mollis morbi nam nec neque nisi non nulla nullam nunc odio orci ornare pellentesque'
'pharetra phasellus porta porttitor posuere pretium proin pulvinar purus quam quis rhoncus rutrum sapien sed sem semper'
'sit sollicitudin tempor tempus tincidunt tortor turpis ullamcorper ultricies ut varius vehicula vel velit vestibulum'
'vitae viverra volutpat vulputate'
), ' ')
return _.join(_.times(lambda i_: _.capitalize(_.join(_.sample(vocab, words or _.random(5, 30)), ' ')), sentences),
'. ')
def decap(s):
if not isinstance(s, str):
raise TypeError('String expected')
return s[0].lower() + s[1:] if len(s) > 0 else s
def random_ident(length=8):
return ''.join(
[random.choice(string.ascii_lowercase)] +
_.times(lambda x_: random.choice(string.ascii_letters + string.digits), length - 1)
)
def validate_phone(text):
text = text.replace(' ', '').replace('-', '')
validate = validators.RegexValidator(
regex=r'^((\+7|8)(\(\d{3}\)|(\d{3}))\d{7})$',
message='Неверный номер телефона. Формат: +71112223344',
)
validate(text)
def to_local_datetime(obj):
if not isinstance(obj, datetime.date):
raise TypeError('Date expected')
if not isinstance(obj, datetime.datetime):
obj = datetime.datetime.combine(obj, datetime.time.min)
if not getattr(obj, 'tzinfo', None):
obj = timezone.utc.localize(obj)
return obj
def morph(number, words):
CHOICES = (2, 0, 1, 1, 1, 2)
if 4 < number % 100 < 20:
choice = 2
else:
choice = CHOICES[number % 10 if number % 10 < 5 else 5]
return words[choice]
# # Example:
#
# words = ['яблоко', 'яблока', 'яблок']
#
# for i in range(0, 30):
# print(i, morph(i, words))
class ASCIIFileSystemStorage(FileSystemStorage):
def get_valid_name(self, name):
symbols = (u"абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",
u"abvgdeejzijklmnoprstufhzcss_y_euaABVGDEEJZIJKLMNOPRSTUFHZCSS_Y_EUA")
tr = {ord(a): ord(b) for a, b in zip(*symbols)}
name = name.translate(tr)
return super().get_valid_name(name)
def build_query(id_str, _class, *args):
"""
Возвращает QuerySet для строки id-ников по заданным args (см. примеры вызова - там понятнее)
:param id_str: 'id1, id2, ...idn'
:param _class: model
:param args:
:return: queryset
"""
query = Q()
id_list = tuple(filter(None, re.split(r'\s|,|;', id_str)))
for id in id_list:
obj = _class.objects.get(id=id)
try:
kwargs = dict(zip(args, (obj.lft, obj.rght)))
except AttributeError:
kwargs = {args[0]: obj.id}
# print("kwargs = ", type(kwargs))
query |= Q(**kwargs)
return query