Browse Source

Merge branch 'devel' of https://github.com/nerosketch/djing into devel

devel
www-data 8 years ago
parent
commit
8f8d85747a
  1. 18
      abonapp/forms.py
  2. 2
      abonapp/locale/ru/LC_MESSAGES/django.po
  3. 30
      abonapp/models.py
  4. 2
      abonapp/pay_systems.py
  5. 22
      abonapp/tests.py
  6. 75
      abonapp/views.py
  7. 4
      accounts_app/forms.py
  8. 12
      accounts_app/models.py
  9. 18
      accounts_app/views.py
  10. 6
      agent/commands/dhcp.py
  11. 116
      agent/mod_mikrotik.py
  12. 14
      agent/monitoring_agent.py
  13. 1
      agent/netflow/netflow_handler.py
  14. 1
      agent/utils.py
  15. 8
      chatbot/models.py
  16. 4
      chatbot/telebot.py
  17. 4
      clientsideapp/views.py
  18. 2
      devapp/base_intr.py
  19. 2
      devapp/dev_types.py
  20. 8
      devapp/models.py
  21. 55
      devapp/views.py
  22. 6
      dialing_app/models.py
  23. 12
      dialing_app/views.py
  24. 2
      group_app/models.py
  25. 6
      group_app/views.py
  26. 2
      mapapp/models.py
  27. 2
      mapapp/views.py
  28. 4
      messaging/utils.py
  29. 14
      msg_app/models.py
  30. 2
      mydefs.py
  31. 1
      requirements.txt
  32. 16
      statistics/models.py
  33. 6
      tariff_app/models.py
  34. 4
      tariff_app/views.py
  35. 6
      taskapp/models.py
  36. 20
      taskapp/views.py

18
abonapp/forms.py

@ -12,10 +12,10 @@ TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^(\+[7,8,9,3]\d{10,11
def generate_random_chars(length=6, chars=digits, split=2, delimiter=''): def generate_random_chars(length=6, chars=digits, split=2, delimiter=''):
username = ''.join([choice(chars) for i in range(length)])
username = ''.join(choice(chars) for i in range(length))
if split: if split:
username = delimiter.join([username[start:start + split] for start in range(0, len(username), split)])
username = delimiter.join(username[start:start + split] for start in range(0, len(username), split))
try: try:
models.Abon.objects.get(username=username) models.Abon.objects.get(username=username)
@ -65,7 +65,7 @@ class AbonForm(forms.ModelForm):
class Meta: class Meta:
model = models.Abon model = models.Abon
fields = ['username', 'telephone', 'fio', 'group', 'description', 'street', 'house', 'is_active', 'ip_address']
fields = ('username', 'telephone', 'fio', 'group', 'description', 'street', 'house', 'is_active', 'ip_address')
widgets = { widgets = {
'fio': forms.TextInput(attrs={ 'fio': forms.TextInput(attrs={
'placeholder': _('fio'), 'placeholder': _('fio'),
@ -88,7 +88,7 @@ class AbonForm(forms.ModelForm):
try: try:
abon_raw_passw = models.AbonRawPassword.objects.get(account=acc) abon_raw_passw = models.AbonRawPassword.objects.get(account=acc)
abon_raw_passw.passw_text = raw_password abon_raw_passw.passw_text = raw_password
abon_raw_passw.save(update_fields=['passw_text'])
abon_raw_passw.save(update_fields=('passw_text',))
except models.AbonRawPassword.DoesNotExist: except models.AbonRawPassword.DoesNotExist:
models.AbonRawPassword.objects.create( models.AbonRawPassword.objects.create(
account=acc, account=acc,
@ -100,7 +100,7 @@ class AbonForm(forms.ModelForm):
class PassportForm(forms.ModelForm): class PassportForm(forms.ModelForm):
class Meta: class Meta:
model = models.PassportInfo model = models.PassportInfo
exclude = ['abon']
exclude = ('abon',)
widgets = { widgets = {
'series': forms.TextInput(attrs={'required': '', 'pattern': '^\d{4}$'}), 'series': forms.TextInput(attrs={'required': '', 'pattern': '^\d{4}$'}),
'number': forms.TextInput(attrs={'required': '', 'pattern': '^\d{6}$'}), 'number': forms.TextInput(attrs={'required': '', 'pattern': '^\d{6}$'}),
@ -136,7 +136,7 @@ class AbonStreetForm(forms.ModelForm):
class AdditionalTelephoneForm(forms.ModelForm): class AdditionalTelephoneForm(forms.ModelForm):
class Meta: class Meta:
model = models.AdditionalTelephone model = models.AdditionalTelephone
exclude = ['abon']
exclude = ('abon',)
widgets = { widgets = {
'telephone': forms.TextInput(attrs={ 'telephone': forms.TextInput(attrs={
'placeholder': _('telephone placeholder'), 'placeholder': _('telephone placeholder'),
@ -151,7 +151,7 @@ class AdditionalTelephoneForm(forms.ModelForm):
class PeriodicPayForIdForm(forms.ModelForm): class PeriodicPayForIdForm(forms.ModelForm):
class Meta: class Meta:
model = models.PeriodicPayForId model = models.PeriodicPayForId
exclude = ['account']
exclude = ('account',)
class ExportUsersForm(forms.Form): class ExportUsersForm(forms.Form):
@ -179,8 +179,8 @@ class ExportUsersForm(forms.Form):
class MarkersForm(forms.ModelForm): class MarkersForm(forms.ModelForm):
class Meta: class Meta:
model = models.Abon model = models.Abon
fields = ['markers']
fields = ('markers',)
def save(self, commit=True): def save(self, commit=True):
instance = super(MarkersForm, self).save(commit=False) instance = super(MarkersForm, self).save(commit=False)
return instance.save(update_fields=['markers'])
return instance.save(update_fields=('markers',))

2
abonapp/locale/ru/LC_MESSAGES/django.po

@ -1153,7 +1153,7 @@ msgid "Payments"
msgstr "Финансы" msgstr "Финансы"
msgid "History of tasks" msgid "History of tasks"
msgstr "История платежей"
msgstr "История задач"
msgid "Charts" msgid "Charts"
msgstr "Графики" msgstr "Графики"

30
abonapp/models.py

@ -34,7 +34,7 @@ class AbonLog(models.Model):
permissions = ( permissions = (
('can_view_abonlog', _('Can view subscriber logs')), ('can_view_abonlog', _('Can view subscriber logs')),
) )
ordering = ['-date']
ordering = ('-date',)
def __str__(self): def __str__(self):
return self.comment return self.comment
@ -68,7 +68,7 @@ class AbonTariff(models.Model):
) )
verbose_name = _('Abon service') verbose_name = _('Abon service')
verbose_name_plural = _('Abon services') verbose_name_plural = _('Abon services')
ordering = ['time_start']
ordering = ('time_start',)
class AbonStreet(models.Model): class AbonStreet(models.Model):
@ -82,7 +82,7 @@ class AbonStreet(models.Model):
db_table = 'abon_street' db_table = 'abon_street'
verbose_name = _('Street') verbose_name = _('Street')
verbose_name_plural = _('Streets') verbose_name_plural = _('Streets')
ordering = ['name']
ordering = ('name',)
class ExtraFieldsModel(models.Model): class ExtraFieldsModel(models.Model):
@ -185,7 +185,7 @@ class Abon(BaseAccount):
# unique_together = ('device', 'dev_port') # unique_together = ('device', 'dev_port')
verbose_name = _('Abon') verbose_name = _('Abon')
verbose_name_plural = _('Abons') verbose_name_plural = _('Abons')
ordering = ['fio']
ordering = ('fio',)
def add_ballance(self, current_user, amount, comment): def add_ballance(self, current_user, amount, comment):
AbonLog.objects.create( AbonLog.objects.create(
@ -273,7 +273,7 @@ class Abon(BaseAccount):
# check if ip address already busy # check if ip address already busy
if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude( if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude(
pk=self.pk).count() > 0: pk=self.pk).count() > 0:
raise ValidationError({'ip_address': [gettext('Ip address already exist')]})
raise ValidationError({'ip_address': (gettext('Ip address already exist'),)})
return super(Abon, self).clean() return super(Abon, self).clean()
def sync_with_nas(self, created: bool) -> Optional[Exception]: def sync_with_nas(self, created: bool) -> Optional[Exception]:
@ -292,8 +292,8 @@ class Abon(BaseAccount):
class PassportInfo(models.Model): class PassportInfo(models.Model):
series = models.CharField(_('Pasport serial'), max_length=4, validators=[validators.integer_validator])
number = models.CharField(_('Pasport number'), max_length=6, validators=[validators.integer_validator])
series = models.CharField(_('Pasport serial'), max_length=4, validators=(validators.integer_validator,))
number = models.CharField(_('Pasport number'), max_length=6, validators=(validators.integer_validator,))
distributor = models.CharField(_('Distributor'), max_length=64) distributor = models.CharField(_('Distributor'), max_length=64)
date_of_acceptance = models.DateField() date_of_acceptance = models.DateField()
abon = models.OneToOneField(Abon, on_delete=models.SET_NULL, blank=True, null=True) abon = models.OneToOneField(Abon, on_delete=models.SET_NULL, blank=True, null=True)
@ -302,7 +302,7 @@ class PassportInfo(models.Model):
db_table = 'passport_info' db_table = 'passport_info'
verbose_name = _('Passport Info') verbose_name = _('Passport Info')
verbose_name_plural = _('Passport Info') verbose_name_plural = _('Passport Info')
ordering = ['series']
ordering = ('series',)
def __str__(self): def __str__(self):
return "%s %s" % (self.series, self.number) return "%s %s" % (self.series, self.number)
@ -366,7 +366,7 @@ class AllTimePayLog(models.Model):
class Meta: class Meta:
db_table = 'all_time_pay_log' db_table = 'all_time_pay_log'
ordering = ['-date_add']
ordering = ('-date_add',)
# log for all terminals # log for all terminals
@ -381,7 +381,7 @@ class AllPayLog(models.Model):
class Meta: class Meta:
db_table = 'all_pay_log' db_table = 'all_pay_log'
ordering = ['-date_action']
ordering = ('-date_action',)
class AbonRawPassword(models.Model): class AbonRawPassword(models.Model):
@ -401,7 +401,7 @@ class AdditionalTelephone(models.Model):
max_length=16, max_length=16,
verbose_name=_('Telephone'), verbose_name=_('Telephone'),
# unique=True, # unique=True,
validators=[RegexValidator(TELEPHONE_REGEXP)]
validators=(RegexValidator(TELEPHONE_REGEXP),)
) )
owner_name = models.CharField(max_length=127) owner_name = models.CharField(max_length=127)
@ -410,7 +410,7 @@ class AdditionalTelephone(models.Model):
class Meta: class Meta:
db_table = 'additional_telephones' db_table = 'additional_telephones'
ordering = ['owner_name']
ordering = ('owner_name',)
permissions = ( permissions = (
('can_view_additionaltelephones', _('Can view additional telephones')), ('can_view_additionaltelephones', _('Can view additional telephones')),
) )
@ -439,17 +439,17 @@ class PeriodicPayForId(models.Model):
abon.add_ballance(author, -amount, comment=gettext('Charge for "%(service)s"') % { abon.add_ballance(author, -amount, comment=gettext('Charge for "%(service)s"') % {
'service': self.periodic_pay 'service': self.periodic_pay
}) })
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
self.last_pay = now self.last_pay = now
self.next_pay = next_pay_date self.next_pay = next_pay_date
self.save(update_fields=['last_pay', 'next_pay'])
self.save(update_fields=('last_pay', 'next_pay'))
def __str__(self): def __str__(self):
return "%s %s" % (self.periodic_pay, self.next_pay) return "%s %s" % (self.periodic_pay, self.next_pay)
class Meta: class Meta:
db_table = 'periodic_pay_for_id' db_table = 'periodic_pay_for_id'
ordering = ['last_pay']
ordering = ('last_pay',)
@receiver(post_delete, sender=Abon) @receiver(post_delete, sender=Abon)

2
abonapp/pay_systems.py

@ -65,7 +65,7 @@ def allpay(request):
return bad_ret(-100) return bad_ret(-100)
abon.add_ballance(None, pay_amount, comment='AllPay %.2f' % pay_amount) abon.add_ballance(None, pay_amount, comment='AllPay %.2f' % pay_amount)
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
AllTimePayLog.objects.create( AllTimePayLog.objects.create(
pay_id=pay_id, pay_id=pay_id,

22
abonapp/tests.py

@ -32,7 +32,7 @@ class AllPayTestCase(TestCase):
) )
a1.ballance = -13.12 a1.ballance = -13.12
a1.fio = 'Test Name' a1.fio = 'Test Name'
a1.save(update_fields=['ballance', 'fio'])
a1.save(update_fields=('ballance', 'fio'))
# Abon.objects.create_user( # Abon.objects.create_user(
# telephone='+79788163841', # telephone='+79788163841',
# username='pay_account2', # username='pay_account2',
@ -52,7 +52,7 @@ class AllPayTestCase(TestCase):
} }
)) ))
r = r.content.decode('utf-8') r = r.content.decode('utf-8')
self.assertXMLEqual(r, ''.join([
self.assertXMLEqual(r, ''.join((
"<pay-response>", "<pay-response>",
"<balance>-13.12</balance>", "<balance>-13.12</balance>",
"<name>Test Name</name>", "<name>Test Name</name>",
@ -63,7 +63,7 @@ class AllPayTestCase(TestCase):
"<status_code>21</status_code>", "<status_code>21</status_code>",
"<time_stamp>%s</time_stamp>" % current_date, "<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>" "</pay-response>"
]))
)))
def user_pay_pay(self): def user_pay_pay(self):
print('test_user_pay_pay') print('test_user_pay_pay')
@ -79,7 +79,7 @@ class AllPayTestCase(TestCase):
'SIGN': _make_sign(4, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') 'SIGN': _make_sign(4, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170')
})) }))
r = r.content.decode('utf-8') r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>", "<pay-response>",
"<pay_id>840ab457-e7d1-4494-8197-9570da035170</pay_id>", "<pay_id>840ab457-e7d1-4494-8197-9570da035170</pay_id>",
"<service_id>%s</service_id>" % SERVICE_ID, "<service_id>%s</service_id>" % SERVICE_ID,
@ -87,7 +87,7 @@ class AllPayTestCase(TestCase):
"<status_code>22</status_code>", "<status_code>22</status_code>",
"<time_stamp>%s</time_stamp>" % current_date, "<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>" "</pay-response>"
])
))
self.test_pay_time = current_date self.test_pay_time = current_date
self.assertXMLEqual(r, xml) self.assertXMLEqual(r, xml)
@ -103,7 +103,7 @@ class AllPayTestCase(TestCase):
} }
)) ))
r = r.content.decode('utf-8') r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>", "<pay-response>",
"<status_code>11</status_code>", "<status_code>11</status_code>",
"<time_stamp>%s</time_stamp>" % current_date, "<time_stamp>%s</time_stamp>" % current_date,
@ -115,7 +115,7 @@ class AllPayTestCase(TestCase):
"<time_stamp>%s</time_stamp>" % self.test_pay_time, "<time_stamp>%s</time_stamp>" % self.test_pay_time,
"</transaction>" "</transaction>"
"</pay-response>" "</pay-response>"
])
))
self.assertXMLEqual(r, xml) self.assertXMLEqual(r, xml)
def check_ballance(self): def check_ballance(self):
@ -148,12 +148,12 @@ class AllPayTestCase(TestCase):
} }
)) ))
r = r.content.decode('utf-8') r = r.content.decode('utf-8')
self.assertXMLEqual(r, ''.join([
self.assertXMLEqual(r, ''.join((
"<pay-response>", "<pay-response>",
"<status_code>-40</status_code>", "<status_code>-40</status_code>",
"<time_stamp>%s</time_stamp>" % current_date, "<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>" "</pay-response>"
]))
)))
def try_pay_double(self): def try_pay_double(self):
print('try_pay_double') print('try_pay_double')
@ -181,12 +181,12 @@ class AllPayTestCase(TestCase):
'SIGN': _make_sign(7, '', SERVICE_ID, uuid) 'SIGN': _make_sign(7, '', SERVICE_ID, uuid)
})) }))
r = r.content.decode('utf-8') r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>", "<pay-response>",
"<status_code>-10</status_code>", "<status_code>-10</status_code>",
"<time_stamp>%s</time_stamp>" % current_date, "<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>" "</pay-response>"
])
))
self.assertXMLEqual(r, xml) self.assertXMLEqual(r, xml)
def test_pays(self): def test_pays(self):

75
abonapp/views.py

@ -37,10 +37,10 @@ PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
class BaseAbonListView(OrderingMixin, BaseListWithFiltering): class BaseAbonListView(OrderingMixin, BaseListWithFiltering):
paginate_by = PAGINATION_ITEMS_PER_PAGE paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class PeoplesListView(BaseAbonListView): class PeoplesListView(BaseAbonListView):
context_object_name = 'peoples' context_object_name = 'peoples'
template_name = 'abonapp/peoples.html' template_name = 'abonapp/peoples.html'
@ -85,7 +85,7 @@ class PeoplesListView(BaseAbonListView):
return context return context
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class GroupListView(BaseAbonListView): class GroupListView(BaseAbonListView):
context_object_name = 'groups' context_object_name = 'groups'
template_name = 'abonapp/group_list.html' template_name = 'abonapp/group_list.html'
@ -98,7 +98,7 @@ class GroupListView(BaseAbonListView):
return queryset return queryset
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
@method_decorator(permission_required('abonapp.add_abon'), name='dispatch') @method_decorator(permission_required('abonapp.add_abon'), name='dispatch')
class AbonCreateView(CreateView): class AbonCreateView(CreateView):
group = None group = None
@ -154,7 +154,7 @@ class AbonCreateView(CreateView):
return super(AbonCreateView, self).form_invalid(form) return super(AbonCreateView, self).form_invalid(form)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
@method_decorator(permission_required('abonapp.delete_abon'), name='dispatch') @method_decorator(permission_required('abonapp.delete_abon'), name='dispatch')
class DelAbonDeleteView(DeleteView): class DelAbonDeleteView(DeleteView):
model = models.Abon model = models.Abon
@ -198,7 +198,7 @@ def abonamount(request, gid, uname):
if abonuname == uname: if abonuname == uname:
amnt = mydefs.safe_float(request.POST.get('amount')) amnt = mydefs.safe_float(request.POST.get('amount'))
abon.add_ballance(request.user, amnt, comment=_('fill account through admin side')) abon.add_ballance(request.user, amnt, comment=_('fill account through admin side'))
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
messages.success(request, _('Account filled successfully on %.2f') % amnt) messages.success(request, _('Account filled successfully on %.2f') % amnt)
return redirect('abonapp:abon_phistory', gid=gid, uname=uname) return redirect('abonapp:abon_phistory', gid=gid, uname=uname)
else: else:
@ -214,7 +214,7 @@ def abonamount(request, gid, uname):
}, request=request) }, request=request)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch') @method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
class DebtsListView(BaseAbonListView): class DebtsListView(BaseAbonListView):
context_object_name = 'invoices' context_object_name = 'invoices'
@ -232,7 +232,7 @@ class DebtsListView(BaseAbonListView):
return context return context
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch') @method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
class PayHistoryListView(BaseAbonListView): class PayHistoryListView(BaseAbonListView):
context_object_name = 'pay_history' context_object_name = 'pay_history'
@ -277,7 +277,7 @@ def abon_services(request, gid, uname):
}) })
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
@method_decorator(permission_required('abonapp.change_abon'), name='post') @method_decorator(permission_required('abonapp.change_abon'), name='post')
class AbonHomeUpdateView(UpdateView): class AbonHomeUpdateView(UpdateView):
model = models.Abon model = models.Abon
@ -473,7 +473,7 @@ def unsubscribe_service(request, gid, uname, abon_tariff_id):
@method_decorator(permission_required('abonapp.can_view_abonlog'), name='dispatch') @method_decorator(permission_required('abonapp.can_view_abonlog'), name='dispatch')
class LogListView(ListView): class LogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'logs' context_object_name = 'logs'
template_name = 'abonapp/log.html' template_name = 'abonapp/log.html'
model = models.AbonLog model = models.AbonLog
@ -483,7 +483,7 @@ class LogListView(ListView):
@method_decorator(permission_required('abonapp.can_view_invoiceforpayment'), name='dispatch') @method_decorator(permission_required('abonapp.can_view_invoiceforpayment'), name='dispatch')
class DebtorsListView(ListView): class DebtorsListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'invoices' context_object_name = 'invoices'
template_name = 'abonapp/debtors.html' template_name = 'abonapp/debtors.html'
queryset = models.InvoiceForPayment.objects.filter(status=True) queryset = models.InvoiceForPayment.objects.filter(status=True)
@ -493,7 +493,7 @@ class DebtorsListView(ListView):
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch') @method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
class TaskLogListView(ListView): class TaskLogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'tasks' context_object_name = 'tasks'
template_name = 'abonapp/task_log.html' template_name = 'abonapp/task_log.html'
@ -553,12 +553,12 @@ def chgroup_tariff(request, gid):
if request.method == 'POST': if request.method == 'POST':
tr = request.POST.getlist('tr') tr = request.POST.getlist('tr')
grp.tariff_set.clear() grp.tariff_set.clear()
grp.tariff_set.add(*[int(d) for d in tr])
grp.tariff_set.add(*(int(d) for d in tr))
grp.save() grp.save()
messages.success(request, _('Successfully saved')) messages.success(request, _('Successfully saved'))
return redirect('abonapp:ch_group_tariff', gid) return redirect('abonapp:ch_group_tariff', gid)
tariffs = Tariff.objects.all() tariffs = Tariff.objects.all()
seleted_tariffs_id = [pk[0] for pk in grp.tariff_set.only('pk').values_list('pk')]
seleted_tariffs_id = (pk[0] for pk in grp.tariff_set.only('pk').values_list('pk'))
return render(request, 'abonapp/group_tariffs.html', { return render(request, 'abonapp/group_tariffs.html', {
'group': grp, 'group': grp,
'seleted_tariffs': seleted_tariffs_id, 'seleted_tariffs': seleted_tariffs_id,
@ -575,7 +575,7 @@ def dev(request, gid, uname):
if request.method == 'POST': if request.method == 'POST':
dev = Device.objects.get(pk=request.POST.get('dev')) dev = Device.objects.get(pk=request.POST.get('dev'))
abon.device = dev abon.device = dev
abon.save(update_fields=['device'])
abon.save(update_fields=('device',))
messages.success(request, _('Device has successfully attached')) messages.success(request, _('Device has successfully attached'))
return redirect('abonapp:abon_home', gid=gid, uname=uname) return redirect('abonapp:abon_home', gid=gid, uname=uname)
else: else:
@ -600,7 +600,7 @@ def clear_dev(request, gid, uname):
abon = models.Abon.objects.get(username=uname) abon = models.Abon.objects.get(username=uname)
abon.device = None abon.device = None
abon.dev_port = None abon.dev_port = None
abon.save(update_fields=['device', 'dev_port'])
abon.save(update_fields=('device', 'dev_port'))
messages.success(request, _('Device has successfully unattached')) messages.success(request, _('Device has successfully unattached'))
except models.Abon.DoesNotExist: except models.Abon.DoesNotExist:
messages.error(request, _('Abon does not exist')) messages.error(request, _('Abon does not exist'))
@ -624,7 +624,7 @@ def charts(request, gid, uname):
abon = models.Abon.objects.get(username=uname) abon = models.Abon.objects.get(username=uname)
if abon.group is None: if abon.group is None:
abon.group = Group.objects.get(pk=gid) abon.group = Group.objects.get(pk=gid)
abon.save(update_fields=['group'])
abon.save(update_fields=('group',))
charts_data = StatElem.objects.chart( charts_data = StatElem.objects.chart(
abon.username, abon.username,
@ -692,16 +692,15 @@ def make_extra_field(request, gid, uname):
@login_required @login_required
@permission_required('abonapp.change_extra_fields_model') @permission_required('abonapp.change_extra_fields_model')
def extra_field_change(request, gid, uname): def extra_field_change(request, gid, uname):
extras = [(int(x), y) for x, y in zip(request.POST.getlist('ed'), request.POST.getlist('ex'))]
try: try:
for ex in extras:
extra_field = models.ExtraFieldsModel.objects.get(pk=ex[0])
extra_field.data = ex[1]
extra_field.save(update_fields=['data'])
for ed, ex in zip(request.POST.getlist('ed'), request.POST.getlist('ex')):
extra_field = models.ExtraFieldsModel.objects.get(pk=ed)
extra_field.data = ex
extra_field.save(update_fields=('data',))
messages.success(request, _("Extra fields has been saved")) messages.success(request, _("Extra fields has been saved"))
except models.ExtraFieldsModel.DoesNotExist: except models.ExtraFieldsModel.DoesNotExist:
messages.error(request, _('One or more extra fields has not been saved')) messages.error(request, _('One or more extra fields has not been saved'))
return redirect('abonapp:abon_home', gid=gid, username=uname)
return redirect('abonapp:abon_home', gid=gid, uname=uname)
@login_required @login_required
@ -763,7 +762,7 @@ def abon_ping(request):
} }
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins,), name='dispatch')
class DialsListView(BaseAbonListView): class DialsListView(BaseAbonListView):
context_object_name = 'logs' context_object_name = 'logs'
template_name = 'abonapp/dial_log.html' template_name = 'abonapp/dial_log.html'
@ -838,9 +837,9 @@ def save_user_dev_port(request, gid, uname):
abon.dev_port = port abon.dev_port = port
if abon.is_dynamic_ip != is_dynamic_ip: if abon.is_dynamic_ip != is_dynamic_ip:
abon.is_dynamic_ip = is_dynamic_ip abon.is_dynamic_ip = is_dynamic_ip
abon.save(update_fields=['dev_port', 'is_dynamic_ip'])
abon.save(update_fields=('dev_port', 'is_dynamic_ip'))
else: else:
abon.save(update_fields=['dev_port'])
abon.save(update_fields=('dev_port',))
messages.success(request, _('User port has been saved')) messages.success(request, _('User port has been saved'))
except DevPort.DoesNotExist: except DevPort.DoesNotExist:
messages.error(request, _('Selected port does not exist')) messages.error(request, _('Selected port does not exist'))
@ -875,9 +874,7 @@ def street_add(request, gid):
def street_edit(request, gid): def street_edit(request, gid):
try: try:
if request.method == 'POST': 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:
for sid, sname in zip(request.POST.getlist('sid'), request.POST.getlist('sname')):
street = models.AbonStreet.objects.get(pk=sid) street = models.AbonStreet.objects.get(pk=sid)
street.name = sname street.name = sname
street.save() street.save()
@ -993,7 +990,7 @@ def abon_export(request, gid):
response = HttpResponse(content_type='text/csv') response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="users.csv"' response['Content-Disposition'] = 'attachment; filename="users.csv"'
writer = csv.writer(response, quoting=csv.QUOTE_NONNUMERIC) writer = csv.writer(response, quoting=csv.QUOTE_NONNUMERIC)
display_values = [f[1] for f in frm.fields['fields'].choices if f[0] in fields]
display_values = (f[1] for f in frm.fields['fields'].choices if f[0] in fields)
writer.writerow(display_values) writer.writerow(display_values)
for row in subscribers: for row in subscribers:
writer.writerow(row) writer.writerow(row)
@ -1019,7 +1016,7 @@ def abon_export(request, gid):
def reset_ip(request, gid, uname): def reset_ip(request, gid, uname):
abon = get_object_or_404(models.Abon, username=uname) abon = get_object_or_404(models.Abon, username=uname)
abon.ip_address = None abon.ip_address = None
abon.save(update_fields=['ip_address'])
abon.save(update_fields=('ip_address',))
return { return {
'status': 0, 'status': 0,
'dat': "<span class='glyphicon glyphicon-refresh'></span>" 'dat': "<span class='glyphicon glyphicon-refresh'></span>"
@ -1087,9 +1084,9 @@ def del_periodic_pay(request, gid, uname, periodic_pay_id):
return redirect('abonapp:abon_services', gid, uname) return redirect('abonapp:abon_services', gid, uname)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins,), name='dispatch')
class EditSibscriberMarkers(UpdateView): class EditSibscriberMarkers(UpdateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'abonapp/modal_user_markers.html' template_name = 'abonapp/modal_user_markers.html'
form_class = forms.MarkersForm form_class = forms.MarkersForm
@ -1121,18 +1118,18 @@ class EditSibscriberMarkers(UpdateView):
@mydefs.only_admins @mydefs.only_admins
@json_view @json_view
def abons(request): def abons(request):
ablist = [{
ablist = ({
'id': abn.pk, 'id': abn.pk,
'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0, 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0,
'ip': abn.ip_address.int_ip(), 'ip': abn.ip_address.int_ip(),
'is_active': abn.is_active 'is_active': abn.is_active
} for abn in models.Abon.objects.all()]
} for abn in models.Abon.objects.all())
tarlist = [{
tarlist = ({
'id': trf.pk, 'id': trf.pk,
'speedIn': trf.speedIn, 'speedIn': trf.speedIn,
'speedOut': trf.speedOut 'speedOut': trf.speedOut
} for trf in Tariff.objects.all()]
} for trf in Tariff.objects.all())
data = { data = {
'subscribers': ablist, 'subscribers': ablist,
@ -1150,7 +1147,7 @@ def search_abon(request):
if not word: if not word:
return None return None
results = models.Abon.objects.filter(fio__icontains=word)[:8] results = models.Abon.objects.filter(fio__icontains=word)[:8]
results = [{'id': usr.pk, 'text': "%s: %s" % (usr.username, usr.fio)} for usr in results]
results = ({'id': usr.pk, 'text': "%s: %s" % (usr.username, usr.fio)} for usr in results)
return results return results
@ -1158,7 +1155,7 @@ class DhcpLever(SecureApiView):
# #
# Api view for dhcp event # Api view for dhcp event
# #
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view) @method_decorator(json_view)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

4
accounts_app/forms.py

@ -14,7 +14,7 @@ class MyUserObjectPermissionsForm(UserObjectPermissionsForm):
Should be called *after* form is validated. Should be called *after* form is validated.
""" """
perms = set(self.cleaned_data[self.get_obj_perms_field_name()]) perms = set(self.cleaned_data[self.get_obj_perms_field_name()])
model_perms = set([c[0] for c in self.get_obj_perms_field_choices()])
model_perms = set((c[0] for c in self.get_obj_perms_field_choices()))
init_perms = set(self.get_obj_perms_field_initial()) init_perms = set(self.get_obj_perms_field_initial())
to_remove = (model_perms - perms) & init_perms to_remove = (model_perms - perms) & init_perms
@ -28,4 +28,4 @@ class MyUserObjectPermissionsForm(UserObjectPermissionsForm):
class AvatarChangeForm(forms.ModelForm): class AvatarChangeForm(forms.ModelForm):
class Meta: class Meta:
model = UserProfile model = UserProfile
fields = ['avatar']
fields = ('avatar',)

12
accounts_app/models.py

@ -50,7 +50,7 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
_('profile username'), _('profile username'),
max_length=127, max_length=127,
unique=True, unique=True,
validators=[RegexValidator(r'^\w{1,127}$')]
validators=(RegexValidator(r'^\w{1,127}$'),)
) )
fio = models.CharField(_('fio'), max_length=256) fio = models.CharField(_('fio'), max_length=256)
birth_day = models.DateField(_('birth day'), auto_now_add=True) birth_day = models.DateField(_('birth day'), auto_now_add=True)
@ -60,11 +60,11 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
max_length=16, max_length=16,
verbose_name=_('Telephone'), verbose_name=_('Telephone'),
blank=True, blank=True,
validators=[RegexValidator(TELEPHONE_REGEXP)]
validators=(RegexValidator(TELEPHONE_REGEXP),)
) )
USERNAME_FIELD = 'username' USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['telephone']
REQUIRED_FIELDS = ('telephone',)
def get_full_name(self): def get_full_name(self):
return self.fio if self.fio else self.username return self.fio if self.fio else self.username
@ -86,12 +86,12 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
class Meta: class Meta:
db_table = 'base_accounts' db_table = 'base_accounts'
ordering = ['username']
ordering = ('username',)
class UserProfileManager(MyUserManager): class UserProfileManager(MyUserManager):
def get_profiles_by_group(self, group_id): def get_profiles_by_group(self, group_id):
return self.filter(responsibility_groups__id__in=[group_id], is_admin=True, is_active=True)
return self.filter(responsibility_groups__id__in=(group_id,), is_admin=True, is_active=True)
class UserProfile(BaseAccount): class UserProfile(BaseAccount):
@ -116,7 +116,7 @@ class UserProfile(BaseAccount):
) )
verbose_name = _('Staff account profile') verbose_name = _('Staff account profile')
verbose_name_plural = _('Staff account profiles') verbose_name_plural = _('Staff account profiles')
ordering = ['fio']
ordering = ('fio',)
def _thumbnail_avatar(self): def _thumbnail_avatar(self):
if self.avatar and os.path.isfile(self.avatar.path): if self.avatar and os.path.isfile(self.avatar.path):

