Browse Source

merge

devel
bashmak 9 years ago
parent
commit
1065070102
  1. BIN
      abonapp/locale/ru/LC_MESSAGES/django.mo
  2. 2
      abonapp/locale/ru/LC_MESSAGES/django.po
  3. 24
      abonapp/migrations/0011_auto_20170222_2224.py
  4. 21
      abonapp/models.py
  5. 38
      abonapp/templates/abonapp/editAbon.html
  6. 2
      abonapp/views.py
  7. BIN
      accounts_app/locale/ru/LC_MESSAGES/django.mo
  8. 61
      accounts_app/locale/ru/LC_MESSAGES/django.po
  9. 21
      accounts_app/migrations/0005_auto_20170222_2224.py
  10. 5
      accounts_app/models.py
  11. 13
      accounts_app/templates/accounts/ext.htm
  12. 14
      accounts_app/templates/accounts/group.html
  13. 16
      accounts_app/templates/accounts/group_list.html
  14. 2
      accounts_app/templates/accounts/index.html
  15. 7
      accounts_app/templates/accounts/login.html
  16. 20
      accounts_app/views.py
  17. 1
      bugs.txt
  18. 3
      devapp/dev_types.py
  19. 3
      devapp/forms.py
  20. 116
      devapp/locale/ru/LC_MESSAGES/django.po
  21. 22
      devapp/migrations/0004_device_user_group.py
  22. 1
      devapp/models.py
  23. 92
      devapp/templates/devapp/add_dev.html
  24. 33
      devapp/templates/devapp/dev.html
  25. 43
      devapp/templates/devapp/devices.html
  26. 81
      devapp/templates/devapp/devices_null_group.html
  27. 26
      devapp/templates/devapp/ext.htm
  28. 51
      devapp/templates/devapp/group_list.html
  29. 29
      devapp/templates/devapp/ports.html
  30. 12
      devapp/urls.py
  31. 88
      devapp/views.py
  32. BIN
      django_messages/locale/ar/LC_MESSAGES/django.mo
  33. BIN
      django_messages/locale/cs/LC_MESSAGES/django.mo
  34. BIN
      django_messages/locale/da/LC_MESSAGES/django.mo
  35. BIN
      django_messages/locale/de/LC_MESSAGES/django.mo
  36. BIN
      django_messages/locale/el/LC_MESSAGES/django.mo
  37. BIN
      django_messages/locale/es/LC_MESSAGES/django.mo
  38. BIN
      django_messages/locale/es_AR/LC_MESSAGES/django.mo
  39. BIN
      django_messages/locale/fa/LC_MESSAGES/django.mo
  40. BIN
      django_messages/locale/fr/LC_MESSAGES/django.mo
  41. BIN
      django_messages/locale/it/LC_MESSAGES/django.mo
  42. BIN
      django_messages/locale/ko/LC_MESSAGES/django.mo
  43. BIN
      django_messages/locale/lt/LC_MESSAGES/django.mo
  44. BIN
      django_messages/locale/nl/LC_MESSAGES/django.mo
  45. BIN
      django_messages/locale/pl/LC_MESSAGES/django.mo
  46. BIN
      django_messages/locale/pt_BR/LC_MESSAGES/django.mo
  47. BIN
      django_messages/locale/ro/LC_MESSAGES/django.mo
  48. BIN
      django_messages/locale/ru/LC_MESSAGES/django.mo
  49. BIN
      django_messages/locale/zh_CN/LC_MESSAGES/django.mo
  50. 12
      systemd_units/djing.service
  51. 12
      systemd_units/djing.timer
  52. 8
      tariff_app/views.py
  53. 3
      taskapp/locale/ru/LC_MESSAGES/django.po
  54. 4
      taskapp/models.py
  55. 2
      taskapp/templates/taskapp/tasklist.html
  56. 2
      taskapp/templates/taskapp/tasklist_active.html
  57. 2
      taskapp/templates/taskapp/tasklist_all.html
  58. 2
      taskapp/templates/taskapp/tasklist_finish.html
  59. 2
      taskapp/templates/taskapp/tasklist_own.html
  60. 2
      taskapp/views.py
  61. 6
      templates/base.html
  62. 14
      templates/toolbar_page.html

BIN
abonapp/locale/ru/LC_MESSAGES/django.mo

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

@ -332,7 +332,7 @@ msgstr "Активен"
#: abonapp/templates/abonapp/editAbon.html:92
msgid "Send account info to user"
msgstr "Отправить учётные данные абоненту"
msgstr "Отправить данные абоненту"
#: abonapp/templates/abonapp/editAbon.html:104
msgid "Technical information"

24
abonapp/migrations/0011_auto_20170222_2224.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2017-02-22 19:24
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('abonapp', '0010_auto_20170220_1630'),
]
operations = [
migrations.AlterModelOptions(
name='abon',
options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'))},
),
migrations.AlterField(
model_name='extrafieldsmodel',
name='field_type',
field=models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой')], max_length=3),
),
]

21
abonapp/models.py

@ -197,6 +197,7 @@ class Abon(UserProfile):
comment=u_comment
)
self.ballance -= how_match_to_pay
self.save(update_fields=['ballance'])
# Пополняем счёт
def add_ballance(self, current_user, amount, comment):
@ -225,10 +226,10 @@ class Abon(UserProfile):
# Если это первая услуга в списке (фильтр по приоритету ничего не вернул)
if not abtrf:
# значит она сразу стаёт активной
new_abtar.time_start = timezone.now()
new_abtar.save()
# значит пробуем её активировать
new_abtar.activate(author)
else:
new_abtar.save()
# Запись об этом в лог
AbonLog.objects.create(
@ -241,9 +242,12 @@ class Abon(UserProfile):
def activate_next_tariff(self, author):
ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority')
nw = timezone.datetime.now()
nw = timezone.make_aware(timezone.datetime.now())
for at in ats:
# усдуга не активна, продолжаем
if at.deadline is None:
continue
# если услуга просрочена
if nw > at.deadline:
print(_('service overdue log'))
@ -261,9 +265,10 @@ class Abon(UserProfile):
# есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs.<TariffBase>.manage_access()
def is_access(self):
trf = self.active_tariff()
if not trf: return False
ct = trf.get_calc_type()()
ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None)
if not ats or ats.count() < 1: return False
trf = ats[0].tariff
ct = trf.get_calc_type()(ats[0])
if ct.manage_access(self):
return True
else:

38
abonapp/templates/abonapp/editAbon.html

