diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 8368e28..a349b40 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -1133,3 +1133,7 @@ msgstr "Выберите шлюз для абонента" msgid "Are you sure you want to free ip user session?" msgstr "Вы уверены что хотите удалить ip абонента?" + +msgid "Document list" +msgstr "Документы" + diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index cca8636..8795c4f 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -99,6 +99,10 @@ {% trans 'Remove subscriber' %} {% endif %} + + + {% trans 'Document list' %} + diff --git a/abonapp/views.py b/abonapp/views.py index 7954bc5..15a80f1 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -776,7 +776,7 @@ def abon_ping(request, gid: int, uname): @json_view def set_auto_continue_service(request, gid: int, uname): checked = request.GET.get('checked') - checked = True if checked == 'true' else False + checked = checked == 'true' abon = get_object_or_404(models.Abon, username=uname) abon.autoconnect_service = checked abon.save(update_fields=('autoconnect_service',)) @@ -845,7 +845,7 @@ def save_user_dev_port(request, gid: int, uname): return redirect('abonapp:abon_home', gid, uname) user_port = lib.safe_int(request.POST.get('user_port')) is_dynamic_ip = request.POST.get('is_dynamic_ip') - is_dynamic_ip = True if is_dynamic_ip == 'on' else False + is_dynamic_ip = is_dynamic_ip == 'on' try: abon = models.Abon.objects.get(username=uname) if user_port == 0: diff --git a/accounts_app/forms.py b/accounts_app/forms.py index 84ffb6b..986641c 100644 --- a/accounts_app/forms.py +++ b/accounts_app/forms.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from guardian.forms import UserObjectPermissionsForm from guardian.shortcuts import assign_perm, remove_perm from django import forms diff --git a/agent/netflow/netflow_collect.sh b/agent/netflow/netflow_collect.sh index 831ad47..803fc2c 100644 --- a/agent/netflow/netflow_collect.sh +++ b/agent/netflow/netflow_collect.sh @@ -15,7 +15,7 @@ spec.loader.exec_module(ls) db = ls.DATABASES ldb = db.get('default') print('%s %s %s %s %d' % (ldb['NAME'], ldb['USER'], -ldb['PASSWORD'], ldb['HOST'], ldb['PORT']))"` +ldb['PASSWORD'], ldb['HOST'], ldb.get('PORT', 3306)))"` if ! ping -c 1 ${mysql_host} &> /dev/null; then echo "Host ${mysql_host} is not accessible" @@ -46,4 +46,4 @@ flow-cat /tmp/djing_flow/dump/*/*.dmp | ./djing_flow -i ${tmp_ipuser_file} -c | rm -f ${tmp_ipuser_file} rm -f /tmp/djing_flow/dump/*/*.dmp -rm -f /tmp/djing_flow/*/ft* \ No newline at end of file +rm -f /tmp/djing_flow/*/ft* diff --git a/clientsideapp/views.py b/clientsideapp/views.py index e2ec01d..e5e93ad 100644 --- a/clientsideapp/views.py +++ b/clientsideapp/views.py @@ -17,7 +17,7 @@ from gw_app.nas_managers import NasFailedResult, NasNetworkError @login_required def home(request): num_active_tasks = Task.objects.filter( - abon=request.user, state='S' + abon=request.user, state=0 ).count() return render(request, 'clientsideapp/index.html', { 'num_active_tasks': num_active_tasks @@ -38,7 +38,7 @@ def services(request): abon = request.user all_tarifs = Tariff.objects.get_tariffs_by_group( abon.group.pk - )# .filter(is_admin=False) + ).filter(is_admin=False) current_service = abon.active_tariff() except Abon.DoesNotExist: all_tarifs = None @@ -140,7 +140,7 @@ def task_history(request): @json_view def set_auto_continue_service(request): checked = request.GET.get('checked') - checked = True if checked == 'true' else False + checked = checked == 'true' abon = request.user abon.autoconnect_service = checked abon.save(update_fields=('autoconnect_service',)) diff --git a/devapp/dev_types.py b/devapp/dev_types.py index 3c887df..a1c88fe 100644 --- a/devapp/dev_types.py +++ b/devapp/dev_types.py @@ -113,7 +113,7 @@ class DLinkDevice(DevBase, SNMPBaseWorker): uptimes = self.get_list('.1.3.6.1.2.1.2.2.1.9') try: for num in ints: - status = True if int(next(stats)) == 1 else False + status = int(next(stats)) == 1 yield DLinkPort( num=num, name=next(nams), @@ -187,7 +187,7 @@ class OLTDevice(DevBase, SNMPBaseWorker): onu = ONUdev( num=n, name=self.get_item('.1.3.6.1.2.1.2.2.1.2.%d' % n), - status=True if status == '3' else False, + status=status == '3', mac=self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % n), speed=0, signal=signal / 10 if signal else '—', @@ -268,7 +268,7 @@ class OnuDevice(DevBase, SNMPBaseWorker): distance = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.27.%d' % num) mac = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % num) if mac is not None: - mac = ':'.join('%x' % ord(i) for i in mac) + mac = ':'.join('%x' % i for i in mac) # uptime = self.get_item('.1.3.6.1.2.1.2.2.1.9.%d' % num) if status is not None and status.isdigit(): return { @@ -276,7 +276,7 @@ class OnuDevice(DevBase, SNMPBaseWorker): 'signal': signal / 10 if signal else '—', 'name': self.get_item('.1.3.6.1.2.1.2.2.1.2.%d' % num), 'mac': mac, - 'distance': int(distance) / 10 if distance.isdigit() else 0 + 'distance': distance / 10 if distance else 0 } except EasySNMPTimeoutError as e: return {'err': "%s: %s" % (_('ONU not connected'), e)} @@ -391,27 +391,6 @@ class Olt_ZTE_C320(OLTDevice): } for fiber_name, fiber_id in self.get_list_keyval('.1.3.6.1.4.1.3902.1012.3.13.1.1.1')) return fibers - def get_ports_on_fiber(self, fiber_num: int) -> Iterable: - - onu_types = self.get_list_keyval('.1.3.6.1.4.1.3902.1012.3.28.1.1.1.%d' % fiber_num) - onu_ports = self.get_list('.1.3.6.1.4.1.3902.1012.3.28.1.1.2.%d' % fiber_num) - onu_signals = safe_int(self.get_list('.1.3.6.1.4.1.3902.1012.3.50.12.1.1.10.%d' % fiber_num)) - - # Real sn in last 3 octets - onu_sns = self.get_list('.1.3.6.1.4.1.3902.1012.3.28.1.1.5.%d' % fiber_num) - onu_prefixs = self.get_list('.1.3.6.1.4.1.3902.1012.3.50.11.2.1.1.%d' % fiber_num) - onu_list = ({ - 'onu_type': onu_type_num[0], - 'onu_port': onu_port, - 'onu_signal': conv_zte_signal(onu_signal), - 'onu_sn': onu_prefix + ''.join('%.2X' % ord(i) for i in onu_sn[-4:]), # Real sn in last 4 octets, - 'snmp_extra': "%d.%d" % (fiber_num, safe_int(onu_type_num[1])), - } for onu_type_num, onu_port, onu_signal, onu_sn, onu_prefix in zip( - onu_types, onu_ports, onu_signals, onu_sns, onu_prefixs - )) - - return onu_list - def get_units_unregistered(self, fiber_num: int) -> Iterable: sn_num_list = self.get_list_keyval('.1.3.6.1.4.1.3902.1012.3.13.3.1.2.%d' % fiber_num) firmware_ver = self.get_list('.1.3.6.1.4.1.3902.1012.3.13.3.1.11.%d' % fiber_num) @@ -596,9 +575,9 @@ class HuaweiSwitch(EltexSwitch): n = int(n) speed = self.get_item('.1.3.6.1.2.1.2.2.1.5.%d' % n) oper_status = safe_int(self.get_item('.1.3.6.1.2.1.2.2.1.7.%d' % n)) - oper_status = True if oper_status == 1 else False + oper_status = oper_status == 1 link_status = safe_int(self.get_item('.1.3.6.1.2.1.2.2.1.8.%d' % n)) - link_status = True if link_status == 1 else False + link_status = link_status == 1 ep = EltexPort( self, num=i+1, diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index 2b09633..64bd2f9 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -484,7 +484,7 @@ msgid "Are you sure you want to delete device?" msgstr "Вы уверены что хотите удалить устройство?" #: templates/devapp/devices.html:83 templates/devapp/devices_null_group.html:65 -msgid "Devices does not found" +msgid "Devices not found" msgstr "Нет созданных устройств" #: templates/devapp/devices.html:83 templates/devapp/devices.html:93 diff --git a/devapp/templates/devapp/custom_dev_page/onu.html b/devapp/templates/devapp/custom_dev_page/onu.html index fd6258a..ac2c2e1 100644 --- a/devapp/templates/devapp/custom_dev_page/onu.html +++ b/devapp/templates/devapp/custom_dev_page/onu.html @@ -59,9 +59,9 @@ {% else %}
- {% if onu_details.status == '3' %} + {% if onu_details.status == 3 %} - {% elif onu_details.status == '2' %} + {% elif onu_details.status == 2 %} {% else %} diff --git a/devapp/templates/devapp/custom_dev_page/onu_for_zte.html b/devapp/templates/devapp/custom_dev_page/onu_for_zte.html index 8575b7b..a8f89a1 100644 --- a/devapp/templates/devapp/custom_dev_page/onu_for_zte.html +++ b/devapp/templates/devapp/custom_dev_page/onu_for_zte.html @@ -60,9 +60,9 @@ {% else %}
- {% if onu_details.status == '1' %} + {% if onu_details.status == 1 %} - {% elif onu_details.status == '2' %} + {% elif onu_details.status == 2 %} {% else %} diff --git a/devapp/templates/devapp/devices.html b/devapp/templates/devapp/devices.html index e2d95a0..293b99c 100644 --- a/devapp/templates/devapp/devices.html +++ b/devapp/templates/devapp/devices.html @@ -82,7 +82,7 @@ {% empty %} - {% trans 'Devices does not found' %}. {% trans 'Create' %} + {% trans 'Devices not found' %}. {% trans 'Create' %} {% endfor %} {% endwith %} diff --git a/devapp/views.py b/devapp/views.py index 8aa9e81..74f8cad 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -681,7 +681,7 @@ def fix_onu(request): }) for srcmac, snmpnum in ports: # convert bytes mac address to str presentation mac address - real_mac = ':'.join('%x' % ord(i) for i in srcmac) + real_mac = ':'.join('%x' % i for i in srcmac) if mac == real_mac: onu.snmp_extra = str(snmpnum) onu.save(update_fields=('snmp_extra',)) diff --git a/djing/__init__.py b/djing/__init__.py index e2c9155..cccab17 100644 --- a/djing/__init__.py +++ b/djing/__init__.py @@ -57,7 +57,7 @@ default_app_config = 'abonapp.apps.AbonappConfig' def ping(ip_addr: str, count=1): if re.match(IP_ADDR_REGEX, ip_addr): response = os.system("`which ping` -4Anq -c%d -W1 %s > /dev/null" % (count, ip_addr)) - return True if response == 0 else False + return response == 0 else: return False diff --git a/djing/settings.py b/djing/settings.py index 93d79aa..558ade8 100644 --- a/djing/settings.py +++ b/djing/settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -* import os try: @@ -43,6 +42,10 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'encrypted_model_fields', 'django_cleanup.apps.CleanupConfig', + 'guardian', + 'pinax_theme_bootstrap', + 'bootstrapform', + 'bootstrap3', 'ip_pool', 'accounts_app', 'gw_app', @@ -59,10 +62,7 @@ INSTALLED_APPS = [ 'msg_app', 'group_app', 'new_customers', - 'guardian', - 'pinax_theme_bootstrap', - 'bootstrapform', - 'bootstrap3' + 'docsapp' ] if DEBUG: diff --git a/djing/urls.py b/djing/urls.py index a1dab3a..12fc23d 100644 --- a/djing/urls.py +++ b/djing/urls.py @@ -20,7 +20,8 @@ urlpatterns = [ path('messenger/', include('messenger.urls', namespace='messenger')), path('gw/', include('gw_app.urls', namespace='gw_app')), path('new_customers/', include('new_customers.urls', namespace='new_customers')), - path('fin/', include('finapp.urls', namespace='finapp')) + path('fin/', include('finapp.urls', namespace='finapp')), + path('docs/', include('docsapp.urls', namespace='docsapp')) # Switch language #path(r'i18n/', include('django.conf.urls.i18n')), diff --git a/docsapp/__init__.py b/docsapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docsapp/apps.py b/docsapp/apps.py new file mode 100644 index 0000000..2dc9042 --- /dev/null +++ b/docsapp/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DocsappConfig(AppConfig): + name = 'docsapp' diff --git a/docsapp/forms.py b/docsapp/forms.py new file mode 100644 index 0000000..8030259 --- /dev/null +++ b/docsapp/forms.py @@ -0,0 +1,8 @@ +from django import forms +from docsapp.models import DocumentTemplateModel + + +class DocumentTemplateModelForm(forms.ModelForm): + class Meta: + model = DocumentTemplateModel + fields = '__all__' diff --git a/docsapp/locale/ru/LC_MESSAGES/django.po b/docsapp/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000..eb91290 --- /dev/null +++ b/docsapp/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,71 @@ +# 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, 2019. +# +#, fuzzy +msgid "" +msgstr "" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-09-12 13:57+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" +"Language: ru\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" + +#: models.py:8 templates/docsapp/documenttemplatemodel_list.html:25 +msgid "Title" +msgstr "Название" + +#: models.py:10 +msgid "File docx template" +msgstr "Файл шаблон docx" + +#: templates/docsapp/documenttemplatemodel_confirm_delete.html:9 +msgid "Remove document" +msgstr "Удалить документ" + +#: templates/docsapp/documenttemplatemodel_confirm_delete.html:13 +msgid "Are you sure you want to delete this document?" +msgstr "Вы уверены что хотите удалить документ?" + +#: templates/docsapp/documenttemplatemodel_form.html:19 +msgid "Change document" +msgstr "Изменить документ" + +#: templates/docsapp/documenttemplatemodel_form.html:21 +#: templates/docsapp/documenttemplatemodel_list.html:58 +#: templates/docsapp/documenttemplatemodel_list.html:69 +msgid "Add document" +msgstr "Добавить документ" + +#: templates/docsapp/documenttemplatemodel_form.html:30 +msgid "Save" +msgstr "Сохранить" + +#: templates/docsapp/documenttemplatemodel_form.html:34 +msgid "Back" +msgstr "Назад" + +#: templates/docsapp/documenttemplatemodel_list.html:5 +#: templates/docsapp/documenttemplatemodel_list.html:11 +#: templates/docsapp/documenttemplatemodel_list.html:16 +msgid "Documents" +msgstr "Документы" + +#: templates/docsapp/documenttemplatemodel_list.html:26 +msgid "File" +msgstr "Файл" + +#: templates/docsapp/documenttemplatemodel_list.html:27 +msgid "Document type" +msgstr "Тип документа" + +#: templates/docsapp/documenttemplatemodel_list.html:57 +msgid "Documents not found" +msgstr "Документы не найдены" diff --git a/docsapp/migrations/0001_initial.py b/docsapp/migrations/0001_initial.py new file mode 100644 index 0000000..09c9ac8 --- /dev/null +++ b/docsapp/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.4 on 2019-09-12 12:52 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='DocumentTemplateModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=80, verbose_name='Title', unique=True)), + ('doc_template', models.FileField(upload_to='word_docs', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=('docx',))], verbose_name='File docx template')), + ], + options={ + 'db_table': 'documents', + 'ordering': ('title',), + }, + ), + ] diff --git a/docsapp/migrations/__init__.py b/docsapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docsapp/models.py b/docsapp/models.py new file mode 100644 index 0000000..52141ea --- /dev/null +++ b/docsapp/models.py @@ -0,0 +1,24 @@ +from django.shortcuts import resolve_url +from django.utils.translation import gettext_lazy as _ +from django.core.validators import FileExtensionValidator +from django.db import models + +from abonapp.models import Abon + + +class DocumentTemplateModel(models.Model): + title = models.CharField(_('Title'), max_length=80, unique=True) + doc_template = models.FileField( + _('File docx template'), upload_to='word_docs', + validators=[FileExtensionValidator(allowed_extensions=('docx',))] + ) + + def get_absolute_url(self): + return resolve_url('docsapp:doc_edit', pk=self.pk) + + def __str__(self): + return self.title + + class Meta: + db_table = 'documents' + ordering = ('title',) diff --git a/docsapp/templates/docsapp/documenttemplatemodel_confirm_delete.html b/docsapp/templates/docsapp/documenttemplatemodel_confirm_delete.html new file mode 100644 index 0000000..792772e --- /dev/null +++ b/docsapp/templates/docsapp/documenttemplatemodel_confirm_delete.html @@ -0,0 +1,14 @@ +{% extends 'base_delete_modal.html' %} +{% load i18n %} + +{% block modal_form_url %} + {% url 'docsapp:doc_del' object.pk %} +{% endblock %} + +{% block modal_form_title %} + {% trans 'Remove document' %} +{% endblock %} + +{% block modal_form_text %} +

{% trans 'Are you sure you want to delete this document?' %}

+{% endblock %} diff --git a/docsapp/templates/docsapp/documenttemplatemodel_form.html b/docsapp/templates/docsapp/documenttemplatemodel_form.html new file mode 100644 index 0000000..1bb0980 --- /dev/null +++ b/docsapp/templates/docsapp/documenttemplatemodel_form.html @@ -0,0 +1,39 @@ +{% extends request.is_ajax|yesno:'bajax.html,base.html' %} +{% load i18n bootstrap3 %} + +{% block main %} + + {% if object %} + {% url 'docsapp:doc_edit' object.pk as objurl %} + {% else %} + {% url 'docsapp:doc_add' as objurl %} + {% endif %} + +
{% csrf_token %} + + +
+{% endblock %} diff --git a/docsapp/templates/docsapp/documenttemplatemodel_list.html b/docsapp/templates/docsapp/documenttemplatemodel_list.html new file mode 100644 index 0000000..fc08c2e --- /dev/null +++ b/docsapp/templates/docsapp/documenttemplatemodel_list.html @@ -0,0 +1,77 @@ +{% extends request.is_ajax|yesno:'bajax.html,base.html' %} +{% load i18n %} + +{% block title %} + {% trans 'Documents' %} +{% endblock %} + +{% block breadcrumb %} + +{% endblock %} + +{% block page-header %} + {% trans 'Documents' %} +{% endblock %} + +{% block main %} +
+ + + + + + + + + + + + + {% with can_del_doc=perms.docsapp.delete_documenttemplatemodel can_ch_doc=perms.docsapp.change_documenttemplatemodel %} + {% for doc in object_list %} + + + + + + + + + {% empty %} + + + + {% endfor %} + {% endwith %} + + + + + + + + +
.{% trans 'Title' %}{% trans 'File' %}{% trans 'Document type' %}#
{{ doc.id }}{{ doc.title }}{{ doc.doc_template }}DocX + {% if can_del_doc %} + + + + {% endif %} + {% if can_ch_doc %} + + + + {% endif %} +
+ {% trans 'Documents not found' %}. + {% trans 'Add document' %} +
+ + {% trans 'Add document' %} + +
+
+{% endblock %} diff --git a/docsapp/templates/docsapp/simple_list.html b/docsapp/templates/docsapp/simple_list.html new file mode 100644 index 0000000..175185f --- /dev/null +++ b/docsapp/templates/docsapp/simple_list.html @@ -0,0 +1,26 @@ +{% load i18n %} + + + diff --git a/docsapp/urls.py b/docsapp/urls.py new file mode 100644 index 0000000..50cb896 --- /dev/null +++ b/docsapp/urls.py @@ -0,0 +1,14 @@ +from django.urls import path +from docsapp import views + +app_name = 'docsapp' + + +urlpatterns = [ + path('', views.DocumentsListView.as_view(), name='docs_list'), + path('add/', views.DocumentCreateView.as_view(), name='doc_add'), + path('/', views.DocumentUpdateView.as_view(), name='doc_edit'), + path('/del/', views.DocumentDeleteView.as_view(), name='doc_del'), + path('//render/', views.RenderDocument.as_view(), name='doc_render'), + path('/simple_list/', views.SimpleListView.as_view(), name='simple_list'), +] diff --git a/docsapp/views.py b/docsapp/views.py new file mode 100644 index 0000000..1395993 --- /dev/null +++ b/docsapp/views.py @@ -0,0 +1,101 @@ +from io import BytesIO + +from django.contrib import messages +from django.utils.datetime_safe import datetime +from django.utils.translation import gettext_lazy as _ +from django.views.generic import UpdateView, DeleteView, CreateView, DetailView, ListView +from django.contrib.auth.mixins import PermissionRequiredMixin +from django.core.exceptions import ValidationError +from django.http import HttpResponse +from django.shortcuts import redirect, get_object_or_404 +from django.urls import reverse_lazy +from docxtpl import DocxTemplate +from docx.opc.constants import CONTENT_TYPE +from jinja2.exceptions import UndefinedError, TemplateSyntaxError + +from abonapp.models import Abon +from djing.global_base_views import OrderedFilteredList +from djing.lib.mixins import LoginAdminMixin, LoginAdminPermissionMixin +from docsapp.models import DocumentTemplateModel +from docsapp.forms import DocumentTemplateModelForm + + +class DocumentsListView(LoginAdminMixin, OrderedFilteredList): + model = DocumentTemplateModel + + +class SimpleListView(LoginAdminMixin, ListView): + template_name = 'docsapp/simple_list.html' + model = DocumentTemplateModel + + def get_context_data(self, **kwargs): + kwargs.update({ + 'account_name': self.kwargs.get('account_name') + }) + return super().get_context_data(**kwargs) + + +class DocumentUpdateView(LoginAdminPermissionMixin, UpdateView): + permission_required = 'docsapp.change_documenttemplatemodel' + model = DocumentTemplateModel + form_class = DocumentTemplateModelForm + + +class DocumentDeleteView(LoginAdminPermissionMixin, DeleteView): + permission_required = 'docsapp.delete_documenttemplatemodel' + model = DocumentTemplateModel + success_url = reverse_lazy('docsapp:docs_list') + + +class DocumentCreateView(LoginAdminMixin, PermissionRequiredMixin, CreateView): + model = DocumentTemplateModel + form_class = DocumentTemplateModelForm + permission_required = 'docsapp.add_documenttemplatemodel' + + +class RenderDocument(LoginAdminPermissionMixin, DetailView): + model = DocumentTemplateModel + permission_required = 'docsapp.view_documenttemplatemodel' + context_object_name = 'document' + extra_context = { + 'date': datetime.now() + } + + def get(self, request, *args, **kwargs): + obj = self.get_object() + self.object = obj + acc = get_object_or_404(Abon, username=self.kwargs.get('uname')) + + try: + doc = DocxTemplate( + obj.doc_template.path + ) + context = self.get_context_data(object=obj) + context.update(self.get_context_account(acc)) + doc.render(context) + + destination_document_file = BytesIO() + doc.get_docx().save(destination_document_file) + resp = HttpResponse( + destination_document_file.getvalue(), + content_type=CONTENT_TYPE.WML_DOCUMENT + ) + resp['Content-Disposition'] = 'attachment; filename="document.docx"' + return resp + except (UndefinedError, ValidationError, TemplateSyntaxError) as e: + messages.error(request, str(e)) + return redirect('docsapp:docs_list') + + def get_context_account(self, account): + if not isinstance(account, Abon): + raise ValidationError(message=_('Account required and must be Abon')) + bp = '_' * 20 + return { + 'account': account, + 'passport': getattr(account, 'passportinfo', { + 'series': bp, + 'number': bp, + 'distributor': bp, + 'date_of_acceptance': bp + }) + } diff --git a/gw_app/nas_managers/mod_mikrotik.py b/gw_app/nas_managers/mod_mikrotik.py index 312715f..25d827d 100644 --- a/gw_app/nas_managers/mod_mikrotik.py +++ b/gw_app/nas_managers/mod_mikrotik.py @@ -235,7 +235,7 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos, name = info.get('=name') disabled = info.get('=disabled', False) if disabled is not None: - disabled = True if disabled == 'true' else False + disabled = disabled == 'true' if target and name: # target may be '192.168.0.3/32,192.168.0.2/32' net = target.split(',')[0] diff --git a/migrate2v2_dump.py b/migrate2v2_dump.py index 0f542a0..543132e 100644 --- a/migrate2v2_dump.py +++ b/migrate2v2_dump.py @@ -54,7 +54,7 @@ class BatchSaveStreamList(list): # image fields elif isinstance(field, ImageField): val = getattr(obj, field.name) - return getattr(val, 'url') if val else None + return getattr(val, 'name') if val else None # mac address validated by netaddr.EUI elif isinstance(field, MACAddressField): @@ -84,10 +84,14 @@ class BatchSaveStreamList(list): return 1 -def batch_save(fname, *args, **kwargs): +def batch_save(app_label: str, fname: str, *args, **kwargs): sa = BatchSaveStreamList(*args, **kwargs) - print(fname) - with open(fname, 'w') as f: + fixt_dir = os.path.join('fixtures', app_label, 'fixtures') + if not os.path.isdir(fixt_dir): + os.makedirs(fixt_dir, mode=0o750) + full_path = os.path.join(fixt_dir, fname) + print(full_path) + with open(full_path, 'w') as f: dump(sa, f, ensure_ascii=False, indent=2, cls=DjangoJSONEncoder) @@ -96,14 +100,15 @@ def batch_save(fname, *args, **kwargs): def dump_groups(): from group_app.models import Group - batch_save("groups.json", Group.objects.all(), 'groupapp.group') + batch_save(app_label='groupapp', fname="groups.json", model_queryset=Group.objects.all(), model_name='groupapp.group') def dump_accounts(): from accounts_app.models import UserProfile, BaseAccount, UserProfileLog - batch_save('accounts_baseaccount.json', BaseAccount.objects.exclude(username='AnonymousUser'), 'profiles.baseaccount', + app_label = 'profiles' + batch_save(app_label=app_label, fname='accounts_baseaccount.json', model_queryset=BaseAccount.objects.exclude(username='AnonymousUser'), model_name='profiles.baseaccount', except_fields=['groups', 'user_permissions']) - batch_save('accounts_userprofile.json', UserProfile.objects.exclude(username='AnonymousUser'), 'profiles.userprofile', + batch_save(app_label=app_label, fname='accounts_userprofile.json', model_queryset=UserProfile.objects.exclude(username='AnonymousUser'), model_name='profiles.userprofile', except_fields=['groups', 'user_permissions']) do_type_map = { 'cusr': 1, 'dusr': 2, @@ -111,7 +116,7 @@ def dump_accounts(): 'cnas': 5, 'dnas': 6, 'csrv': 7, 'dsrv': 8 } - batch_save('accounts_userprofilelog.json', UserProfileLog.objects.all(), 'profiles.userprofilelog', + batch_save(app_label=app_label, fname='accounts_userprofilelog.json', model_queryset=UserProfileLog.objects.all(), model_name='profiles.userprofilelog', except_fields=['meta_info'], choice_list_map={ 'do_type': do_type_map @@ -120,15 +125,17 @@ def dump_accounts(): def dump_messenger(): from messenger.models import Messenger, ViberMessenger, ViberMessage, ViberSubscriber - batch_save("messenger.json", Messenger.objects.all(), 'messenger.messenger') - batch_save("vibermessenger.json", ViberMessenger.objects.all(), 'messenger.vibermessenger') - batch_save("vibermessage.json", ViberMessage.objects.all(), 'messenger.vibermessage') - batch_save("vibersubscriber.json", ViberSubscriber.objects.all(), 'messenger.vibersubscriber') + app_label = 'messenger' + batch_save(app_label, "messenger.json", Messenger.objects.all(), 'messenger.messenger') + batch_save(app_label, "vibermessenger.json", ViberMessenger.objects.all(), 'messenger.vibermessenger') + batch_save(app_label, "vibermessage.json", ViberMessage.objects.all(), 'messenger.vibermessage') + batch_save(app_label, "vibersubscriber.json", ViberSubscriber.objects.all(), 'messenger.vibersubscriber') def dump_services(): from tariff_app.models import Tariff, PeriodicPay - batch_save("services.json", Tariff.objects.all(), 'services.service', field_name_map={ + app_label = 'services' + batch_save(app_label, "services.json", Tariff.objects.all(), 'services.service', field_name_map={ 'speedIn': 'speed_in', 'speedOut': 'speed_out', 'amount': 'cost' @@ -140,7 +147,7 @@ def dump_services(): 'Dl': 3 } }) - batch_save("services_periodicpay.json", PeriodicPay.objects.all(), 'services.periodicpay', choice_list_map={ + batch_save(app_label, "services_periodicpay.json", PeriodicPay.objects.all(), 'services.periodicpay', choice_list_map={ 'calc_type': { 'df': 0, 'cs': 1 @@ -150,7 +157,8 @@ def dump_services(): def dump_gateways(): from gw_app.models import NASModel - batch_save("gateways.json", NASModel.objects.all(), 'gateways.gateway', field_name_map={ + app_label = 'gateways' + batch_save(app_label, "gateways.json", NASModel.objects.all(), 'gateways.gateway', field_name_map={ 'nas_type': 'gw_type', 'default': 'is_default' }, choice_list_map={ @@ -162,7 +170,8 @@ def dump_gateways(): def dump_devices(): from devapp.models import Device, Port - batch_save("devices.json", Device.objects.all(), 'devices.device', field_name_map={ + app_label = 'devices' + batch_save(app_label, "devices.json", Device.objects.all(), 'devices.device', field_name_map={ 'devtype': 'dev_type' }, choice_list_map={ 'devtype': { @@ -178,7 +187,7 @@ def dump_devices(): 'dwn': 3 } }) - batch_save('devices_port.json', Port.objects.all(), 'devices.port') + batch_save(app_label, 'devices_port.json', Port.objects.all(), 'devices.port') def dump_customers(): @@ -187,41 +196,43 @@ def dump_customers(): PassportInfo, InvoiceForPayment, AbonRawPassword, AdditionalTelephone, PeriodicPayForId ) - batch_save('customer.json', Abon.objects.exclude(username='AnonymousUser'), 'customers.customer', field_name_map={ + app_label = 'customers' + batch_save(app_label, 'customer.json', Abon.objects.exclude(username='AnonymousUser'), 'customers.customer', field_name_map={ 'current_tariff': 'current_service', 'ballance': 'balance', 'nas': 'gateway', 'autoconnect_service': 'auto_renewal_service', 'last_connected_tariff': 'last_connected_service' }, except_fields=['groups', 'user_permissions']) - batch_save('customers_log.json', AbonLog.objects.all(), 'customers.customerlog', field_name_map={ + batch_save(app_label, 'customers_log.json', AbonLog.objects.all(), 'customers.customerlog', field_name_map={ 'abon': 'customer', 'amount': 'cost' }) - batch_save('customers_service.json', AbonTariff.objects.all(), 'customers.customerservice', field_name_map={ + batch_save(app_label, 'customers_service.json', AbonTariff.objects.all(), 'customers.customerservice', field_name_map={ 'tariff': 'service', 'time_start': 'start_time' }) - batch_save('customers_street.json', AbonStreet.objects.all(), 'customers.customerstreet') - batch_save('customers_passport.json', PassportInfo.objects.all(), 'customers.passportinfo', field_name_map={ + batch_save(app_label, 'customers_street.json', AbonStreet.objects.all(), 'customers.customerstreet') + batch_save(app_label, 'customers_passport.json', PassportInfo.objects.all(), 'customers.passportinfo', field_name_map={ 'abon': 'customer' }) - batch_save('customers_inv.json', InvoiceForPayment.objects.all(), 'customers.invoiceforpayment', field_name_map={ + batch_save(app_label, 'customers_inv.json', InvoiceForPayment.objects.all(), 'customers.invoiceforpayment', field_name_map={ 'abon': 'customer', 'amount': 'cost' }) - batch_save('customers_passw.json', AbonRawPassword.objects.all(), 'customers.customerrawpassword', field_name_map={ + batch_save(app_label, 'customers_passw.json', AbonRawPassword.objects.all(), 'customers.customerrawpassword', field_name_map={ 'account': 'customer' }) - batch_save('customers_tels.json', AdditionalTelephone.objects.all(), 'customers.additionaltelephone', field_name_map={ + batch_save(app_label, 'customers_tels.json', AdditionalTelephone.objects.all(), 'customers.additionaltelephone', field_name_map={ 'abon': 'customer' }) - batch_save('customers_tels.json', PeriodicPayForId.objects.all(), 'customers.periodicpayforid') + batch_save(app_label, 'customers_tels.json', PeriodicPayForId.objects.all(), 'customers.periodicpayforid') def dump_networks(): from ip_pool.models import NetworkModel - batch_save('nets.json', NetworkModel.objects.all(), 'networks.networkmodel', choice_list_map={ + app_label = 'networks' + batch_save(app_label, 'nets.json', NetworkModel.objects.all(), 'networks.networkmodel', choice_list_map={ 'kind': { 'inet': 1, 'guest': 2, @@ -234,7 +245,8 @@ def dump_networks(): def dump_tasks(): from taskapp.models import Task, ExtraComment, ChangeLog - batch_save('task.json', Task.objects.all(), 'tasks.task', field_name_map={ + app_label = 'tasks' + batch_save(app_label, 'task.json', Task.objects.all(), 'tasks.task', field_name_map={ 'abon': 'customer' }, except_fields=['attachment'], choice_list_map={ 'priority': { @@ -257,8 +269,8 @@ def dump_tasks(): 'ot': 12 } }) - batch_save('task_comments.json', ExtraComment.objects.all(), 'tasks.extracomment') - batch_save('task_log.json', ChangeLog.objects.all(), 'tasks.changelog', choice_list_map={ + batch_save(app_label, 'task_comments.json', ExtraComment.objects.all(), 'tasks.extracomment') + batch_save(app_label, 'task_log.json', ChangeLog.objects.all(), 'tasks.changelog', choice_list_map={ 'act_type': { 'e': 1, 'c': 2, 'd': 3, 'f': 4, 'b': 5 @@ -266,10 +278,21 @@ def dump_tasks(): }) +def dump_fin(): + from finapp.models import PayAllTimeGateway, AllTimePayLog + app_label = 'fin_app' + batch_save(app_label, 'fin_gws.json', PayAllTimeGateway.objects.all(), 'fin_app.payalltimegateway') + batch_save(app_label, 'fin_logs.json', AllTimePayLog.objects.all(), 'fin_app.alltimepaylog', field_name_map={ + 'abon': 'customer', + 'summ': 'sum' + }) + + all_migrs = ( dump_groups, dump_accounts, dump_messenger, dump_services, dump_gateways, dump_devices, - dump_customers, dump_networks, dump_tasks + dump_customers, dump_networks, dump_tasks, + dump_fin ) if __name__ == '__main__': diff --git a/periodic.py b/periodic.py index 90e378e..d5e7b9d 100755 --- a/periodic.py +++ b/periodic.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/var/www/djing/venv/bin/python import os from threading import Thread import django diff --git a/requirements.txt b/requirements.txt index 0ca642a..97ae54f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,31 +1,30 @@ -wheel -urllib3 -Django>=2 -Pillow +urllib3==1.25.10 +Django==2.2.17 +Pillow==7.2.0 # for mac address field -netaddr +netaddr==0.8.0 # for testing required xmltodict #xmltodict -dicttoxml +dicttoxml==1.7.4 # db client for Mariadb mysqlclient -easysnmp -pid -django-guardian -pinax-theme-bootstrap -django-bootstrap3 +git+git://github.com/nerosketch/easysnmp.git#egg=easysnmp +pid==3.0.4 +django-guardian==2.3.0 +pinax-theme-bootstrap==8.0.1 +django-bootstrap3==14.1.0 # django-jsonfield -e git://github.com/dmkoch/django-jsonfield.git#egg=django-jsonfield -requests -webdavclient -transliterate -django-encrypted-model-fields +requests==2.24.0 +webdavclient==1.0.8 +transliterate==1.10.2 +django-encrypted-model-fields==0.5.8 # django-xmlview for pay system allpay -e git://github.com/nerosketch/django-xmlview.git#egg=django-xmlview @@ -43,5 +42,7 @@ django-encrypted-model-fields -e git://github.com/pexpect/pexpect.git#egg=pexpect Celery -redis +redis==3.5.3 celery[redis] + +docxtpl diff --git a/systemd_units/djing.timer b/systemd_units/djing.timer index ec8b50b..e3d7ef0 100644 --- a/systemd_units/djing.timer +++ b/systemd_units/djing.timer @@ -3,7 +3,6 @@ Description=Run every night a job for djing [Timer] OnCalendar=*-*-* 01:59:00 -Persistent=true Unit=djing.service [Install] diff --git a/systemd_units/djing_backup.timer b/systemd_units/djing_backup.timer index 8bcea86..c447d9b 100644 --- a/systemd_units/djing_backup.timer +++ b/systemd_units/djing_backup.timer @@ -3,7 +3,6 @@ Description=Run backup periodically [Timer] OnCalendar=*-*-* 8,12,14,16,19,23:15:0 -Persistent=true Unit=djing_backup.service [Install] diff --git a/systemd_units/webdav_backup.py b/systemd_units/webdav_backup.py index 1645272..cc7b6ed 100644 --- a/systemd_units/webdav_backup.py +++ b/systemd_units/webdav_backup.py @@ -9,14 +9,15 @@ options = { 'webdav_login': "YANDEX USERNAME", 'webdav_password': "YANDEX PASSWORD" } +REMOTE_DIR = 'DjingBackups' def remove_old_files(border_time: datetime, client): # files that older than border_time will be removed - for file in client.list('ISBackups'): + for file in client.list(REMOTE_DIR): fdate = datetime.strptime(file, 'djing%Y-%m-%d_%H.%M.%S.sql.gz') if fdate < border_time: - del_fname = os.path.join('ISBackups', file) + del_fname = os.path.join(REMOTE_DIR, file) client.clean(del_fname) print("rm %s" % del_fname) @@ -30,7 +31,7 @@ if __name__ == '__main__': remove_old_files(border_time, client) else: client.upload_sync( - remote_path=os.path.join('ISBackups', reqfile), + remote_path=os.path.join(REMOTE_DIR, reqfile), local_path=os.path.join(os.path.sep, 'var', 'backups', reqfile) ) except wc.WebDavException as we: diff --git a/tariff_app/custom_tariffs.py b/tariff_app/custom_tariffs.py index d0001a6..7aeadf3 100644 --- a/tariff_app/custom_tariffs.py +++ b/tariff_app/custom_tariffs.py @@ -1,14 +1,12 @@ -# -*- coding: utf-8 -*- from datetime import timedelta, datetime, date -from typing import AnyStr + from calendar import monthrange +from random import uniform from django.utils import timezone from django.utils.translation import gettext as _ from .base_intr import TariffBase, PeriodicPayCalcBase -from random import uniform - class TariffDefault(TariffBase): description = _('Base calculate functionality') @@ -101,7 +99,7 @@ class PeriodicPayCalcDefault(PeriodicPayCalcBase): today = date.today() nw = datetime(today.year, today.month, today.day) days = monthrange(nw.year, nw.month)[1] - return nw + timedelta(days - nw.day+1) + return nw + timedelta(days - nw.day + 1) class PeriodicPayCalcCustom(PeriodicPayCalcDefault): diff --git a/templates/base.html b/templates/base.html index 80091e0..a089293 100644 --- a/templates/base.html +++ b/templates/base.html @@ -129,6 +129,12 @@ + {% url 'docsapp:docs_list' as docslist %} + + + {% trans 'Documents' %} + +
diff --git a/templates/custom_pages/footer.htm b/templates/custom_pages/footer.htm index 55ce634..2ee2ea3 100644 --- a/templates/custom_pages/footer.htm +++ b/templates/custom_pages/footer.htm @@ -1 +1 @@ -Your custom content here. \ No newline at end of file +{# Your custom content here. #} diff --git a/templates/custom_pages/main_page.htm b/templates/custom_pages/main_page.htm index 27e1fca..f24dce8 100644 --- a/templates/custom_pages/main_page.htm +++ b/templates/custom_pages/main_page.htm @@ -1 +1 @@ -

You can change this page

\ No newline at end of file +{#

You can change this page

#} diff --git a/templates/custom_pages/service.htm b/templates/custom_pages/service.htm index a987da4..c2f67a8 100644 --- a/templates/custom_pages/service.htm +++ b/templates/custom_pages/service.htm @@ -1,2 +1,2 @@ -

Your custom content

-

You have service variable {{ active_service }}

\ No newline at end of file +{#

Your custom content

#} +{#

You have service variable {{ active_service }}

#} diff --git a/templates/custom_pages/service_bottom.htm b/templates/custom_pages/service_bottom.htm index 89cbb76..21fb88e 100644 --- a/templates/custom_pages/service_bottom.htm +++ b/templates/custom_pages/service_bottom.htm @@ -1 +1 @@ -

Your custom content on bottom

\ No newline at end of file +{#

Your custom content on bottom

#}