From fbd93d719f4af458505ec36ce304e69c48d8d9a3 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 20 May 2017 14:12:03 +0300 Subject: [PATCH 001/179] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D1=82=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=B4=D0=BB=D1=8F=20=D1=87=D1=82=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BB=D0=B8=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE?= =?UTF-8?q?=D0=B4=D1=8B=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B8=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BD=D0=B0=20=D1=82=D0=B5=20=D0=BA=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D1=8B=D0=B5=20=D0=BD=D0=B8=D1=87=D0=B5=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BD=D0=B5=20=D0=B4=D0=B5=D0=BB=D0=B0=D1=8E=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/models.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/statistics/models.py b/statistics/models.py index 8940d52..9ab0f18 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -31,6 +31,12 @@ class StatElem(models.Model): objects = StatManager() + def save(self, *args, **kwargs): + return + + def delete(self, *args, **kwargs): + return + @staticmethod def percentile(N, percent, key=lambda x:x): """ From 51fda660ee09fb3582fd03c419210a133ab5f05e Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 12:05:21 +0300 Subject: [PATCH 002/179] refactor --- devapp/locale/ru/LC_MESSAGES/django.po | 76 +++++++++++++++----------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index 5c0d5eb..c376b20 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-27 12:27+0300\n" +"POT-Creation-Date: 2017-05-22 11:59+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" "Language: ru\n" @@ -19,6 +19,22 @@ msgstr "" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" +#: devapp/dev_types.py:54 +msgid "DLink switch" +msgstr "Свич D'Link" + +#: devapp/dev_types.py:70 +msgid "does not fetch the name" +msgstr "не получил имя" + +#: devapp/dev_types.py:72 +msgid "does not fetch the mac" +msgstr "не нашёл мак" + +#: devapp/dev_types.py:116 +msgid "PON ONU" +msgstr "ONU Голова" + #: devapp/templates/devapp/add_dev.html:7 #: devapp/templates/devapp/devices.html:7 #: devapp/templates/devapp/devices_null_group.html:7 @@ -114,6 +130,26 @@ msgstr "Эта точка не пингуется" msgid "Add group" msgstr "" +#: devapp/templates/devapp/olt.html:13 +msgid "Mac" +msgstr "Мак" + +#: devapp/templates/devapp/olt.html:14 +msgid "Name" +msgstr "Имя" + +#: devapp/templates/devapp/olt.html:15 +msgid "Distance(m)" +msgstr "Расстояние (м)" + +#: devapp/templates/devapp/olt.html:16 +msgid "Signal" +msgstr "Ур. сигнала" + +#: devapp/templates/devapp/olt.html:34 +msgid "Ports not found" +msgstr "Онушки не получил" + #: devapp/templates/devapp/ports.html:9 msgid "Title of the type of switch" msgstr "Название типа свича" @@ -170,47 +206,21 @@ msgstr "Инфа о точке сохранена" msgid "Form is invalid, check fields and try again" msgstr "Ошибка в данных, проверте их ещё раз" -#: devapp/views.py:112 devapp/views.py:140 +#: devapp/views.py:114 devapp/views.py:144 msgid "Not Set snmp device password" msgstr "Не указан snmp пароль для устройства" -#: devapp/views.py:114 devapp/views.py:142 +#: devapp/views.py:116 devapp/views.py:146 msgid "Dot was not pinged" msgstr "Эта точка не пингуется" -#: devapp/views.py:116 +#: devapp/views.py:118 msgid "wait for a reply from the SNMP Timeout" msgstr "Время ожидания ответа от SNMP истекло" -msgid "Ports" -msgstr "Порты" +#: devapp/views.py:120 +msgid "SNMP error on device" +msgstr "Ошибка SNMP на устройстве" msgid "Edit" msgstr "Редактировать" - -msgid "PON ONU" -msgstr "ONU Голова" - -msgid "does not fetch the name" -msgstr "не получил имя" - -msgid "does not fetch the mac" -msgstr "не нашёл мак" - -msgid "Ports not found" -msgstr "Онушки не получил" - -msgid "DLink switch" -msgstr "Свич D'Link" - -msgid "Mac" -msgstr "Мак" - -msgid "Name" -msgstr "Имя" - -msgid "Distance(m)" -msgstr "Расстояние (м)" - -msgid "Signal" -msgstr "Ур. сигнала" From 3fa3dc1d41efade8137d3ae6f1d24611f0110c5f Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 12:12:42 +0300 Subject: [PATCH 003/179] refactor --- abonapp/locale/ru/LC_MESSAGES/django.po | 428 ++++++++++++++---------- 1 file changed, 248 insertions(+), 180 deletions(-) diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 40513ea..bf181a3 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-25 00:40+0300\n" +"POT-Creation-Date: 2017-05-22 11:59+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" "Language: ru\n" @@ -19,27 +19,37 @@ msgstr "" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" -#: abonapp/forms.py:29 abonapp/templates/abonapp/addAbon.html.py:21 +#: abonapp/formfields.py:12 +#, fuzzy +#| msgid "Enter a valid MAC Address." +msgid "Enter a valid integer." +msgstr "Введите валидный mac адрес" + +#: abonapp/formfields.py:21 +msgid "Enter a valid MAC Address." +msgstr "Введите валидный mac адрес" + +#: abonapp/forms.py:43 abonapp/templates/abonapp/addAbon.html.py:21 #: abonapp/templates/abonapp/editAbon.html:15 #: abonapp/templates/abonapp/viewAbon.html:28 msgid "login" msgstr "Логин" -#: abonapp/forms.py:42 abonapp/templates/abonapp/editAbon.html.py:22 -#: abonapp/templates/abonapp/peoples.html:33 +#: abonapp/forms.py:56 abonapp/templates/abonapp/editAbon.html.py:22 +#: abonapp/templates/abonapp/peoples.html:36 #: abonapp/templates/abonapp/viewAbon.html:32 msgid "fio" msgstr "ФИО" -#: abonapp/forms.py:47 +#: abonapp/forms.py:61 msgid "telephone placeholder" msgstr "+[7,8,9,3] и 10,11 цифр" -#: abonapp/models.py:26 +#: abonapp/models.py:23 msgid "fill account" msgstr "Пополнение счёта" -#: abonapp/models.py:119 +#: abonapp/models.py:116 msgid "not enough money" msgstr "Не хватает денег на счету" @@ -63,30 +73,35 @@ msgstr "Текстовое поле" msgid "Floating field" msgstr "Дробное с плавающей точкой" -#: abonapp/models.py:178 +#: abonapp/models.py:165 abonapp/templates/abonapp/editAbon.html.py:36 +#: abonapp/templates/abonapp/viewAbon.html:50 +msgid "Ip Address" +msgstr "IP Адрес" + +#: abonapp/models.py:190 msgid "Double invalid value" msgstr "Введите число с плавающей запятой" -#: abonapp/models.py:219 +#: abonapp/models.py:243 msgid "Buy service perm" msgstr "Покупка тарифа абоненту" -#: abonapp/models.py:220 +#: abonapp/models.py:244 msgid "Can view passport" msgstr "Может просматривать паспортные данные" -#: abonapp/models.py:224 -msgid "pay log" -msgstr "Снятие со счёта средств" - -#: abonapp/models.py:270 +#: abonapp/models.py:288 msgid "Buy service default log" msgstr "Покупка тарифного плана через админку" -#: abonapp/models.py:285 +#: abonapp/models.py:303 msgid "service overdue log" msgstr "Услуга просрочена, отключаем, и подключаем новую" +#: abonapp/models.py:346 +msgid "Ip address already exist" +msgstr "Такой ip уже у кого-то есть" + #: abonapp/templates/abonapp/activate_service.html:8 #: abonapp/templates/abonapp/addAbon.html:7 #: abonapp/templates/abonapp/addGroup.html:7 @@ -101,7 +116,7 @@ msgstr "Услуга просрочена, отключаем, и подключ #: abonapp/templates/abonapp/invoiceForPayment.html:7 #: abonapp/templates/abonapp/log.html:7 #: abonapp/templates/abonapp/peoples.html:8 -#: abonapp/templates/abonapp/peoples.html:114 +#: abonapp/templates/abonapp/peoples.html:127 msgid "User groups" msgstr "Группы абонентов" @@ -129,21 +144,24 @@ msgstr "" "руб, останется %(diff)s руб.
Услуга будет действовать до %(deadline)s" #: abonapp/templates/abonapp/activate_service.html:34 -#: abonapp/templates/abonapp/addAbon.html:86 +#: abonapp/templates/abonapp/addAbon.html:91 #: abonapp/templates/abonapp/addGroup.html:29 #: abonapp/templates/abonapp/addInvoice.html:46 -#: abonapp/templates/abonapp/buy_tariff.html:38 +#: abonapp/templates/abonapp/buy_tariff.html:57 #: abonapp/templates/abonapp/complete_service.html:49 #: abonapp/templates/abonapp/editAbon.html:96 +#: abonapp/templates/abonapp/editAbon.html:165 +#: abonapp/templates/abonapp/editAbon.html:211 #: abonapp/templates/abonapp/group_tariffs.html:29 -#: abonapp/templates/abonapp/passport_view.html:42 +#: abonapp/templates/abonapp/modal_dev.html:29 +#: abonapp/templates/abonapp/passport_view.html:49 msgid "Save" msgstr "Сохранить" #: abonapp/templates/abonapp/addAbon.html:9 #: abonapp/templates/abonapp/addAbon.html:16 -#: abonapp/templates/abonapp/peoples.html:97 -#: abonapp/templates/abonapp/peoples.html:108 +#: abonapp/templates/abonapp/peoples.html:110 +#: abonapp/templates/abonapp/peoples.html:121 msgid "Add abon" msgstr "Добавить абонента" @@ -153,7 +171,7 @@ msgstr "Фамилия и Имя" #: abonapp/templates/abonapp/addAbon.html:37 #: abonapp/templates/abonapp/editAbon.html:29 -#: abonapp/templates/abonapp/peoples.html:49 +#: abonapp/templates/abonapp/peoples.html:52 #: abonapp/templates/abonapp/viewAbon.html:36 msgid "Telephone" msgstr "Телефон" @@ -177,13 +195,13 @@ msgstr "Комментарий" #: abonapp/templates/abonapp/addAbon.html:59 #: abonapp/templates/abonapp/editAbon.html:43 -#: abonapp/templates/abonapp/peoples.html:39 +#: abonapp/templates/abonapp/peoples.html:42 #: abonapp/templates/abonapp/viewAbon.html:40 msgid "Street" msgstr "Улица" #: abonapp/templates/abonapp/addAbon.html:67 -#: abonapp/templates/abonapp/peoples.html:45 +#: abonapp/templates/abonapp/peoples.html:48 msgid "Apartment" msgstr "Квартира" @@ -193,12 +211,14 @@ msgstr "Квартира" msgid "Password" msgstr "Пароль" -#: abonapp/templates/abonapp/addAbon.html:89 +#: abonapp/templates/abonapp/addAbon.html:94 #: abonapp/templates/abonapp/addGroup.html:32 #: abonapp/templates/abonapp/addInvoice.html:49 -#: abonapp/templates/abonapp/buy_tariff.html:41 +#: abonapp/templates/abonapp/buy_tariff.html:60 #: abonapp/templates/abonapp/group_tariffs.html:29 -#: abonapp/templates/abonapp/modal_abonamount.html:26 +#: abonapp/templates/abonapp/modal_abonamount.html:25 +#: abonapp/templates/abonapp/modal_dev.html:32 +#: abonapp/templates/abonapp/modal_extra_field.html:40 msgid "Reset" msgstr "Сбросить" @@ -245,10 +265,15 @@ msgstr "Купить новую услугу (заказать тариф) дл #: abonapp/templates/abonapp/debtors.html:20 #: abonapp/templates/abonapp/log.html:19 #: abonapp/templates/abonapp/payHistory.html:8 -#: abonapp/templates/abonapp/peoples.html:21 +#: abonapp/templates/abonapp/peoples.html:23 msgid "Sub" msgstr "Абонент" +#: abonapp/templates/abonapp/buy_tariff.html:32 +#: abonapp/templates/abonapp/group_tariffs.html:24 +msgid "currency" +msgstr "руб" + #: abonapp/templates/abonapp/complete_service.html:10 #: abonapp/templates/abonapp/complete_service.html:17 #: abonapp/templates/abonapp/services.html:72 @@ -314,15 +339,23 @@ msgstr "Нет должников" msgid "Change subscriber" msgstr "Изменение абонента" -#: abonapp/templates/abonapp/editAbon.html:36 -#: abonapp/templates/abonapp/editAbon.html:117 -#: abonapp/templates/abonapp/editAbon.html:135 -#: abonapp/templates/abonapp/viewAbon.html:50 -msgid "Ip Address" -msgstr "IP Адрес" +#: abonapp/templates/abonapp/editAbon.html:38 +#: abonapp/templates/abonapp/editAbon.html:189 +#: abonapp/templates/abonapp/peoples.html:81 +#: abonapp/templates/abonapp/peoples.html:83 +#: abonapp/templates/abonapp/peoples.html:84 +#: abonapp/templates/abonapp/viewAbon.html:18 +#: abonapp/templates/abonapp/viewAbon.html:29 +#: abonapp/templates/abonapp/viewAbon.html:33 +#: abonapp/templates/abonapp/viewAbon.html:37 +#: abonapp/templates/abonapp/viewAbon.html:42 +#: abonapp/templates/abonapp/viewAbon.html:47 +#: abonapp/templates/abonapp/viewAbon.html:51 +msgid "Not assigned" +msgstr "<Не назначен>" #: abonapp/templates/abonapp/editAbon.html:51 -#: abonapp/templates/abonapp/peoples.html:45 +#: abonapp/templates/abonapp/peoples.html:48 #: abonapp/templates/abonapp/viewAbon.html:46 msgid "House" msgstr "Дом" @@ -336,10 +369,61 @@ msgstr "Активен" msgid "Send account info to user" msgstr "Отправить данные абоненту" -#: abonapp/templates/abonapp/editAbon.html:111 +#: abonapp/templates/abonapp/editAbon.html:102 +#: abonapp/templates/abonapp/editAbon.html:103 +#, fuzzy +#| msgid "Add debt" +msgid "Add new task" +msgstr "Добавить квитанцию" + +#: abonapp/templates/abonapp/editAbon.html:116 +msgid "Remove clutch" +msgstr "Удалить муфту" + +#: abonapp/templates/abonapp/editAbon.html:120 +#: abonapp/templates/abonapp/modal_dev.html:6 +msgid "Add clutch" +msgstr "Добавить муфту" + +#: abonapp/templates/abonapp/editAbon.html:143 msgid "DHCP information" msgstr "DHCP информация" +#: abonapp/templates/abonapp/editAbon.html:149 +msgid "Mac Address" +msgstr "Мак" + +#: abonapp/templates/abonapp/editAbon.html:156 +msgid "Port" +msgstr "Порт" + +#: abonapp/templates/abonapp/editAbon.html:167 +msgid "Reset option82" +msgstr "Сбросить option82" + +#: abonapp/templates/abonapp/editAbon.html:168 +#: abonapp/templates/abonapp/editAbon.html:192 +msgid "Delete" +msgstr "Удалить" + +#: abonapp/templates/abonapp/editAbon.html:178 +msgid "Extra fields" +msgstr "Динамические записи" + +#: abonapp/templates/abonapp/editAbon.html:201 abonapp/views.py:824 +msgid "Extra field does not exist" +msgstr "Поле не найдено" + +#: abonapp/templates/abonapp/editAbon.html:206 +#: abonapp/templates/abonapp/modal_extra_field.html:6 +msgid "Add extra field" +msgstr "Добавить новое динамическое поле" + +#: abonapp/templates/abonapp/editAbon.html:207 +#: abonapp/templates/abonapp/modal_extra_field.html:37 +msgid "Add" +msgstr "Добавить" + #: abonapp/templates/abonapp/group_list.html:27 msgid "Number of subscribers" msgstr "Количество абонентов" @@ -420,10 +504,26 @@ msgstr "Начисление средств на счёт" msgid "Amount of money" msgstr "Количество денег" -#: abonapp/templates/abonapp/modal_abonamount.html:23 +#: abonapp/templates/abonapp/modal_abonamount.html:22 msgid "Refill" msgstr "Пополнить" +#: abonapp/templates/abonapp/modal_dev.html:13 +msgid "Select a device" +msgstr "Выберите устройство" + +#: abonapp/templates/abonapp/modal_extra_field.html:11 +msgid "Field title" +msgstr "Название поля" + +#: abonapp/templates/abonapp/modal_extra_field.html:20 +msgid "Field type" +msgstr "Тип динамического поля" + +#: abonapp/templates/abonapp/modal_extra_field.html:28 +msgid "Field content" +msgstr "Содержимое динамического поля" + #: abonapp/templates/abonapp/passport_view.html:9 #: abonapp/templates/abonapp/viewAbon.html:67 msgid "Passport information" @@ -444,8 +544,8 @@ msgid "Distributor" msgstr "Кем выдан" #: abonapp/templates/abonapp/passport_view.html:33 -msgid "Birthday" -msgstr "Дата рождения" +msgid "Date of acceptance" +msgstr "Дата выдачи" #: abonapp/templates/abonapp/payHistory.html:26 msgid "Payment history is empty" @@ -460,45 +560,40 @@ msgid "The people in the selected group" msgstr "Народ в выбранной группе" #: abonapp/templates/abonapp/peoples.html:27 +msgid "Last traffic" +msgstr "Последний траффик" + +#: abonapp/templates/abonapp/peoples.html:30 #, fuzzy #| msgid "Ip Address" msgid "Ip address" msgstr "IP Адрес" -#: abonapp/templates/abonapp/peoples.html:50 +#: abonapp/templates/abonapp/peoples.html:53 #: abonapp/templates/abonapp/services.html:10 msgid "Service" msgstr "Услуга" -#: abonapp/templates/abonapp/peoples.html:53 +#: abonapp/templates/abonapp/peoples.html:56 msgid "Ballance" msgstr "Балланс" -#: abonapp/templates/abonapp/peoples.html:68 -#: abonapp/templates/abonapp/peoples.html:70 -#: abonapp/templates/abonapp/peoples.html:71 -#: abonapp/templates/abonapp/viewAbon.html:18 -#: abonapp/templates/abonapp/viewAbon.html:29 -#: abonapp/templates/abonapp/viewAbon.html:33 -#: abonapp/templates/abonapp/viewAbon.html:37 -#: abonapp/templates/abonapp/viewAbon.html:42 -#: abonapp/templates/abonapp/viewAbon.html:47 -#: abonapp/templates/abonapp/viewAbon.html:51 -msgid "Not assigned" -msgstr "<Не назначен>" - -#: abonapp/templates/abonapp/peoples.html:95 +#: abonapp/templates/abonapp/peoples.html:108 msgid "Subscribers not found" msgstr "Абоненты не найдены" -#: abonapp/templates/abonapp/peoples.html:112 +#: abonapp/templates/abonapp/peoples.html:125 msgid "Refresh subscribers on NAS" msgstr "Обновить абонентов в NAS" -#: abonapp/templates/abonapp/peoples.html:115 +#: abonapp/templates/abonapp/peoples.html:128 msgid "Tariffs in groups" msgstr "Тарифы в группах" +#: abonapp/templates/abonapp/peoples.html:141 +msgid "No streets found for that group" +msgstr "Не найдены улицы для группы" + #: abonapp/templates/abonapp/services.html:5 msgid "Services of subscriber" msgstr "Купленные абонентом услуги (назначенные тарифные планы)" @@ -515,6 +610,14 @@ msgstr "Входящая скорость" msgid "Output speed" msgstr "Исходящая скорость" +#: abonapp/templates/abonapp/services.html:14 +msgid "Works until" +msgstr "Действует до" + +#: abonapp/templates/abonapp/services.html:15 +msgid "Do" +msgstr "Действия" + #: abonapp/templates/abonapp/services.html:52 msgid "Priority up" msgstr "Повысить приоритет" @@ -567,207 +670,166 @@ msgstr "Просмотр абонента" msgid "yes,no" msgstr "Да,Нет" -#: abonapp/views.py:51 +#: abonapp/views.py:74 msgid "create group success msg" msgstr "Группа успешно создана" -#: abonapp/views.py:54 abonapp/views.py:112 abonapp/views.py:253 +#: abonapp/views.py:77 abonapp/views.py:137 abonapp/views.py:282 +#: abonapp/views.py:337 abonapp/views.py:426 abonapp/views.py:637 +#: abonapp/views.py:779 msgid "fix form errors" msgstr "Некоторые поля заполнены не правильно, проверте ещё раз" -#: abonapp/views.py:89 abonapp/views.py:154 +#: abonapp/views.py:113 abonapp/views.py:176 msgid "delete group success msg" msgstr "Группа успешно удалена" -#: abonapp/views.py:109 +#: abonapp/views.py:134 msgid "create abon success msg" msgstr "Абонент успешно создан" -#: abonapp/views.py:126 +#: abonapp/views.py:148 msgid "Address" msgstr "Адрес" -#: abonapp/views.py:148 +#: abonapp/views.py:170 msgid "delete abon success msg" msgstr "Абонент успешно удалён" -#: abonapp/views.py:157 +#: abonapp/views.py:179 msgid "I not know what to delete" msgstr "Не понятно что удалять" -#: abonapp/views.py:161 +#: abonapp/views.py:183 #, python-format msgid "NAS says: '%s'" msgstr "NAS сказал: '%s'" -#: abonapp/views.py:174 +#: abonapp/views.py:199 msgid "fill account through admin side" msgstr "Пополнение счёта через админку" -#: abonapp/views.py:176 +#: abonapp/views.py:201 #, python-format msgid "Account filled successfully on %.2f" msgstr "" -#: abonapp/views.py:179 +#: abonapp/views.py:204 msgid "I not know the account id" msgstr "Счёт успешно пополнен на %.2f" -#: abonapp/views.py:251 +#: abonapp/views.py:280 msgid "edit abon success msg" msgstr "Абонент успешно изменён" -#: abonapp/views.py:258 -#, python-format -msgid "Ip address already exist" -msgstr "Такой ip уже у кого-то есть" - -#: abonapp/views.py:268 +#: abonapp/views.py:295 msgid "User has not have password, and cannot login" msgstr "Для абонента не задан пароль, он не сможет войти в учётку" -#: abonapp/views.py:315 +#: abonapp/views.py:297 abonapp/views.py:692 +msgid "User device was not found" +msgstr "Пользовательское устройство не найдено" + +#: abonapp/views.py:350 +#, fuzzy +#| msgid "Abon does not exist" +msgid "User does not exist" +msgstr "Абонент не найден" + +#: abonapp/views.py:383 msgid "Receipt has been created" msgstr "Квитанция на оплату была создана" -#: abonapp/views.py:339 +#: abonapp/views.py:413 msgid "Tariff has been picked" msgstr "Тариф успешно выбран" -#: abonapp/views.py:349 +#: abonapp/views.py:421 msgid "Tariff your picked does not exist" msgstr "Тариф, который вы выбрали, не существует" -#: abonapp/views.py:406 +#: abonapp/views.py:484 msgid "Refunds for unused resources" msgstr "Возврат средств за неиспользованные ресурсы" -#: abonapp/views.py:412 +#: abonapp/views.py:490 msgid "Service has been finished successfully" msgstr "Услуга успешно завершена" -#: abonapp/views.py:415 abonapp/views.py:446 +#: abonapp/views.py:493 abonapp/views.py:525 msgid "Not confirmed" msgstr "Действие не подтверждено" -#: abonapp/views.py:449 +#: abonapp/views.py:528 msgid "Service has been activated successfully" msgstr "Услуга успешно активирована" -#: abonapp/views.py:474 +#: abonapp/views.py:554 msgid "User has been detached from service" msgstr "Абонент отвязан от услуги" -msgid "Sub information" -msgstr "Информация абонента" - -msgid "Services" -msgstr "Услуги" - -msgid "Payment history" -msgstr "История платежей" - -msgid "Payments" -msgstr "Финансы" - -msgid "History of tasks" -msgstr "История задач" - -msgid "Dynamic Field" -msgstr "Динамическое поле" - -msgid "Mac Address" -msgstr "Мак" - -msgid "Port" -msgstr "Порт" - -msgid "Enter a valid MAC Address." -msgstr "Введите валидный mac адрес" - -msgid "Reset option82" -msgstr "Сбросить option82" - -msgid "Delete" -msgstr "Удалить" - -msgid "Instance of a option82 unexpectiadly disappeared" -msgstr "Экземпляр option82 неожиданно исчез из базы" - -msgid "SNMP error on device" -msgstr "Ошибка в SNMP на устройстве" - -msgid "No streets found for that group" -msgstr "Не найдены улицы для группы" - -msgid "Date of acceptance" -msgstr "Дата выдачи" - +#: abonapp/views.py:634 msgid "Passport information has been saved" msgstr "Информация о паспорте сохранена" +#: abonapp/views.py:642 abonapp/views.py:689 abonapp/views.py:709 +#: abonapp/views.py:750 msgid "Abon does not exist" msgstr "Абонент не найден" +#: abonapp/views.py:645 msgid "Passport info for the user does not exist" msgstr "Для абонента не найдены паспортные данные" -msgid "currency" -msgstr "руб" - -msgid "Charts" -msgstr "Графики" - -msgid "Group what you want doesn't exist" -msgstr "Указанная вами группа не найдена" - -msgid "User device was not found" -msgstr "Пользовательское устройство не найдено" - -msgid "Add clutch" -msgstr "Добавить муфту" - -msgid "Remove clutch" -msgstr "Удалить муфту" - -msgid "Select a device" -msgstr "Выберите устройство" +#: abonapp/views.py:682 +msgid "Device has successfully attached" +msgstr "Устройство успешно прикреплено" +#: abonapp/views.py:687 msgid "Device your selected already does not exist" msgstr "Устройство, выбранное вами, уже не существует" -msgid "Device has successfully attached" -msgstr "Устройство успешно прикреплено" - +#: abonapp/views.py:707 msgid "Device has successfully unattached" msgstr "Устройство успешно откреплено" -msgid "Works until" -msgstr "Действует до" - -msgid "Do" -msgstr "Действия" - -msgid "Last traffic" -msgstr "Последний траффик" +#: abonapp/views.py:753 +msgid "Group what you want doesn't exist" +msgstr "Указанная вами группа не найдена" +#: abonapp/views.py:777 msgid "Extra field successfully created" msgstr "Динамичесое поле добавлено успешно" +#: abonapp/views.py:808 +msgid "Extra fields has been saved" +msgstr "Динамические поля сохранены" + +#: abonapp/views.py:810 +msgid "One or more extra fields has not been saved" +msgstr "Поле или одно из полей не найдено" + +#: abonapp/views.py:822 msgid "Extra field successfully deleted" msgstr "Динамическое поле успешно удалено" -msgid "Extra field does not exist" -msgstr "Поле не найдено" +#: abonapp/views.py:832 +msgid "no ping" +msgstr "не пингуется" -msgid "Extra fields" -msgstr "Динамические записи" +#: abonapp/views.py:839 abonapp/views.py:849 +msgid "ping ok" +msgstr "пингуется" -msgid "Add extra field" -msgstr "Добавить новое динамическое поле" +#: abonapp/views.py:844 +#, python-format +msgid "ok ping, %d/%d loses" +msgstr "пингуется, %d/%d" -msgid "Add" -msgstr "Добавить" +#: abonapp/views.py:847 +#, python-format +msgid "no ping, %d/%d loses" +msgstr "не пингуется, %d/%d" msgid "Field title" msgstr "Название поля" @@ -778,20 +840,26 @@ msgstr "Тип динамического поля" msgid "Field content" msgstr "Содержимое динамического поля" -msgid "Extra fields has been saved" -msgstr "Динамические поля сохранены" +msgid "Services" +msgstr "Услуги" -msgid "One or more extra fields has not been saved" -msgstr "Поле или одно из полей не найдено" +msgid "Payment history" +msgstr "История платежей" -msgid "ok ping, %d/%d loses" -msgstr "пингуется, %d/%d" +msgid "Payments" +msgstr "Финансы" -msgid "no ping, %d/%d loses" -msgstr "не пингуется, %d/%d" +msgid "History of tasks" +msgstr "История задач" -msgid "no ping" -msgstr "не пингуется" +msgid "Dynamic Field" +msgstr "Динамическое поле" -msgid "ping ok" -msgstr "пингуется" +msgid "Instance of a option82 unexpectiadly disappeared" +msgstr "Экземпляр option82 неожиданно исчез из базы" + +msgid "SNMP error on device" +msgstr "Ошибка в SNMP на устройстве" + +msgid "Charts" +msgstr "Графики" From 85f4ba2e92d92c4fdd064fcce5047c867acb86c9 Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 12:49:15 +0300 Subject: [PATCH 004/179] refactor --- abonapp/locale/ru/LC_MESSAGES/django.po | 9 --------- 1 file changed, 9 deletions(-) diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index bf181a3..0d37ee5 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -831,15 +831,6 @@ msgstr "пингуется, %d/%d" msgid "no ping, %d/%d loses" msgstr "не пингуется, %d/%d" -msgid "Field title" -msgstr "Название поля" - -msgid "Field type" -msgstr "Тип динамического поля" - -msgid "Field content" -msgstr "Содержимое динамического поля" - msgid "Services" msgstr "Услуги" From eec85a5773e8d6cfe9f3a440eed10ec3c6ee6137 Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 16:52:23 +0300 Subject: [PATCH 005/179] init commit --- dialing_app/__init__.py | 0 dialing_app/admin.py | 3 +++ dialing_app/apps.py | 5 +++++ dialing_app/models.py | 48 +++++++++++++++++++++++++++++++++++++++++ dialing_app/tests.py | 3 +++ dialing_app/urls.py | 7 ++++++ dialing_app/views.py | 15 +++++++++++++ 7 files changed, 81 insertions(+) create mode 100644 dialing_app/__init__.py create mode 100644 dialing_app/admin.py create mode 100644 dialing_app/apps.py create mode 100644 dialing_app/models.py create mode 100644 dialing_app/tests.py create mode 100644 dialing_app/urls.py create mode 100644 dialing_app/views.py diff --git a/dialing_app/__init__.py b/dialing_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dialing_app/admin.py b/dialing_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/dialing_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/dialing_app/apps.py b/dialing_app/apps.py new file mode 100644 index 0000000..42a981b --- /dev/null +++ b/dialing_app/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DialingAppConfig(AppConfig): + name = 'dialing_app' diff --git a/dialing_app/models.py b/dialing_app/models.py new file mode 100644 index 0000000..29ab683 --- /dev/null +++ b/dialing_app/models.py @@ -0,0 +1,48 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class AsteriskCDR(models.Model): + DISPOSITION_CHOICES = ( + ('NO ANSWER', _('No answer')), + ('FAILED', _('Failed')), + ('BUSY', _('Busy')), + ('ANSWERED', _('Answered')), + ('UNKNOWN', _('Unknown')) + ) + calldate = models.DateTimeField(default='0000-00-00 00:00:00', primary_key=True) + clid = models.CharField(max_length=80, default='') + src = models.CharField(max_length=80, default='') + dst = models.CharField(max_length=80, default='') + dcontext = models.CharField(max_length=80, default='') + channel = models.CharField(max_length=80, default='') + dstchannel = models.CharField(max_length=80, default='') + lastapp = models.CharField(max_length=80, default='') + lastdata = models.CharField(max_length=80, default='') + duration = models.IntegerField(default=0) + billsec = models.IntegerField(default=0) + start = models.DateTimeField(null=True, blank=True, default=None) + answer = models.DateTimeField(null=True, blank=True, default=None) + end = models.DateTimeField(null=True, blank=True, default=None) + disposition = models.CharField(max_length=45, choices=DISPOSITION_CHOICES, default='') + amaflags = models.IntegerField(default=0) + accountcode = models.CharField(max_length=20, default='') + userfield = models.CharField(max_length=255, default='') + uniqueid = models.CharField(max_length=32, default='') + + def save(self, *args, **kwargs): + return + + def delete(self, *args, **kwargs): + return + + class Meta: + abstract = True + + +def getModel(): + class DynamicCDR(AsteriskCDR): + class Meta: + abstract = False + db_table = 'cdr' + return DynamicCDR diff --git a/dialing_app/tests.py b/dialing_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dialing_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dialing_app/urls.py b/dialing_app/urls.py new file mode 100644 index 0000000..c114c32 --- /dev/null +++ b/dialing_app/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import url +from . import views + + +urlpatterns = [ + url(r'^$', views.home, name='home'), +] diff --git a/dialing_app/views.py b/dialing_app/views.py new file mode 100644 index 0000000..0a1292e --- /dev/null +++ b/dialing_app/views.py @@ -0,0 +1,15 @@ +from django.contrib.auth.decorators import login_required +from django.shortcuts import render + +from mydefs import only_admins +from .models import getModel + + +@login_required +@only_admins +def home(request): + AsteriskCDR = getModel() + logs = AsteriskCDR.objects.filter() + return render(request, 'index.html', { + 'logs': logs + }) From ae522c586eb78859952a9fd124c3368856ac416b Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 16:52:45 +0300 Subject: [PATCH 006/179] init commit --- dialing_app/locale/ru/LC_MESSAGES/django.po | 112 ++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 dialing_app/locale/ru/LC_MESSAGES/django.po diff --git a/dialing_app/locale/ru/LC_MESSAGES/django.po b/dialing_app/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000..a5c9f8c --- /dev/null +++ b/dialing_app/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,112 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Dmitry Novikov nerosketch@gmail.com, 2017. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-05-22 11:59+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" +"%100>=11 && n%100<=14)? 2 : 3);\n" + +#: dialing_app/models.py:8 +msgid "No answer" +msgstr "Не отвечен" + +#: dialing_app/models.py:9 +msgid "Failed" +msgstr "С ошибкой" + +#: dialing_app/models.py:10 +msgid "Busy" +msgstr "Занято" + +#: dialing_app/models.py:11 +msgid "Answered" +msgstr "Отвечен" + +#: dialing_app/models.py:12 +msgid "Unknown" +msgstr "Не определён" + +#: dialing_app/templates/index.html:8 +msgid "Dialing" +msgstr "Звонки" + +#: dialing_app/templates/index.html:11 +msgid "Last calls" +msgstr "Последние звонки" + +#: dialing_app/templates/index.html:19 +msgid "calldate" +msgstr "дата звонка" + +#: dialing_app/templates/index.html:20 +msgid "src" +msgstr "кто" + +#: dialing_app/templates/index.html:21 +msgid "dst" +msgstr "куда" + +#: dialing_app/templates/index.html:22 +msgid "dcontext" +msgstr "контекст" + +#: dialing_app/templates/index.html:23 +msgid "channel" +msgstr "канал" + +#: dialing_app/templates/index.html:24 +msgid "dstchannel" +msgstr "канал назначения" + +#: dialing_app/templates/index.html:25 +msgid "lastdata" +msgstr "lastdata" + +#: dialing_app/templates/index.html:26 +msgid "duration" +msgstr "продолжительность" + +#: dialing_app/templates/index.html:27 +msgid "billsec" +msgstr "вся продолж." + +#: dialing_app/templates/index.html:28 +msgid "start" +msgstr "начало" + +#: dialing_app/templates/index.html:29 +msgid "answer" +msgstr "ответ" + +#: dialing_app/templates/index.html:30 +msgid "end" +msgstr "конец" + +#: dialing_app/templates/index.html:31 +msgid "disposition" +msgstr "состояние" + +#: dialing_app/templates/index.html:32 +msgid "amaflags" +msgstr "amaflags" + +#: dialing_app/templates/index.html:33 +msgid "uniqueid" +msgstr "uniqueid" + +#: dialing_app/templates/index.html:57 +msgid "Calls was not found" +msgstr "Звонки не найдены" From 98c4bc4516e20d49bc5e3efae87482feb3d3e12d Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 16:52:57 +0300 Subject: [PATCH 007/179] init commit --- dialing_app/migrations/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dialing_app/migrations/__init__.py diff --git a/dialing_app/migrations/__init__.py b/dialing_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 From fc15ff02447fe74fe49c47a67bff48fd990aa82b Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 16:53:04 +0300 Subject: [PATCH 008/179] init commit --- dialing_app/templates/index.html | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dialing_app/templates/index.html diff --git a/dialing_app/templates/index.html b/dialing_app/templates/index.html new file mode 100644 index 0000000..1c4b0cc --- /dev/null +++ b/dialing_app/templates/index.html @@ -0,0 +1,66 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block main %} + + + + +

{% trans 'Last calls' %}

+ + {% include 'message_block.html' %} + +
+ + + + + + + + + + + + + + + + + + + + + + {% for log in logs %} + + + + + + + + + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans 'calldate' %}{% trans 'src' %}{% trans 'dst' %}{% trans 'dcontext' %}{% trans 'channel' %}{% trans 'dstchannel' %}{% trans 'lastdata' %}{% trans 'duration' %}{% trans 'billsec' %}{% trans 'start' %}{% trans 'answer' %}{% trans 'end' %}{% trans 'disposition' %}{% trans 'amaflags' %}{% trans 'uniqueid' %}
{{ log.calldate|date:'d E Y, H:i:s' }}{{ log.src }}{{ log.dst }}{{ log.dcontext }}{{ log.channel }}{{ log.dstchannel }}{{ log.lastdata }}{{ log.duration }}{{ log.billsec }}{{ log.start|date:'d E Y, H:i:s' }}{{ log.answer|date:'d E Y, H:i:s' }}{{ log.end|date:'d E Y, H:i:s' }}{{ log.disposition }}{{ log.amaflags }}{{ log.uniqueid }}
{% trans 'Calls was not found' %}
+
+ + {% include 'toolbar_page.html' with pag=logs %} + +{% endblock %} From 12d0b7362be0fe719afec86e271303b162a1cb4d Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 22 May 2017 16:53:53 +0300 Subject: [PATCH 009/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- djing/settings_example.py | 3 ++- djing/urls.py | 1 + templates/base.html | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/djing/settings_example.py b/djing/settings_example.py index 4e8660d..a7099d8 100644 --- a/djing/settings_example.py +++ b/djing/settings_example.py @@ -37,7 +37,8 @@ INSTALLED_APPS = [ 'taskapp', 'clientsideapp', 'chatbot', - 'django_messages' + 'django_messages', + 'dialing_app' ] MIDDLEWARE_CLASSES = [ diff --git a/djing/urls.py b/djing/urls.py index 43bf88b..fcbbffc 100644 --- a/djing/urls.py +++ b/djing/urls.py @@ -17,6 +17,7 @@ urlpatterns = [ url(r'^tasks/', include('taskapp.urls', namespace='taskapp')), url(r'^client/', include('clientsideapp.urls', namespace='client_side')), url(r'^msg/', include('django_messages.urls', namespace='django_messages')), + url(r'dialing/', include('dialing_app.urls', namespace='dialapp')), url(r'^admin/', admin.site.urls) ] diff --git a/templates/base.html b/templates/base.html index 32a0b80..0d78128 100644 --- a/templates/base.html +++ b/templates/base.html @@ -63,6 +63,12 @@ внутренняя переписка --> + {% url 'dialapp:home' as dialhome %} + + + Телефония + + {% url 'devapp:group_list' as devapp_groups %} From caf25f0d210fd0a41bedb2efda06eda1f6c6a970 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 22 May 2017 00:33:24 +0300 Subject: [PATCH 010/179] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D1=91=D1=81=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=87=D1=91=D1=82=20=D1=81=D0=B3=D0=BB=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=B0=20=D0=B2=20=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=B4=D0=B6=D0=B5=D1=80=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 15 ++------------- statistics/models.py | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/abonapp/views.py b/abonapp/views.py index 7759ae7..db57887 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -19,6 +19,7 @@ from . import models import mydefs from devapp.models import Device from datetime import datetime +from taskapp.models import Task @login_required @@ -610,7 +611,6 @@ def update_nas(request, group_id): @login_required @mydefs.only_admins def task_log(request, gid, uid): - from taskapp.models import Task abon = get_object_or_404(models.Abon, pk=uid) tasks = Task.objects.filter(abon=abon) return render(request, 'abonapp/task_log.html', { @@ -715,11 +715,8 @@ def clear_dev(request, gid, uid): @mydefs.only_admins def charts(request, gid, uid): from statistics.models import getModel - from datetime import datetime, date, time, timedelta high = 100 - def byte_to_mbit(x): - return ((x/60)*8)/2**20 try: StatElem = getModel() abon = models.Abon.objects.get(pk=uid) @@ -731,15 +728,7 @@ def charts(request, gid, uid): if abon.ip_address is None: charts_data = None else: - charts_data = StatElem.objects.filter(ip=abon.ip_address) - #oct_limit = StatElem.percentile([cd.octets for cd in charts_data], 0.05) - # ниже возвращаем пары значений трафика который переведён в mByte, и unix timestamp - midnight = datetime.combine(date.today(), time.min) - charts_data = [(cd.cur_time.timestamp()*1000, byte_to_mbit(cd.octets)) for cd in charts_data] - if len(charts_data) > 0: - charts_data.append( (charts_data[-1:][0][0], 0.0) ) - charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data] - charts_data.append("{x:new Date(%d),y:0}" % (int((midnight + timedelta(days=1)).timestamp()) * 1000)) + charts_data = StatElem.objects.chart(abon.ip_address) abontariff = abon.active_tariff() high = abontariff.speedIn + abontariff.speedOut diff --git a/statistics/models.py b/statistics/models.py index 9ab0f18..50ec5df 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -1,5 +1,5 @@ import math -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date, time from django.db import models, ProgrammingError from django.utils import timezone from mydefs import MyGenericIPAddressField @@ -22,6 +22,35 @@ class StatManager(models.Manager): except ProgrammingError as e: raise LogicError(e) + def chart(self, ip_addr, count_of_parts=12): + def byte_to_mbit(x): + return ((x/60)*8)/2**20 + + def split_list(lst, chunk_count): + chunk_size = len(lst) // chunk_count + return [lst[i:i+chunk_size] for i in range(0, len(lst), chunk_size)] + + def avarage(elements): + return sum(elements) / len(elements) + + charts_data = self.filter(ip=ip_addr) + charts_times = [cd.cur_time.timestamp()*1000 for cd in charts_data] + charts_octets = [byte_to_mbit(cd.octets) for cd in charts_data] + if len(charts_octets) > 0 and len(charts_octets) == len(charts_times): + charts_octets = split_list(charts_octets, count_of_parts) + charts_octets = [avarage(c) for c in charts_octets] + + charts_times = split_list(charts_times, count_of_parts) + charts_times = [avarage(t) for t in charts_times] + + charts_data = map(lambda x, y: (x, y), charts_times, charts_octets) + charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data] + midnight = datetime.combine(date.today(), time.min) + charts_data.append("{x:new Date(%d),y:0}" % (int((midnight + timedelta(days=1)).timestamp()) * 1000)) + return charts_data + else: + return + class StatElem(models.Model): cur_time = UnixDateTimeField(primary_key=True) @@ -67,6 +96,6 @@ def getModel(): class DynamicStatElem(StatElem): class Meta: - db_table = 'flowstat_%s' % timezone.now().strftime("%d%m%Y") + db_table = 'flowstat_%s' % datetime.now().strftime("%d%m%Y") abstract = False return DynamicStatElem From e2b6727fd5bc21e1b8ffcf6c4a63a74e14d76f25 Mon Sep 17 00:00:00 2001 From: http Date: Tue, 23 May 2017 00:51:46 +0300 Subject: [PATCH 011/179] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B9print?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/abonapp/views.py b/abonapp/views.py index db57887..a304d06 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -788,7 +788,6 @@ def make_extra_field(request, gid, uid): @permission_required('abonapp.change_extra_fields_model') def extra_field_change(request, gid, uid): extras = [(int(x), y) for x, y in zip(request.POST.getlist('ed'), request.POST.getlist('ex'))] - print(extras) try: for ex in extras: extra_field = models.ExtraFieldsModel.objects.get(pk=ex[0]) From 0a598679b31a99a7e7d5042ead910458295216b1 Mon Sep 17 00:00:00 2001 From: http Date: Tue, 23 May 2017 01:11:38 +0300 Subject: [PATCH 012/179] FIXBUG --- abonapp/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/abonapp/views.py b/abonapp/views.py index a304d06..ca493d4 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -731,9 +731,10 @@ def charts(request, gid, uid): charts_data = StatElem.objects.chart(abon.ip_address) abontariff = abon.active_tariff() - high = abontariff.speedIn + abontariff.speedOut - if high > 100: - high = 100 + if abontariff is not None: + high = abontariff.speedIn + abontariff.speedOut + if high > 100: + high = 100 except models.Abon.DoesNotExist: messages.error(request, _('Abon does not exist')) From b1513bec0e4e037b7ff7cc20b5f56552f76b7930 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 13:47:01 +0300 Subject: [PATCH 013/179] init commit --- dialing_app/templatetags/__init__.py | 0 dialing_app/templatetags/telephone_filters.py | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 dialing_app/templatetags/__init__.py create mode 100644 dialing_app/templatetags/telephone_filters.py diff --git a/dialing_app/templatetags/__init__.py b/dialing_app/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dialing_app/templatetags/telephone_filters.py b/dialing_app/templatetags/telephone_filters.py new file mode 100644 index 0000000..4cf7e48 --- /dev/null +++ b/dialing_app/templatetags/telephone_filters.py @@ -0,0 +1,22 @@ +import re +from django import template +from django.shortcuts import resolve_url +from django.template.defaultfilters import stringfilter + +register = template.Library() + + +@register.filter +@stringfilter +def abon_if_telephone(value): + print(value, type(value)) + """Возвращаем ссыль на абонента если передали номер телефона""" + if re.match(r'^\+?\d+$', value): + if value[0] != '+': + value = '+'+value + url = resolve_url('dialapp:to_abon', tel=value) + a = '%s' % (url, value) + print(a) + return a + else: + return value From 644ed6fa46adbd3e501bc378ff67bb15e05edc81 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 13:47:30 +0300 Subject: [PATCH 014/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D1=82=D1=80=D0=BE=D1=87=D0=BA=D1=83,=20=D1=83?= =?UTF-8?q?=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2=D0=B0=D1=8E=D1=89=D1=83=D1=8E=20?= =?UTF-8?q?=D0=BF=D1=83=D1=82=D1=8C=20=D0=BA=20=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8F=D0=BC=20=D0=B0=D1=81=D1=82=D0=B5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- djing/settings_example.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/djing/settings_example.py b/djing/settings_example.py index a7099d8..a9a7dfe 100644 --- a/djing/settings_example.py +++ b/djing/settings_example.py @@ -124,7 +124,7 @@ USE_I18N = True USE_L10N = False -USE_TZ = True +USE_TZ = False DEFAULT_FROM_EMAIL = 'nerosketch@gmail.com' @@ -160,3 +160,5 @@ PAGINATION_ITEMS_PER_PAGE=10 pay_SERV_ID = '' pay_SECRET = '' + +DIALING_MEDIA = 'path/to/asterisk_records' From c68eebba41e78b62570318b50c03e48943e83b4c Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 13:49:13 +0300 Subject: [PATCH 015/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=BE=D1=81=D0=BB=D1=83=D1=88=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA=D0=BE=D0=B2,=20=D0=B8?= =?UTF-8?q?=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D1=83=20=D0=BD=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=20=D1=81=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20=D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/locale/ru/LC_MESSAGES/django.po | 37 +++++---------------- dialing_app/models.py | 19 +++++++++++ dialing_app/urls.py | 1 + dialing_app/views.py | 19 ++++++++++- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/dialing_app/locale/ru/LC_MESSAGES/django.po b/dialing_app/locale/ru/LC_MESSAGES/django.po index a5c9f8c..482b2b0 100644 --- a/dialing_app/locale/ru/LC_MESSAGES/django.po +++ b/dialing_app/locale/ru/LC_MESSAGES/django.po @@ -59,30 +59,10 @@ msgstr "кто" msgid "dst" msgstr "куда" -#: dialing_app/templates/index.html:22 -msgid "dcontext" -msgstr "контекст" - -#: dialing_app/templates/index.html:23 -msgid "channel" -msgstr "канал" - -#: dialing_app/templates/index.html:24 -msgid "dstchannel" -msgstr "канал назначения" - -#: dialing_app/templates/index.html:25 -msgid "lastdata" -msgstr "lastdata" - #: dialing_app/templates/index.html:26 msgid "duration" msgstr "продолжительность" -#: dialing_app/templates/index.html:27 -msgid "billsec" -msgstr "вся продолж." - #: dialing_app/templates/index.html:28 msgid "start" msgstr "начало" @@ -99,14 +79,15 @@ msgstr "конец" msgid "disposition" msgstr "состояние" -#: dialing_app/templates/index.html:32 -msgid "amaflags" -msgstr "amaflags" - -#: dialing_app/templates/index.html:33 -msgid "uniqueid" -msgstr "uniqueid" - #: dialing_app/templates/index.html:57 msgid "Calls was not found" msgstr "Звонки не найдены" + +msgid "Play" +msgstr "Слушать" + +msgid "User with the telephone number not found" +msgstr "Абонент с таким номером телефона не найден" + +msgid "Multiple users with the telephone number" +msgstr "Несколько абонентов с указанным номером телефона" diff --git a/dialing_app/models.py b/dialing_app/models.py index 29ab683..c1ab834 100644 --- a/dialing_app/models.py +++ b/dialing_app/models.py @@ -1,5 +1,6 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +from djing import settings class AsteriskCDR(models.Model): @@ -36,6 +37,24 @@ class AsteriskCDR(models.Model): def delete(self, *args, **kwargs): return + def locate_disposition(self): + dsp = self.disposition + if dsp == 'NO ANSWER': + return _('No answer') + elif dsp == 'FAILED': + return _('Failed') + elif dsp == 'BUSY': + return _('Busy') + elif dsp == 'ANSWERED': + return _('Answered') + elif dsp == 'UNKNOWN': + return _('Unknown') + return '' + + @staticmethod + def path_to_media(): + return getattr(settings, 'DIALING_MEDIA', '/media') + class Meta: abstract = True diff --git a/dialing_app/urls.py b/dialing_app/urls.py index c114c32..20b529f 100644 --- a/dialing_app/urls.py +++ b/dialing_app/urls.py @@ -4,4 +4,5 @@ from . import views urlpatterns = [ url(r'^$', views.home, name='home'), + url(r'^to_abon(?P\+?\d+)$', views.to_abon, name='to_abon') ] diff --git a/dialing_app/views.py b/dialing_app/views.py index 0a1292e..9013817 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -1,6 +1,9 @@ from django.contrib.auth.decorators import login_required -from django.shortcuts import render +from django.contrib import messages +from django.shortcuts import render, redirect +from django.utils.translation import ugettext_lazy as _ +from abonapp.models import Abon from mydefs import only_admins from .models import getModel @@ -13,3 +16,17 @@ def home(request): return render(request, 'index.html', { 'logs': logs }) + + +@login_required +@only_admins +def to_abon(request, tel): + abon = Abon.objects.filter(telephone=tel) + abon_count = abon.count() + if abon_count > 1: + messages.warning(request, _('Multiple users with the telephone number')) + abon = abon[0] + elif abon_count == 0: + messages.error(request, _('User with the telephone number not found')) + return redirect('dialapp:home') + return redirect('abonapp:abon_home', gid=abon.group_id, uid=abon.pk) From 46e50c41172f31172d5be327e1e8dc63b76a707d Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 13:49:36 +0300 Subject: [PATCH 016/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=BE=D1=81=D0=BB=D1=83=D1=88=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA=D0=BE=D0=B2,=20=D0=B8?= =?UTF-8?q?=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D1=83=20=D0=BD=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=20=D1=81=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20=D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/templates/index.html | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/dialing_app/templates/index.html b/dialing_app/templates/index.html index 1c4b0cc..776cab3 100644 --- a/dialing_app/templates/index.html +++ b/dialing_app/templates/index.html @@ -1,5 +1,6 @@ {% extends 'base.html' %} {% load i18n %} +{% load telephone_filters %} {% block main %} @@ -16,45 +17,37 @@ + - - - - - - - {% for log in logs %} + - - - - - - + + - - - - + {% empty %} - + {% endfor %} From be75bdcf0a51aa7dcabc5afe458ca1264854564f Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 13:49:57 +0300 Subject: [PATCH 017/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=BE=D1=81=D0=BB=D1=83=D1=88=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA=D0=BE=D0=B2,=20=D0=B8?= =?UTF-8?q?=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D1=83=20=D0=BD=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=20=D1=81=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20=D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/css/custom.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/static/css/custom.css b/static/css/custom.css index 68b70e7..bb88cc3 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -239,3 +239,9 @@ button[data-toggle=offcanvas]{ .ct-series-a .ct-area { fill: black; } + + +/* + * Сужаем аудио элемент чтоб скрыть большинство контролов + */ +audio{width: 100px;} From 1d8bd15c955d35529d18d1b54acdf3621973b056 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 14:56:21 +0300 Subject: [PATCH 018/179] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/locale/ru/LC_MESSAGES/django.po | 3 +++ statistics/models.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 0d37ee5..ea0fd05 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -854,3 +854,6 @@ msgstr "Ошибка в SNMP на устройстве" msgid "Charts" msgstr "Графики" + +msgid "Sub information" +msgstr "Информация абонента" diff --git a/statistics/models.py b/statistics/models.py index 50ec5df..468aba9 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -35,10 +35,10 @@ class StatManager(models.Manager): charts_data = self.filter(ip=ip_addr) charts_times = [cd.cur_time.timestamp()*1000 for cd in charts_data] - charts_octets = [byte_to_mbit(cd.octets) for cd in charts_data] + charts_octets = [cd.octets for cd in charts_data] if len(charts_octets) > 0 and len(charts_octets) == len(charts_times): charts_octets = split_list(charts_octets, count_of_parts) - charts_octets = [avarage(c) for c in charts_octets] + charts_octets = [byte_to_mbit(avarage(c)) for c in charts_octets] charts_times = split_list(charts_times, count_of_parts) charts_times = [avarage(t) for t in charts_times] @@ -46,6 +46,7 @@ class StatManager(models.Manager): charts_data = map(lambda x, y: (x, y), charts_times, charts_octets) charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data] midnight = datetime.combine(date.today(), time.min) + charts_data.append("{x:new Date(%d),y:0}" % (int(charts_times[-1:][0]) + 1)) charts_data.append("{x:new Date(%d),y:0}" % (int((midnight + timedelta(days=1)).timestamp()) * 1000)) return charts_data else: From a76d2c6755ca0b64bb5a76225133ac7e3aa71000 Mon Sep 17 00:00:00 2001 From: http Date: Tue, 23 May 2017 15:45:58 +0300 Subject: [PATCH 019/179] FIXBUG --- dialing_app/views.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dialing_app/views.py b/dialing_app/views.py index 9013817..f40c488 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -25,8 +25,12 @@ def to_abon(request, tel): abon_count = abon.count() if abon_count > 1: messages.warning(request, _('Multiple users with the telephone number')) - abon = abon[0] elif abon_count == 0: messages.error(request, _('User with the telephone number not found')) return redirect('dialapp:home') - return redirect('abonapp:abon_home', gid=abon.group_id, uid=abon.pk) + abon = abon[0] + if abon.group: + return redirect('abonapp:abon_home', gid=abon.group.pk, uid=abon.pk) + else: + return redirect('abonapp:group_list') + From dab02a5fa7982b37d70efa5ba5792a84fd1f7d44 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 16:01:13 +0300 Subject: [PATCH 020/179] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BF=D0=BE=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BD=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/models.py | 10 +--------- dialing_app/views.py | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/dialing_app/models.py b/dialing_app/models.py index c1ab834..fd74209 100644 --- a/dialing_app/models.py +++ b/dialing_app/models.py @@ -56,12 +56,4 @@ class AsteriskCDR(models.Model): return getattr(settings, 'DIALING_MEDIA', '/media') class Meta: - abstract = True - - -def getModel(): - class DynamicCDR(AsteriskCDR): - class Meta: - abstract = False - db_table = 'cdr' - return DynamicCDR + db_table = 'cdr' diff --git a/dialing_app/views.py b/dialing_app/views.py index 9013817..d665e4f 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -5,13 +5,12 @@ from django.utils.translation import ugettext_lazy as _ from abonapp.models import Abon from mydefs import only_admins -from .models import getModel +from .models import AsteriskCDR @login_required @only_admins def home(request): - AsteriskCDR = getModel() logs = AsteriskCDR.objects.filter() return render(request, 'index.html', { 'logs': logs From 1e147b394579b9c724a1a9f78a2e537958f563a3 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 16:20:31 +0300 Subject: [PATCH 021/179] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BF=D0=BE=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BD=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/peoples.html | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 5f79838..ddaf443 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -134,12 +134,15 @@ From 3465a404ae9ed28c70086d814bcbb8e7cbe90da9 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 17:27:35 +0300 Subject: [PATCH 022/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=20=D0=B4=D0=B0=D1=82?= =?UTF-8?q?=D1=8B=20=D0=BF=D1=80=D0=BE=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B0?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/locale/ru/LC_MESSAGES/django.po | 12 ++++++++++++ abonapp/templates/abonapp/charts.html | 19 +++++++++++++++---- abonapp/views.py | 19 +++++++++++++++---- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index ea0fd05..12832bc 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -857,3 +857,15 @@ msgstr "Графики" msgid "Sub information" msgstr "Информация абонента" + +msgid "Streets" +msgstr "Улицы" + +msgid "Static info was Not found" +msgstr "Статистика не найдена" + +msgid "Graphs by dates" +msgstr "Графики по датам" + +msgid "Graph of use" +msgstr "График использования" diff --git a/abonapp/templates/abonapp/charts.html b/abonapp/templates/abonapp/charts.html index a740699..99dcd37 100644 --- a/abonapp/templates/abonapp/charts.html +++ b/abonapp/templates/abonapp/charts.html @@ -3,10 +3,10 @@ {% block content %}
-
+
-

График использования

+

{% trans 'Graph of use' %}

{% if charts_data %} @@ -16,7 +16,6 @@ new Chartist.Line('#chrt', { series: [ { - name: 'График траффика', data: [ {{ charts_data }} ] @@ -39,11 +38,23 @@ }); {% else %} -

Траффик не найден

+

{% trans 'Static info was Not found' %}

{% endif %}
+
+
+
{% trans 'Graphs by dates' %}
+
+ {% for dat in dates %} + {{ dat|date:'j E' }} + {% empty %} + {% trans 'Static info was Not found' %} + {% endfor %} +
+
+
{% endblock %} diff --git a/abonapp/views.py b/abonapp/views.py index ca493d4..43c3605 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -18,7 +18,7 @@ from . import forms from . import models import mydefs from devapp.models import Device -from datetime import datetime +from datetime import datetime, date from taskapp.models import Task @@ -717,8 +717,14 @@ def charts(request, gid, uid): from statistics.models import getModel high = 100 + wandate = request.GET.get('wantdate') + if wandate: + wandate = datetime.strptime(wandate, '%d%m%Y').date() + else: + wandate = date.today() + try: - StatElem = getModel() + StatElem = getModel(wandate) abon = models.Abon.objects.get(pk=uid) if abon.group is None: abon.group = models.AbonGroup.objects.get(pk=gid) @@ -728,7 +734,11 @@ def charts(request, gid, uid): if abon.ip_address is None: charts_data = None else: - charts_data = StatElem.objects.chart(abon.ip_address) + charts_data = StatElem.objects.chart( + abon.ip_address, + count_of_parts=24, + want_date=wandate + ) abontariff = abon.active_tariff() if abontariff is not None: @@ -750,7 +760,8 @@ def charts(request, gid, uid): 'abon_group': abongroup, 'abon': abon, 'charts_data': ',\n'.join(charts_data) if charts_data is not None else None, - 'high': high + 'high': high, + 'dates': StatElem.objects.get_dates() }) From 400f000d95d568120823a76004abf0ce23d7ca85 Mon Sep 17 00:00:00 2001 From: bashmak Date: Tue, 23 May 2017 17:28:55 +0300 Subject: [PATCH 023/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=82=D0=B0=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D1=86=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D1=86=D0=B0=D0=BC=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/models.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/statistics/models.py b/statistics/models.py index 468aba9..6a34c7f 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -1,7 +1,6 @@ import math from datetime import datetime, timedelta, date, time -from django.db import models, ProgrammingError -from django.utils import timezone +from django.db import models, ProgrammingError, connection from mydefs import MyGenericIPAddressField from .fields import UnixDateTimeField from mydefs import LogicError @@ -22,7 +21,7 @@ class StatManager(models.Manager): except ProgrammingError as e: raise LogicError(e) - def chart(self, ip_addr, count_of_parts=12): + def chart(self, ip_addr, count_of_parts=12, want_date=date.today()): def byte_to_mbit(x): return ((x/60)*8)/2**20 @@ -45,13 +44,18 @@ class StatManager(models.Manager): charts_data = map(lambda x, y: (x, y), charts_times, charts_octets) charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data] - midnight = datetime.combine(date.today(), time.min) + midnight = datetime.combine(want_date, time.min) charts_data.append("{x:new Date(%d),y:0}" % (int(charts_times[-1:][0]) + 1)) charts_data.append("{x:new Date(%d),y:0}" % (int((midnight + timedelta(days=1)).timestamp()) * 1000)) return charts_data else: return + def get_dates(self): + tables = connection.introspection.table_names() + tables = [t.replace('flowstat_', '') for t in tables if t.startswith('flowstat_')] + return [datetime.strptime(t, '%d%m%Y').date() for t in tables] + class StatElem(models.Model): cur_time = UnixDateTimeField(primary_key=True) @@ -93,10 +97,10 @@ class StatElem(models.Model): abstract = True -def getModel(): +def getModel(want_date=datetime.now()): class DynamicStatElem(StatElem): class Meta: - db_table = 'flowstat_%s' % datetime.now().strftime("%d%m%Y") + db_table = 'flowstat_%s' % want_date.strftime("%d%m%Y") abstract = False return DynamicStatElem From 70e0031a1318158f0024a0e3fe2d44fdbabed957 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 24 May 2017 15:05:18 +0300 Subject: [PATCH 024/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81?= =?UTF-8?q?=D1=82=20python-rq,=20=D0=BD=D1=83=D0=B6=D0=BD=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BE=D1=87=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=B9?= =?UTF-8?q?=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20redis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index a57bd5f..952569a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ netaddr xmltodict mysqlclient easysnmp +rq From 62a956a80b871089af361860ca069fd15710747a Mon Sep 17 00:00:00 2001 From: http Date: Wed, 24 May 2017 15:29:36 +0300 Subject: [PATCH 025/179] =?UTF-8?q?FIXBUG:=20=D0=BF=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5?= =?UTF-8?q?=D0=BC=D1=83=20=D1=81=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D0=B7=D0=BE=D0=BD=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/models.py | 3 +-- tariff_app/custom_tariffs.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/abonapp/models.py b/abonapp/models.py index 0ac2a8e..3e0fb45 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from datetime import datetime from django.core.exceptions import ValidationError from django.utils import timezone from django.db import models @@ -292,7 +291,7 @@ class Abon(UserProfile): def activate_next_tariff(self, author): ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority') - nw = timezone.make_aware(datetime.now()) + nw = timezone.now() for at in ats: # услуга не активна, продолжаем diff --git a/tariff_app/custom_tariffs.py b/tariff_app/custom_tariffs.py index a9888d2..630ce4a 100644 --- a/tariff_app/custom_tariffs.py +++ b/tariff_app/custom_tariffs.py @@ -40,7 +40,7 @@ class TariffDefault(TariffBase): last_day = monthrange(nw.year, nw.month)[1] last_month_date = datetime(year=nw.year, month=nw.month, day=last_day, hour=23, minute=59, second=59) - return timezone.make_aware(last_month_date) + return last_month_date @staticmethod def description(): @@ -67,7 +67,7 @@ class TariffCp(TariffDp): nw = timezone.now() long_long_time = datetime(year=nw.year+10, month=nw.month, day=nw.day, hour=23, minute=59, second=59) - return timezone.make_aware(long_long_time) + return long_long_time @staticmethod def description(): From b518f25063247086c14f54667d5e120a79481122 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 24 May 2017 15:33:56 +0300 Subject: [PATCH 026/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?dhcp=20=D0=BE=D0=BF=D0=BE=D0=B2=D0=B5=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B1=D0=B8=D0=BB=D0=BB=D0=B8=D0=BD=D0=B3=D0=B0=20?= =?UTF-8?q?=D0=B1=D1=83=D0=B4=D0=B5=D1=82=20=D0=B2=D1=8B=D0=BF=D0=BB=D0=BD?= =?UTF-8?q?=D1=8F=D1=82=D1=81=D1=8F=20=D0=B2=20=D0=BE=D1=87=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B8=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/commands/dhcp.py | 44 +++++++++++++++++++++++++++ dhcp_lever.py | 68 +++++------------------------------------- queue_mngr.py | 24 +++++++++++++++ 3 files changed, 76 insertions(+), 60 deletions(-) create mode 100644 agent/commands/dhcp.py create mode 100644 queue_mngr.py diff --git a/agent/commands/dhcp.py b/agent/commands/dhcp.py new file mode 100644 index 0000000..2eaf084 --- /dev/null +++ b/agent/commands/dhcp.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +from django.core.exceptions import MultipleObjectsReturned +from django.utils.translation import ugettext as _ +from abonapp.models import Abon, Opt82 + + +def get_82_opts(switch_mac, switch_port): + try: + opt82 = Opt82.objects.get(mac=switch_mac, port=switch_port) + except MultipleObjectsReturned: + Opt82.objects.filter(mac=switch_mac, port=switch_port)[1:].delete() + return get_82_opts(switch_mac, switch_port) + except Opt82.DoesNotExist: + opt82 = Opt82.objects.create(mac=switch_mac, port=switch_port) + return opt82 + + +def dhcp_commit(client_ip, client_mac, switch_mac, switch_port): + opt82 = get_82_opts(switch_mac, switch_port) + if opt82 is None: + print(_("ERROR: opt82 with mac:%s and port:%d does not exist in db") % (switch_mac, switch_port)) + return + try: + abon = Abon.objects.get(opt82=opt82) + abon.ip_address = client_ip + abon.is_dhcp = True + abon.save(update_fields=['ip_address']) + print(_('Ip address update for %s successfull') % abon.get_short_name()) + except Abon.DoesNotExist: + print('ERROR: abon with option82(%s-%d) does not exist' % (opt82.mac, opt82.port)) + + +def dhcp_expiry(client_ip): + try: + abon = Abon.objects.get(ip_address=client_ip) + abon.ip_address = None + abon.is_dhcp = True + abon.save(update_fields=['ip_address']) + except Abon.DoesNotExist: + pass + + +def dhcp_release(client_ip): + dhcp_expiry(client_ip) diff --git a/dhcp_lever.py b/dhcp_lever.py index f499cc5..fe7aec9 100755 --- a/dhcp_lever.py +++ b/dhcp_lever.py @@ -1,13 +1,8 @@ #!/usr/bin/env python3 -import os import sys -import django -from django.core.exceptions import MultipleObjectsReturned, ValidationError +from redis import Redis +from rq import Queue from django.utils.translation import ugettext as _ -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") -django.setup() -from agent import NasFailedResult, NasNetworkError -from abonapp.models import Abon, Opt82 def die(text): @@ -15,64 +10,17 @@ def die(text): exit(1) -def get_82_opts(switch_mac, switch_port): - try: - opt82 = Opt82.objects.get(mac=switch_mac, port=switch_port) - except MultipleObjectsReturned: - Opt82.objects.filter(mac=switch_mac, port=switch_port)[1:].delete() - return get_82_opts(switch_mac, switch_port) - except Opt82.DoesNotExist: - opt82 = Opt82.objects.create(mac=switch_mac, port=switch_port) - return opt82 - - -def dhcp_commit(client_ip, client_mac, switch_mac, switch_port): - opt82 = get_82_opts(switch_mac, switch_port) - if opt82 is None: - print(_("ERROR: opt82 with mac:%s and port:%d does not exist in db") % (switch_mac, switch_port)) - return - try: - abon = Abon.objects.get(opt82=opt82) - abon.ip_address = client_ip - abon.is_dhcp = True - abon.save(update_fields=['ip_address']) - print(_('Ip address update for %s successfull') % abon.get_short_name()) - except Abon.DoesNotExist: - print('ERROR: abon with option82(%s-%d) does not exist' % (opt82.mac, opt82.port)) - - -def dhcp_expiry(client_ip): - try: - abon = Abon.objects.get(ip_address=client_ip) - abon.ip_address = None - abon.is_dhcp = True - abon.save(update_fields=['ip_address']) - except Abon.DoesNotExist: - pass - - -def dhcp_release(client_ip): - dhcp_expiry(client_ip) - - -def main(argv): +if __name__ == "__main__": + argv = sys.argv if len(argv) < 3: die(_('Too few arguments, exiting...')) action = argv[1] + q = Queue(connection=Redis()) if action == 'commit': if len(argv) < 6: die(_('Too few arguments, exiting...')) - dhcp_commit(argv[2], argv[3], argv[4], int(argv[5])) + q.enqueue('agent.commands.dhcp.dhcp_commit', argv[2], argv[3], argv[4], int(argv[5])) elif action == 'expiry': - dhcp_expiry(argv[2]) + q.enqueue('agent.commands.dhcp.dhcp_expiry', argv[2]) elif action == 'release': - dhcp_release(argv[2]) - - -if __name__ == "__main__": - try: - main(sys.argv) - except (NasNetworkError, NasFailedResult) as e: - print('NAS:', e) - except (ValidationError, ValueError) as e: - print('ERROR:', e) + q.enqueue('agent.commands.dhcp.dhcp_release', argv[2]) diff --git a/queue_mngr.py b/queue_mngr.py new file mode 100644 index 0000000..4faefa3 --- /dev/null +++ b/queue_mngr.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +import os +import sys +from rq import Connection, Worker +import django +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") +from agent import NasFailedResult, NasNetworkError +from django.core.exceptions import ValidationError + + +""" + Заустить этот скрипт как демон, он соединяет redis и django +""" +if __name__ == '__main__': + try: + django.setup() + with Connection(): + qs = sys.argv[1:] or ['default'] + w = Worker(qs) + w.work() + except (NasNetworkError, NasFailedResult) as e: + print('NAS:', e) + except (ValidationError, ValueError) as e: + print('ERROR:', e) From 195e9f03141e001c1de2546d40b4e8002ae848a8 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 25 May 2017 12:31:00 +0300 Subject: [PATCH 027/179] =?UTF-8?q?FIXBUG:=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=B5=20=D0=BE=D0=B4=D0=B8?= =?UTF-8?q?=D0=BD=D0=B0=D0=BA=D0=BE=D0=B2=D0=BE=D0=B5=20=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B2=D0=BA=D0=B8=20=D1=86=D0=B2=D0=B5=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/css/custom.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/css/custom.css b/static/css/custom.css index bb88cc3..78c1330 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -238,6 +238,8 @@ button[data-toggle=offcanvas]{ */ .ct-series-a .ct-area { fill: black; + opacity: 0.3; + fill-opacity: 0.3; } From 43b2eb6e7a4c30ddf9f8a64ff35075d77a7c14a6 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 25 May 2017 12:31:38 +0300 Subject: [PATCH 028/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=B0=D0=B3=D0=B8=D0=BD=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=B2=20=D0=BB=D0=BE=D0=B3=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dialing_app/views.py b/dialing_app/views.py index 8c69b94..2f5ff31 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -4,14 +4,15 @@ from django.shortcuts import render, redirect from django.utils.translation import ugettext_lazy as _ from abonapp.models import Abon -from mydefs import only_admins +from mydefs import only_admins, pag_mn from .models import AsteriskCDR @login_required @only_admins def home(request): - logs = AsteriskCDR.objects.filter() + logs = AsteriskCDR.objects.all() + logs = pag_mn(request, logs) return render(request, 'index.html', { 'logs': logs }) From 191bd18fa28471e0ee763718499a357a3e0d1c08 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 25 May 2017 12:32:18 +0300 Subject: [PATCH 029/179] =?UTF-8?q?=D0=9E=D1=82=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D0=B3=D0=BB=D0=B0=D0=B6=D0=B8=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/charts.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/abonapp/templates/abonapp/charts.html b/abonapp/templates/abonapp/charts.html index 99dcd37..a9481b0 100644 --- a/abonapp/templates/abonapp/charts.html +++ b/abonapp/templates/abonapp/charts.html @@ -33,7 +33,10 @@ labelInterpolationFnc: function (value) { return moment(value).format('HH:mm:ss'); } - } + }, + lineSmooth: Chartist.Interpolation.cardinal({ + tension: 0 + }) }); }); From d62b2839fe568a1173f04244d61b0b2eddb1ae59 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 25 May 2017 12:32:59 +0300 Subject: [PATCH 030/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BB=D0=BE=D0=B3=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B2=20=D0=BA=D0=B0=D0=B1=D0=B8=D0=BD=D0=B5?= =?UTF-8?q?=D1=82=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/locale/ru/LC_MESSAGES/django.po | 33 +++++++++++++++++ abonapp/templates/abonapp/dial_log.html | 47 +++++++++++++++++++++++++ abonapp/templates/abonapp/ext.htm | 5 +++ abonapp/urls_abon.py | 1 + abonapp/views.py | 27 ++++++++++++-- 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 abonapp/templates/abonapp/dial_log.html diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 12832bc..5be7d30 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -869,3 +869,36 @@ msgstr "Графики по датам" msgid "Graph of use" msgstr "График использования" + +msgid "Play" +msgstr "Слушать" + +msgid "calldate" +msgstr "дата звонка" + +msgid "src" +msgstr "кто" + +msgid "dst" +msgstr "куда" + +msgid "duration" +msgstr "продолжительность" + +msgid "start" +msgstr "начало" + +msgid "answer" +msgstr "ответ" + +msgid "end" +msgstr "конец" + +msgid "disposition" +msgstr "состояние" + +msgid "Calls was not found" +msgstr "Звонки не найдены" + +msgid "Dialing" +msgstr "Звонки" diff --git a/abonapp/templates/abonapp/dial_log.html b/abonapp/templates/abonapp/dial_log.html new file mode 100644 index 0000000..695ab3a --- /dev/null +++ b/abonapp/templates/abonapp/dial_log.html @@ -0,0 +1,47 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} +{% load i18n %} +{% block content %} + +
{% trans 'Play' %} {% trans 'calldate' %} {% trans 'src' %} {% trans 'dst' %}{% trans 'dcontext' %}{% trans 'channel' %}{% trans 'dstchannel' %}{% trans 'lastdata' %} {% trans 'duration' %}{% trans 'billsec' %} {% trans 'start' %} {% trans 'answer' %} {% trans 'end' %} {% trans 'disposition' %}{% trans 'amaflags' %}{% trans 'uniqueid' %}
+ + {{ log.calldate|date:'d E Y, H:i:s' }}{{ log.src }}{{ log.dst }}{{ log.dcontext }}{{ log.channel }}{{ log.dstchannel }}{{ log.lastdata }}{{ log.src|abon_if_telephone|safe }}{{ log.dst|abon_if_telephone|safe }} {{ log.duration }}{{ log.billsec }} {{ log.start|date:'d E Y, H:i:s' }} {{ log.answer|date:'d E Y, H:i:s' }} {{ log.end|date:'d E Y, H:i:s' }}{{ log.disposition }}{{ log.amaflags }}{{ log.uniqueid }}{{ log.locate_disposition }}
{% trans 'Calls was not found' %}{% trans 'Calls was not found' %}
+ + + + + + + + + + + + + + + {% for log in logs %} + + + + + + + + + + + + {% empty %} + + + + {% endfor %} + + +
{% trans 'Play' %}{% trans 'calldate' %}{% trans 'src' %}{% trans 'dst' %}{% trans 'duration' %}{% trans 'start' %}{% trans 'answer' %}{% trans 'end' %}{% trans 'disposition' %}
+ + {{ log.calldate|date:'d E Y, H:i:s' }}{{ log.src }}{{ log.dst }}{{ log.duration }}{{ log.start|date:'d E Y, H:i:s' }}{{ log.answer|date:'d E Y, H:i:s' }}{{ log.end|date:'d E Y, H:i:s' }}{{ log.locate_disposition }}
{% trans 'Calls was not found' %}
+ + {% include 'toolbar_page.html' with pag=logs %} + +{% endblock %} diff --git a/abonapp/templates/abonapp/ext.htm b/abonapp/templates/abonapp/ext.htm index 2aaff6f..4d0ca3f 100644 --- a/abonapp/templates/abonapp/ext.htm +++ b/abonapp/templates/abonapp/ext.htm @@ -53,6 +53,11 @@ {% trans 'Charts' %} + {% url 'abonapp:dials' abon_group.pk abon.pk as abdials %} + + {% trans 'Dialing' %} + +
diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index b93c5d3..1de99da 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -21,6 +21,7 @@ urlpatterns = [ url(r'^(?P\d+)/activate_service(?P\d+)$', views.activate_service, name='activate_service'), url(r'^(?P\d+)/opt82$', views.opt82, name='opt82'), url(r'^(?P\d+)/chart$', views.charts, name='charts'), + url(r'^(?P\d+)/dials$', views.dials, name='dials'), url(r'^(?P\d+)/extra_field$', views.make_extra_field, name='extra_field'), url(r'^(?P\d+)/extra_field/(?P\d+)/delete$', views.extra_field_delete, name='extra_field_delete'), url(r'^(?P\d+)/extra_field/edit$', views.extra_field_change, name='extra_field_edit'), diff --git a/abonapp/views.py b/abonapp/views.py index 43c3605..db135c9 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -3,7 +3,7 @@ from json import dumps from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.db import IntegrityError, ProgrammingError -from django.db.models import Count +from django.db.models import Count, Q from django.shortcuts import render, redirect, get_object_or_404, resolve_url from django.contrib.auth.decorators import login_required, permission_required from django.utils import timezone @@ -20,6 +20,7 @@ import mydefs from devapp.models import Device from datetime import datetime, date from taskapp.models import Task +from dialing_app.models import AsteriskCDR @login_required @@ -736,7 +737,7 @@ def charts(request, gid, uid): else: charts_data = StatElem.objects.chart( abon.ip_address, - count_of_parts=24, + count_of_parts=30, want_date=wandate ) @@ -860,6 +861,28 @@ def abon_ping(request): })) +@login_required +@mydefs.only_admins +def dials(request, gid, uid): + abon = get_object_or_404(models.Abon, pk=uid) + if hasattr(abon.group, 'pk') and abon.group.pk != int(gid): + print(gid, type(gid), abon.group.pk, type(abon.group.pk)) + return redirect('abonapp:dials', abon.group.pk, abon.pk) + if abon.telephone is not None and abon.telephone != '': + tel = abon.telephone.replace('+', '') + logs = AsteriskCDR.objects.filter( + Q(src__contains=tel) | Q(dst__contains=tel) + ) + logs = mydefs.pag_mn(request, logs) + else: + logs = None + return render(request, 'abonapp/dial_log.html', { + 'logs': logs, + 'abon_group': get_object_or_404(models.AbonGroup, pk=gid), + 'abon': abon + }) + + # API's def abons(request): From 795dd73b80c0e988b422f222d1e54d64655cd0d6 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 25 May 2017 14:40:00 +0300 Subject: [PATCH 031/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=20=D0=BB=D0=B8=D1=87=D0=BD=D1=8B=D0=B9=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=B1=D0=B8=D0=BD=D0=B5=D1=82=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BA=D1=83=20=D1=87=D1=82=D0=BE=D0=B1=20=D0=B7=D0=B2=D0=BE?= =?UTF-8?q?=D0=BD=D0=B8=D1=82=D1=8C=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/editAbon.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index 3a2cda1..a5c2698 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -28,7 +28,14 @@
- {{ form.telephone }}{{ form.telephone.errors }} +
+ {{ form.telephone }}{{ form.telephone.errors }} + + + + + +
From 51a0ebe654fb548c7953d30bfc235afabe6ce567 Mon Sep 17 00:00:00 2001 From: http Date: Thu, 25 May 2017 14:43:16 +0300 Subject: [PATCH 032/179] tel: to sip: --- abonapp/templates/abonapp/editAbon.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index a5c2698..8324b9b 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -31,7 +31,7 @@
{{ form.telephone }}{{ form.telephone.errors }} - + From 0db62b9e3ba59c531d14973db5b22f3b610963fe Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 25 May 2017 16:47:58 +0300 Subject: [PATCH 033/179] =?UTF-8?q?=D0=9D=D0=B0=D0=B4=D0=BE=20=D0=B1=D1=8B?= =?UTF-8?q?=D0=BB=D0=BE=20=D1=83=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20=D0=BE?= =?UTF-8?q?=D1=82=D1=81=D1=8E=D0=B4=D0=B0=20=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20=D1=87=D1=82=D0=BE=D0=B1?= =?UTF-8?q?=20=D0=BD=D0=B5=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20django?= =?UTF-8?q?=20=D1=82=D1=83=D1=82,=20=D0=B0=20=D1=82=D0=BE=20django=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BB=D0=B3=D0=BE=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D0=B7=D0=B8=D1=80=D1=83=D0=B5=D1=82=D1=81?= =?UTF-8?q?=D1=8F,=20=D0=B4=D0=B0=20=D0=B8=20=D0=B2=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B0=D1=85=20=D0=BB=D1=83=D1=87=D1=88=D0=B5=20=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D1=82=D1=8C=20=D0=BB=D0=B0=D1=82=D0=B8=D0=BD=D0=B8?= =?UTF-8?q?=D1=86=D0=B5=D0=B9=20=D0=BD=D0=B0=20=D0=B2=D1=81=D1=8F=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dhcp_lever.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dhcp_lever.py b/dhcp_lever.py index fe7aec9..f6ac08c 100755 --- a/dhcp_lever.py +++ b/dhcp_lever.py @@ -2,7 +2,6 @@ import sys from redis import Redis from rq import Queue -from django.utils.translation import ugettext as _ def die(text): @@ -13,12 +12,12 @@ def die(text): if __name__ == "__main__": argv = sys.argv if len(argv) < 3: - die(_('Too few arguments, exiting...')) + die('Too few arguments, exiting...') action = argv[1] q = Queue(connection=Redis()) if action == 'commit': if len(argv) < 6: - die(_('Too few arguments, exiting...')) + die('Too few arguments, exiting...') q.enqueue('agent.commands.dhcp.dhcp_commit', argv[2], argv[3], argv[4], int(argv[5])) elif action == 'expiry': q.enqueue('agent.commands.dhcp.dhcp_expiry', argv[2]) From fa90ab6324ba24ba916cbeb889c3d7e21cbb8069 Mon Sep 17 00:00:00 2001 From: http Date: Mon, 29 May 2017 11:38:40 +0300 Subject: [PATCH 034/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D0=B5=D0=BD=D1=8C=20=D0=BD=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/peoples.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index ddaf443..ad334f7 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -75,7 +75,7 @@ {% if human.traf %} - {{ human.traf.cur_time|date:"H:i" }} + {{ human.traf.cur_time|date:"D H:i" }} {% endif %} {{ human.ip_address|default:_('Not assigned') }} @@ -149,4 +149,4 @@ {% include 'toolbar_page.html' with pag=peoples %} -{% endblock %} \ No newline at end of file +{% endblock %} From ba05d169823993e1c4020a74a9e2d664d2806482 Mon Sep 17 00:00:00 2001 From: http Date: Mon, 29 May 2017 11:40:12 +0300 Subject: [PATCH 035/179] =?UTF-8?q?FIXBUG:=20=D0=A1=D0=B2=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B2=D0=B0=D0=BB=D1=81=D1=8F=20=D0=BF=D0=BE=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=20=D0=B5=D1=81=D0=BB=D0=B8=20=D0=B5=D1=81=D1=82=D1=8C=20?= =?UTF-8?q?=D1=81=D0=B8=D0=BC=D0=B2=D0=BE=D0=BB=20'+'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- searchapp/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/searchapp/views.py b/searchapp/views.py index 30bc4c7..e9155fe 100644 --- a/searchapp/views.py +++ b/searchapp/views.py @@ -12,6 +12,7 @@ def replace_without_case(orig, old, new): def home(request): s = request.GET.get('s') + s = s.replace('+', '') if s: if bool(re.match(ip_addr_regex, s)): From 580ea9378aed9ef23ed4804be21c74b167b2d527 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 13:18:04 +0300 Subject: [PATCH 036/179] =?UTF-8?q?FIXBUG:=20=D0=9D=D0=B5=20=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D0=BC=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BD?= =?UTF-8?q?=D1=8B=20=D1=81=20=D0=B2=D0=B5=D0=B4=D1=83=D1=89=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=BD=D1=83=D0=BB=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/abonapp/forms.py b/abonapp/forms.py index cf31d19..cc27e2d 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -12,6 +12,7 @@ from .formfields import MACAddressField def generate_random_username(length=6, chars=digits, split=2, delimiter=''): username = ''.join([choice(chars) for i in range(length)]) + username = str(int(username)) if split: username = delimiter.join([username[start:start+split] for start in range(0, len(username), split)]) From e2210a2974922d6901a223886427bc429f6ccb1f Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:33:06 +0300 Subject: [PATCH 037/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C=20=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B5=20=D0=BA=D0=B5=D1=88=D0=B0?= =?UTF-8?q?=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc.txt b/Doc.txt index c361607..0b24ce0 100644 --- a/Doc.txt +++ b/Doc.txt @@ -13,3 +13,6 @@ и ваш класс для своей логики расчёта тарифа ВАЖНО! Для отработки своевременного выключения услуги, время на сервере биллинга и NAS должно быть настроено точно. + +Таблицу кеша статистики лучше сделать в памяти т.к. будет часто обновляться +ALTER TABLE flowcache ENGINE=MEMORY; From 51fbaca2c084b54a53c423bc18cc522abbe1081a Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:34:19 +0300 Subject: [PATCH 038/179] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=D0=B5=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/forms.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/abonapp/forms.py b/abonapp/forms.py index cc27e2d..fc07833 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from django.http import QueryDict from datetime import datetime from django.utils.translation import ugettext as _ from django import forms @@ -98,9 +97,6 @@ class Opt82Form(forms.ModelForm): 'port': forms.NumberInput(attrs={'class': 'form-control', 'required': ''}) } - #def save(self, commit=True): - # super().save(commit=commit) - class AbonGroupForm(forms.ModelForm): class Meta: From f374d3ad0f22c59ef5f76440e98df3074de7df93 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:35:40 +0300 Subject: [PATCH 039/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B9=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0=20=D1=81=D1=82=D0=B0=D1=82=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D0=BA=D0=B8=20=D1=82=D1=80=D0=B0=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0,=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=B5?= =?UTF-8?q?=D1=81=D0=BB=D0=B8=20=D1=81=D1=80=D0=B0=D1=84=D0=B8=D0=BA=20?= =?UTF-8?q?=D0=B1=D1=8B=D0=BB=20=D1=81=D0=B5=D0=B3=D0=BE=D0=B4=D0=BD=D1=8F?= =?UTF-8?q?=20=D1=82=D0=BE=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B8=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D1=82=D0=BE=D1=80=D0=BB=D1=8C=D0=BA=D0=BE=20?= =?UTF-8?q?=D1=87=D0=B0=D1=81=D1=8B=20=D0=B8=20=D0=BC=D0=B8=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D1=8B=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D1=84=D0=B8=D0=BA=D0=B0,=20=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D1=87=D0=B5=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B8=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D0=B5=D1=89=D1=91=20=D0=B8=20=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D1=8C=20=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/peoples.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index ddaf443..16e9538 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -69,13 +69,17 @@ {% endif %} {{ human.username }} - {% if human.is_online %} + {% if human.stat_cache and human.stat_cache.is_online %} {% endif %} - {% if human.traf %} - {{ human.traf.cur_time|date:"H:i" }} + {% if human.stat_cache %} + {% if human.stat_cache.is_today %} + {{ human.stat_cache.last_time|date:"H:i" }} + {% else %} + {{ human.stat_cache.last_time|date:"D H:i" }} + {% endif %} {% endif %} {{ human.ip_address|default:_('Not assigned') }} From dab98a8b5400ab8522b7ffdb5757d85f92df8654 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:36:51 +0300 Subject: [PATCH 040/179] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20view=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=B0=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B8=20=D1=82=D1=80=D0=B0=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/abonapp/views.py b/abonapp/views.py index db135c9..1152242 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -11,7 +11,7 @@ from django.http import HttpResponse from django.contrib import messages from django.utils.translation import ugettext_lazy as _ -from statistics.models import getModel +from statistics.models import StatCache from tariff_app.models import Tariff from agent import NasFailedResult, Transmitter, NasNetworkError from . import forms @@ -33,8 +33,6 @@ def peoples(request, gid): else: peoples_list = peoples_list.filter(group=gid) - StatModel = getModel() - # фильтр dr, field = mydefs.order_helper(request) if field: @@ -44,10 +42,10 @@ def peoples(request, gid): peoples_list = mydefs.pag_mn(request, peoples_list) for abon in peoples_list: if abon.ip_address is not None: - traf = StatModel.objects.traffic_by_ip(abon.ip_address) - if traf[1] is not None: - abon.traf = traf[1] - abon.is_online =traf[0] + try: + abon.stat_cache = StatCache.objects.get(ip=abon.ip_address) + except StatCache.DoesNotExist: + pass except mydefs.LogicError as e: messages.warning(request, e) From 5fd543c23cafeea3af4615f8e0b7b47e86063b4e Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:39:25 +0300 Subject: [PATCH 041/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20=D0=BA=D0=B5?= =?UTF-8?q?=D1=88=D0=B0=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=82=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/migrations/0002_statcache.py | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 statistics/migrations/0002_statcache.py diff --git a/statistics/migrations/0002_statcache.py b/statistics/migrations/0002_statcache.py new file mode 100644 index 0000000..4710120 --- /dev/null +++ b/statistics/migrations/0002_statcache.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-05-31 17:37 +from __future__ import unicode_literals + +from django.db import migrations, models +import mydefs +import statistics.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('statistics', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='StatCache', + fields=[ + ('last_time', statistics.fields.UnixDateTimeField()), + ('ip', mydefs.MyGenericIPAddressField(max_length=8, primary_key=True, protocol='ipv4', serialize=False)), + ('octets', models.PositiveIntegerField(default=0)), + ('packets', models.PositiveIntegerField(default=0)), + ], + options={ + 'db_table': 'flowcache', + }, + ), + ] From ae181c61b9f384bf13a6fcc7382fd206a9df651f Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:44:08 +0300 Subject: [PATCH 042/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20=D0=BA=D0=B5?= =?UTF-8?q?=D1=88=D0=B0=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/models.py | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/statistics/models.py b/statistics/models.py index 6a34c7f..00ea0e3 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -1,26 +1,14 @@ import math from datetime import datetime, timedelta, date, time -from django.db import models, ProgrammingError, connection +from django.db import models, connection +from django.utils.timezone import now + from mydefs import MyGenericIPAddressField from .fields import UnixDateTimeField -from mydefs import LogicError class StatManager(models.Manager): - def traffic_by_ip(self, ip): - try: - traf = self.order_by('-cur_time').filter(ip=ip, octets__gt=524288)[0] - now = datetime.now() - if traf.cur_time < now - timedelta(minutes=55): - return False, traf - else: - return True, traf - except IndexError: - return False, None - except ProgrammingError as e: - raise LogicError(e) - def chart(self, ip_addr, count_of_parts=12, want_date=date.today()): def byte_to_mbit(x): return ((x/60)*8)/2**20 @@ -42,7 +30,7 @@ class StatManager(models.Manager): charts_times = split_list(charts_times, count_of_parts) charts_times = [avarage(t) for t in charts_times] - charts_data = map(lambda x, y: (x, y), charts_times, charts_octets) + charts_data = zip(charts_times, charts_octets) charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data] midnight = datetime.combine(want_date, time.min) charts_data.append("{x:new Date(%d),y:0}" % (int(charts_times[-1:][0]) + 1)) @@ -97,10 +85,27 @@ class StatElem(models.Model): abstract = True -def getModel(want_date=datetime.now()): +def getModel(want_date=now()): class DynamicStatElem(StatElem): class Meta: db_table = 'flowstat_%s' % want_date.strftime("%d%m%Y") abstract = False return DynamicStatElem + + +class StatCache(models.Model): + last_time = UnixDateTimeField() + ip = MyGenericIPAddressField(primary_key=True) + octets = models.PositiveIntegerField(default=0) + packets = models.PositiveIntegerField(default=0) + + def is_online(self): + return self.last_time < now() - timedelta(minutes=55) + + def is_today(self): + return date.today() == self.last_time.date() + + + class Meta: + db_table = 'flowcache' From d1d2153fbbfb61b096a46730ffd593df2fde9c54 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:46:15 +0300 Subject: [PATCH 043/179] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BB=D0=BE=D0=B3=D0=B0=20=D0=B7=D0=B2?= =?UTF-8?q?=D0=BE=D0=BD=D0=BA=D0=BE=D0=B2=20=D0=BA=D0=B0=D0=BA=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/migrations/0001_initial.py | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 dialing_app/migrations/0001_initial.py diff --git a/dialing_app/migrations/0001_initial.py b/dialing_app/migrations/0001_initial.py new file mode 100644 index 0000000..9459b1a --- /dev/null +++ b/dialing_app/migrations/0001_initial.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-05-30 13:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='AsteriskCDR', + fields=[ + ('calldate', models.DateTimeField(default='0000-00-00 00:00:00', primary_key=True, serialize=False)), + ('clid', models.CharField(default='', max_length=80)), + ('src', models.CharField(default='', max_length=80)), + ('dst', models.CharField(default='', max_length=80)), + ('dcontext', models.CharField(default='', max_length=80)), + ('channel', models.CharField(default='', max_length=80)), + ('dstchannel', models.CharField(default='', max_length=80)), + ('lastapp', models.CharField(default='', max_length=80)), + ('lastdata', models.CharField(default='', max_length=80)), + ('duration', models.IntegerField(default=0)), + ('billsec', models.IntegerField(default=0)), + ('start', models.DateTimeField(blank=True, default=None, null=True)), + ('answer', models.DateTimeField(blank=True, default=None, null=True)), + ('end', models.DateTimeField(blank=True, default=None, null=True)), + ('disposition', models.CharField(choices=[('NO ANSWER', 'No answer'), ('FAILED', 'Failed'), ('BUSY', 'Busy'), ('ANSWERED', 'Answered'), ('UNKNOWN', 'Unknown')], default='', max_length=45)), + ('amaflags', models.IntegerField(default=0)), + ('accountcode', models.CharField(default='', max_length=20)), + ('userfield', models.CharField(default='', max_length=255)), + ('uniqueid', models.CharField(default='', max_length=32)), + ], + options={ + 'db_table': 'cdr', + }, + ), + ] From 7492fdcd7a2cc66967724a013f2b2dbe286ba2a6 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 31 May 2017 17:46:40 +0300 Subject: [PATCH 044/179] =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=BD=D1=8F=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=B8=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/migrations/0002_delete_statelem.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 statistics/migrations/0002_delete_statelem.py diff --git a/statistics/migrations/0002_delete_statelem.py b/statistics/migrations/0002_delete_statelem.py deleted file mode 100644 index 8fd4fbe..0000000 --- a/statistics/migrations/0002_delete_statelem.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-04-25 13:27 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('statistics', '0001_initial'), - ] - - operations = [ - migrations.DeleteModel( - name='StatElem', - ), - ] From bfc59e6a8adb2f2809b107ac2f8924975acf1078 Mon Sep 17 00:00:00 2001 From: http Date: Wed, 31 May 2017 17:59:29 +0300 Subject: [PATCH 045/179] =?UTF-8?q?FIXBUG:=20=D1=81=D1=82=D0=B0=D1=82?= =?UTF-8?q?=D1=83=D1=81=20online=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B0=D0=BB=D1=81=D1=8F=20=D0=BD=D0=B0=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/statistics/models.py b/statistics/models.py index 00ea0e3..4b32e15 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -101,7 +101,7 @@ class StatCache(models.Model): packets = models.PositiveIntegerField(default=0) def is_online(self): - return self.last_time < now() - timedelta(minutes=55) + return self.last_time > now() - timedelta(minutes=55) def is_today(self): return date.today() == self.last_time.date() From b1972c2f0bfdc4b4140c97c0b48f73df581f9c42 Mon Sep 17 00:00:00 2001 From: http Date: Wed, 31 May 2017 17:59:59 +0300 Subject: [PATCH 046/179] =?UTF-8?q?=D0=BD=D0=B5=20=D0=BD=D0=B0=D0=B4=D0=BE?= =?UTF-8?q?=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/netflow/djing_flow.conf | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 agent/netflow/djing_flow.conf diff --git a/agent/netflow/djing_flow.conf b/agent/netflow/djing_flow.conf deleted file mode 100644 index eccdbfa..0000000 --- a/agent/netflow/djing_flow.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Config for djing flow - -version = "0.1"; - -# количество строк на запрос -mysql_rows_per_request = 65735; From a61f960a9e04d49324841e60dd90b740cc9dbf38 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 1 Jun 2017 13:40:19 +0300 Subject: [PATCH 047/179] FIXBUG --- abonapp/pay_systems.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/abonapp/pay_systems.py b/abonapp/pay_systems.py index f0f0606..4835348 100644 --- a/abonapp/pay_systems.py +++ b/abonapp/pay_systems.py @@ -62,13 +62,15 @@ def allpay(request): pays = AllTimePayLog.objects.filter(pay_id=pay_id) if pays.count() > 0: return bad_ret(-100) + + # тут в author передаём учётку абонента, т.к. это он сам через терминал пополняет + abon.add_ballance(abon, pay_amount, comment='AllPay %.2f' % pay_amount) + abon.save(update_fields=['ballance']) + AllTimePayLog.objects.create( pay_id=pay_id, summ=pay_amount ) - # тут в author передаём учётку абонента, т.к. это он сам через терминал пополняет - abon.add_ballance(abon, pay_amount, comment='AllPay %.2f' % pay_amount) - abon.save(update_fields=['ballance']) current_date = timezone.now().strftime("%d.%m.%Y %H:%M:%S") return "" \ "\n" +\ From 379ff1cb70d4f05dfd706daaaedad44cbd3e1904 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 1 Jun 2017 13:41:33 +0300 Subject: [PATCH 048/179] =?UTF-8?q?=D0=A1=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B2=D0=BE=D0=B4=D0=B8=D0=BC=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D1=91=D0=BD=D0=BD=D1=8B=D0=B5=20=D1=83=D1=81?= =?UTF-8?q?=D0=BB=D1=83=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/peoples.html | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 2b04bfd..0e95b5e 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -50,7 +50,7 @@ {% if order_by == 'house' %}{% endif %} {% trans 'Telephone' %} - + {% trans 'Service' %} {% trans 'Ballance' %} @@ -87,16 +87,16 @@ {{ human.street|default:_('Not assigned') }} {{ human.house|default:_('Not assigned') }} {{ human.telephone }} - + + {% if human.active_tariff %} + {% if perms.tariff_app.change_tariff %} + {{ human.active_tariff.title }} + {% else %} + {{ human.active_tariff.title }} + {% endif %} + {% else %}——— + {% endif %} + {{ human.ballance }} {% if perms.abonapp.delete_abon %} @@ -108,7 +108,7 @@ {% empty %} - + {% trans 'Subscribers not found' %}. {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} @@ -119,7 +119,7 @@ - + {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} From 8885777a8eb5734747824c9bad6487cca7eaad43 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 1 Jun 2017 14:02:04 +0300 Subject: [PATCH 049/179] =?UTF-8?q?=D0=94=D0=BB=D1=8F=20=D0=BF=D0=BB=D0=B0?= =?UTF-8?q?=D1=82=D0=B5=D0=B6=D0=B5=D0=B9=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B0=D1=82=D0=BE=D0=BC=D0=B0=D1=80=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20django?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/abonapp/views.py b/abonapp/views.py index 1152242..6de44c6 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -4,6 +4,7 @@ from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.db import IntegrityError, ProgrammingError from django.db.models import Count, Q +from django.db.transaction import atomic from django.shortcuts import render, redirect, get_object_or_404, resolve_url from django.contrib.auth.decorators import login_required, permission_required from django.utils import timezone @@ -351,7 +352,7 @@ def opt82(request, gid, uid): return redirect('abonapp:abon_home', gid=gid, uid=uid) -@mydefs.require_ssl +@atomic def terminal_pay(request): from .pay_systems import allpay ret_text = allpay(request) From 42e3b6a6c3a1c8489d76f913c5e86b5f213f2446 Mon Sep 17 00:00:00 2001 From: http Date: Thu, 1 Jun 2017 15:32:41 +0300 Subject: [PATCH 050/179] =?UTF-8?q?=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D1=83=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=83?= =?UTF-8?q?=D1=81=D0=BB=D1=83=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clientsideapp/templates/clientsideapp/services.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clientsideapp/templates/clientsideapp/services.html b/clientsideapp/templates/clientsideapp/services.html index b900a28..c9e39a7 100644 --- a/clientsideapp/templates/clientsideapp/services.html +++ b/clientsideapp/templates/clientsideapp/services.html @@ -21,8 +21,8 @@
  • {% if abon_tariff == current_service %} - + {% else %} From 8c51ec3b1e2efaac649843bd73452d51f5693a67 Mon Sep 17 00:00:00 2001 From: http Date: Thu, 1 Jun 2017 15:33:20 +0300 Subject: [PATCH 051/179] FIXBUG --- abonapp/forms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/abonapp/forms.py b/abonapp/forms.py index fc07833..2bb9bad 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -11,7 +11,6 @@ from .formfields import MACAddressField def generate_random_username(length=6, chars=digits, split=2, delimiter=''): username = ''.join([choice(chars) for i in range(length)]) - username = str(int(username)) if split: username = delimiter.join([username[start:start+split] for start in range(0, len(username), split)]) From c6e309e4781b87ec29877e54ab35594353425f23 Mon Sep 17 00:00:00 2001 From: http Date: Thu, 1 Jun 2017 15:34:08 +0300 Subject: [PATCH 052/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B0=D1=82=D0=BE=D0=BC=D0=B0=D1=80=D0=BD=D1=83=D1=8E?= =?UTF-8?q?=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=B2=20=D0=BF=D0=BB=D0=B0=D1=82=D1=91=D0=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/abonapp/views.py b/abonapp/views.py index 1152242..6de44c6 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -4,6 +4,7 @@ from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.db import IntegrityError, ProgrammingError from django.db.models import Count, Q +from django.db.transaction import atomic from django.shortcuts import render, redirect, get_object_or_404, resolve_url from django.contrib.auth.decorators import login_required, permission_required from django.utils import timezone @@ -351,7 +352,7 @@ def opt82(request, gid, uid): return redirect('abonapp:abon_home', gid=gid, uid=uid) -@mydefs.require_ssl +@atomic def terminal_pay(request): from .pay_systems import allpay ret_text = allpay(request) From 18bea3eb4803be1a9311af918a803339c06ddb2e Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 13:51:57 +0300 Subject: [PATCH 053/179] =?UTF-8?q?FIXBUG:=20=D0=BF=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts_app/locale/ru/LC_MESSAGES/django.po | 6 ++++++ accounts_app/views.py | 16 +++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/accounts_app/locale/ru/LC_MESSAGES/django.po b/accounts_app/locale/ru/LC_MESSAGES/django.po index ba3578d..16426bd 100644 --- a/accounts_app/locale/ru/LC_MESSAGES/django.po +++ b/accounts_app/locale/ru/LC_MESSAGES/django.po @@ -184,3 +184,9 @@ msgstr "Редактировать" msgid "Set a task" msgstr "Дать задачу" + +msgid "Empty password, fill it" +msgstr "Пустой пароль, впишите что-то в пароль" + +msgid "New password is empty, fill it" +msgstr "Новый пароль пустой, придумайте себе пароль" diff --git a/accounts_app/views.py b/accounts_app/views.py index b8c8961..910328d 100644 --- a/accounts_app/views.py +++ b/accounts_app/views.py @@ -4,7 +4,6 @@ from django.contrib.auth import authenticate, login, logout from django.core.exceptions import PermissionDenied from django.core.urlresolvers import NoReverseMatch from django.shortcuts import render, redirect, get_object_or_404, resolve_url -from django.http import Http404 from django.contrib.auth.models import Group, Permission from django.contrib import messages from django.utils.translation import ugettext as _ @@ -129,14 +128,21 @@ def ch_info(request): user.telephone = request.POST.get('telephone') psw = request.POST.get('oldpasswd') - if psw != '': + if psw != '' and psw is not None: if user.check_password(psw): newpasswd = request.POST.get('newpasswd') - user.set_password(newpasswd) + if newpasswd != '' and newpasswd is not None: + user.set_password(newpasswd) + user.save() + request.user = user + logout(request) + return redirect('acc_app:other_profile', uid=user.pk) + else: + messages.error(request, _('New password is empty, fill it')) else: messages.error(request, _('Wrong password')) - user.save() - request.user = user + else: + messages.warning(request, _('Empty password, fill it')) return render(request, 'accounts/settings/ch_info.html', { 'user': request.user From f51e8eb1f89014d087ed7f4f337e1f09e4001706 Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 15:39:07 +0300 Subject: [PATCH 054/179] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D1=8F=D0=BB=20=D0=B0=D1=82=D0=BE=D0=BC=D0=B0=D1=80?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D0=BA=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5?= =?UTF-8?q?=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=BC=20=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/abonapp/views.py b/abonapp/views.py index 6de44c6..6b450fd 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -190,6 +190,7 @@ def delentity(request): @login_required @permission_required('abonapp.can_add_ballance') +@atomic def abonamount(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) try: @@ -398,6 +399,7 @@ def add_invoice(request, gid, uid): @login_required @permission_required('abonapp.can_buy_tariff') +@atomic def pick_tariff(request, gid, uid): grp = get_object_or_404(models.AbonGroup, pk=gid) abon = get_object_or_404(models.Abon, pk=uid) @@ -457,6 +459,7 @@ def chpriority(request, gid, uid): @login_required @permission_required('abonapp.can_complete_service') +@atomic def complete_service(request, gid, uid, srvid): abtar = get_object_or_404(models.AbonTariff, pk=srvid) abon = abtar.abon @@ -516,6 +519,7 @@ def complete_service(request, gid, uid, srvid): @login_required @permission_required('abonapp.can_activate_service') +@atomic def activate_service(request, gid, uid, srvid): abtar = get_object_or_404(models.AbonTariff, pk=srvid) amount = abtar.calc_amount_service() From ebeea963331d9de2c6757946ffac649bd9f22cc9 Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 15:39:24 +0300 Subject: [PATCH 055/179] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D1=8F=D0=BB=20=D0=B0=D1=82=D0=BE=D0=BC=D0=B0=D1=80?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D0=BA=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5?= =?UTF-8?q?=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=BC=20=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clientsideapp/locale/ru/LC_MESSAGES/django.po | 38 ++++++++++++++++++ clientsideapp/views.py | 39 +++++++++++-------- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/clientsideapp/locale/ru/LC_MESSAGES/django.po b/clientsideapp/locale/ru/LC_MESSAGES/django.po index 6b08e8a..d418db2 100644 --- a/clientsideapp/locale/ru/LC_MESSAGES/django.po +++ b/clientsideapp/locale/ru/LC_MESSAGES/django.po @@ -162,3 +162,41 @@ msgstr "Комментарий" #: clientsideapp/templates/clientsideapp/pays.html:25 msgid "You have not spent payments" msgstr "У вас нет проведённых платежей" + +msgid "Buy the service via user side, service '%s'" +msgstr "Покупка тарифного плана через личный кабинет, тариф '%s'" + +msgid "" +"You are subscribed on new service. " +"That will enable service when your current service has expired." + +msgstr "" +"Вы подписались на новую услугу. Она встала на очередь подключений. " +"Когда закончится ваша текущая услуга, то включится эта" + +msgid "Service '%s' has been finished" +msgstr "Услуга '%s' успешно завершена" + +msgid "The service '%s' wan successfully activated" +msgstr "Услуга '%s' успешно активирована" + +msgid "Early terminated service '%s' via client side" +msgstr "Досрочное завершение услуги '%s' из личного кабинета" + +msgid "Act is not confirmed" +msgstr "Действие не подтверждено" + +msgid "Temporary network bug" +msgstr "Временные неполадки в сети" + +msgid "You has been successfully unsubscribed from service, '%s'" +msgstr "Вы успешно отписались от услуги, '%s'" + +msgid "The service was not found" +msgstr "Указанная подписка на услугу не найдена" + +msgid "Are you not sure that you want buy the service?" +msgstr "Вы не уверены что хотите оплатить долг?" + +msgid "Your account have not enough money" +msgstr "Недостаточно средств на счету" diff --git a/clientsideapp/views.py b/clientsideapp/views.py index fb3d785..5db6210 100644 --- a/clientsideapp/views.py +++ b/clientsideapp/views.py @@ -4,6 +4,8 @@ from django.contrib.gis.shortcuts import render_to_text from django.shortcuts import render, get_object_or_404, redirect from django.contrib import messages from django.utils import timezone +from django.db.transaction import atomic +from django.utils.translation import ugettext_lazy as _ from abonapp.models import AbonLog, AbonTariff, InvoiceForPayment, Abon from tariff_app.models import Tariff @@ -41,16 +43,17 @@ def services(request): @login_required +@atomic def buy_service(request, srv_id): abon = get_object_or_404(Abon, pk=request.user.pk) service = get_object_or_404(Tariff, pk=srv_id) try: current_service = abon.active_tariff() if request.method == 'POST': - abon.pick_tariff(service, request.user, 'Покупка тарифного плана через личный кабинет, тариф "%s"' - % service) - messages.success(request, 'Вы подписались на новую услугу. Она встала на очередь подключений. ' - 'Когда закончится ваша текущая услуга, то включится эта') + abon.pick_tariff(service, request.user, _("Buy the service via user side, service '%s'") + % service) + messages.success(request, _('You are subscribed on new service. ' + 'That will enable service when your current service has expired.')) else: return render_to_text('clientsideapp/modal_service_buy.html', { 'service': service, @@ -64,6 +67,7 @@ def buy_service(request, srv_id): @login_required +@atomic def complete_service(request, srv_id): abtar = get_object_or_404(AbonTariff, id=srv_id) service = abtar.tariff @@ -75,15 +79,15 @@ def complete_service(request, srv_id): if finish_confirm == 'yes': # удаляем запись о текущей услуге. abtar.delete() - messages.success(request, 'Услуга "%s" успешно завершена' % service.title) + messages.success(request, _("Service '%s' has been finished") % service.title) AbonLog.objects.create( abon=abtar.abon, amount=0.0, author=abtar.abon, - comment='Досрочное завершение услуги "%s" из личного кабинета' % service.title + comment=_("Early terminated service '%s' via client side") % service.title ) else: - messages.error(request, 'Действие не подтверждено') + messages.error(request, _('Act is not confirmed')) else: time_use = RuTimedelta(timezone.now() - abtar.time_start) return render_to_text('clientsideapp/modal_complete_service.html', { @@ -96,11 +100,12 @@ def complete_service(request, srv_id): except NasFailedResult as e: messages.error(request, e) except NasNetworkError: - messages.error(request, 'Временные неполадки') + messages.error(request, _('Temporary network bug')) return redirect('client_side:services') @login_required +@atomic def unsubscribe_service(request, srv_id): abtar = get_object_or_404(AbonTariff, id=srv_id) service = abtar.tariff @@ -109,24 +114,25 @@ def unsubscribe_service(request, srv_id): # досрочно завершаем услугу if request.POST.get('finish_confirm') == 'yes': AbonTariff.objects.get(pk=srv_id).delete() - messages.success(request, 'Вы успешно отписались от услуги, "%s"' % service.title) + messages.success(request, _("You has been successfully unsubscribed from service, '%s'") % service.title) else: - messages.error(request, 'Действие не подтверждено') + messages.error(request, _('Act is not confirmed')) else: return render_to_text('clientsideapp/modal_unsubscribe_service.html', { 'abtar': abtar, 'service': service }, request=request) except AbonTariff.DoesNotExist: - messages.error(request, 'Указанная подписка на услугу не найдена') + messages.error(request, _('The service was not found')) except NasFailedResult as e: messages.error(request, e) except NasNetworkError: - messages.error(request, 'Временные неполадки') + messages.error(request, _('Temporary network bug')) return redirect('client_side:services') @login_required +@atomic def activate_service(request, srv_id): abtar = get_object_or_404(AbonTariff, id=srv_id) service = abtar.tariff @@ -136,9 +142,9 @@ def activate_service(request, srv_id): # активируем услугу if request.POST.get('finish_confirm') == 'yes': abtar.activate(request.user) - messages.success(request, 'Услуга "%s" успешно активирована' % service.title) + messages.success(request, _("The service '%s' wan successfully activated") % service.title) else: - messages.error(request, 'Запрос не подтверждён') + messages.error(request, _('Act is not confirmed')) return redirect('client_side:services') except NasFailedResult as e: messages.error(request, e) @@ -164,6 +170,7 @@ def debts_list(request): @login_required +@atomic def debt_buy(request, d_id): debt = get_object_or_404(InvoiceForPayment, id=d_id) abon = get_object_or_404(Abon, id=request.user.id) @@ -171,9 +178,9 @@ def debt_buy(request, d_id): try: sure = request.POST.get('sure') if sure != 'on': - raise LogicError('Вы не уверены что хотите оплатить долг?') + raise LogicError(_("Are you not sure that you want buy the service?")) if abon.ballance < debt.amount: - raise LogicError('Не достаточно средств на счету') + raise LogicError(_('Your account have not enough money')) abon.make_pay(request.user, debt.amount) debt.set_ok() From e871d4f4f925948c02d5c580ecb09014a25ae165 Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 16:56:50 +0300 Subject: [PATCH 056/179] =?UTF-8?q?=D1=83=D0=BA=D1=80=D0=B0=D1=81=D0=B8?= =?UTF-8?q?=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/ports.html | 78 ++++++------------------------ 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/devapp/templates/devapp/ports.html b/devapp/templates/devapp/ports.html index 21ea774..d2cad97 100644 --- a/devapp/templates/devapp/ports.html +++ b/devapp/templates/devapp/ports.html @@ -14,29 +14,30 @@ {% for port in ports %} {% if port.st %} {% if port.sp == 10 %} -
    +
    {% elif port.sp == 100 %} -
    +
    {% elif port.sp == 1000 %} -
    +
    {% else %} -
    +
    {% endif %} {% else %} -
    +
    {% endif %} - + {{ port.num }} - + {% else %} + + + + {% endif %}
    {% empty %}

    {% trans 'We have not received info, please check options :(' %}

    @@ -65,58 +66,7 @@ - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 2 - Err:bug - port Eth1 state Up - 21 Dec 12:15:23 - - - 3 - Err:Other - port Eth1 state Up - 21 Dec 12:15:45 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 - - - 1 - Err:Disable - port Eth1 state Down - 21 Dec 12:14:55 + Coming soon.. From bb8c8351445e83c2443ac0de9d3c9c904facd02e Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 16:57:02 +0300 Subject: [PATCH 057/179] =?UTF-8?q?=D1=83=D0=BA=D1=80=D0=B0=D1=81=D0=B8?= =?UTF-8?q?=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/locale/ru/LC_MESSAGES/django.po | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index c376b20..4350c64 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -41,11 +41,11 @@ msgstr "ONU Голова" #: devapp/templates/devapp/group_list.html:7 #: devapp/templates/devapp/group_list.html:10 msgid "Groups" -msgstr "" +msgstr "Группы" #: devapp/templates/devapp/add_dev.html:8 msgid "Add new device" -msgstr "" +msgstr "Добавить устройство" #: devapp/templates/devapp/add_dev.html:14 #: devapp/templates/devapp/ports.html:143 @@ -84,7 +84,7 @@ msgstr "Точка топологии" #: devapp/templates/devapp/add_dev.html:71 devapp/templates/devapp/dev.html:59 msgid "User group" -msgstr "" +msgstr "Группа" #: devapp/templates/devapp/add_dev.html:81 devapp/templates/devapp/dev.html:69 msgid "Save" @@ -118,7 +118,7 @@ msgstr "Устройства без группы" #: devapp/templates/devapp/group_list.html:18 msgid "Group title" -msgstr "" +msgstr "Название" #: devapp/templates/devapp/group_list.html:28 #, fuzzy @@ -128,7 +128,7 @@ msgstr "Эта точка не пингуется" #: devapp/templates/devapp/group_list.html:37 msgid "Add group" -msgstr "" +msgstr "Добавить группу" #: devapp/templates/devapp/olt.html:13 msgid "Mac" @@ -224,3 +224,9 @@ msgstr "Ошибка SNMP на устройстве" msgid "Edit" msgstr "Редактировать" + +msgid "Enable port" +msgstr "Включить порт" + +msgid "Disable port" +msgstr "Выключить порт" From 6112fdb2998be6ab9aede28bac88a414f6ffe7e7 Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 17:00:50 +0300 Subject: [PATCH 058/179] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=81=D0=BA=D0=BB=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/locale/ru/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 5be7d30..e94f112 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -853,7 +853,7 @@ msgid "SNMP error on device" msgstr "Ошибка в SNMP на устройстве" msgid "Charts" -msgstr "Графики" +msgstr "График" msgid "Sub information" msgstr "Информация абонента" From 1ed45e2370192cfd9559a997f2e591d660eea37c Mon Sep 17 00:00:00 2001 From: bashmak Date: Fri, 2 Jun 2017 17:04:12 +0300 Subject: [PATCH 059/179] =?UTF-8?q?=D0=97=D0=B0=D0=B2=D0=B5=D1=80=D1=88?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=83=D1=87=D1=91=D1=82=20=D0=B2=D1=80=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=B7=D0=BE=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bugs.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/bugs.txt b/bugs.txt index fa0bb2e..b93b54a 100644 --- a/bugs.txt +++ b/bugs.txt @@ -7,4 +7,3 @@ - Доделать везде переводы - Не надо коннектиться к микротику когда не собираемся ничего изменять. А то при сохранении залогинились и вышли без действий - Не удаляет просроченные услуги если не пингуется NAS -- Надо отменить учёт временной зоны From 9a96374bec123e10e9f80cf93a750f3d758ce3a8 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 5 Jun 2017 18:11:02 +0300 Subject: [PATCH 060/179] FIXBUG --- clientsideapp/templates/clientsideapp/ext.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientsideapp/templates/clientsideapp/ext.html b/clientsideapp/templates/clientsideapp/ext.html index 5e2b2bd..da140c9 100644 --- a/clientsideapp/templates/clientsideapp/ext.html +++ b/clientsideapp/templates/clientsideapp/ext.html @@ -11,7 +11,7 @@ -/head> + +
    + +{% endblock %} diff --git a/devapp/templates/devapp/manage_ports/list.html b/devapp/templates/devapp/manage_ports/list.html new file mode 100644 index 0000000..c2421ba --- /dev/null +++ b/devapp/templates/devapp/manage_ports/list.html @@ -0,0 +1,60 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %} +{% load i18n %} +{% block content %} + +
    +
    +
    + + + + + + + + + + + {% with gid=dev.user_group.pk did=dev.pk can_del_port=perms.devapp.delete_port can_edit_port=perms.devapp.change_port %} + {% for port in ports %} + + + + + + {% empty %} + + + + {% endfor %} + {% endwith %} + + + + + + + +
    {% trans 'Number' %}{% trans 'Description' %}#
    {{ port.num }}{{ port.descr }} + {% if can_del_port %} + + + + {% endif %} + {% if can_edit_port %} + + + + {% endif %} +
    {% trans 'Ports not found' %}
    + {% if perms.devapp.add_port %} + + {% trans 'Add ports' %} + + {% endif %} +
    +
    +
    +
    + +{% endblock %} diff --git a/devapp/templates/devapp/manage_ports/modal_add_edit_port.html b/devapp/templates/devapp/manage_ports/modal_add_edit_port.html new file mode 100644 index 0000000..7442975 --- /dev/null +++ b/devapp/templates/devapp/manage_ports/modal_add_edit_port.html @@ -0,0 +1,37 @@ +{% load i18n %} + +{% if port_id %} +
    {% else %} +{% endif %}{% csrf_token %} + + + + + +
    diff --git a/devapp/templates/devapp/manage_ports/modal_del_port.html b/devapp/templates/devapp/manage_ports/modal_del_port.html new file mode 100644 index 0000000..33e15d2 --- /dev/null +++ b/devapp/templates/devapp/manage_ports/modal_del_port.html @@ -0,0 +1,18 @@ +{% load i18n %} + +
    {% csrf_token %} + + + + + +
    diff --git a/devapp/urls.py b/devapp/urls.py index c79a932..e9700eb 100644 --- a/devapp/urls.py +++ b/devapp/urls.py @@ -5,11 +5,16 @@ from . import views urlpatterns = [ url(r'^$', views.group_list, name='group_list'), - url(r'^add$', views.dev, name='add'), url(r'^devices_without_groups$', views.devices_null_group, name='devices_null_group'), url(r'^(?P\d+)$', views.devices, name='devs'), + url(r'^(?P\d+)/add$', views.dev, name='add'), url(r'^(\d+)/(?P\d+)$', views.devview, name='view'), url(r'^(\d+)/(?P\d+)/del$', views.devdel, name='del'), - url(r'^(\d+)/(?P\d+)/edit$', views.dev, name='edit'), - url(r'^(\d+)/(?P\d+)/(?P\d+)_(?P[0-1]{1})$', views.toggle_port, name='port_toggle') + url(r'^(?P\d+)/(?P\d+)/add$', views.add_single_port, name='add_port'), + url(r'^(?P\d+)/(?P\d+)/edit$', views.dev, name='edit'), + url(r'^(\d+)/(?P\d+)/ports$', views.manage_ports, name='manage_ports'), + url(r'^(\d+)/(?P\d+)/ports_add', views.add_ports, name='add_ports'), + url(r'^(\d+)/(?P\d+)/(?P\d+)_(?P[0-1]{1})$', views.toggle_port, name='port_toggle'), + url(r'^(?P\d+)/(?P\d+)/(?P\d+)/del$', views.delete_single_port, name='del_port'), + url(r'^(?P\d+)/(?P\d+)/(?P\d+)/edit$', views.edit_single_port, name='edit_port') ] diff --git a/devapp/views.py b/devapp/views.py index 65126a4..0bbc25f 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.shortcuts import render, redirect, get_object_or_404, resolve_url from django.contrib import messages from django.utils.translation import ugettext_lazy as _ from easysnmp import EasySNMPTimeoutError, EasySNMPError -from .models import Device +from .models import Device, Port, DeviceDBException from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_helper -from .forms import DeviceForm -from abonapp.models import AbonGroup +from .forms import DeviceForm, PortForm +from abonapp.models import AbonGroup, Abon +from djing.settings import DEFAULT_SNMP_PASSWORD @login_required @@ -61,12 +63,15 @@ def devdel(request, did): return res_success(request, back_url) except Device.DoesNotExist: return res_error(request, _('Delete failed')) + except DeviceDBException as e: + return res_error(request, e) @login_required @only_admins -def dev(request, devid=0): +def dev(request, grp, devid=0): devinst = get_object_or_404(Device, id=devid) if devid != 0 else None + user_group = get_object_or_404(AbonGroup, pk=grp) if request.method == 'POST': if devid == 0: @@ -79,14 +84,26 @@ def dev(request, devid=0): if frm.is_valid(): frm.save() messages.success(request, _('Device info has been saved')) + return redirect('devapp:devs', grp) else: messages.error(request, _('Form is invalid, check fields and try again')) else: - frm = DeviceForm(instance=devinst) + if devinst is None: + frm = DeviceForm(initial={ + 'user_group': user_group, + 'devtype': request.GET.get('t'), + 'mac_addr': request.GET.get('mac'), + 'comment': request.GET.get('c'), + 'ip_address': request.GET.get('ip'), + 'man_passw': DEFAULT_SNMP_PASSWORD + }) + else: + frm = DeviceForm(instance=devinst) if devinst is None: return render(request, 'devapp/add_dev.html', { - 'form': frm + 'form': frm, + 'group': user_group }) else: return render(request, 'devapp/dev.html', { @@ -95,14 +112,179 @@ def dev(request, devid=0): }) +@login_required +@permission_required('devapp.change_device') +def manage_ports(request, devid): + try: + dev = Device.objects.get(pk=devid) + if dev.user_group is None: + messages.error(request, _('Device is not have a group, please fix that')) + return redirect('devapp:group_list') + ports = Port.objects.filter(device=dev) + + except Device.DoesNotExist: + messages.error(request, _('Device does not exist')) + return redirect('devapp:view', dev.user_group.pk if dev.user_group else 0, did=devid) + except DeviceDBException as e: + messages.error(request, e) + return render(request, 'devapp/manage_ports/list.html', { + 'ports': ports, + 'dev': dev + }) + + +@login_required +@permission_required('devapp.add_port') +def add_ports(request, devid): + class TempPort: + def __init__(self, pid, text, status, from_db, pk=None): + self.pid = pid + self.text = text + self.status = status + self.from_db = from_db + self.pk = pk + + def __eq__(self, other): + return self.pid == other.pid + + def __hash__(self): + return self.pid + + def __str__(self): + return "p:%d\tM:%s\tT:%s" % (self.pid, self.text) + + try: + dev = Device.objects.get(pk=devid) + if dev.user_group is None: + messages.error(request, _('Device is not have a group, please fix that')) + return redirect('devapp:group_list') + if request.method == 'POST': + ports = zip( + request.POST.getlist('p_text'), + request.POST.getlist('pids') + ) + for port_text, port_num in ports: + if port_text == '' or port_text is None: + continue + try: + port = Port.objects.get(num=port_num, device=dev) + port.descr = port_text + port.save(update_fields=['descr']) + except Port.DoesNotExist: + Port.objects.create( + num=port_num, + device=dev, + descr=port_text + ) + + db_ports = Port.objects.filter(device=dev) + db_ports = [TempPort(p.num, p.descr, None, True, p.pk) for p in db_ports] + + manager = dev.get_manager_klass()(dev.ip_address, dev.man_passw) + ports = manager.get_ports() + if ports is not None: + ports = [TempPort(p.num, p.nm, p.st, False) for p in ports] + res_ports = set(db_ports + ports) + else: + res_ports = db_ports + + except Device.DoesNotExist: + messages.error(request, _('Device does not exist')) + return redirect('devapp:group_list') + except DeviceDBException as e: + messages.error(request, e) + return render(request, 'devapp/manage_ports/add_ports.html', { + 'ports': res_ports, + 'dev': dev + }) + + +@login_required +@permission_required('devapp.delete_port') +def delete_single_port(request, grp, did, portid): + try: + if request.method == 'POST': + if request.POST.get('confirm') == 'yes': + Port.objects.get(pk=portid).delete() + messages.success(request, _('Port successfully removed')) + else: + return render_to_text('devapp/manage_ports/modal_del_port.html', { + 'grp': grp, + 'did': did, + 'port_id': portid + }, request=request) + except Port.DoesNotExist: + messages.error(request, _('Port does not exist')) + except DeviceDBException as e: + messages.error(request, e) + return redirect('devapp:manage_ports', grp, did) + + +@login_required +@permission_required('devapp.add_port') +def edit_single_port(request, grp, did, pid): + try: + port = Port.objects.get(pk=pid) + if request.method == 'POST': + frm = PortForm(request.POST, instance=port) + if frm.is_valid(): + frm.save() + messages.success(request, _('Port successfully saved')) + else: + messages.error(request, _('Form is invalid, check fields and try again')) + return redirect('devapp:manage_ports', grp, did) + + frm = PortForm(instance=port) + return render_to_text('devapp/manage_ports/modal_add_edit_port.html', { + 'port_id': pid, + 'did': did, + 'gid': grp, + 'form': frm + }, request=request) + except Port.DoesNotExist: + messages.error(request, _('Port does not exist')) + except DeviceDBException as e: + messages.error(request, e) + return redirect('devapp:manage_ports', grp, did) + + +@login_required +@permission_required('devapp.add_port') +def add_single_port(request, grp, did): + try: + device = Device.objects.get(pk=did) + if request.method == 'POST': + frm = PortForm(request.POST, instance=Port(device=device)) + if frm.is_valid(): + frm.save() + messages.success(request, _('Port successfully saved')) + return redirect('devapp:manage_ports', grp, did) + else: + messages.error(request, _('Form is invalid, check fields and try again')) + else: + frm = PortForm(initial={ + 'num': request.GET.get('n'), + 'descr': request.GET.get('t') + }) + return render_to_text('devapp/manage_ports/modal_add_edit_port.html', { + 'did': did, + 'gid': grp, + 'form': frm + }, request=request) + except Device.DoesNotExist: + messages.error(request, _('Device does not exist')) + except DeviceDBException as e: + messages.error(request, e) + return redirect('devapp:manage_ports', grp, did) + + @login_required @only_admins def devview(request, did): - ports = None uptime = 0 dev = get_object_or_404(Device, id=did) - template_name = 'devapp/ports.html' + template_name = 'ports.html' try: if ping(dev.ip_address): if dev.man_passw: @@ -118,11 +300,14 @@ def devview(request, did): messages.error(request, _('wait for a reply from the SNMP Timeout')) except EasySNMPError: messages.error(request, _('SNMP error on device')) + except DeviceDBException as e: + messages.error(request, e) - return render(request, template_name, { + return render(request, 'devapp/custom_dev_page/'+template_name, { 'dev': dev, 'ports': ports, - 'uptime': uptime + 'uptime': uptime, + 'dev_accs': Abon.objects.filter(device=dev) }) From 0883996aceb1946278ef5bfe9949f7a548874ec9 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:51:49 +0300 Subject: [PATCH 115/179] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BE=D0=BF=D0=B5=D1=87=D0=B0=D1=82=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/migrations/0005_auto_20170502_2232.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devapp/migrations/0005_auto_20170502_2232.py b/devapp/migrations/0005_auto_20170502_2232.py index 104ce71..91cbe61 100644 --- a/devapp/migrations/0005_auto_20170502_2232.py +++ b/devapp/migrations/0005_auto_20170502_2232.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='device', name='devtype', - field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON ONU')], default='Dl', max_length=2), + field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT')], default='Dl', max_length=2), ), ] From fc2168a61f2a0d129af20e066fc8765ab773d935 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:52:19 +0300 Subject: [PATCH 116/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts_app/locale/ru/LC_MESSAGES/django.po | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/accounts_app/locale/ru/LC_MESSAGES/django.po b/accounts_app/locale/ru/LC_MESSAGES/django.po index 571b3b8..d3c7a5c 100644 --- a/accounts_app/locale/ru/LC_MESSAGES/django.po +++ b/accounts_app/locale/ru/LC_MESSAGES/django.po @@ -188,3 +188,9 @@ msgstr "Редактировать" msgid "Set a task" msgstr "Дать задачу" + +msgid "Please select an image" +msgstr "Пожалуйста выберите изображение" + +msgid "Avatar successfully changed" +msgstr "Аватар успешно изменён" From 3964455bfaf590458ee3fac30fb42ae49e91b192 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:53:09 +0300 Subject: [PATCH 117/179] =?UTF-8?q?=D0=9F=D1=80=D0=B8=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D1=82=D0=B0=20=D0=BD=D0=B5=20=D1=83=D1=87?= =?UTF-8?q?=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D0=B5=D0=BC=20=D0=B4=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9=20=D0=BE?= =?UTF-8?q?=D0=BD=20=D0=B8=D0=BB=D0=B8=20=D0=BD=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/mod_mikrotik.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/agent/mod_mikrotik.py b/agent/mod_mikrotik.py index 05cf43f..2d17233 100644 --- a/agent/mod_mikrotik.py +++ b/agent/mod_mikrotik.py @@ -375,8 +375,7 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager): def add_user_range(self, user_list): for usr in user_list: - if hasattr(usr, 'is_dhcp') and not usr.is_dhcp(): - self.add_user(usr) + self.add_user(usr) def remove_user_range(self, users): queue_ids = [usr.queue_id for usr in users if usr is not None] From b552f3b3cbc12a67ad8ae2b3b6de845bcbc84f21 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:54:38 +0300 Subject: [PATCH 118/179] =?UTF-8?q?Super()=20=D0=B2=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=20=D0=BD=D0=BE=D1=82=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- photo_app/models.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/photo_app/models.py b/photo_app/models.py index edc9748..5f33500 100644 --- a/photo_app/models.py +++ b/photo_app/models.py @@ -27,9 +27,7 @@ class Photo(models.Model): def save(self, *args, **kwargs): if not self.image: return - - super().save() - + super(Photo, self).save() im = Image.open(self.image.path) im.thumbnail((759, 759), Image.ANTIALIAS) @@ -44,8 +42,7 @@ class Photo(models.Model): im.save(fname) os.remove(self.image.path) self.image = "%s.%s" % (hs, ext) - super().save() - + super(Photo, self).save() # class Meta: # unique_together = (('image',),) From a49570fded18a77d8efcc77837f5cfa5c90acfa0 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:55:21 +0300 Subject: [PATCH 119/179] =?UTF-8?q?ajax=20=D1=82=D0=B0=D0=B1=D1=8B=20?= =?UTF-8?q?=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20=D0=BD?= =?UTF-8?q?=D1=83=D0=B6=D0=BD=D1=8B,=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B8=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/my.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/static/js/my.js b/static/js/my.js index d7be95e..34416b7 100644 --- a/static/js/my.js +++ b/static/js/my.js @@ -72,15 +72,6 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) { $(document).ready(function () { - // ajax tabs - $('.nav-tabs a').on('show.bs.tab', function (e) { - var ct = $(e.target).attr('href'); - var remoteUrl = $(this).attr('data-tab-remote'); - if (remoteUrl !== '') { - $(ct).load(remoteUrl); - } - }); - // Live html5 image preview if (window.File && window.FileReader && window.FileList && window.Blob) { $('input[type=file].live_review').on('change', function () { From 1ee557f383a752dc1bdb7c01f1535c6173e4b931 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:56:27 +0300 Subject: [PATCH 120/179] =?UTF-8?q?=D0=90=D0=B4=D0=B0=D0=BF=D1=82=D0=B5?= =?UTF-8?q?=D1=80=20=D0=B4=D0=BB=D1=8F=20calc=5Ftype=20choices=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B6=D0=BD=D0=BE=20=D0=B1=D1=8B=D0=BB=D0=BE=20=D1=83?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=D1=82=D0=B8=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tariff_app/models.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tariff_app/models.py b/tariff_app/models.py index 04aa970..0981537 100644 --- a/tariff_app/models.py +++ b/tariff_app/models.py @@ -5,21 +5,13 @@ from .custom_tariffs import TariffBase, TARIFF_CHOICES from mydefs import MyChoicesAdapter -# Класс похож на адаптер. Предназначен для Django CHOICES чтоб можно было передавать классывместо просто описания поля, -# классы передавать для того чтоб по значению из базы понять какой класс нужно взять для расчёта стоимости тарифа. -class _TariffChoicesAdapter(MyChoicesAdapter): - # На вход принимает кортеж кортежей, вложенный из 2х элементов: кода и класса, как: TARIFF_CHOICES - def __init__(self): - super().__init__(TARIFF_CHOICES) - - class Tariff(models.Model): title = models.CharField(max_length=32) descr = models.CharField(max_length=256) speedIn = models.FloatField(default=0.0) speedOut = models.FloatField(default=0.0) amount = models.FloatField(default=0.0) - calc_type = models.CharField(max_length=2, default=TARIFF_CHOICES[0][0], choices=_TariffChoicesAdapter()) + calc_type = models.CharField(max_length=2, default=TARIFF_CHOICES[0][0], choices=MyChoicesAdapter(TARIFF_CHOICES)) is_admin = models.BooleanField(default=False) # Возвращает потомок класса TariffBase, методы которого дают нужную логику оплаты по тарифу From 7fc1d0457e38532b505436c08166791ca7bdbfdc Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 13:56:56 +0300 Subject: [PATCH 121/179] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tariff_app/templates/tariff_app/tarifs.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tariff_app/templates/tariff_app/tarifs.html b/tariff_app/templates/tariff_app/tarifs.html index 70e88d6..0105d1c 100644 --- a/tariff_app/templates/tariff_app/tarifs.html +++ b/tariff_app/templates/tariff_app/tarifs.html @@ -43,10 +43,11 @@ + {% with can_ch_trf=perms.tariff_app.change_tariff can_del_trf=perms.tariff_app.delete_tariff %} {% for tar in tariflist %} - {% if perms.tariff_app.change_tariff %} + {% if can_ch_trf %} {{ tar.title }} {% else %} {{ tar.title }} @@ -57,7 +58,7 @@ {{ tar.amount }} руб {{ tar.get_calc_type_display }} - {% if perms.tariff_app.delete_tariff %} + {% if can_del_trf %} @@ -73,6 +74,7 @@ {% endfor %} + {% endwith %} {% if perms.tariff_app.add_tariff %} From e83b4baefcad7a858a93813ffd61f43587bb769c Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 16:30:58 +0300 Subject: [PATCH 122/179] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/migrations/0021_auto_20170705_1403.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 abonapp/migrations/0021_auto_20170705_1403.py diff --git a/abonapp/migrations/0021_auto_20170705_1403.py b/abonapp/migrations/0021_auto_20170705_1403.py new file mode 100644 index 0000000..16a2a15 --- /dev/null +++ b/abonapp/migrations/0021_auto_20170705_1403.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-07-05 14:03 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('devapp', '0006_auto_20170705_1403'), + ('abonapp', '0020_auto_20170517_1655'), + ] + + operations = [ + migrations.RemoveField( + model_name='abon', + name='opt82', + ), + migrations.DeleteModel( + name='Opt82', + ), + migrations.AddField( + model_name='abon', + name='dev_port', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Port'), + ), + migrations.AddField( + model_name='abon', + name='device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), + ), + migrations.AddField( + model_name='abon', + name='is_dynamic_ip', + field=models.BooleanField(default=False), + ), + migrations.DeleteModel( + name='AbonDevice', + ), + ] From 869f7d8ca1aa322c070619a0653441c18dc7d7b4 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 16:32:55 +0300 Subject: [PATCH 123/179] =?UTF-8?q?=D0=9F=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/migrations/0002_statcache.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/statistics/migrations/0002_statcache.py b/statistics/migrations/0002_statcache.py index 4710120..391ea4e 100644 --- a/statistics/migrations/0002_statcache.py +++ b/statistics/migrations/0002_statcache.py @@ -28,4 +28,7 @@ class Migration(migrations.Migration): 'db_table': 'flowcache', }, ), + migrations.DeleteModel( + name='StatElem', + ), ] From ced88f1d1670888a4fbaf33295f47f793e66f182 Mon Sep 17 00:00:00 2001 From: bashmak Date: Wed, 5 Jul 2017 16:33:34 +0300 Subject: [PATCH 124/179] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=B0=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/migrations/0006_auto_20170705_1403.py | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 devapp/migrations/0006_auto_20170705_1403.py diff --git a/devapp/migrations/0006_auto_20170705_1403.py b/devapp/migrations/0006_auto_20170705_1403.py new file mode 100644 index 0000000..33d3b75 --- /dev/null +++ b/devapp/migrations/0006_auto_20170705_1403.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-07-05 14:03 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import djing.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('devapp', '0005_auto_20170502_2232'), + ] + + operations = [ + migrations.RemoveField( + model_name='portstates', + name='port', + ), + migrations.RemoveField( + model_name='port', + name='speed', + ), + migrations.AddField( + model_name='device', + name='mac_addr', + field=djing.fields.MACAddressField(blank=True, integer=True, null=True, unique=True), + ), + migrations.AddField( + model_name='device', + name='parent_dev', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), + ), + migrations.AddField( + model_name='port', + name='descr', + field=models.CharField(blank=True, max_length=60, null=True), + ), + migrations.AlterField( + model_name='device', + name='devtype', + field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT'), ('On', 'PON ONU')], default='Dl', max_length=2), + ), + migrations.DeleteModel( + name='PortStates', + ), + ] From c5b05225394b483f37953ec9f38dec2efbc42bd5 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 6 Jul 2017 16:03:55 +0300 Subject: [PATCH 125/179] =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BB?= =?UTF-8?q?=D0=B8=D1=88=D0=BD=D0=B8=D0=B9=20=D0=B8=D0=BC=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/commands/dhcp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/agent/commands/dhcp.py b/agent/commands/dhcp.py index 8fe1579..fd39c4e 100644 --- a/agent/commands/dhcp.py +++ b/agent/commands/dhcp.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from builtins import print from django.core.exceptions import MultipleObjectsReturned from django.utils.translation import ugettext as _ from abonapp.models import Abon From 4e6365cab9ec34aac370e53a387ad847920ecf3b Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 8 Jul 2017 14:37:00 +0300 Subject: [PATCH 126/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20uptime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/olt.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/devapp/templates/devapp/olt.html b/devapp/templates/devapp/olt.html index f47a296..0e7fa10 100644 --- a/devapp/templates/devapp/olt.html +++ b/devapp/templates/devapp/olt.html @@ -6,6 +6,9 @@
    + {% if uptime %} + {% trans 'Uptime' %} {{ uptime }} + {% endif %} From 6d02eb304a805b89782ed3a8e6e44b5ab9caa023 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 8 Jul 2017 14:37:27 +0300 Subject: [PATCH 127/179] =?UTF-8?q?=D0=B2=D1=8B=D1=80=D0=B0=D0=B2=D0=BD?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BB=D0=BE=D0=B3=D0=BE=D1=82=D0=B8=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/css/custom.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static/css/custom.css b/static/css/custom.css index 78c1330..06e30fb 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -247,3 +247,8 @@ button[data-toggle=offcanvas]{ * Сужаем аудио элемент чтоб скрыть большинство контролов */ audio{width: 100px;} + +a.navbar-brand { + padding-left: 88px; +} + From d1fa4a35c8773a187670962afc1ad47de9f874e2 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 16:58:36 +0300 Subject: [PATCH 128/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=20title=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D0=B8?= =?UTF-8?q?=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=B0?= =?UTF-8?q?=20=D0=BC=D0=B0=D0=BA=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B0.=20=D0=98=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=80=D1=82=D0=B0=20=D0=B2=20=D1=81=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=BE=D0=BA=20=D0=BF=D0=BE=D1=80=D1=82=D0=BE=D0=B2=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/templates/abonapp/editAbon.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index 1ee030e..e3b2bcc 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -140,7 +140,7 @@
    {% if device %} - + {{ device.comment|truncatechars:11 }} {{ device.ip_address }} @@ -162,9 +162,9 @@ {% for port in dev_ports %} {% if port == abon.dev_port %} - + {% else %} - + {% endif %} {% empty %} From 69abcc31a73ddf016ecdfc1e1d0ba2c067860d4e Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 17:01:07 +0300 Subject: [PATCH 129/179] =?UTF-8?q?FIXBUG:=20=D0=BA=D0=BE=D0=B3=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20=D0=B2=D1=8B=D0=B1=D1=80=D0=B0=D0=BD=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=82=20=D1=82=D0=BE=20=D0=B2=D1=8B=D0=BB?= =?UTF-8?q?=D0=B5=D1=82=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/abonapp/views.py b/abonapp/views.py index 5ed1b9e..2771ee5 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -851,10 +851,13 @@ def save_user_dev_port(request, gid, uid): if request.method != 'POST': messages.error(request, _('Method is not POST')) return redirect('abonapp:abon_home', gid, uid) - user_port = request.POST.get('user_port') + user_port = mydefs.safe_int(request.POST.get('user_port')) is_dynamic_ip = request.POST.get('is_dynamic_ip') try: - port = DevPort.objects.get(pk=user_port) + if user_port == 0: + port = None + else: + port = DevPort.objects.get(pk=user_port) abon = models.Abon.objects.get(pk=uid) abon.dev_port = port if abon.is_dynamic_ip != is_dynamic_ip: From 2c0e35c524943a9127df8a46181da715608ef664 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 17:02:10 +0300 Subject: [PATCH 130/179] =?UTF-8?q?FIXBUG:=20=D0=BA=D0=BE=D0=B3=D0=B4?= =?UTF-8?q?=D0=B0=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=BE=20=D0=BD=D0=B5=20=D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF?= =?UTF-8?q?=D0=BD=D0=BE,=20=D1=82=D0=BE=20=D0=BD=D0=B5=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=B0=D1=82=D1=8B=D0=B2=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D1=81=D1=8C=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BE=D0=B1=20=D1=8D=D1=82=D0=BE=D0=BC=20=D0=B8?= =?UTF-8?q?=20=D0=B2=D1=8B=D0=BB=D0=B5=D1=82=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/devapp/views.py b/devapp/views.py index 6c65228..2d0a23b 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -154,6 +154,7 @@ def add_ports(request, devid): return "p:%d\tM:%s\tT:%s" % (self.pid, self.text) try: + res_ports = list() dev = Device.objects.get(pk=devid) if dev.user_group is None: messages.error(request, _('Device is not have a group, please fix that')) @@ -193,6 +194,8 @@ def add_ports(request, devid): return redirect('devapp:group_list') except DeviceDBException as e: messages.error(request, e) + except EasySNMPTimeoutError: + messages.error(request, _('wait for a reply from the SNMP Timeout')) return render(request, 'devapp/manage_ports/add_ports.html', { 'ports': res_ports, 'dev': dev From ed08ba5449dd98724365d00e9f114f15586bf913 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 17:06:05 +0300 Subject: [PATCH 131/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=B5=D1=81=D0=BB=D0=B8=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=BE=20=D0=BD=D0=B5=20=D0=B4=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=83=D0=BF=D0=BD=D0=BE=20=D0=BD=D0=B0=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D0=B5=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D1=80=D1=82?= =?UTF-8?q?=D0=BE=D0=B2,=20=D1=82=D0=BE=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BD=D0=B5=20=D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BD?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/manage_ports/add_ports.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/devapp/templates/devapp/manage_ports/add_ports.html b/devapp/templates/devapp/manage_ports/add_ports.html index 0addfc8..33bb77c 100644 --- a/devapp/templates/devapp/manage_ports/add_ports.html +++ b/devapp/templates/devapp/manage_ports/add_ports.html @@ -70,10 +70,14 @@
    From ba60bb6cafe8893cf49498878b11171c7a4b2ba3 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 17:21:42 +0300 Subject: [PATCH 132/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D1=81=D1=8B=D0=BB=D1=8C=20=D0=BD=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D0=B0,=20=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D0=BA=D0=BE=D0=B5=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE,?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=B4=D0=BF=D0=B8=D1=81=D0=B8=20=D1=87=D1=82?= =?UTF-8?q?=D0=BE=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B8=D1=82=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=B6=D0=B4=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/devapp/custom_dev_page/onu.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/devapp/templates/devapp/custom_dev_page/onu.html b/devapp/templates/devapp/custom_dev_page/onu.html index 85c02f5..0a70d20 100644 --- a/devapp/templates/devapp/custom_dev_page/onu.html +++ b/devapp/templates/devapp/custom_dev_page/onu.html @@ -14,16 +14,25 @@
    From b581b2533c0c02bb20325dc042767fd2b00bd6f0 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 13 Jul 2017 17:22:38 +0300 Subject: [PATCH 133/179] =?UTF-8?q?=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=D0=BE=D0=B2..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/locale/ru/LC_MESSAGES/django.po | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index edc5c92..2ba0d21 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -1,4 +1,3 @@ -# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE"S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Dmitry Novikov nerosketch@gmail.com, 2017. @@ -33,7 +32,7 @@ msgstr "не нашёл мак" #: devapp/dev_types.py:116 msgid "PON OLT" -msgstr "ONU Голова" +msgstr "PON OLT голова" #: devapp/templates/devapp/add_dev.html:7 #: devapp/templates/devapp/devices.html:7 @@ -283,3 +282,10 @@ msgstr "MAC-адрес необходим для заполнения" msgid "Device with that mac is already exist" msgstr "Устройство с этим мак-адресом уже есть" + +msgid "Parent device" +msgstr "Родительское устройство" + +msgid "Attached user" +msgstr "Прикрепленный абонент" + From fb3fb799af90955debb4c9de935a60dd3e22ba2e Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 15 Jul 2017 10:25:01 +0300 Subject: [PATCH 134/179] =?UTF-8?q?FIXBUG:=20=D0=B2=D1=8B=D0=BB=D0=B5?= =?UTF-8?q?=D1=82=D0=B0=D0=BB=D0=BE=20=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=8B=D1=82=D0=B0=D0=B5=D0=BC=D1=81=D1=8F=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=D1=82=D1=8C=20=D0=B8=20=D0=BD=D0=B5=20=D0=B0=D0=B2?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- searchapp/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/searchapp/views.py b/searchapp/views.py index e9155fe..4e5a8d4 100644 --- a/searchapp/views.py +++ b/searchapp/views.py @@ -4,12 +4,14 @@ from django.shortcuts import render from django.utils.html import escape from abonapp.models import Abon from mydefs import ip_addr_regex +from django.contrib.auth.decorators import login_required def replace_without_case(orig, old, new): return re.sub(old, new, orig, flags=re.IGNORECASE) +@login_required def home(request): s = request.GET.get('s') s = s.replace('+', '') From b113b23dfd306f1970842da7a6eb1ba053b21e95 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 15 Jul 2017 10:26:23 +0300 Subject: [PATCH 135/179] =?UTF-8?q?FIXBUG:=20=D0=BD=D0=B5=20=D0=B2=D0=B8?= =?UTF-8?q?=D0=B4=D0=BD=D0=BE=20=D0=B1=D1=8B=D0=BB=D0=BE=20=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D0=BC=D1=83=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/all_base.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/templates/all_base.html b/templates/all_base.html index 7c66202..956692e 100644 --- a/templates/all_base.html +++ b/templates/all_base.html @@ -44,9 +44,6 @@ - {% url 'client_side:home' as client_url %} - Кабинет клиента -
    - {% if perms.devapp.add_port %} + {% if perms.devapp.add_port and ports %} + {% else %} + {% endif %}
    @@ -31,10 +21,14 @@ {% for log in logs %} - diff --git a/dialing_app/templates/vmail.html b/dialing_app/templates/vmail.html new file mode 100644 index 0000000..fb4169a --- /dev/null +++ b/dialing_app/templates/vmail.html @@ -0,0 +1,57 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,ext.html' %} +{% load i18n %} +{% load telephone_filters %} +{% block content %} + +
    +
    - + + + + + {{ log.calldate|date:'d E Y, H:i:s' }} {{ log.src|abon_if_telephone|safe }}
    + + + + + + + + + + + + + + + {% for vmail in vmessages %} + + + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
    {% trans 'Play' %}{% trans 'calldate' %}{% trans 'src' %}{% trans 'Type' %}{% trans 'duration' %}{% trans 'start' %}{% trans 'answer' %}{% trans 'end' %}{% trans 'disposition' %}
    + + + + + {{ vmail.calldate|date:'d E Y, H:i:s' }}{{ vmail.src|abon_if_telephone|safe }} + {% if vmail.userfield == 'request' %}{% trans 'Request' %} + {% elif vmail.userfield == 'report' %}{% trans 'Report' %} + {% else %}{{ vmail.userfield }}{% endif %} + {{ vmail.duration }}{{ vmail.start|date:'d E Y, H:i:s' }}{{ vmail.answer|date:'d E Y, H:i:s' }}{{ vmail.end|date:'d E Y, H:i:s' }}{{ vmail.locate_disposition }}
    {% trans 'Calls was not found' %}
    +
    + + {% include 'toolbar_page.html' with pag=vmessages %} + +{% endblock %} diff --git a/dialing_app/urls.py b/dialing_app/urls.py index 20b529f..a35f0e2 100644 --- a/dialing_app/urls.py +++ b/dialing_app/urls.py @@ -4,5 +4,6 @@ from . import views urlpatterns = [ url(r'^$', views.home, name='home'), - url(r'^to_abon(?P\+?\d+)$', views.to_abon, name='to_abon') + url(r'^to_abon(?P\+?\d+)$', views.to_abon, name='to_abon'), + url(r'^voicemail$', views.vmail, name='vmail') ] diff --git a/dialing_app/views.py b/dialing_app/views.py index 9125ccc..a190c23 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -13,8 +13,10 @@ from .models import AsteriskCDR def home(request): logs = AsteriskCDR.objects.order_by('-calldate') logs = pag_mn(request, logs) + title = _('Last calls') return render(request, 'index.html', { - 'logs': logs + 'logs': logs, + 'title': title }) @@ -34,3 +36,14 @@ def to_abon(request, tel): else: return redirect('abonapp:group_list') + +@login_required +@only_admins +def vmail(request): + title = _('Voice mail') + cdr = AsteriskCDR.objects.filter(userfield='request').order_by('-calldate') + cdr = pag_mn(request, cdr) + return render(request, 'vmail.html', { + 'title': title, + 'vmessages': cdr + }) \ No newline at end of file diff --git a/static/js/my.js b/static/js/my.js index 34416b7..7dc9601 100644 --- a/static/js/my.js +++ b/static/js/my.js @@ -40,7 +40,6 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) { var hr = a.attr('href'); var tx = a.text(); selecthid.val(hr.substr(1)); - console.debug(tx); selectbtn.text(tx).removeClass('hidden'); selectinp.addClass('hidden').val(tx); }; @@ -70,6 +69,54 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) { })(jQuery); +// AudioPlayer +(function ($) { + $.fn.aplayer = function(){ + + var def_play = function(e){ + var audiotag = e.data['audiotag'][0]; + + if(audiotag.readyState == 0){ + $(this).prop('disabled', true); + return; + }else + $(this).prop('disabled', false); + + if(audiotag.paused) + audiotag.play(); + else + audiotag.pause(); + }; + + var def_canplay = function(){ + var els = $(this).parent(); + els.prop('disabled', false).removeClass('disabled'); + els.siblings().prop('disabled', false).removeClass('disabled'); + }; + + var def_on_play = function(){ + $(this).siblings('span.glyphicon').attr('class', 'glyphicon glyphicon-pause'); + }; + + var def_on_pause = function(){ + $(this).siblings('span.glyphicon').attr('class', 'glyphicon glyphicon-play'); + }; + + this.each(function(){ + var i = $(this); + var audiotag = i.children('audio'); + var icon = i.children('span.glyphicon'); + i.on('click', {'audiotag': audiotag}, def_play); + audiotag.on('canplay', def_canplay); + audiotag.on('play', def_on_play); + audiotag.on('pause', def_on_pause); + }); + + }; +})(jQuery); + + + $(document).ready(function () { // Live html5 image preview @@ -138,6 +185,8 @@ $(document).ready(function () { self.html(r.dat); }); return false; - }) + }); + + $('button.player-btn').aplayer(); }); From 603c73cbe485373e81e4be69c2263d16d323323e Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 17 Jul 2017 15:36:02 +0300 Subject: [PATCH 140/179] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=83=D1=82=D0=B8=D0=BB=D0=B8,=20=D0=BE=D0=BD=D0=B8=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B=20=D0=B1=D0=BE=D0=BB?= =?UTF-8?q?=D0=B5=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- djing/utils/load_dot_from_nodeny.py | 32 ---- djing/utils/load_from_nodeny.py | 92 --------- djing/utils/push_snmp_passw.py | 45 ----- djing/utils/save_dot_from_nodeny.py | 29 --- djing/utils/save_from_nodeny.py | 280 ---------------------------- 5 files changed, 478 deletions(-) delete mode 100644 djing/utils/load_dot_from_nodeny.py delete mode 100755 djing/utils/load_from_nodeny.py delete mode 100644 djing/utils/push_snmp_passw.py delete mode 100644 djing/utils/save_dot_from_nodeny.py delete mode 100755 djing/utils/save_from_nodeny.py diff --git a/djing/utils/load_dot_from_nodeny.py b/djing/utils/load_dot_from_nodeny.py deleted file mode 100644 index e8310d7..0000000 --- a/djing/utils/load_dot_from_nodeny.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/env python3 -# coding=utf-8 - -import os -import MySQLdb -from json import dumps - - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") - - db = MySQLdb.connect(host="localhost", user="root", passwd="ps", db="nodeny", charset='utf8') - cursor = db.cursor() - - result = dict() - - # выбираем абонентов - sql = r"SELECT location, descr FROM places WHERE location LIKE 'Сад_%'" - cursor.execute(sql) - places = list() - res = cursor.fetchone() - while res: - places.append({ - 'loc': res[0], - 'descr': res[1] - }) - res = cursor.fetchone() - - db.close() - f = open('../../places.json', 'w') - f.write(dumps(places, ensure_ascii=False).encode('utf8')) - f.close() diff --git a/djing/utils/load_from_nodeny.py b/djing/utils/load_from_nodeny.py deleted file mode 100755 index c8aa523..0000000 --- a/djing/utils/load_from_nodeny.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/env python3 -# coding=utf-8 - -import MySQLdb -from json import dumps, loads - - -def param_to_python(st): - st = st.replace('$VAR1 = ', '') - st = st.replace("'", '"') - st = st.replace(" =>", ':') - st = st.replace(";", '') - return loads(st) - - -def load_service(cursor, uid): - sql = "SELECT services.title, services.service_id, services.price, services.description, services.param " \ - "FROM services LEFT JOIN users_services ON " \ - "(users_services.service_id=services.service_id) WHERE users_services.uid=%d" % uid - cursor.execute(sql) - service_line = cursor.fetchone() - if service_line is not None: - service = { - 'title': service_line[0], - 'service_id': service_line[1], - 'price': service_line[2], - 'description': service_line[3], - 'param': param_to_python(service_line[4]) - } - else: - service = None - return service - - -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, " \ - "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], - 'fio': res[1], - 'tel': res[2], - 'street': str(res[3] or ''), - 'house': str(res[4]), - 'birth': res[5], - 'grp': int(res[6]), - '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])), - 'opt82': { - 'dev_mac': res[11], - 'dev_port': res[12], - 'oneconnect': res[13] - } - } for res in cursor.fetchall()] - return users - - -def load_groups(cursor): - # выбираем группы - sql = r'SELECT grp_id, grp_name FROM user_grp' - cursor.execute(sql) - groups = list() - for res in cursor.fetchall(): - users = load_users(cursor=cursor, grp_id=int(res[0])) - groups.append({ - 'gid': int(res[0]), - 'gname': res[1], - 'users': users - }) - return groups - - - -if __name__ == "__main__": - db = MySQLdb.connect(host="127.0.0.1", user="user", passwd="password", db="db", charset='utf8') - cursor = db.cursor() - - result = dict() - - result = load_groups(cursor=cursor) - db.close() - f = open('dump.json', 'w') - f.write(dumps(result, ensure_ascii=False)) - f.close() diff --git a/djing/utils/push_snmp_passw.py b/djing/utils/push_snmp_passw.py deleted file mode 100644 index 7d9d181..0000000 --- a/djing/utils/push_snmp_passw.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -import telnetlib -from mydefs import ping -from socket import error -from multiprocessing import Process - - -# Пробуем настроить свичи через telnet на snmp - - -def cmd(ip): - tn = telnetlib.Telnet(ip) - tn.read_until("login: ") - tn.write("\n") - tn.read_until("Password: ") - tn.write("\n") - - tn.write("create snmp community ertNjuWr ReadWrite\n") - tn.write("save\n") - tn.write("save config\n") - tn.write("save config config_id 1\n") - - tn.write("log\n") - print((tn.read_all())) - tn.close() - - -def prc(ip): - try: - if ping(ip): - cmd(ip) - except error: - print(('Error connect to', ip)) - - -if __name__ == '__main__': - proc_list = list() - with open('swips.txt', 'r') as f: - for ln in f: - ip = ln.strip() - p = Process(target=prc, args=(ip,)) - p.start() - proc_list.append(p) - for proc in proc_list: - proc.join() diff --git a/djing/utils/save_dot_from_nodeny.py b/djing/utils/save_dot_from_nodeny.py deleted file mode 100644 index e58f844..0000000 --- a/djing/utils/save_dot_from_nodeny.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/env python3 -# coding=utf-8 - -import os -from json import load -import django - - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") - django.setup() - from devapp.models import Device - - with open('../../places.json', 'r') as f: - dat = load(f) - - for dt in dat: - if dt['descr']: - dt['descr']=dt['descr'].replace('10.15.', '10.115.') - dt['loc']=dt['loc'].encode('utf8') - try: - dev = Device.objects.get(ip_address=dt['descr']) - except Device.DoesNotExist: - dev = Device( - ip_address=dt['descr'] - ) - dev.comment=dt['loc'] - dev.save() - print((dt['descr'], dt['loc'], dev)) diff --git a/djing/utils/save_from_nodeny.py b/djing/utils/save_from_nodeny.py deleted file mode 100755 index ab5cc4b..0000000 --- a/djing/utils/save_from_nodeny.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/bin/env python3 -# coding=utf-8 - -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, Opt82 -from ip_pool.models import IpPoolItem -from tariff_app.models import Tariff - - -class DumpService(object): - price = 0.0 - speedIn = 0.0 - speedOut = 0.0 - - def __init__(self, obj=None): - if obj is None: return - self.title = obj['title'] - self.price = obj['price'] - self.description = obj['description'] - self.speedIn = int(obj['param']['speed_in1']) / 1000000 - self.speedOut = int(obj['param']['speed_out1']) / 1000000 - - @staticmethod - def build_from_db(obj): - self = DumpService() - self.title = obj.title - self.price = obj.amount - self.description = obj.descr - self.speedIn = obj.speedIn - self.speedOut = obj.speedOut - return self - - def __eq__(self, other): - assert isinstance(other, DumpService) - print('DBG:', type(other.price), other.price, type(self.price), self.price) - r = self.price == other.price - r = r and self.speedIn == other.speedIn - r = r and self.speedOut == other.speedOut - return r - - def __ne__(self, other): - return not self.__eq__(other) - - def __str__(self): - return "%s; '%.2f', %f %f" % (self.title, self.price, self.speedIn, self.speedOut) - - -class DumpAbon(object): - - def __init__(self, obj=None): - if obj is None: return - self.name = obj['name'] - self.fio = obj['fio'] - self.tel = obj['tel'] - self.street = obj['street'] - self.house = obj['house'] - self.birth = obj['birth'] - self.grp = obj['grp'] - 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: - self.service = None - - @staticmethod - def build_from_django(obj): - assert isinstance(obj, Abon) - self = DumpAbon() - self.name = obj.username - self.fio = obj.fio - self.tel = obj.telephone - self.street = obj.street - self.house = obj.house - self.birth = obj.birth_day - if obj.group is None: - self.grp = None - else: - self.grp = obj.group.pk - if obj.ip_address is None: - self.ip = None - else: - self.ip = obj.ip_address - self.balance = obj.ballance - try: - raw_passw = AbonRawPassword.objects.get(account=obj) - except AbonRawPassword.DoesNotExist: - raw_passw = '' - self.passw = raw_passw - srv = obj.active_tariff() - if srv is not None: - 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): - assert isinstance(other, DumpAbon) - r = self.name == other.name - r = r and self.name == other.name - r = r and self.fio == other.fio - r = r and self.tel == other.tel - r = r and self.street == other.street - r = r and self.house == other.house - r = r and self.birth == other.birth - r = r and self.grp == other.grp - r = r and self.ip == other.ip - r = r and self.balance == other.ballance - return r - - def __ne__(self, other): - return not self.__eq__(other) - - -def add_service_if_not_exist(service): - assert isinstance(service, DumpService) - try: - obj = Tariff.objects.get(speedIn=service.speedIn, speedOut=service.speedOut, amount=service.price) - except Tariff.DoesNotExist: - obj = Tariff.objects.create( - title=service.title, - descr=service.description, - speedIn=service.speedIn, - speedOut=service.speedOut, - amount=service.price, - calc_type='Dp' - ) - 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 - for usr in obj: - # абонент из дампа - dump_abon = DumpAbon(usr) - # абонент из биллинга - print('\t', dump_abon.name, dump_abon.fio, dump_abon.ip) - try: - abon = Abon.objects.get(username=dump_abon.name) - bl_abon = DumpAbon.build_from_django(abon) - if bl_abon != dump_abon: - update_user(abon, dump_abon, 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: - continue - abon_service = add_service_if_not_exist(abon_service_from_dump) - try: - AbonTariff.objects.get(abon=abon, tariff=abon_service) - except AbonTariff.DoesNotExist: - calc_obj = abon_service.get_calc_type()(abon_service) - AbonTariff.objects.create( - abon=abon, - tariff=abon_service, - 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): - assert isinstance(obj, DumpAbon) - street = None - ip = None - try: - if obj.ip is not None: - ip = IpPoolItem.objects.get(ip=obj.ip) - street = AbonStreet.objects.get(name=obj.street, group=user_group) - except IpPoolItem.DoesNotExist: - if obj.ip is not None: - ip = IpPoolItem.objects.create(ip=obj.ip) - except AbonStreet.DoesNotExist: - street = AbonStreet.objects.create(name=obj.street, group=user_group) - - 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): - assert isinstance(obj, DumpAbon) - assert isinstance(db_abon, Abon) - street = None - ip = None - try: - if obj.ip is not None: - ip = IpPoolItem.objects.get(ip=obj.ip) - street = AbonStreet.objects.get(name=obj.street, group=user_group) - except IpPoolItem.DoesNotExist: - if obj.ip is not None: - ip = IpPoolItem.objects.create(ip=obj.ip) - except AbonStreet.DoesNotExist: - street = AbonStreet.objects.create(name=obj.street, group=user_group) - db_abon.fio = obj.fio - db_abon.telephone = obj.tel - db_abon.street = street - db_abon.house = obj.house - #db_abon.birth_day = datetime(obj.birth) - 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__": - - with open('dump.json', 'r') as f: - dat = load(f) - - for grp in dat: - try: - abgrp=AbonGroup.objects.get(title=grp['gname']) - except AbonGroup.DoesNotExist: - abgrp = AbonGroup.objects.create( - title=grp['gname'] - ) - print(grp['gname']) - load_users(grp['users'], abgrp) From 3409a967f7ff3c241a74d69d62f6a3219c10431b Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 17 Jul 2017 15:36:47 +0300 Subject: [PATCH 141/179] =?UTF-8?q?=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D1=81=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D1=81=D0=BA=D0=BE=D0=B9=20=D1=83?= =?UTF-8?q?=D1=87=D1=91=D1=82=D0=BA=D0=B8=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=8C=20=D0=B0=D0=B4=D0=B0=D0=BF=D1=82=D0=B8=D0=B2=D0=BD=D0=B0?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts_app/templates/accounts/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/accounts_app/templates/accounts/index.html b/accounts_app/templates/accounts/index.html index 1ab3684..b90ee3b 100644 --- a/accounts_app/templates/accounts/index.html +++ b/accounts_app/templates/accounts/index.html @@ -2,6 +2,7 @@ {% load i18n %} {% block content %} +
    @@ -32,5 +33,6 @@ {% endif %}
    +
    -{% endblock %} \ No newline at end of file +{% endblock %} From 9b86f8cf891b3d964d1d095ef3db24be184dba14 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 22 Jul 2017 11:07:46 +0300 Subject: [PATCH 142/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B8=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8E=20tooltip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/my.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/js/my.js b/static/js/my.js index 7dc9601..082f437 100644 --- a/static/js/my.js +++ b/static/js/my.js @@ -189,4 +189,6 @@ $(document).ready(function () { $('button.player-btn').aplayer(); + $('[data-toggle="tooltip"]').tooltip({container:'body'}); + }); From cba5321760cbf8c08efdae9eed24d2682702e910 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 22 Jul 2017 11:08:40 +0300 Subject: [PATCH 143/179] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B=D1=83=D1=8E=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D1=81=D0=BA=D0=B0=D0=B7=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taskapp/templates/taskapp/footer_btns.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskapp/templates/taskapp/footer_btns.html b/taskapp/templates/taskapp/footer_btns.html index ae9c76e..add4901 100644 --- a/taskapp/templates/taskapp/footer_btns.html +++ b/taskapp/templates/taskapp/footer_btns.html @@ -1,6 +1,6 @@ {% load i18n %} {% if perms.taskapp.add_task %} - + {% trans 'Add new task' %} {% endif %} From 157fec76d1554a48590a4396f3a2f1172cd0821f Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 22 Jul 2017 11:35:32 +0300 Subject: [PATCH 144/179] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20"=D0=BD=D0=B0=20=D0=B2=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8"=20=D0=BD=D0=B0=20"=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=D0=B5=D0=BD=D0=BE".=20=D0=A1=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=8F=D0=BD=D0=B8=D0=B5=D0=BC=20"=D0=BD=D0=B0=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D1=82=D0=BE=20=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D1=83=D0=B5=D1=82=D1=81=D1=8F",=20=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D1=87=D0=B0=D1=82=D1=8C=20=D0=B7=D0=B0=D0=B4?= =?UTF-8?q?=D0=B0=D1=87=D0=B8=20=D0=BA=D0=B0=D0=BA=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B6=D0=B5=D1=82=20=D0=BF=D1=80=D0=B8=D0=B3=D0=BE=D0=B4=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taskapp/models.py | 8 ++++---- taskapp/templates/taskapp/ext.htm | 14 +++++++------- taskapp/templates/taskapp/tasklist.html | 18 +++++++++--------- taskapp/templates/taskapp/tasklist_all.html | 16 +++++++++------- ...klist_active.html => tasklist_failed.html} | 12 ++++++------ .../templates/taskapp/tasklist_finish.html | 19 +++++++------------ taskapp/templates/taskapp/tasklist_own.html | 2 +- taskapp/templates/taskapp/view.html | 10 +++++----- taskapp/urls.py | 4 ++-- taskapp/views.py | 10 +++++----- 10 files changed, 55 insertions(+), 58 deletions(-) rename taskapp/templates/taskapp/{tasklist_active.html => tasklist_failed.html} (84%) diff --git a/taskapp/models.py b/taskapp/models.py index e484e04..f4db733 100644 --- a/taskapp/models.py +++ b/taskapp/models.py @@ -18,7 +18,7 @@ TASK_PRIORITIES = ( TASK_STATES = ( ('S', _('New')), - ('C', _('In fulfilling')), + ('C', _('Confused')), ('F', _('Completed')) ) @@ -44,7 +44,7 @@ class ChangeLog(models.Model): ('c', _('Create task')), ('d', _('Delete task')), ('f', _('Completing tasks')), - ('b', _('The task started')) + ('b', _('The task failed')) ) act_type = models.CharField(max_length=1, choices=ACT_CHOICES) when = models.DateTimeField(auto_now_add=True) @@ -89,8 +89,8 @@ class Task(models.Model): ) self.save(update_fields=['state', 'out_date']) - def begin(self, current_user): - self.state = 'C' # Начата + def do_fail(self, current_user): + self.state = 'C' # Провалена ChangeLog.objects.create( task=self, act_type='b', diff --git a/taskapp/templates/taskapp/ext.htm b/taskapp/templates/taskapp/ext.htm index c955a40..04412ba 100644 --- a/taskapp/templates/taskapp/ext.htm +++ b/taskapp/templates/taskapp/ext.htm @@ -23,13 +23,6 @@
  • - {% url 'taskapp:active_tasks' as taskactive %} - - - {% trans 'Active tasks' %} - - - {% url 'taskapp:finished_tasks' as taskfin %} @@ -44,6 +37,13 @@ + {% url 'taskapp:failed_tasks' as taskfailed %} + + + {% trans 'Failed tasks' %} + + + {% url 'taskapp:my_tasks' as taskmy %} diff --git a/taskapp/templates/taskapp/tasklist.html b/taskapp/templates/taskapp/tasklist.html index 7788eaa..a14091c 100644 --- a/taskapp/templates/taskapp/tasklist.html +++ b/taskapp/templates/taskapp/tasklist.html @@ -33,7 +33,7 @@ {% endif %} {% endif %} - {{ task.id }} + {{ task.pk }} {% if task.abon and task.abon.group %} {{ task.abon.get_full_name }} @@ -45,19 +45,19 @@ {{ task.get_mode_display }} {{ task.descr }} - {{ task.author.username }} - {{ task.time_of_create|date:'d N Y H:i:s' }} + {{ task.time_of_create|date:'d E H:i' }} - - - - - + + + + + {% if perms.taskapp.change_task %} - + {% endif %} diff --git a/taskapp/templates/taskapp/tasklist_all.html b/taskapp/templates/taskapp/tasklist_all.html index 6878c2a..710efc1 100644 --- a/taskapp/templates/taskapp/tasklist_all.html +++ b/taskapp/templates/taskapp/tasklist_all.html @@ -46,7 +46,7 @@ {% endif %} {% endif %} - {{ task.id }} + {{ task.pk }} {% if task.abon and task.abon.group %} {{ task.abon.get_full_name }} @@ -59,22 +59,24 @@ {{ task.get_mode_display }} {{ task.descr }} {% if task.author %} - {{ task.author.username }} + + {{ task.author.username }} + {% else %} {% trans 'Not assigned' %} {% endif %} {{ task.get_state_display }} - {{ task.time_of_create|date:'d N Y H:i:s' }} + {{ task.time_of_create|date:'d E H:i' }} - + {% if perms.taskapp.change_task %} - + {% endif %} {% if perms.taskapp.can_remind %} - + {% endif %} @@ -90,7 +92,7 @@ {% if perms.taskapp.add_task %} - + {% trans 'Add new task' %} {% endif %} diff --git a/taskapp/templates/taskapp/tasklist_active.html b/taskapp/templates/taskapp/tasklist_failed.html similarity index 84% rename from taskapp/templates/taskapp/tasklist_active.html rename to taskapp/templates/taskapp/tasklist_failed.html index c325927..d93402d 100644 --- a/taskapp/templates/taskapp/tasklist_active.html +++ b/taskapp/templates/taskapp/tasklist_failed.html @@ -33,7 +33,7 @@ {% endif %} {% endif %} - {{ task.id }} + {{ task.pk }} {% if task.abon and task.abon.group %} {{ task.abon.get_full_name }} @@ -45,16 +45,16 @@ {{ task.get_mode_display }} {{ task.descr }} - {{ task.author.username }} - {{ task.time_of_create|date:'d N Y H:i:s' }} + {{ task.time_of_create|date:'d E H:i' }} - - + + {% if perms.taskapp.change_task %} - + {% endif %} diff --git a/taskapp/templates/taskapp/tasklist_finish.html b/taskapp/templates/taskapp/tasklist_finish.html index 3dab8a6..70caf9e 100644 --- a/taskapp/templates/taskapp/tasklist_finish.html +++ b/taskapp/templates/taskapp/tasklist_finish.html @@ -8,12 +8,12 @@ # {% trans 'Name' %} - {% trans 'Address' %} + {% trans 'Address' %} {% trans 'The nature of the damage' %} {% trans 'Description' %} {% trans 'Task author' %} {% trans 'Date of create' %} - {% trans 'Actions' %} + # @@ -33,7 +33,7 @@ {% endif %} {% endif %} - {{ task.id }} + {{ task.pk }} {% if task.abon and task.abon.group %} {{ task.abon.get_full_name }} @@ -45,21 +45,16 @@ {{ task.get_mode_display }} {{ task.descr }} - {{ task.author.username }} - {{ task.time_of_create|date:'d N Y H:i:s' }} + {{ task.time_of_create|date:'d E H:i' }} - + {% if perms.taskapp.change_task %} - + {% endif %} - {% if perms.taskapp.delete_task %} - - - - {% endif %} {% empty %} diff --git a/taskapp/templates/taskapp/tasklist_own.html b/taskapp/templates/taskapp/tasklist_own.html index 030d4db..19f4348 100644 --- a/taskapp/templates/taskapp/tasklist_own.html +++ b/taskapp/templates/taskapp/tasklist_own.html @@ -46,7 +46,7 @@ {{ task.get_mode_display }} {{ task.descr }} {{ task.get_state_display }} - {{ task.time_of_create|date:'d N Y H:i:s' }} + {{ task.time_of_create|date:'d E H:i' }} {% if perms.taskapp.change_task %} diff --git a/taskapp/templates/taskapp/view.html b/taskapp/templates/taskapp/view.html index 5dfe159..0c0a927 100644 --- a/taskapp/templates/taskapp/view.html +++ b/taskapp/templates/taskapp/view.html @@ -5,7 +5,7 @@ {% include 'message_block.html' %} @@ -18,23 +18,23 @@

    {% trans 'Description' %}: {{ task.descr }}

    - {% trans 'Task author' %}: {{ task.author.username }}
    + {% trans 'Task author' %}: {{ task.author.username }}
    {% trans 'Implementers' %}: {% trans 'A priority' %}: {{ task.get_priority_display }}
    {% trans 'The task is valid until' %} {{ task.out_date|date:'d E Y' }}
    - {% trans 'Date of create' %} {{ task.time_of_create|date:'d E Y' }}
    + {% trans 'Date of create' %} {{ task.time_of_create|date:'d E Y H:i:s' }}
    {% trans 'time left' %} {{ time_diff }}
    {% trans 'Task type' %}: {{ task.get_mode_display }}
    {% trans 'Condition' %}: {{ task.get_state_display }}
    {% trans 'Subscriber' %} {% if task.abon %} - {{ task.abon.get_full_name }} + {{ task.abon.get_full_name }} {% else %} {% trans 'Not assigned' %} {% endif %}
    diff --git a/taskapp/urls.py b/taskapp/urls.py index e297e3c..e921f3b 100644 --- a/taskapp/urls.py +++ b/taskapp/urls.py @@ -9,10 +9,10 @@ urlpatterns = [ url(r'^(?P\d+)/edit$', views.task_add_edit, name='edit'), url(r'^(?P\d+)/delete$', views.task_delete, name='delete'), url(r'^(?P\d+)/fin$', views.task_finish, name='finish'), - url(r'^(?P\d+)/begin$', views.task_begin, name='begin'), + url(r'^(?P\d+)/fail$', views.task_failed, name='fail'), url(r'^(?P\d+)/remind', views.remind, name='remind'), url(r'^add$', views.task_add_edit, name='add'), - url(r'^active$', views.active_tasks, name='active_tasks'), + url(r'^failed$', views.failed_tasks, name='failed_tasks'), url(r'^finished$', views.finished_tasks, name='finished_tasks'), url(r'^own$', views.own_tasks, name='own_tasks'), url(r'^my$', views.my_tasks, name='my_tasks'), diff --git a/taskapp/views.py b/taskapp/views.py index ceb764e..c4e1966 100644 --- a/taskapp/views.py +++ b/taskapp/views.py @@ -23,10 +23,10 @@ def home(request): @login_required @only_admins -def active_tasks(request): - tasks = Task.objects.filter(recipients=request.user, state='C') # На выполнении +def failed_tasks(request): + tasks = Task.objects.filter(recipients=request.user, state='C') # Проваленные tasks = pag_mn(request, tasks) - return render(request, 'taskapp/tasklist_active.html', { + return render(request, 'taskapp/tasklist_failed.html', { 'tasks': tasks }) @@ -174,9 +174,9 @@ def task_finish(request, task_id): @login_required @only_admins -def task_begin(request, task_id): +def task_failed(request, task_id): task = get_object_or_404(Task, id=task_id) - task.begin(request.user) + task.do_fail(request.user) return redirect('taskapp:home') From 4d275cc6a871d4a91bea05077efe595beaafb1ac Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 22 Jul 2017 11:45:56 +0300 Subject: [PATCH 145/179] ref --- clientsideapp/templates/clientsideapp/ext.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clientsideapp/templates/clientsideapp/ext.html b/clientsideapp/templates/clientsideapp/ext.html index da140c9..b19ef15 100644 --- a/clientsideapp/templates/clientsideapp/ext.html +++ b/clientsideapp/templates/clientsideapp/ext.html @@ -71,13 +71,11 @@ Ваш балланс {{ subscriber.ballance }} руб. -
    - +
    -
    {% if request.user.is_staff %} From e38421dadf85929e155b2552992b35e6fae588b3 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 22 Jul 2017 11:47:00 +0300 Subject: [PATCH 146/179] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20"=D0=9F=D1=80=D0=B2=D0=BE=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE"=20=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taskapp/locale/ru/LC_MESSAGES/django.po | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/taskapp/locale/ru/LC_MESSAGES/django.po b/taskapp/locale/ru/LC_MESSAGES/django.po index 9bedd56..019c4d3 100644 --- a/taskapp/locale/ru/LC_MESSAGES/django.po +++ b/taskapp/locale/ru/LC_MESSAGES/django.po @@ -63,8 +63,8 @@ msgid "New" msgstr "Новая" #: taskapp/models.py:21 -msgid "In fulfilling" -msgstr "На выполнении" +msgid "Confused" +msgstr "Провалена" #: taskapp/models.py:22 msgid "Completed" @@ -127,8 +127,8 @@ msgid "Completing tasks" msgstr "Завершение задачи" #: taskapp/models.py:47 -msgid "The task started" -msgstr "Задача начата" +msgid "The task failed" +msgstr "Задача провалена" #: taskapp/models.py:78 msgid "Access to all tasks" @@ -281,8 +281,8 @@ msgid "User does not exist" msgstr "Абонент не найден" #: taskapp/templates/taskapp/tasklist.html:53 -msgid "Begin" -msgstr "Начать" +msgid "Mark as unsuccessful" +msgstr "Отметить задачу как проваленную" #: taskapp/templates/taskapp/tasklist.html:56 #: taskapp/templates/taskapp/tasklist_active.html:53 @@ -358,8 +358,8 @@ msgstr "Нужно выбрать абонента" msgid "Error in the form fields" msgstr "Ошибка в полях формы" -msgid "Active tasks" -msgstr "Активные задачи" +msgid "Failed tasks" +msgstr "Проваленные задачи" msgid "All my tasks" msgstr "Все мои задачи" From 5d69b3bb6bb5fbf732203dfa5fc755bb5a9548e6 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 22 Jul 2017 11:48:41 +0300 Subject: [PATCH 147/179] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D1=83=D1=82=D1=8C=20=D1=83=20=D0=B7=D0=B2?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D1=8F=D0=BC=20asterisk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dialing_app/models.py b/dialing_app/models.py index 0e60f4f..ff6c720 100644 --- a/dialing_app/models.py +++ b/dialing_app/models.py @@ -57,7 +57,7 @@ class AsteriskCDR(models.Model): return "%s/recording/request" % path elif self.userfield == 'report': return "%s/recording/bug" % path - return path + return "%s/monitor" % path class Meta: db_table = 'cdr' From 8501ffb5b84f53eb88a099b9a8d5a1fe568738ef Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 22 Jul 2017 11:50:44 +0300 Subject: [PATCH 148/179] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D1=81=D1=82=D1=8F=D0=B3=D0=B8=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D1=80=D1=83=D0=BF?= =?UTF-8?q?=D0=BF=D1=8B=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialing_app/templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dialing_app/templates/index.html b/dialing_app/templates/index.html index ed89478..adc5061 100644 --- a/dialing_app/templates/index.html +++ b/dialing_app/templates/index.html @@ -21,7 +21,7 @@ {% for log in logs %} - +
    +
    + + +
    + + + {% if selected_parent_dev %} + + + {% else %} + + + {% endif %} + {{ form.parent_dev.errors }} +
    +
    +
    - + {% else %} - + {% endif %} {{ form.abon.errors }}
    From 9eb69619df7cc315d5042ee3ac4af9f4cdb4dce2 Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 24 Jul 2017 14:21:23 +0300 Subject: [PATCH 155/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=20=D1=83?= =?UTF-8?q?=D0=BB=D0=B8=D1=86=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/forms.py | 10 ++++ abonapp/locale/ru/LC_MESSAGES/django.po | 27 ++++++++++ .../templates/abonapp/modal_addstreet.html | 38 +++++++++++++ .../templates/abonapp/modal_editstreet.html | 38 +++++++++++++ abonapp/templates/abonapp/peoples.html | 8 +++ abonapp/urls_abon.py | 3 ++ abonapp/views.py | 54 +++++++++++++++++++ 7 files changed, 178 insertions(+) create mode 100644 abonapp/templates/abonapp/modal_addstreet.html create mode 100644 abonapp/templates/abonapp/modal_editstreet.html diff --git a/abonapp/forms.py b/abonapp/forms.py index 8d57d36..1666c8a 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -121,3 +121,13 @@ class ExtraFieldForm(forms.ModelForm): 'field_type': forms.Select(attrs={'class': 'form-control'}), 'data': forms.TextInput(attrs={'class': 'form-control'}) } + + +class AbonStreetForm(forms.ModelForm): + class Meta: + model = models.AbonStreet + fields = '__all__' + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control', 'required':'', 'autofocus':''}), + 'group': forms.Select(attrs={'class': 'form-control'}) + } diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index bc5df87..46877c6 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -653,6 +653,33 @@ msgstr "Не найдены улицы для группы" msgid "Services of subscriber" msgstr "Купленные абонентом услуги (назначенные тарифные планы)" +msgid "Add street" +msgstr "Добавить улицу" + +msgid "Edit streets" +msgstr "Редактировать улицы" + +msgid "Street successfully saved" +msgstr "Улица успешно сохранена" + +msgid "Streets has been saved" +msgstr "Улицы сохранены" + +msgid "Street title" +msgstr "Название улицы" + +msgid "One of these streets has not been found" +msgstr "Одна из этих улиц не была найдена" + +msgid "The street has not been found" +msgstr "Улица не найдена" + +msgid "The street successfully deleted" +msgstr "Улица успешно удалена" + +msgid "Streets has not been found" +msgstr "Улицы не найдены" + #: abonapp/templates/abonapp/services.html:9 msgid "Priority" msgstr "Приоритет" diff --git a/abonapp/templates/abonapp/modal_addstreet.html b/abonapp/templates/abonapp/modal_addstreet.html new file mode 100644 index 0000000..c723157 --- /dev/null +++ b/abonapp/templates/abonapp/modal_addstreet.html @@ -0,0 +1,38 @@ +{% load i18n %} +
    {% csrf_token %} + + + {% include 'message_block.html' %} + + + +
    diff --git a/abonapp/templates/abonapp/modal_editstreet.html b/abonapp/templates/abonapp/modal_editstreet.html new file mode 100644 index 0000000..bf2b39d --- /dev/null +++ b/abonapp/templates/abonapp/modal_editstreet.html @@ -0,0 +1,38 @@ +{% load i18n %} +
    {% csrf_token %} + + + {% include 'message_block.html' %} + + + +
    diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 0d7d4f7..6dd709f 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -149,6 +149,14 @@ {% empty %} {% trans 'No streets found for that group' %} {% endfor %} + diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index ce80f13..357900b 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -6,6 +6,9 @@ urlpatterns = [ url(r'^$', views.peoples, name='people_list'), url(r'^addabon$', views.addabon, name='add_abon'), url(r'^services$', views.chgroup_tariff, name='ch_group_tariff'), + url(r'^street/add$', views.street_add, name='street_add'), + url(r'^street/edit', views.street_edit, name='street_edit'), + url(r'^street/(?P\d+)/delete$', views.street_del, name='street_del'), url(r'^(?P\d+)$', views.abonhome, name='abon_home'), url(r'^(?P\d+)/services$', views.abon_services, name='abon_services'), diff --git a/abonapp/views.py b/abonapp/views.py index f579a05..8d0b6ab 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -873,6 +873,60 @@ def save_user_dev_port(request, gid, uid): return redirect('abonapp:abon_home', gid, uid) +@login_required +@permission_required('abonapp.add_abonstreet') +def street_add(request, gid): + if request.method == 'POST': + frm = forms.AbonStreetForm(request.POST) + if frm.is_valid(): + frm.save() + messages.success(request, _('Street successfully saved')) + return redirect('abonapp:people_list', gid) + else: + messages.error(request, _('fix form errors')) + else: + frm = forms.AbonStreetForm(initial={'group': gid}) + return render_to_text('abonapp/modal_addstreet.html', { + 'form': frm, + 'gid': gid + }, request=request) + + +@login_required +@permission_required('abonapp.change_abonstreet') +def street_edit(request, gid): + try: + if request.method == 'POST': + streets_pairs = [(int(sid), sname) for sid, sname in zip(request.POST.getlist('sid'), request.POST.getlist('sname'))] + for sid, sname in streets_pairs: + street = models.AbonStreet.objects.get(pk=sid) + street.name = sname + street.save() + messages.success(request, _('Streets has been saved')) + else: + return render_to_text('abonapp/modal_editstreet.html', { + 'gid': gid, + 'streets': models.AbonStreet.objects.filter(group=gid) + }, request=request) + + except models.AbonStreet.DoesNotExist: + messages.error(request, _('One of these streets has not been found')) + + return redirect('abonapp:people_list', gid) + + +@login_required +@permission_required('abonapp.delete_abonstreet') +def street_del(request, gid, sid): + try: + models.AbonStreet.objects.get(pk=sid, group=gid).delete() + messages.success(request, _('The street successfully deleted')) + except models.AbonStreet.DoesNotExist: + messages.error(request, _('The street has not been found')) + return redirect('abonapp:people_list', gid) + + + # API's def abons(request): From 9daac6254971b5110546ec013fc85f87eb4e8b91 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 26 Jul 2017 02:23:16 +0300 Subject: [PATCH 156/179] =?UTF-8?q?=D0=9D=D0=B0=20=D1=81=D1=82=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/locale/ru/LC_MESSAGES/django.po | 30 +-- abonapp/models.py | 241 ++++++---------------- abonapp/templates/abonapp/buy_tariff.html | 2 +- abonapp/templates/abonapp/peoples.html | 26 +-- abonapp/templates/abonapp/service.html | 54 +++++ abonapp/templates/abonapp/services.html | 101 --------- abonapp/tests.py | 225 -------------------- abonapp/urls_abon.py | 2 - abonapp/views.py | 67 +----- bugs.txt | 3 + clientsideapp/views.py | 2 +- cron.py | 2 +- djing/utils/save_from_nodeny.py | 2 +- 13 files changed, 143 insertions(+), 614 deletions(-) create mode 100644 abonapp/templates/abonapp/service.html delete mode 100644 abonapp/templates/abonapp/services.html delete mode 100644 abonapp/tests.py diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 5be7d30..8ee31a6 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -57,10 +57,6 @@ msgstr "Не хватает денег на счету" msgid "finish service perm" msgstr "Снятие со счёта средств" -#: abonapp/models.py:145 -msgid "activate service perm" -msgstr "Активация услуги абонента" - #: abonapp/models.py:162 msgid "Digital field" msgstr "Цифровое поле" @@ -94,10 +90,6 @@ msgstr "Может просматривать паспортные данные" msgid "Buy service default log" msgstr "Покупка тарифного плана через админку" -#: abonapp/models.py:303 -msgid "service overdue log" -msgstr "Услуга просрочена, отключаем, и подключаем новую" - #: abonapp/models.py:346 msgid "Ip address already exist" msgstr "Такой ip уже у кого-то есть" @@ -598,10 +590,6 @@ msgstr "Не найдены улицы для группы" msgid "Services of subscriber" msgstr "Купленные абонентом услуги (назначенные тарифные планы)" -#: abonapp/templates/abonapp/services.html:9 -msgid "Priority" -msgstr "Приоритет" - #: abonapp/templates/abonapp/services.html:12 msgid "Input speed" msgstr "Входящая скорость" @@ -614,18 +602,6 @@ msgstr "Исходящая скорость" msgid "Works until" msgstr "Действует до" -#: abonapp/templates/abonapp/services.html:15 -msgid "Do" -msgstr "Действия" - -#: abonapp/templates/abonapp/services.html:52 -msgid "Priority up" -msgstr "Повысить приоритет" - -#: abonapp/templates/abonapp/services.html:58 -msgid "Priority down" -msgstr "Понизить приоритет" - #: abonapp/templates/abonapp/services.html:64 msgid "Delete service" msgstr "Удалить услугу" @@ -902,3 +878,9 @@ msgstr "Звонки не найдены" msgid "Dialing" msgstr "Звонки" + +msgid "That service already activated" +msgstr "Эта услуга уже подключена" + +msgid "Service already activated" +msgstr "Услуга уже подключена" diff --git a/abonapp/models.py b/abonapp/models.py index 3e0fb45..f291155 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -41,107 +41,42 @@ class AbonLog(models.Model): class AbonTariff(models.Model): - abon = models.ForeignKey('Abon') + + def __init__(self, deadline=None, *args, **kwargs): + super(AbonTariff, self).__init__(*args, **kwargs) + calc_obj = self.tariff.get_calc_type()(self) + self.time_start = timezone.now() + if deadline is None: + self.deadline = calc_obj.calc_deadline() + else: + self.deadline = deadline + tariff = models.ForeignKey(Tariff, related_name='linkto_tariff') - tariff_priority = models.PositiveSmallIntegerField(default=0) - # время начала действия, остальные что не начали действие - NULL + # время начала действия услуги time_start = models.DateTimeField(null=True, blank=True, default=None) # время завершения услуги deadline = models.DateTimeField(null=True, blank=True, default=None) - def priority_up(self): - # ищем услугу с большим приоритетом(число приоритета меньше) - target_abtar = AbonTariff.objects.filter( - abon=self.abon, - tariff_priority__lt=self.tariff_priority - ).order_by('-tariff_priority')[:1] - if target_abtar.count() > 0: - target_abtar = target_abtar[0] - else: - return - - # Ищем текущий тариф абонента - active_abtar = AbonTariff.objects.filter( - abon=self.abon - )[:1] - if active_abtar.count() > 0: - active_abtar = active_abtar[0] - else: - return - - # Если услуга с которой хотим поменяться приоритетом является текущей то нельзя меняться - if active_abtar == target_abtar: - return - - # Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом) - tmp_prior = target_abtar.tariff_priority - target_abtar.tariff_priority = self.tariff_priority - target_abtar.save(update_fields=['tariff_priority']) - self.tariff_priority = tmp_prior - self.save(update_fields=['tariff_priority']) - - def priority_down(self): - # ищем услугу с меньшим приоритетом - target_abtar = AbonTariff.objects.filter( - abon=self.abon, - tariff_priority__gt=self.tariff_priority - )[:1] - if target_abtar.count() > 0: - target_abtar = target_abtar[0] - else: - # меньше нет, это самая последняя услуга - return - - # Swap приоритетов у текущего и найденного с большим tariff_priority (меньшим приоритетом) - tmp_pr = self.tariff_priority - self.tariff_priority = target_abtar.tariff_priority - target_abtar.tariff_priority = tmp_pr - target_abtar.save(update_fields=['tariff_priority']) - self.save(update_fields=['tariff_priority']) - - # Считает текущую стоимость услуг согласно выбранной для тарифа логики оплаты (см. в документации) def calc_amount_service(self): amount = self.tariff.amount return round(amount, 2) - # Активируем тариф - def activate(self, current_user, deadline=None): - calc_obj = self.tariff.get_calc_type()(self) - amnt = self.tariff.amount - # если не хватает денег - if self.abon.ballance < amnt: - raise LogicError(_('not enough money')) - # считаем дату активации услуги - self.time_start = timezone.now() - # считаем дату завершения услуги - if deadline is None: - self.deadline = calc_obj.calc_deadline() - else: - self.deadline = deadline - # снимаем деньги за услугу - self.abon.make_pay(current_user, amnt) - self.save() - # Используется-ли услуга сейчас, если время старта есть то он активирован def is_started(self): - return True if self.time_start is not None else False + return False if self.time_start is None else True def __str__(self): - return "%d: '%s' - '%s'" % ( - self.tariff_priority, + return "'%s' - '%s'" % ( self.tariff.title, self.abon.get_short_name() ) class Meta: - ordering = ('tariff_priority',) db_table = 'abonent_tariff' - unique_together = (('abon', 'tariff', 'tariff_priority'),) permissions = ( - ('can_complete_service', _('finish service perm')), - ('can_activate_service', _('activate service perm')) + ('can_complete_service', _('finish service perm')) ) @@ -211,7 +146,7 @@ class Opt82(models.Model): class Abon(UserProfile): - current_tariffs = models.ManyToManyField(Tariff, through=AbonTariff) + current_tariff = models.ForeignKey(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL) group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True) ballance = models.FloatField(default=0.0) ip_address = MyGenericIPAddressField(blank=True, null=True) @@ -221,20 +156,9 @@ class Abon(UserProfile): extra_fields = models.ManyToManyField(ExtraFieldsModel, blank=True) opt82 = models.ForeignKey(Opt82, null=True, blank=True, on_delete=models.SET_NULL) - _act_tar_cache = None - - # возвращает текущий тариф для абонента - def active_tariff(self, use_cache=True): - if self._act_tar_cache and use_cache: - return self._act_tar_cache - - ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None) - - if ats.count() > 0: - self._act_tar_cache = ats[0].tariff - return ats[0].tariff - else: - self._act_tar_cache = None + # возвращает связь с текущим тарифом для абонента + def active_tariff(self): + return self.current_tariff class Meta: db_table = 'abonent' @@ -262,23 +186,28 @@ class Abon(UserProfile): def pick_tariff(self, tariff, author, comment=None, deadline=None): assert isinstance(tariff, Tariff) - # выбераем связь ТарифАбонент с самым низким приоритетом - abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] - abtrf = abtrf[0] if abtrf.count() > 0 else None + amount = round(tariff.amount, 2) - # создаём новую связь с приоритетом ещё ниже - new_abtar = AbonTariff( - abon=self, - tariff=tariff, - tariff_priority=abtrf.tariff_priority + 1 if abtrf else -1 - ) + if self.current_tariff is not None: + if self.current_tariff.tariff == tariff: + # Эта услуга уже подключена + raise LogicError(_('That service already activated')) + else: + # Не надо молча заменять услугу если какая-то уже есть + raise LogicError(_('Service already activated')) - # Если это первая услуга в списке (фильтр по приоритету ничего не вернул) - if not abtrf: - # значит пробуем её активировать - new_abtar.activate(author, deadline) - else: - new_abtar.save() + # если не хватает денег + if self.ballance < amount: + raise LogicError(_('not enough money')) + + new_abtar = AbonTariff(deadline=deadline, tariff=tariff) + new_abtar.save() + self.current_tariff = new_abtar + + # снимаем деньги за услугу + self.ballance -= amount + + self.save() # Запись об этом в лог AbonLog.objects.create( @@ -287,43 +216,23 @@ class Abon(UserProfile): comment=comment or _('Buy service default log') ) - # Пробует подключить новую услугу если пришло время - def activate_next_tariff(self, author): - ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority') - + # Производим расчёт услуги абонента, т.е. завершаем если пришло время + def bill_service(self, author): + abon_tariff = self.active_tariff() nw = timezone.now() - - for at in ats: - # услуга не активна, продолжаем - if at.deadline is None: - continue - # если услуга просрочена - if nw > at.deadline: - print(_('service overdue log')) - # выберем следующую по приоритету - # next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon) - next_tarifs = [tr for tr in ats if tr.tariff_priority > at.tariff_priority][:2] - #next_tarifs = filter(lambda tr: tr.tariff_priority > at.tariff_priority, ats)[:2] - - # и если что-нибудь из списка следующих услуг вернулось - то активируем - if len(next_tarifs) > 0: - next_tarifs[0].activate(author) - - # удаляем запись о текущей услугу. - at.delete() - return + # если услуга просрочена + if nw > abon_tariff.deadline: + print("Service %s for user %s is overdued, end service" % (abon_tariff.tariff, self)) + abon_tariff.delete() # есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs..manage_access() def is_access(self): - ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None) - if not ats or ats.count() < 1: - return False - trf = ats[0].tariff - ct = trf.get_calc_type()(ats[0]) - if ct.manage_access(self): - return True - else: + abon_tariff = self.active_tariff() + if abon_tariff is None: return False + trf = abon_tariff.tariff + ct = trf.get_calc_type()(abon_tariff) + return ct.manage_access(self) # создаём абонента из структуры агента def build_agent_struct(self): @@ -331,16 +240,17 @@ class Abon(UserProfile): user_ip = ip2int(self.ip_address) else: return - inst_tariff = self.active_tariff() - if inst_tariff: - agent_trf = TariffStruct(inst_tariff.id, inst_tariff.speedIn, inst_tariff.speedOut) - else: + abon_tariff = self.active_tariff() + if abon_tariff is None: agent_trf = TariffStruct() + else: + trf = abon_tariff.tariff + agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut) return AbonStruct(self.pk, user_ip, agent_trf, bool(self.is_active)) def save(self, *args, **kwargs): # проверяем не-ли у кого такого-же ip - if Abon.objects.filter(ip_address=self.ip_address).exclude(pk=self.pk).count() > 0: + if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude(pk=self.pk).count() > 0: self.is_bad_ip = True raise LogicError(_('Ip address already exist')) super(Abon, self).save(*args, **kwargs) @@ -467,40 +377,5 @@ def abon_del_signal(sender, instance, **kwargs): return True -def abontariff_post_save(sender, instance, **kwargs): - # Тут или подключение абону услуги, или изменение приоритета - if not kwargs['created']: - # если изменение приоритета то не говорим об этом NAS'у - return - if instance.abon.ip_address is None: - return - try: - agent_abon = instance.abon.build_agent_struct() - if agent_abon is None: - return True - tm = Transmitter() - tm.update_user(agent_abon) - except (NasFailedResult, NasNetworkError): - return True - - -def abontariff_del_signal(sender, instance, **kwargs): - if not instance.is_started(): - # если удаляем не активную услугу то говорить об этом NAS'у не обязательно - return - if instance.abon.ip_address is None: - # если у абонента нет ip то и создавать правило не на кого - return - try: - agent_abon = instance.abon.build_agent_struct() - tm = Transmitter() - tm.pause_user(agent_abon) - except (NasFailedResult, NasNetworkError): - return True - - -models.signals.post_save.connect(abon_post_save, sender=Abon) -models.signals.post_delete.connect(abon_del_signal, sender=Abon) - -models.signals.post_save.connect(abontariff_post_save, sender=AbonTariff) -models.signals.post_delete.connect(abontariff_del_signal, sender=AbonTariff) +#models.signals.post_save.connect(abon_post_save, sender=Abon) +#models.signals.post_delete.connect(abon_del_signal, sender=Abon) diff --git a/abonapp/templates/abonapp/buy_tariff.html b/abonapp/templates/abonapp/buy_tariff.html index ab4aad9..3b968e7 100644 --- a/abonapp/templates/abonapp/buy_tariff.html +++ b/abonapp/templates/abonapp/buy_tariff.html @@ -22,7 +22,7 @@
    {% csrf_token %}
    - +
    diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index ad334f7..079a32e 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -50,7 +50,7 @@ {% if order_by == 'house' %}{% endif %} {% trans 'Telephone' %} - + {% trans 'Service' %} {% trans 'Ballance' %} @@ -83,16 +83,16 @@ {{ human.street|default:_('Not assigned') }} {{ human.house|default:_('Not assigned') }} {{ human.telephone }} - + + {% if human.active_tariff %} + {% if perms.tariff_app.change_tariff %} + {{ human.active_tariff.tariff.title }} + {% else %} + {{ human.active_tariff.tariff.title }} + {% endif %} + {% else %}——— + {% endif %} + {{ human.ballance }} {% if perms.abonapp.delete_abon %} @@ -104,7 +104,7 @@ {% empty %} - + {% trans 'Subscribers not found' %}. {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} @@ -115,7 +115,7 @@ - + {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} diff --git a/abonapp/templates/abonapp/service.html b/abonapp/templates/abonapp/service.html new file mode 100644 index 0000000..17f81c0 --- /dev/null +++ b/abonapp/templates/abonapp/service.html @@ -0,0 +1,54 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} +{% load i18n %} +{% block content %} + +
    +
    + +
    +
    +

    {% trans 'Services of subscriber' %}

    +
    +
    + {% if abon_tariff %} +

    + {% trans 'Service' %}: + {% if perms.tariff_app.change_tariff %} + + {{ abon_tariff.tariff.title }} + + {% else %} + {{ abon_tariff.tariff.title }} + {% endif %} +

    + {% trans 'Sum' %}: {{ abon_tariff.tarif.amount }} руб. +

    {% trans 'Input speed' %}: {{ abon_tariff.tariff.speedIn }}

    +

    {% trans 'Output speed' %}: {{ abon_tariff.tariff.speedOut }}

    +

    {% trans 'Works until' %}: {{ abon_tariff.deadline|date:"d E Y, l" }}

    +

    {{ abon_tariff.tarif.descr }}

    + {% else %} + No service, + {% trans 'Buy service' %} + + {% endif %} + +
    +
    +
    +
    +
    +
    +

    Услуги для заказа

    +
    +
    +
    +
    +
    +
    +
    + + + + + +{% endblock %} diff --git a/abonapp/templates/abonapp/services.html b/abonapp/templates/abonapp/services.html deleted file mode 100644 index 47b67a9..0000000 --- a/abonapp/templates/abonapp/services.html +++ /dev/null @@ -1,101 +0,0 @@ -{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} -{% load i18n %} -{% block content %} - - {% trans 'Services of subscriber' %} - - - - - - - - - - - - - - - {% for trf in abon_tarifs %} - - - - - - - - {% if trf.id != active_abontariff_id %} - - {% else %} - - {% endif %} - - {% empty %} - - - - {% endfor %} - - {% if perms.abonapp.can_buy_tariff %} - - - - - - {% endif %} -
    {% trans 'Priority' %}{% trans 'Service' %}{% trans 'Sum' %}{% trans 'Input speed' %}{% trans 'Output speed' %}{% trans 'Works until' %}{% trans 'Do' %}
    {{ trf.tariff_priority }} - - {% if perms.tariff_app.change_tariff %} - - {{ trf.tariff.title }} - - {% else %} - {{ trf.tariff.title }} - {% endif %} - - {{ trf.tariff.amount }}{{ trf.tariff.speedIn }}{{ trf.tariff.speedOut }}{{ trf.deadline|date:"d E Y, l" }} - - {% if perms.abonapp.can_activate_service %} - {% if not active_abontariff_id %} - - - - {% endif %} - {% endif %} - - - - - - - - - - - - {% if perms.abonapp.delete_abontariff %} - - - - {% endif %} - - - {% trans 'Finish service' %} - -
    {% trans 'Services of subscribers not found' %}. - {% if perms.abonapp.can_buy_tariff %} - {% trans 'Buy' %} - {% endif %} -
    - - {% trans 'Buy service' %} - -
    - - -{% endblock %} \ No newline at end of file diff --git a/abonapp/tests.py b/abonapp/tests.py deleted file mode 100644 index b66baf8..0000000 --- a/abonapp/tests.py +++ /dev/null @@ -1,225 +0,0 @@ -from django.shortcuts import resolve_url -from django.test import TestCase -from django.test.client import Client -from agent import NasNetworkError -from .models import AbonTariff, Abon, AbonGroup, AbonRawPassword -from tariff_app.models import Tariff -from mydefs import LogicError - - -class AbonTestCase(TestCase): - def setUp(self): - try: - Tariff.objects.create( - title='test_tariff', - descr='taroff descr', - speedIn=1.2, - speedOut=3.0, - amount=3 - ) - abon = Abon() - abon.username = '1234567' - abon.fio = 'mainuser' - abon.telephone = '+79788328884' - abon.set_password('ps') - abon.is_superuser = True - abon.save() - abon_group = AbonGroup.objects.create(title='abon_group') - abon_group.profiles.add(abon) - except NasNetworkError: - pass - - # проверка на пополнение счёта - def test_add_ballance(self): - try: - abon = Abon.objects.get(username='1234567') - ballance = abon.ballance - abon.add_ballance(abon, 13, 'test pay') - abon.save(update_fields=['ballance']) - self.assertEqual(abon.ballance, ballance+13) - ballance = abon.ballance - abon.add_ballance(abon, 5.34, 'test float pay') - abon.save(update_fields=['ballance']) - self.assertEqual(abon.ballance, ballance+5.34) - except NasNetworkError: - pass - - # пробуем выбрать услугу - def test_pick_tariff(self): - try: - tariff = Tariff.objects.get(title='test_tariff') - abon = Abon.objects.get(username='1234567') - try: - abon.pick_tariff(tariff, abon) - # нет денег, должно всплыть исключение и сюда дойти мы не должны - self.assertFalse(True) - except LogicError: - pass - act_tar = abon.active_tariff() - # если недостаточно денег на счету - assert abon.ballance <= tariff.amount - # У абонента на счету 0, не должна быть куплена услуга - self.assertEqual(act_tar, None) - # Раз услуги нет то и доступа быть не должно - self.assertTrue(not abon.is_access()) - - # с деньгами - abon.add_ballance(abon, 7.34, 'add pay for test pick tariff') - abon.pick_tariff(tariff, abon) - act_tar = abon.active_tariff() - # должны получить указанную услугу - self.assertEqual(act_tar, tariff) - # и получить доступ - self.assertTrue(abon.is_access()) - except NasNetworkError: - pass - - # тестим очередь услуг - def test_services_queue(self): - abon = Abon.objects.get(username='1234567') - tariff = Tariff.objects.get(title='test_tariff') - abon.add_ballance(abon, 9, 'add pay for test services queue') - abon.save() - abon.pick_tariff(tariff, abon) - abon.pick_tariff(tariff, abon) - abon.pick_tariff(tariff, abon) - # снять деньги должно было только за первый выбор, остальные стают в очередь услуг - self.assertEqual(abon.ballance, 6) - - c = Client() - # login - c.post(resolve_url('acc_app:login'), {'login': '1234567', 'password': 'ps'}) - url = resolve_url('abonapp:compl_srv', gid=1, uid=1, srvid=1) - resp = c.get(url) - print('RESP:', resp) - self.assertEqual(resp.status_code, 200) - resp = c.post(url, data={ - 'finish_confirm': 'yes' - }) - print('RESP:', resp) - # при успешной остановке услуги идёт редирект на др страницу - self.assertEqual(resp.status_code, 302) - # текущей услуги быть не должно - act_tar = abon.active_tariff() - self.assertIsNone(act_tar) - # не активных услуг останется 2 - noact_count = AbonTariff.objects.filter(abon=abon).filter(time_start=None).count() - self.assertEqual(noact_count, 2) - - # проверяем платёжку alltime - def test_allpay(self): - from hashlib import md5 - from djing.settings import pay_SECRET, pay_SERV_ID - import xmltodict - - def sig(act, pay_account, pay_id): - md = md5() - s = '_'.join((str(act), str(pay_account), pay_SERV_ID, str(pay_id), pay_SECRET)) - md.update(bytes(s, 'utf-8')) - return md.hexdigest() - - c = Client() - url = resolve_url('abonapp:terminal_pay') - r = c.get(url, { - 'ACT': 1, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'TRADE_POINT': 377, - 'SIGN': sig(1, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 21) - r = c.get(url, { - 'ACT': 4, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(4, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 22) - r = c.get(url, { - 'ACT': 4, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(4, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), -100) - r = c.get(url, { - 'ACT': 7, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(7, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 11) - abon = Abon.objects.get(username='1234567') - self.assertEqual(abon.ballance, 1) - - # пробуем добавить группу абонентов - def test_add_abongroup(self): - abon = Abon.objects.get(username='1234567') - ag = AbonGroup.objects.create(title='%&34%$&*(') - ag.profiles.add(abon) - - # пробуем добавить абонента - def test_add_abon(self): - c = Client() - c.login(username='1234567', password='ps') - url = resolve_url('abonapp:add_abon', gid=1) - r = c.get(url) - # поглядим на страницу добавления абонента - self.assertEqual(r.status_code, 200) - r = c.post(url, { - 'username': '123', - 'password': 'ps', - 'fio': 'Abon Fio', - 'telephone': '+79783753914', - 'is_active': True - }) - self.assertEqual(r.status_code, 302) - r = c.get(resolve_url('abonapp:add_abon', gid=324)) - self.assertEqual(r.status_code, 404) - try: - abn = Abon.objects.get(username='123') - self.assertIsNotNone(abn) - psw = AbonRawPassword.objects.get(account=abn, passw_text='ps') - self.assertIsNotNone(psw) - except Abon.DoesNotExist: - # абонент должен был создаться - self.assertTrue(False) - except AbonRawPassword.DoesNotExist: - # должен быть пароль абонента простым текстом - self.assertTrue(False) - - # пробуем удалить абонента - def test_view_delentity(self): - c = Client() - c.login(username='1234567', password='ps') - url = resolve_url('abonapp:del_abon') + '?t=a&id=1' - r = c.get('/abons/1/addabon') - - -class AbonTariffTestCase(TestCase): - def setUp(self): - abon = Abon.objects.create( - username='1234567', - telephone='+79788328884' - ) - tariff = Tariff.objects.create( - title='test_tariff', - descr='taroff descr', - speedIn=1.2, - speedOut=3.0, - amount=3 - ) - AbonTariff.objects.create( - abon=abon, - tariff=tariff - ) diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index 1de99da..9636922 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -15,10 +15,8 @@ urlpatterns = [ url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='add_invoice'), url(r'^(?P\d+)/pick$', views.pick_tariff, name='pick_tariff'), - url(r'^(?P\d+)/chpriority$', views.chpriority, name='chpriority_tariff'), url(r'^(?P\d+)/passport_view$', views.passport_view, name='passport_view'), url(r'^(?P\d+)/complete_service(?P\d+)$', views.complete_service, name='compl_srv'), - url(r'^(?P\d+)/activate_service(?P\d+)$', views.activate_service, name='activate_service'), url(r'^(?P\d+)/opt82$', views.opt82, name='opt82'), url(r'^(?P\d+)/chart$', views.charts, name='charts'), url(r'^(?P\d+)/dials$', views.dials, name='dials'), diff --git a/abonapp/views.py b/abonapp/views.py index db135c9..5fd3f9b 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -245,14 +245,10 @@ def pay_history(request, gid, uid): @mydefs.only_admins def abon_services(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) - abon_tarifs = models.AbonTariff.objects.filter(abon=uid) - active_abontariff = abon_tarifs.exclude(time_start=None) - - return render(request, 'abonapp/services.html', { + return render(request, 'abonapp/service.html', { 'abon': abon, - 'abon_tarifs': abon_tarifs, - 'active_abontariff_id': active_abontariff[0].id if active_abontariff.count() > 0 else None, + 'abon_tariff': abon.current_tariff, 'abon_group': abon.group }) @@ -434,28 +430,6 @@ def pick_tariff(request, gid, uid): }) -@login_required -@mydefs.only_admins -def chpriority(request, gid, uid): - t = request.GET.get('t') - act = request.GET.get('a') - - current_abon_tariff = get_object_or_404(models.AbonTariff, pk=t) - - try: - if act == 'up': - current_abon_tariff.priority_up() - elif act == 'down': - current_abon_tariff.priority_down() - except (NasFailedResult, NasNetworkError) as e: - messages.error(request, e) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - - return redirect('abonapp:abon_home', gid=gid, uid=uid) - - @login_required @permission_required('abonapp.can_complete_service') def complete_service(request, gid, uid, srvid): @@ -515,38 +489,6 @@ def complete_service(request, gid, uid, srvid): }) -@login_required -@permission_required('abonapp.can_activate_service') -def activate_service(request, gid, uid, srvid): - abtar = get_object_or_404(models.AbonTariff, pk=srvid) - amount = abtar.calc_amount_service() - - try: - if request.method == 'POST': - if request.POST.get('finish_confirm') != 'yes': - return HttpResponse(_('Not confirmed')) - - abtar.activate(request.user) - messages.success(request, _('Service has been activated successfully')) - return redirect('abonapp:abon_services', gid, uid) - - except (NasFailedResult, mydefs.LogicError) as e: - messages.error(request, e) - except NasNetworkError as e: - messages.warning(request, e) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - calc_obj = abtar.tariff.get_calc_type()(abtar) - return render(request, 'abonapp/activate_service.html', { - 'abon': abtar.abon, - 'abon_group': abtar.abon.group, - 'abtar': abtar, - 'amount': amount, - 'diff': abtar.abon.ballance - amount, - 'deadline': calc_obj.calc_deadline() - }) - @login_required @permission_required('abonapp.delete_abontariff') @@ -743,7 +685,8 @@ def charts(request, gid, uid): abontariff = abon.active_tariff() if abontariff is not None: - high = abontariff.speedIn + abontariff.speedOut + trf = abontariff.tariff + high = trf.speedIn + trf.speedOut if high > 100: high = 100 @@ -888,7 +831,7 @@ def dials(request, gid, uid): def abons(request): ablist = [{ 'id': abn.pk, - 'tarif_id': abn.active_tariff().pk if abn.active_tariff() else 0, + 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0, 'ip': abn.ip_address.int_ip(), 'is_active': abn.is_active } for abn in models.Abon.objects.all()] diff --git a/bugs.txt b/bugs.txt index fa0bb2e..ba9cf41 100644 --- a/bugs.txt +++ b/bugs.txt @@ -8,3 +8,6 @@ - Не надо коннектиться к микротику когда не собираемся ничего изменять. А то при сохранении залогинились и вышли без действий - Не удаляет просроченные услуги если не пингуется NAS - Надо отменить учёт временной зоны +!!! Обязательно проверить как отрабатывает на NAS удаление и изменение AbonTariff +!!! Удалить всё что связано с активацией услуги +!!! Убрать досрочное завершение услуги diff --git a/clientsideapp/views.py b/clientsideapp/views.py index fb3d785..b40f628 100644 --- a/clientsideapp/views.py +++ b/clientsideapp/views.py @@ -54,7 +54,7 @@ def buy_service(request, srv_id): else: return render_to_text('clientsideapp/modal_service_buy.html', { 'service': service, - 'current_service': current_service + 'current_service': current_service.tariff if current_service is not None else None }, request=request) except LogicError as e: messages.error(request, e) diff --git a/cron.py b/cron.py index e42d2d8..1369392 100755 --- a/cron.py +++ b/cron.py @@ -16,7 +16,7 @@ def main(): for user in users: try: # бдим за услугами абонента: просроченные отключить, заказанные подключить - user.activate_next_tariff(user) + user.bill_service(user) # если нет ip то и нет смысла лезть в NAS if user.ip_address is None: diff --git a/djing/utils/save_from_nodeny.py b/djing/utils/save_from_nodeny.py index ab5cc4b..c8dfc76 100755 --- a/djing/utils/save_from_nodeny.py +++ b/djing/utils/save_from_nodeny.py @@ -102,7 +102,7 @@ class DumpAbon(object): self.passw = raw_passw srv = obj.active_tariff() if srv is not None: - self.service = DumpService.build_from_db(srv) + self.service = DumpService.build_from_db(srv.tariff) else: self.service = None if obj.opt82 is not None and obj.opt82.mac is not None and obj.opt82.port is not None: From 81dc1a4f0cbff4ba9927d200e46c1ace6f29bc45 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 29 Jul 2017 13:53:25 +0300 Subject: [PATCH 157/179] =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D1=82=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- abonapp/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abonapp/views.py b/abonapp/views.py index 8d0b6ab..ec65647 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -22,6 +22,7 @@ from devapp.models import Device, Port as DevPort from datetime import datetime, date from taskapp.models import Task from dialing_app.models import AsteriskCDR +from statistics.models import getModel, get_dates @login_required @@ -678,7 +679,6 @@ def clear_dev(request, gid, uid): @login_required @mydefs.only_admins def charts(request, gid, uid): - from statistics.models import getModel high = 100 wandate = request.GET.get('wantdate') @@ -725,7 +725,7 @@ def charts(request, gid, uid): 'abon': abon, 'charts_data': ',\n'.join(charts_data) if charts_data is not None else None, 'high': high, - 'dates': StatElem.objects.get_dates() + 'dates': get_dates() }) From 23fac2bbcc4756158b9cb44d02d052ad98009e5c Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 29 Jul 2017 13:53:45 +0300 Subject: [PATCH 158/179] =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D1=82=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- statistics/models.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/statistics/models.py b/statistics/models.py index 9bf6b38..c222edc 100644 --- a/statistics/models.py +++ b/statistics/models.py @@ -7,6 +7,12 @@ from mydefs import MyGenericIPAddressField from .fields import UnixDateTimeField +def get_dates(): + tables = connection.introspection.table_names() + tables = [t.replace('flowstat_', '') for t in tables if t.startswith('flowstat_')] + return [datetime.strptime(t, '%d%m%Y').date() for t in tables] + + class StatManager(models.Manager): def chart(self, ip_addr, count_of_parts=12, want_date=date.today()): @@ -41,11 +47,6 @@ class StatManager(models.Manager): else: return - def get_dates(self): - tables = connection.introspection.table_names() - tables = [t.replace('flowstat_', '') for t in tables if t.startswith('flowstat_')] - return [datetime.strptime(t, '%d%m%Y').date() for t in tables] - class StatElem(models.Model): cur_time = UnixDateTimeField(primary_key=True) @@ -55,11 +56,19 @@ class StatElem(models.Model): objects = StatManager() + # ReadOnly def save(self, *args, **kwargs): - return + pass + # ReadOnly def delete(self, *args, **kwargs): - return + pass + + def delete_month(self): + cursor = connection.cursor() + table_name = self._meta.db_table + sql = "DROP TABLE %s;" % table_name + cursor.execute(sql) @staticmethod def percentile(N, percent, key=lambda x:x): From 08ae94452f665f6b6152df9efb14ec6101bfcfcb Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 29 Jul 2017 13:54:53 +0300 Subject: [PATCH 159/179] =?UTF-8?q?=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BE=D0=B4=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D1=87=D0=BD=D1=8B=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devapp/forms.py b/devapp/forms.py index 09a823d..826c714 100644 --- a/devapp/forms.py +++ b/devapp/forms.py @@ -27,7 +27,7 @@ class DeviceForm(forms.ModelForm): 'placeholder': '192.168.0.100', 'class': 'form-control' }), - 'comment': forms.Textarea(attrs={ + 'comment': forms.TextInput(attrs={ 'required': True, 'class': 'form-control' }), From 69f36b831d610f8b33be22d7be4c3cdf47da5e07 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 29 Jul 2017 13:55:24 +0300 Subject: [PATCH 160/179] fixbug --- mapapp/templates/maps/map_tooltip.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapapp/templates/maps/map_tooltip.html b/mapapp/templates/maps/map_tooltip.html index b7488b1..a628124 100644 --- a/mapapp/templates/maps/map_tooltip.html +++ b/mapapp/templates/maps/map_tooltip.html @@ -1,7 +1,7 @@

    {{ dot.title }}

    {% for dev in devs %} - + {{ dev.comment }} {% empty %} From db6c18f2276a90c61457b30cb62af951dbd2df54 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Sat, 29 Jul 2017 13:55:49 +0300 Subject: [PATCH 161/179] fixbug --- devapp/dev_types.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devapp/dev_types.py b/devapp/dev_types.py index 74099df..c759242 100644 --- a/devapp/dev_types.py +++ b/devapp/dev_types.py @@ -62,9 +62,10 @@ class DLinkDevice(DevBase, SNMPBaseWorker): macs = self.get_list(oids['get_ports']['macs']) speeds = self.get_list(oids['get_ports']['speeds']) res = [] - ln = len(macs) + ln = len(speeds) for n in range(ln): status = True if int(stats[n]) == 1 else False + print(len(nams), len(speeds), len(macs)) res.append(DLinkPort( n+1, nams[n] if len(nams) > 0 else _('does not fetch the name'), From 7b97df542d79542e29d942f37c44e240ca0f02f5 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 14:59:04 +0300 Subject: [PATCH 162/179] Init commit --- systemd_units/djing_telebot.service | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 systemd_units/djing_telebot.service diff --git a/systemd_units/djing_telebot.service b/systemd_units/djing_telebot.service new file mode 100644 index 0000000..535b8c0 --- /dev/null +++ b/systemd_units/djing_telebot.service @@ -0,0 +1,15 @@ +[Unit] +Description=A job for djing + +[Service] +Type=simple +ExecStart=/usr/bin/python3 ./telebot.py > /dev/null +PIDFile=/run/telebot.py.pid +WorkingDirectory=/srv/http/djing +TimeoutSec=9 +Restart=always +User=http +Group=http + +[Install] +WantedBy=multi-user.target From 987e18c1a7f66e6f08310ff2ddd7ddc93a7c4dc6 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 14:59:48 +0300 Subject: [PATCH 163/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20pid=20=D0=B4=D0=BB=D1=8F=20=D0=BE?= =?UTF-8?q?=D1=82=D1=81=D0=BB=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D0=B3=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 952569a..327d758 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ xmltodict mysqlclient easysnmp rq +pid From 41f68fdfeee2947faed9cf9548468c8cdd8e342b Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 15:00:18 +0300 Subject: [PATCH 164/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20pid=20=D1=87=D1=82=D0=BE=D0=B1=20?= =?UTF-8?q?=D0=BE=D1=82=D1=81=D0=BB=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telebot.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/telebot.py b/telebot.py index 8669551..b34d78d 100755 --- a/telebot.py +++ b/telebot.py @@ -1,12 +1,14 @@ #!/usr/bin/python3 # -*- coding: utf-8 -*- import os +from pid.decorator import pidfile import django from telepot import DelegatorBot from telepot.delegate import per_chat_id, create_open, pave_event_space -if __name__ == '__main__': +@pidfile() +def main(): os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") django.setup() from chatbot.telebot import token, DjingTelebot @@ -16,3 +18,7 @@ if __name__ == '__main__': ), ]) bot.message_loop(run_forever='Listening ...') + + +if __name__ == '__main__': + main() From a92922fd1150656af61344a26a297eb178e44ab3 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 15:12:07 +0300 Subject: [PATCH 165/179] init commit --- systemd_units/djing_queue.service | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 systemd_units/djing_queue.service diff --git a/systemd_units/djing_queue.service b/systemd_units/djing_queue.service new file mode 100644 index 0000000..830a585 --- /dev/null +++ b/systemd_units/djing_queue.service @@ -0,0 +1,15 @@ +[Unit] +Description=Djing queue manager + +[Service] +Type=simple +ExecStart=/usr/bin/python3 ./queue_mngr.py > /dev/null +PIDFile=/run/queue_mngr.py.pid +WorkingDirectory=/var/www/djing +TimeoutSec=15 +Restart=always +User=http +Group=http + +[Install] +WantedBy=multi-user.target From a78b7aa0a4ba1fcff5a4566b7d4168fb2079c8a1 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 15:12:28 +0300 Subject: [PATCH 166/179] fix --- systemd_units/djing_telebot.service | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/systemd_units/djing_telebot.service b/systemd_units/djing_telebot.service index 535b8c0..e7676af 100644 --- a/systemd_units/djing_telebot.service +++ b/systemd_units/djing_telebot.service @@ -1,11 +1,11 @@ [Unit] -Description=A job for djing +Description=Djing telegram bot [Service] Type=simple ExecStart=/usr/bin/python3 ./telebot.py > /dev/null PIDFile=/run/telebot.py.pid -WorkingDirectory=/srv/http/djing +WorkingDirectory=/var/www/djing TimeoutSec=9 Restart=always User=http From 46e035b381b792c7a58580dd54a9d2065431fc8b Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 15:25:20 +0300 Subject: [PATCH 167/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=20pid=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- queue_mngr.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/queue_mngr.py b/queue_mngr.py index 4faefa3..a5b7835 100755 --- a/queue_mngr.py +++ b/queue_mngr.py @@ -2,6 +2,7 @@ import os import sys from rq import Connection, Worker +from pid.decorator import pidfile import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") from agent import NasFailedResult, NasNetworkError @@ -11,7 +12,8 @@ from django.core.exceptions import ValidationError """ Заустить этот скрипт как демон, он соединяет redis и django """ -if __name__ == '__main__': +@pidfile() +def main(): try: django.setup() with Connection(): @@ -22,3 +24,7 @@ if __name__ == '__main__': print('NAS:', e) except (ValidationError, ValueError) as e: print('ERROR:', e) + + +if __name__ == "__main__": + main() From 9f5817b4922794083e75c2b8befadfb44ea492d0 Mon Sep 17 00:00:00 2001 From: bashmak Date: Sat, 29 Jul 2017 18:57:51 +0300 Subject: [PATCH 168/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BE=D0=BD=D1=83=D1=88=D0=BA=D0=B8=20=D1=80=D0=B5=D0=B3=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B8=D1=80=D1=83=D1=8E=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8=20=D0=BE=D0=BD=D1=83=D1=88=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/models.py | 35 +++++++++++++++++++++++++++++++++++ devapp/onu_register.sh | 32 ++++++++++++++++++++++++++++++++ djing/__init__.py | 32 +++++--------------------------- 3 files changed, 72 insertions(+), 27 deletions(-) create mode 100755 devapp/onu_register.sh diff --git a/devapp/models.py b/devapp/models.py index 6561425..a028786 100644 --- a/devapp/models.py +++ b/devapp/models.py @@ -6,6 +6,8 @@ from .base_intr import DevBase from mydefs import MyGenericIPAddressField, MyChoicesAdapter from .dev_types import DLinkDevice, OLTDevice, OnuDevice from mapapp.models import Dot +from subprocess import call +from django.conf import settings DEVICE_TYPES = ( @@ -66,3 +68,36 @@ class Port(models.Model): class Meta: db_table = 'dev_port' unique_together = (('device', 'num')) + + +def dev_post_save_signal(sender, instance, **kwargs): + if instance.devtype != 'On': + return + grp = instance.user_group.pk + if grp == 87: + code = 'chk' + elif grp == 85: + code = 'drf' + elif grp == 86: + code = 'eme' + elif grp == 84: + code = 'kunc' + elif grp == 47: + code = 'mtr' + elif grp == 60: + code = 'nvg' + elif grp == 65: + code = 'ohot' + elif grp == 89: + code = 'psh' + elif grp == 92: + code = 'str' + elif grp == 80: + code = 'uy' + elif grp == 79 or grp == 91: + code = 'zrk' + newmac = str(instance.mac_addr) + call(["%s/devapp/onu_register.sh" % settings.BASE_DIR, newmac, code]) + + +models.signals.post_save.connect(dev_post_save_signal, sender=Device) diff --git a/devapp/onu_register.sh b/devapp/onu_register.sh new file mode 100755 index 0000000..32bd6a7 --- /dev/null +++ b/devapp/onu_register.sh @@ -0,0 +1,32 @@ +#!/bin/bash + + +# old mac address +if [[ $1 =~ ^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$ ]]; then + MAC=$1 +else + echo "Bad mac $MAC addr" + exit +fi + + +# part code +if [[ $2 =~ ^[a-zA-Z]+$ ]]; then + PART_CODE=$2 +else + echo 'code must contains only letters' + exit +fi + + +DHCP_PATH='/home/bashmak/Projects/djing/macs' +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin + + +if grep "${MAC}" "${DHCP_PATH}/${PART_CODE}.conf" > /dev/null; then + # mac is already exists + exit +else + # add new mac + echo "subclass \"${PART_CODE}\" \"${MAC}\";" >> "${DHCP_PATH}/${PART_CODE}.conf" +fi diff --git a/djing/__init__.py b/djing/__init__.py index 8c21558..f71a4cf 100644 --- a/djing/__init__.py +++ b/djing/__init__.py @@ -1,39 +1,17 @@ import importlib -import warnings - -from django.conf import settings from netaddr import mac_unix, mac_eui48 -MAC_ADDR_REGEX = r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$' +MAC_ADDR_REGEX = r'^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$' class mac_linux(mac_unix): """MAC format with zero-padded all upper-case hex and colon separated""" - word_fmt = '%.2X' + word_fmt = '%x' + def default_dialect(eui_obj=None): - # Check to see if a default dialect class has been specified in settings, - # using 'module.dialect_cls' string and use importlib and getattr to retrieve dialect class. 'module' is the module and - # 'dialect_cls' is the class name of the custom dialect. The dialect must either be defined or imported by the module's - # __init__.py if the module is a package. - from .fields import MACAddressField # Remove import at v1.4 - if hasattr(settings, 'MACADDRESS_DEFAULT_DIALECT') and not MACAddressField.dialect: - module, dialect_cls = settings.MACADDRESS_DEFAULT_DIALECT.split('.') - dialect = getattr(importlib.import_module(module), dialect_cls, mac_linux) - return dialect - else: - if MACAddressField.dialect: # Remove this "if" statement at v1.4 - warnings.warn( - "The set_dialect class method on MACAddressField has been deprecated, in favor of the default_dialect " - "utility function and settings.MACADDRESS_DEFAULT_DIALECT. See macaddress.__init__.py source or the " - "project README for more information.", - DeprecationWarning, - ) - return MACAddressField.dialect - if eui_obj: - return eui_obj.dialect - else: - return mac_linux + return mac_linux + def format_mac(eui_obj, dialect): # Format a EUI instance as a string using the supplied dialect class, allowing custom string classes by From bdefe33175b9545e17e5c683e9a6dd6f5443a055 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 11:46:17 +0300 Subject: [PATCH 169/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=83=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20=D1=83=D0=B6=D0=B5?= =?UTF-8?q?=20=D0=B5=D1=81=D1=82=D1=8C=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5?= =?UTF-8?q?,=20=D1=82=D0=BE=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0,=20=D0=B2=D0=B5=D0=B4=D1=83=D1=89=D0=B0=D1=8F=20=D0=BD?= =?UTF-8?q?=20=D1=8D=D1=82=D0=BE=20=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B5=20=D1=83=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/add_dev.html | 12 ++++++++++-- devapp/views.py | 12 +++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/devapp/templates/devapp/add_dev.html b/devapp/templates/devapp/add_dev.html index 5cd2f4e..4838e99 100644 --- a/devapp/templates/devapp/add_dev.html +++ b/devapp/templates/devapp/add_dev.html @@ -37,7 +37,15 @@
    - {{ form.mac_addr }}{{ form.mac_addr.errors }} + {{ form.mac_addr }} + {% if already_dev %} + + + {% for err in form.mac_addr.errors %}{{ err }}{% endfor %} + {{ already_dev.comment }} + + + {% endif %}
    @@ -99,4 +107,4 @@
    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/devapp/views.py b/devapp/views.py index d3b124a..f8faf8b 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -75,6 +75,7 @@ def devdel(request, did): def dev(request, grp, devid=0): devinst = get_object_or_404(Device, id=devid) if devid != 0 else None user_group = get_object_or_404(AbonGroup, pk=grp) + already_dev = None if request.method == 'POST': if devid == 0: @@ -85,10 +86,14 @@ def dev(request, grp, devid=0): raise PermissionDenied frm = DeviceForm(request.POST, instance=devinst) if frm.is_valid(): - frm.save() + ndev = frm.save() messages.success(request, _('Device info has been saved')) - return redirect('devapp:devs', grp) + return redirect('devapp:edit', grp, ndev.pk) else: + try: + already_dev = Device.objects.get(mac_addr=request.POST.get('mac_addr')) + except Device.DoesNotExist: + pass messages.error(request, _('Form is invalid, check fields and try again')) else: if devinst is None: @@ -106,7 +111,8 @@ def dev(request, grp, devid=0): if devinst is None: return render(request, 'devapp/add_dev.html', { 'form': frm, - 'group': user_group + 'group': user_group, + 'already_dev': already_dev }) else: return render(request, 'devapp/dev.html', { From 5eb18c838192edbcc1611e40263c8c09dc01b942 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 11:46:42 +0300 Subject: [PATCH 170/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=83=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20=D1=83=D0=B6=D0=B5?= =?UTF-8?q?=20=D0=B5=D1=81=D1=82=D1=8C=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5?= =?UTF-8?q?,=20=D1=82=D0=BE=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0,=20=D0=B2=D0=B5=D0=B4=D1=83=D1=89=D0=B0=D1=8F=20=D0=BD?= =?UTF-8?q?=20=D1=8D=D1=82=D0=BE=20=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B5=20=D1=83=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/locale/ru/LC_MESSAGES/django.po | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index 7e402dd..2d29775 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -294,3 +294,7 @@ msgstr "Найти устройство" msgid "Find the subscriber" msgstr "Найти абонента" + +msgid "View the device" +msgstr "Посмотреть устройство" + From 3bdf337098fd70fea58b077837bf273db223de20 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 11:48:22 +0300 Subject: [PATCH 171/179] =?UTF-8?q?=D0=B8=D0=B3=D0=BD=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BC=20=D0=BD=D0=B5=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0?= =?UTF-8?q?=D1=80=D1=82=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20queue=20=D0=B2=20=D0=BC=D0=B8=D0=BA=D1=80=D0=BE=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/mod_mikrotik.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/agent/mod_mikrotik.py b/agent/mod_mikrotik.py index 2e515c5..e1345b3 100644 --- a/agent/mod_mikrotik.py +++ b/agent/mod_mikrotik.py @@ -201,15 +201,18 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta): speedIn=parse_speed(speeds[1]), speedOut=parse_speed(speeds[0]) ) - a = AbonStruct( - uid=int(info['=name'][3:]), - # FIXME: тут в разных микротиках или =target-addresses или =target - ip=info['=target'][:-3], - tariff=t, - is_active=False if info['=disabled'] == 'false' else True - ) - a.queue_id = info['=.id'] - return a + try: + a = AbonStruct( + uid=int(info['=name'][3:]), + # FIXME: тут в разных микротиках или =target-addresses или =target + ip=info['=target'][:-3], + tariff=t, + is_active=False if info['=disabled'] == 'false' else True + ) + a.queue_id = info['=.id'] + return a + except ValueError: + pass class QueueManager(TransmitterManager, metaclass=ABCMeta): From add5361025ddc7203d17af44ac8aa24206f1bd2d Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 13:03:25 +0300 Subject: [PATCH 172/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=83=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20=D1=83=D0=B6=D0=B5?= =?UTF-8?q?=20=D0=B5=D1=81=D1=82=D1=8C=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5?= =?UTF-8?q?,=20=D1=82=D0=BE=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0,=20=D0=B2=D0=B5=D0=B4=D1=83=D1=89=D0=B0=D1=8F=20=D0=BD?= =?UTF-8?q?=20=D1=8D=D1=82=D0=BE=20=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B5=20=D1=83=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/add_dev.html | 2 +- devapp/views.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/devapp/templates/devapp/add_dev.html b/devapp/templates/devapp/add_dev.html index 4838e99..0646437 100644 --- a/devapp/templates/devapp/add_dev.html +++ b/devapp/templates/devapp/add_dev.html @@ -41,12 +41,12 @@ {% if already_dev %} - {% for err in form.mac_addr.errors %}{{ err }}{% endfor %} {{ already_dev.comment }} {% endif %} + {{ form.mac_addr.errors }}
    diff --git a/devapp/views.py b/devapp/views.py index f8faf8b..46bab38 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -118,7 +118,9 @@ def dev(request, grp, devid=0): return render(request, 'devapp/dev.html', { 'form': frm, 'dev': devinst, - 'selected_parent_dev': devinst.parent_dev or None + 'selected_parent_dev': devinst.parent_dev or None, + 'group': user_group, + 'already_dev': already_dev }) From b157551c84ad6c7bec01bd1027d22ff623dacfc6 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 13:04:10 +0300 Subject: [PATCH 173/179] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=83=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20=D1=83=D0=B6=D0=B5?= =?UTF-8?q?=20=D0=B5=D1=81=D1=82=D1=8C=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5?= =?UTF-8?q?,=20=D1=82=D0=BE=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0,=20=D0=B2=D0=B5=D0=B4=D1=83=D1=89=D0=B0=D1=8F=20=D0=BD?= =?UTF-8?q?=20=D1=8D=D1=82=D0=BE=20=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B5=20=D1=83=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/templates/devapp/dev.html | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/devapp/templates/devapp/dev.html b/devapp/templates/devapp/dev.html index e80bab6..43e627d 100644 --- a/devapp/templates/devapp/dev.html +++ b/devapp/templates/devapp/dev.html @@ -8,7 +8,7 @@
    - {% csrf_token %} + {% csrf_token %}
    @@ -22,11 +22,19 @@
    -
    +
    - {{ form.mac_addr }}{{ form.mac_addr.errors }} + {{ form.mac_addr }} + {% if already_dev %} + + + {{ already_dev.comment }} + + + {% endif %}
    -
    + {{ form.mac_addr.errors }} +
    @@ -103,4 +111,4 @@
    -{% endblock %} \ No newline at end of file +{% endblock %} From b2343942252e01984a0b2f03c8ac6f1751169db8 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Mon, 31 Jul 2017 13:05:06 +0300 Subject: [PATCH 174/179] fix --- devapp/onu_register.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devapp/onu_register.sh b/devapp/onu_register.sh index 32bd6a7..c835550 100755 --- a/devapp/onu_register.sh +++ b/devapp/onu_register.sh @@ -19,7 +19,7 @@ else fi -DHCP_PATH='/home/bashmak/Projects/djing/macs' +DHCP_PATH='/etc/dhcp/macs' PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin @@ -29,4 +29,6 @@ if grep "${MAC}" "${DHCP_PATH}/${PART_CODE}.conf" > /dev/null; then else # add new mac echo "subclass \"${PART_CODE}\" \"${MAC}\";" >> "${DHCP_PATH}/${PART_CODE}.conf" + /usr/bin/sudo /usr/bin/systemctl restart dhcpd.service fi + From 8bb817274097ecf541c5c570ff6a1026545cdd94 Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 10 Aug 2017 14:19:50 +0300 Subject: [PATCH 175/179] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D1=82=D0=B8=D0=BB=D1=8C=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?10gb=20=D0=BF=D0=BE=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/css/custom.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/static/css/custom.css b/static/css/custom.css index 38991ed..b3e2810 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -155,6 +155,9 @@ a.port-img{ text-decoration: none; } +/* 10GBit/s */ +.port.ten{background-color: #a4fff7;} + /* 1GBit/s */ .port.giga{background-color: #caccfb;} From b378cf95d609f77b20bdcb04fbfc440ff572045f Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 10 Aug 2017 14:44:15 +0300 Subject: [PATCH 176/179] =?UTF-8?q?=D0=A8=D1=80=D0=B8=D1=84=D1=82=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B5=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=B4=D0=BF=D0=B8=D1=81=D0=B8=20=D0=BE=20=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D1=80=D0=BE=D1=81=D1=82=D0=B8=20=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/css/custom.css | 1 + 1 file changed, 1 insertion(+) diff --git a/static/css/custom.css b/static/css/custom.css index b3e2810..d698291 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -138,6 +138,7 @@ td.btn-group { border-radius: 3px; padding: 6px; width: 79px; + font-size: x-small; } .port .port-img{ background-image: url(/static/img/icon-port-64x64-grey.png); From 5b8f21cf299c86eeda99c1ef8c0b435221ebe84d Mon Sep 17 00:00:00 2001 From: bashmak Date: Thu, 10 Aug 2017 14:57:39 +0300 Subject: [PATCH 177/179] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E=20=D0=B4=D0=BB=D1=8F=20Eltex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapp/dev_types.py | 99 +++++++++++++------ devapp/locale/ru/LC_MESSAGES/django.po | 2 + devapp/models.py | 9 +- .../devapp/custom_dev_page/ports.html | 6 ++ 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/devapp/dev_types.py b/devapp/dev_types.py index c759242..d9798cc 100644 --- a/devapp/dev_types.py +++ b/devapp/dev_types.py @@ -5,22 +5,6 @@ from datetime import timedelta from .base_intr import DevBase, SNMPBaseWorker, BasePort - -oids = { - 'reboot': '.1.3.6.1.4.1.2021.8.1.101.1', - 'get_ports': { - 'names': '.1.3.6.1.4.1.171.10.134.2.1.1.100.2.1.3', - 'stats': '.1.3.6.1.2.1.2.2.1.7', - 'macs': '.1.3.6.1.2.1.2.2.1.6', - 'speeds': '.1.3.6.1.2.1.31.1.1.1.15' - }, - 'name': '.1.3.6.1.2.1.1.1.0', - 'position': '.1.3.6.1.2.1.1.5.0', - 'toggle_port': '.1.3.6.1.2.1.2.2.1.7', - 'uptime': '.1.3.6.1.2.1.1.8.0' -} - - class DLinkPort(BasePort): def __init__(self, num, name, status, mac, speed, snmpWorker): @@ -31,15 +15,13 @@ class DLinkPort(BasePort): # выключаем этот порт def disable(self): self.snmp_worker.set_int_value( - "%s.%d" % (oids['toggle_port'], self.num), - 2 + "%s.%d" % ('.1.3.6.1.2.1.2.2.1.7', self.num), 2 ) # включаем этот порт def enable(self): self.snmp_worker.set_int_value( - "%s.%d" % (oids['toggle_port'], self.num), - 1 + "%s.%d" % ('.1.3.6.1.2.1.2.2.1.7', self.num), 1 ) @@ -54,18 +36,17 @@ class DLinkDevice(DevBase, SNMPBaseWorker): return _('DLink switch') def reboot(self): - pass + return self.get_item('.1.3.6.1.4.1.2021.8.1.101.1') def get_ports(self): - nams = self.get_list(oids['get_ports']['names']) - stats = self.get_list(oids['get_ports']['stats']) - macs = self.get_list(oids['get_ports']['macs']) - speeds = self.get_list(oids['get_ports']['speeds']) + nams = self.get_list('.1.3.6.1.4.1.171.10.134.2.1.1.100.2.1.3') + stats = self.get_list('.1.3.6.1.2.1.2.2.1.7') + macs = self.get_list('.1.3.6.1.2.1.2.2.1.6') + speeds = self.get_list('.1.3.6.1.2.1.31.1.1.1.15') res = [] ln = len(speeds) for n in range(ln): status = True if int(stats[n]) == 1 else False - print(len(nams), len(speeds), len(macs)) res.append(DLinkPort( n+1, nams[n] if len(nams) > 0 else _('does not fetch the name'), @@ -76,10 +57,10 @@ class DLinkDevice(DevBase, SNMPBaseWorker): return res def get_device_name(self): - return self.get_item(oids['name']) + return self.get_item('.1.3.6.1.2.1.1.1.0') def uptime(self): - uptimestamp = safe_int(self.get_item(oids['uptime'])) + uptimestamp = safe_int(self.get_item('.1.3.6.1.2.1.1.8.0')) tm = RuTimedelta(timedelta(seconds=uptimestamp/100)) or RuTimedelta(timedelta()) return tm @@ -194,3 +175,65 @@ class OnuDevice(DevBase, SNMPBaseWorker): @staticmethod def is_use_device_port(): return False + + +class EltexPort(BasePort): + + def __init__(self, num, name, status, mac, speed, snmpWorker): + BasePort.__init__(self, num, name, status, mac, speed) + assert issubclass(snmpWorker.__class__ , SNMPBaseWorker) + self.snmp_worker = snmpWorker + + # выключаем этот порт + def disable(self): + self.snmp_worker.set_int_value( + "%s.%d" % ('.1.3.6.1.2.1.2.2.1.7', self.num), + 2 + ) + + # включаем этот порт + def enable(self): + self.snmp_worker.set_int_value( + "%s.%d" % ('.1.3.6.1.2.1.2.2.1.7', self.num), + 1 + ) + + +class EltexSwitch(DLinkDevice): + + @staticmethod + def description(): + return _('Eltex switch') + + def get_ports(self): + #nams = self.get_list('.1.3.6.1.4.1.171.10.134.2.1.1.100.2.1.3') + stats = self.get_list('.1.3.6.1.2.1.2.2.1.7') + oper_stats = self.get_list('.1.3.6.1.2.1.2.2.1.8') + #macs = self.get_list('.1.3.6.1.2.1.2.2.1.6') + speeds = self.get_list('.1.3.6.1.2.1.31.1.1.1.15') + res = [] + for n in range(28): + res.append(EltexPort( + n+1, + '',#nams[n] if len(nams) > 0 else _('does not fetch the name'), + True if int(stats[n]) == 1 else False, + '',#macs[n] if len(macs) > 0 else _('does not fetch the mac'), + int(speeds[n]) if len(speeds) > 0 and int(oper_stats[n]) == 1 else 0, + self)) + return res + + def get_device_name(self): + return self.get_item('.1.3.6.1.2.1.1.5.0') + + def uptime(self): + uptimestamp = safe_int(self.get_item('.1.3.6.1.2.1.1.3.0')) + tm = RuTimedelta(timedelta(seconds=uptimestamp/100)) or RuTimedelta(timedelta()) + return tm + + @staticmethod + def has_attachable_to_subscriber(): + return False + + @staticmethod + def is_use_device_port(): + return False diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index 2d29775..7a6f8e3 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -298,3 +298,5 @@ msgstr "Найти абонента" msgid "View the device" msgstr "Посмотреть устройство" +msgid "Eltex switch" +msgstr "Элтекс свич" diff --git a/devapp/models.py b/devapp/models.py index a028786..eef53b5 100644 --- a/devapp/models.py +++ b/devapp/models.py @@ -4,16 +4,17 @@ from django.db import models from djing.fields import MACAddressField from .base_intr import DevBase from mydefs import MyGenericIPAddressField, MyChoicesAdapter -from .dev_types import DLinkDevice, OLTDevice, OnuDevice +from . import dev_types from mapapp.models import Dot from subprocess import call from django.conf import settings DEVICE_TYPES = ( - ('Dl', DLinkDevice), - ('Pn', OLTDevice), - ('On', OnuDevice) + ('Dl', dev_types.DLinkDevice), + ('Pn', dev_types.OLTDevice), + ('On', dev_types.OnuDevice), + ('Ex', dev_types.EltexSwitch) ) diff --git a/devapp/templates/devapp/custom_dev_page/ports.html b/devapp/templates/devapp/custom_dev_page/ports.html index 9488ecf..e6f8884 100644 --- a/devapp/templates/devapp/custom_dev_page/ports.html +++ b/devapp/templates/devapp/custom_dev_page/ports.html @@ -18,10 +18,16 @@ {% if port.st %} {% if port.sp == 10 %}
    + 10 mbps {% elif port.sp == 100 %}
    + 100 mbps {% elif port.sp == 1000 %}
    + 1 gbps + {% elif port.sp == 10000 %} +
    + 10 gbps {% else %}
    {% endif %} From 3bc35540a070bd988e449685b5328b7c42ae49c7 Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 14 Aug 2017 13:04:58 +0300 Subject: [PATCH 178/179] =?UTF-8?q?FIXBUG:=20=D0=BE=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20=D0=B4?= =?UTF-8?q?=D1=83=D0=B1=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D1=81=D1=8C=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80=D1=83=20=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D1=80=D0=B0=D0=B7=20?= =?UTF-8?q?=D1=81=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=B1=D1=8B=D0=BB?= =?UTF-8?q?=D0=BE=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taskapp/handle.py | 73 ++++++++++++++++++++++++++--------------------- taskapp/handle.sh | 2 +- taskapp/models.py | 18 ++++-------- taskapp/views.py | 8 ++++++ 4 files changed, 55 insertions(+), 46 deletions(-) diff --git a/taskapp/handle.py b/taskapp/handle.py index be59da7..e31303f 100644 --- a/taskapp/handle.py +++ b/taskapp/handle.py @@ -2,41 +2,50 @@ from django.utils.translation import ugettext as _ from chatbot.telebot import send_notify from chatbot.models import ChatException +from mydefs import MultipleException class TaskException(Exception): pass -def handle(task, author, recipient, abon_group): - try: - dst_account = recipient - text = _('Task') - # Если сигнал самому себе то молчим - if author == recipient: - return - # Если задача 'На выполнении' то молчим - if task.state == 'C': - return - # Если задача завершена - elif task.state == 'F': - text = _('Task completed') - # Меняем цель назначения на автора, т.к. при завершении - # идёт оповещение автору о выполнении - dst_account = author - if task.abon is not None: - fulltext="%s:\n%s\n" % (text, task.abon.get_full_name()) - else: - fulltext="%s\n" % text - fulltext += _('locality %s.\n') % abon_group.title - if task.abon: - fulltext += _('address %s %s.\ntelephone %s\n') % ( - task.abon.street.name if task.abon.street is not None else '<'+_('not chosen')+'>', - task.abon.house, - task.abon.telephone - ) - fulltext += _('Task type - %s.') % task.get_mode_display() + '\n' - fulltext += task.descr if task.descr else '' - send_notify(fulltext, dst_account) - except ChatException as e: - raise TaskException(e) +def handle(task, author, recipients, abon_group): + errors = [] + for recipient in recipients: + try: + dst_account = recipient + text = _('Task') + # Если сигнал самому себе то молчим + if author == recipient: + return + # Если задача завершена или провалена + elif task.state == 'F' or task.state == 'C': + text = _('Task completed') + if task.abon is not None: + fulltext = "%s:\n%s\n" % (text, task.abon.get_full_name()) + else: + fulltext = "%s\n" % text + fulltext += _('locality %s.\n') % abon_group.title + if task.abon: + fulltext += _('address %s %s.\ntelephone %s\n') % ( + task.abon.street.name if task.abon.street is not None else '<'+_('not chosen')+'>', + task.abon.house, + task.abon.telephone + ) + fulltext += _('Task type - %s.') % task.get_mode_display() + '\n' + fulltext += task.descr if task.descr else '' + + print('task.state:', task.state) + + if task.state == 'F' or task.state == 'C': + # Если задача завершена или провалена то отправляем одно оповещение автору + try: + send_notify(fulltext, author) + except ChatException as e: + raise TaskException(e) + else: + send_notify(fulltext, dst_account) + except ChatException as e: + errors.append(e) + if len(errors) > 0: + raise MultipleException(errors) diff --git a/taskapp/handle.sh b/taskapp/handle.sh index e08b533..8ac380f 100755 --- a/taskapp/handle.sh +++ b/taskapp/handle.sh @@ -44,6 +44,6 @@ fi FULLTEXT="$text: $ABON_FIO. $ABON_ADDR $ABON_TEL. $ABON_GRP. $FAIL_MODE. $DESCR" -echo "TO $RECIPIENT_TEL: $FULLTEXT" >> /tmp/task_sms.log +echo "TO $RECIPIENT_TEL: $FULLTEXT" /usr/bin/gammu-smsd-inject EMS $RECIPIENT_TEL -text "$FULLTEXT" -unicode diff --git a/taskapp/models.py b/taskapp/models.py index f4db733..37e30f6 100644 --- a/taskapp/models.py +++ b/taskapp/models.py @@ -6,8 +6,7 @@ from django.conf import settings from django.utils import timezone from django.utils.translation import ugettext as _ from abonapp.models import Abon -from .handle import handle as task_handle, TaskException -from mydefs import MultipleException +from .handle import handle as task_handle TASK_PRIORITIES = ( @@ -121,17 +120,10 @@ def task_handler(sender, instance, **kwargs): act_type='e', who=instance.author ) - errors = [] - for recipient in instance.recipients.all(): - try: - task_handle( - instance, instance.author, - recipient, group - ) - except TaskException as e: - errors.append(e) - if len(errors) > 0: - raise MultipleException(errors) + task_handle( + instance, instance.author, + instance.recipients.all(), group + ) #def task_delete(sender, instance, **kwargs): diff --git a/taskapp/views.py b/taskapp/views.py index c4e1966..d8ec471 100644 --- a/taskapp/views.py +++ b/taskapp/views.py @@ -6,6 +6,8 @@ from django.contrib import messages from abonapp.models import Abon from django.utils.translation import ugettext as _ from datetime import date + +from .handle import TaskException from .models import Task from mydefs import pag_mn, only_admins, safe_int, MultipleException, RuTimedelta from .forms import TaskFrm @@ -152,6 +154,8 @@ def task_add_edit(request, task_id=0): except MultipleException as errs: for err in errs.err_list: messages.add_message(request, messages.constants.ERROR, err) + except TaskException as e: + messages.error(request, e) return render(request, 'taskapp/add_edit_task.html', { 'form': frm, @@ -169,6 +173,8 @@ def task_finish(request, task_id): except MultipleException as errs: for err in errs.err_list: messages.add_message(request, messages.constants.ERROR, err) + except TaskException as e: + messages.error(request, e) return redirect('taskapp:home') @@ -189,4 +195,6 @@ def remind(request, task_id): except MultipleException as errs: for err in errs.err_list: messages.add_message(request, messages.constants.ERROR, err) + except TaskException as e: + messages.error(request, e) return redirect('taskapp:home') From 9e1d0810de05c59abeaa71c68d132cb2a24c5dc5 Mon Sep 17 00:00:00 2001 From: bashmak Date: Mon, 14 Aug 2017 14:12:26 +0300 Subject: [PATCH 179/179] fixbug --- abonapp/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abonapp/models.py b/abonapp/models.py index f291155..ce857b1 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -76,7 +76,7 @@ class AbonTariff(models.Model): class Meta: db_table = 'abonent_tariff' permissions = ( - ('can_complete_service', _('finish service perm')) + ('can_complete_service', _('finish service perm')), )