Browse Source

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

devel
nerosketch 8 years ago
parent
commit
ca8a0aa57e
  1. 21
      abonapp/forms.py
  2. 10
      abonapp/locale/ru/LC_MESSAGES/django.po
  3. 11
      abonapp/models.py
  4. 11
      abonapp/pay_systems.py
  5. 18
      abonapp/templates/abonapp/abon_confirm_delete.html
  6. 145
      abonapp/templates/abonapp/editAbon.html
  7. 2
      abonapp/templates/abonapp/peoples.html
  8. 78
      abonapp/templates/abonapp/viewAbon.html
  9. 5
      abonapp/urls.py
  10. 194
      abonapp/views.py
  11. 3
      accounts_app/templates/accounts/create_acc.html
  12. 3
      accounts_app/templates/accounts/settings/ch_info.html
  13. 12
      djing/settings.py

21
abonapp/forms.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from django.utils.translation import ugettext as _
from django import forms
@ -7,6 +6,7 @@ from random import choice
from string import digits, ascii_lowercase
from . import models
from django.conf import settings
from djing import IP_ADDR_REGEX
TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$')
@ -36,29 +36,36 @@ def generate_random_password():
class AbonForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AbonForm, self).__init__(*args, **kwargs)
if self.instance is not None and self.instance.group is not None:
abon_group_queryset = models.AbonStreet.objects.filter(group=self.instance.group)
instance = getattr(self, 'instance')
if instance is not None and instance.group is not None:
abon_group_queryset = models.AbonStreet.objects.filter(group=instance.group)
elif 'group' in self.initial.keys() and self.initial['group'] is not None:
abon_group_queryset = models.AbonStreet.objects.filter(group=self.initial['group'])
else:
abon_group_queryset = None
if abon_group_queryset is not None:
self.fields['street'].queryset = abon_group_queryset
if instance is not None and instance.is_dynamic_ip:
self.fields['ip_address'].widget.attrs['readonly'] = True
username = forms.CharField(max_length=127, required=False, initial=generate_random_username,
widget=forms.TextInput(attrs={
'placeholder': _('login'),
'required': '',
'pattern': r'^\w{1,127}$'
}))
}), label=_('login'))
password = forms.CharField(max_length=64, initial=generate_random_password, widget=forms.TextInput(attrs={
'class': 'form-control', 'type': 'password', 'autocomplete': 'new-password'
}))
'type': 'password', 'autocomplete': 'new-password'
}), label=_('Password'))
ip_address = forms.CharField(widget=forms.TextInput(attrs={
'pattern': IP_ADDR_REGEX
}), label=_('Ip Address'), required=False)
class Meta:
model = models.Abon
fields = ['username', 'telephone', 'fio', 'group', 'description', 'street', 'house', 'is_active']
fields = ['username', 'telephone', 'fio', 'group', 'description', 'street', 'house', 'is_active', 'ip_address']
widgets = {
'fio': forms.TextInput(attrs={
'placeholder': _('fio'),

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

@ -876,10 +876,6 @@ msgstr "Нет исполнителей"
msgid "Tasks not found"
msgstr "Нет задач"
#: templates/abonapp/viewAbon.html:10
msgid "View the subscriber"
msgstr "Просмотр абонента"
#: templates/abonapp/viewAbon.html:24
msgid "yes,no"
msgstr "Да,Нет"
@ -1135,3 +1131,9 @@ msgstr "Успешно сохранено"
msgid "This user can not buy admin services"
msgstr "Этот пользователь не может назначать административные услуги"
msgid "Remove subscriber"
msgstr "Удаление абонента"
msgid "Are you sure about them?"
msgstr "Вы уверены в этом?"

11
abonapp/models.py

@ -136,7 +136,7 @@ class Abon(BaseAccount):
current_tariff = models.ForeignKey(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL)
group = models.ForeignKey(Group, models.SET_NULL, blank=True, null=True, verbose_name=_('User group'))
ballance = models.FloatField(default=0.0)
ip_address = MyGenericIPAddressField(blank=True, null=True)
ip_address = MyGenericIPAddressField(blank=True, null=True, verbose_name=_('Ip Address'))
description = models.TextField(_('Comment'), null=True, blank=True)
street = models.ForeignKey(AbonStreet, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Street'))
house = models.CharField(_('House'), max_length=12, null=True, blank=True)
@ -263,17 +263,18 @@ class Abon(BaseAccount):
else:
return
abon_tariff = self.active_tariff()
if abon_tariff is None:
return
trf = abon_tariff.tariff
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
return AbonStruct(self.pk, user_ip, agent_trf, bool(self.is_active))
def save(self, *args, **kwargs):
def clean(self):
# 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:
self.is_bad_ip = True
raise LogicError(_('Ip address already exist'))
super(Abon, self).save(*args, **kwargs)
raise ValidationError({'ip_address': [gettext('Ip address already exist')]})
return super(Abon, self).clean()
def sync_with_nas(self, created: bool) -> Optional[Exception]:
agent_abon = self.build_agent_struct()

11
abonapp/pay_systems.py

@ -25,22 +25,21 @@ def allpay(request):
try:
serv_id = request.GET.get('SERVICE_ID')
act = safe_int(request.GET.get('ACT'))
pay_account = safe_int(request.GET.get('PAY_ACCOUNT'))
pay_account = request.GET.get('PAY_ACCOUNT')
pay_id = request.GET.get('PAY_ID')
pay_amount = safe_float(request.GET.get('PAY_AMOUNT'))
sign = request.GET.get('SIGN').lower()
if act <= 0: return bad_ret(-101, 'ACT less than zero')
# check sign
md = md5()
s = '_'.join((str(act), str(pay_account), serv_id or '', pay_id, SECRET))
s = '_'.join((str(act), pay_account or '', serv_id or '', pay_id, SECRET))
md.update(bytes(s, 'utf-8'))
our_sign = md.hexdigest()
if our_sign != sign:
return bad_ret(-101)
if act <= 0: return bad_ret(-101, 'ACT less than zero')
if pay_account == 0: return bad_ret(-40, 'PAY_ACCOUNT is not passed')
if act == 1:
abon = Abon.objects.get(username=pay_account)
fio = abon.fio
@ -50,7 +49,7 @@ def allpay(request):
"<pay-response>\n" \
" <balance>%.2f</balance>\n" % ballance + \
" <name>%s</name>\n" % fio + \
" <account>%d</account>\n" % pay_account + \
" <account>%s</account>\n" % pay_account + \
" <service_id>%s</service_id>\n" % SERV_ID + \
" <min_amount>10.0</min_amount>\n" \
" <max_amount>50000</max_amount>\n" \

18
abonapp/templates/abonapp/abon_confirm_delete.html

@ -0,0 +1,18 @@
{% load i18n %}
<form role="form" action="{% url 'abonapp:del_abon' abon.group.pk abon.username %}" method="post">{% csrf_token %}
<div class="modal-header warning">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title"><span class="glyphicon glyphicon-earphone"></span>{% trans 'Remove subscriber' %}</h4>
</div>
<div class="modal-body">
<h4>{% trans 'Are you sure about them?' %}</h4>
<button type="submit" class="btn btn-danger" value="DELETE">
<span class="glyphicon glyphicon-remove"></span> {% trans 'Delete' %}
</button>
</div>
</form>

145
abonapp/templates/abonapp/editAbon.html

@ -10,86 +10,99 @@
<h3 class="panel-title">{% trans 'Change subscriber' %}</h3>
</div>
<div class="panel-body">
<form autocomplete="off" class="form-horizontal" action="{% url 'abonapp:abon_home' group.pk abon.username %}" method="post">{% csrf_token %}
{% bootstrap_field form.username label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% bootstrap_field form.fio label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% if perms.abonapp.change_abon %}
{% url 'abonapp:abon_home' group.pk abon.username as ahlink %}
{% endif %}
<div class="form-group-sm">
<label for="id_telephone" class="col-sm-4 control-label">{% trans 'Telephone' %}</label>
<div class="col-sm-8">
<div class="input-group input-group-sm">
{{ form.telephone }}{{ form.telephone.errors }}
<span class="input-group-btn">
<a href="sip:{{ form.telephone.value }}" class="btn btn-default" data-toggle="tooltip" title="{% trans 'Call to' %}">
<span class="glyphicon glyphicon-earphone"></span>
</a>
<a href="{% url 'abonapp:telephones' group.pk abon.username %}" class="btn btn-default btn-modal" data-toggle="tooltip" title="{% trans 'Additional telephones' %}">
<span class="glyphicon glyphicon-list"></span>
</a>
<a href="{% url 'abonapp:telephone_new' group.pk abon.username %}" class="btn btn-default btn-modal" data-toggle="tooltip" title="{% trans 'Add telephone' %}">
<span class="glyphicon glyphicon-plus"></span>
</a>
</span>
</div>
</div>
</div>
<form autocomplete="off" class="form-horizontal" action="{{ ahlink|default:'#' }}" method="post">{% csrf_token %}
<div class="form-group-sm{% if is_bad_ip %} has-error{% endif %}">
<label for="id_ip" class="col-sm-4 control-label">{% trans 'Ip Address' %}</label>
<div class="col-sm-8">
<div class="input-group input-group-sm">
<input type="text" value="{{ ip|default:'' }}" class="form-control" name="ip" placeholder="{% trans 'Not assigned' %}" id="ipfield" pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"{% if abon.is_dynamic_ip %} disabled{% endif %}/>
<span class="input-group-btn">
<a href="{% url 'abonapp:reset_ip' group.pk abon.username %}" class="btn btn-default btn-cmd" data-toggle="tooltip" title="{% trans 'Reset ip' %}" onclick="$('#ipfield').val('');">
<span class="glyphicon glyphicon-refresh"></span>
</a>
</span>
</div>
</div>
</div>
{% bootstrap_field form.username form_group_class='form-group-sm' %}
{% bootstrap_field form.fio form_group_class='form-group-sm' %}
{% bootstrap_field form.street label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% bootstrap_field form.house label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% bootstrap_field form.is_active label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% bootstrap_field form.group label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
<div class="form-group-sm">
<label for="id_password" class="col-sm-4 control-label">{% trans 'Password' %}</label>
<div class="col-sm-8">
<div class="input-group input-group-sm">
{{ form.password }}{{ form.password.errors }}
<span class="input-group-btn">
<button type="button" class="btn btn-default" onmousedown="document.getElementById('id_password').type='text'" onmouseup="document.getElementById('id_password').type='password'">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
</span>
</div>
</div>
</div>
{# telephone field #}
{% trans 'Call to' as tx %}
{% bootstrap_button '' button_type='link' icon='earphone' button_class='btn-default' title=tx href='sip:'|add:form.telephone.value size='sm' as btn_call %}
{% bootstrap_field form.description label_class='col-sm-4' field_class='col-sm-8' form_group_class='form-group-sm' %}
{% trans 'Additional telephones' as tx %}
{% url 'abonapp:telephones' group.pk abon.username as url %}
{% bootstrap_button '' button_type='link' icon='list' button_class='btn-default btn-modal' title=tx href=url size='sm' as btn_teleph_list %}
{% trans 'Add telephone' as tx %}
{% url 'abonapp:telephone_new' group.pk abon.username as url %}
{% bootstrap_button '' button_type='link' icon='plus' button_class='btn-default btn-modal' title=tx href=url size='sm' as btn_teleph_add %}
{% with ''|add:btn_call|add:btn_teleph_list|add:btn_teleph_add as bt %}
{% bootstrap_field form.telephone form_group_class='form-group-sm' addon_after_class='input-group-btn' addon_after=bt %}
{% endwith %}
{# Ip address field #}
{% trans 'Reset ip' as tx %}
{% url 'abonapp:reset_ip' group.pk abon.username as url %}
{% bootstrap_button '' button_type='link' icon='refresh' button_class='btn-default btn-cmd' id='iprefreshbtn' href=url size='sm' title=tx as bt %}
{% bootstrap_field form.ip_address form_group_class='form-group-sm' addon_after_class='input-group-btn' addon_after=bt %}
{% bootstrap_field form.street form_group_class='form-group-sm' %}
{% bootstrap_field form.house form_group_class='form-group-sm' %}
{% bootstrap_field form.is_active form_group_class='form-group-sm' %}
{% bootstrap_field form.group form_group_class='form-group-sm' %}
{# password field #}
{% bootstrap_button '' button_type='button' icon='eye-open' button_class='btn-default' id='passwdtoggler' size='sm' as bt %}
{% bootstrap_field form.password form_group_class='form-group-sm' addon_after_class='input-group-btn' addon_after=bt %}
<script type="text/javascript">
$(function () {
$("#iprefreshbtn").on('click', function(){
$("#{{ form.ip_address.id_for_label }}").val('');
});
$('#passwdtoggler').on('mousedown', function(){
document.getElementById("{{ form.password.id_for_label }}").type='text';
}).on('mouseup', function(){
document.getElementById("{{ form.password.id_for_label }}").type='password';
});
});
</script>
{% bootstrap_field form.description form_group_class='form-group-sm' %}
<div class="form-group-sm">
<div class="col-sm-offset-4 col-sm-8 btn-group btn-group-sm">
<div class="btn-group btn-group-sm">
{% trans 'Save' as tx %}
{% bootstrap_button tx button_type='submit' icon='floppy-disk' button_class='btn-primary' %}
{% if perms.abonapp.change_abon %}
{% bootstrap_button tx button_type='submit' icon='floppy-disk' button_class='btn-primary' %}
{% else %}
{% bootstrap_button tx button_type='button' icon='floppy-disk' button_class='btn-primary disabled' %}
{% endif %}
{% if perms.taskapp.add_task %}
<a href="{% url 'taskapp:add' %}?uid={{ abon.username }}" class="btn btn-success" title="{% trans 'Add new task' %}">
<span class="glyphicon glyphicon-plus"></span> <span class="hidden-xs">{% trans 'Add new task' %}</span>
<span class="glyphicon glyphicon-plus"></span>
{% trans 'Add new task' %}
</a>
{% else %}
<a href="#" class="btn btn-success disabled" title="{% trans 'Permission denied' %}">
<span class="glyphicon glyphicon-plus"></span>
{% trans 'Add new task' %}
</a>
{% endif %}
</div>
</div>
<div class="form-group-sm">
<div class="col-sm-offset-4 col-sm-8 btn-group btn-group-sm">
{% if ip and perms.abonapp.can_ping %}
<a href="{% url 'abonapp:ping' %}" class="btn btn-default btn-cmd" title="Ping" data-param="{{ ip }}">
<span class="glyphicon glyphicon-flash"></span> Ping
</a>
{% if form.ip_address.value %}
{% if perms.abonapp.can_ping %}
<a href="{% url 'abonapp:ping' %}" class="btn btn-default btn-cmd" title="Ping" data-param="{{ form.ip_address.value }}">
<span class="glyphicon glyphicon-flash"></span> Ping
</a>
{% else %}
<a href="#" class="btn btn-default disabled" title="{% trans 'Permission denied' %}">
<span class="glyphicon glyphicon-flash"></span> Ping
</a>
{% endif %}
{% else %}
<a href="#" class="btn btn-default disabled">
<span class="glyphicon glyphicon-flash"></span> {% trans 'No have ip' %}
@ -100,6 +113,10 @@
<a href="{% url 'dialapp:send_sms' %}?path={{ request.path|urlencode }}&dst={{ form.telephone.value|urlencode }}" class="btn btn-default btn-modal">
<span class="glyphicon glyphicon-envelope"></span> {% trans 'Send sms' %}
</a>
{% else %}
<a href="#" class="btn btn-default disabled" title="{% trans 'Permission denied' %}">
<span class="glyphicon glyphicon-envelope"></span> {% trans 'Send sms' %}
</a>
{% endif %}
</div>
</div>

2
abonapp/templates/abonapp/peoples.html

@ -113,7 +113,7 @@
</td>
<td class="hidden-xs">
{% if can_del_abon %}
<a href="{% url 'abonapp:del_abon' %}?id={{ human.pk }}" class="btn btn-danger btn-sm">
<a href="{% url 'abonapp:del_abon' group.pk human.username %}" class="btn btn-danger btn-sm btn-modal">
<span class="glyphicon glyphicon-remove"></span>
</a>
{% endif %}

78
abonapp/templates/abonapp/viewAbon.html

@ -1,78 +0,0 @@
{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{% trans 'View the subscriber' %}</h3>
</div>
<div class="panel-body">
<table class="table borderbot">
<tbody>
<tr>
<td>{% trans 'User group' %}</td>
<td>
<i>{{ abon.group|default:_('Not assigned') }}</i>
</td>
</tr>
<tr>
<td>{% trans 'Is active' %}</td>
<td>
<i>{{ abon.is_active|yesno:_('yes,no') }}</i>
</td>
</tr>
<tr>
<td>{% trans 'login' %}</td>
<td><i>{{ abon.username|default:_('Not assigned') }}</i></td>
</tr>
<tr>
<td>{% trans 'fio' %}</td>
<td><i>{{ abon.fio|default:_('Not assigned') }}</i></td>
</tr>
<tr>
<td>{% trans 'Telephone' %}</td>
<td><i>{{ abon.telephone|default:_('Not assigned') }}</i></td>
</tr>
<tr>
<td>{% trans 'Street' %}</td>
<td>
<i>{{ abon.street|default:_('Not assigned') }}</i>
</td>
</tr>
<tr>
<td>{% trans 'House' %}</td>
<td><i>{{ abon.house|default:_('Not assigned') }}</i></td>
</tr>
<tr>
<td>{% trans 'Ip Address' %}</td>
<td><i>{{ abon.ip_address|default:_('Not assigned') }}</i></td>
</tr>
<tr>
<td>{% trans 'Password' %}</td>
<td><i>{{ passw }}</i></td>
</tr>
</tbody>
</table>
{% if abon.description %}<p>{{ abon.description }}</p>{% endif %}
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{% trans 'User flags' %}</h3>
</div>
<div class="panel-body">
{% for user_icon in abon.get_flag_icons %}
<span class="m-icon {{ user_icon }}"></span>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

5
abonapp/urls.py

@ -5,7 +5,7 @@ from . import views
app_name = 'abonapp'
subscriber_patterns = [
url(r'^$', views.abonhome, name='abon_home'),
url(r'^$', views.AbonHomeUpdateView.as_view(), name='abon_home'),
url(r'^services/$', views.abon_services, name='abon_services'),
url(r'^amount/$', views.abonamount, name='abon_amount'),
url(r'^debts/$', views.DebtsListView.as_view(), name='abon_debts'),
@ -21,6 +21,7 @@ subscriber_patterns = [
url(r'^extra_field/edit$', views.extra_field_change, name='extra_field_edit'),
url(r'^unsubscribe_service(?P<abon_tariff_id>\d+)/$', views.unsubscribe_service, name='unsubscribe_service'),
url(r'^dev/$', views.dev, name='dev'),
url(r'^del$', views.DelAbonDeleteView.as_view(), name='del_abon'),
url(r'^clear_dev/$', views.clear_dev, name='clear_dev'),
url(r'^task_log/$', views.TaskLogListView.as_view(), name='task_log'),
url(r'^user_dev/$', views.save_user_dev_port, name='save_user_dev_port'),
@ -55,8 +56,6 @@ urlpatterns = [
url(r'^log$', views.LogListView.as_view(), name='log'),
url(r'^del$', views.del_abon, name='del_abon'),
url(r'^pay$', views.terminal_pay, name='terminal_pay'),
url(r'^debtors$', views.DebtorsListView.as_view(), name='debtors'),

194
abonapp/views.py

@ -5,11 +5,12 @@ from django.db import IntegrityError, ProgrammingError, transaction
from django.db.models import Count, Q
from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseRedirect
from django.contrib import messages
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.decorators import method_decorator
from django.views.generic import ListView, UpdateView, CreateView
from django.views.generic import ListView, UpdateView, CreateView, DeleteView
from django.conf import settings
from jsonview.decorators import json_view
@ -28,6 +29,7 @@ from statistics.models import getModel
from group_app.models import Group
from guardian.shortcuts import get_objects_for_user, assign_perm
from guardian.decorators import permission_required_or_403 as permission_required
from djing import ping
from djing.global_base_views import OrderingMixin, BaseListWithFiltering, SecureApiView
PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@ -152,29 +154,37 @@ class AbonCreateView(CreateView):
return super(AbonCreateView, self).form_invalid(form)
@login_required
@mydefs.only_admins
def del_abon(request):
uid = request.GET.get('id')
try:
abon = get_object_or_404(models.Abon, pk=uid)
if not request.user.has_perm('abonapp.delete_abon') or not request.user.has_perm(
'group_app.can_view_group', abon.group):
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator(permission_required('abonapp.delete_abon'), name='dispatch')
class DelAbonDeleteView(DeleteView):
model = models.Abon
slug_url_kwarg = 'uname'
slug_field = 'username'
success_url = reverse_lazy('abonapp:group_list')
context_object_name = 'abon'
def get_object(self, queryset=None):
abon = super(DelAbonDeleteView, self).get_object(queryset)
if not self.request.user.has_perm('group_app.can_view_group', abon.group):
raise PermissionDenied
gid = abon.group.id
abon.delete()
abon.sync_with_nas(created=False)
messages.success(request, _('delete abon success msg'))
return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid))
return abon
except NasNetworkError as e:
messages.error(request, e)
except NasFailedResult as e:
messages.error(request, _("NAS says: '%s'") % e)
except mydefs.MultipleException as errs:
for err in errs.err_list:
messages.error(request, err)
return redirect('abonapp:group_list')
def delete(self, request, *args, **kwargs):
try:
abon = self.get_object()
gid = abon.group.id
abon.delete()
abon.sync_with_nas(created=False)
messages.success(request, _('delete abon success msg'))
return redirect('abonapp:people_list', gid=gid)
except NasNetworkError as e:
messages.error(self.request, e)
except NasFailedResult as e:
messages.error(self.request, _("NAS says: '%s'") % e)
except mydefs.MultipleException as errs:
for err in errs.err_list:
messages.error(self.request, err)
return HttpResponseRedirect(self.success_url)
@login_required
@ -267,66 +277,82 @@ def abon_services(request, gid, uname):
})
@login_required
@mydefs.only_admins
def abonhome(request, gid, uname):
abon = get_object_or_404(models.Abon, username=uname)
group = get_object_or_404(Group, pk=gid)
if not request.user.has_perm('group_app.can_view_group', group):
raise PermissionDenied
frm = None
passw = None
try:
if request.method == 'POST':
if not request.user.has_perm('abonapp.change_abon'):
raise PermissionDenied
frm = forms.AbonForm(request.POST, instance=abon)
if frm.is_valid():
newip = request.POST.get('ip')
if newip:
abon.ip_address = newip
abon = frm.save()
res = abon.sync_with_nas(created=False)
if isinstance(res, Exception):
messages.warning(request, res)
messages.success(request, _('edit abon success msg'))
else:
messages.warning(request, _('fix form errors'))
else:
passw = models.AbonRawPassword.objects.get(account=abon).passw_text
frm = forms.AbonForm(instance=abon, initial={'password': passw})
if abon.device is None:
messages.warning(request, _('User device was not found'))
except mydefs.LogicError as e:
messages.error(request, e)
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
@method_decorator(permission_required('abonapp.change_abon'), name='post')
class AbonHomeUpdateView(UpdateView):
model = models.Abon
form_class = forms.AbonForm
slug_field = 'username'
slug_url_kwarg = 'uname'
template_name = 'abonapp/editAbon.html'
context_object_name = 'abon'
group = None
def dispatch(self, request, *args, **kwargs):
try:
return super(AbonHomeUpdateView, self).dispatch(request, *args, **kwargs)
except mydefs.LogicError as e:
messages.error(request, e)
except (NasFailedResult, NasNetworkError) as e:
messages.error(request, e)
except models.AbonRawPassword.DoesNotExist:
messages.warning(request, _('User has not have password, and cannot login'))
except mydefs.MultipleException as errs:
for err in errs.err_list:
messages.error(request, err)
return self.render_to_response(self.get_context_data())
def get_object(self, queryset=None):
gid = self.kwargs.get('gid')
self.group = get_object_or_404(Group, pk=gid)
if not self.request.user.has_perm('group_app.can_view_group', self.group):
raise PermissionDenied
return super(AbonHomeUpdateView, self).get_object(queryset)
def form_valid(self, form):
r = super(AbonHomeUpdateView, self).form_valid(form)
abon = self.object
res = abon.sync_with_nas(created=False)
if isinstance(res, Exception):
messages.warning(self.request, res)
messages.success(self.request, _('edit abon success msg'))
return r
def form_invalid(self, form):
messages.warning(self.request, _('fix form errors'))
return super(AbonHomeUpdateView, self).form_invalid(form)
def get(self, request, *args, **kwargs):
r = super(AbonHomeUpdateView, self).get(request, *args, **kwargs)
abon = self.object
if abon.device is None:
messages.warning(request, _('User device was not found'))
return r
def get_initial(self):
abon = self.object
passw = models.AbonRawPassword.objects.get(account=abon).passw_text
frm = forms.AbonForm(instance=abon, initial={'password': passw})
return {
'password': passw
}
except (NasFailedResult, NasNetworkError) as e:
messages.error(request, e)
except models.AbonRawPassword.DoesNotExist:
messages.warning(request, _('User has not have password, and cannot login'))
except mydefs.MultipleException as errs:
for err in errs.err_list:
messages.error(request, err)
def get_context_data(self, **kwargs):
abon = self.object
dev = getattr(abon, 'device')
context = {
'group': self.group,
'device': dev,
'dev_ports': DevPort.objects.filter(device=dev) if dev else None
}
context.update(kwargs)
return super(AbonHomeUpdateView, self).get_context_data(**context)
if request.user.has_perm('abonapp.change_abon'):
return render(request, 'abonapp/editAbon.html', {
'form': frm or forms.AbonForm(instance=abon, initial={'password': passw}),
'abon': abon,
'group': group,
'ip': abon.ip_address,
'is_bad_ip': getattr(abon, 'is_bad_ip', False),
'device': abon.device,
'dev_ports': DevPort.objects.filter(device=abon.device) if abon.device else None
})
else:
return render(request, 'abonapp/viewAbon.html', {
'abon': abon,
'group': group,
'ip': abon.ip_address,
'passw': passw
})
def get_success_url(self):
abon = self.object
return resolve_url('abonapp:abon_home',
gid=getattr(abon.group, 'pk', 0),
uname=abon.username
)
@transaction.atomic
@ -698,7 +724,7 @@ def abon_ping(request):
tm = Transmitter()
ping_result = tm.ping(ip)
if ping_result is None:
if mydefs.ping(ip, 10):
if ping(ip, 10):
status = True
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok')
else:
@ -792,9 +818,9 @@ def save_user_dev_port(request, gid, uname):
user_url = resolve_url('abonapp:abon_home', other_abon.group.id, other_abon.username)
messages.error(request, _(
"<a href='%(user_url)s'>%(user_name)s</a> already pinned to this port on this device") % {
'user_url': user_url,
'user_name': other_abon.get_full_name()
})
'user_url': user_url,
'user_name': other_abon.get_full_name()
})
return redirect('abonapp:abon_home', gid, uname)
except models.Abon.DoesNotExist:
pass

3
accounts_app/templates/accounts/create_acc.html

@ -1,4 +1,5 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load globaltags %}
{% load i18n %}
{% block main %}
@ -62,7 +63,7 @@
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-phone"></span></span>
<input id="tel" type="tel" pattern="\+[7,8,9,3]\d{10,11}" name="telephone"
<input id="tel" type="tel" pattern="{% global_var 'TELEPHONE_REGEXP' %}" name="telephone"
placeholder="{% trans '+[7,8,9,3] and 10,11 digits' %}" value="{{ newuser.telephone }}"
class="form-control" required>
</div>

3
accounts_app/templates/accounts/settings/ch_info.html

@ -1,4 +1,5 @@
{% extends request.is_ajax|yesno:'nullcont.htm,accounts/settings/ext.htm' %}
{% load globaltags %}
{% load i18n %}
{% block content %}
@ -38,7 +39,7 @@
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
<input id="tel" type="text" value="{{ user.telephone }}" pattern="\+[7,8,9,3]\d{10,11}" name="telephone"
<input id="tel" type="text" value="{{ user.telephone }}" pattern="{% global_var 'TELEPHONE_REGEXP' %}" name="telephone"
placeholder="{% trans '+[7,8,9,3] and 10,11 digits' %}" class="form-control">
</div>
</div>

12
djing/settings.py

@ -172,7 +172,7 @@ DEFAULT_SNMP_PASSWORD = local_settings.DEFAULT_SNMP_PASSWORD
TELEGRAM_BOT_TOKEN = local_settings.TELEGRAM_BOT_TOKEN
TELEPHONE_REGEXP = r'^\+[7,8,9,3]\d{10,11}$'
TELEPHONE_REGEXP = local_settings.TELEPHONE_REGEXP
ASTERISK_MANAGER_AUTH = local_settings.ASTERISK_MANAGER_AUTH
@ -184,3 +184,13 @@ API_AUTH_SUBNET = local_settings.API_AUTH_SUBNET
# Company name
COMPANY_NAME = local_settings.COMPANY_NAME
# bootstrap3 settings
BOOTSTRAP3 = {
# Label class to use in horizontal forms
'horizontal_label_class': 'col-md-3',
# Field class to use in horizontal forms
'horizontal_field_class': 'col-md-9',
}
Loading…
Cancel
Save