@ -12,59 +12,59 @@
<form role="form" class="form-horizontal" action="{% url 'abonapp:abon_home' abon_group.id abon.id %}" method="post"> {% csrf_token %}
<div class="form-group-sm">
<label for="id_username" class="col-sm-2 control-label">{% trans 'login' %}</label>
<div class="col-sm-10">
<label for="id_username" class="col-sm-4 control-label">{% trans 'login' %}</label>
<div class="col-sm-8">
{{ form.username }}{{ form.username.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_fio" class="col-sm-2 control-label">{% trans 'fio' %}</label>
<div class="col-sm-10">
<label for="id_fio" class="col-sm-4 control-label">{% trans 'fio' %}</label>
<div class="col-sm-8">
{{ form.fio }}{{ form.fio.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_telephone" class="col-sm-2 control-label">{% trans 'Telephone' %}</label>
<div class="col-sm-10">
<label for="id_telephone" class="col-sm-4 control-label">{% trans 'Telephone' %}</label>
<div class="col-sm-8">
{{ form.telephone }}{{ form.telephone.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_street" class="col-sm-2 control-label">{% trans 'Street' %}</label>
<label for="id_street" class="col-sm-4 control-label">{% trans 'Street' %}</label>
<div class="col-sm-10">
<div class="col-sm-8">
{{ form.street }}{{ form.street.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_house" class="col-sm-2 control-label">{% trans 'House' %}</label>
<label for="id_house" class="col-sm-4 control-label">{% trans 'House' %}</label>
<div class="col-sm-10">
<div class="col-sm-8">
{{ form.house }}{{ form.house.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_is_active" class="col-sm-2 control-label">{% trans 'Is active' %}</label>
<div class="col-sm-10">
<label for="id_is_active" class="col-sm-4 control-label">{% trans 'Is active' %}</label>
<div class="col-sm-8">
{{ form.is_active }}
</div>
</div>
<div class="form-group-sm">
<label for="id_group" class="col-sm-2 control-label">{% trans 'User group' %}</label>
<div class="col-sm-10">
<label for="id_group" class="col-sm-4 control-label">{% trans 'User group' %}</label>
<div class="col-sm-8">
{{ form.group }}{{ form.group.errors }}
</div>
</div>
<div class="form-group-sm">
<label for="id_password" class="col-sm-2 control-label">{% trans 'Password' %}</label>
<div class="col-sm-10">
<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">
@ -77,14 +77,14 @@
</div>
<div class="form-group-sm">
<label for="id_description" class="col-sm-2 control-label">{% trans 'Comment' %}</label>
<div class="col-sm-10">
<label for="id_description" class="col-sm-4 control-label">{% trans 'Comment' %}</label>
<div class="col-sm-8">
{{ form.description }}{{ form.description.errors }}
</div>
</div>
<div class="form-group-sm">
<div class="col-sm-offset-2 col-sm-10 btn-group">
<div class="col-sm-offset-4 col-sm-8 btn-group btn-group-sm">
<button type="submit" class="btn btn-primary btn-sm">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>

2
abonapp/views.py

@ -8,7 +8,7 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.utils import timezone
from django.http import HttpResponse
from django.contrib import messages
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy as _
from tariff_app.models import Tariff
from agent import NasFailedResult, Transmitter, NasNetworkError

BIN
accounts_app/locale/ru/LC_MESSAGES/django.mo

61
accounts_app/locale/ru/LC_MESSAGES/django.po

@ -49,7 +49,7 @@ msgstr "Адрес электронной почты"
#: accounts_app/templates/accounts/settings/ch_info.html:37
msgid "Telephone"
msgstr "Номр телефона"
msgstr "Номер телефона"
#: accounts_app/templates/accounts/settings/ch_info.html:42
msgid "+[7,8,9,3] and 10,11 digits"
@ -73,6 +73,9 @@ msgstr "Сохранить"
msgid "Administrators"
msgstr "Администраторы"
msgid "Administrator"
msgstr "Администратор"
msgid "Options"
msgstr "Настройки"
@ -85,6 +88,30 @@ msgstr "Изменить инфу о себе"
msgid "Permission options"
msgstr "Настройка прав"
msgid "Users must have an telephone number"
msgstr "У пользователей должен быть номер телефона"
msgid "Telephone number"
msgstr "Номер телефона"
msgid "Wrong login or password, please try again"
msgstr "Неправильный логин или пароль, попробуйте ещё раз"
msgid "Wrong password"
msgstr "Неправильный пароль"
msgid "You forget specify a password for the new account"
msgstr "Забыли указать пароль для нового аккаунта"
msgid "You forget to repeat a password for the new account"
msgstr "Забыли повторить пароль для нового аккаунта"
msgid "Subscriber with this name already exist"
msgstr "Пользователь с таким именем уже есть"
msgid "Passwords does not match, try again"
msgstr "Пароли не совпадают, попробуйте ещё раз"
msgid "The responsibility of the administrator of the group of subscribers"
msgstr "Ответственность администратора за группы абонентов"
@ -94,5 +121,35 @@ msgstr "Включён-ли"
msgid "Last login"
msgstr "Последняя авторизация"
msgid "Administrative access (all rights)"
msgid "All permissions"
msgstr "Административный доступ (все права)"
msgid "Groups"
msgstr "Группы"
msgid "Group"
msgstr "Группа"
msgid "Admin groups list"
msgstr "Список групп администраторов"
msgid "Groups does not found"
msgstr "Нет групп"
msgid "Add group"
msgstr "Добавить группу"
msgid "The current distribution of rights for groups"
msgstr "Действующее распределение прав для группы"
msgid "Available rights"
msgstr "Доступные права"
msgid "Rights for the group"
msgstr "Права группы"
msgid "Edit"
msgstr "Редактировать"
msgid "Set a task"
msgstr "Дать задачу"

21
accounts_app/migrations/0005_auto_20170222_2224.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2017-02-22 19:24
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts_app', '0004_auto_20170128_1316'),
]
operations = [
migrations.AlterField(
model_name='userprofile',
name='telephone',
field=models.CharField(max_length=16, validators=[django.core.validators.RegexValidator('^\\+[7,8,9,3]\\d{10,11}$')], verbose_name='Номер телефона'),
),
]

5
accounts_app/models.py

@ -2,6 +2,7 @@
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.core.validators import RegexValidator
from django.utils.translation import ugettext as _
from djing.settings import DEFAULT_PICTURE
from photo_app.models import Photo
@ -14,7 +15,7 @@ class MyUserManager(BaseUserManager):
birth and password.
"""
if not telephone:
raise ValueError('Users must have an telephone number')
raise ValueError(_('Users must have an telephone number'))
user = self.model(
telephone=telephone,
@ -48,7 +49,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
is_admin = models.BooleanField(default=False)
telephone = models.CharField(
max_length=16,
verbose_name='Telephone number',
verbose_name=_('Telephone number'),
#unique=True,
validators=[RegexValidator('^\+[7,8,9,3]\d{10,11}$')]
)

13
accounts_app/templates/accounts/ext.htm

@ -1,9 +1,10 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">Администраторы</a></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li class="active">{{ userprofile.username }}</li>
</ol>
@ -22,27 +23,27 @@
<div class="caption btn-group btn-group-sm">
{% if userprofile == request.user %}
<a href="{% url 'acc_app:setup_info' %}" class="btn btn-primary btn-sm" role="button">
<span class="glyphicon glyphicon-edit"></span> Редактировать</a>
<span class="glyphicon glyphicon-edit"></span> {% trans 'Edit' %}</a>
{% endif %}
<a href="#" class="btn btn-default btn-sm disabled" role="button">
<span class="glyphicon glyphicon-star-empty"></span> Дать задачу</a>
<span class="glyphicon glyphicon-star-empty"></span> {% trans 'Set a task' %}</a>
</div>
</div>
</div>
<div class="col-sm-9">
<h3>{{ userprofile.username|default:"&lt;Нет ника&gt;" }}</h3>
<h3>{{ userprofile.username|default:_('Not assigned') }}</h3>
<ul class="nav nav-tabs">
{% url 'acc_app:other_profile' uid as profile_url %}
<li{% if profile_url == request.path %} class="active"{% endif %}>
<a href="{{ profile_url }}">
Администратор
{% trans 'Administrator' %}
</a>
</li>
{% url 'acc_app:profile_setup_group' uid as profilegroups_url %}
<li{% if profilegroups_url == request.path %} class="active"{% endif %}>
<a href="{{ profilegroups_url }}">
Группы
{% trans 'Groups' %}
</a>
</li>
</ul>

14
accounts_app/templates/accounts/group.html

@ -1,11 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">Администраторы</a></li>
<li><a href="{% url 'acc_app:groups_list' %}">Группы</a></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:groups_list' %}">{% trans 'Groups' %}</a></li>
<li class="active">{{ group.name }}</li>
</ol>
@ -13,13 +13,13 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Действующее распределение прав для группы <b>{{ group.name }}</b></h3>
<h3 class="panel-title">{% trans 'The current distribution of rights for groups' %} <b>{{ group.name }}</b></h3>
</div>
<div class="panel-body">
<form role="form" action="{% url 'acc_app:group_link' group.id %}" method="post">{% csrf_token %}
<div class="choice_wrapper">
<label for="sel_left">Доступные права</label>
<label for="sel_left">{% trans 'Available rights' %}</label>
<select name="allrights" multiple id="sel_left">
{% for rgt in all_rights %}
<option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option>
@ -33,7 +33,7 @@
class="black icon-arrow-left"></i></a></li>
</ul>
<div class="choice_wrapper">
<label for="sel_right">Права группы</label>
<label for="sel_right">{% trans 'Rights for the group' %}</label>
<select name="group_rights" multiple id="sel_right">
{% for rgt in grp_rights %}
<option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option>
@ -41,7 +41,7 @@
</select>
</div>
<br/>
<input type="submit" value="Сохранить"> <input type="reset" value="Сбросить">
<input type="submit" value="{% trans 'Save' %}"> <input type="reset" value="{% trans 'Reset' %}">
</form>
</div>

16
accounts_app/templates/accounts/group_list.html

@ -1,14 +1,14 @@
{% extends 'base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">Администраторы</a></li>
<li class="active">Группы</li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li class="active">{% trans 'Groups' %}</li>
</ol>
<h3>Список групп администраторов</h3>
<h3>{% trans 'Admin groups list' %}</h3>
{% include 'message_block.html' %}
@ -17,7 +17,7 @@
<thead>
<tr>
<th width="50">#</th>
<th>Группа</th>
<th>{% trans 'Group' %}</th>
<th class="col-sm-1">&mdash;</th>
</tr>
</thead>
@ -37,14 +37,16 @@
</tr>
{% empty %}
<tr>
<td colspan="3"><a href="#">Нет групп</a></td>
<td colspan="3"><a href="#">{% trans 'Groups does not found' %}</a></td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3">
<a href="#" class="btn btn-primary btn-sm" title="Добавить группу"><i class="icon-plus"></i></a>
<a href="#" class="btn btn-primary btn-sm disabled" title="{% trans 'Add group' %}">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
</tfoot>

2
accounts_app/templates/accounts/index.html

@ -26,7 +26,7 @@
</tr>
{% if request.user.is_superuser %}
<tr>
<td>{% trans 'Administrative access (all rights)' %}</td>
<td>{% trans 'All permissions' %}</td>
<td><input type="checkbox"{{ userprofile.is_staff|yesno:' checked,' }}></td>
</tr>
{% endif %}

7
accounts_app/templates/accounts/login.html

@ -11,8 +11,7 @@
background-color: #ececec;
}
.form-signin {
max-width: 35%;
min-width: 222px;
width: 478px;
margin: 10% auto;
position: relative;
}
@ -50,10 +49,10 @@
<div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Login' %}
<span class="glyphicon glyphicon-log-in"></span> {% trans 'Login' %}
</button>
<button type="reset" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %}
<span class="glyphicon glyphicon-remove-sign"></span> {% trans 'Reset' %}
</button>
</div>

20
accounts_app/views.py

@ -7,6 +7,7 @@ from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.http import Http404
from django.contrib.auth.models import Group, Permission
from django.contrib import messages
from django.utils.translation import ugettext as _
from abonapp.models import AbonGroup
from photo_app.models import Photo
@ -39,13 +40,13 @@ def to_signin(request):
return render(request, 'accounts/login.html', {
'next': nextl,
'errmsg': 'Неправильный логин или пароль, попробуйте ещё раз'
'errmsg': _('Wrong login or password, please try again')
})
return render(request, 'accounts/login.html', {
'next': nextl
})
except NoReverseMatch:
raise Http404("Destination page does not exist")
return redirect('acc_app:profile')
def sign_out(request):
@ -133,7 +134,7 @@ def ch_info(request):
newpasswd = request.POST.get('newpasswd')
user.set_password(newpasswd)
else:
messages.error(request, 'Неправильный пароль')
messages.error(request, _('Wrong password'))
user.save()
request.user = user
@ -158,10 +159,10 @@ def create_profile(request):
passwd = request.POST.get('passwd')
conpasswd = request.POST.get('conpasswd')
if not passwd:
messages.error(request, 'Забыли указать пароль для нового аккаунта')
messages.error(request, _('You forget specify a password for the new account'))
if not conpasswd:
messages.error(request, 'Забыли повторить пароль для нового аккаунта')
messages.error(request, _('You forget to repeat a password for the new account'))
if passwd == conpasswd:
user_qs = UserProfile.objects.filter(username=username)[:1]
@ -170,9 +171,9 @@ def create_profile(request):
user.save()
return redirect('acc_app:accounts_list')
else:
messages.error(request, 'Пользователь с таким именем уже есть')
messages.error(request, _('Subscriber with this name already exist'))
else:
messages.error(request, 'Пароли не совпадают, попробуйте ещё раз')
messages.error(request, _('Passwords does not match, try again'))
return render(request, 'accounts/create_acc.html', {
'newuser': user
})
@ -194,9 +195,7 @@ def delete_profile(request, uid):
@mydefs.only_admins
def acc_list(request):
users = UserProfile.objects.filter(is_admin=True)
users = mydefs.pag_mn(request, users)
return render(request, 'accounts/acc_list.html', {
'users': users
})
@ -207,7 +206,6 @@ def acc_list(request):
def perms(request, uid):
profile = get_object_or_404(UserProfile, id=uid)
own_permissions = UserProfile.get_all_permissions(profile)
return render(request, 'accounts/settings/permissions.html', {
'uid': uid,
'own_permissions': own_permissions
@ -218,9 +216,7 @@ def perms(request, uid):
@mydefs.only_admins
def groups(request):
grps = Group.objects.all()
grps = mydefs.pag_mn(request, grps)
return render(request, 'accounts/group_list.html', {
'groups': grps
})

1
bugs.txt

@ -5,3 +5,4 @@
- В Mikrotik надо редиректить тех, у кого нет доступа в сеть
- Пароли абонентов надо шифровать ключом для паролей
- Доделать везде переводы
- Не надо коннектиться к микротику когда не собираемся ничего изменять. А то при сохранении залогинились и вышли без действий

3
devapp/dev_types.py

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from mydefs import RuTimedelta, safe_int
from datetime import timedelta
from .base_intr import DevBase, SNMPBaseWorker, BasePort
@ -77,7 +78,7 @@ class DLinkDevice(DevBase, SNMPBaseWorker):
def uptime(self):
uptimestamp = safe_int(self.get_item(oids['uptime']))
tm = RuTimedelta(seconds=uptimestamp/100) or RuTimedelta()
tm = RuTimedelta(timedelta(seconds=uptimestamp/100)) or RuTimedelta()
return tm

3
devapp/forms.py

@ -28,5 +28,8 @@ class DeviceForm(forms.ModelForm):
}),
'map_dot': forms.Select(attrs={
'class': 'form-control'
}),
'user_group': forms.Select(attrs={
'class': 'form-control'
})
}

116
devapp/locale/ru/LC_MESSAGES/django.po

@ -0,0 +1,116 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE"S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Dmitry Novikov nerosketch@gmail.com, 2017.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-22 01:50+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
msgid "Device info"
msgstr "Инфа о железке"
msgid "Ip address"
msgstr "Ip адрес"
msgid "Comment"
msgstr "Комментарий"
msgid "Device type"
msgstr "Тип устройства"
msgid "SNMP password"
msgstr "Пароль SNMP"
msgid "Map point"
msgstr "Точка топологии"
msgid "Save"
msgstr "Сохранить"
msgid "Reset"
msgstr "Сбросить"
msgid "Devices"
msgstr "Устройства"
msgid "Devices does not found"
msgstr "Нет созданных устройств"
msgid "Create"
msgstr "Cоздать"
msgid "Not assigned"
msgstr "&lt;Не назначено&gt;"
msgid "Ports"
msgstr "Порты"
msgid "Port"
msgstr "Порт"
msgid "Edit"
msgstr "Редактировать"
msgid "Title of the type of switch"
msgstr "Название типа свича"
msgid "Uptime"
msgstr "Без перезагрузки"
msgid "We have not received info, please check options :("
msgstr "Инфа не получена, проверьте настройки :("
msgid "Device log"
msgstr "Лог устройства"
msgid "Level"
msgstr "Уровень"
msgid "Description"
msgstr "Описание"
msgid "Date"
msgstr "Дата"
msgid "Ports comment"
msgstr "Комментарии портов"
msgid "Title"
msgstr "Название"
msgid "We have not received info for ports"
msgstr "Инфа о портах не получена"
msgid "Delete failed"
msgstr "Неизвестная ошибка при удалении :("
msgid "Device info has been saved"
msgstr "Инфа о точке сохранена"
msgid "Form is invalid, check fields and try again"
msgstr "Ошибка в данных, проверте их ещё раз"
msgid "Not Set snmp device password"
msgstr "Не указан snmp пароль для устройства"
msgid "Dot was not pinged"
msgstr "Эта точка не пингуется"
msgid "wait for a reply from the SNMP Timeout"
msgstr "Время ожидания ответа от SNMP истекло"
msgid "Devices without group"
msgstr "Устройства без группы"

22
devapp/migrations/0004_device_user_group.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2017-02-22 19:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('abonapp', '0011_auto_20170222_2224'),
('devapp', '0003_device_map_dot'),
]
operations = [
migrations.AddField(
model_name='device',
name='user_group',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonGroup'),
),
]

1
devapp/models.py

@ -18,6 +18,7 @@ class Device(models.Model):
devtype = models.CharField(max_length=2, default=DEVICE_TYPES[0][0], choices=_DeviceChoicesAdapter())
man_passw = models.CharField(max_length=16, null=True, blank=True)
map_dot = models.ForeignKey(Dot, on_delete=models.SET_NULL, null=True, blank=True)
user_group = models.ForeignKey('abonapp.AbonGroup', on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
db_table = 'dev'

92
devapp/templates/devapp/add_dev.html

@ -0,0 +1,92 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
<li class="active">{% trans 'Add new device' %}</li>
</ol>
{% include 'message_block.html' %}
<div class="page-header">
<h2>{{ dev.comment|default:_('Not assigned') }}</h2>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{% trans 'Device info' %}</h3>
</div>
<div class="panel-body">
<form role="form" action="{% url 'devapp:add' %}" method="post">{% csrf_token %}
<div class="form-group">
<label for="id_ip_address">{% trans 'Ip address' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span>
{{ form.ip_address }}{{ form.ip_address.errors }}
</div>
</div>
<div class="form-group">
<label for="id_comment">{% trans 'Comment' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
{{ form.comment }}{{ form.comment.errors }}
</div>
</div>
<div class="form-group">
<label for="id_devtype">{% trans 'Device type' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span>
{{ form.devtype }}{{ form.devtype.errors }}
</div>
</div>
<div class="form-group">
<label for="id_man_passw">{% trans 'SNMP password' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
{{ form.man_passw }}{{ form.man_passw.errors }}
</div>
</div>
<div class="form-group">
<label for="id_map_dot">{% trans 'Map point' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-map-marker"></span></span>
{{ form.map_dot }}{{ form.devtype.errors }}
</div>
</div>
<div class="form-group">
<label for="id_user_group">{% trans 'User group' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-subscript"></span></span>
{{ form.user_group }}{{ form.user_group.errors }}
</div>
</div>
<div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>
<button type="reset" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %}
</button>
</div>
</form>
</div>
</div>
{% endblock %}

33
devapp/templates/devapp/dev.html

@ -1,21 +1,17 @@
{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
{% load i18n %}
{% block content %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Инфа о железке</h3>
<h3 class="panel-title">{% trans 'Device info' %}</h3>
</div>
<div class="panel-body">
<form role="form" action="
{% if dev.id == 0 %}
{% url 'devapp:add' %}
{% else %}
{% url 'devapp:edit' dev.id %}
{% endif %}" method="post">{% csrf_token %}
<form role="form" action="{% url 'devapp:edit' dev.user_group.pk|default:0 dev.pk %}" method="post">{% csrf_token %}
<div class="form-group">
<label for="id_ip_address">Ip адрес</label>
<label for="id_ip_address">{% trans 'Ip address' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span>
@ -24,7 +20,7 @@
</div>
<div class="form-group">
<label for="id_comment">Комментарий</label>
<label for="id_comment">{% trans 'Comment' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
@ -33,7 +29,7 @@
</div>
<div class="form-group">
<label for="id_devtype">Тип устройства</label>
<label for="id_devtype">{% trans 'Device type' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span>
@ -42,7 +38,7 @@
</div>
<div class="form-group">
<label for="id_man_passw">Пароль SNMP</label>
<label for="id_man_passw">{% trans 'SNMP password' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
@ -51,7 +47,7 @@
</div>
<div class="form-group">
<label for="id_map_dot">Точка топологии</label>
<label for="id_map_dot">{% trans 'Map point' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-map-marker"></span></span>
@ -59,12 +55,21 @@
</div>
</div>
<div class="form-group">
<label for="id_user_group">{% trans 'User group' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-subscript"></span></span>
{{ form.user_group }}{{ form.user_group.errors }}
</div>
</div>
<div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> Сохранить
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>
<button type="reset" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-remove-circle"></span> Отменить
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %}
</button>
</div>

43
devapp/templates/devapp/devices.html

@ -1,22 +1,38 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li class="active">Устройства</li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
<li class="active">{{ group.title }}</li>
</ol>
{% include 'message_block.html' %}
<h3>Устройства</h3>
<h3>{% trans 'Devices' %}</h3>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Ip</th>
<th>Комментарий</th>
<th width="250">Тип</th>
<th>
<a href="{% url 'devapp:devs' group.pk %}?order_by=ip_address&dir={{ dir|default:"down" }}">
{% trans 'Ip address' %}
</a>
{% if order_by == 'ip_address' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'devapp:devs' group.pk %}?order_by=comment&dir={{ dir|default:"down" }}">
{% trans 'Comment' %}
</a>
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="250">
<a href="{% url 'devapp:devs' group.pk %}?order_by=devtype&dir={{ dir|default:"down" }}">
{% trans 'Device type' %}
</a>
{% if order_by == 'devtype' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="100">Do</th>
</tr>
</thead>
@ -24,20 +40,25 @@
<tbody>
{% for dev in devices %}
<tr>
<td><a href="{% url 'devapp:view' dev.id %}">{{ dev.ip_address }}</a></td>
<td><a href="{% url 'devapp:view' dev.user_group.pk|default:0 dev.pk %}">{{ dev.ip_address }}</a></td>
<td>{{ dev.comment }}</td>
<td>{{ dev.get_devtype_display }}</td>
<td>
<td class="btn-group btn-group-sm">
{% if perms.devapp.delete_device %}
<a href="{% url 'devapp:del' dev.id %}" class="btn btn-danger btn-sm">
<a href="{% url 'devapp:del' dev.user_group.pk|default:0 dev.pk %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-remove"></span>
</a>
{% endif %}
{% if perms.devapp.change_device %}
<a href="{% url 'devapp:edit' dev.user_group.pk|default:0 dev.id %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-edit"></span>
</a>
{% endif %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="4">Нет созданных устройств, <a href="{% url 'devapp:add' %}">создать</a></td>
<td colspan="4">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' %}">{% trans 'Create' %}</a></td>
</tr>
{% endfor %}
</tbody>
@ -46,7 +67,7 @@
<tr>
<td colspan="4">
<a href="{% url 'devapp:add' %}" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-plus"></span> Добавить
<span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %}
</a>
</td>
</tr>

81
devapp/templates/devapp/devices_null_group.html

@ -0,0 +1,81 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
<li class="active">{% trans 'Devices' %}</li>
</ol>
{% include 'message_block.html' %}
<h3>{% trans 'Devices without group' %}</h3>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>
<a href="{% url 'devapp:devices_null_group' %}?order_by=ip_address&dir={{ dir|default:"down" }}">
{% trans 'Ip address' %}
</a>
{% if order_by == 'ip_address' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'devapp:devices_null_group' %}?order_by=comment&dir={{ dir|default:"down" }}">
{% trans 'Comment' %}
</a>
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="250">
<a href="{% url 'devapp:devices_null_group' %}?order_by=devtype&dir={{ dir|default:"down" }}">
{% trans 'Device type' %}
</a>
{% if order_by == 'devtype' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="100">Do</th>
</tr>
</thead>
<tbody>
{% for dev in devices %}
<tr>
<td><a href="{% url 'devapp:view' dev.user_group.pk|default:0 dev.id %}">{{ dev.ip_address }}</a></td>
<td>{{ dev.comment }}</td>
<td>{{ dev.get_devtype_display }}</td>
<td class="btn-group btn-group-sm">
{% if perms.devapp.delete_device %}
<a href="{% url 'devapp:del' dev.user_group.pk|default:0 dev.id %}" class="btn btn-danger btn-sm">
<span class="glyphicon glyphicon-remove"></span>
</a>
{% endif %}
{% if perms.devapp.change_device %}
<a href="{% url 'devapp:edit' dev.user_group.pk|default:0 dev.id %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-edit"></span>
</a>
{% endif %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="4">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' %}">{% trans 'Create' %}</a></td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="4">
<a href="{% url 'devapp:add' %}" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %}
</a>
</td>
</tr>
</tfoot>
</table>
</div>
{% include 'toolbar_page.html' with pag=devices %}
{% endblock %}

26
devapp/templates/devapp/ext.htm

@ -1,31 +1,39 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:devs' %}">Устройства</a></li>
<li class="active">{{ dev.ip_address }}</li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
{% if dev.user_group %}
<li><a href="{% url 'devapp:devs' dev.user_group.pk %}">{{ dev.user_group.title }}</a></li>
{% else %}
<li>{% trans 'Not assigned' %}</li>
{% endif %}
<li class="active">{{ dev.comment }}</li>
</ol>
{% include 'message_block.html' %}
<div class="page-header">
<h2>{{ dev.comment|default:'Без названия' }}</h2>
<h2>{{ dev.comment|default:_('Not assigned') }}</h2>
</div>
<ul class="nav nav-tabs">
{% url 'devapp:view' dev.id as devapp_view %}
{% url 'devapp:view' dev.user_group.pk|default:0 dev.id as devapp_view %}
<li{% if devapp_view == request.path %} class="active"{% endif %}>
<a href="{{ devapp_view }}">
Порты {{ dev.ip_address }}
{% trans 'Ports' %} {{ dev.ip_address }}
</a>
</li>
{% url 'devapp:edit' dev.id as devapp_edit %}
<li{% if devapp_edit == request.path %} class="active"{% endif %}>
<a href="{{ devapp_edit }}">Редактировать</a>
</li>
{% if perms.devapp.change_device %}
{% url 'devapp:edit' dev.user_group.pk|default:0 dev.id as devapp_edit %}
<li{% if devapp_edit == request.path %} class="active"{% endif %}>
<a href="{{ devapp_edit }}">{% trans 'Edit' %}</a>
</li>
{% endif %}
</ul>
<div class="tab-content">

51
devapp/templates/devapp/group_list.html

@ -0,0 +1,51 @@
{% extends 'base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li class="active">{% trans 'Groups' %}</li>
</ol>
<h3>{% trans 'Groups' %}</h3>
{% include 'message_block.html' %}
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>{% trans 'Group title' %}</th>
</tr>
</thead>
<tbody>
{% for gr in groups %}
<tr>
<td><a href="{% url 'devapp:devs' gr.id %}">{{ gr.title }}</a></td>
</tr>
{% empty %}
<tr>
<td><a href="#">{% trans 'Groups was not found' %}</a></td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td class="btn-group">
{% if perms.abonapp.add_abongroup %}
<a href="{% url 'abonapp:add_group' %}" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-plus"></span> {% trans 'Add group' %}
</a>
{% endif %}
<a href="{% url 'devapp:devices_null_group' %}" class="btn btn-primary btn-sm">
<span class="glyphicon glyphicon-list-alt"></span> {% trans 'Devices without group' %}
</a>
</td>
</tr>
</tfoot>
</table>
</div>
{% include 'toolbar_page.html' with pag=groups %}
{% endblock %}

29
devapp/templates/devapp/ports.html

@ -1,12 +1,13 @@
{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">{{ dev.get_devtype_display|default:'Название типа свича' }}, без
перезагрузки {{ uptime }}</div>
<div class="panel-title">{{ dev.get_devtype_display|default:_('Title of the type of switch') }}.
{% trans 'Uptime' %} {{ uptime }}</div>
</div>
<div class="panel-body">
@ -29,16 +30,16 @@
<b>{{ port.num }}</b>
</a>
<div class="btn-group btn-group-xs btn-group-justified">
<a href="{% url 'devapp:port_toggle' dev.id port.num 1 %}" class="btn btn-success">
<a href="{% url 'devapp:port_toggle' dev.user_group.pk|default:0 dev.id port.num 1 %}" class="btn btn-success">
<span class="glyphicon glyphicon-ok"></span>
</a>
<a href="{% url 'devapp:port_toggle' dev.id port.num 0 %}" class="btn btn-danger">
<a href="{% url 'devapp:port_toggle' dev.user_group.pk|default:0 dev.id port.num 0 %}" class="btn btn-danger">
<span class="glyphicon glyphicon-off"></span>
</a>
</div>
</div>
{% empty %}
<h3>Инфа не получена, проверьте настройки :(</h3>
<h3>{% trans 'We have not received info, please check options :(' %}</h3>
{% endfor %}
</div>
@ -50,16 +51,16 @@
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Лог устройства</h3>
<h3 class="panel-title">{% trans 'Device log' %}</h3>
</div>
<div class="panel-body">
<table class="table table-responsive">
<thead>
<tr>
<td>ID</td>
<td>уровень</td>
<td>описание</td>
<td>дата</td>
<td>{% trans 'Level' %}</td>
<td>{% trans 'Description' %}</td>
<td>{% trans 'Date' %}</td>
</tr>
</thead>
<tbody>
@ -125,25 +126,25 @@
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Комментарии портов</h3>
<h3 class="panel-title">{% trans 'Ports comment' %}</h3>
</div>
<div class="panel-body">
<table class="table table-responsive">
<thead>
<tr>
<th width="50">Порт</th>
<th>Название</th>
<th width="50">{% trans 'Port' %}</th>
<th>{% trans 'Title' %}</th>
</tr>
</thead>
<tbody>
{% for port in ports %}
<tr>
<td>{{ port.num }}</td>
<td>{{ port.nm|default:"&lt;не назначен&gt;" }}</td>
<td>{{ port.nm|default:_('Not assigned') }}</td>
</tr>
{% empty %}
<tr>
<td colspan="2">инфа о портах не получена</td>
<td colspan="2">{% trans 'We have not received info for ports' %}</td>
</tr>
{% endfor %}
</tbody>

12
devapp/urls.py

@ -4,10 +4,12 @@ from . import views
urlpatterns = [
url(r'^$', views.devices, name='devs'),
url(r'^$', views.group_list, name='group_list'),
url(r'^add$', views.dev, name='add'),
url(r'^(?P<did>\d+)$', views.devview, name='view'),
url(r'^(?P<did>\d+)/del$', views.devdel, name='del'),
url(r'^(?P<devid>\d+)/edit$', views.dev, name='edit'),
url(r'^(?P<did>\d+)/(?P<portid>\d+)_(?P<status>[0-1]{1})$', views.toggle_port, name='port_toggle')
url(r'^devices_without_groups$', views.devices_null_group, name='devices_null_group'),
url(r'^(?P<grp>\d+)$', views.devices, name='devs'),
url(r'^(\d+)/(?P<did>\d+)$', views.devview, name='view'),
url(r'^(\d+)/(?P<did>\d+)/del$', views.devdel, name='del'),
url(r'^(\d+)/(?P<devid>\d+)/edit$', views.dev, name='edit'),
url(r'^(\d+)/(?P<did>\d+)/(?P<portid>\d+)_(?P<status>[0-1]{1})$', views.toggle_port, name='port_toggle')
]

88
devapp/views.py

@ -1,23 +1,53 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import render, redirect, get_object_or_404
from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from easysnmp import EasySNMPTimeoutError
from .models import Device
from mydefs import pag_mn, res_success, res_error, only_admins, ping
from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_helper
from .forms import DeviceForm
from abonapp.models import AbonGroup
@login_required
@only_admins
def devices(request):
devs = Device.objects.all()
def devices(request, grp):
group = get_object_or_404(AbonGroup, pk=grp)
devs = Device.objects.filter(user_group=grp)
# фильтр
dr, field = order_helper(request)
if field:
devs = devs.order_by(field)
devs = pag_mn(request, devs)
return render(request, 'devapp/devices.html', {
'devices': devs
'devices': devs,
'dir': dr,
'order_by': request.GET.get('order_by'),
'group': group
})
@login_required
@only_admins
def devices_null_group(request):
devs = Device.objects.all()
# фильтр
dr, field = order_helper(request)
if field:
devs = devs.order_by(field)
devs = pag_mn(request, devs)
return render(request, 'devapp/devices_null_group.html', {
'devices': devs,
'dir': dr,
'order_by': request.GET.get('order_by')
})
@ -25,10 +55,12 @@ def devices(request):
@permission_required('devapp.delete_device')
def devdel(request, did):
try:
get_object_or_404(Device, id=did).delete()
return res_success(request, 'devapp:devs')
except:
return res_error(request, 'Неизвестная ошибка при удалении :(')
dev = Device.objects.get(pk=did)
back_url = resolve_url('devapp:devs', grp=dev.user_group.pk if dev.user_group else 0)
dev.delete()
return res_success(request, back_url)
except Device.DoesNotExist:
return res_error(request, _('Delete failed'))
@login_required
@ -46,16 +78,21 @@ def dev(request, devid=0):
frm = DeviceForm(request.POST, instance=devinst)
if frm.is_valid():
frm.save()
messages.success(request, 'Инфа о точке сохранена')
messages.success(request, _('Device info has been saved'))
else:
messages.error(request, 'Ошибка в данных, проверте их ещё раз')
messages.error(request, _('Form is invalid, check fields and try again'))
else:
frm = DeviceForm(instance=devinst)
return render(request, 'devapp/dev.html', {
'form': frm,
'dev': devinst
})
if devinst is None:
return render(request, 'devapp/add_dev.html', {
'form': frm
})
else:
return render(request, 'devapp/dev.html', {
'form': frm,
'dev': devinst
})
@login_required
@ -72,11 +109,11 @@ def devview(request, did):
uptime = manager.uptime()
ports = manager.get_ports()
else:
messages.warning(request, 'Не указан snmp пароль для устройства')
messages.warning(request, _('Not Set snmp device password'))
else:
messages.error(request, 'Эта точка не пингуется')
messages.error(request, _('Dot was not pinged'))
except EasySNMPTimeoutError:
messages.error(request, 'Время ожидания ответа от SNMP истекло')
messages.error(request, _('wait for a reply from the SNMP Timeout'))
return render(request, 'devapp/ports.html', {
'dev': dev,
@ -100,7 +137,16 @@ def toggle_port(request, did, portid, status=0):
else:
ports[portid-1].disable()
else:
messages.warning(request, 'Не указан snmp пароль для устройства')
messages.warning(request, _('Not Set snmp device password'))
else:
messages.error(request, 'Эта точка не пингуется')
return redirect('devapp:view', did=did)
messages.error(request, _('Dot was not pinged'))
return redirect('devapp:view', dev.user_group or 0, did)
@login_required
@only_admins
def group_list(request):
groups = AbonGroup.objects.all()
return render(request, 'devapp/group_list.html', {
'groups': groups
})

BIN
django_messages/locale/ar/LC_MESSAGES/django.mo

BIN
django_messages/locale/cs/LC_MESSAGES/django.mo

BIN
django_messages/locale/da/LC_MESSAGES/django.mo

BIN
django_messages/locale/de/LC_MESSAGES/django.mo

BIN
django_messages/locale/el/LC_MESSAGES/django.mo

BIN
django_messages/locale/es/LC_MESSAGES/django.mo

BIN
django_messages/locale/es_AR/LC_MESSAGES/django.mo

BIN
django_messages/locale/fa/LC_MESSAGES/django.mo

BIN
django_messages/locale/fr/LC_MESSAGES/django.mo

BIN
django_messages/locale/it/LC_MESSAGES/django.mo

BIN
django_messages/locale/ko/LC_MESSAGES/django.mo

BIN
django_messages/locale/lt/LC_MESSAGES/django.mo

BIN
django_messages/locale/nl/LC_MESSAGES/django.mo

BIN
django_messages/locale/pl/LC_MESSAGES/django.mo

BIN
django_messages/locale/pt_BR/LC_MESSAGES/django.mo

BIN
django_messages/locale/ro/LC_MESSAGES/django.mo

BIN
django_messages/locale/ru/LC_MESSAGES/django.mo

BIN
django_messages/locale/zh_CN/LC_MESSAGES/django.mo

12
systemd_units/djing.service

@ -0,0 +1,12 @@
[Unit]
Description=A job for djing
[Service]
Type=simple
ExecStart=/usr/bin/python3 cron.py > /dev/null
WorkingDirectory=/srv/http/djing
User=http
Group=http
[Install]
WantedBy=multi-user.target

12
systemd_units/djing.timer

@ -0,0 +1,12 @@
[Unit]
Description=Run every 30 minutes a job for djing
[Timer]
OnCalendar=*-*-* *:30:00
Persistent=true
RandomizedDelaySec=300
Unit=djing.service
[Install]
WantedBy=timers.target

8
tariff_app/views.py

@ -35,22 +35,20 @@ def edit_tarif(request, tarif_id=0):
if tarif_id == 0:
if not request.user.has_perm('tariff_app.add_tariff'):
raise PermissionDenied
tarif = None
else:
if not request.user.has_perm('tariff_app.change_tariff'):
raise PermissionDenied
tarif = get_object_or_404(Tariff, pk=tarif_id)
if request.method == 'POST':
frm = forms.TariffForm(request.POST)
frm = forms.TariffForm(request.POST, instance=tarif)
if frm.is_valid():
frm.save()
return redirect('tarifs:home')
else:
messages.warning(request, 'Не все поля заполнены правильно, проверте и попробуйте ещё раз')
else:
if tarif_id == 0:
tarif = Tariff()
else:
tarif = get_object_or_404(Tariff, id=tarif_id)
frm = forms.TariffForm(instance=tarif)
return render(request, 'tariff_app/editTarif.html', {

3
taskapp/locale/ru/LC_MESSAGES/django.po

@ -353,3 +353,6 @@ msgstr "Назначенные мной задачи"
msgid "All my tasks"
msgstr "Все мои задачи"
msgid "You cannot delete task that assigned to you"
msgstr "Вы не можете удалять назначенные на вас задачи"

4
taskapp/models.py

@ -1,5 +1,6 @@
# coding=utf-8
from datetime import timedelta
import os
from django.db import models
from django.conf import settings
from django.utils import timezone
@ -96,6 +97,9 @@ class Task(models.Model):
)
self.save(update_fields=['state'])
def get_attachment_fname(self):
return os.path.basename(self.attachment.name)
def task_handler(sender, instance, **kwargs):
group = ''

2
taskapp/templates/taskapp/tasklist.html

@ -36,7 +36,7 @@
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.attachment.name }}</a>{% else %}&horbar;{% endif %}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.get_attachment_fname|truncatechars:32|truncatechars:32 }}</a>{% else %}&horbar;{% endif %}</td>
<td colspan="3" class="btn-group btn-group-justified">
<a href="{% url 'taskapp:begin' task.id %}" class="btn btn-primary btn-xs" title="{% trans 'Begin' %}">
<span class="glyphicon glyphicon-cog"></span>

2
taskapp/templates/taskapp/tasklist_active.html

@ -37,7 +37,7 @@
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.attachment.name }}</a>{% else %}&horbar;{% endif %}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.get_attachment_fname|truncatechars:32 }}</a>{% else %}&horbar;{% endif %}</td>
<td colspan="3" class="btn-group">
<a href="{% url 'taskapp:finish' task.id %}" class="btn btn-sm btn-success" title="{% trans 'Complete' %}">
<span class="glyphicon glyphicon-ok"></span>

2
taskapp/templates/taskapp/tasklist_all.html

@ -48,7 +48,7 @@
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.attachment.name }}</a>{% else %}&horbar;{% endif %}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.get_attachment_fname|truncatechars:32 }}</a>{% else %}&horbar;{% endif %}</td>
<td colspan="3" class="btn-group btn-group-justified">
{% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-default btn-sm" title="{% trans 'Edit' %}">

2
taskapp/templates/taskapp/tasklist_finish.html

@ -37,7 +37,7 @@
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.attachment.name }}</a>{% else %}&horbar;{% endif %}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.get_attachment_fname|truncatechars:32 }}</a>{% else %}&horbar;{% endif %}</td>
<td colspan="3" class="btn-group">
{% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-sm btn-default" title="{% trans 'Edit' %}">

2
taskapp/templates/taskapp/tasklist_own.html

@ -34,7 +34,7 @@
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.attachment.name }}</a>{% else %}&horbar;{% endif %}</td>
<td>{% if task.attachment %}<a href="{{ task.attachment.url }}" target="_blank">{{ task.get_attachment_fname|truncatechars:32 }}</a>{% else %}&horbar;{% endif %}</td>
<td class="btn-group btn-group-justified">
{% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-sm btn-default" title="{% trans 'Edit' %}">

2
taskapp/views.py

@ -80,6 +80,8 @@ def task_delete(request, task_id):
# нельзя удалить назначенную мне задачу
if request.user not in task.recipients.all():
task.delete()
else:
messages.warning(request, _('You cannot delete task that assigned to you'))
return redirect('taskapp:home')

6
templates/base.html

@ -70,9 +70,9 @@
<span class="glyphicon glyphicon-compressed"></span> ip пул
</a></li>
{% url 'devapp:devs' as devapp_devs %}
<li{% if devapp_devs in request.path %} class="active"{% endif %}>
<a href="{{ devapp_devs }}">
{% url 'devapp:group_list' as devapp_groups %}
<li{% if devapp_groups in request.path %} class="active"{% endif %}>
<a href="{{ devapp_groups }}">
<span class="glyphicon glyphicon-hdd"></span> железки
</a></li>

14
templates/toolbar_page.html

@ -1,3 +1,5 @@
{% with request.GET.urlencode|yesno:'&,' as start_divide %}
{% with request.GET.urlencode as url %}
{% if pag.paginator.num_pages > 1 %}
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
@ -5,21 +7,23 @@
{% if pag.number == 1 %}
<li class="disabled"><a href="#">&laquo;</a></li>
{% else %}
<li><a href="?p=1">&laquo;</a></li>
<li><a href="?{{ url }}{{ start_divide }}p=1">&laquo;</a></li>
{% endif %}
{% if pag.has_previous %}
<li><a href="?p={{ pag.previous_page_number }}">{{ pag.previous_page_number }}</a></li>
<li><a href="?{{ url }}{{ start_divide }}p={{ pag.previous_page_number }}">{{ pag.previous_page_number }}</a></li>
{% endif %}
<li class="disabled"><a href="#">{{ pag.number }}</a></li>
{% if pag.has_next %}
<li><a href="?p={{ pag.next_page_number }}">{{ pag.next_page_number }}</a></li>
<li><a href="?{{ url }}{{ start_divide }}p={{ pag.next_page_number }}">{{ pag.next_page_number }}</a></li>
{% endif %}
{% if pag.number == pag.paginator.num_pages %}
<li class="disabled"><a href="#">&raquo;</a></li>
{% else %}
<li><a href="?p={{ pag.paginator.num_pages }}">&raquo;</a></li>
<li><a href="?{{ url }}{{ start_divide }}p={{ pag.paginator.num_pages }}">&raquo;</a></li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% endif %}
{% endwith %}
{% endwith %}
Loading…
Cancel
Save