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=''):
username = ''.join([choice(chars) for i in range(length)])
username = ''.join(choice(chars) for i in range(length))
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:
models.Abon.objects.get(username=username)
@ -65,7 +65,7 @@ class AbonForm(forms.ModelForm):
class Meta:
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 = {
'fio': forms.TextInput(attrs={
'placeholder': _('fio'),
@ -88,7 +88,7 @@ class AbonForm(forms.ModelForm):
try:
abon_raw_passw = models.AbonRawPassword.objects.get(account=acc)
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:
models.AbonRawPassword.objects.create(
account=acc,
@ -100,7 +100,7 @@ class AbonForm(forms.ModelForm):
class PassportForm(forms.ModelForm):
class Meta:
model = models.PassportInfo
exclude = ['abon']
exclude = ('abon',)
widgets = {
'series': forms.TextInput(attrs={'required': '', 'pattern': '^\d{4}$'}),
'number': forms.TextInput(attrs={'required': '', 'pattern': '^\d{6}$'}),
@ -136,7 +136,7 @@ class AbonStreetForm(forms.ModelForm):
class AdditionalTelephoneForm(forms.ModelForm):
class Meta:
model = models.AdditionalTelephone
exclude = ['abon']
exclude = ('abon',)
widgets = {
'telephone': forms.TextInput(attrs={
'placeholder': _('telephone placeholder'),
@ -151,7 +151,7 @@ class AdditionalTelephoneForm(forms.ModelForm):
class PeriodicPayForIdForm(forms.ModelForm):
class Meta:
model = models.PeriodicPayForId
exclude = ['account']
exclude = ('account',)
class ExportUsersForm(forms.Form):
@ -179,8 +179,8 @@ class ExportUsersForm(forms.Form):
class MarkersForm(forms.ModelForm):
class Meta:
model = models.Abon
fields = ['markers']
fields = ('markers',)
def save(self, commit=True):
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 "Финансы"
msgid "History of tasks"
msgstr "История платежей"
msgstr "История задач"
msgid "Charts"
msgstr "Графики"

30
abonapp/models.py

@ -34,7 +34,7 @@ class AbonLog(models.Model):
permissions = (
('can_view_abonlog', _('Can view subscriber logs')),
)
ordering = ['-date']
ordering = ('-date',)
def __str__(self):
return self.comment
@ -68,7 +68,7 @@ class AbonTariff(models.Model):
)
verbose_name = _('Abon service')
verbose_name_plural = _('Abon services')
ordering = ['time_start']
ordering = ('time_start',)
class AbonStreet(models.Model):
@ -82,7 +82,7 @@ class AbonStreet(models.Model):
db_table = 'abon_street'
verbose_name = _('Street')
verbose_name_plural = _('Streets')
ordering = ['name']
ordering = ('name',)
class ExtraFieldsModel(models.Model):
@ -185,7 +185,7 @@ class Abon(BaseAccount):
# unique_together = ('device', 'dev_port')
verbose_name = _('Abon')
verbose_name_plural = _('Abons')
ordering = ['fio']
ordering = ('fio',)
def add_ballance(self, current_user, amount, comment):
AbonLog.objects.create(
@ -273,7 +273,7 @@ class Abon(BaseAccount):
# check if ip address already busy
if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude(
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()
def sync_with_nas(self, created: bool) -> Optional[Exception]:
@ -292,8 +292,8 @@ class Abon(BaseAccount):
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)
date_of_acceptance = models.DateField()
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'
verbose_name = _('Passport Info')
verbose_name_plural = _('Passport Info')
ordering = ['series']
ordering = ('series',)
def __str__(self):
return "%s %s" % (self.series, self.number)
@ -366,7 +366,7 @@ class AllTimePayLog(models.Model):
class Meta:
db_table = 'all_time_pay_log'
ordering = ['-date_add']
ordering = ('-date_add',)
# log for all terminals
@ -381,7 +381,7 @@ class AllPayLog(models.Model):
class Meta:
db_table = 'all_pay_log'
ordering = ['-date_action']
ordering = ('-date_action',)
class AbonRawPassword(models.Model):
@ -401,7 +401,7 @@ class AdditionalTelephone(models.Model):
max_length=16,
verbose_name=_('Telephone'),
# unique=True,
validators=[RegexValidator(TELEPHONE_REGEXP)]
validators=(RegexValidator(TELEPHONE_REGEXP),)
)
owner_name = models.CharField(max_length=127)
@ -410,7 +410,7 @@ class AdditionalTelephone(models.Model):
class Meta:
db_table = 'additional_telephones'
ordering = ['owner_name']
ordering = ('owner_name',)
permissions = (
('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"') % {
'service': self.periodic_pay
})
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
self.last_pay = now
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):
return "%s %s" % (self.periodic_pay, self.next_pay)
class Meta:
db_table = 'periodic_pay_for_id'
ordering = ['last_pay']
ordering = ('last_pay',)
@receiver(post_delete, sender=Abon)

2
abonapp/pay_systems.py

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

22
abonapp/tests.py

@ -32,7 +32,7 @@ class AllPayTestCase(TestCase):
)
a1.ballance = -13.12
a1.fio = 'Test Name'
a1.save(update_fields=['ballance', 'fio'])
a1.save(update_fields=('ballance', 'fio'))
# Abon.objects.create_user(
# telephone='+79788163841',
# username='pay_account2',
@ -52,7 +52,7 @@ class AllPayTestCase(TestCase):
}
))
r = r.content.decode('utf-8')
self.assertXMLEqual(r, ''.join([
self.assertXMLEqual(r, ''.join((
"<pay-response>",
"<balance>-13.12</balance>",
"<name>Test Name</name>",
@ -63,7 +63,7 @@ class AllPayTestCase(TestCase):
"<status_code>21</status_code>",
"<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>"
]))
)))
def user_pay_pay(self):
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')
}))
r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>",
"<pay_id>840ab457-e7d1-4494-8197-9570da035170</pay_id>",
"<service_id>%s</service_id>" % SERVICE_ID,
@ -87,7 +87,7 @@ class AllPayTestCase(TestCase):
"<status_code>22</status_code>",
"<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>"
])
))
self.test_pay_time = current_date
self.assertXMLEqual(r, xml)
@ -103,7 +103,7 @@ class AllPayTestCase(TestCase):
}
))
r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>",
"<status_code>11</status_code>",
"<time_stamp>%s</time_stamp>" % current_date,
@ -115,7 +115,7 @@ class AllPayTestCase(TestCase):
"<time_stamp>%s</time_stamp>" % self.test_pay_time,
"</transaction>"
"</pay-response>"
])
))
self.assertXMLEqual(r, xml)
def check_ballance(self):
@ -148,12 +148,12 @@ class AllPayTestCase(TestCase):
}
))
r = r.content.decode('utf-8')
self.assertXMLEqual(r, ''.join([
self.assertXMLEqual(r, ''.join((
"<pay-response>",
"<status_code>-40</status_code>",
"<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>"
]))
)))
def try_pay_double(self):
print('try_pay_double')
@ -181,12 +181,12 @@ class AllPayTestCase(TestCase):
'SIGN': _make_sign(7, '', SERVICE_ID, uuid)
}))
r = r.content.decode('utf-8')
xml = ''.join([
xml = ''.join((
"<pay-response>",
"<status_code>-10</status_code>",
"<time_stamp>%s</time_stamp>" % current_date,
"</pay-response>"
])
))
self.assertXMLEqual(r, xml)
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):
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):
context_object_name = 'peoples'
template_name = 'abonapp/peoples.html'
@ -85,7 +85,7 @@ class PeoplesListView(BaseAbonListView):
return context
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins), name='dispatch')
class GroupListView(BaseAbonListView):
context_object_name = 'groups'
template_name = 'abonapp/group_list.html'
@ -98,7 +98,7 @@ class GroupListView(BaseAbonListView):
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')
class AbonCreateView(CreateView):
group = None
@ -154,7 +154,7 @@ class AbonCreateView(CreateView):
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')
class DelAbonDeleteView(DeleteView):
model = models.Abon
@ -198,7 +198,7 @@ def abonamount(request, gid, uname):
if abonuname == uname:
amnt = mydefs.safe_float(request.POST.get('amount'))
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)
return redirect('abonapp:abon_phistory', gid=gid, uname=uname)
else:
@ -214,7 +214,7 @@ def abonamount(request, gid, uname):
}, 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')
class DebtsListView(BaseAbonListView):
context_object_name = 'invoices'
@ -232,7 +232,7 @@ class DebtsListView(BaseAbonListView):
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')
class PayHistoryListView(BaseAbonListView):
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')
class AbonHomeUpdateView(UpdateView):
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')
class LogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'logs'
template_name = 'abonapp/log.html'
model = models.AbonLog
@ -483,7 +483,7 @@ class LogListView(ListView):
@method_decorator(permission_required('abonapp.can_view_invoiceforpayment'), name='dispatch')
class DebtorsListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'invoices'
template_name = 'abonapp/debtors.html'
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')
class TaskLogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
http_method_names = ('get',)
context_object_name = 'tasks'
template_name = 'abonapp/task_log.html'
@ -553,12 +553,12 @@ def chgroup_tariff(request, gid):
if request.method == 'POST':
tr = request.POST.getlist('tr')
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()
messages.success(request, _('Successfully saved'))
return redirect('abonapp:ch_group_tariff', gid)
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', {
'group': grp,
'seleted_tariffs': seleted_tariffs_id,
@ -575,7 +575,7 @@ def dev(request, gid, uname):
if request.method == 'POST':
dev = Device.objects.get(pk=request.POST.get('dev'))
abon.device = dev
abon.save(update_fields=['device'])
abon.save(update_fields=('device',))
messages.success(request, _('Device has successfully attached'))
return redirect('abonapp:abon_home', gid=gid, uname=uname)
else:
@ -600,7 +600,7 @@ def clear_dev(request, gid, uname):
abon = models.Abon.objects.get(username=uname)
abon.device = 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'))
except models.Abon.DoesNotExist:
messages.error(request, _('Abon does not exist'))
@ -624,7 +624,7 @@ def charts(request, gid, uname):
abon = models.Abon.objects.get(username=uname)
if abon.group is None:
abon.group = Group.objects.get(pk=gid)
abon.save(update_fields=['group'])
abon.save(update_fields=('group',))
charts_data = StatElem.objects.chart(
abon.username,
@ -692,16 +692,15 @@ def make_extra_field(request, gid, uname):
@login_required
@permission_required('abonapp.change_extra_fields_model')
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:
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"))
except models.ExtraFieldsModel.DoesNotExist:
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
@ -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):
context_object_name = 'logs'
template_name = 'abonapp/dial_log.html'
@ -838,9 +837,9 @@ def save_user_dev_port(request, gid, uname):
abon.dev_port = port
if 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:
abon.save(update_fields=['dev_port'])
abon.save(update_fields=('dev_port',))
messages.success(request, _('User port has been saved'))
except DevPort.DoesNotExist:
messages.error(request, _('Selected port does not exist'))
@ -875,9 +874,7 @@ def street_add(request, gid):
def street_edit(request, gid):
try:
if request.method == 'POST':
streets_pairs = [(int(sid), sname) for sid, sname in
zip(request.POST.getlist('sid'), request.POST.getlist('sname'))]
for sid, sname in streets_pairs:
for sid, sname in zip(request.POST.getlist('sid'), request.POST.getlist('sname')):
street = models.AbonStreet.objects.get(pk=sid)
street.name = sname
street.save()
@ -993,7 +990,7 @@ def abon_export(request, gid):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="users.csv"'
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)
for row in subscribers:
writer.writerow(row)
@ -1019,7 +1016,7 @@ def abon_export(request, gid):
def reset_ip(request, gid, uname):
abon = get_object_or_404(models.Abon, username=uname)
abon.ip_address = None
abon.save(update_fields=['ip_address'])
abon.save(update_fields=('ip_address',))
return {
'status': 0,
'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)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator((login_required, mydefs.only_admins,), name='dispatch')
class EditSibscriberMarkers(UpdateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'abonapp/modal_user_markers.html'
form_class = forms.MarkersForm
@ -1121,18 +1118,18 @@ class EditSibscriberMarkers(UpdateView):
@mydefs.only_admins
@json_view
def abons(request):
ablist = [{
ablist = ({
'id': abn.pk,
'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0,
'ip': abn.ip_address.int_ip(),
'is_active': abn.is_active
} for abn in models.Abon.objects.all()]
} for abn in models.Abon.objects.all())
tarlist = [{
tarlist = ({
'id': trf.pk,
'speedIn': trf.speedIn,
'speedOut': trf.speedOut
} for trf in Tariff.objects.all()]
} for trf in Tariff.objects.all())
data = {
'subscribers': ablist,
@ -1150,7 +1147,7 @@ def search_abon(request):
if not word:
return None
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
@ -1158,7 +1155,7 @@ class DhcpLever(SecureApiView):
#
# Api view for dhcp event
#
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view)
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.
"""
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())
to_remove = (model_perms - perms) & init_perms
@ -28,4 +28,4 @@ class MyUserObjectPermissionsForm(UserObjectPermissionsForm):
class AvatarChangeForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['avatar']
fields = ('avatar',)

12
accounts_app/models.py

@ -50,7 +50,7 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
_('profile username'),
max_length=127,
unique=True,
validators=[RegexValidator(r'^\w{1,127}$')]
validators=(RegexValidator(r'^\w{1,127}$'),)
)
fio = models.CharField(_('fio'), max_length=256)
birth_day = models.DateField(_('birth day'), auto_now_add=True)
@ -60,11 +60,11 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
max_length=16,
verbose_name=_('Telephone'),
blank=True,
validators=[RegexValidator(TELEPHONE_REGEXP)]
validators=(RegexValidator(TELEPHONE_REGEXP),)
)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['telephone']
REQUIRED_FIELDS = ('telephone',)
def get_full_name(self):
return self.fio if self.fio else self.username
@ -86,12 +86,12 @@ class BaseAccount(AbstractBaseUser, PermissionsMixin):
class Meta:
db_table = 'base_accounts'
ordering = ['username']
ordering = ('username',)
class UserProfileManager(MyUserManager):
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):
@ -116,7 +116,7 @@ class UserProfile(BaseAccount):
)
verbose_name = _('Staff account profile')
verbose_name_plural = _('Staff account profiles')
ordering = ['fio']
ordering = ('fio',)
def _thumbnail_avatar(self):
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):
http_method_names = ['get']
http_method_names = ('get',)
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):
form_class = AvatarChangeForm
template_name = 'accounts/settings/ch_info.html'
@ -180,7 +180,7 @@ def delete_profile(request, uid):
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):
template_name = 'accounts/acc_list.html'
context_object_name = 'users'
@ -270,7 +270,7 @@ def set_abon_groups_permission(request, uid):
picked_groups = picked_groups.values_list('pk', flat=True)
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():
if grp.pk in checked_groups and grp.pk not in picked_groups:
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):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'accounts/manage_responsibility_groups.html'
context_object_name = 'groups'
queryset = Group.objects.only('pk', 'title')
@ -306,14 +306,14 @@ class ManageResponsibilityGroups(ListView):
context = super(ManageResponsibilityGroups, self).get_context_data(**kwargs)
context['uid'] = self.kwargs.get('uid')
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
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.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()
messages.success(request, _('Responsibilities has been updated'))
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
if 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)
except Abon.DoesNotExist:
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
}
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]:
try:
abon = Abon.objects.get(ip_address=client_ip)
abon.ip_address = None
abon.save(update_fields=['ip_address'])
abon.save(update_fields=('ip_address',))
abon.sync_with_nas(created=False)
except Abon.DoesNotExist:
return "Subscriber with ip %s does not exist" % client_ip

116
agent/mod_mikrotik.py

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

14
agent/monitoring_agent.py

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

1
agent/netflow/netflow_handler.py

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

1
agent/utils.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import socket
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.conf import settings
@ -20,7 +20,7 @@ class TelegramBot(models.Model):
db_table = 'chat_telegram_bot'
verbose_name = _('Telegram bot')
verbose_name_plural = _('Telegram bots')
ordering = ['chat_id']
ordering = ('chat_id',)
class MessageHistory(models.Model):
@ -35,7 +35,7 @@ class MessageHistory(models.Model):
db_table = 'chat_message_history'
verbose_name = _('Message history')
verbose_name_plural = _('Message histories')
ordering = ['-date_sent']
ordering = ('-date_sent',)
class MessageQueueManager(models.Manager):
@ -70,4 +70,4 @@ class MessageQueue(models.Model):
db_table = 'chat_message_queue'
verbose_name = _('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()
# выполняем комманды если они есть
if text in list(self.cmds.keys()):
if text in self.cmds.keys():
self.cmds[text]()
elif self._dialog_fn is not None:
if not callable(self._dialog_fn):
@ -123,7 +123,7 @@ class DjingTelebot(helper.ChatHandler):
return
try:
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)
except socket.error:
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(),
'amount': amount
})
abon.save(update_fields=['ballance'])
abon.save(update_fields=('ballance',))
debt.set_ok()
debt.save(update_fields=['status', 'date_pay'])
debt.save(update_fields=('status', 'date_pay'))
return redirect('client_side:debts')
except LogicError as e:
messages.error(request, e)

2
devapp/base_intr.py

@ -71,7 +71,7 @@ class BasePort(object, metaclass=ABCMeta):
pass
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):

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)
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)
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)
return {
'status': status,

8
devapp/models.py

@ -54,7 +54,7 @@ class Device(models.Model):
)
verbose_name = _('Device')
verbose_name_plural = _('Devices')
ordering = ['id']
ordering = ('id',)
def get_abons(self):
pass
@ -63,7 +63,7 @@ class Device(models.Model):
return self.status
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:
res = klasses[0][1]
if issubclass(res, DevBase):
@ -94,7 +94,7 @@ class Device(models.Model):
param = 'del'
else:
param = 'update'
run([filepath, param, newmac, code])
run((filepath, param, newmac, code))
class Port(models.Model):
@ -113,4 +113,4 @@ class Port(models.Model):
)
verbose_name = _('Port')
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):
http_method_names = ['get']
http_method_names = ('get',)
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):
context_object_name = 'devices'
template_name = 'devapp/devices.html'
@ -61,7 +61,7 @@ class DevicesListView(global_base_views.OrderingMixin, BaseDeviceListView):
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):
context_object_name = 'devices'
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):
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):
dev_id = self.kwargs.get('device_id')
@ -241,7 +241,7 @@ def add_ports(request, device_id):
try:
port = Port.objects.get(num=port_num, device=dev)
port.descr = port_text
port.save(update_fields=['descr'])
port.save(update_fields=('descr',))
except Port.DoesNotExist:
Port.objects.create(
num=port_num,
@ -250,12 +250,12 @@ def add_ports(request, device_id):
)
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()
ports = manager.get_ports()
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)
else:
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)
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class GroupsListView(BaseDeviceListView):
context_object_name = 'groups'
template_name = 'devapp/group_list.html'
@ -431,16 +431,18 @@ class GroupsListView(BaseDeviceListView):
@login_required
@json_view
def search_dev(request):
word = request.GET.get('s')
if word is None or word == '':
results = [{'id': 0, 'text': ''}]
results = ({'id': 0, 'text': ''},)
else:
results = Device.objects.filter(
Q(comment__icontains=word) | Q(ip_address=word)
).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
@ -470,6 +472,7 @@ def fix_device_group(request, device_id):
@login_required
@json_view
def fix_onu(request):
mac = request.GET.get('cmd_param')
status = 1
@ -484,10 +487,10 @@ def fix_onu(request):
(_('Device with mac address %(mac)s does not exist') % {'mac': mac})
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' % ord(i) for i in srcmac)
if mac == real_mac:
onu.snmp_item_num = snmpnum
onu.save(update_fields=['snmp_item_num'])
onu.save(update_fields=('snmp_item_num',))
status = 0
text = '<span class="glyphicon glyphicon-ok"></span> <span class="hidden-xs">%s</span>' % _('Fixed')
break
@ -495,10 +498,10 @@ def fix_onu(request):
text = text + '\n%s' % _('Parent device not found')
except Device.DoesNotExist:
pass
return JsonResponse({
return {
'status': status,
'dat': text
})
}
@login_required
@ -519,7 +522,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
#
# Api view for monitoring devices
#
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view)
def get(self, request):
@ -550,7 +553,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
device_down.status = 'und'
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:
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):
http_method_names = ['get']
http_method_names = ('get',)
def get(self, request, *args, **kwargs):
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]):
if not host_addr:
return
r = [
r = (
"define host{",
"\tuse generic-switch",
"\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 '',
"\t_mac_addr %s" % mac if mac is not None else '',
"}\n"
]
)
return '\n'.join(i for i in r if i)
@staticmethod
def templ_onu(host_name: str, host_addr: str, mac: Optional[str], snmp_item: int):
if not host_addr:
return
r = [
r = (
"define host{",
"\tuse device-onu",
"\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_mac_addr %s" % mac if mac is not None else '',
"}\n"
]
)
return '\n'.join(i for i in r if i)
class DevicesGetListView(global_base_views.SecureApiView):
http_method_names = ['get']
http_method_names = ('get',)
@method_decorator(json_view)
def get(self, request, *args, **kwargs):
from netaddr import EUI
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:
devs = Device.objects.all()
else:
@ -663,4 +666,4 @@ class DevicesGetListView(global_base_views.SecureApiView):
for r in res:
if isinstance(r['mac_addr'], EUI):
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:
db_table = 'cdr'
managed = False
ordering = ['-calldate']
ordering = ('-calldate',)
class SMSModel(models.Model):
@ -85,7 +85,7 @@ class SMSModel(models.Model):
)
verbose_name = _('SMS')
verbose_name_plural = _('SMS')
ordering = ['-when']
ordering = ('-when',)
def __str__(self):
return self.text
@ -110,7 +110,7 @@ class SMSOut(models.Model):
)
verbose_name = _('Out SMS')
verbose_name_plural = _('Out SMS')
ordering = ['-when']
ordering = ('-when',)
def __str__(self):
return self.text

12
dialing_app/views.py

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

2
group_app/models.py

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

6
group_app/views.py

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

2
mapapp/models.py

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

2
mapapp/views.py

@ -20,7 +20,7 @@ from guardian.decorators import permission_required
class BaseListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
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):
"""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):
return ''.join(["%02x" % n for n in b])
return ''.join("%02x" % n for n in b)
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:
return False
ms.status = code
ms.save(update_fields=['status'])
ms.save(update_fields=('status',))
return True
except MessageStatus.DoesNotExist:
return False
@ -64,7 +64,7 @@ class Message(models.Model):
class Meta:
db_table = 'messages'
ordering = ['-sent_at']
ordering = ('-sent_at',)
verbose_name = _("Message")
verbose_name_plural = _("Messages")
permissions = (
@ -105,9 +105,9 @@ def id_to_userprofile(acc):
class ConversationManager(models.Manager):
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:
usernames = [acc.username for acc in other_participants]
usernames = tuple(acc.username for acc in other_participants)
if not usernames:
title = _('No name')
else:
@ -130,7 +130,7 @@ class ConversationManager(models.Manager):
return 0
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)
)
return conversations
@ -194,7 +194,7 @@ class Conversation(models.Model):
if not isinstance(cm, ConversationMembership):
raise TypeError('cm must be instance of msg_app.ConversationMembership')
cm.status = status
cm.save(update_fields=['status'])
cm.save(update_fields=('status',))
return cm
def make_participant_status_admin(self, user):
@ -243,4 +243,4 @@ class Conversation(models.Model):
permissions = (
('can_view_conversation', _('Can view conversation')),
)
ordering = ['title']
ordering = ('title',)

2
mydefs.py

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

1
requirements.txt

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

16
statistics/models.py

@ -9,8 +9,8 @@ from .fields import UnixDateTimeField
def get_dates():
tables = connection.introspection.table_names()
tables = [t.replace('flowstat_', '') for t in tables if t.startswith('flowstat_')]
return [datetime.strptime(t, '%d%m%Y').date() for t in tables]
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):
@ -22,21 +22,21 @@ class StatManager(models.Manager):
chunk_size = len(lst) // chunk_count
if chunk_size == 0:
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):
return sum(elements) / len(elements)
try:
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):
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 = [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 = ["{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:
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):
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):
@ -51,7 +51,7 @@ class Tariff(models.Model):
class Meta:
db_table = 'tariffs'
ordering = ['title']
ordering = ('title',)
verbose_name = _('Service')
verbose_name_plural = _('Services')
@ -104,7 +104,7 @@ class PeriodicPay(models.Model):
)
verbose_name = _('Periodic pay')
verbose_name_plural = _('Periodic pays')
ordering = ['-id']
ordering = ('-id',)
@receiver(models.signals.pre_delete, sender=PeriodicPay)

4
tariff_app/views.py

@ -17,11 +17,11 @@ from . import forms
class BaseServiceListView(ListView):
http_method_names = ['get']
http_method_names = ('get',)
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):
"""
Show Services(Tariffs) list

6
taskapp/models.py

@ -88,7 +88,7 @@ class Task(models.Model):
act_type='f',
who=current_user
)
self.save(update_fields=['state', 'out_date'])
self.save(update_fields=('state', 'out_date'))
def do_fail(self, current_user):
self.state = 'C' # Crashed
@ -97,7 +97,7 @@ class Task(models.Model):
act_type='b',
who=current_user
)
self.save(update_fields=['state'])
self.save(update_fields=('state',))
def send_notification(self):
if self.abon:
@ -132,4 +132,4 @@ class ExtraComment(models.Model):
)
verbose_name = _('Extra comment')
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):
http_method_names = ['get']
http_method_names = ('get',)
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):
"""
Show new tasks
@ -81,7 +81,7 @@ class MyTaskListView(NewTasksView):
.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):
template_name = 'taskapp/tasklist_all.html'
context_object_name = 'tasks'
@ -110,9 +110,9 @@ def task_delete(request, task_id):
return redirect('taskapp:home')
@method_decorator([login_required, only_admins], name='dispatch')
@method_decorator((login_required, only_admins), name='dispatch')
class TaskUpdateView(UpdateView):
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'taskapp/add_edit_task.html'
form_class = TaskFrm
context_object_name = 'task'
@ -150,7 +150,7 @@ class TaskUpdateView(UpdateView):
self.object = form.save()
if self.object.author is None:
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))
if task_id == 0:
log_text = _('Task has successfully created')
@ -234,7 +234,7 @@ def task_failed(request, task_id):
def remind(request, task_id):
try:
task = get_object_or_404(Task, id=task_id)
task.save(update_fields=['state'])
task.save(update_fields=('state',))
task.send_notification()
except MultipleException as errs:
for err in errs.err_list:
@ -261,7 +261,7 @@ def check_news(request):
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')
class NewCommentView(CreateView):
form_class = ExtraCommentForm
@ -280,12 +280,12 @@ class NewCommentView(CreateView):
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')
class DeleteCommentView(DeleteView):
model = ExtraComment
pk_url_kwarg = 'comment_id'
http_method_names = ['get', 'post']
http_method_names = ('get', 'post')
template_name = 'taskapp/comments/extracomment_confirm_delete.html'
def get_context_data(self, **kwargs):

Loading…
Cancel
Save