diff --git a/abonapp/forms.py b/abonapp/forms.py index a253024..4d3e3e0 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -76,7 +76,7 @@ class AbonForm(forms.ModelForm): class Opt82Form(forms.ModelForm): - mac = MACAddressField(widget=forms.TextInput(attrs={'class': 'form-control', 'pattern': r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$', 'required': ''})) + mac = MACAddressField(widget=forms.TextInput(attrs={'class': 'form-control', 'pattern': r'^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$', 'required': ''})) class Meta: model = models.Opt82 fields = '__all__' diff --git a/abonapp/models.py b/abonapp/models.py index 1f402b0..8c26888 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -5,7 +5,7 @@ from django.utils import timezone from django.db import models from django.core import validators from django.utils.translation import ugettext as _ -from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult +from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError from ip_pool.models import IpPoolItem from tariff_app.models import Tariff from accounts_app.models import UserProfile @@ -332,7 +332,7 @@ class Abon(UserProfile): agent_trf = TariffStruct(inst_tariff.id, inst_tariff.speedIn, inst_tariff.speedOut) else: agent_trf = TariffStruct() - return AbonStruct(self.pk, user_ip, agent_trf) + return AbonStruct(self.pk, user_ip, agent_trf, bool(self.is_active)) class InvoiceForPayment(models.Model): @@ -403,21 +403,20 @@ def abon_post_save(sender, instance, **kwargs): timeout = None if hasattr(instance, 'opt82'): timeout = 3600 - tm = Transmitter() agent_abon = instance.build_agent_struct() if agent_abon is None: return True - if kwargs['created']: - # создаём абонента - tm.add_user(agent_abon, ip_timeout=timeout) - else: - # обновляем абонента на NAS - tm.update_user(agent_abon, ip_timeout=timeout) - # если не активен то приостановим услугу - if instance.is_active: - tm.start_user(agent_abon) + try: + tm = Transmitter() + if kwargs['created']: + # создаём абонента + tm.add_user(agent_abon, ip_timeout=timeout) else: - tm.pause_user(agent_abon) + # обновляем абонента на NAS + tm.update_user(agent_abon, ip_timeout=timeout) + + except (NasFailedResult, NasNetworkError): + return True def abon_del_signal(sender, instance, **kwargs): @@ -427,7 +426,7 @@ def abon_del_signal(sender, instance, **kwargs): tm = Transmitter() # нашли абонента, и удаляем его на NAS tm.remove_user(ab) - except NasFailedResult: + except (NasFailedResult, NasNetworkError): return True @@ -444,7 +443,7 @@ def abontariff_post_save(sender, instance, **kwargs): return True tm = Transmitter() tm.update_user(agent_abon) - except NasFailedResult: + except (NasFailedResult, NasNetworkError): return True @@ -459,7 +458,7 @@ def abontariff_del_signal(sender, instance, **kwargs): agent_abon = instance.abon.build_agent_struct() tm = Transmitter() tm.pause_user(agent_abon) - except NasFailedResult: + except (NasFailedResult, NasNetworkError): return True diff --git a/agent/mod_mikrotik.py b/agent/mod_mikrotik.py index 869f8c8..05bfd4a 100644 --- a/agent/mod_mikrotik.py +++ b/agent/mod_mikrotik.py @@ -206,7 +206,8 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta): uid=int(info['=name'][3:]), #FIXME: тут в разных микротиках или =target-addresses или =target ip=info['=target'][:-3], - tariff=t + tariff=t, + is_active=False if info['=disabled'] == 'false' else True ) return ShapeItem(abon=a, sid=info['=.id'].replace('*', '')) except KeyError: @@ -389,6 +390,14 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager): #ищем ip абонента в списке ip find_res = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED) + if not user.is_active: + # если не активен - то и обновлять не надо + # но и выключить на всяк случай надо, а то вдруг был включён + if len(find_res) > 1: + # и если найден был - то удалим ip из разрешённых + IpAddressListManager.remove(self, find_res[0]['=.id']) + return + # если не найден (mikrotik возвращает пустой словарь в списке если ничего нет) if len(find_res) < 2: # добавим запись об абоненте @@ -409,13 +418,11 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager): # приостановливаем обслуживание абонента def pause_user(self, user): - IpAddressListManager.disable(self, user) - QueueManager.disable(self, user) + pass # продолжаем обслуживание абонента def start_user(self, user): - QueueManager.enable(self, user) - IpAddressListManager.enable(self, user) + pass # Тарифы хранить нам не надо, так что методы тарифов ниже не реализуем def add_tariff_range(self, tariff_list): diff --git a/agent/structs.py b/agent/structs.py index 9f444b0..2bb2efa 100644 --- a/agent/structs.py +++ b/agent/structs.py @@ -53,8 +53,8 @@ class TariffStruct(BaseStruct): def __init__(self, tariff_id=0, speedIn=None, speedOut=None): self.tid = tariff_id - self.speedIn = speedIn if speedIn is not None else 5.0625 - self.speedOut = speedOut if speedOut is not None else 5.0625 + self.speedIn = speedIn if speedIn is not None else 0.0625 + self.speedOut = speedOut if speedOut is not None else 0.0625 def serialize(self): dt = pack("!Iff", int(self.tid), float(self.speedIn), float(self.speedOut)) @@ -80,25 +80,27 @@ class TariffStruct(BaseStruct): # Абонент из базы class AbonStruct(BaseStruct): - def __init__(self, uid=None, ip=None, tariff=None): + def __init__(self, uid=None, ip=None, tariff=None, is_active=True): self.uid = int(uid) self.ip = IpStruct(ip) assert isinstance(tariff, TariffStruct) self.tariff = tariff + self.is_active = is_active def serialize(self): assert isinstance(self.tariff, TariffStruct) assert isinstance(self.ip, IpStruct) - dt = pack("!LII", self.uid, self.ip.get_int(), self.tariff.tid) + dt = pack("!LII?", self.uid, self.ip.get_int(), self.tariff.tid, self.is_active) return dt def deserialize(self, data, tariff=None): - dt = unpack("!LII", data) + dt = unpack("!LII?", data) self.uid = dt[0] self.ip = IpStruct(dt[1]) if tariff is not None: assert isinstance(tariff, TariffStruct) self.tariff = tariff + self.is_active = dt['3'] return self def __eq__(self, other): diff --git a/cron.py b/cron.py index 582ce34..3e16d91 100755 --- a/cron.py +++ b/cron.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import django @@ -34,11 +34,6 @@ def main(): # ищем абонента в списке инфы из nas tm.update_user(ab) - # если не активен то приостановим услугу - if user.is_active: - tm.start_user(ab) - else: - tm.pause_user(ab) except NasNetworkError as er: print("Error:", er) @@ -51,7 +46,5 @@ def main(): if __name__ == "__main__": try: main() - except NasNetworkError as e: - print(e) - except NasFailedResult as e: - print(e) + except (NasNetworkError, NasFailedResult) as e: + print('NAS:', e) diff --git a/djing/utils/load_from_nodeny.py b/djing/utils/load_from_nodeny.py index f01e43c..c8aa523 100755 --- a/djing/utils/load_from_nodeny.py +++ b/djing/utils/load_from_nodeny.py @@ -35,9 +35,12 @@ def load_service(cursor, uid): def load_users(cursor, grp_id): # выбираем абонентов sql = r"SELECT users.name, users.fio, data0._adr_telefon, dictionary.v AS street, data0._adr_house, data0._birthday, " \ - "users.grp, INET_NTOA(ip_pool.ip) AS ip, users.balance, AES_DECRYPT(users.passwd, 'Vu6saiZa') as decr_passwd, users.id " \ - "FROM users LEFT JOIN data0 ON (data0.uid = users.id) LEFT JOIN dictionary ON (dictionary.k = data0._adr_street " \ - "AND dictionary.type = 'street') LEFT JOIN ip_pool ON (ip_pool.uid = users.id) WHERE users.grp = %d" % grp_id + "users.grp, INET_NTOA(ip_pool.ip) AS ip, users.balance, AES_DECRYPT(users.passwd, 'Vu6saiZa') as decr_passwd, users.id, " \ + "mac_uid.device_mac, mac_uid.device_port, mac_uid.oneconnect " \ + "FROM users " \ + "LEFT JOIN data0 ON (data0.uid = users.id) LEFT JOIN dictionary ON (dictionary.k = data0._adr_street AND dictionary.type = 'street') " \ + "LEFT JOIN mac_uid ON (mac_uid.uid=users.id) " \ + "LEFT JOIN ip_pool ON (ip_pool.uid = users.id) WHERE users.grp = %d" % grp_id cursor.execute(sql) users = [{ 'name': res[0], @@ -50,7 +53,12 @@ def load_users(cursor, grp_id): 'ip': str(res[7] or ''), 'balance': float(res[8]), 'passw': res[9].decode("utf-8") if res[9] is not None else '', - 'service': load_service(cursor, int(res[10])) + 'service': load_service(cursor, int(res[10])), + 'opt82': { + 'dev_mac': res[11], + 'dev_port': res[12], + 'oneconnect': res[13] + } } for res in cursor.fetchall()] return users diff --git a/djing/utils/save_from_nodeny.py b/djing/utils/save_from_nodeny.py index 060a43e..ab5cc4b 100755 --- a/djing/utils/save_from_nodeny.py +++ b/djing/utils/save_from_nodeny.py @@ -5,14 +5,14 @@ import os from json import load import django from django.utils import timezone +from django.core.exceptions import ValidationError os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") django.setup() -from abonapp.models import Abon, AbonGroup, AbonRawPassword, AbonStreet, AbonTariff +from abonapp.models import Abon, AbonGroup, AbonRawPassword, AbonStreet, AbonTariff, Opt82 from ip_pool.models import IpPoolItem from tariff_app.models import Tariff - class DumpService(object): price = 0.0 speedIn = 0.0 @@ -65,6 +65,12 @@ class DumpAbon(object): self.ip = obj['ip'] if obj['ip'] != '' else None self.balance = obj['balance'] self.passw = obj['passw'] + if obj['opt82']['dev_mac'] is not None and obj['opt82']['dev_port'] is not None: + self.opt82 = { + 'dev_mac': obj['opt82']['dev_mac'], + 'dev_port': obj['opt82']['dev_port'] + } + if obj['service'] is not None: self.service = DumpService(obj['service']) else: @@ -99,6 +105,11 @@ class DumpAbon(object): self.service = DumpService.build_from_db(srv) else: self.service = None + if obj.opt82 is not None and obj.opt82.mac is not None and obj.opt82.port is not None: + self.opt82 = { + 'dev_mac': obj.opt82.mac, + 'dev_port': obj.opt82.port + } return self def __eq__(self, other): @@ -135,6 +146,26 @@ def add_service_if_not_exist(service): return obj +def add_raw_password_if_not_exist(acc, raw_passw): + try: + psw = AbonRawPassword.objects.get(account=acc) + #if psw != raw_passw: + # psw.passw_text = raw_passw + # psw.save(update_fields=['passw_text']) + except AbonRawPassword.DoesNotExist: + psw = AbonRawPassword.objects.create(account=acc, passw_text=raw_passw) + return psw + + +def add_opt82_if_not_exist(mac, port): + print(mac, port) + try: + opt82 = Opt82.objects.get(mac=mac, port=port) + except Opt82.DoesNotExist: + opt82 = Opt82.objects.create(mac=mac, port=port) + return opt82 + + def load_users(obj, group): if len(obj) < 1: return @@ -151,6 +182,8 @@ def load_users(obj, group): except Abon.DoesNotExist: # добавляем абонента abon = add_user(dump_abon, group) + if abon is None: + raise Exception("Чё за херня!? Не создался абонент") abon_service_from_dump = dump_abon.service if abon_service_from_dump is None: @@ -166,6 +199,12 @@ def load_users(obj, group): time_start=timezone.now(), deadline=calc_obj.calc_deadline() ) + try: + if hasattr(dump_abon, 'opt82'): + abon.opt82 = add_opt82_if_not_exist(dump_abon.opt82['dev_mac'], dump_abon.opt82['dev_port']) + abon.save(update_fields=['opt82']) + except ValidationError as e: + print('\t', e) def add_user(obj, user_group): @@ -182,17 +221,20 @@ def add_user(obj, user_group): except AbonStreet.DoesNotExist: street = AbonStreet.objects.create(name=obj.street, group=user_group) - return Abon.objects.create( - username=obj.name, - fio=obj.fio, - telephone=obj.tel, - street=street, - house=obj.house, - birth_day=obj.birth, - group = user_group, - ip_address=ip, - ballance=obj.balance - ) + abon = Abon() + abon.username = obj.name + abon.fio = obj.fio + abon.telephone = obj.tel + abon.street = street + abon.house = obj.house + abon.birth_day = obj.birth + abon.group = user_group + abon.ip_address = ip + abon.ballance = obj.balance + abon.set_password(obj.passw) + abon.save() + add_raw_password_if_not_exist(abon, obj.passw) + return abon def update_user(db_abon, obj, user_group): @@ -217,7 +259,9 @@ def update_user(db_abon, obj, user_group): db_abon.group = user_group db_abon.ip_address = ip db_abon.ballance = obj.balance + db_abon.set_password(obj.passw) db_abon.save() + add_raw_password_if_not_exist(db_abon, obj.passw) if __name__ == "__main__": diff --git a/taskapp/migrations/0012_auto_20170407_0124.py b/taskapp/migrations/0012_auto_20170407_0124.py new file mode 100644 index 0000000..9128309 --- /dev/null +++ b/taskapp/migrations/0012_auto_20170407_0124.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-04-06 22:24 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('taskapp', '0011_auto_20170116_0126'), + ] + + operations = [ + migrations.AlterField( + model_name='task', + name='attachment', + field=models.ImageField(blank=True, null=True, upload_to='media/task_attachments/%Y.%m.%d'), + ), + ] diff --git a/taskapp/models.py b/taskapp/models.py index 649ad70..e738742 100644 --- a/taskapp/models.py +++ b/taskapp/models.py @@ -67,7 +67,7 @@ class Task(models.Model): out_date = models.DateField(null=True, blank=True, default=_delta_add_days) time_of_create = models.DateTimeField(auto_now_add=True) state = models.CharField(max_length=1, choices=TASK_STATES, default=TASK_STATES[0][0]) - attachment = models.ImageField(upload_to='task_attachments/%Y.%m.%d', blank=True, null=True) + attachment = models.ImageField(upload_to='media/task_attachments/%Y.%m.%d', blank=True, null=True) mode = models.CharField(max_length=2, choices=TASK_TYPES, default=TASK_TYPES[0][0]) abon = models.ForeignKey(Abon, on_delete=models.SET_NULL, null=True, blank=True, related_name='+')