18
accounts_app/views.py

@ -21,7 +21,7 @@ from guardian.shortcuts import get_objects_for_user, assign_perm, remove_perm
class BaseAccListView(ListView): class BaseAccListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@ -87,7 +87,7 @@ def profile_show(request, uid=0):
}) })
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class AvatarUpdateView(UpdateView): class AvatarUpdateView(UpdateView):
form_class = AvatarChangeForm form_class = AvatarChangeForm
template_name = 'accounts/settings/ch_info.html' template_name = 'accounts/settings/ch_info.html'
@ -180,7 +180,7 @@ def delete_profile(request, uid):
return redirect('acc_app:accounts_list') return redirect('acc_app:accounts_list')
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class AccountsListView(BaseAccListView): class AccountsListView(BaseAccListView):
template_name = 'accounts/acc_list.html' template_name = 'accounts/acc_list.html'
context_object_name = 'users' context_object_name = 'users'
@ -270,7 +270,7 @@ def set_abon_groups_permission(request, uid):
picked_groups = picked_groups.values_list('pk', flat=True) picked_groups = picked_groups.values_list('pk', flat=True)
if request.method == 'POST': if request.method == 'POST':
checked_groups = [int(ag) for ag in request.POST.getlist('grp', default=0)]
checked_groups = tuple(int(ag) for ag in request.POST.getlist('grp', default=0))
for grp in Group.objects.all(): for grp in Group.objects.all():
if grp.pk in checked_groups and grp.pk not in picked_groups: if grp.pk in checked_groups and grp.pk not in picked_groups:
assign_perm('groupapp.can_view_group', userprofile, obj=grp) assign_perm('groupapp.can_view_group', userprofile, obj=grp)
@ -287,9 +287,9 @@ def set_abon_groups_permission(request, uid):
}) })
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class ManageResponsibilityGroups(ListView): class ManageResponsibilityGroups(ListView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'accounts/manage_responsibility_groups.html' template_name = 'accounts/manage_responsibility_groups.html'
context_object_name = 'groups' context_object_name = 'groups'
queryset = Group.objects.only('pk', 'title') queryset = Group.objects.only('pk', 'title')
@ -306,14 +306,14 @@ class ManageResponsibilityGroups(ListView):
context = super(ManageResponsibilityGroups, self).get_context_data(**kwargs) context = super(ManageResponsibilityGroups, self).get_context_data(**kwargs)
context['uid'] = self.kwargs.get('uid') context['uid'] = self.kwargs.get('uid')
context['userprofile'] = self.object context['userprofile'] = self.object
context['existing_groups'] = [g.get('pk') for g in self.object.responsibility_groups.only('pk').values('pk')]
context['existing_groups'] = (g.get('pk') for g in self.object.responsibility_groups.only('pk').values('pk'))
return context return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
checked_groups = [int(ag) for ag in request.POST.getlist('grp', default=0)]
checked_groups = (int(ag) for ag in request.POST.getlist('grp', default=0))
profile = self.object profile = self.object
profile.responsibility_groups.clear() profile.responsibility_groups.clear()
profile.responsibility_groups.add(*[int(g) for g in checked_groups])
profile.responsibility_groups.add(*(int(g) for g in checked_groups))
profile.save() profile.save()
messages.success(request, _('Responsibilities has been updated')) messages.success(request, _('Responsibilities has been updated'))
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())

6
agent/commands/dhcp.py

@ -24,7 +24,7 @@ def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: i
return return
if abon.ip_address != client_ip: if abon.ip_address != client_ip:
abon.ip_address = client_ip abon.ip_address = client_ip
abon.save(update_fields=['ip_address'])
abon.save(update_fields=('ip_address',))
abon.sync_with_nas(created=False) abon.sync_with_nas(created=False)
except Abon.DoesNotExist: except Abon.DoesNotExist:
return "User with device with mac '%s' does not exist" % switch_mac return "User with device with mac '%s' does not exist" % switch_mac
@ -36,14 +36,14 @@ def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: i
'switch_mac': switch_mac 'switch_mac': switch_mac
} }
except MultipleObjectsReturned as e: except MultipleObjectsReturned as e:
return 'MultipleObjectsReturned:' + ' '.join([type(e), e, str(switch_port)])
return 'MultipleObjectsReturned:' + ' '.join(type(e), e, str(switch_port))
def dhcp_expiry(client_ip) -> Optional[str]: def dhcp_expiry(client_ip) -> Optional[str]:
try: try:
abon = Abon.objects.get(ip_address=client_ip) abon = Abon.objects.get(ip_address=client_ip)
abon.ip_address = None abon.ip_address = None
abon.save(update_fields=['ip_address'])
abon.save(update_fields=('ip_address',))
abon.sync_with_nas(created=False) abon.sync_with_nas(created=False)
except Abon.DoesNotExist: except Abon.DoesNotExist:
return "Subscriber with ip %s does not exist" % client_ip return "Subscriber with ip %s does not exist" % client_ip

116
agent/mod_mikrotik.py

@ -4,7 +4,7 @@ import socket
import binascii import binascii
from abc import ABCMeta from abc import ABCMeta
from hashlib import md5 from hashlib import md5
from typing import List, Iterable, Optional, Tuple
from typing import Iterable, Optional, Tuple
from .core import BaseTransmitter, NasFailedResult, NasNetworkError from .core import BaseTransmitter, NasFailedResult, NasNetworkError
from mydefs import singleton from mydefs import singleton
from .structs import TariffStruct, AbonStruct, IpStruct, VectorAbon, VectorTariff from .structs import TariffStruct, AbonStruct, IpStruct, VectorAbon, VectorTariff
@ -38,18 +38,18 @@ class ApiRos:
if self.is_login: if self.is_login:
return return
chal = None chal = None
for repl, attrs in self.talk_iter(["/login"]):
for repl, attrs in self.talk_iter(("/login",)):
chal = binascii.unhexlify(attrs['=ret']) chal = binascii.unhexlify(attrs['=ret'])
md = md5() md = md5()
md.update(b'\x00') md.update(b'\x00')
md.update(bytes(pwd, 'utf-8')) md.update(bytes(pwd, 'utf-8'))
md.update(chal) md.update(chal)
for _ in self.talk_iter(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest()).decode('utf-8')]):
for _ in self.talk_iter(("/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest()).decode('utf-8'))):
pass pass
self.is_login = True self.is_login = True
def talk_iter(self, words):
def talk_iter(self, words: Iterable):
if self.write_sentence(words) == 0: if self.write_sentence(words) == 0:
return return
while 1: while 1:
@ -68,7 +68,7 @@ class ApiRos:
if reply == '!done': if reply == '!done':
return return
def write_sentence(self, words):
def write_sentence(self, words: Iterable):
ret = 0 ret = 0
for w in words: for w in words:
self.write_word(w) self.write_word(w)
@ -99,18 +99,18 @@ class ApiRos:
def write_len(self, l): def write_len(self, l):
if l < 0x80: if l < 0x80:
self.write_bytes(bytes([l]))
self.write_bytes(bytes((l,)))
elif l < 0x4000: elif l < 0x4000:
l |= 0x8000 l |= 0x8000
self.write_bytes(bytes([(l >> 8) & 0xff, l & 0xff]))
self.write_bytes(bytes(((l >> 8) & 0xff, l & 0xff)))
elif l < 0x200000: elif l < 0x200000:
l |= 0xC00000 l |= 0xC00000
self.write_bytes(bytes([(l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff]))
self.write_bytes(bytes(((l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff)))
elif l < 0x10000000: elif l < 0x10000000:
l |= 0xE0000000 l |= 0xE0000000
self.write_bytes(bytes([(l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff]))
self.write_bytes(bytes(((l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff)))
else: else:
self.write_bytes(bytes([0xf0, (l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff]))
self.write_bytes(bytes((0xf0, (l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, l & 0xff)))
def read_len(self): def read_len(self):
c = self.read_bytes(1)[0] c = self.read_bytes(1)[0]
@ -182,8 +182,8 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta):
if hasattr(self, 's'): if hasattr(self, 's'):
self.s.close() self.s.close()
def _exec_cmd(self, cmd: list) -> list:
if not isinstance(cmd, list):
def _exec_cmd(self, cmd: Iterable) -> list:
if not isinstance(cmd, (list, tuple)):
raise TypeError raise TypeError
result_iter = self.ar.talk_iter(cmd) result_iter = self.ar.talk_iter(cmd)
res = [] res = []
@ -193,8 +193,8 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta):
res.append(rt[1]) res.append(rt[1])
return res return res
def _exec_cmd_iter(self, cmd: list) -> Iterable:
if not isinstance(cmd, list):
def _exec_cmd_iter(self, cmd: Iterable) -> Iterable:
if not isinstance(cmd, (list, tuple)):
raise TypeError raise TypeError
result_iter = self.ar.talk_iter(cmd) result_iter = self.ar.talk_iter(cmd)
for rt in result_iter: for rt in result_iter:
@ -243,7 +243,7 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta):
class QueueManager(TransmitterManager, metaclass=ABCMeta): class QueueManager(TransmitterManager, metaclass=ABCMeta):
# Find queue by name # Find queue by name
def find(self, name: str) -> AbonStruct: def find(self, name: str) -> AbonStruct:
ret = self._exec_cmd(['/queue/simple/print', '?name=%s' % name])
ret = self._exec_cmd(('/queue/simple/print', '?name=%s' % name))
if len(ret) > 1: if len(ret) > 1:
return self._build_shape_obj(ret[0]) return self._build_shape_obj(ret[0])
@ -252,26 +252,26 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta):
raise TypeError raise TypeError
if user.tariff is None or not isinstance(user.tariff, TariffStruct): if user.tariff is None or not isinstance(user.tariff, TariffStruct):
return return
return self._exec_cmd(['/queue/simple/add',
return self._exec_cmd(('/queue/simple/add',
'=name=uid%d' % user.uid, '=name=uid%d' % user.uid,
# FIXME: тут в разных микротиках или =target-addresses или =target # FIXME: тут в разных микротиках или =target-addresses или =target
'=target=%s' % str(user.ip),
'=target=%s' % user.ip,
'=max-limit=%.3fM/%.3fM' % (user.tariff.speedOut, user.tariff.speedIn), '=max-limit=%.3fM/%.3fM' % (user.tariff.speedOut, user.tariff.speedIn),
'=queue=MikroBILL_SFQ/MikroBILL_SFQ', '=queue=MikroBILL_SFQ/MikroBILL_SFQ',
'=burst-time=1/1' '=burst-time=1/1'
])
))
def remove(self, user: AbonStruct): def remove(self, user: AbonStruct):
if not isinstance(user, AbonStruct): if not isinstance(user, AbonStruct):
raise TypeError raise TypeError
q = self.find('uid%d' % user.uid) q = self.find('uid%d' % user.uid)
if q is not None: if q is not None:
return self._exec_cmd(['/queue/simple/remove', '=.id=' + getattr(q, 'queue_id', '')])
return self._exec_cmd(('/queue/simple/remove', '=.id=' + getattr(q, 'queue_id', ''),))
def remove_range(self, q_ids: List[str]):
def remove_range(self, q_ids: Iterable[str]):
try: try:
# q_ids = [q.queue_id for q in q_ids] # q_ids = [q.queue_id for q in q_ids]
return self._exec_cmd(['/queue/simple/remove', '=numbers=' + ','.join(q_ids)])
return self._exec_cmd(('/queue/simple/remove', '=numbers=' + ','.join(q_ids)))
except TypeError as e: except TypeError as e:
print(e) print(e)
@ -285,17 +285,17 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta):
return self.add(user) return self.add(user)
else: else:
mk_id = getattr(queue, 'queue_id', '') mk_id = getattr(queue, 'queue_id', '')
return self._exec_cmd(['/queue/simple/set', '=.id=' + mk_id,
return self._exec_cmd(('/queue/simple/set', '=.id=' + mk_id,
'=name=uid%d' % user.uid, '=name=uid%d' % user.uid,
'=max-limit=%.3fM/%.3fM' % (user.tariff.speedOut, user.tariff.speedIn), '=max-limit=%.3fM/%.3fM' % (user.tariff.speedOut, user.tariff.speedIn),
# FIXME: тут в разных микротиках или =target-addresses или =target # FIXME: тут в разных микротиках или =target-addresses или =target
'=target=%s' % str(user.ip),
'=target=%s' % user.ip,
'=queue=MikroBILL_SFQ/MikroBILL_SFQ', '=queue=MikroBILL_SFQ/MikroBILL_SFQ',
'=burst-time=1/1' '=burst-time=1/1'
])
))
def read_queue_iter(self): def read_queue_iter(self):
for code, dat in self._exec_cmd_iter(['/queue/simple/print', '=detail']):
for code, dat in self._exec_cmd_iter(('/queue/simple/print', '=detail')):
if code == '!done': if code == '!done':
return return
sobj = self._build_shape_obj(dat) sobj = self._build_shape_obj(dat)
@ -303,7 +303,7 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta):
yield sobj yield sobj
def read_mikroids_iter(self): def read_mikroids_iter(self):
queues = self._exec_cmd_iter(['/queue/simple/print', '=detail'])
queues = self._exec_cmd_iter(('/queue/simple/print', '=detail'))
for queue in queues: for queue in queues:
if queue[0] == '!done': if queue[0] == '!done':
return return
@ -317,7 +317,7 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta):
self.add(user) self.add(user)
return self.disable(user) return self.disable(user)
else: else:
return self._exec_cmd(['/queue/simple/disable', '=.id=*' + getattr(q, 'queue_id', '')])
return self._exec_cmd(('/queue/simple/disable', '=.id=*' + getattr(q, 'queue_id', '')))
def enable(self, user: AbonStruct): def enable(self, user: AbonStruct):
if not isinstance(user, AbonStruct): if not isinstance(user, AbonStruct):
@ -327,7 +327,7 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta):
self.add(user) self.add(user)
self.enable(user) self.enable(user)
else: else:
return self._exec_cmd(['/queue/simple/enable', '=.id=*' + getattr(q, 'queue_id', '')])
return self._exec_cmd(('/queue/simple/enable', '=.id=*' + getattr(q, 'queue_id', '')))
class IpAddressListObj(IpStruct): class IpAddressListObj(IpStruct):
@ -340,21 +340,21 @@ class IpAddressListManager(TransmitterManager, metaclass=ABCMeta):
def add(self, list_name: str, ip: IpStruct): def add(self, list_name: str, ip: IpStruct):
if not isinstance(ip, IpStruct): if not isinstance(ip, IpStruct):
raise TypeError raise TypeError
commands = [
commands = (
'/ip/firewall/address-list/add', '/ip/firewall/address-list/add',
'=list=%s' % list_name, '=list=%s' % list_name,
'=address=%s' % str(ip)
]
'=address=%s' % ip
)
return self._exec_cmd(commands) return self._exec_cmd(commands)
def remove(self, mk_id): def remove(self, mk_id):
return self._exec_cmd([
return self._exec_cmd((
'/ip/firewall/address-list/remove', '/ip/firewall/address-list/remove',
'=.id=*' + str(mk_id).replace('*', '') '=.id=*' + str(mk_id).replace('*', '')
])
))
def remove_range(self, items: Iterable[IpAddressListObj]): def remove_range(self, items: Iterable[IpAddressListObj]):
ids = [ip.mk_id for ip in items if isinstance(ip, IpAddressListObj)]
ids = tuple(ip.mk_id for ip in items if isinstance(ip, IpAddressListObj))
if len(ids) > 0: if len(ids) > 0:
return self._exec_cmd([ return self._exec_cmd([
'/ip/firewall/address-list/remove', '/ip/firewall/address-list/remove',
@ -364,18 +364,18 @@ class IpAddressListManager(TransmitterManager, metaclass=ABCMeta):
def find(self, ip: IpStruct, list_name: str): def find(self, ip: IpStruct, list_name: str):
if not isinstance(ip, IpStruct): if not isinstance(ip, IpStruct):
raise TypeError raise TypeError
return self._exec_cmd([
return self._exec_cmd((
'/ip/firewall/address-list/print', 'where', '/ip/firewall/address-list/print', 'where',
'?list=%s' % list_name, '?list=%s' % list_name,
'?address=%s' % str(ip)
])
'?address=%s' % ip
))
def read_ips_iter(self, list_name: str): def read_ips_iter(self, list_name: str):
ips = self._exec_cmd_iter([
ips = self._exec_cmd_iter((
'/ip/firewall/address-list/print', 'where', '/ip/firewall/address-list/print', 'where',
'?list=%s' % list_name, '?list=%s' % list_name,
'?dynamic=no' '?dynamic=no'
])
))
for code, dat in ips: for code, dat in ips:
if dat != {}: if dat != {}:
yield IpAddressListObj(dat['=address'], dat['=.id']) yield IpAddressListObj(dat['=address'], dat['=.id'])
@ -384,19 +384,19 @@ class IpAddressListManager(TransmitterManager, metaclass=ABCMeta):
r = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED) r = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED)
if len(r) > 1: if len(r) > 1:
mk_id = r[0]['=.id'] mk_id = r[0]['=.id']
return self._exec_cmd([
return self._exec_cmd((
'/ip/firewall/address-list/disable', '/ip/firewall/address-list/disable',
'=.id=' + str(mk_id), '=.id=' + str(mk_id),
])
))
def enable(self, user): def enable(self, user):
r = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED) r = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED)
if len(r) > 1: if len(r) > 1:
mk_id = r[0]['=.id'] mk_id = r[0]['=.id']
return self._exec_cmd([
return self._exec_cmd((
'/ip/firewall/address-list/enable', '/ip/firewall/address-list/enable',
'=.id=' + str(mk_id), '=.id=' + str(mk_id),
])
))
class MikrotikTransmitter(QueueManager, IpAddressListManager): class MikrotikTransmitter(QueueManager, IpAddressListManager):
@ -405,10 +405,11 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager):
self.add_user(usr) self.add_user(usr)
def remove_user_range(self, users: VectorAbon): def remove_user_range(self, users: VectorAbon):
queue_ids = [usr.queue_id for usr in users if usr is not None]
if not isinstance(users, (tuple, list)):
raise ValueError('*users* is used twice, generator does not fit')
queue_ids = (usr.queue_id for usr in users if usr is not None)
QueueManager.remove_range(self, queue_ids) QueueManager.remove_range(self, queue_ids)
ips = [user.ip for user in users if isinstance(user, AbonStruct)]
for ip in ips:
for ip in (user.ip for user in users if isinstance(user, AbonStruct)):
ip_list_entity = IpAddressListManager.find(self, ip, LIST_USERS_ALLOWED) ip_list_entity = IpAddressListManager.find(self, ip, LIST_USERS_ALLOWED)
if ip_list_entity is not None and len(ip_list_entity) > 1: if ip_list_entity is not None and len(ip_list_entity) > 1:
IpAddressListManager.remove(self, ip_list_entity[0]['=.id']) IpAddressListManager.remove(self, ip_list_entity[0]['=.id'])
@ -416,8 +417,10 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager):
def add_user(self, user: AbonStruct, *args): def add_user(self, user: AbonStruct, *args):
if not isinstance(user.ip, IpStruct): if not isinstance(user.ip, IpStruct):
raise TypeError raise TypeError
if user.tariff is None or not isinstance(user.tariff, TariffStruct):
if user.tariff is None:
return return
if not isinstance(user.tariff, TariffStruct):
raise TypeError
QueueManager.add(self, user) QueueManager.add(self, user)
IpAddressListManager.add(self, LIST_USERS_ALLOWED, user.ip) IpAddressListManager.add(self, LIST_USERS_ALLOWED, user.ip)
# remove user from denied user list # remove user from denied user list
@ -468,17 +471,17 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager):
QueueManager.update(self, user) QueueManager.update(self, user)
def ping(self, host, count=10) -> Optional[Tuple[int, int]]: def ping(self, host, count=10) -> Optional[Tuple[int, int]]:
r = self._exec_cmd([
r = self._exec_cmd((
'/ip/arp/print', '/ip/arp/print',
'?address=%s' % host '?address=%s' % host
])
))
if r == [{}]: if r == [{}]:
return return
interface = r[0]['=interface'] interface = r[0]['=interface']
r = self._exec_cmd([
r = self._exec_cmd((
'/ping', '=address=%s' % host, '=arp-ping=yes', '=interval=100ms', '=count=%d' % count, '/ping', '=address=%s' % host, '=arp-ping=yes', '=interval=100ms', '=count=%d' % count,
'=interface=%s' % interface '=interface=%s' % interface
])
))
received, sent = int(r[-2:][0]['=received']), int(r[-2:][0]['=sent']) received, sent = int(r[-2:][0]['=received']), int(r[-2:][0]['=sent'])
return received, sent return received, sent
@ -504,13 +507,12 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager):
def read_users(self) -> Iterable[AbonStruct]: def read_users(self) -> Iterable[AbonStruct]:
# shapes is ShapeItem # shapes is ShapeItem
allowed_ips = set(IpAddressListManager.read_ips_iter(self, LIST_USERS_ALLOWED)) allowed_ips = set(IpAddressListManager.read_ips_iter(self, LIST_USERS_ALLOWED))
queues = set(q for q in QueueManager.read_queue_iter(self) if q.ip in allowed_ips)
queues = tuple(q for q in QueueManager.read_queue_iter(self) if q.ip in allowed_ips)
ips_from_queues = set([q.ip for q in queues])
allowed_ips = set(allowed_ips)
ips_from_queues = set(q.ip for q in queues)
# удаляем ip адреса которые есть в firewall/address-list и нет соответствующих в queues
diff = list(allowed_ips - ips_from_queues)
# delete ip addresses that are in firewall/address-list and there are no corresponding in queues
diff = tuple(allowed_ips - ips_from_queues)
if len(diff) > 0: if len(diff) > 0:
IpAddressListManager.remove_range(self, diff) IpAddressListManager.remove_range(self, diff)

14
agent/monitoring_agent.py

@ -2,6 +2,8 @@
import sys import sys
import re import re
from hashlib import sha256 from hashlib import sha256
from typing import Iterable, Union, AnyStr
import requests import requests
API_AUTH_SECRET = 'your api key' API_AUTH_SECRET = 'your api key'
@ -19,31 +21,31 @@ def calc_hash(data):
return sha256(result_data).hexdigest() return sha256(result_data).hexdigest()
def check_sign(get_list, sign):
def check_sign(get_list: Iterable, sign: str):
hashed = '_'.join(get_list) hashed = '_'.join(get_list)
my_sign = calc_hash(hashed) my_sign = calc_hash(hashed)
return sign == my_sign return sign == my_sign
def validate(regexp, string):
def validate(regexp: Union[bytes, str, re.__Regex], string: AnyStr):
if not re.match(regexp, string): if not re.match(regexp, string):
raise ValueError raise ValueError
return string return string
def validate_status(text):
def validate_status(text: str):
if text not in ('UP', 'DOWN', 'UNREACHABLE'): if text not in ('UP', 'DOWN', 'UNREACHABLE'):
raise ValueError raise ValueError
return text return text
def send_request(mac, status, sign):
def send_request(mac, stat, sign_hash):
r = requests.get( r = requests.get(
"%(domain)s/dev/on_device_event/" % {'domain': SERVER_DOMAIN}, "%(domain)s/dev/on_device_event/" % {'domain': SERVER_DOMAIN},
params={ params={
'mac': mac, 'mac': mac,
'status': status,
'sign': sign
'status': stat,
'sign': sign_hash
}) })
if r.status_code == 200: if r.status_code == 200:
print(r.json()) print(r.json())

1
agent/netflow/netflow_handler.py

@ -4,6 +4,7 @@ import sys
import os import os
from importlib import import_module from importlib import import_module
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 2: if len(sys.argv) < 2:
print("File name of netflow required") print("File name of netflow required")

1
agent/utils.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import socket import socket
import struct import struct

8
chatbot/models.py

@ -1,4 +1,4 @@
from django.utils.translation import ugettext as _
from django.utils.translation import gettext_lazy as _
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
@ -20,7 +20,7 @@ class TelegramBot(models.Model):
db_table = 'chat_telegram_bot' db_table = 'chat_telegram_bot'
verbose_name = _('Telegram bot') verbose_name = _('Telegram bot')
verbose_name_plural = _('Telegram bots') verbose_name_plural = _('Telegram bots')
ordering = ['chat_id']
ordering = ('chat_id',)
class MessageHistory(models.Model): class MessageHistory(models.Model):
@ -35,7 +35,7 @@ class MessageHistory(models.Model):
db_table = 'chat_message_history' db_table = 'chat_message_history'
verbose_name = _('Message history') verbose_name = _('Message history')
verbose_name_plural = _('Message histories') verbose_name_plural = _('Message histories')
ordering = ['-date_sent']
ordering = ('-date_sent',)
class MessageQueueManager(models.Manager): class MessageQueueManager(models.Manager):
@ -70,4 +70,4 @@ class MessageQueue(models.Model):
db_table = 'chat_message_queue' db_table = 'chat_message_queue'
verbose_name = _('Message queue') verbose_name = _('Message queue')
verbose_name_plural = _('Message queue') verbose_name_plural = _('Message queue')
ordering = ['target_employee__username']
ordering = ('target_employee__username',)

4
chatbot/telebot.py

@ -74,7 +74,7 @@ class DjingTelebot(helper.ChatHandler):
text = msg['text'].lower() text = msg['text'].lower()
# выполняем комманды если они есть # выполняем комманды если они есть
if text in list(self.cmds.keys()):
if text in self.cmds.keys():
self.cmds[text]() self.cmds[text]()
elif self._dialog_fn is not None: elif self._dialog_fn is not None:
if not callable(self._dialog_fn): if not callable(self._dialog_fn):
@ -123,7 +123,7 @@ class DjingTelebot(helper.ChatHandler):
return return
try: try:
socket.inet_aton(ip) socket.inet_aton(ip)
ret = os.popen('`which ping` -c 10 ' + ip).read()
ret = os.popen('`which ping` -c 10 %s' % ip).read()
self._sent_reply(ret) self._sent_reply(ret)
except socket.error: except socket.error:
self._question(_("It's not like ip address, try again"), self.ping) self._question(_("It's not like ip address, try again"), self.ping)

4
clientsideapp/views.py

@ -90,9 +90,9 @@ def debt_buy(request, d_id):
'username': abon.get_full_name(), 'username': abon.get_full_name(),
'amount': amount 'amount': amount
}) })
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
debt.set_ok() debt.set_ok()
debt.save(update_fields=['status', 'date_pay'])
debt.save(update_fields=('status', 'date_pay'))
return redirect('client_side:debts') return redirect('client_side:debts')
except LogicError as e: except LogicError as e:
messages.error(request, e) messages.error(request, e)

2
devapp/base_intr.py

@ -71,7 +71,7 @@ class BasePort(object, metaclass=ABCMeta):
pass pass
def mac(self) -> str: def mac(self) -> str:
return ':'.join(['%x' % ord(i) for i in self._mac])
return ':'.join('%x' % ord(i) for i in self._mac)
class SNMPBaseWorker(object, metaclass=ABCMeta): class SNMPBaseWorker(object, metaclass=ABCMeta):

2
devapp/dev_types.py

@ -203,7 +203,7 @@ class OnuDevice(DevBase, SNMPBaseWorker):
status = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.26.%d' % num) status = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.26.%d' % num)
signal = self.get_item('.1.3.6.1.4.1.3320.101.10.5.1.5.%d' % num) signal = self.get_item('.1.3.6.1.4.1.3320.101.10.5.1.5.%d' % num)
distance = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.27.%d' % num) distance = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.27.%d' % num)
mac = ':'.join(['%x' % ord(i) for i in self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % num)])
mac = ':'.join('%x' % ord(i) for i in self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % num))
# uptime = self.get_item('.1.3.6.1.2.1.2.2.1.9.%d' % num) # uptime = self.get_item('.1.3.6.1.2.1.2.2.1.9.%d' % num)
return { return {
'status': status, 'status': status,

8
devapp/models.py

@ -54,7 +54,7 @@ class Device(models.Model):
) )
verbose_name = _('Device') verbose_name = _('Device')
verbose_name_plural = _('Devices') verbose_name_plural = _('Devices')
ordering = ['id']
ordering = ('id',)
def get_abons(self): def get_abons(self):
pass pass
@ -63,7 +63,7 @@ class Device(models.Model):
return self.status return self.status
def get_manager_klass(self): def get_manager_klass(self):
klasses = [kl for kl in self.DEVICE_TYPES if kl[0] == self.devtype]
klasses = tuple(kl for kl in self.DEVICE_TYPES if kl[0] == self.devtype)
if len(klasses) > 0: if len(klasses) > 0:
res = klasses[0][1] res = klasses[0][1]
if issubclass(res, DevBase): if issubclass(res, DevBase):
@ -94,7 +94,7 @@ class Device(models.Model):
param = 'del' param = 'del'
else: else:
param = 'update' param = 'update'
run([filepath, param, newmac, code])
run((filepath, param, newmac, code))
class Port(models.Model): class Port(models.Model):
@ -113,4 +113,4 @@ class Port(models.Model):
) )
verbose_name = _('Port') verbose_name = _('Port')
verbose_name_plural = _('Ports') verbose_name_plural = _('Ports')
ordering = ['num']
ordering = ('num',)

55
devapp/views.py

@ -30,11 +30,11 @@ from .forms import DeviceForm, PortForm
class BaseDeviceListView(global_base_views.BaseListWithFiltering): class BaseDeviceListView(global_base_views.BaseListWithFiltering):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class DevicesListView(global_base_views.OrderingMixin, BaseDeviceListView): class DevicesListView(global_base_views.OrderingMixin, BaseDeviceListView):
context_object_name = 'devices' context_object_name = 'devices'
template_name = 'devapp/devices.html' template_name = 'devapp/devices.html'
@ -61,7 +61,7 @@ class DevicesListView(global_base_views.OrderingMixin, BaseDeviceListView):
return response return response
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class DevicesWithoutGroupsListView(global_base_views.OrderingMixin, BaseDeviceListView): class DevicesWithoutGroupsListView(global_base_views.OrderingMixin, BaseDeviceListView):
context_object_name = 'devices' context_object_name = 'devices'
template_name = 'devapp/devices_null_group.html' template_name = 'devapp/devices_null_group.html'
@ -181,10 +181,10 @@ def manage_ports(request, device_id):
}) })
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class ShowSubscriberOnPort(global_base_views.RedirectWhenErrorMixin, DetailView): class ShowSubscriberOnPort(global_base_views.RedirectWhenErrorMixin, DetailView):
template_name = 'devapp/manage_ports/modal_show_subscriber_on_port.html' template_name = 'devapp/manage_ports/modal_show_subscriber_on_port.html'
http_method_names = ['get']
http_method_names = ('get',)
def get_object(self, queryset=None): def get_object(self, queryset=None):
dev_id = self.kwargs.get('device_id') dev_id = self.kwargs.get('device_id')
@ -241,7 +241,7 @@ def add_ports(request, device_id):
try: try:
port = Port.objects.get(num=port_num, device=dev) port = Port.objects.get(num=port_num, device=dev)
port.descr = port_text port.descr = port_text
port.save(update_fields=['descr'])
port.save(update_fields=('descr',))
except Port.DoesNotExist: except Port.DoesNotExist:
Port.objects.create( Port.objects.create(
num=port_num, num=port_num,
@ -250,12 +250,12 @@ def add_ports(request, device_id):
) )
db_ports = Port.objects.filter(device=dev) db_ports = Port.objects.filter(device=dev)
db_ports = [TempPort(p.num, p.descr, None, True, p.pk) for p in db_ports]
db_ports = (TempPort(p.num, p.descr, None, True, p.pk) for p in db_ports)
manager = dev.get_manager_object() manager = dev.get_manager_object()
ports = manager.get_ports() ports = manager.get_ports()
if ports is not None: if ports is not None:
ports = [TempPort(p.num, p.nm, p.st, False) for p in ports]
ports = (TempPort(p.num, p.nm, p.st, False) for p in ports)
res_ports = set(db_ports + ports) res_ports = set(db_ports + ports)
else: else:
res_ports = db_ports res_ports = db_ports
@ -417,7 +417,7 @@ def toggle_port(request, device_id, portid, status=0):
return redirect('devapp:view', dev.group.pk if dev.group is not None else 0, device_id) return redirect('devapp:view', dev.group.pk if dev.group is not None else 0, device_id)
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class GroupsListView(BaseDeviceListView): class GroupsListView(BaseDeviceListView):
context_object_name = 'groups' context_object_name = 'groups'
template_name = 'devapp/group_list.html' template_name = 'devapp/group_list.html'
@ -431,16 +431,18 @@ class GroupsListView(BaseDeviceListView):
@login_required @login_required
@json_view
def search_dev(request): def search_dev(request):
word = request.GET.get('s') word = request.GET.get('s')
if word is None or word == '': if word is None or word == '':
results = [{'id': 0, 'text': ''}]
results = ({'id': 0, 'text': ''},)
else: else:
results = Device.objects.filter( results = Device.objects.filter(
Q(comment__icontains=word) | Q(ip_address=word) Q(comment__icontains=word) | Q(ip_address=word)
).only('pk', 'ip_address', 'comment')[:16] ).only('pk', 'ip_address', 'comment')[:16]
results = [{'id': dev.pk, 'text': "%s: %s" % (dev.ip_address or '', dev.comment)} for dev in results]
return JsonResponse(results, json_dumps_params={'ensure_ascii': False}, safe=False)
results = ({'id': dev.pk, 'text': "%s: %s" % (dev.ip_address or '', dev.comment)} for dev in results)
#return JsonResponse(results, json_dumps_params={'ensure_ascii': False}, safe=False)
return results
@login_required @login_required
@ -470,6 +472,7 @@ def fix_device_group(request, device_id):
@login_required @login_required
@json_view
def fix_onu(request): def fix_onu(request):
mac = request.GET.get('cmd_param') mac = request.GET.get('cmd_param')
status = 1 status = 1
@ -484,10 +487,10 @@ def fix_onu(request):
(_('Device with mac address %(mac)s does not exist') % {'mac': mac}) (_('Device with mac address %(mac)s does not exist') % {'mac': mac})
for srcmac, snmpnum in ports: for srcmac, snmpnum in ports:
# convert bytes mac address to str presentation mac address # convert bytes mac address to str presentation mac address
real_mac = ':'.join(['%x' % ord(i) for i in srcmac])
real_mac = ':'.join('%x' % ord(i) for i in srcmac)
if mac == real_mac: if mac == real_mac:
onu.snmp_item_num = snmpnum onu.snmp_item_num = snmpnum
onu.save(update_fields=['snmp_item_num'])
onu.save(update_fields=('snmp_item_num',))
status = 0 status = 0
text = '<span class="glyphicon glyphicon-ok"></span> <span class="hidden-xs">%s</span>' % _('Fixed') text = '<span class="glyphicon glyphicon-ok"></span> <span class="hidden-xs">%s</span>' % _('Fixed')
break break
@ -495,10 +498,10 @@ def fix_onu(request):
text = text + '\n%s' % _('Parent device not found') text = text + '\n%s' % _('Parent device not found')
except Device.DoesNotExist: except Device.DoesNotExist:
pass pass
return JsonResponse({
return {
'status': status, 'status': status,
'dat': text 'dat': text
})
}
@login_required @login_required
@ -519,7 +522,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
# #
# Api view for monitoring devices # Api view for monitoring devices
# #
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view) @method_decorator(json_view)
def get(self, request): def get(self, request):
@ -550,7 +553,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
device_down.status = 'und' device_down.status = 'und'
notify_text = 'Device %(device_name)s getting undefined status code' notify_text = 'Device %(device_name)s getting undefined status code'
device_down.save(update_fields=['status'])
device_down.save(update_fields=('status',))
if not device_down.is_noticeable: if not device_down.is_noticeable:
return {'text': 'Notification for %s is unnecessary' % device_down.ip_address or device_down.comment} return {'text': 'Notification for %s is unnecessary' % device_down.ip_address or device_down.comment}
@ -582,7 +585,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView): class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView):
http_method_names = ['get']
http_method_names = ('get',)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
from transliterate import translit from transliterate import translit
@ -620,7 +623,7 @@ class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView):
def templ(host_name: str, host_addr: str, mac: Optional[str], parent_host_name: Optional[str]): def templ(host_name: str, host_addr: str, mac: Optional[str], parent_host_name: Optional[str]):
if not host_addr: if not host_addr:
return return
r = [
r = (
"define host{", "define host{",
"\tuse generic-switch", "\tuse generic-switch",
"\thost_name %s" % host_name, "\thost_name %s" % host_name,
@ -628,14 +631,14 @@ class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView):
"\tparents %s" % parent_host_name if parent_host_name is not None else '', "\tparents %s" % parent_host_name if parent_host_name is not None else '',
"\t_mac_addr %s" % mac if mac is not None else '', "\t_mac_addr %s" % mac if mac is not None else '',
"}\n" "}\n"
]
)
return '\n'.join(i for i in r if i) return '\n'.join(i for i in r if i)
@staticmethod @staticmethod
def templ_onu(host_name: str, host_addr: str, mac: Optional[str], snmp_item: int): def templ_onu(host_name: str, host_addr: str, mac: Optional[str], snmp_item: int):
if not host_addr: if not host_addr:
return return
r = [
r = (
"define host{", "define host{",
"\tuse device-onu", "\tuse device-onu",
"\thost_name %s" % host_name, "\thost_name %s" % host_name,
@ -643,18 +646,18 @@ class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView):
"\t_snmp_item %d" % snmp_item if snmp_item is not None else '', "\t_snmp_item %d" % snmp_item if snmp_item is not None else '',
"\t_mac_addr %s" % mac if mac is not None else '', "\t_mac_addr %s" % mac if mac is not None else '',
"}\n" "}\n"
]
)
return '\n'.join(i for i in r if i) return '\n'.join(i for i in r if i)
class DevicesGetListView(global_base_views.SecureApiView): class DevicesGetListView(global_base_views.SecureApiView):
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view) @method_decorator(json_view)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
from netaddr import EUI from netaddr import EUI
device_type = request.GET.get('type') device_type = request.GET.get('type')
dev_types = [dt[0] for dt in Device.DEVICE_TYPES]
dev_types = tuple(dt[0] for dt in Device.DEVICE_TYPES)
if device_type not in dev_types: if device_type not in dev_types:
devs = Device.objects.all() devs = Device.objects.all()
else: else:
@ -663,4 +666,4 @@ class DevicesGetListView(global_base_views.SecureApiView):
for r in res: for r in res:
if isinstance(r['mac_addr'], EUI): if isinstance(r['mac_addr'], EUI):
r['mac_addr'] = int(r['mac_addr']) r['mac_addr'] = int(r['mac_addr'])
return list(res)
return tuple(res)

6
dialing_app/models.py

@ -69,7 +69,7 @@ class AsteriskCDR(models.Model):
class Meta: class Meta:
db_table = 'cdr' db_table = 'cdr'
managed = False managed = False
ordering = ['-calldate']
ordering = ('-calldate',)
class SMSModel(models.Model): class SMSModel(models.Model):
@ -85,7 +85,7 @@ class SMSModel(models.Model):
) )
verbose_name = _('SMS') verbose_name = _('SMS')
verbose_name_plural = _('SMS') verbose_name_plural = _('SMS')
ordering = ['-when']
ordering = ('-when',)
def __str__(self): def __str__(self):
return self.text return self.text
@ -110,7 +110,7 @@ class SMSOut(models.Model):
) )
verbose_name = _('Out SMS') verbose_name = _('Out SMS')
verbose_name_plural = _('Out SMS') verbose_name_plural = _('Out SMS')
ordering = ['-when']
ordering = ('-when',)
def __str__(self): def __str__(self):
return self.text return self.text

12
dialing_app/views.py

@ -22,11 +22,11 @@ from .forms import SMSOutForm
class BaseListView(ListView): class BaseListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator([login_required, permission_required('dialing_app.change_asteriskcdr')], name='dispatch')
@method_decorator((login_required, permission_required('dialing_app.change_asteriskcdr')), name='dispatch')
class LastCallsListView(BaseListView): class LastCallsListView(BaseListView):
template_name = 'index.html' template_name = 'index.html'
context_object_name = 'logs' context_object_name = 'logs'
@ -62,7 +62,7 @@ def to_abon(request, tel):
return redirect('abonapp:group_list') return redirect('abonapp:group_list')
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class VoiceMailRequestsListView(BaseListView): class VoiceMailRequestsListView(BaseListView):
template_name = 'vmail.html' template_name = 'vmail.html'
context_object_name = 'vmessages' context_object_name = 'vmessages'
@ -83,7 +83,7 @@ class VoiceMailReportsListView(VoiceMailRequestsListView):
return context return context
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class DialsFilterListView(BaseListView): class DialsFilterListView(BaseListView):
context_object_name = 'logs' context_object_name = 'logs'
template_name = 'index.html' template_name = 'index.html'
@ -118,7 +118,7 @@ class DialsFilterListView(BaseListView):
return cdr return cdr
@method_decorator([login_required, permission_required('dialing_app.can_view_sms')], name='dispatch')
@method_decorator((login_required, permission_required('dialing_app.can_view_sms')), name='dispatch')
class InboxSMSListView(BaseListView): class InboxSMSListView(BaseListView):
template_name = 'inbox_sms.html' template_name = 'inbox_sms.html'
context_object_name = 'sms_messages' context_object_name = 'sms_messages'
@ -160,7 +160,7 @@ class SmsManager(SecureApiView):
# #
# Api view for management sms from dongle # Api view for management sms from dongle
# #
http_method_names = ['get']
http_method_names = ('get',)
@staticmethod @staticmethod
def bad_cmd(**kwargs) -> JSONType: def bad_cmd(**kwargs) -> JSONType:

2
group_app/models.py

@ -18,7 +18,7 @@ class Group(models.Model):
) )
verbose_name = _('Group') verbose_name = _('Group')
verbose_name_plural = _('Groups') verbose_name_plural = _('Groups')
ordering = ['title']
ordering = ('title',)
def __str__(self): def __str__(self):
return self.title return self.title

6
group_app/views.py

@ -11,7 +11,7 @@ from . import forms
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class GroupListView(ListView): class GroupListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
template_name = 'group_app/group_list.html' template_name = 'group_app/group_list.html'
model = models.Group model = models.Group
@ -20,7 +20,7 @@ class GroupListView(ListView):
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class EditGroupView(UpdateView): class EditGroupView(UpdateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'group_app/edit_group.html' template_name = 'group_app/edit_group.html'
form_class = forms.GroupForm form_class = forms.GroupForm
model = models.Group model = models.Group
@ -38,7 +38,7 @@ class EditGroupView(UpdateView):
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class AddGroupView(CreateView): class AddGroupView(CreateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'group_app/add_group.html' template_name = 'group_app/add_group.html'
form_class = forms.GroupForm form_class = forms.GroupForm
success_url = reverse_lazy('group_app:group_list') success_url = reverse_lazy('group_app:group_list')

2
mapapp/models.py

@ -14,7 +14,7 @@ class Dot(models.Model):
db_table = 'dots' db_table = 'dots'
verbose_name = _('Map point') verbose_name = _('Map point')
verbose_name_plural = _('Map points') verbose_name_plural = _('Map points')
ordering = ['title']
ordering = ('title',)
permissions = ( permissions = (
('can_view', _('Can view')), ('can_view', _('Can view')),
) )

2
mapapp/views.py

@ -20,7 +20,7 @@ from guardian.decorators import permission_required
class BaseListView(ListView): class BaseListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)

4
messaging/utils.py

@ -88,11 +88,11 @@ def clean_number(n):
def encode_str(s): def encode_str(s):
"""Returns the hexadecimal representation of ``s``""" """Returns the hexadecimal representation of ``s``"""
return ''.join(["%02x" % ord(n) for n in s])
return ''.join("%02x" % ord(n) for n in s)
def encode_bytes(b): def encode_bytes(b):
return ''.join(["%02x" % n for n in b])
return ''.join("%02x" % n for n in b)
def pack_8bits_to_7bits(message, udh=None): def pack_8bits_to_7bits(message, udh=None):

14
msg_app/models.py

@ -48,7 +48,7 @@ class Message(models.Model):
if ms.status == code: if ms.status == code:
return False return False
ms.status = code ms.status = code
ms.save(update_fields=['status'])
ms.save(update_fields=('status',))
return True return True
except MessageStatus.DoesNotExist: except MessageStatus.DoesNotExist:
return False return False
@ -64,7 +64,7 @@ class Message(models.Model):
class Meta: class Meta:
db_table = 'messages' db_table = 'messages'
ordering = ['-sent_at']
ordering = ('-sent_at',)
verbose_name = _("Message") verbose_name = _("Message")
verbose_name_plural = _("Messages") verbose_name_plural = _("Messages")
permissions = ( permissions = (
@ -105,9 +105,9 @@ def id_to_userprofile(acc):
class ConversationManager(models.Manager): class ConversationManager(models.Manager):
def create_conversation(self, author, other_participants, title=None): def create_conversation(self, author, other_participants, title=None):
other_participants = [id_to_userprofile(acc) for acc in other_participants]
other_participants = tuple(id_to_userprofile(acc) for acc in other_participants)
if not title: if not title:
usernames = [acc.username for acc in other_participants]
usernames = tuple(acc.username for acc in other_participants)
if not usernames: if not usernames:
title = _('No name') title = _('No name')
else: else:
@ -130,7 +130,7 @@ class ConversationManager(models.Manager):
return 0 return 0
def fetch(self, account): def fetch(self, account):
conversations = self.filter(models.Q(author=account) | models.Q(participants__in=[account])).annotate(
conversations = self.filter(models.Q(author=account) | models.Q(participants__in=(account,))).annotate(
msg_count=models.Count('message', distinct=True) msg_count=models.Count('message', distinct=True)
) )
return conversations return conversations
@ -194,7 +194,7 @@ class Conversation(models.Model):
if not isinstance(cm, ConversationMembership): if not isinstance(cm, ConversationMembership):
raise TypeError('cm must be instance of msg_app.ConversationMembership') raise TypeError('cm must be instance of msg_app.ConversationMembership')
cm.status = status cm.status = status
cm.save(update_fields=['status'])
cm.save(update_fields=('status',))
return cm return cm
def make_participant_status_admin(self, user): def make_participant_status_admin(self, user):
@ -243,4 +243,4 @@ class Conversation(models.Model):
permissions = ( permissions = (
('can_view_conversation', _('Can view conversation')), ('can_view_conversation', _('Can view conversation')),
) )
ordering = ['title']
ordering = ('title',)

2
mydefs.py

@ -167,7 +167,7 @@ def require_ssl(view):
class MultipleException(Exception): class MultipleException(Exception):
def __init__(self, err_list): def __init__(self, err_list):
if not isinstance(err_list, list):
if not isinstance(err_list, (list, tuple)):
raise TypeError raise TypeError
self.err_list = err_list self.err_list = err_list

1
requirements.txt

@ -1,3 +1,4 @@
urllib3
Django==1.11 Django==1.11
Pillow Pillow
telepot telepot

16
statistics/models.py

@ -9,8 +9,8 @@ from .fields import UnixDateTimeField
def get_dates(): def get_dates():
tables = connection.introspection.table_names() 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]
tables = (t.replace('flowstat_', '') for t in tables if t.startswith('flowstat_'))
return tuple(datetime.strptime(t, '%d%m%Y').date() for t in tables)
class StatManager(models.Manager): class StatManager(models.Manager):
@ -22,21 +22,21 @@ class StatManager(models.Manager):
chunk_size = len(lst) // chunk_count chunk_size = len(lst) // chunk_count
if chunk_size == 0: if chunk_size == 0:
chunk_size = 1 chunk_size = 1
return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]
return tuple(lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size))
def avarage(elements): def avarage(elements):
return sum(elements) / len(elements) return sum(elements) / len(elements)
try: try:
charts_data = self.filter(uname=username) charts_data = self.filter(uname=username)
charts_times = [cd.cur_time.timestamp() * 1000 for cd in charts_data]
charts_octets = [cd.octets for cd in charts_data]
charts_times = tuple(cd.cur_time.timestamp() * 1000 for cd in charts_data)
charts_octets = tuple(cd.octets for cd in charts_data)
if len(charts_octets) > 0 and len(charts_octets) == len(charts_times): if len(charts_octets) > 0 and len(charts_octets) == len(charts_times):
charts_octets = split_list(charts_octets, count_of_parts) charts_octets = split_list(charts_octets, count_of_parts)
charts_octets = [byte_to_mbit(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 = split_list(charts_times, count_of_parts)
charts_times = [avarage(t) for t in charts_times]
charts_times = (avarage(t) for t in charts_times)
charts_data = zip(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] charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data]
@ -127,4 +127,4 @@ class StatCache(models.Model):
class Meta: class Meta:
db_table = 'flowcache' db_table = 'flowcache'
ordering = ['-last_time']
ordering = ('-last_time',)

6
tariff_app/models.py

@ -11,7 +11,7 @@ from jsonfield import JSONField
class TariffManager(models.Manager): class TariffManager(models.Manager):
def get_tariffs_by_group(self, group_id): def get_tariffs_by_group(self, group_id):
return self.filter(groups__id__in=[group_id])
return self.filter(groups__id__in=(group_id,))
class Tariff(models.Model): class Tariff(models.Model):
@ -51,7 +51,7 @@ class Tariff(models.Model):
class Meta: class Meta:
db_table = 'tariffs' db_table = 'tariffs'
ordering = ['title']
ordering = ('title',)
verbose_name = _('Service') verbose_name = _('Service')
verbose_name_plural = _('Services') verbose_name_plural = _('Services')
@ -104,7 +104,7 @@ class PeriodicPay(models.Model):
) )
verbose_name = _('Periodic pay') verbose_name = _('Periodic pay')
verbose_name_plural = _('Periodic pays') verbose_name_plural = _('Periodic pays')
ordering = ['-id']
ordering = ('-id',)
@receiver(models.signals.pre_delete, sender=PeriodicPay) @receiver(models.signals.pre_delete, sender=PeriodicPay)

4
tariff_app/views.py

@ -17,11 +17,11 @@ from . import forms
class BaseServiceListView(ListView): class BaseServiceListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class TariffsListView(BaseServiceListView, OrderingMixin): class TariffsListView(BaseServiceListView, OrderingMixin):
""" """
Show Services(Tariffs) list Show Services(Tariffs) list

6
taskapp/models.py

@ -88,7 +88,7 @@ class Task(models.Model):
act_type='f', act_type='f',
who=current_user who=current_user
) )
self.save(update_fields=['state', 'out_date'])
self.save(update_fields=('state', 'out_date'))
def do_fail(self, current_user): def do_fail(self, current_user):
self.state = 'C' # Crashed self.state = 'C' # Crashed
@ -97,7 +97,7 @@ class Task(models.Model):
act_type='b', act_type='b',
who=current_user who=current_user
) )
self.save(update_fields=['state'])
self.save(update_fields=('state',))
def send_notification(self): def send_notification(self):
if self.abon: if self.abon:
@ -132,4 +132,4 @@ class ExtraComment(models.Model):
) )
verbose_name = _('Extra comment') verbose_name = _('Extra comment')
verbose_name_plural = _('Extra comments') verbose_name_plural = _('Extra comments')
ordering = ['-date_create']
ordering = ('-date_create',)

20
taskapp/views.py

@ -24,11 +24,11 @@ from .forms import TaskFrm, ExtraCommentForm
class BaseTaskListView(ListView): class BaseTaskListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class NewTasksView(BaseTaskListView): class NewTasksView(BaseTaskListView):
""" """
Show new tasks Show new tasks
@ -81,7 +81,7 @@ class MyTaskListView(NewTasksView):
.select_related('abon', 'abon__street', 'abon__group', 'author') .select_related('abon', 'abon__street', 'abon__group', 'author')
@method_decorator([login_required, permission_required('taskapp.can_viewall')], name='dispatch')
@method_decorator((login_required, permission_required('taskapp.can_viewall')), name='dispatch')
class AllTasksListView(BaseTaskListView): class AllTasksListView(BaseTaskListView):
template_name = 'taskapp/tasklist_all.html' template_name = 'taskapp/tasklist_all.html'
context_object_name = 'tasks' context_object_name = 'tasks'
@ -110,9 +110,9 @@ def task_delete(request, task_id):
return redirect('taskapp:home') return redirect('taskapp:home')
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class TaskUpdateView(UpdateView): class TaskUpdateView(UpdateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'taskapp/add_edit_task.html' template_name = 'taskapp/add_edit_task.html'
form_class = TaskFrm form_class = TaskFrm
context_object_name = 'task' context_object_name = 'task'
@ -150,7 +150,7 @@ class TaskUpdateView(UpdateView):
self.object = form.save() self.object = form.save()
if self.object.author is None: if self.object.author is None:
self.object.author = self.request.user self.object.author = self.request.user
self.object.save(update_fields=['author'])
self.object.save(update_fields=('author',))
task_id = safe_int(self.kwargs.get('task_id', 0)) task_id = safe_int(self.kwargs.get('task_id', 0))
if task_id == 0: if task_id == 0:
log_text = _('Task has successfully created') log_text = _('Task has successfully created')
@ -234,7 +234,7 @@ def task_failed(request, task_id):
def remind(request, task_id): def remind(request, task_id):
try: try:
task = get_object_or_404(Task, id=task_id) task = get_object_or_404(Task, id=task_id)
task.save(update_fields=['state'])
task.save(update_fields=('state',))
task.send_notification() task.send_notification()
except MultipleException as errs: except MultipleException as errs:
for err in errs.err_list: for err in errs.err_list:
@ -261,7 +261,7 @@ def check_news(request):
return HttpResponse(dumps(r)) return HttpResponse(dumps(r))
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
@method_decorator(permission_required('taskapp.add_extracomment'), name='dispatch') @method_decorator(permission_required('taskapp.add_extracomment'), name='dispatch')
class NewCommentView(CreateView): class NewCommentView(CreateView):
form_class = ExtraCommentForm form_class = ExtraCommentForm
@ -280,12 +280,12 @@ class NewCommentView(CreateView):
return FormMixin.form_valid(self, form) return FormMixin.form_valid(self, form)
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
@method_decorator(permission_required('taskapp.delete_extracomment'), name='dispatch') @method_decorator(permission_required('taskapp.delete_extracomment'), name='dispatch')
class DeleteCommentView(DeleteView): class DeleteCommentView(DeleteView):
model = ExtraComment model = ExtraComment
pk_url_kwarg = 'comment_id' pk_url_kwarg = 'comment_id'
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'taskapp/comments/extracomment_confirm_delete.html' template_name = 'taskapp/comments/extracomment_confirm_delete.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

Loading…
Cancel
Save