13 changed files with 243 additions and 589 deletions
-
66devapp/dev_types.py
-
60devapp/migrations/0003_auto_20180529_1311.py
-
8devapp/models.py
-
2devapp/templates/devapp/add_dev.html
-
2devapp/templates/devapp/custom_dev_page/olt_ztec320_ports.html
-
17devapp/templates/devapp/custom_dev_page/onu.html
-
91devapp/templates/devapp/custom_dev_page/onu_for_zte.html
-
2devapp/templates/devapp/dev.html
-
16devapp/views.py
-
0djing/lib/auth_backends.py
-
359migrate_to_0.2.py
-
187mydefs.py
-
18static/css/custom.css
@ -0,0 +1,60 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.11 on 2018-05-29 13:11 |
|||
from __future__ import unicode_literals |
|||
import os |
|||
from json import load |
|||
|
|||
from django.db import migrations, models |
|||
from django.core import serializers |
|||
|
|||
TMP_FILE = '/tmp/djing_snmp_info_backup.json' |
|||
|
|||
|
|||
def snmp_backup_info(apps, _): |
|||
Device = apps.get_model('devapp', 'Device') |
|||
obs = Device.objects.only('snmp_item_num') |
|||
with open(TMP_FILE, 'w') as f: |
|||
serializers.serialize('json', obs, stream=f) |
|||
|
|||
|
|||
def snmp_restore_info_to_new_scheme(apps, _): |
|||
Device = apps.get_model('devapp', 'Device') |
|||
with open(TMP_FILE, 'r') as f: |
|||
for device in load(f): |
|||
Device.objects.filter(pk=device['pk']).update(snmp_extra=device['fields']['snmp_item_num']) |
|||
if os.path.isfile(TMP_FILE): |
|||
os.remove(TMP_FILE) |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('devapp', '0002_auto_20180409_1318'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.RunPython(snmp_backup_info), |
|||
migrations.AlterModelOptions( |
|||
name='device', |
|||
options={'ordering': ('id',), 'permissions': (('can_view_device', 'Can view device'),), 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'}, |
|||
), |
|||
migrations.AlterModelOptions( |
|||
name='port', |
|||
options={'ordering': ('num',), 'permissions': (('can_toggle_ports', 'Can toggle ports'),), 'verbose_name': 'Port', 'verbose_name_plural': 'Ports'}, |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='device', |
|||
name='snmp_item_num', |
|||
), |
|||
migrations.AddField( |
|||
model_name='device', |
|||
name='snmp_extra', |
|||
field=models.CharField(blank=True, max_length=256, null=True, verbose_name='SNMP extra info'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='device', |
|||
name='devtype', |
|||
field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT'), ('On', 'PON ONU'), ('Ex', 'Eltex switch'), ('Zt', 'OLT ZTE C320'), ('Zo', 'ZTE PON ONU')], default='Dl', max_length=2, verbose_name='Device type'), |
|||
), |
|||
migrations.RunPython(snmp_restore_info_to_new_scheme) |
|||
] |
|||
@ -0,0 +1,91 @@ |
|||
{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %} |
|||
{% load i18n %} |
|||
{% block content %} |
|||
|
|||
{% with uptime=dev_manager.uptime onu_details=dev_manager.get_details %} |
|||
<div class="row"> |
|||
<div class="col-xs-12 col-sm-6"> |
|||
<div class="panel panel-default"> |
|||
<div class="panel-heading"> |
|||
<div class="panel-title">{{ dev.get_devtype_display|default:_('Title of the type of switch') }}. |
|||
{% if uptime %} |
|||
{% trans 'Uptime' %} {{ uptime }} |
|||
{% endif %} |
|||
</div> |
|||
</div> |
|||
<div class="panel-body"> |
|||
<ul class="list-group"> |
|||
<li class="list-group-item">{% trans 'Ip address' %}: {{ dev.ip_address|default:'-' }}</li> |
|||
<li class="list-group-item">{% trans 'Mac' %}: {{ dev.mac_addr }}</li> |
|||
<li class="list-group-item">{% trans 'Description' %}: {{ dev.comment }}</li> |
|||
{% for da in dev_accs %} |
|||
<li class="list-group-item">{% trans 'Attached user' %}: |
|||
{% if da.group %} |
|||
<a href="{% url 'abonapp:abon_home' da.group.pk da.username %}" |
|||
target="_blank">{{ da.get_full_name }}</a> |
|||
{% else %} |
|||
{{ da.get_full_name }} |
|||
{% endif %} |
|||
</li> |
|||
{% endfor %} |
|||
{% if dev.parent_dev %} |
|||
<li class="list-group-item"> |
|||
{% with pdev=dev.parent_dev pdgrp=dev.parent_dev.group %} |
|||
{% trans 'Parent device' %}: |
|||
<a href="{% url 'devapp:view' pdgrp.pk pdev.pk %}" |
|||
title="{{ pdev.mac_addr|default:'' }}" |
|||
target="_blank"> |
|||
{{ pdev.ip_address|default:'-' }} {{ pdev.comment }} |
|||
</a> |
|||
{% endwith %} |
|||
</li> |
|||
{% endif %} |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-xs-12 col-sm-6"> |
|||
<div class="panel panel-default"> |
|||
<div class="panel-heading"> |
|||
<h3 class="panel-title">{% trans 'ONU Status' %}</h3> |
|||
</div> |
|||
|
|||
<div class="panel-body"> |
|||
{% if onu_details %} |
|||
{% if onu_details.err %} |
|||
<div class="media"> |
|||
<div class="media-left"><span class="media-object glyphicon glyphicon-remove-sign text-danger font-extra-large"></span></div> |
|||
</div> |
|||
<div class="media-body"> |
|||
<b>{% trans 'ONU error' %}</b>: {{ onu_details.err }}<br> |
|||
</div> |
|||
{% else %} |
|||
<div class="media"> |
|||
<div class="media-left font-extra-large"> |
|||
{% if onu_details.status == '1' %} |
|||
<span class="media-object glyphicon glyphicon-ok-sign text-success"></span> |
|||
{% elif onu_details.status == '2' %} |
|||
<span class="media-object glyphicon glyphicon-remove-sign text-danger"></span> |
|||
{% else %} |
|||
<span class="media-object glyphicon glyphicon-question-sign"></span> |
|||
{% endif %} |
|||
</div> |
|||
<div class="media-body"> |
|||
|
|||
<b>{% trans 'Name on OLT' %}</b>: {{ onu_details.name }}<br> |
|||
<b>{% trans 'Distance(m)' %}</b>: {{ onu_details.distance }}<br> |
|||
<b>{% trans 'Signal' %}</b>: {{ onu_details.signal }}<br> |
|||
|
|||
</div> |
|||
</div> |
|||
{% endif %} |
|||
{% else %} |
|||
<h3>{% trans 'Info does not fetch' %}</h3> |
|||
{% endif %} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
{% endwith %} |
|||
{% endblock %} |
|||
@ -1,359 +0,0 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
import os |
|||
import sys |
|||
import shutil |
|||
from json import dump |
|||
import django |
|||
|
|||
''' |
|||
Some permissions is not migrates, all admins is superuser |
|||
after migrate. |
|||
''' |
|||
|
|||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") |
|||
from django.db.models import fields as django_fields |
|||
|
|||
|
|||
def get_fixture_from_unchanget_model(model_name: str, model_class): |
|||
""" |
|||
Создаёт фикстуру если модели между версиями не изменились |
|||
:param model_name: str 'app_label.model_name' |
|||
:param model_class: Model модель для которой надо сделать фикстуру |
|||
:return: список словарей |
|||
""" |
|||
print(model_name) |
|||
|
|||
def get_fields(obj): |
|||
fields = dict() |
|||
for field in obj._meta.get_fields(): |
|||
if isinstance(field, |
|||
(django_fields.reverse_related.ManyToOneRel, django_fields.reverse_related.ManyToManyRel)): |
|||
continue |
|||
field_val = getattr(obj, field.name) |
|||
if field_val is None: |
|||
continue |
|||
if isinstance(field, django_fields.related.ManyToManyField): |
|||
fields[field.name] = [f.pk for f in field_val.all()] |
|||
elif isinstance(field, |
|||
(django_fields.related.ForeignKey, django.contrib.contenttypes.fields.GenericForeignKey)): |
|||
fields[field.name] = field_val.pk |
|||
elif isinstance(field, django_fields.FloatField): |
|||
fields[field.name] = float(field_val) |
|||
elif isinstance(field, django_fields.DateTimeField): |
|||
fields[field.name] = str(field_val) |
|||
elif isinstance(field, django_fields.AutoField): |
|||
continue |
|||
else: |
|||
fields[field.name] = field_val |
|||
return fields |
|||
|
|||
res = [{ |
|||
'model': model_name, |
|||
'pk': obj.pk, |
|||
'fields': get_fields(obj) |
|||
} for obj in model_class.objects.all()] |
|||
return res |
|||
|
|||
|
|||
def dump_groups(): |
|||
from abonapp import models |
|||
print('group_app.group') |
|||
res = [{ |
|||
'model': 'group_app.group', |
|||
'pk': abon_group.pk, |
|||
'fields': { |
|||
'title': abon_group.title |
|||
} |
|||
} for abon_group in models.AbonGroup.objects.all()] |
|||
return res |
|||
|
|||
|
|||
def dump_abonapp(): |
|||
from abonapp import models |
|||
|
|||
res = get_fixture_from_unchanget_model('abonapp.abontariff', models.AbonTariff) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.abonstreet', models.AbonStreet) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.extrafieldsmodel', models.ExtraFieldsModel) |
|||
|
|||
# res += get_fixture_from_unchanget_model('abonapp.abonlog', models.AbonLog) |
|||
|
|||
print('abonapp.abon') |
|||
res += [{ |
|||
'model': 'abonapp.abon', |
|||
'pk': abon.pk, |
|||
'fields': { |
|||
'current_tariff': abon.current_tariff.pk if abon.current_tariff else None, |
|||
'group': abon.group.pk if abon.group else None, |
|||
'ballance': abon.ballance, |
|||
'ip_address': abon.ip_address, |
|||
'description': abon.description, |
|||
'street': abon.street.pk if abon.street else None, |
|||
'house': abon.house, |
|||
'extra_fields': [a.pk for a in abon.extra_fields.all()], |
|||
'device': abon.device.pk if abon.device else None, |
|||
'dev_port': abon.dev_port if abon.dev_port else None, |
|||
'is_dynamic_ip': abon.is_dynamic_ip, |
|||
'markers': abon.markers |
|||
} |
|||
} for abon in models.Abon.objects.filter(is_admin=False)] |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.passportinfo', models.PassportInfo) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.invoiceforpayment', models.InvoiceForPayment) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.alltimepaylog', models.AllTimePayLog) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.abonrawpassword', models.AbonRawPassword) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.additionaltelephone', models.AdditionalTelephone) |
|||
|
|||
res += get_fixture_from_unchanget_model('abonapp.periodicpayforid', models.PeriodicPayForId) |
|||
|
|||
return res |
|||
|
|||
|
|||
def dump_tariffs(): |
|||
from tariff_app import models |
|||
from abonapp.models import AbonGroup |
|||
print('tariff_app.tariff') |
|||
res = [{ |
|||
'model': 'tariff_app.tariff', |
|||
'pk': trf.pk, |
|||
'fields': { |
|||
'title': trf.title, |
|||
'descr': trf.descr, |
|||
'speedIn': trf.speedIn, |
|||
'speedOut': trf.speedOut, |
|||
'amount': trf.amount, |
|||
'calc_type': trf.calc_type, |
|||
'is_admin': trf.is_admin, |
|||
'groups': [ag.pk for ag in AbonGroup.objects.filter(tariffs__in=[trf])] |
|||
} |
|||
} for trf in models.Tariff.objects.all()] |
|||
|
|||
res += get_fixture_from_unchanget_model('tariff_app.periodicpay', models.PeriodicPay) |
|||
|
|||
return res |
|||
|
|||
|
|||
def dump_devs(): |
|||
from devapp import models |
|||
print('devapp.device') |
|||
res = [{ |
|||
'model': 'devapp.device', |
|||
'pk': dv.pk, |
|||
'fields': { |
|||
'ip_address': dv.ip_address, |
|||
'mac_addr': str(dv.mac_addr) if dv.mac_addr else None, |
|||
'comment': dv.comment, |
|||
'devtype': dv.devtype, |
|||
'man_passw': dv.man_passw, |
|||
'group': dv.user_group.pk if dv.user_group else None, |
|||
'parent_dev': dv.parent_dev.pk if dv.parent_dev else None, |
|||
'snmp_item_num': dv.snmp_item_num, |
|||
'status': dv.status, |
|||
'is_noticeable': dv.is_noticeable |
|||
} |
|||
} for dv in models.Device.objects.all()] |
|||
|
|||
res += get_fixture_from_unchanget_model('devapp.port', models.Port) |
|||
return res |
|||
|
|||
|
|||
def dump_accounts(): |
|||
from accounts_app import models |
|||
from abonapp.models import AbonGroup |
|||
|
|||
def get_responsibility_groups(account): |
|||
responsibility_groups = AbonGroup.objects.filter(profiles__in=[account]) |
|||
ids = [ag.pk for ag in responsibility_groups] |
|||
return ids |
|||
|
|||
print('accounts_app.baseaccount') |
|||
res = [{ |
|||
'model': 'accounts_app.baseaccount', |
|||
'pk': up.pk, |
|||
'fields': { |
|||
'username': up.username, |
|||
'fio': up.fio, |
|||
'birth_day': up.birth_day, |
|||
'is_active': up.is_active, |
|||
'is_admin': up.is_admin, |
|||
'telephone': up.telephone, |
|||
'password': up.password, |
|||
'last_login': up.last_login, |
|||
'is_superuser': up.is_admin |
|||
} |
|||
} for up in models.UserProfile.objects.all()] |
|||
|
|||
print('accounts_app.userprofile') |
|||
res += [{ |
|||
'model': 'accounts_app.userprofile', |
|||
'pk': up.pk, |
|||
'fields': { |
|||
'avatar': up.avatar.pk if up.avatar else None, |
|||
'email': up.email, |
|||
'responsibility_groups': get_responsibility_groups(up) |
|||
} |
|||
} for up in models.UserProfile.objects.filter(is_admin=True)] |
|||
|
|||
return res |
|||
|
|||
|
|||
def dump_photos(): |
|||
from photo_app.models import Photo |
|||
print('photo_app.photo') |
|||
res = [{ |
|||
'model': 'photo_app.photo', |
|||
'pk': p.pk, |
|||
'fields': { |
|||
'image': "%s" % p.image, |
|||
'wdth': p.wdth, |
|||
'heigt': p.heigt |
|||
} |
|||
} for p in Photo.objects.all()] |
|||
return res |
|||
|
|||
|
|||
def dump_chatbot(): |
|||
from chatbot import models |
|||
res = get_fixture_from_unchanget_model('chatbot.telegrambot', models.TelegramBot) |
|||
res += get_fixture_from_unchanget_model('chatbot.messagehistory', models.MessageHistory) |
|||
res += get_fixture_from_unchanget_model('chatbot.messagequeue', models.MessageQueue) |
|||
return res |
|||
|
|||
|
|||
def dump_map(): |
|||
from mapapp import models |
|||
res = get_fixture_from_unchanget_model('mapapp.dot', models.Dot) |
|||
return res |
|||
|
|||
|
|||
def dump_task_app(): |
|||
from taskapp import models |
|||
res = get_fixture_from_unchanget_model('taskapp.changelog', models.ChangeLog) |
|||
res += get_fixture_from_unchanget_model('taskapp.task', models.Task) |
|||
res += get_fixture_from_unchanget_model('taskapp.ExtraComment', models.ExtraComment) |
|||
return res |
|||
|
|||
|
|||
def dump_auth(): |
|||
from django.contrib.auth import models |
|||
from django.contrib.contenttypes.models import ContentType |
|||
res = get_fixture_from_unchanget_model('contenttypes.contenttype', ContentType) |
|||
res += get_fixture_from_unchanget_model('auth.group', models.Group) |
|||
res += get_fixture_from_unchanget_model('auth.permission', models.Permission) |
|||
return res |
|||
|
|||
|
|||
def dump_guardian(): |
|||
from guardian import models |
|||
print('guardian.groupobjectpermission') |
|||
res = [{ |
|||
'model': 'guardian.groupobjectpermission', |
|||
'pk': gp.pk, |
|||
'fields': { |
|||
'group': gp.group.pk, |
|||
'permission': gp.permission.pk, |
|||
'content_type': gp.content_type.pk, |
|||
'object_pk': str(gp.object_pk), |
|||
'content_object': gp.content_object.pk |
|||
} |
|||
} for gp in models.GroupObjectPermission.objects.all()] |
|||
print('guardian.userobjectpermission') |
|||
res += [{ |
|||
'model': 'guardian.userobjectpermission', |
|||
'pk': up.pk, |
|||
'fields': { |
|||
'permission': up.permission.pk, |
|||
'content_type': up.content_type.pk, |
|||
'object_pk': str(up.object_pk), |
|||
'user': up.user.pk |
|||
} |
|||
} for up in models.UserObjectPermission.objects.all()] |
|||
return res |
|||
|
|||
|
|||
def make_migration(): |
|||
from datetime import datetime, date |
|||
|
|||
def my_date_converter(o): |
|||
if isinstance(o, datetime) or isinstance(o, date): |
|||
return "%s" % o |
|||
|
|||
def appdump(path, func): |
|||
fname = os.path.join(*path) |
|||
path_dir = os.path.join(*path[:-1]) |
|||
if not os.path.isdir(path_dir): |
|||
os.mkdir(path_dir) |
|||
with open(fname, 'w') as f: |
|||
dump(func(), f, default=my_date_converter, ensure_ascii=False) |
|||
|
|||
if not os.path.isdir('fixtures'): |
|||
os.mkdir('fixtures') |
|||
appdump(['fixtures', 'group_app', 'groups_fixture.json'], dump_groups) |
|||
appdump(['fixtures', 'tariff_app', 'tariffs_fixture.json'], dump_tariffs) |
|||
appdump(['fixtures', 'photo_app', 'photos_fixture.json'], dump_photos) |
|||
appdump(['fixtures', 'devapp', 'devs_fixture.json'], dump_devs) |
|||
appdump(['fixtures', 'accounts_app', 'accounts_fixture.json'], dump_accounts) |
|||
appdump(['fixtures', 'abonapp', 'abon_fixture.json'], dump_abonapp) |
|||
appdump(['fixtures', 'chatbot', 'chatbot_fixture.json'], dump_chatbot) |
|||
appdump(['fixtures', 'mapapp', 'map_fixture.json'], dump_map) |
|||
appdump(['fixtures', 'taskapp', 'task_fixture.json'], dump_task_app) |
|||
# appdump(['fixtures', 'accounts_app', 'auth_fixture.json'], dump_auth) |
|||
# appdump(['fixtures', 'accounts_app', 'guardian_fixture.json'], dump_guardian) |
|||
|
|||
|
|||
def move_to_fixtures_dirs(): |
|||
fixdir = 'fixtures' |
|||
for dr in os.listdir(fixdir): |
|||
fixture_dir = os.path.join(fixdir, dr) |
|||
for fixture_file in os.listdir(fixture_dir): |
|||
from_file = os.path.join(fixture_dir, fixture_file) |
|||
dst_dir = os.path.join(dr, fixdir) |
|||
to_file = os.path.join(dst_dir, fixture_file) |
|||
if not os.path.isdir(dst_dir): |
|||
os.mkdir(dst_dir) |
|||
shutil.copyfile(from_file, to_file) |
|||
print('cp %s -> %s' % (from_file, to_file)) |
|||
|
|||
|
|||
def apply_fixtures(): |
|||
from django.core.management import execute_from_command_line |
|||
from accounts_app.models import UserProfile |
|||
# from django.contrib.auth import models |
|||
|
|||
UserProfile.objects.filter(username='AnonymousUser').delete() |
|||
# print('clearing auth.group') |
|||
# models.Group.objects.all().delete() |
|||
# print('clearing auth.permission') |
|||
# models.Permission.objects.all().delete() |
|||
|
|||
fixtures_names = [ |
|||
'groups_fixture.json', 'tariffs_fixture.json', 'photos_fixture.json', |
|||
'devs_fixture.json', 'accounts_fixture.json', 'abon_fixture.json', |
|||
'chatbot_fixture.json', 'map_fixture.json', 'task_fixture.json' |
|||
] |
|||
# 'auth_fixture.json', 'guardian_fixture.json' |
|||
print('./manage.py loaddata ' + ', '.join(fixtures_names)) |
|||
execute_from_command_line([sys.argv[0], 'loaddata'] + fixtures_names) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
if len(sys.argv) < 2: |
|||
print('Usage: ./migrate_to_0.2.py [makedump OR applydump]') |
|||
exit(1) |
|||
choice = sys.argv[1] |
|||
if choice == 'applydump': |
|||
django.setup() |
|||
move_to_fixtures_dirs() |
|||
apply_fixtures() |
|||
shutil.rmtree('fixtures') |
|||
elif choice == 'makedump': |
|||
django.setup() |
|||
make_migration() |
|||
else: |
|||
print('Unexpected choice') |
|||
@ -1,187 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from datetime import timedelta |
|||
from json import dumps |
|||
import socket |
|||
import struct |
|||
from collections import Iterator |
|||
from functools import wraps |
|||
from django.http import HttpResponse, Http404, HttpResponseRedirect |
|||
from django.shortcuts import redirect |
|||
from django.db import models |
|||
from django.conf import settings |
|||
|
|||
DEBUG = getattr(settings, 'DEBUG', False) |
|||
|
|||
|
|||
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) |
|||
|
|||
|
|||
class MyGenericIPAddressField(models.GenericIPAddressField): |
|||
description = "Int32 notation ip address" |
|||
|
|||
def __init__(self, protocol='ipv4', *args, **kwargs): |
|||
super(MyGenericIPAddressField, self).__init__(protocol=protocol, *args, **kwargs) |
|||
self.max_length = 8 |
|||
|
|||
def get_prep_value(self, value): |
|||
# strIp to Int |
|||
value = super(MyGenericIPAddressField, self).get_prep_value(value) |
|||
return ip2int(value) |
|||
|
|||
def to_python(self, value): |
|||
return value |
|||
|
|||
def get_internal_type(self): |
|||
return 'PositiveIntegerField' |
|||
|
|||
@staticmethod |
|||
def from_db_value(value, expression, connection, context): |
|||
return int2ip(value) if value != 0 else None |
|||
|
|||
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 |
|||
|
|||
|
|||
# Декоратор проверяет аккаунт, чтоб не пускать клиентов в страницы администрации |
|||
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 |
|||
|
|||
|
|||
# Русифицированный вывод 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" % ( |
|||
# hours, |
|||
# minutes |
|||
# ) |
|||
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) |
|||
text_date = '%d %s' % (self.days, ru_days) |
|||
else: |
|||
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, tuple)): |
|||
raise TypeError |
|||
self.err_list = err_list |
|||
|
|||
|
|||
class LogicError(Exception): |
|||
pass |
|||
|
|||
|
|||
def singleton(class_): |
|||
instances = {} |
|||
|
|||
def getinstance(*args, **kwargs): |
|||
if class_ not in instances: |
|||
instances[class_] = class_(*args, **kwargs) |
|||
return instances[class_] |
|||
|
|||
return getinstance |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue