108 changed files with 2369 additions and 909 deletions
-
17abonapp/locale/ru/LC_MESSAGES/django.po
-
1abonapp/models.py
-
2abonapp/templates/abonapp/dial_log.html
-
44abonapp/templates/abonapp/editAbon.html
-
4abonapp/templates/abonapp/ext.htm
-
10abonapp/templates/abonapp/group_list.html
-
32abonapp/templates/abonapp/modal_phonebook.html
-
41abonapp/templates/abonapp/peoples.html
-
2abonapp/urls_abon.py
-
54abonapp/views.py
-
4accounts_app/locale/ru/LC_MESSAGES/django.po
-
29accounts_app/templates/accounts/acc_list.html
-
10accounts_app/templates/accounts/ext.htm
-
4accounts_app/templates/accounts/index.html
-
13accounts_app/templates/accounts/login.html
-
14accounts_app/templates/accounts/settings/test.html
-
7agent/commands/dhcp.py
-
20agent/mod_mikrotik.py
-
8bugs.txt
-
1chatbot/admin.py
-
78chatbot/locale/ru/LC_MESSAGES/django.po
-
59chatbot/migrations/0002_auto_20171214_1517.py
-
52chatbot/models.py
-
17chatbot/telebot.py
-
5clientsideapp/templates/clientsideapp/ext.html
-
12clientsideapp/templates/clientsideapp/services.html
-
8clientsideapp/views.py
-
17cron.py
-
16devapp/base_intr.py
-
79devapp/dev_types.py
-
28devapp/forms.py
-
28devapp/locale/ru/LC_MESSAGES/django.po
-
72devapp/migrations/0004_auto_20171103_0006.py
-
20devapp/migrations/0005_device_snmp_item_num.py
-
112devapp/models.py
-
87devapp/templates/devapp/add_dev.html
-
22devapp/templates/devapp/custom_dev_page/olt.html
-
59devapp/templates/devapp/custom_dev_page/onu.html
-
2devapp/templates/devapp/custom_dev_page/ports.html
-
96devapp/templates/devapp/dev.html
-
36devapp/templates/devapp/devices.html
-
82devapp/templates/devapp/fix_dev_group.html
-
2devapp/templates/devapp/group_list.html
-
33devapp/templates/devapp/manage_ports/modal_add_edit_port.html
-
2devapp/urls.py
-
122devapp/views.py
-
44dhcp_lever.py
-
13dialing_app/locale/ru/LC_MESSAGES/django.po
-
4dialing_app/models.py
-
12dialing_app/templates/ext.html
-
23dialing_app/templates/index.html
-
10dialing_app/templates/vmail.html
-
4dialing_app/urls.py
-
30dialing_app/views.py
-
6djing/settings_example.py
-
8djing/urls.py
-
69docs/dev.md
-
12global_context_processors.py
-
7mapapp/forms.py
-
167mapapp/locale/ru/LC_MESSAGES/django.po
-
45mapapp/migrations/0002_auto_20171103_0006.py
-
15mapapp/models.py
-
70mapapp/templates/maps/add_device.html
-
112mapapp/templates/maps/dot.html
-
62mapapp/templates/maps/index.html
-
19mapapp/templates/maps/map_tooltip.html
-
20mapapp/templates/maps/modal_add_device.html
-
28mapapp/templates/maps/modal_add_dot.html
-
38mapapp/templates/maps/options.html
-
7mapapp/templates/maps/preload_devices_tmpl.html
-
121mapapp/templates/maps/ya_index.html
-
6mapapp/urls.py
-
149mapapp/views.py
-
5msg_app/admin.py
-
2msg_app/locale/ru/LC_MESSAGES/django.po
-
8msg_app/models.py
-
4msg_app/templates/msg_app/chat.html
-
3msg_app/urls.py
-
17msg_app/views.py
-
9mydefs.py
-
69queue_mngr.py
-
5requirements.txt
-
48static/clientside/ISPlaylist.m3u
-
19static/clientside/custom.css
-
27static/css/custom.css
-
BINstatic/img/loading.gif
-
BINstatic/img/noticon.png
-
111static/js/my.js
-
2systemd_units/djing_telebot.service
-
20systemd_units/do_backup.sh
-
20systemd_units/webdav_backup.py
-
6taskapp/handle.py
-
8taskapp/locale/ru/LC_MESSAGES/django.po
-
2taskapp/models.py
-
2taskapp/templates/taskapp/add_edit_task.html
-
3taskapp/templates/taskapp/footer_btns.html
-
10taskapp/templates/taskapp/tasklist.html
-
8taskapp/templates/taskapp/tasklist_all.html
-
10taskapp/templates/taskapp/tasklist_failed.html
-
11taskapp/templates/taskapp/tasklist_finish.html
@ -0,0 +1,32 @@ |
|||||
|
{% load i18n %} |
||||
|
<div class="modal-header primary"> |
||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
||||
|
<h4 class="modal-title"><span class="glyphicon glyphicon-earphone"></span>{% trans 'Phonebook' %}</h4> |
||||
|
</div> |
||||
|
|
||||
|
<table class="table table-striped table-bordered"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>{% trans 'Telephone' %}</th> |
||||
|
<th>{% trans 'Telephone owner' %}</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
{% for t in tels %} |
||||
|
<tr> |
||||
|
<td><a href="sip:{{ t.0 }}" class="btn btn-link">{{ t.0 }}</a></td> |
||||
|
<td>{{ t.1 }}</td> |
||||
|
</tr> |
||||
|
{% empty %} |
||||
|
<tr> |
||||
|
<td colspan="2">{% trans 'Telephone numbers not found' %}</td> |
||||
|
</tr> |
||||
|
{% endfor %} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<div class="modal-footer"> |
||||
|
<a href="{% url 'abonapp:phonebook' gid %}?f=csv" class="btn btn-default" target="_blank"> |
||||
|
<span class="glyphicon glyphicon-export"></span> {% trans 'Export to csv' %} |
||||
|
</a> |
||||
|
</div> |
||||
@ -1,14 +0,0 @@ |
|||||
<p> |
|
||||
<label for="id_permissions">Permissions:</label> |
|
||||
<select multiple="multiple" id="id_permissions" name="permissions"> |
|
||||
<option value="add_abongroup">Can add abon group</option> |
|
||||
|
|
||||
<option value="can_add_ballance">Пополнение счёта</option> |
|
||||
|
|
||||
<option value="can_view_abongroup" selected="selected">Can view subscriber group</option> |
|
||||
|
|
||||
<option value="change_abongroup">Can change abon group</option> |
|
||||
|
|
||||
<option value="delete_abongroup">Can delete abon group</option> |
|
||||
</select> |
|
||||
</p> |
|
||||
@ -1,8 +0,0 @@ |
|||||
- (GUI) Иконки возле кнопок не настроены, натыканы случайно |
|
||||
- В abonapp.complete_service нельзя досрочно завершить услугу пока нет связи с NAS'ом |
|
||||
- Надо указывать в /usr/lib/python3.5/site-packages/django/contrib/auth/decorators.py raise_exception=True |
|
||||
- Пароли абонентов надо шифровать ключом для паролей |
|
||||
- Доделать везде переводы |
|
||||
- Не надо коннектиться к микротику когда не собираемся ничего изменять. А то при сохранении залогинились и вышли без действий |
|
||||
- Не удаляет просроченные услуги если не пингуется NAS |
|
||||
! Проверить дату завершения услуги |
|
||||
@ -0,0 +1,59 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9 on 2017-12-14 15:17 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.conf import settings |
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||
|
('chatbot', '0001_initial'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='MessageQueue', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('message', models.CharField(max_length=255, verbose_name='Message')), |
||||
|
('status', models.CharField(choices=[('n', 'New'), ('r', 'Read')], default='n', max_length=1, verbose_name='Status of message')), |
||||
|
('tag', models.CharField(default='none', max_length=6, verbose_name='App tag')), |
||||
|
('target_employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Target employee')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Message queue', |
||||
|
'verbose_name_plural': 'Message queue', |
||||
|
'db_table': 'chat_message_queue', |
||||
|
}, |
||||
|
), |
||||
|
migrations.AlterModelOptions( |
||||
|
name='messagehistory', |
||||
|
options={'verbose_name': 'Message history', 'verbose_name_plural': 'Message histories'}, |
||||
|
), |
||||
|
migrations.AlterModelOptions( |
||||
|
name='telegrambot', |
||||
|
options={'verbose_name': 'Telegram bot', 'verbose_name_plural': 'Telegram bots'}, |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='telegrambot', |
||||
|
name='chat_id', |
||||
|
field=models.PositiveIntegerField(default=0, verbose_name='Telegram chat id'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='telegrambot', |
||||
|
name='user', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Employee'), |
||||
|
), |
||||
|
migrations.AlterModelTable( |
||||
|
name='messagehistory', |
||||
|
table='chat_message_history', |
||||
|
), |
||||
|
migrations.AlterModelTable( |
||||
|
name='telegrambot', |
||||
|
table='chat_telegram_bot', |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,72 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9 on 2017-11-03 00:06 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
import djing.fields |
||||
|
import mydefs |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('devapp', '0003_auto_20170927_1838'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.RemoveField( |
||||
|
model_name='device', |
||||
|
name='map_dot', |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='comment', |
||||
|
field=models.CharField(max_length=256, verbose_name='Comment'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='devtype', |
||||
|
field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT'), ('On', 'PON ONU'), ('Ex', 'Eltex switch')], default='Dl', max_length=2, verbose_name='Device type'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='ip_address', |
||||
|
field=mydefs.MyGenericIPAddressField(max_length=8, protocol='ipv4', verbose_name='Ip address'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='mac_addr', |
||||
|
field=djing.fields.MACAddressField(blank=True, integer=True, null=True, unique=True, verbose_name='Mac address'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='man_passw', |
||||
|
field=models.CharField(blank=True, max_length=16, null=True, verbose_name='SNMP password'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='parent_dev', |
||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device', verbose_name='Parent device'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='user_group', |
||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonGroup', verbose_name='User group'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='port', |
||||
|
name='descr', |
||||
|
field=models.CharField(blank=True, max_length=60, null=True, verbose_name='Description'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='port', |
||||
|
name='device', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device', verbose_name='Device'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='port', |
||||
|
name='num', |
||||
|
field=models.PositiveSmallIntegerField(default=0, verbose_name='Number'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9 on 2017-11-07 16:19 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('devapp', '0004_auto_20171103_0006'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name='device', |
||||
|
name='snmp_item_num', |
||||
|
field=models.PositiveSmallIntegerField(default=0), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,82 @@ |
|||||
|
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} |
||||
|
{% load i18n %} |
||||
|
{% load bootstrap3 %} |
||||
|
{% 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">{{ dev.comment }}</li> |
||||
|
</ol> |
||||
|
|
||||
|
{% include 'message_block.html' %} |
||||
|
|
||||
|
<div class="panel panel-default"> |
||||
|
<div class="panel-heading"> |
||||
|
<h3 class="panel-title">{% trans 'Fix device group' %}</h3> |
||||
|
</div> |
||||
|
<div class="panel-body"> |
||||
|
|
||||
|
<form role="form" action="{% url 'devapp:fix_device_group' dev.pk %}" method="post">{% csrf_token %} |
||||
|
|
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.ip_address addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.mac_addr addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'comment' as ic %} |
||||
|
{% bootstrap_field form.comment addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'hdd' as ic %} |
||||
|
{% bootstrap_field form.devtype addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'lock' as ic %} |
||||
|
{% bootstrap_field form.man_passw addon_before=ic %} |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label class="control-label" for="{{ form.user_group.id_for_label }}">{{ form.user_group.label }}</label> |
||||
|
<div class="input-group{% if not dev.user_group %} has-error{% endif %}"> |
||||
|
<span class="input-group-addon"> |
||||
|
{% bootstrap_icon 'subscript' %} |
||||
|
</span> |
||||
|
{{ form.user_group }} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label for="id_parent_dev">{% trans 'Parent device' %}</label> |
||||
|
|
||||
|
<div class="input-group selectajax" data-dst="/dev/search_dev"> |
||||
|
<span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span> |
||||
|
<input type="hidden" name="parent_dev" class="selectajax-hid" {% if selected_parent_dev %} |
||||
|
value="{{ selected_parent_dev.pk }}" {% endif %}> |
||||
|
{% if selected_parent_dev %} |
||||
|
<button class="selectajax-btn form-control btn btn-default">{{ selected_parent_dev.comment }}</button> |
||||
|
<input type="text" class="form-control dropdown-toggle selectajax-inp hidden" data-toggle="dropdown" |
||||
|
id="id_parent_dev" placeholder="{% trans 'Find the device' %}"> |
||||
|
{% else %} |
||||
|
<button class="selectajax-btn form-control btn btn-default hidden"></button> |
||||
|
<input type="text" class="form-control dropdown-toggle selectajax-inp" data-toggle="dropdown" |
||||
|
id="id_parent_dev" placeholder="{% trans 'Find the device' %}"> |
||||
|
{% endif %} |
||||
|
<ul class="dropdown-menu selectajax-ul"></ul> |
||||
|
{{ form.parent_dev.errors }} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="btn-group btn-group-sm"> |
||||
|
<button type="submit" class="btn btn-primary"> |
||||
|
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} |
||||
|
</button> |
||||
|
<button type="reset" class="btn btn-default"> |
||||
|
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %} |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
{% endblock %} |
||||
@ -1,25 +1,53 @@ |
|||||
#!/usr/bin/env python3 |
#!/usr/bin/env python3 |
||||
import sys |
import sys |
||||
from redis import Redis |
|
||||
from rq import Queue |
|
||||
|
import socket |
||||
|
|
||||
|
|
||||
def die(text): |
def die(text): |
||||
print(text) |
print(text) |
||||
exit(1) |
exit(1) |
||||
|
|
||||
|
''' |
||||
|
obj = { |
||||
|
'client_ip': ip2int('127.0.0.1'), |
||||
|
'client_mac': 'aa:bb:cc:dd:ee:ff', |
||||
|
'switch_mac': 'aa:bb:cc:dd:ee:ff', |
||||
|
'switch_port': 3, |
||||
|
'cmd': 'commit' |
||||
|
} |
||||
|
''' |
||||
|
|
||||
|
|
||||
|
def send_to(data, addr='127.0.0.1', port=5436): |
||||
|
from pickle import dumps |
||||
|
try: |
||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
||||
|
s.connect((addr, port)) |
||||
|
data = dumps(data) |
||||
|
s.send(data) |
||||
|
except ConnectionRefusedError: |
||||
|
print('ERROR: connection refused') |
||||
|
|
||||
|
|
||||
if __name__ == "__main__": |
if __name__ == "__main__": |
||||
argv = sys.argv |
argv = sys.argv |
||||
if len(argv) < 3: |
if len(argv) < 3: |
||||
die('Too few arguments, exiting...') |
die('Too few arguments, exiting...') |
||||
action = argv[1] |
action = argv[1] |
||||
q = Queue(connection=Redis()) |
|
||||
if action == 'commit': |
if action == 'commit': |
||||
if len(argv) < 6: |
if len(argv) < 6: |
||||
die('Too few arguments, exiting...') |
die('Too few arguments, exiting...') |
||||
q.enqueue('agent.commands.dhcp.dhcp_commit', argv[2], argv[3], argv[4], int(argv[5])) |
|
||||
elif action == 'expiry': |
|
||||
q.enqueue('agent.commands.dhcp.dhcp_expiry', argv[2]) |
|
||||
elif action == 'release': |
|
||||
q.enqueue('agent.commands.dhcp.dhcp_release', argv[2]) |
|
||||
|
dat = { |
||||
|
'client_ip': argv[2], |
||||
|
'client_mac': argv[3], |
||||
|
'switch_mac': argv[4], |
||||
|
'switch_port': int(argv[5]), |
||||
|
'cmd': 'commit' |
||||
|
} |
||||
|
send_to(dat) |
||||
|
elif action == 'expiry' or action == 'release': |
||||
|
dat = { |
||||
|
'client_ip': argv[2], |
||||
|
'cmd': action |
||||
|
} |
||||
|
send_to(dat) |
||||
@ -1,18 +1,12 @@ |
|||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||
from django.shortcuts import get_object_or_404 |
from django.shortcuts import get_object_or_404 |
||||
from abonapp.models import Abon |
from abonapp.models import Abon |
||||
|
|
||||
|
|
||||
#def context_processor_client_ipaddress(request): |
|
||||
# ip = request.META.get('REMOTE_ADDR', '') or request.META.get('HTTP_X_FORWARDED_FOR', '') |
|
||||
# return { |
|
||||
# 'client_ipaddress': ip |
|
||||
# } |
|
||||
|
from django.conf import settings |
||||
|
|
||||
|
|
||||
# От сюда можно получать на клиентской стороне профиль абонента |
# От сюда можно получать на клиентской стороне профиль абонента |
||||
def context_processor_additional_profile(request): |
def context_processor_additional_profile(request): |
||||
if request.user.is_staff or request.user.is_anonymous(): |
if request.user.is_staff or request.user.is_anonymous(): |
||||
return {'subscriber': request.user} |
|
||||
|
return {'subscriber': request.user, 'FILE_UPLOAD_MAX_MEMORY_SIZE': settings.FILE_UPLOAD_MAX_MEMORY_SIZE} |
||||
else: |
else: |
||||
return {'subscriber': get_object_or_404(Abon, id=request.user.pk)} |
|
||||
|
return {'subscriber': get_object_or_404(Abon, id=request.user.pk), 'FILE_UPLOAD_MAX_MEMORY_SIZE': settings.FILE_UPLOAD_MAX_MEMORY_SIZE} |
||||
@ -0,0 +1,167 @@ |
|||||
|
# 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-11-03 00:12+0300\n" |
||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
||||
|
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" |
||||
|
"Language: \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" |
||||
|
|
||||
|
#: models.py:7 |
||||
|
msgid "Map point title" |
||||
|
msgstr "Название точки" |
||||
|
|
||||
|
#: models.py:8 |
||||
|
msgid "Latitude" |
||||
|
msgstr "Широта" |
||||
|
|
||||
|
#: models.py:9 templates/maps/options.html.py:18 |
||||
|
msgid "Longitude" |
||||
|
msgstr "Долгота" |
||||
|
|
||||
|
#: models.py:10 templates/maps/dot.html.py:63 |
||||
|
msgid "Devices" |
||||
|
msgstr "Устройства" |
||||
|
|
||||
|
#: models.py:11 |
||||
|
msgid "Attachment" |
||||
|
msgstr "Приложение" |
||||
|
|
||||
|
#: models.py:15 |
||||
|
msgid "Map point" |
||||
|
msgstr "Геоточка" |
||||
|
|
||||
|
#: models.py:16 |
||||
|
msgid "Map points" |
||||
|
msgstr "Геоточки" |
||||
|
|
||||
|
#: models.py:18 |
||||
|
msgid "Can view" |
||||
|
msgstr "Может просматривать" |
||||
|
|
||||
|
#: templates/maps/add_device.html:8 templates/maps/dot.html.py:8 |
||||
|
#: templates/maps/options.html:7 |
||||
|
msgid "Map settings" |
||||
|
msgstr "Настройки карты" |
||||
|
|
||||
|
#: templates/maps/add_device.html:10 |
||||
|
msgid "Add devices" |
||||
|
msgstr "Добавить устройства" |
||||
|
|
||||
|
#: templates/maps/add_device.html:24 |
||||
|
msgid "Pick the group" |
||||
|
msgstr "Выбрать группу" |
||||
|
|
||||
|
#: templates/maps/add_device.html:55 |
||||
|
msgid "Select the devices" |
||||
|
msgstr "Выбрать устройства" |
||||
|
|
||||
|
#: templates/maps/add_device.html:62 templates/maps/dot.html.py:49 |
||||
|
#: templates/maps/modal_add_device.html:15 templates/maps/modal_add_dot.html:25 |
||||
|
msgid "Save" |
||||
|
msgstr "Сохранить" |
||||
|
|
||||
|
#: templates/maps/dot.html:13 |
||||
|
msgid "Add new point" |
||||
|
msgstr "Добавить новую точку" |
||||
|
|
||||
|
#: templates/maps/dot.html:52 |
||||
|
msgid "Reset" |
||||
|
msgstr "Сбросить" |
||||
|
|
||||
|
#: templates/maps/dot.html:83 |
||||
|
msgid "User group has no attached" |
||||
|
msgstr "Группа абонентов не привязана" |
||||
|
|
||||
|
#: templates/maps/dot.html:89 |
||||
|
msgid "Devices not found" |
||||
|
msgstr "Устройства не найдены" |
||||
|
|
||||
|
#: templates/maps/dot.html:94 |
||||
|
msgid "Add" |
||||
|
msgstr "Добавить" |
||||
|
|
||||
|
#: templates/maps/map_tooltip.html:15 |
||||
|
msgid "Pinned devices not found" |
||||
|
msgstr "Привязанные устройства не найдены" |
||||
|
|
||||
|
#: templates/maps/modal_add_device.html:5 |
||||
|
msgid "Add device" |
||||
|
msgstr "Добавить устройство" |
||||
|
|
||||
|
#: templates/maps/modal_add_device.html:17 |
||||
|
msgid "Close" |
||||
|
msgstr "Закрыть" |
||||
|
|
||||
|
#: templates/maps/modal_add_dot.html:6 |
||||
|
msgid "Add point" |
||||
|
msgstr "Добавить точку" |
||||
|
|
||||
|
#: templates/maps/modal_add_dot.html:9 |
||||
|
#, python-format |
||||
|
msgid "Coords: %(coords)s" |
||||
|
msgstr "Координаты %(coords)s" |
||||
|
|
||||
|
#: templates/maps/options.html:17 |
||||
|
msgid "Title" |
||||
|
msgstr "Название" |
||||
|
|
||||
|
#: templates/maps/options.html:32 |
||||
|
msgid "Edit" |
||||
|
msgstr "Изменить" |
||||
|
|
||||
|
#: templates/maps/options.html:39 |
||||
|
msgid "Delete" |
||||
|
msgstr "Удалить" |
||||
|
|
||||
|
#: templates/maps/options.html:49 |
||||
|
msgid "You have not created map points yet" |
||||
|
msgstr "Вы ещё не создали ни одной геоточки" |
||||
|
|
||||
|
#: templates/maps/options.html:49 |
||||
|
msgid "Create" |
||||
|
msgstr "Создать" |
||||
|
|
||||
|
#: templates/maps/preload_devices_tmpl.html:7 |
||||
|
msgid "no devices found" |
||||
|
msgstr "нет усройств" |
||||
|
|
||||
|
#: templates/maps/ya_index.html:11 |
||||
|
msgid "Loading.." |
||||
|
msgstr "Загрузка.." |
||||
|
|
||||
|
#: templates/maps/ya_index.html:144 |
||||
|
msgid "Layers" |
||||
|
msgstr "Слои" |
||||
|
|
||||
|
#: templates/maps/ya_index.html:153 |
||||
|
msgid "Show all" |
||||
|
msgstr "Показать всё" |
||||
|
|
||||
|
#: views.py:53 |
||||
|
msgid "Map point has been saved" |
||||
|
msgstr "Геоточка сохранена" |
||||
|
|
||||
|
#: views.py:56 views.py:111 |
||||
|
msgid "fix form errors" |
||||
|
msgstr "исправте ошибки формы" |
||||
|
|
||||
|
#: views.py:66 views.py:79 |
||||
|
msgid "Map point does not exist" |
||||
|
msgstr "Геоточка не найдена" |
||||
|
|
||||
|
#: views.py:77 |
||||
|
#, python-format |
||||
|
msgid "Map point '%(title)s' has been deleted" |
||||
|
msgstr "Геоточка '%(title)s' была удалена" |
||||
@ -0,0 +1,45 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9 on 2017-11-03 00:06 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('devapp', '0004_auto_20171103_0006'), |
||||
|
('mapapp', '0001_initial'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='dot', |
||||
|
options={'permissions': (('can_view', 'Can view'),), 'verbose_name': 'Map dot', 'verbose_name_plural': 'Map dots'}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='dot', |
||||
|
name='attachment', |
||||
|
field=models.FileField(blank=True, null=True, upload_to='map_attachments/%Y_%m_%d', verbose_name='Attachment'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='dot', |
||||
|
name='devices', |
||||
|
field=models.ManyToManyField(db_table='dot_device', to='devapp.Device', verbose_name='Devices'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='dot', |
||||
|
name='latitude', |
||||
|
field=models.FloatField(verbose_name='Latitude'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='dot', |
||||
|
name='longitude', |
||||
|
field=models.FloatField(verbose_name='Longitude'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='dot', |
||||
|
name='title', |
||||
|
field=models.CharField(max_length=127, verbose_name='Map point title'), |
||||
|
), |
||||
|
] |
||||
@ -1,13 +1,22 @@ |
|||||
from django.db import models |
from django.db import models |
||||
|
from django.utils.translation import ugettext_lazy as _ |
||||
|
from devapp.models import Device |
||||
|
|
||||
|
|
||||
class Dot(models.Model): |
class Dot(models.Model): |
||||
title = models.CharField(max_length=127) |
|
||||
latitude = models.FloatField() |
|
||||
longitude = models.FloatField() |
|
||||
|
title = models.CharField(_('Map point title'), max_length=127) |
||||
|
latitude = models.FloatField(_('Latitude')) |
||||
|
longitude = models.FloatField(_('Longitude')) |
||||
|
devices = models.ManyToManyField(Device, verbose_name=_('Devices'), db_table='dot_device') |
||||
|
attachment = models.FileField(_('Attachment'), upload_to='map_attachments/%Y_%m_%d', null=True, blank=True) |
||||
|
|
||||
class Meta: |
class Meta: |
||||
db_table = 'dots' |
db_table = 'dots' |
||||
|
verbose_name = _('Map point') |
||||
|
verbose_name_plural = _('Map points') |
||||
|
permissions = ( |
||||
|
('can_view', _('Can view')), |
||||
|
) |
||||
|
|
||||
def __str__(self): |
def __str__(self): |
||||
return self.title |
return self.title |
||||
@ -0,0 +1,70 @@ |
|||||
|
{% extends 'base.html' %} |
||||
|
{% load i18n %} |
||||
|
{% load bootstrap3 %} |
||||
|
{% block main %} |
||||
|
|
||||
|
<ol class="breadcrumb"> |
||||
|
<li><span class="glyphicon glyphicon-home"></span></li> |
||||
|
<li><a href="{% url 'mapapp:options' %}">{% trans 'Map settings' %}</a></li> |
||||
|
<li><a href="{% url 'mapapp:edit_dot' dot.pk %}">{{ dot.title }}</a></li> |
||||
|
<li class="active">{% trans 'Add devices' %}</li> |
||||
|
</ol> |
||||
|
|
||||
|
{% include 'message_block.html' %} |
||||
|
|
||||
|
<script type="text/javascript"> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
|
||||
|
<div class="row"> |
||||
|
<div class="col-sm-4"> |
||||
|
<div class="panel panel-default"> |
||||
|
<div class="panel-heading"> |
||||
|
<h3 class="panel-title">{% trans 'Pick the group' %}</h3> |
||||
|
</div> |
||||
|
<div class="panel-body"> |
||||
|
{% url 'mapapp:preload_devices' as prel_url %} |
||||
|
{% for group in groups %} |
||||
|
{% if group.pk == grp %} |
||||
|
<u><a href="#" data-href="{{ prel_url }}?dot={{ dot.pk }}&grp={{ group.pk }}" class="btn_ajloader">{{ group.title }}</a></u> |
||||
|
{% else %} |
||||
|
<a href="#" data-href="{{ prel_url }}?dot={{ dot.pk }}&grp={{ group.pk }}" class="btn_ajloader">{{ group.title }}</a> |
||||
|
{% endif %}<br> |
||||
|
{% endfor %} |
||||
|
</div> |
||||
|
</div> |
||||
|
<script type="text/javascript"> |
||||
|
$(window).load(function() { |
||||
|
$('.btn_ajloader').on('click', function(e){ |
||||
|
var grp_id = $(this).attr('data-href'); |
||||
|
grp_id = grp_id.split('='); |
||||
|
grp_id = grp_id[grp_id.length-1]; |
||||
|
$('#selected_user_group').val(grp_id); |
||||
|
e.preventDefault(); |
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
</div> |
||||
|
<div class="col-sm-8"> |
||||
|
<form role="form" action="{% url 'mapapp:add_dev' dot.pk %}?grp={{ grp }}" method="post">{% csrf_token %} |
||||
|
<input type="hidden" id="selected_user_group" name="selected_user_group"> |
||||
|
<div class="panel panel-default"> |
||||
|
<div class="panel-heading"> |
||||
|
<h3 class="panel-title">{% trans 'Select the devices' %}</h3> |
||||
|
</div> |
||||
|
<div class="panel-body" id="id_block_devices"> |
||||
|
{% include 'maps/preload_devices_tmpl.html' with all_devices=existing_devs dot_devices_ids=dot_devices_ids %} |
||||
|
</div> |
||||
|
<div class="panel-footer"> |
||||
|
<button type="submit" class="btn btn-primary"> |
||||
|
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
{% endblock %} |
||||
@ -1,63 +1,103 @@ |
|||||
{% extends 'base.html' %} |
{% extends 'base.html' %} |
||||
|
{% load i18n %} |
||||
|
{% load bootstrap3 %} |
||||
{% 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 'mapapp:options' %}">Настройки карты</a></li> |
|
||||
|
<li><a href="{% url 'mapapp:options' %}">{% trans 'Map settings' %}</a></li> |
||||
|
{% if dot.id %} |
||||
<li class="active">{{ dot.title }}</li> |
<li class="active">{{ dot.title }}</li> |
||||
|
{% url 'mapapp:edit_dot' dot.id as form_url %} |
||||
|
{% else %} |
||||
|
<li class="active">{% trans 'Add new point' %}</li> |
||||
|
{% url 'mapapp:add_dot' as form_url %} |
||||
|
{% endif %} |
||||
</ol> |
</ol> |
||||
|
|
||||
{% include 'message_block.html' %} |
{% include 'message_block.html' %} |
||||
|
|
||||
|
<div class="row"> |
||||
|
<div class="{% if dot.id %}col-sm-6{% else %}col-sm-12{% endif %}"> |
||||
|
<form role="form" action="{{ form_url }}" method="post" enctype="multipart/form-data">{% csrf_token %} |
||||
|
<input type="hidden" name="MAX_FILE_SIZE" value="{{ FILE_UPLOAD_MAX_MEMORY_SIZE }}"/> |
||||
<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 'Map point' %}</h3> |
||||
</div> |
</div> |
||||
<div class="panel-body"> |
<div class="panel-body"> |
||||
|
|
||||
{% if dot.id %} |
|
||||
<form role="form" action="{% url 'mapapp:edit_dot' dot.id %}" method="post"> |
|
||||
{% else %} |
|
||||
<form role="form" action="{% url 'mapapp:add_dot' %}" method="post"> |
|
||||
{% endif %} |
|
||||
{% csrf_token %} |
|
||||
|
{# title input #} |
||||
|
{% bootstrap_icon 'edit' as ic %} |
||||
|
{% bootstrap_field form.title addon_before=ic %} |
||||
|
|
||||
<div class="form-group"> |
|
||||
<label for="id_title">Название точки топологии</label> |
|
||||
<div class="input-group"> |
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-edit"></span></span> |
|
||||
{{ form.title }}{{ form.title.errors }} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
{# longitude input #} |
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.longitude addon_before=ic %} |
||||
|
|
||||
<div class="form-group"> |
|
||||
<label for="id_longitude">Longitude</label> |
|
||||
<div class="input-group"> |
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span> |
|
||||
{{ form.longitude }}{{ form.longitude.errors }} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
{# latitude input #} |
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.latitude addon_before=ic %} |
||||
|
|
||||
<div class="form-group"> |
|
||||
<label for="id_latitude">Latitude</label> |
|
||||
<div class="input-group"> |
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span> |
|
||||
{{ form.latitude }}{{ form.latitude.errors }} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
{# attachment input #} |
||||
|
{% bootstrap_field form.attachment %} |
||||
|
|
||||
<div class="btn-group"> |
|
||||
<button type="submit" class="btn btn-sm btn-primary"> |
|
||||
<span class="glyphicon glyphicon-save"></span> Сохранить |
|
||||
|
</div> |
||||
|
<div class="panel-footer"> |
||||
|
<div class="btn-group btn-group-sm"> |
||||
|
<button type="submit" class="btn btn-primary"> |
||||
|
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} |
||||
</button> |
</button> |
||||
<button type="reset" class="btn btn-sm btn-default"> |
|
||||
<span class="glyphicon glyphicon-remove-circle"></span> Сбросить |
|
||||
|
<button type="reset" class="btn btn-default"> |
||||
|
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %} |
||||
</button> |
</button> |
||||
</div> |
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
</form> |
</form> |
||||
</div> |
</div> |
||||
|
{% if dot.id %} |
||||
|
<div class="col-sm-6"> |
||||
|
<div class="panel panel-default"> |
||||
|
<div class="panel-heading"> |
||||
|
<h3 class="panel-title">{% trans 'Devices' %}</h3> |
||||
|
</div> |
||||
|
<table class="table"> |
||||
|
{% for dev in dot.devices.all %} |
||||
|
<tr> |
||||
|
<td> |
||||
|
{% if dev.user_group %} |
||||
|
<a href="{% url 'devapp:view' dev.user_group.pk dev.pk %}">{{ dev.comment }}</a> |
||||
|
{% else %} |
||||
|
<a href="{% url 'devapp:view' 0 dev.pk %}">{{ dev.comment }}</a> |
||||
|
{% endif %} |
||||
|
</td> |
||||
|
<td>{{ dev.ip_address }}</td> |
||||
|
<td>{{ dev.get_comment_display }}</td> |
||||
|
<td> |
||||
|
{% if dev.user_group %} |
||||
|
<a href="{% url 'abonapp:people_list' dev.user_group.pk %}"> |
||||
|
{{ dev.user_group }} |
||||
|
</a> |
||||
|
{% else %} |
||||
|
{% trans 'User group has no attached' %} |
||||
|
{% endif %} |
||||
|
</td> |
||||
|
</tr> |
||||
|
{% empty %} |
||||
|
<tr> |
||||
|
<td colspan="3">{% trans 'Devices not found' %}</td> |
||||
|
</tr> |
||||
|
{% endfor %} |
||||
|
</table> |
||||
|
<div class="panel-footer"> |
||||
|
{% trans 'Add' as trns %} |
||||
|
{% url 'mapapp:add_dev' dot.pk as url %} |
||||
|
{% bootstrap_button trns button_type="link" icon='plus' size='sm' button_class='btn-success' href=url %} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{% endif %} |
||||
</div> |
</div> |
||||
|
|
||||
{% endblock %} |
{% endblock %} |
||||
@ -1,62 +0,0 @@ |
|||||
{% extends 'base_no_lmenu.html' %} |
|
||||
{% block main %} |
|
||||
<script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> |
|
||||
<script> |
|
||||
|
|
||||
var markers = { |
|
||||
dev_ok: 'dev_ok.png', |
|
||||
dev_bug: 'dev_bug.png', |
|
||||
dev: 'dev.png', |
|
||||
disabled: 'flag_black.png' |
|
||||
}; |
|
||||
|
|
||||
google.maps.Map.prototype.onMapDblClick = function (e) { |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
google.maps.Map.prototype.SetStaticMarker = function (wlink, type, x, y) { |
|
||||
var dot = new google.maps.LatLng(x, y); |
|
||||
|
|
||||
var m = new google.maps.Marker({icon: '/static/img/gmarkers/' + type, position: dot}); |
|
||||
|
|
||||
var iw = new google.maps.InfoWindow(); |
|
||||
|
|
||||
google.maps.event.addListener(m, 'click', function () { |
|
||||
var mp = this.map; |
|
||||
$.get(wlink, function (r) { |
|
||||
iw.setContent(r); |
|
||||
iw.open(mp, m); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
m.setMap(this); |
|
||||
}; |
|
||||
|
|
||||
function MyISGmap(elId) { |
|
||||
var contain_block = document.getElementById(elId); |
|
||||
this.map = new google.maps.Map(contain_block, { |
|
||||
center: new google.maps.LatLng(45.4489018, 34.7880390), |
|
||||
zoom: 11, |
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP |
|
||||
}); |
|
||||
this.map.set("disableDoubleClickZoom", true); |
|
||||
|
|
||||
google.maps.event.addListener(this.map, 'dblclick', this.map.onMapDblClick); |
|
||||
} |
|
||||
|
|
||||
function initialize() { |
|
||||
var mm = new MyISGmap("main"); |
|
||||
|
|
||||
$.getJSON("#{ % url 'maps_get_dots' %}", function (r) { |
|
||||
for (var n in r.dots) { |
|
||||
var el = r.dots[n]; |
|
||||
mm.map.SetStaticMarker("/", markers.disabled, el[1], el[2]); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
google.maps.event.addDomListener(window, 'load', initialize); |
|
||||
</script> |
|
||||
|
|
||||
|
|
||||
{% endblock %} |
|
||||
@ -1,10 +1,23 @@ |
|||||
|
{% load i18n %} |
||||
<h4>{{ dot.title }}</h4> |
<h4>{{ dot.title }}</h4> |
||||
<div class="list-group"> |
<div class="list-group"> |
||||
{% for dev in devs %} |
{% for dev in devs %} |
||||
<a class="list-group-item" href="{% url 'devapp:view' dev.user_group.pk dev.pk %}" target="_blank"> |
|
||||
{{ dev.comment }} |
|
||||
|
<a class="list-group-item" href="{% url 'devapp:view' dev.user_group.pk dev.pk %}" target="_blank" title="{{ dev.mon.plugin_output }}"> |
||||
|
{% if dev.mon.current_state == '0' %} |
||||
|
<span class="glyphicon glyphicon-ok-circle text-success"></span> |
||||
|
{% else %} |
||||
|
<span class="glyphicon glyphicon-exclamation-sign text-danger"></span> |
||||
|
{% endif %} |
||||
|
<b>{{ dev.comment }}</b> {{ dev.mon.plugin_output }} |
||||
</a> |
</a> |
||||
|
|
||||
{% empty %} |
{% empty %} |
||||
<li class="list-group-item">нет привязанных устройств</li> |
|
||||
|
<li class="list-group-item">{% trans 'Pinned devices not found' %}</li> |
||||
{% endfor %} |
{% endfor %} |
||||
|
|
||||
</div> |
</div> |
||||
|
|
||||
|
{% if dot.attachment %} |
||||
|
<span class="glyphicon glyphicon-file"></span> |
||||
|
<a href="{{ dot.attachment.url }}" class="btn btn-xs btn-dfault" target="_blank">{{ dot.attachment.name }}</a> |
||||
|
{% endif %} |
||||
@ -0,0 +1,20 @@ |
|||||
|
{% load i18n %}{% load bootstrap3 %} |
||||
|
<form action="{% url 'mapapp:add_dev' dot_id %}" method="post">{% csrf_token %} |
||||
|
<div class="modal-header primary"> |
||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
||||
|
<h4 class="modal-title"><span class="glyphicon glyphicon-warning-sign"></span>{% trans 'Add device' %}</h4> |
||||
|
</div> |
||||
|
<div class="modal-body"> |
||||
|
|
||||
|
{% bootstrap_form form %} |
||||
|
|
||||
|
</div> |
||||
|
<div class="modal-footer"> |
||||
|
<div class="btn-group btn-grup-sm"> |
||||
|
<button type="submit" class="btn btn-primary"> |
||||
|
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} |
||||
|
</button> |
||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Close' %}</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -1,20 +1,28 @@ |
|||||
<form action="{% url 'mapapp:modal_add_dot' %}" method="post">{% csrf_token %} |
|
||||
|
{% load i18n %}{% load bootstrap3 %} |
||||
|
<form action="{% url 'mapapp:modal_add_dot' %}" class="form-ajax" method="post" enctype="multipart/form-data">{% csrf_token %} |
||||
|
<input type="hidden" name="MAX_FILE_SIZE" value="{{ FILE_UPLOAD_MAX_MEMORY_SIZE }}"/> |
||||
<div class="modal-header primary"> |
<div class="modal-header primary"> |
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
||||
<h4 class="modal-title"><span class="glyphicon glyphicon-warning-sign"></span>Добавить точку</h4> |
|
||||
|
<h4 class="modal-title"><span class="glyphicon glyphicon-warning-sign"></span>{% trans 'Add point' %}</h4> |
||||
</div> |
</div> |
||||
<div class="modal-body"> |
<div class="modal-body"> |
||||
<h4>Координаты: {{ coords }}</h4> |
|
||||
<div class="form-group"> |
|
||||
<label for="id_title">Название точки</label> |
|
||||
<input type="text" class="form-control" autofocus name="title" id="id_title"> |
|
||||
</div> |
|
||||
<input type="hidden" name="coords" value="{{ coords }}"> |
|
||||
|
<h4>{% blocktrans %}Coords: {{ coords }}{% endblocktrans %}</h4> |
||||
|
|
||||
|
{% bootstrap_icon 'edit' as ic %} |
||||
|
{% bootstrap_field form.title addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.longitude addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_icon 'globe' as ic %} |
||||
|
{% bootstrap_field form.latitude addon_before=ic %} |
||||
|
|
||||
|
{% bootstrap_field form.attachment %} |
||||
|
|
||||
</div> |
</div> |
||||
<div class="modal-footer"> |
<div class="modal-footer"> |
||||
<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="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> |
|
||||
</div> |
</div> |
||||
</form> |
</form> |
||||
@ -0,0 +1,7 @@ |
|||||
|
{% load i18n %} |
||||
|
{% for dev in all_devices %}<div class="checkbox"> |
||||
|
<label> |
||||
|
<input name="dv" type="checkbox"{% if dev.pk in dot_devices_ids %} checked{% endif %} value="{{ dev.pk }}"/> {{ dev.comment }} |
||||
|
</label> |
||||
|
</div> |
||||
|
{% empty %}{% trans 'no devices found' %}{% endfor %} |
||||
@ -1,3 +1,6 @@ |
|||||
from django.contrib import admin |
from django.contrib import admin |
||||
|
from . import models |
||||
|
|
||||
|
admin.site.register(models.Message) |
||||
|
admin.site.register(models.Conversation) |
||||
|
|
||||
# Register your models here. |
|
||||
@ -1,30 +1,55 @@ |
|||||
#!/usr/bin/env python3 |
#!/usr/bin/env python3 |
||||
import os |
import os |
||||
import sys |
|
||||
from rq import Connection, Worker |
|
||||
|
from pickle import loads |
||||
from pid.decorator import pidfile |
from pid.decorator import pidfile |
||||
|
import socket |
||||
import django |
import django |
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") |
|
||||
from agent import NasFailedResult, NasNetworkError |
|
||||
from django.core.exceptions import ValidationError |
|
||||
|
|
||||
|
|
||||
""" |
|
||||
Заустить этот скрипт как демон, он соединяет redis и django |
|
||||
""" |
|
||||
@pidfile() |
|
||||
def main(): |
|
||||
|
''' |
||||
|
obj = { |
||||
|
'client_ip': ip2int('127.0.0.1'), |
||||
|
'client_mac': 'aa:bb:cc:dd:ee:ff', |
||||
|
'switch_mac': 'aa:bb:cc:dd:ee:ff', |
||||
|
'switch_port': 3, |
||||
|
'cmd': 'commit' |
||||
|
} |
||||
|
''' |
||||
|
|
||||
|
|
||||
|
def on_new_data(client_sock, ip): |
||||
|
data = client_sock.recv(16384) |
||||
|
data = loads(data) |
||||
|
action = data['cmd'] |
||||
|
if action == 'commit': |
||||
|
dhcp_commit( |
||||
|
data['client_ip'], data['client_mac'], |
||||
|
data['switch_mac'], data['switch_port'] |
||||
|
) |
||||
|
elif action == 'expiry': |
||||
|
dhcp_expiry(data['client_ip']) |
||||
|
elif action == 'release': |
||||
|
dhcp_release(data['client_ip']) |
||||
|
client_sock.close() |
||||
|
|
||||
|
|
||||
|
@pidfile(pidname='queue_mngr.py.pid', piddir='/run') |
||||
|
def serve(addr='127.0.0.1', port=5436): |
||||
try: |
try: |
||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
||||
|
s.bind((addr, port)) |
||||
|
s.listen(3) |
||||
|
print('ready') |
||||
|
while True: |
||||
|
conn, client_addr = s.accept() |
||||
|
on_new_data(conn, client_addr) |
||||
|
except ConnectionRefusedError: |
||||
|
print('ERROR: connection refused') |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") |
||||
django.setup() |
django.setup() |
||||
with Connection(): |
|
||||
qs = sys.argv[1:] or ['default'] |
|
||||
w = Worker(qs) |
|
||||
w.work() |
|
||||
except (NasNetworkError, NasFailedResult) as e: |
|
||||
print('NAS:', e) |
|
||||
except (ValidationError, ValueError) as e: |
|
||||
print('ERROR:', e) |
|
||||
|
|
||||
|
|
||||
if __name__ == "__main__": |
|
||||
main() |
|
||||
|
from agent.commands.dhcp import dhcp_commit, dhcp_expiry, dhcp_release |
||||
|
serve() |
||||
|
|
||||
@ -1,48 +0,0 @@ |
|||||
#EXTM3U |
|
||||
#EXTINF:-1,ПЕРВЫЙ КАНАЛ |
|
||||
udp://@239.255.1.15:1234 |
|
||||
#EXTINF:-1,Россия-1 |
|
||||
udp://@239.255.1.16:1234 |
|
||||
#EXTINF:-1,МАТЧ ТВ |
|
||||
udp://@239.255.1.17:1234 |
|
||||
#EXTINF:-1,НТВ |
|
||||
udp://@239.255.1.18:1234 |
|
||||
#EXTINF:-1,ПЯТЫЙ КАНАЛ |
|
||||
udp://@239.255.1.19:1234 |
|
||||
#EXTINF:-1,РОССИЯ-КУЛЬТУРА |
|
||||
udp://@239.255.1.20:1234 |
|
||||
#EXTINF:-1,Россия-24 |
|
||||
udp://@239.255.1.21:1234 |
|
||||
#EXTINF:-1,КАРУСЕЛЬ |
|
||||
udp://@239.255.1.22:1234 |
|
||||
#EXTINF:-1,ОТР |
|
||||
udp://@239.255.1.23:1234 |
|
||||
#EXTINF:-1,ТВ Центр |
|
||||
udp://@239.255.1.24:1234 |
|
||||
|
|
||||
#EXTINF:-1,РЕН ТВ |
|
||||
udp://@239.255.1.28:1234 |
|
||||
#EXTINF:-1,Спас |
|
||||
udp://@239.255.1.29:1234 |
|
||||
#EXTINF:-1,СТС |
|
||||
udp://@239.255.1.30:1234 |
|
||||
#EXTINF:-1,Домашний |
|
||||
udp://@239.255.1.31:1234 |
|
||||
#EXTINF:-1,ТВ3 |
|
||||
udp://@239.255.1.32:1234 |
|
||||
|
|
||||
#EXTINF:-1,Звезда |
|
||||
udp://@239.255.1.34:1234 |
|
||||
|
|
||||
#EXTINF:-1,Мир-24 |
|
||||
udp://@239.255.1.9:1234 |
|
||||
|
|
||||
#EXTINF:-1,ТНТ |
|
||||
udp://@239.255.1.35:1234 |
|
||||
#EXTINF:-1,МУЗ ТВ |
|
||||
udp://@239.255.1.36:1234 |
|
||||
#EXTINF:-1,Крым 24 |
|
||||
udp://@239.255.1.14:1234 |
|
||||
|
|
||||
#EXTINF:-1,Перец |
|
||||
udp://@239.255.1.12:1234 |
|
||||
|
After Width: 100 | Height: 100 | Size: 6.6 KiB |
|
After Width: 192 | Height: 192 | Size: 12 KiB |
@ -0,0 +1,20 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin |
||||
|
|
||||
|
cd /var/backups |
||||
|
|
||||
|
file="djing`date "+%Y-%m-%d_%H.%M.%S"`.sql.gz" |
||||
|
|
||||
|
mysql_passw=MYSQL ROOT PASSWORD |
||||
|
|
||||
|
echo show tables | mysql -uroot -p$mysql_passw djingdb | \ |
||||
|
grep -v '^flowstat' | grep -v 'traflost' | grep -v '^Tables' | \ |
||||
|
xargs mysqldump -R -Q --add-locks -uroot --password=$mysql_passw djingdb $1 | gzip -9 > $file |
||||
|
|
||||
|
chmod 400 $file |
||||
|
./webdav_backup.py $file |
||||
|
|
||||
|
# удаляем старые |
||||
|
find . -name "djing20??-??-??_??.??.??.sql.gz" -mtime +30 -type f -delete |
||||
|
|
||||
@ -0,0 +1,20 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
|
import webdav.client as wc |
||||
|
from webdav.client import WebDavException |
||||
|
from sys import argv |
||||
|
|
||||
|
|
||||
|
options = { |
||||
|
'webdav_hostname': "https://webdav.yandex.ru/", |
||||
|
'webdav_login': "YANDEX USERNAME", |
||||
|
'webdav_password': "YANDEX PASSWORD" |
||||
|
} |
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
reqfile = argv[1] |
||||
|
try: |
||||
|
client = wc.Client(options) |
||||
|
client.upload_sync(remote_path="ISBackups/%s" % reqfile, local_path="/var/backups/%s" % reqfile) |
||||
|
except WebDavException as we: |
||||
|
print(we, type(we)) |
||||
|
|
||||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue