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 #: abonapp/templates/abonapp/editAbon.html:92
msgid "Send account info to user" msgid "Send account info to user"
msgstr "Отправить учётные данные абоненту"
msgstr "Отправить данные абоненту"
#: abonapp/templates/abonapp/editAbon.html:104 #: abonapp/templates/abonapp/editAbon.html:104
msgid "Technical information" 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 comment=u_comment
) )
self.ballance -= how_match_to_pay self.ballance -= how_match_to_pay
self.save(update_fields=['ballance'])
# Пополняем счёт # Пополняем счёт
def add_ballance(self, current_user, amount, comment): def add_ballance(self, current_user, amount, comment):
@ -225,10 +226,10 @@ class Abon(UserProfile):
# Если это первая услуга в списке (фильтр по приоритету ничего не вернул) # Если это первая услуга в списке (фильтр по приоритету ничего не вернул)
if not abtrf: if not abtrf:
# значит она сразу стаёт активной
new_abtar.time_start = timezone.now()
new_abtar.save()
# значит пробуем её активировать
new_abtar.activate(author)
else:
new_abtar.save()
# Запись об этом в лог # Запись об этом в лог
AbonLog.objects.create( AbonLog.objects.create(
@ -241,9 +242,12 @@ class Abon(UserProfile):
def activate_next_tariff(self, author): def activate_next_tariff(self, author):
ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority') 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: for at in ats:
# усдуга не активна, продолжаем
if at.deadline is None:
continue
# если услуга просрочена # если услуга просрочена
if nw > at.deadline: if nw > at.deadline:
print(_('service overdue log')) print(_('service overdue log'))
@ -261,9 +265,10 @@ class Abon(UserProfile):
# есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs.<TariffBase>.manage_access() # есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs.<TariffBase>.manage_access()
def is_access(self): 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): if ct.manage_access(self):
return True return True
else: 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 %} <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"> <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 }} {{ form.username }}{{ form.username.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.fio }}{{ form.fio.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.telephone }}{{ form.telephone.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.street }}{{ form.street.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.house }}{{ form.house.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.is_active }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.group }}{{ form.group.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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"> <div class="input-group input-group-sm">
{{ form.password }}{{ form.password.errors }} {{ form.password }}{{ form.password.errors }}
<span class="input-group-btn"> <span class="input-group-btn">
@ -77,14 +77,14 @@
</div> </div>
<div class="form-group-sm"> <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 }} {{ form.description }}{{ form.description.errors }}
</div> </div>
</div> </div>
<div class="form-group-sm"> <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"> <button type="submit" class="btn btn-primary btn-sm">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} <span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button> </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.utils import timezone
from django.http import HttpResponse from django.http import HttpResponse
from django.contrib import messages 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 tariff_app.models import Tariff
from agent import NasFailedResult, Transmitter, NasNetworkError 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 #: accounts_app/templates/accounts/settings/ch_info.html:37
msgid "Telephone" msgid "Telephone"
msgstr "Номр телефона"
msgstr "Номер телефона"
#: accounts_app/templates/accounts/settings/ch_info.html:42 #: accounts_app/templates/accounts/settings/ch_info.html:42
msgid "+[7,8,9,3] and 10,11 digits" msgid "+[7,8,9,3] and 10,11 digits"
@ -73,6 +73,9 @@ msgstr "Сохранить"
msgid "Administrators" msgid "Administrators"
msgstr "Администраторы" msgstr "Администраторы"
msgid "Administrator"
msgstr "Администратор"
msgid "Options" msgid "Options"
msgstr "Настройки" msgstr "Настройки"
@ -85,6 +88,30 @@ msgstr "Изменить инфу о себе"
msgid "Permission options" msgid "Permission options"
msgstr "Настройка прав" 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" msgid "The responsibility of the administrator of the group of subscribers"
msgstr "Ответственность администратора за группы абонентов" msgstr "Ответственность администратора за группы абонентов"
@ -94,5 +121,35 @@ msgstr "Включён-ли"
msgid "Last login" msgid "Last login"
msgstr "Последняя авторизация" msgstr "Последняя авторизация"
msgid "Administrative access (all rights)"
msgid "All permissions"
msgstr "Административный доступ (все права)" 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.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.utils.translation import ugettext as _
from djing.settings import DEFAULT_PICTURE from djing.settings import DEFAULT_PICTURE
from photo_app.models import Photo from photo_app.models import Photo
@ -14,7 +15,7 @@ class MyUserManager(BaseUserManager):
birth and password. birth and password.
""" """
if not telephone: if not telephone:
raise ValueError('Users must have an telephone number')
raise ValueError(_('Users must have an telephone number'))
user = self.model( user = self.model(
telephone=telephone, telephone=telephone,
@ -48,7 +49,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
is_admin = models.BooleanField(default=False) is_admin = models.BooleanField(default=False)
telephone = models.CharField( telephone = models.CharField(
max_length=16, max_length=16,
verbose_name='Telephone number',
verbose_name=_('Telephone number'),
#unique=True, #unique=True,
validators=[RegexValidator('^\+[7,8,9,3]\d{10,11}$')] 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' %} {% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <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> <li class="active">{{ userprofile.username }}</li>
</ol> </ol>
@ -22,27 +23,27 @@
<div class="caption btn-group btn-group-sm"> <div class="caption btn-group btn-group-sm">
{% if userprofile == request.user %} {% if userprofile == request.user %}
<a href="{% url 'acc_app:setup_info' %}" class="btn btn-primary btn-sm" role="button"> <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 %} {% endif %}
<a href="#" class="btn btn-default btn-sm disabled" role="button"> <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>
</div> </div>
<div class="col-sm-9"> <div class="col-sm-9">
<h3>{{ userprofile.username|default:"&lt;Нет ника&gt;" }}</h3>
<h3>{{ userprofile.username|default:_('Not assigned') }}</h3>
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
{% url 'acc_app:other_profile' uid as profile_url %} {% url 'acc_app:other_profile' uid as profile_url %}
<li{% if profile_url == request.path %} class="active"{% endif %}> <li{% if profile_url == request.path %} class="active"{% endif %}>
<a href="{{ profile_url }}"> <a href="{{ profile_url }}">
Администратор
{% trans 'Administrator' %}
</a> </a>
</li> </li>
{% url 'acc_app:profile_setup_group' uid as profilegroups_url %} {% url 'acc_app:profile_setup_group' uid as profilegroups_url %}
<li{% if profilegroups_url == request.path %} class="active"{% endif %}> <li{% if profilegroups_url == request.path %} class="active"{% endif %}>
<a href="{{ profilegroups_url }}"> <a href="{{ profilegroups_url }}">
Группы
{% trans 'Groups' %}
</a> </a>
</li> </li>
</ul> </ul>

14
accounts_app/templates/accounts/group.html

@ -1,11 +1,11 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <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> <li class="active">{{ group.name }}</li>
</ol> </ol>
@ -13,13 +13,13 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <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>
<div class="panel-body"> <div class="panel-body">
<form role="form" action="{% url 'acc_app:group_link' group.id %}" method="post">{% csrf_token %} <form role="form" action="{% url 'acc_app:group_link' group.id %}" method="post">{% csrf_token %}
<div class="choice_wrapper"> <div class="choice_wrapper">
<label for="sel_left">Доступные права</label>
<label for="sel_left">{% trans 'Available rights' %}</label>
<select name="allrights" multiple id="sel_left"> <select name="allrights" multiple id="sel_left">
{% for rgt in all_rights %} {% for rgt in all_rights %}
<option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option> <option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option>
@ -33,7 +33,7 @@
class="black icon-arrow-left"></i></a></li> class="black icon-arrow-left"></i></a></li>
</ul> </ul>
<div class="choice_wrapper"> <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"> <select name="group_rights" multiple id="sel_right">
{% for rgt in grp_rights %} {% for rgt in grp_rights %}
<option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option> <option value="{{ rgt.id }}">{{ rgt.content_type }} &lt;{{ rgt.name }}&gt;</option>
@ -41,7 +41,7 @@
</select> </select>
</div> </div>
<br/> <br/>
<input type="submit" value="Сохранить"> <input type="reset" value="Сбросить">
<input type="submit" value="{% trans 'Save' %}"> <input type="reset" value="{% trans 'Reset' %}">
</form> </form>
</div> </div>

16
accounts_app/templates/accounts/group_list.html

@ -1,14 +1,14 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <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> </ol>
<h3>Список групп администраторов</h3>
<h3>{% trans 'Admin groups list' %}</h3>
{% include 'message_block.html' %} {% include 'message_block.html' %}
@ -17,7 +17,7 @@
<thead> <thead>
<tr> <tr>
<th width="50">#</th> <th width="50">#</th>
<th>Группа</th>
<th>{% trans 'Group' %}</th>
<th class="col-sm-1">&mdash;</th> <th class="col-sm-1">&mdash;</th>
</tr> </tr>
</thead> </thead>
@ -37,14 +37,16 @@
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="3"><a href="#">Нет групп</a></td>
<td colspan="3"><a href="#">{% trans 'Groups does not found' %}</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="3"> <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> </td>
</tr> </tr>
</tfoot> </tfoot>

2
accounts_app/templates/accounts/index.html

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

7
accounts_app/templates/accounts/login.html

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

1
bugs.txt

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

3
devapp/dev_types.py

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

3
devapp/forms.py

@ -28,5 +28,8 @@ class DeviceForm(forms.ModelForm):
}), }),
'map_dot': forms.Select(attrs={ 'map_dot': forms.Select(attrs={
'class': 'form-control' '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()) devtype = models.CharField(max_length=2, default=DEVICE_TYPES[0][0], choices=_DeviceChoicesAdapter())
man_passw = models.CharField(max_length=16, null=True, blank=True) 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) 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: class Meta:
db_table = 'dev' 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' %} {% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
{% load i18n %}
{% block content %} {% block content %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">Инфа о железке</h3>
<h3 class="panel-title">{% trans 'Device info' %}</h3>
</div> </div>
<div class="panel-body"> <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"> <div class="form-group">
<label for="id_ip_address">Ip адрес</label>
<label for="id_ip_address">{% trans 'Ip address' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span>
@ -24,7 +20,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="id_comment">Комментарий</label>
<label for="id_comment">{% trans 'Comment' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
@ -33,7 +29,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="id_devtype">Тип устройства</label>
<label for="id_devtype">{% trans 'Device type' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span>
@ -42,7 +38,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="id_man_passw">Пароль SNMP</label>
<label for="id_man_passw">{% trans 'SNMP password' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
@ -51,7 +47,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="id_map_dot">Точка топологии</label>
<label for="id_map_dot">{% trans 'Map point' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-map-marker"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-map-marker"></span></span>
@ -59,12 +55,21 @@
</div> </div>
</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"> <div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary"> <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>
<button type="reset" class="btn btn-sm btn-default"> <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> </button>
</div> </div>

43
devapp/templates/devapp/devices.html

@ -1,22 +1,38 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} {% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <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> </ol>
{% include 'message_block.html' %} {% include 'message_block.html' %}
<h3>Устройства</h3>
<h3>{% trans 'Devices' %}</h3>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<thead> <thead>
<tr> <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> <th width="100">Do</th>
</tr> </tr>
</thead> </thead>
@ -24,20 +40,25 @@
<tbody> <tbody>
{% for dev in devices %} {% for dev in devices %}
<tr> <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.comment }}</td>
<td>{{ dev.get_devtype_display }}</td> <td>{{ dev.get_devtype_display }}</td>
<td>
<td class="btn-group btn-group-sm">
{% if perms.devapp.delete_device %} {% 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> <span class="glyphicon glyphicon-remove"></span>
</a> </a>
{% endif %} {% 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> </td>
</tr> </tr>
{% empty %} {% empty %}
<tr> <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> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -46,7 +67,7 @@
<tr> <tr>
<td colspan="4"> <td colspan="4">
<a href="{% url 'devapp:add' %}" class="btn btn-success btn-sm"> <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> </a>
</td> </td>
</tr> </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' %} {% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <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> </ol>
{% include 'message_block.html' %} {% include 'message_block.html' %}
<div class="page-header"> <div class="page-header">
<h2>{{ dev.comment|default:'Без названия' }}</h2>
<h2>{{ dev.comment|default:_('Not assigned') }}</h2>
</div> </div>
<ul class="nav nav-tabs"> <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 %}> <li{% if devapp_view == request.path %} class="active"{% endif %}>
<a href="{{ devapp_view }}"> <a href="{{ devapp_view }}">
Порты {{ dev.ip_address }}
{% trans 'Ports' %} {{ dev.ip_address }}
</a> </a>
</li> </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> </ul>
<div class="tab-content"> <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' %} {% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
{% load i18n %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <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>
<div class="panel-body"> <div class="panel-body">
@ -29,16 +30,16 @@
<b>{{ port.num }}</b> <b>{{ port.num }}</b>
</a> </a>
<div class="btn-group btn-group-xs btn-group-justified"> <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> <span class="glyphicon glyphicon-ok"></span>
</a> </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> <span class="glyphicon glyphicon-off"></span>
</a> </a>
</div> </div>
</div> </div>
{% empty %} {% empty %}
<h3>Инфа не получена, проверьте настройки :(</h3>
<h3>{% trans 'We have not received info, please check options :(' %}</h3>
{% endfor %} {% endfor %}
</div> </div>
@ -50,16 +51,16 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">Лог устройства</h3>
<h3 class="panel-title">{% trans 'Device log' %}</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table table-responsive"> <table class="table table-responsive">
<thead> <thead>
<tr> <tr>
<td>ID</td> <td>ID</td>
<td>уровень</td>
<td>описание</td>
<td>дата</td>
<td>{% trans 'Level' %}</td>
<td>{% trans 'Description' %}</td>
<td>{% trans 'Date' %}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -125,25 +126,25 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">Комментарии портов</h3>
<h3 class="panel-title">{% trans 'Ports comment' %}</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table table-responsive"> <table class="table table-responsive">
<thead> <thead>
<tr> <tr>
<th width="50">Порт</th>
<th>Название</th>
<th width="50">{% trans 'Port' %}</th>
<th>{% trans 'Title' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for port in ports %} {% for port in ports %}
<tr> <tr>
<td>{{ port.num }}</td> <td>{{ port.num }}</td>
<td>{{ port.nm|default:"&lt;не назначен&gt;" }}</td>
<td>{{ port.nm|default:_('Not assigned') }}</td>
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="2">инфа о портах не получена</td>
<td colspan="2">{% trans 'We have not received info for ports' %}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

12
devapp/urls.py

@ -4,10 +4,12 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.devices, name='devs'),
url(r'^$', views.group_list, name='group_list'),
url(r'^add$', views.dev, name='add'), 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 -*- # -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import PermissionDenied 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.contrib import messages
from django.utils.translation import ugettext_lazy as _
from easysnmp import EasySNMPTimeoutError from easysnmp import EasySNMPTimeoutError
from .models import Device 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 .forms import DeviceForm
from abonapp.models import AbonGroup
@login_required @login_required
@only_admins @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) devs = pag_mn(request, devs)
return render(request, 'devapp/devices.html', { 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') @permission_required('devapp.delete_device')
def devdel(request, did): def devdel(request, did):
try: 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 @login_required
@ -46,16 +78,21 @@ def dev(request, devid=0):
frm = DeviceForm(request.POST, instance=devinst) frm = DeviceForm(request.POST, instance=devinst)
if frm.is_valid(): if frm.is_valid():
frm.save() frm.save()
messages.success(request, 'Инфа о точке сохранена')
messages.success(request, _('Device info has been saved'))
else: else:
messages.error(request, 'Ошибка в данных, проверте их ещё раз')
messages.error(request, _('Form is invalid, check fields and try again'))
else: else:
frm = DeviceForm(instance=devinst) 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 @login_required
@ -72,11 +109,11 @@ def devview(request, did):
uptime = manager.uptime() uptime = manager.uptime()
ports = manager.get_ports() ports = manager.get_ports()
else: else:
messages.warning(request, 'Не указан snmp пароль для устройства')
messages.warning(request, _('Not Set snmp device password'))
else: else:
messages.error(request, 'Эта точка не пингуется')
messages.error(request, _('Dot was not pinged'))
except EasySNMPTimeoutError: except EasySNMPTimeoutError:
messages.error(request, 'Время ожидания ответа от SNMP истекло')
messages.error(request, _('wait for a reply from the SNMP Timeout'))
return render(request, 'devapp/ports.html', { return render(request, 'devapp/ports.html', {
'dev': dev, 'dev': dev,
@ -100,7 +137,16 @@ def toggle_port(request, did, portid, status=0):
else: else:
ports[portid-1].disable() ports[portid-1].disable()
else: else:
messages.warning(request, 'Не указан snmp пароль для устройства')
messages.warning(request, _('Not Set snmp device password'))
else: 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 tarif_id == 0:
if not request.user.has_perm('tariff_app.add_tariff'): if not request.user.has_perm('tariff_app.add_tariff'):
raise PermissionDenied raise PermissionDenied
tarif = None
else: else:
if not request.user.has_perm('tariff_app.change_tariff'): if not request.user.has_perm('tariff_app.change_tariff'):
raise PermissionDenied raise PermissionDenied
tarif = get_object_or_404(Tariff, pk=tarif_id)
if request.method == 'POST': if request.method == 'POST':
frm = forms.TariffForm(request.POST)
frm = forms.TariffForm(request.POST, instance=tarif)
if frm.is_valid(): if frm.is_valid():
frm.save() frm.save()
return redirect('tarifs:home') return redirect('tarifs:home')
else: else:
messages.warning(request, 'Не все поля заполнены правильно, проверте и попробуйте ещё раз') messages.warning(request, 'Не все поля заполнены правильно, проверте и попробуйте ещё раз')
else: else:
if tarif_id == 0:
tarif = Tariff()
else:
tarif = get_object_or_404(Tariff, id=tarif_id)
frm = forms.TariffForm(instance=tarif) frm = forms.TariffForm(instance=tarif)
return render(request, 'tariff_app/editTarif.html', { return render(request, 'tariff_app/editTarif.html', {

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

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

4
taskapp/models.py

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

2
taskapp/templates/taskapp/tasklist.html

@ -36,7 +36,7 @@
<td>{{ task.get_state_display }}</td> <td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td> <td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</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"> <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' %}"> <a href="{% url 'taskapp:begin' task.id %}" class="btn btn-primary btn-xs" title="{% trans 'Begin' %}">
<span class="glyphicon glyphicon-cog"></span> <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_state_display }}</td>
<td>{{ task.get_priority_display }}</td> <td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</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"> <td colspan="3" class="btn-group">
<a href="{% url 'taskapp:finish' task.id %}" class="btn btn-sm btn-success" title="{% trans 'Complete' %}"> <a href="{% url 'taskapp:finish' task.id %}" class="btn btn-sm btn-success" title="{% trans 'Complete' %}">
<span class="glyphicon glyphicon-ok"></span> <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_state_display }}</td>
<td>{{ task.get_priority_display }}</td> <td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</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"> <td colspan="3" class="btn-group btn-group-justified">
{% if perms.taskapp.change_task %} {% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-default btn-sm" title="{% trans 'Edit' %}"> <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_state_display }}</td>
<td>{{ task.get_priority_display }}</td> <td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</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"> <td colspan="3" class="btn-group">
{% if perms.taskapp.change_task %} {% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-sm btn-default" title="{% trans 'Edit' %}"> <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_state_display }}</td>
<td>{{ task.get_priority_display }}</td> <td>{{ task.get_priority_display }}</td>
<td>{{ task.time_of_create|date:'d N Y H:i:s' }}</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"> <td class="btn-group btn-group-justified">
{% if perms.taskapp.change_task %} {% if perms.taskapp.change_task %}
<a href="{% url 'taskapp:edit' task.id %}" class="btn btn-sm btn-default" title="{% trans 'Edit' %}"> <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(): if request.user not in task.recipients.all():
task.delete() task.delete()
else:
messages.warning(request, _('You cannot delete task that assigned to you'))
return redirect('taskapp:home') return redirect('taskapp:home')

6
templates/base.html

@ -70,9 +70,9 @@
<span class="glyphicon glyphicon-compressed"></span> ip пул <span class="glyphicon glyphicon-compressed"></span> ip пул
</a></li> </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> железки <span class="glyphicon glyphicon-hdd"></span> железки
</a></li> </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 %} {% if pag.paginator.num_pages > 1 %}
<div class="row"> <div class="row">
<div class="col-sm-4 col-sm-offset-4"> <div class="col-sm-4 col-sm-offset-4">
@ -5,21 +7,23 @@
{% if pag.number == 1 %} {% if pag.number == 1 %}
<li class="disabled"><a href="#">&laquo;</a></li> <li class="disabled"><a href="#">&laquo;</a></li>
{% else %} {% else %}
<li><a href="?p=1">&laquo;</a></li>
<li><a href="?{{ url }}{{ start_divide }}p=1">&laquo;</a></li>
{% endif %} {% endif %}
{% if pag.has_previous %} {% 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 %} {% endif %}
<li class="disabled"><a href="#">{{ pag.number }}</a></li> <li class="disabled"><a href="#">{{ pag.number }}</a></li>
{% if pag.has_next %} {% 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 %} {% endif %}
{% if pag.number == pag.paginator.num_pages %} {% if pag.number == pag.paginator.num_pages %}
<li class="disabled"><a href="#">&raquo;</a></li> <li class="disabled"><a href="#">&raquo;</a></li>
{% else %} {% 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 %} {% endif %}
</ul> </ul>
</div> </div>
</div> </div>
{% endif %}
{% endif %}
{% endwith %}
{% endwith %}
Loading…
Cancel
Save