diff --git a/abonapp/admin.py b/abonapp/admin.py index c3e76ef..082d3d8 100644 --- a/abonapp/admin.py +++ b/abonapp/admin.py @@ -14,3 +14,4 @@ admin.site.register(models.AbonRawPassword) admin.site.register(models.ExtraFieldsModel) admin.site.register(models.AllPayLog) admin.site.register(models.PassportInfo) +admin.site.register(models.AdditionalTelephone) diff --git a/abonapp/forms.py b/abonapp/forms.py index b9e11d4..36fa6b5 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -6,6 +6,10 @@ from django.contrib.auth.hashers import make_password from random import choice from string import digits, ascii_lowercase from . import models +from django.conf import settings + + +TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$') def generate_random_username(length=6, chars=digits, split=2, delimiter=''): @@ -57,7 +61,7 @@ class AbonForm(forms.ModelForm): }), 'telephone': forms.TextInput(attrs={ 'placeholder': _('telephone placeholder'), - 'pattern': r'^\+[7,8,9,3]\d{10,11}$', + 'pattern': TELEPHONE_REGEXP, 'required': '', 'class': 'form-control' }), @@ -131,3 +135,18 @@ class AbonStreetForm(forms.ModelForm): 'name': forms.TextInput(attrs={'class': 'form-control', 'required':'', 'autofocus':''}), 'group': forms.Select(attrs={'class': 'form-control'}) } + + +class AdditionalTelephoneForm(forms.ModelForm): + class Meta: + model = models.AdditionalTelephone + exclude = ['abon'] + widgets = { + 'telephone': forms.TextInput(attrs={ + 'placeholder': _('telephone placeholder'), + 'pattern': TELEPHONE_REGEXP, + 'required': '', + 'class': 'form-control' + }), + 'owner_name': forms.TextInput(attrs={'class': 'form-control', 'required':''}) + } diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 7e81d54..1e734a0 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -339,7 +339,7 @@ msgstr "куда" #: abonapp/templates/abonapp/dial_log.html:12 msgid "duration" -msgstr "продолжительность" +msgstr "прод." #: abonapp/templates/abonapp/dial_log.html:13 msgid "start" @@ -389,10 +389,6 @@ msgstr "Дом" msgid "Is active" msgstr "Активен" -#: abonapp/templates/abonapp/editAbon.html:106 -msgid "Send account info to user" -msgstr "Отправить данные абоненту" - #: abonapp/templates/abonapp/editAbon.html:109 #: abonapp/templates/abonapp/editAbon.html:110 #, fuzzy @@ -473,7 +469,7 @@ msgstr "Принадлежность услуг к группам" #: abonapp/templates/abonapp/invoiceForPayment.html:10 #: abonapp/templates/abonapp/payHistory.html:39 msgid "Debts" -msgstr "Долги" +msgstr "Квитанции (долги)" #: abonapp/templates/abonapp/invoiceForPayment.html:15 msgid "Debtor" @@ -606,10 +602,6 @@ msgstr "Балланс" msgid "Subscribers not found" msgstr "Абоненты не найдены" -#: abonapp/templates/abonapp/peoples.html:130 -msgid "Refresh subscribers on NAS" -msgstr "Обновить абонентов в NAS" - #: abonapp/templates/abonapp/peoples.html:133 msgid "Tariffs in groups" msgstr "Тарифы в группах" @@ -736,10 +728,6 @@ msgstr "Адрес" msgid "delete abon success msg" msgstr "Абонент успешно удалён" -#: abonapp/views.py:180 -msgid "I not know what to delete" -msgstr "Не понятно что удалять" - #: abonapp/views.py:184 #, python-format msgid "NAS says: '%s'" @@ -951,3 +939,69 @@ msgstr "Пользователь, который не является перс msgid "Ip not passed" msgstr "Ip адрес не передан" + +msgid "Additional telephone" +msgstr "Дополнительный телефон" + +msgid "Additional telephones" +msgstr "Дополнительные телефоны" + +msgid "Abon group" +msgstr "Группа абонентов" + +msgid "Abon groups" +msgstr "Группы абонентов" + +msgid "Abon service" +msgstr "Услуга абонента" + +msgid "Abon services" +msgstr "Услуги абонентов" + +msgid "Abon" +msgstr "Абонент" + +msgid "Abons" +msgstr "Абоненты" + +msgid "New telephone has been saved" +msgstr "Новый телефон сохранен" + +msgid "Add telephone" +msgstr "Добавить номер телефона" + +msgid "Telephone owner" +msgstr "Владелец телефона" + +msgid "Additional telephones not found" +msgstr "Дополнительные телефоны не найдены" + +msgid "Additional telephone successfully deleted" +msgstr "Номер телефона успешно удалён" + +msgid "Telephone not found" +msgstr "Телефон не найден" + +msgid "Can view subscriber group" +msgstr "Может просматривать группу абонентов" + +msgid "Permission denied" +msgstr "Доступ запрещён" + +msgid "Can view subscriber logs" +msgstr "Может видеть логи абонента" + +msgid "Can view invoice for payment" +msgstr "Может видеть назначенные платежи" + +msgid "Debt" +msgstr "Квитанция (долг)" + +msgid "Passport Info" +msgstr "Паспортные данные" + +msgid "Can ping" +msgstr "Может пинговать" + +msgid "Can view additional telephones" +msgstr "Может видеть дополнительные телефоны" diff --git a/abonapp/migrations/0001_initial.py b/abonapp/migrations/0001_initial.py deleted file mode 100644 index 7b1368f..0000000 --- a/abonapp/migrations/0001_initial.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-06-28 23:51 - -from django.conf import settings -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - initial = True - - dependencies = [ - ('accounts_app', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('tariff_app', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Abon', - fields=[ - ('userprofile_ptr', - models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, - primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), - ('ballance', models.FloatField(default=0.0, validators=[django.core.validators.DecimalValidator])), - ('address', models.CharField(max_length=256)), - ], - options={ - 'db_table': 'abonent', - }, - bases=('accounts_app.userprofile',), - ), - migrations.CreateModel( - name='AbonGroup', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=127)), - ('address', models.CharField(blank=True, max_length=256, null=True)), - ], - options={ - 'db_table': 'abonent_groups', - }, - ), - migrations.CreateModel( - name='AbonLog', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('amount', models.FloatField(default=0.0)), - ('comment', models.CharField(max_length=128)), - ('date', models.DateTimeField(auto_now_add=True)), - ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', - to=settings.AUTH_USER_MODEL)), - ], - options={ - 'db_table': 'abonent_log', - }, - ), - migrations.CreateModel( - name='AbonTariff', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('tariff_priority', models.PositiveSmallIntegerField(default=0)), - ('time_start', models.DateTimeField(blank=True, default=None, null=True)), - ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), - ('tariff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='linkto_tariff', - to='tariff_app.Tariff')), - ], - options={ - 'ordering': ('tariff_priority',), - 'db_table': 'abonent_tariff', - }, - ), - migrations.CreateModel( - name='InvoiceForPayment', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('status', models.BooleanField(default=False)), - ('amount', models.FloatField(default=0.0)), - ('comment', models.CharField(max_length=128)), - ('date_create', models.DateTimeField(auto_now_add=True)), - ('date_pay', models.DateTimeField(blank=True, null=True)), - ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', - to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ('date_create',), - 'db_table': 'abonent_inv_pay', - }, - ), - migrations.AddField( - model_name='abon', - name='current_tariffs', - field=models.ManyToManyField(through='abonapp.AbonTariff', to='tariff_app.Tariff'), - ), - migrations.AddField( - model_name='abon', - name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, - to='abonapp.AbonGroup'), - ), - migrations.AlterUniqueTogether( - name='abontariff', - unique_together={('abon', 'tariff', 'tariff_priority')}, - ), - ] diff --git a/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py b/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py new file mode 100644 index 0000000..89e222c --- /dev/null +++ b/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-04 16:15 +from __future__ import unicode_literals + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import mydefs +import re + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('devapp', '0001_squashed_0007_auto_20170816_1109'), + ('tariff_app', '0002_tariff_descr'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('accounts_app', '0001_initial'), + ('tariff_app', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Abon', + fields=[ + ('userprofile_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ('ballance', models.FloatField(default=0.0, validators=[django.core.validators.DecimalValidator])), + ('address', models.CharField(max_length=256)), + ], + options={ + 'db_table': 'abonent', + }, + bases=('accounts_app.userprofile',), + ), + migrations.CreateModel( + name='AbonGroup', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=127, unique=True)), + ], + options={ + 'db_table': 'abonent_groups', + }, + ), + migrations.CreateModel( + name='AbonLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.FloatField(default=0.0)), + ('comment', models.CharField(max_length=128)), + ('date', models.DateTimeField(auto_now_add=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'abonent_log', + }, + ), + migrations.CreateModel( + name='AbonTariff', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tariff_priority', models.PositiveSmallIntegerField(default=0)), + ('time_start', models.DateTimeField(blank=True, default=None, null=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('tariff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='linkto_tariff', to='tariff_app.Tariff')), + ], + options={ + 'ordering': ('tariff_priority',), + 'db_table': 'abonent_tariff', + }, + ), + migrations.CreateModel( + name='InvoiceForPayment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.BooleanField(default=False)), + ('amount', models.FloatField(default=0.0)), + ('comment', models.CharField(max_length=128)), + ('date_create', models.DateTimeField(auto_now_add=True)), + ('date_pay', models.DateTimeField(blank=True, null=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('date_create',), + 'db_table': 'abonent_inv_pay', + }, + ), + migrations.AddField( + model_name='abon', + name='current_tariffs', + field=models.ManyToManyField(through='abonapp.AbonTariff', to='tariff_app.Tariff'), + ), + migrations.AddField( + model_name='abon', + name='group', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonGroup'), + ), + migrations.AlterUniqueTogether( + name='abontariff', + unique_together=set([('abon', 'tariff', 'tariff_priority')]), + ), + migrations.AddField( + model_name='abongroup', + name='profiles', + field=models.ManyToManyField(blank=True, related_name='abon_groups', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterModelOptions( + name='abon', + options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'),)}, + ), + migrations.AlterModelOptions( + name='abongroup', + options={'permissions': (('can_add_ballance', 'Пополнение счёта'),)}, + ), + migrations.AlterModelOptions( + name='abontariff', + options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Досрочное завершение услуги абонента'), ('can_activate_service', 'Активация услуги абонента'))}, + ), + migrations.CreateModel( + name='AbonStreet', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=64)), + ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.AbonGroup')), + ], + ), + migrations.RemoveField( + model_name='abon', + name='address', + ), + migrations.AddField( + model_name='abon', + name='description', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='abon', + name='house', + field=models.CharField(blank=True, max_length=12, null=True), + ), + migrations.AddField( + model_name='abon', + name='street', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonStreet'), + ), + migrations.CreateModel( + name='AllPayLog', + fields=[ + ('pay_id', models.CharField(max_length=64, primary_key=True, serialize=False)), + ('date_action', models.DateTimeField(auto_now_add=True)), + ('summ', models.FloatField(default=0.0)), + ('pay_system_name', models.CharField(max_length=16)), + ], + options={ + 'db_table': 'all_pay_log', + 'ordering': ('date_action',), + }, + ), + migrations.CreateModel( + name='AllTimePayLog', + fields=[ + ('pay_id', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)), + ('date_add', models.DateTimeField(auto_now_add=True)), + ('summ', models.FloatField(default=0.0)), + ], + options={ + 'db_table': 'all_time_pay_log', + 'ordering': ('date_add',), + }, + ), + migrations.CreateModel( + name='AbonRawPassword', + fields=[ + ('account', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='abonapp.Abon')), + ('passw_text', models.CharField(max_length=64)), + ], + options={ + 'db_table': 'abon_raw_password', + }, + ), + migrations.AlterModelTable( + name='abonstreet', + table='abon_street', + ), + migrations.AddField( + model_name='abontariff', + name='deadline', + field=models.DateTimeField(blank=True, default=None, null=True), + ), + migrations.CreateModel( + name='ExtraFieldsModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('field_type', models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой'), ('ipa', 'IP Адрес')], default='str', max_length=3)), + ('data', models.CharField(blank=True, max_length=64, null=True)), + ('title', models.CharField(default='no title', max_length=16)), + ], + options={ + 'db_table': 'abon_extra_fields', + }, + ), + migrations.AlterModelOptions( + name='abon', + options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Can view passport'))}, + ), + migrations.AlterModelOptions( + name='abontariff', + options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Снятие со счёта средств'), ('can_activate_service', 'Активация услуги абонента'))}, + ), + migrations.AlterField( + model_name='abon', + name='ballance', + field=models.FloatField(default=0.0), + ), + migrations.AlterModelOptions( + name='abon', + options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'))}, + ), + migrations.AddField( + model_name='abon', + name='extra_fields', + field=models.ManyToManyField(blank=True, to='abonapp.ExtraFieldsModel'), + ), + migrations.AddField( + model_name='abongroup', + name='tariffs', + field=models.ManyToManyField(blank=True, related_name='tariff_groups', to='tariff_app.Tariff'), + ), + migrations.CreateModel( + name='PassportInfo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('series', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])), + ('number', models.CharField(max_length=6, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])), + ('distributor', models.CharField(max_length=64)), + ('date_of_acceptance', models.DateField()), + ('abon', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.Abon')), + ], + ), + migrations.CreateModel( + name='AbonDevice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('abon', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('device', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')), + ], + options={ + 'db_table': 'abon_device', + }, + ), + migrations.AlterUniqueTogether( + name='abondevice', + unique_together=set([('abon', 'device')]), + ), + migrations.AlterField( + model_name='abondevice', + name='abon', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon'), + ), + migrations.AlterField( + model_name='abondevice', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device'), + ), + migrations.AddField( + model_name='abon', + name='ip_address', + field=mydefs.MyGenericIPAddressField(blank=True, max_length=8, null=True, protocol='ipv4'), + ), + migrations.AddField( + model_name='abon', + name='dev_port', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Port'), + ), + migrations.AddField( + model_name='abon', + name='device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), + ), + migrations.AddField( + model_name='abon', + name='is_dynamic_ip', + field=models.BooleanField(default=False), + ), + migrations.DeleteModel( + name='AbonDevice', + ), + migrations.AlterModelOptions( + name='abontariff', + options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),)}, + ), + migrations.RemoveField( + model_name='abon', + name='current_tariffs', + ), + migrations.AddField( + model_name='abon', + name='current_tariff', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonTariff'), + ), + migrations.AlterUniqueTogether( + name='abontariff', + unique_together=set([]), + ), + migrations.RemoveField( + model_name='abontariff', + name='abon', + ), + migrations.RemoveField( + model_name='abontariff', + name='tariff_priority', + ), + ] diff --git a/abonapp/migrations/0002_auto_20161206_2135.py b/abonapp/migrations/0002_auto_20161206_2135.py deleted file mode 100644 index a865928..0000000 --- a/abonapp/migrations/0002_auto_20161206_2135.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-12-06 18:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='abongroup', - name='address', - ), - migrations.AlterField( - model_name='abongroup', - name='title', - field=models.CharField(max_length=127, unique=True), - ), - ] diff --git a/abonapp/migrations/0002_auto_20170905_1248.py b/abonapp/migrations/0002_auto_20170905_1248.py new file mode 100644 index 0000000..75bbac0 --- /dev/null +++ b/abonapp/migrations/0002_auto_20170905_1248.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-05 12:48 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('abonapp', '0001_squashed_0022_auto_20170816_1109'), + ] + + operations = [ + migrations.CreateModel( + name='AdditionalTelephone', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('telephone', models.CharField(max_length=16, validators=[django.core.validators.RegexValidator('^\\+[7,8,9,3]\\d{10,11}$')], verbose_name='Телефон')), + ('owner_name', models.CharField(max_length=127)), + ], + options={ + 'verbose_name': 'Дополнительный телефон', + 'verbose_name_plural': 'Дополнительные телефоны', + 'db_table': 'additional_telephones', + 'ordering': ('owner_name',), + }, + ), + migrations.AlterModelOptions( + name='abon', + options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные')), 'verbose_name': 'Абонент', 'verbose_name_plural': 'Абоненты'}, + ), + migrations.AlterModelOptions( + name='abongroup', + options={'permissions': (('can_add_ballance', 'Пополнение счёта'),), 'verbose_name': 'Группа абонентов', 'verbose_name_plural': 'Группы абонентов'}, + ), + migrations.AlterModelOptions( + name='abonstreet', + options={'verbose_name': 'Улица', 'verbose_name_plural': 'Улицы'}, + ), + migrations.AlterModelOptions( + name='abontariff', + options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),), 'verbose_name': 'Услуга абонента', 'verbose_name_plural': 'Услуги абонентов'}, + ), + migrations.AddField( + model_name='additionaltelephone', + name='abon', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='additional_telephones', to='abonapp.Abon'), + ), + ] diff --git a/abonapp/migrations/0003_abongroup_profiles.py b/abonapp/migrations/0003_abongroup_profiles.py deleted file mode 100644 index f3b2d91..0000000 --- a/abonapp/migrations/0003_abongroup_profiles.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-12-16 19:14 -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('abonapp', '0002_auto_20161206_2135'), - ] - - operations = [ - migrations.AddField( - model_name='abongroup', - name='profiles', - field=models.ManyToManyField(related_name='abon_groups', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/abonapp/migrations/0003_auto_20170927_1838.py b/abonapp/migrations/0003_auto_20170927_1838.py new file mode 100644 index 0000000..f15a614 --- /dev/null +++ b/abonapp/migrations/0003_auto_20170927_1838.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-27 18:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('abonapp', '0002_auto_20170905_1248'), + ] + + operations = [ + migrations.AlterModelOptions( + name='abon', + options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'), ('can_add_ballance', 'Пополнение счёта'), ('can_ping', 'Может пинговать')), 'verbose_name': 'Абонент', 'verbose_name_plural': 'Абоненты'}, + ), + migrations.AlterModelOptions( + name='abongroup', + options={'permissions': (('can_view_abongroup', 'Может просматривать группу абонентов'),), 'verbose_name': 'Группа абонентов', 'verbose_name_plural': 'Группы абонентов'}, + ), + migrations.AlterModelOptions( + name='abonlog', + options={'permissions': (('can_view_abonlog', 'Может видеть логи абонента'),)}, + ), + migrations.AlterModelOptions( + name='additionaltelephone', + options={'ordering': ('owner_name',), 'permissions': (('can_view_additionaltelephones', 'Может видеть дополнительные телефоны'),), 'verbose_name': 'Дополнительный телефон', 'verbose_name_plural': 'Дополнительные телефоны'}, + ), + migrations.AlterModelOptions( + name='invoiceforpayment', + options={'ordering': ('date_create',), 'permissions': (('can_view_invoiceforpayment', 'Может видеть назначенные платежи'),), 'verbose_name': 'Квитанция (долг)', 'verbose_name_plural': 'Квитанции (долги)'}, + ), + migrations.AlterModelOptions( + name='passportinfo', + options={'verbose_name': 'Паспортные данные', 'verbose_name_plural': 'Паспортные данные'}, + ), + migrations.AlterModelTable( + name='passportinfo', + table='passport_info', + ), + ] diff --git a/abonapp/migrations/0004_auto_20161220_0102.py b/abonapp/migrations/0004_auto_20161220_0102.py deleted file mode 100644 index b19ca18..0000000 --- a/abonapp/migrations/0004_auto_20161220_0102.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-12-19 22:02 -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0003_abongroup_profiles'), - ] - - operations = [ - migrations.AlterField( - model_name='abongroup', - name='profiles', - field=models.ManyToManyField(blank=True, related_name='abon_groups', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/abonapp/migrations/0005_auto_20161226_0054.py b/abonapp/migrations/0005_auto_20161226_0054.py deleted file mode 100644 index 3b206ae..0000000 --- a/abonapp/migrations/0005_auto_20161226_0054.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-12-25 21:54 -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0004_auto_20161220_0102'), - ] - - operations = [ - migrations.AlterModelOptions( - name='abon', - options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'),)}, - ), - migrations.AlterModelOptions( - name='abongroup', - options={'permissions': (('can_add_ballance', 'Пополнение счёта'),)}, - ), - migrations.AlterModelOptions( - name='abontariff', - options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Досрочное завершение услуги абонента'), ('can_activate_service', 'Активация услуги абонента'))}, - ), - ] diff --git a/abonapp/migrations/0006_auto_20170128_1626.py b/abonapp/migrations/0006_auto_20170128_1626.py deleted file mode 100644 index 6274a5d..0000000 --- a/abonapp/migrations/0006_auto_20170128_1626.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-01-28 13:26 -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0005_auto_20161226_0054'), - ] - - operations = [ - migrations.CreateModel( - name='AbonStreets', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=64)), - ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.AbonGroup')), - ], - ), - migrations.RemoveField( - model_name='abon', - name='address', - ), - migrations.AddField( - model_name='abon', - name='description', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='abon', - name='house', - field=models.CharField(blank=True, max_length=12, null=True), - ), - migrations.AddField( - model_name='abon', - name='street', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonStreets'), - ), - ] diff --git a/abonapp/migrations/0007_auto_20170131_1650.py b/abonapp/migrations/0007_auto_20170131_1650.py deleted file mode 100644 index c1f4ae5..0000000 --- a/abonapp/migrations/0007_auto_20170131_1650.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-01-31 13:50 -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0006_auto_20170128_1626'), - ] - - operations = [ - migrations.CreateModel( - name='AllPayLog', - fields=[ - ('pay_id', models.CharField(max_length=64, primary_key=True, serialize=False)), - ('date_action', models.DateTimeField(auto_now_add=True)), - ('summ', models.FloatField(default=0.0)), - ('pay_system_name', models.CharField(max_length=16)), - ], - options={ - 'db_table': 'all_pay_log', - 'ordering': ('date_action',), - }, - ), - migrations.CreateModel( - name='AllTimePayLog', - fields=[ - ('pay_id', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)), - ('date_add', models.DateTimeField(auto_now_add=True)), - ('summ', models.FloatField(default=0.0)), - ], - options={ - 'db_table': 'all_time_pay_log', - 'ordering': ('date_add',), - }, - ), - migrations.RenameModel( - old_name='AbonStreets', - new_name='AbonStreet', - ), - ] diff --git a/abonapp/migrations/0008_auto_20170209_0002.py b/abonapp/migrations/0008_auto_20170209_0002.py deleted file mode 100644 index 8d24b5d..0000000 --- a/abonapp/migrations/0008_auto_20170209_0002.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-02-08 21:02 -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0007_auto_20170131_1650'), - ] - - operations = [ - migrations.CreateModel( - name='AbonRawPassword', - fields=[ - ('account', models.OneToOneField(primary_key=True, serialize=False, to='abonapp.Abon')), - ('passw_text', models.CharField(max_length=64)), - ], - options={ - 'db_table': 'abon_raw_password', - }, - ), - migrations.AlterModelTable( - name='abonstreet', - table='abon_street', - ), - ] diff --git a/abonapp/migrations/0009_abontariff_death_line.py b/abonapp/migrations/0009_abontariff_death_line.py deleted file mode 100644 index 1152d33..0000000 --- a/abonapp/migrations/0009_abontariff_death_line.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-02-16 12:22 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0008_auto_20170209_0002'), - ] - - operations = [ - migrations.AddField( - model_name='abontariff', - name='deadline', - field=models.DateTimeField(blank=True, default=None, null=True), - ), - ] diff --git a/abonapp/migrations/0010_auto_20170220_1630.py b/abonapp/migrations/0010_auto_20170220_1630.py deleted file mode 100644 index 69718b8..0000000 --- a/abonapp/migrations/0010_auto_20170220_1630.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-02-20 13:30 -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0009_abontariff_death_line'), - ] - - operations = [ - migrations.CreateModel( - name='ExtraFieldsModel', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('field_type', models.CharField(choices=[('int', 'Digital field'), ('str', 'Text field'), ('dbl', 'Floating field')], max_length=3)), - ('data', models.CharField(blank=True, max_length=64, null=True)), - ], - options={ - 'db_table': 'abon_extra_fields', - }, - ), - migrations.AlterModelOptions( - name='abon', - options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Can view passport'))}, - ), - migrations.AlterModelOptions( - name='abontariff', - options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Снятие со счёта средств'), ('can_activate_service', 'Активация услуги абонента'))}, - ), - migrations.AlterField( - model_name='abon', - name='ballance', - field=models.FloatField(default=0.0), - ), - migrations.AddField( - model_name='extrafieldsmodel', - name='account', - field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='abonapp.Abon'), - ), - ] diff --git a/abonapp/migrations/0011_auto_20170222_2224.py b/abonapp/migrations/0011_auto_20170222_2224.py deleted file mode 100644 index d197189..0000000 --- a/abonapp/migrations/0011_auto_20170222_2224.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- 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), - ), - ] diff --git a/abonapp/migrations/0012_auto_20170227_1718.py b/abonapp/migrations/0012_auto_20170227_1718.py deleted file mode 100644 index 63a66de..0000000 --- a/abonapp/migrations/0012_auto_20170227_1718.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-03-02 18:41 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0011_auto_20170222_2224'), - ] - - operations = [ - migrations.RemoveField( - model_name='extrafieldsmodel', - name='account', - ), - migrations.AddField( - model_name='abon', - name='extra_fields', - field=models.ManyToManyField(to='abonapp.ExtraFieldsModel'), - ), - ] diff --git a/abonapp/migrations/0013_abongroup_tariffs.py b/abonapp/migrations/0013_abongroup_tariffs.py deleted file mode 100644 index b67ffbd..0000000 --- a/abonapp/migrations/0013_abongroup_tariffs.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-03-21 11:30 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('tariff_app', '0002_tariff_descr'), - ('abonapp', '0012_auto_20170227_1718'), - ] - - operations = [ - migrations.AddField( - model_name='abongroup', - name='tariffs', - field=models.ManyToManyField(blank=True, related_name='tariff_groups', to='tariff_app.Tariff'), - ), - ] diff --git a/abonapp/migrations/0014_auto_20170330_1452.py b/abonapp/migrations/0014_auto_20170330_1452.py deleted file mode 100644 index c0985ab..0000000 --- a/abonapp/migrations/0014_auto_20170330_1452.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-03-30 11:52 -from __future__ import unicode_literals - -import django.db.models.deletion -import djing.fields -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0013_abongroup_tariffs'), - ] - - operations = [ - migrations.CreateModel( - name='Opt82', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('mac', djing.fields.MACAddressField(integer=True)), - ('port', models.PositiveSmallIntegerField(default=0)), - ], - options={ - 'db_table': 'opt_82', - }, - ), - migrations.AlterField( - model_name='abon', - name='extra_fields', - field=models.ManyToManyField(blank=True, to='abonapp.ExtraFieldsModel'), - ), - migrations.AlterUniqueTogether( - name='opt82', - unique_together=set([('mac', 'port')]), - ), - migrations.AddField( - model_name='abon', - name='opt82', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='abonapp.Opt82'), - ), - ] diff --git a/abonapp/migrations/0015_passportinfo.py b/abonapp/migrations/0015_passportinfo.py deleted file mode 100644 index 5207173..0000000 --- a/abonapp/migrations/0015_passportinfo.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-04-11 10:43 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import re - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0014_auto_20170330_1452'), - ] - - operations = [ - migrations.CreateModel( - name='PassportInfo', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('series', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])), - ('number', models.CharField(max_length=6, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])), - ('distributor', models.CharField(max_length=64)), - ('date_of_acceptance', models.DateField()), - ('abon', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.Abon')), - ], - ), - migrations.AlterField( - model_name='abon', - name='opt82', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, - to='abonapp.Opt82'), - ) - ] diff --git a/abonapp/migrations/0016_auto_20170415_1311.py b/abonapp/migrations/0016_auto_20170415_1311.py deleted file mode 100644 index 4070341..0000000 --- a/abonapp/migrations/0016_auto_20170415_1311.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-04-15 10:11 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0004_device_user_group'), - ('abonapp', '0015_passportinfo'), - ] - - operations = [ - migrations.CreateModel( - name='AbonDevice', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('abon', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), - ('device', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')), - ], - options={ - 'db_table': 'abon_device', - }, - ), - migrations.AlterUniqueTogether( - name='abondevice', - unique_together=set([('abon', 'device')]), - ), - ] diff --git a/abonapp/migrations/0017_auto_20170416_1029.py b/abonapp/migrations/0017_auto_20170416_1029.py deleted file mode 100644 index fb70627..0000000 --- a/abonapp/migrations/0017_auto_20170416_1029.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-04-16 07:29 -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 = [ - ('abonapp', '0016_auto_20170415_1311'), - ] - - operations = [ - migrations.AlterField( - model_name='invoiceforpayment', - name='author', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/abonapp/migrations/0018_auto_20170418_1236.py b/abonapp/migrations/0018_auto_20170418_1236.py deleted file mode 100644 index 175a62b..0000000 --- a/abonapp/migrations/0018_auto_20170418_1236.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-04-18 09:36 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0017_auto_20170416_1029'), - ] - - operations = [ - migrations.AlterField( - model_name='abondevice', - name='abon', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon'), - ), - migrations.AlterField( - model_name='abondevice', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device'), - ), - ] diff --git a/abonapp/migrations/0019_abon_ip_address.py b/abonapp/migrations/0019_abon_ip_address.py deleted file mode 100644 index 96c2613..0000000 --- a/abonapp/migrations/0019_abon_ip_address.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-05-10 23:17 -from __future__ import unicode_literals - -from django.db import migrations -import mydefs - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0018_auto_20170418_1236'), - ] - - operations = [ - migrations.AddField( - model_name='abon', - name='ip_address', - field=mydefs.MyGenericIPAddressField(blank=True, max_length=8, null=True, protocol='ipv4'), - ), - ] diff --git a/abonapp/migrations/0020_auto_20170517_1655.py b/abonapp/migrations/0020_auto_20170517_1655.py deleted file mode 100644 index edcf585..0000000 --- a/abonapp/migrations/0020_auto_20170517_1655.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-05-17 13:55 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0019_abon_ip_address'), - ] - - operations = [ - migrations.AddField( - model_name='extrafieldsmodel', - name='title', - field=models.CharField(default='no title', max_length=16), - ), - migrations.AlterField( - model_name='extrafieldsmodel', - name='field_type', - field=models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой'), ('ipa', 'IP Адрес')], default='str', max_length=3), - ), - ] diff --git a/abonapp/migrations/0021_auto_20170705_1403.py b/abonapp/migrations/0021_auto_20170705_1403.py deleted file mode 100644 index 16a2a15..0000000 --- a/abonapp/migrations/0021_auto_20170705_1403.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-07-05 14:03 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0006_auto_20170705_1403'), - ('abonapp', '0020_auto_20170517_1655'), - ] - - operations = [ - migrations.RemoveField( - model_name='abon', - name='opt82', - ), - migrations.DeleteModel( - name='Opt82', - ), - migrations.AddField( - model_name='abon', - name='dev_port', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Port'), - ), - migrations.AddField( - model_name='abon', - name='device', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), - ), - migrations.AddField( - model_name='abon', - name='is_dynamic_ip', - field=models.BooleanField(default=False), - ), - migrations.DeleteModel( - name='AbonDevice', - ), - ] diff --git a/abonapp/migrations/0022_auto_20170816_1109.py b/abonapp/migrations/0022_auto_20170816_1109.py deleted file mode 100644 index d514365..0000000 --- a/abonapp/migrations/0022_auto_20170816_1109.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-08-16 11:09 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('abonapp', '0021_auto_20170705_1403'), - ] - - operations = [ - migrations.AlterModelOptions( - name='abontariff', - options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),)}, - ), - migrations.RemoveField( - model_name='abon', - name='current_tariffs', - ), - migrations.AddField( - model_name='abon', - name='current_tariff', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonTariff'), - ), - migrations.AlterUniqueTogether( - name='abontariff', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='abontariff', - name='abon', - ), - migrations.RemoveField( - model_name='abontariff', - name='tariff_priority', - ), - ] diff --git a/abonapp/models.py b/abonapp/models.py index ce737ea..212ae5c 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -1,14 +1,20 @@ # -*- coding: utf-8 -*- from django.core.exceptions import ValidationError +from django.core.validators import RegexValidator +from django.db.models.signals import post_save, post_delete, pre_delete, post_init +from django.dispatch import receiver from django.utils import timezone from django.db import models from django.core import validators from django.utils.translation import ugettext as _ from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError from tariff_app.models import Tariff -from accounts_app.models import UserProfile +from accounts_app.models import UserProfile, MyUserManager from mydefs import MyGenericIPAddressField, ip2int, LogicError, ip_addr_regex -from djing import settings +from django.conf import settings + + +TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$') class AbonGroup(models.Model): @@ -19,8 +25,10 @@ class AbonGroup(models.Model): class Meta: db_table = 'abonent_groups' permissions = ( - ('can_add_ballance', _('fill account')), + ('can_view_abongroup', _('Can view subscriber group')), ) + verbose_name = _('Abon group') + verbose_name_plural = _('Abon groups') def __str__(self): return self.title @@ -35,6 +43,9 @@ class AbonLog(models.Model): class Meta: db_table = 'abonent_log' + permissions = ( + ('can_view_abonlog', _('Can view subscriber logs')), + ) def __str__(self): return self.comment @@ -68,6 +79,8 @@ class AbonTariff(models.Model): permissions = ( ('can_complete_service', _('finish service perm')), ) + verbose_name = _('Abon service') + verbose_name_plural = _('Abon services') class AbonStreet(models.Model): @@ -79,6 +92,8 @@ class AbonStreet(models.Model): class Meta: db_table = 'abon_street' + verbose_name = _('Street') + verbose_name_plural = _('Streets') class ExtraFieldsModel(models.Model): @@ -123,6 +138,13 @@ class ExtraFieldsModel(models.Model): db_table = 'abon_extra_fields' + +class AbonManager(MyUserManager): + + def get_queryset(self): + return super(MyUserManager, self).get_queryset().filter(is_admin=False) + + class Abon(UserProfile): current_tariff = models.ForeignKey(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL) group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True) @@ -140,12 +162,18 @@ class Abon(UserProfile): def active_tariff(self): return self.current_tariff + objects = AbonManager() + class Meta: db_table = 'abonent' permissions = ( ('can_buy_tariff', _('Buy service perm')), - ('can_view_passport', _('Can view passport')) + ('can_view_passport', _('Can view passport')), + ('can_add_ballance', _('fill account')), + ('can_ping', _('Can ping')) ) + verbose_name = _('Abon') + verbose_name_plural = _('Abons') # Платим за что-то def make_pay(self, curuser, how_match_to_pay=0.0): @@ -203,6 +231,8 @@ class Abon(UserProfile): # Производим расчёт услуги абонента, т.е. завершаем если пришло время def bill_service(self, author): abon_tariff = self.active_tariff() + if abon_tariff is None: + return nw = timezone.now() # если услуга просрочена if nw > abon_tariff.deadline: @@ -226,7 +256,7 @@ class Abon(UserProfile): return abon_tariff = self.active_tariff() if abon_tariff is None: - agent_trf = TariffStruct() + agent_trf = None else: trf = abon_tariff.tariff agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut) @@ -247,7 +277,12 @@ class PassportInfo(models.Model): date_of_acceptance = models.DateField() abon = models.OneToOneField(Abon, on_delete=models.SET_NULL, blank=True, null=True) - def __unicode__(self): + class Meta: + db_table = 'passport_info' + verbose_name = _('Passport Info') + verbose_name_plural = _('Passport Info') + + def __str__(self): return "%s %s" % (self.series, self.number) @@ -273,6 +308,11 @@ class InvoiceForPayment(models.Model): class Meta: ordering = ('date_create',) db_table = 'abonent_inv_pay' + permissions = ( + ('can_view_invoiceforpayment', _('Can view invoice for payment')), + ) + verbose_name = _('Debt') + verbose_name_plural = _('Debts') # Log for pay system "AllTime" @@ -315,7 +355,32 @@ class AbonRawPassword(models.Model): db_table = 'abon_raw_password' -def abon_post_save(sender, instance, **kwargs): +class AdditionalTelephone(models.Model): + abon = models.ForeignKey(Abon, related_name='additional_telephones') + telephone = models.CharField( + max_length=16, + verbose_name=_('Telephone'), + # unique=True, + validators=[RegexValidator(TELEPHONE_REGEXP)] + ) + owner_name = models.CharField(max_length=127) + + def __str__(self): + return "%s - (%s)" % (self.owner_name, self.telephone) + + class Meta: + db_table = 'additional_telephones' + ordering = ('owner_name',) + permissions = ( + ('can_view_additionaltelephones', _('Can view additional telephones')), + ) + verbose_name = _('Additional telephone') + verbose_name_plural = _('Additional telephones') + + +@receiver(post_save, sender=Abon) +def abon_post_save(sender, **kwargs): + instance, created = kwargs["instance"], kwargs["created"] timeout = None if hasattr(instance, 'is_dhcp') and instance.is_dhcp: timeout = getattr(settings, 'DHCP_TIMEOUT', 14400) @@ -324,21 +389,23 @@ def abon_post_save(sender, instance, **kwargs): return True try: tm = Transmitter() - if kwargs['created']: + if created: # создаём абонента tm.add_user(agent_abon, ip_timeout=timeout) else: # обновляем абонента на NAS tm.update_user(agent_abon, ip_timeout=timeout) - except (NasFailedResult, NasNetworkError) as e: + except (NasFailedResult, NasNetworkError, ConnectionResetError) as e: print('ERROR:', e) return True -def abon_del_signal(sender, instance, **kwargs): +@receiver(post_delete, sender=Abon) +def abon_del_signal(sender, **kwargs): + abon = kwargs["instance"] try: - ab = instance.build_agent_struct() + ab = abon.build_agent_struct() if ab is None: return True # подключаемся к NAS'у @@ -349,14 +416,28 @@ def abon_del_signal(sender, instance, **kwargs): return True -def abon_tariff_post_init(sender, instance, **kwargs): - if getattr(instance, 'time_start') is None: - instance.time_start = timezone.now() - calc_obj = instance.tariff.get_calc_type()(instance) - if getattr(instance, 'deadline') is None: - instance.deadline = calc_obj.calc_deadline() +@receiver(post_init, sender=AbonTariff) +def abon_tariff_post_init(sender, **kwargs): + abon_tariff = kwargs["instance"] + if getattr(abon_tariff, 'time_start') is None: + abon_tariff.time_start = timezone.now() + calc_obj = abon_tariff.tariff.get_calc_type()(abon_tariff) + if getattr(abon_tariff, 'deadline') is None: + abon_tariff.deadline = calc_obj.calc_deadline() -models.signals.post_save.connect(abon_post_save, sender=Abon) -models.signals.post_delete.connect(abon_del_signal, sender=Abon) -models.signals.post_init.connect(abon_tariff_post_init, sender=AbonTariff) +@receiver(pre_delete, sender=AbonTariff) +def abontariff_pre_delete(sender, **kwargs): + abon_tariff = kwargs["instance"] + try: + abon = Abon.objects.get(current_tariff=abon_tariff) + ab = abon.build_agent_struct() + if ab is None: + return True + tm = Transmitter() + tm.remove_user(ab) + except Abon.DoesNotExist: + print('ERROR: Abon.DoesNotExist') + except (NasFailedResult, NasNetworkError, ConnectionResetError) as e: + print('NetErr:', e) + return True diff --git a/abonapp/pay_systems.py b/abonapp/pay_systems.py index c159507..cd7bccb 100644 --- a/abonapp/pay_systems.py +++ b/abonapp/pay_systems.py @@ -6,8 +6,8 @@ from django.db import DatabaseError from django.conf import settings -SECRET = getattr(settings, 'pay_SECRET') -SERV_ID = getattr(settings, 'pay_SERV_ID') +SECRET = getattr(settings, 'PAY_SECRET') +SERV_ID = getattr(settings, 'PAY_SERV_ID') #?ACT=1&PAY_ACCOUNT=960849&SERVICE_ID=y832r92y8f9e&PAY_ID=3561234&TRADE_POINT=377&SIGN=32e533a72389fe4e93746509f9d672f8 diff --git a/abonapp/templates/abonapp/complete_service.html b/abonapp/templates/abonapp/complete_service.html deleted file mode 100644 index d0939a2..0000000 --- a/abonapp/templates/abonapp/complete_service.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends request.is_ajax|yesno:'bajax.html,base.html' %} -{% load i18n %} -{% block main %} - - - - {% include 'message_block.html' %} - -
-
-

{% trans 'Finish service' %}

-
-
- -
{% csrf_token %} - - -

- {% blocktrans %}Early completion of the current service will cause that user will be denied access to services Resources (Net closes) -To continue to use the resources necessary to connect the required service{% endblocktrans %} -

- -

{% blocktrans %}Details:
-You complete tariff{% endblocktrans %} - - {% if perms.tariff_app.change_tariff %} - {{ abtar.tariff.title }}.
- {% else %} - {{ abtar.tariff.title }}.
- {% endif %} - - {% now "d F Y, H: i: s" as today %} - {% blocktrans with time_start=abtar.time_start|date:'d F Y, H: i: s' amount=abtar.tariff.amount %}The service has been connected: {{ time_start }}
-Today: {{ today }}
-Time of use: {{ time_use }}
-The total cost of the service: {{ amount }}
-Total cost: {{ tcost }}
-Cashback: {{ cashback }}{% endblocktrans %} -

- -
- -
- -
- -
-
- -{% endblock %} \ No newline at end of file diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index e5883ae..5e93ebd 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -1,5 +1,6 @@ {% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} {% load i18n %} +{% load guardian_tags %} {% block content %}
@@ -31,9 +32,15 @@
{{ form.telephone }}{{ form.telephone.errors }} - + + + + + + +
@@ -102,9 +109,6 @@ - {% if perms.taskapp.add_task %} {% trans 'Add new task' %} @@ -113,7 +117,7 @@ - {% if ip %} + {% if ip and perms.abonapp.can_ping %}
@@ -128,6 +132,7 @@
+ {% if perms.abonapp.change_abon %}
+ {% endif %} + {% if perms.abonapp.add_extrafieldsmodel %}

{% trans 'Extra fields' %}

@@ -236,6 +243,7 @@
+ {% endif %}
diff --git a/abonapp/templates/abonapp/group_list.html b/abonapp/templates/abonapp/group_list.html index 59fb7ed..00362e7 100644 --- a/abonapp/templates/abonapp/group_list.html +++ b/abonapp/templates/abonapp/group_list.html @@ -38,7 +38,7 @@ {% if perms.abonapp.delete_abongroup %} {% if gr.usercount == 0 %} - + {% endif %} @@ -63,12 +63,16 @@ {% trans 'Add group' %} {% endif %} + {% if perms.abonapp.can_view_abonlog %} {% trans 'Subscribers actions' %} + {% endif %} + {% if perms.abonapp.can_view_invoiceforpayment %} {% trans 'List of debtors' %} + {% endif %} @@ -77,4 +81,4 @@ {% include 'toolbar_page.html' with pag=groups %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/abonapp/templates/abonapp/modal_add_phone.html b/abonapp/templates/abonapp/modal_add_phone.html new file mode 100644 index 0000000..1ca2916 --- /dev/null +++ b/abonapp/templates/abonapp/modal_add_phone.html @@ -0,0 +1,35 @@ +{% load i18n %} +
{% csrf_token %} + + + + +
diff --git a/abonapp/templates/abonapp/modal_additional_telephones.html b/abonapp/templates/abonapp/modal_additional_telephones.html new file mode 100644 index 0000000..5782e6b --- /dev/null +++ b/abonapp/templates/abonapp/modal_additional_telephones.html @@ -0,0 +1,37 @@ +{% load i18n %} + + + + diff --git a/abonapp/templates/abonapp/payHistory.html b/abonapp/templates/abonapp/payHistory.html index f81a128..fc55b95 100644 --- a/abonapp/templates/abonapp/payHistory.html +++ b/abonapp/templates/abonapp/payHistory.html @@ -1,5 +1,6 @@ {% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} {% load i18n %} +{% load guardian_tags %} {% block content %} @@ -31,11 +32,15 @@ @@ -45,4 +50,4 @@
{% if perms.abonapp.can_add_ballance %} - - {% trans 'Fill account' %} - + + {% trans 'Fill account' %} + + {% else %} + + {% trans 'Fill account' %} + {% endif %} - + {% trans 'Debts' %}
{% include 'toolbar_page.html' with pag=pay_history %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 905ea2e..eeadaae 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -1,5 +1,6 @@ {% extends 'base.html' %} {% load i18n %} +{% load dpagination %} {% block main %} @@ -20,32 +21,32 @@ # - + {% trans 'Sub' %} {% if order_by == 'username' %}{% endif %} {% trans 'Last traffic' %} - + {% trans 'Ip address' %} {% if order_by == 'ip_address' %}{% endif %} - + {% trans 'fio' %} {% if order_by == 'fio' %}{% endif %} - + {% trans 'Street' %} {% if order_by == 'street' %}{% endif %} - + {% trans 'Apartment' %} {% if order_by == 'house' %}{% endif %} @@ -53,7 +54,7 @@ {% trans 'Telephone' %} {% trans 'Service' %} - + {% trans 'Ballance' %} {% if order_by == 'ballance' %}{% endif %} @@ -104,7 +105,7 @@ {{ human.ballance }} {% if can_del_trf %} - + {% endif %} @@ -126,14 +127,11 @@ {% if perms.abonapp.add_abon %} - + {% trans 'Add abon' %} {% endif %} - - {% trans 'Refresh subscribers on NAS' %} - - + {% trans 'Tariffs in groups' %} @@ -147,7 +145,7 @@
{% trans 'Streets' %}
{% for street in streets %} - {{ street.name }} + {{ street.name }} {% empty %} {% trans 'No streets found for that group' %} {% endfor %} diff --git a/abonapp/templates/abonapp/viewAbon.html b/abonapp/templates/abonapp/viewAbon.html index 914b7e9..b05df1a 100644 --- a/abonapp/templates/abonapp/viewAbon.html +++ b/abonapp/templates/abonapp/viewAbon.html @@ -61,6 +61,7 @@
+ {% if perms.abonapp.can_view_passport %}
@@ -86,6 +87,7 @@
+ {% endif %} {% endblock %} \ No newline at end of file diff --git a/abonapp/templatetags/dpagination.py b/abonapp/templatetags/dpagination.py index 582009b..e8232c7 100644 --- a/abonapp/templatetags/dpagination.py +++ b/abonapp/templatetags/dpagination.py @@ -8,3 +8,11 @@ def url_page_replace(request, field, value): dict_ = request.GET.copy() dict_[field] = value return dict_.urlencode() + + +@register.simple_tag +def url_replace(request, *args, **kwargs): + dict_ = request.GET.copy() + for k, v in kwargs.items(): + dict_[k] = v + return dict_.urlencode() diff --git a/abonapp/urls.py b/abonapp/urls.py index 3aa6686..048f525 100644 --- a/abonapp/urls.py +++ b/abonapp/urls.py @@ -13,7 +13,7 @@ urlpatterns = [ url(r'^log$', views.log_page, name='log'), - url(r'^del$', views.delentity, name='del_abon'), + url(r'^del$', views.del_abon, name='del_abon'), url(r'^pay$', views.terminal_pay, name='terminal_pay'), @@ -21,8 +21,6 @@ urlpatterns = [ url(r'^ping$', views.abon_ping, name='ping'), - url(r'^refresh_group_nas(?P\d+)$', views.update_nas, name='update_nas'), - # Api's url(r'^api/abons$', views.abons), url(r'^api/abon_filter$', views.search_abon) diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index 2922a6b..d37a86c 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -19,7 +19,6 @@ urlpatterns = [ url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='add_invoice'), url(r'^(?P\d+)/pick$', views.pick_tariff, name='pick_tariff'), url(r'^(?P\d+)/passport_view$', views.passport_view, name='passport_view'), - url(r'^(?P\d+)/complete_service(?P\d+)$', views.complete_service, name='compl_srv'), url(r'^(?P\d+)/chart$', views.charts, name='charts'), url(r'^(?P\d+)/dials$', views.dials, name='dials'), url(r'^(?P\d+)/extra_field$', views.make_extra_field, name='extra_field'), @@ -33,5 +32,9 @@ urlpatterns = [ url(r'^(?P\d+)/clear_dev/$', views.clear_dev, name='clear_dev'), url(r'^(?P\d+)/task_log$', views.task_log, name='task_log'), - url(r'^(?P\d+)/user_dev$', views.save_user_dev_port, name='save_user_dev_port') + url(r'^(?P\d+)/user_dev$', views.save_user_dev_port, name='save_user_dev_port'), + + url(r'^(?P\d+)/tel$', views.tels, name='telephones'), + url(r'^(?P\d+)/tel/add$', views.tel_add, name='telephone_new'), + url(r'^(?P\d+)/tel/del$', views.tel_del, name='telephone_del') ] diff --git a/abonapp/views.py b/abonapp/views.py index b47f23d..e8846ac 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -6,8 +6,7 @@ from django.db import IntegrityError, ProgrammingError from django.db.models import Count, Q from django.db.transaction import atomic from django.shortcuts import render, redirect, get_object_or_404, resolve_url -from django.contrib.auth.decorators import login_required, permission_required -from django.utils import timezone +from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.contrib import messages from django.utils.translation import ugettext_lazy as _ @@ -23,17 +22,22 @@ from datetime import datetime, date from taskapp.models import Task from dialing_app.models import AsteriskCDR from statistics.models import getModel, get_dates +from guardian.shortcuts import get_objects_for_user, assign_perm +from guardian.decorators import permission_required_or_403 as permission_required @login_required @mydefs.only_admins def peoples(request, gid): + abon_group = get_object_or_404(models.AbonGroup, pk=gid) + if not request.user.has_perm('abonapp.can_view_abongroup', abon_group): + raise PermissionDenied street_id = mydefs.safe_int(request.GET.get('street')) peoples_list = models.Abon.objects.select_related('group', 'street') if street_id > 0: - peoples_list = peoples_list.filter(group=gid, street=street_id) + peoples_list = peoples_list.filter(group=abon_group, street=street_id) else: - peoples_list = peoples_list.filter(group=gid) + peoples_list = peoples_list.filter(group=abon_group) # фильтр dr, field = mydefs.order_helper(request) @@ -72,7 +76,10 @@ def addgroup(request): if request.method == 'POST': frm = forms.AbonGroupForm(request.POST) if frm.is_valid(): - frm.save() + grp = frm.save() + assign_perm('abonapp.can_view_abongroup', request.user, grp) + assign_perm('abonapp.delete_abongroup', request.user, grp) + assign_perm('abonapp.change_abongroup', request.user, grp) messages.success(request, _('create group success msg')) return redirect('abonapp:group_list') else: @@ -91,6 +98,7 @@ def addgroup(request): @mydefs.only_admins def grouplist(request): groups = models.AbonGroup.objects.annotate(usercount=Count('abon')).order_by('title') + groups = get_objects_for_user(request.user, 'abonapp.can_view_abongroup', klass=groups, accept_global_perms=False) # фильтр directory, field = mydefs.order_helper(request) @@ -107,11 +115,13 @@ def grouplist(request): @login_required -@permission_required('abonapp.delete_abongroup') def delgroup(request): try: agd = mydefs.safe_int(request.GET.get('id')) - get_object_or_404(models.AbonGroup, pk=agd).delete() + abon_group = models.AbonGroup.objects.get(pk=agd) + if not request.user.has_perm('abonapp.delete_abongroup', abon_group): + raise PermissionDenied + abon_group.delete() messages.success(request, _('delete group success msg')) return mydefs.res_success(request, 'abonapp:group_list') except (NasFailedResult, NasNetworkError) as e: @@ -119,6 +129,8 @@ def delgroup(request): except mydefs.MultipleException as errs: for err in errs.err_list: messages.add_message(request, messages.constants.ERROR, err) + except models.AbonGroup.DoesNotExist: + return mydefs.res_error(request, 'Group with id=%d does not exist' % agd) return mydefs.res_error(request, 'abonapp:group_list') @@ -129,10 +141,17 @@ def addabon(request, gid): group = None try: group = get_object_or_404(models.AbonGroup, pk=gid) + if not request.user.has_perm('abonapp.can_view_abongroup', group): + raise PermissionDenied if request.method == 'POST': frm = forms.AbonForm(request.POST, initial={'group': group}) if frm.is_valid(): abon = frm.save() + assign_perm("abonapp.change_abon", request.user, abon) + assign_perm("abonapp.delete_abon", request.user, abon) + assign_perm("abonapp.can_buy_tariff", request.user, abon) + assign_perm("abonapp.can_view_passport", request.user, abon) + assign_perm('abonapp.can_add_ballance', request.user, abon) messages.success(request, _('create abon success msg')) return redirect('abonapp:abon_home', group.id, abon.pk) else: @@ -159,26 +178,18 @@ def addabon(request, gid): @login_required @mydefs.only_admins -def delentity(request): - typ = request.GET.get('t') +def del_abon(request): uid = request.GET.get('id') try: - if typ == 'a': - if not request.user.has_perm('abonapp.delete_abon'): - raise PermissionDenied - abon = get_object_or_404(models.Abon, pk=uid) - gid = abon.group.id - abon.delete() - messages.success(request, _('delete abon success msg')) - return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid)) - elif typ == 'g': - if not request.user.has_perm('abonapp.delete_abongroup'): - raise PermissionDenied - get_object_or_404(models.AbonGroup, pk=uid).delete() - messages.success(request, _('delete group success msg')) - return mydefs.res_success(request, 'abonapp:group_list') - else: - messages.warning(request, _('I not know what to delete')) + abon = get_object_or_404(models.Abon, pk=uid) + if not request.user.has_perm('abonapp.delete_abon') or not request.user.has_perm( + 'abonapp.can_view_abongroup', abon.group): + raise PermissionDenied + gid = abon.group.id + abon.delete() + messages.success(request, _('delete abon success msg')) + return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid)) + except NasNetworkError as e: messages.error(request, e) except NasFailedResult as e: @@ -218,6 +229,7 @@ def abonamount(request, gid, uid): @login_required @mydefs.only_admins +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def invoice_for_payment(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) invoices = models.InvoiceForPayment.objects.filter(abon=abon) @@ -231,6 +243,7 @@ def invoice_for_payment(request, gid, uid): @login_required @mydefs.only_admins +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def pay_history(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) pay_history = models.AbonLog.objects.filter(abon=abon).order_by('-id') @@ -246,6 +259,8 @@ def pay_history(request, gid, uid): @mydefs.only_admins def abon_services(request, gid, uid): grp = get_object_or_404(models.AbonGroup, pk=gid) + if not request.user.has_perm('abonapp.can_view_abongroup', grp): + raise PermissionDenied abon = get_object_or_404(models.Abon, pk=uid) return render(request, 'abonapp/service.html', { @@ -261,6 +276,8 @@ def abon_services(request, gid, uid): def abonhome(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) abon_group = get_object_or_404(models.AbonGroup, pk=gid) + if not request.user.has_perm('abonapp.can_view_abongroup', abon_group): + raise PermissionDenied frm = None passw = None try: @@ -394,71 +411,13 @@ def pick_tariff(request, gid, uid): }) -@login_required -@permission_required('abonapp.can_complete_service') -@atomic -def complete_service(request, gid, uid, srvid): - abtar = get_object_or_404(models.AbonTariff, pk=srvid) - abon = abtar.abon - # считаем не использованные ресурсы - calc_obj = abtar.tariff.get_calc_type()(abtar) - # получаем сколько использовано - res_amount = calc_obj.calc_amount() - cashback = abtar.tariff.amount - res_amount - - if abtar.abon.group is None: - abon.group = get_object_or_404(models.AbonGroup, pk=gid) - abon.save(update_fields=['group']) - if int(abtar.abon.pk) != int(uid) or int(abtar.abon.group.pk) != int(gid): - # если что-то написали в урле вручную, то вернём на путь истинный - return redirect('abonapp:compl_srv', gid=abtar.abon.group.pk, uid=abtar.abon.pk, srvid=srvid) - time_use = None - try: - if request.method == 'POST': - # досрочно завершаем услугу - if request.POST.get('finish_confirm') == 'yes': - if cashback > 0.5: - # возвращаем деньги, которые абонент не использовал - abon.add_ballance( - request.user, - cashback, - _('Refunds for unused resources') - ) - abon.save(update_fields=['ballance']) - - # удаляем запись о текущей услуге. - abtar.delete() - messages.success(request, _('Service has been finished successfully')) - return redirect('abonapp:abon_services', gid, uid) - else: - raise mydefs.LogicError(_('Not confirmed')) - - time_use = mydefs.RuTimedelta(timezone.now() - abtar.time_start) - - except (mydefs.LogicError, NasFailedResult) as e: - messages.error(request, e) - except NasNetworkError as e: - messages.warning(request, e) - return redirect('abonapp:abon_home', gid, uid) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - - return render(request, 'abonapp/complete_service.html', { - 'abtar': abtar, - 'abon': abon, - 'time_use': time_use, - 'abon_group': get_object_or_404(models.AbonGroup, pk=gid), - 'tcost': round(res_amount, 4), - 'cashback': round(cashback, 4) - }) - - @login_required @permission_required('abonapp.delete_abontariff') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def unsubscribe_service(request, gid, uid, abon_tariff_id): try: - get_object_or_404(models.AbonTariff, pk=int(abon_tariff_id)).delete() + abon_tariff = get_object_or_404(models.AbonTariff, pk=int(abon_tariff_id)) + abon_tariff.delete() messages.success(request, _('User has been detached from service')) except NasFailedResult as e: messages.error(request, e) @@ -471,7 +430,7 @@ def unsubscribe_service(request, gid, uid, abon_tariff_id): @login_required -@mydefs.only_admins +@permission_required('abonapp.can_view_abonlog') def log_page(request): logs = models.AbonLog.objects.all() logs = mydefs.pag_mn(request, logs) @@ -481,42 +440,17 @@ def log_page(request): @login_required -@mydefs.only_admins +@permission_required('abonapp.can_view_invoiceforpayment') def debtors(request): - # peoples_list = models.Abon.objects.filter(invoiceforpayment__status=True) - # peoples_list = mydefs.pag_mn(request, peoples_list) invs = models.InvoiceForPayment.objects.filter(status=True) invs = mydefs.pag_mn(request, invs) return render(request, 'abonapp/debtors.html', { - # 'peoples': peoples_list 'invoices': invs }) @login_required -@mydefs.only_admins -def update_nas(request, group_id): - users = models.Abon.objects.filter(group=group_id) - try: - tm = Transmitter() - for usr in users: - if not usr.ip_address: - continue - agent_abon = usr.build_agent_struct() - if agent_abon is not None: - tm.update_user(agent_abon) - except NasFailedResult as e: - messages.error(request, e) - except NasNetworkError as e: - messages.warning(request, e) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - return redirect('abonapp:people_list', gid=group_id) - - -@login_required -@mydefs.only_admins +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def task_log(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) tasks = Task.objects.filter(abon=abon) @@ -528,7 +462,7 @@ def task_log(request, gid, uid): @login_required -@mydefs.only_admins +@permission_required('abonapp.can_view_passport') def passport_view(request, gid, uid): try: abon = models.Abon.objects.get(pk=uid) @@ -566,6 +500,8 @@ def passport_view(request, gid, uid): @mydefs.only_admins def chgroup_tariff(request, gid): grp = get_object_or_404(models.AbonGroup, pk=gid) + if not request.user.has_perm('abonapp.change_abongroup', grp): + raise PermissionDenied if request.method == 'POST': tr = request.POST.getlist('tr') grp.tariffs.clear() @@ -579,7 +515,7 @@ def chgroup_tariff(request, gid): @login_required -@mydefs.only_admins +@permission_required('abonapp.change_abon') def dev(request, gid, uid): abon_dev = None try: @@ -605,7 +541,8 @@ def dev(request, gid, uid): @login_required -@mydefs.only_admins +@permission_required('abonapp.change_abon') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def clear_dev(request, gid, uid): try: abon = models.Abon.objects.get(pk=uid) @@ -619,7 +556,7 @@ def clear_dev(request, gid, uid): @login_required -@mydefs.only_admins +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def charts(request, gid, uid): high = 100 @@ -673,7 +610,7 @@ def charts(request, gid, uid): @login_required -@permission_required('abonapp.add_extra_fields_model') +@permission_required('abonapp.add_extrafieldsmodel') def make_extra_field(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) try: @@ -733,6 +670,7 @@ def extra_field_delete(request, gid, uid, fid): @login_required +@permission_required('abonapp.can_ping') def abon_ping(request): ip = request.GET.get('cmd_param') status = False @@ -753,7 +691,8 @@ def abon_ping(request): text = ' %s' % _('ok ping, %d/%d loses') % ping_result status = True else: - text = ' %s' % _('no ping, %d/%d loses') % ping_result + text = ' %s' % _( + 'no ping, %d/%d loses') % ping_result else: text = ' %s' % _('ping ok') + ' ' + str(ping_result) status = True @@ -773,6 +712,8 @@ def abon_ping(request): @mydefs.only_admins def dials(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) + if not request.user.has_perm('abonapp.can_view_abongroup', abon.group): + raise PermissionDenied if hasattr(abon.group, 'pk') and abon.group.pk != int(gid): return redirect('abonapp:dials', abon.group.pk, abon.pk) if abon.telephone is not None and abon.telephone != '': @@ -791,7 +732,7 @@ def dials(request, gid, uid): @login_required -@mydefs.only_admins +@permission_required('abonapp.change_abon') def save_user_dev_port(request, gid, uid): if request.method != 'POST': messages.error(request, _('Method is not POST')) @@ -820,6 +761,7 @@ def save_user_dev_port(request, gid, uid): @login_required @permission_required('abonapp.add_abonstreet') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def street_add(request, gid): if request.method == 'POST': frm = forms.AbonStreetForm(request.POST) @@ -839,10 +781,12 @@ def street_add(request, gid): @login_required @permission_required('abonapp.change_abonstreet') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def street_edit(request, gid): try: if request.method == 'POST': - streets_pairs = [(int(sid), sname) for sid, sname in zip(request.POST.getlist('sid'), request.POST.getlist('sname'))] + streets_pairs = [(int(sid), sname) for sid, sname in + zip(request.POST.getlist('sid'), request.POST.getlist('sname'))] for sid, sname in streets_pairs: street = models.AbonStreet.objects.get(pk=sid) street.name = sname @@ -862,6 +806,7 @@ def street_edit(request, gid): @login_required @permission_required('abonapp.delete_abonstreet') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) def street_del(request, gid, sid): try: models.AbonStreet.objects.get(pk=sid, group=gid).delete() @@ -871,22 +816,70 @@ def street_del(request, gid, sid): return redirect('abonapp:people_list', gid) +@login_required +@permission_required('abonapp.can_view_additionaltelephones') +@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')) +def tels(request, gid, uid): + abon = get_object_or_404(models.Abon, pk=uid) + telephones = abon.additional_telephones.all() + return render_to_text('abonapp/modal_additional_telephones.html', { + 'telephones': telephones, + 'gid': gid, + 'uid': uid + }, request=request) + + +@login_required +@permission_required('abnapp.add_additionaltelephone') +def tel_add(request, gid, uid): + if request.method == 'POST': + frm = forms.AdditionalTelephoneForm(request.POST) + if frm.is_valid(): + new_tel = frm.save(commit=False) + abon = get_object_or_404(models.Abon, pk=uid) + new_tel.abon = abon + new_tel.save() + messages.success(request, _('New telephone has been saved')) + return redirect('abonapp:abon_home', gid, uid) + else: + messages.error(request, _('fix form errors')) + else: + frm = forms.AdditionalTelephoneForm() + return render_to_text('abonapp/modal_add_phone.html', { + 'form': frm, + 'gid': gid, + 'uid': uid + }, request=request) + + +@login_required +@permission_required('abnapp.delete_additionaltelephone') +def tel_del(request, gid, uid): + try: + tid = mydefs.safe_int(request.GET.get('tid')) + tel = models.AdditionalTelephone.objects.get(pk=tid) + tel.delete() + messages.success(request, _('Additional telephone successfully deleted')) + except models.AdditionalTelephone.DoesNotExist: + messages.error(request, _('Telephone not found')) + return redirect('abonapp:abon_home', gid, uid) + # API's def abons(request): ablist = [{ - 'id': abn.pk, - 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0, - 'ip': abn.ip_address.int_ip(), - 'is_active': abn.is_active - } for abn in models.Abon.objects.all()] + 'id': abn.pk, + 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0, + 'ip': abn.ip_address.int_ip(), + 'is_active': abn.is_active + } for abn in models.Abon.objects.all()] tarlist = [{ - 'id': trf.pk, - 'speedIn': trf.speedIn, - 'speedOut': trf.speedOut - } for trf in Tariff.objects.all()] + 'id': trf.pk, + 'speedIn': trf.speedIn, + 'speedOut': trf.speedOut + } for trf in Tariff.objects.all()] data = { 'subscribers': ablist, diff --git a/accounts_app/forms.py b/accounts_app/forms.py index fbedf6f..4288081 100644 --- a/accounts_app/forms.py +++ b/accounts_app/forms.py @@ -1,12 +1,24 @@ # -*- coding: utf-8 -*- -from django import forms -from .models import UserProfile +from guardian.forms import UserObjectPermissionsForm +from guardian.shortcuts import assign_perm, remove_perm -class SetupPerms(forms.ModelForm): - class Meta: - model = UserProfile - fields = ['user_permissions'] - widgets = { - 'user_permissions': forms.CheckboxSelectMultiple() - } +class MyUserObjectPermissionsForm(UserObjectPermissionsForm): + + def save_obj_perms(self): + """ + Saves selected object permissions by creating new ones and removing + those which were not selected but already exists. + + Should be called *after* form is validated. + """ + perms = set(self.cleaned_data[self.get_obj_perms_field_name()]) + model_perms = set([c[0] for c in self.get_obj_perms_field_choices()]) + init_perms = set(self.get_obj_perms_field_initial()) + + to_remove = (model_perms - perms) & init_perms + for perm in to_remove: + remove_perm(perm, self.user, self.obj) + + for perm in perms - init_perms: + assign_perm(perm, self.user, self.obj) diff --git a/accounts_app/locale/ru/LC_MESSAGES/django.po b/accounts_app/locale/ru/LC_MESSAGES/django.po index d3c7a5c..1de16c6 100644 --- a/accounts_app/locale/ru/LC_MESSAGES/django.po +++ b/accounts_app/locale/ru/LC_MESSAGES/django.po @@ -33,18 +33,6 @@ msgstr "Администраторы" msgid "Groups" msgstr "Группы" -#: accounts_app/templates/accounts/group.html:16 -msgid "The current distribution of rights for groups" -msgstr "Действующее распределение прав для группы" - -#: accounts_app/templates/accounts/group.html:22 -msgid "Available rights" -msgstr "Доступные права" - -#: accounts_app/templates/accounts/group.html:36 -msgid "Rights for the group" -msgstr "Права группы" - #: accounts_app/templates/accounts/group.html:44 #: accounts_app/templates/accounts/profile_chgroup.html:20 #: accounts_app/templates/accounts/settings/ch_info.html:66 @@ -58,22 +46,6 @@ msgstr "Сохранить" msgid "Reset" msgstr "Сбросить" -#: accounts_app/templates/accounts/group_list.html:11 -msgid "Admin groups list" -msgstr "Список групп администраторов" - -#: accounts_app/templates/accounts/group_list.html:20 -msgid "Group" -msgstr "Группа" - -#: accounts_app/templates/accounts/group_list.html:40 -msgid "Groups does not found" -msgstr "Нет групп" - -#: accounts_app/templates/accounts/group_list.html:47 -msgid "Add group" -msgstr "Добавить группу" - #: accounts_app/templates/accounts/index.html:8 #: accounts_app/templates/accounts/settings/ch_info.html:37 msgid "Telephone" @@ -186,11 +158,47 @@ msgstr "Настройка прав" msgid "Edit" msgstr "Редактировать" -msgid "Set a task" -msgstr "Дать задачу" - msgid "Please select an image" msgstr "Пожалуйста выберите изображение" msgid "Avatar successfully changed" msgstr "Аватар успешно изменён" + +msgid "Access to groups" +msgstr "Доступ к группам" + +msgid "The list of user groups to which the account has access" +msgstr "Список групп абонентов, к которым учётка имеет доступ" + +msgid "The responsibility of the staff of the group of subscribers" +msgstr "Ответственность работника за группы абонентов" + +msgid "Not set" +msgstr "Не найдено" + +msgid "Change permission for that object" +msgstr "Изменение прав доступа для выбранного объекта" + +msgid "Permissions has successfully updated" +msgstr "Права успешно обновлены" + +msgid "Profile is superuser, permissions to change it makes no sense" +msgstr "Учётная запись является суперпользователем, разрешения менять нет смысла" + +msgid "Staff account profile" +msgstr "Учётная запись работника" + +msgid "Staff account profiles" +msgstr "Учётные записи работников" + +msgid "Can view staff profile" +msgstr "Может просматривать учётку сотрудника" + +msgid "Pick object for edit permissions" +msgstr "Выберите объект для редактирования прав доступа" + +msgid "Pick the type of object" +msgstr "Выберите тип объекта" + +msgid "Profile has been deleted" +msgstr "Учётная запись удалена" diff --git a/accounts_app/migrations/0008_auto_20170927_1838.py b/accounts_app/migrations/0008_auto_20170927_1838.py new file mode 100644 index 0000000..fb3c6fe --- /dev/null +++ b/accounts_app/migrations/0008_auto_20170927_1838.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-27 18:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts_app', '0007_auto_20170816_1109'), + ] + + operations = [ + migrations.AlterModelOptions( + name='userprofile', + options={'permissions': (('can_view_userprofile', 'Может просматривать учётку сотрудника'),), 'verbose_name': 'Учётная запись работника', 'verbose_name_plural': 'Учётные записи работников'}, + ), + ] diff --git a/accounts_app/models.py b/accounts_app/models.py index a5f5238..731b432 100644 --- a/accounts_app/models.py +++ b/accounts_app/models.py @@ -1,4 +1,5 @@ # -*- coding:utf-8 -*- +import os from django.db import models from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin from django.core.validators import RegexValidator @@ -7,7 +8,7 @@ from django.conf import settings from photo_app.models import Photo -DEFAULT_PICTURE = getattr(settings, 'DEFAULT_PICTURE', '/static/images/default-avatar.png') +DEFAULT_PICTURE = getattr(settings, 'DEFAULT_PICTURE', '/static/img/user_ava.gif') TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$') @@ -79,15 +80,31 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): def get_big_ava(self): if self.avatar: - return self.avatar.big() + path = self.avatar.big() + if os.path.exists(path): + return path + else: + return DEFAULT_PICTURE else: return DEFAULT_PICTURE def get_min_ava(self): if self.avatar: - return self.avatar.min() + url_path = self.avatar.min() + real_path = url_path[1:] + if os.path.exists(real_path): + return url_path + else: + return DEFAULT_PICTURE else: return DEFAULT_PICTURE def __str__(self): return self.get_full_name() + + class Meta: + permissions = ( + ('can_view_userprofile', _('Can view staff profile')), + ) + verbose_name = _('Staff account profile') + verbose_name_plural = _('Staff account profiles') diff --git a/accounts_app/templates/accounts/acc_list.html b/accounts_app/templates/accounts/acc_list.html index 09e2880..ed5e52e 100644 --- a/accounts_app/templates/accounts/acc_list.html +++ b/accounts_app/templates/accounts/acc_list.html @@ -25,7 +25,7 @@ {% for usr in users %} - {{ usr.username }} {{ usr.username }} @@ -39,7 +39,7 @@ title="Дать задание"> - diff --git a/accounts_app/templates/accounts/ext.htm b/accounts_app/templates/accounts/ext.htm index cc08e5c..19cf4e1 100644 --- a/accounts_app/templates/accounts/ext.htm +++ b/accounts_app/templates/accounts/ext.htm @@ -14,19 +14,32 @@
{% if userprofile.avatar %} - - ava + + ava {% else %} ava {% endif %}
{% if userprofile == request.user %} - - {% trans 'Edit' %} + + + {% trans 'Edit' %} + + {% endif %} + {% if request.user.is_superuser %} + {% if userprofile.is_superuser %} + + + {% trans 'Permission options' %} + + {% else %} + + + {% trans 'Permission options' %} + + {% endif %} {% endif %} - - {% trans 'Set a task' %}
@@ -46,6 +59,15 @@ {% trans 'Groups' %} + {% if request.user.is_superuser %} + {% url 'acc_app:set_abon_groups_permission' uid as set_ag_perm %} + + + + {% trans 'Access to groups' %} + + + {% endif %}
@@ -55,4 +77,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/accounts_app/templates/accounts/group.html b/accounts_app/templates/accounts/group.html deleted file mode 100644 index 96e0120..0000000 --- a/accounts_app/templates/accounts/group.html +++ /dev/null @@ -1,50 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block main %} - - - - {% include 'message_block.html' %} - -
-
-

{% trans 'The current distribution of rights for groups' %} {{ group.name }}

-
-
-
{% csrf_token %} - -
- - -
-
    -
  • -
  • -
-
- - -
-
- - -
-
-
- -{% endblock %} \ No newline at end of file diff --git a/accounts_app/templates/accounts/group_list.html b/accounts_app/templates/accounts/group_list.html deleted file mode 100644 index fd90afd..0000000 --- a/accounts_app/templates/accounts/group_list.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block main %} - - - -

{% trans 'Admin groups list' %}

- - {% include 'message_block.html' %} - -
- - - - - - - - - - {% for grp in groups %} - - - - - - {% empty %} - - - - {% endfor %} - - - - - - -
#{% trans 'Group' %}
{{ grp.id }}{{ grp.name }} - - - - - - -
{% trans 'Groups does not found' %}
- - - -
-
- - {% include 'toolbar_page.html' with pag=groups %} - -{% endblock %} \ No newline at end of file diff --git a/accounts_app/templates/accounts/perms/objects_of_type.html b/accounts_app/templates/accounts/perms/objects_of_type.html new file mode 100644 index 0000000..e5adbcf --- /dev/null +++ b/accounts_app/templates/accounts/perms/objects_of_type.html @@ -0,0 +1,34 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block main %} + + + +

{% trans 'Pick object for edit permissions' %}

+ + {% include 'message_block.html' %} + +
+ + + + + + + + {% for obj in objects %}{% endfor %} + +
obj
+ {{ obj }} +
+
+ + {% include 'toolbar_page.html' with pag=objects %} + +{% endblock %} diff --git a/accounts_app/templates/accounts/perms/objects_types.html b/accounts_app/templates/accounts/perms/objects_types.html new file mode 100644 index 0000000..a831c76 --- /dev/null +++ b/accounts_app/templates/accounts/perms/objects_types.html @@ -0,0 +1,36 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load acc_tags %} +{% block main %} + + + +

{% trans 'Pick the type of object' %}

+ + {% include 'message_block.html' %} + +
+ + + + + + + + {% for klass in klasses %} + + + + {% endfor %} + +
{% trans 'Group' %}
+ <{{ klass }}> {% klass_name klass %} +
+
+ +{% endblock %} diff --git a/accounts_app/templates/accounts/perms/perms_edit.html b/accounts_app/templates/accounts/perms/perms_edit.html new file mode 100644 index 0000000..1e0cf96 --- /dev/null +++ b/accounts_app/templates/accounts/perms/perms_edit.html @@ -0,0 +1,71 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load guardian_tags %} +{% block main %} + + + +

{% trans 'Pick object for edit permissions' %}

+ + {% include 'message_block.html' %} + + {% if userprofile.is_superuser %} +
+ + + {% trans 'Profile is superuser, permissions to change it makes no sense' %} +
+ {% endif %} + +
+
+

{% trans 'Change permission for that object' %}

+
+
+ +
{% csrf_token %} + + {% get_obj_perms userprofile for obj as 'obj_perms' %} + + {% for field in form %} +
+ + +
+ +
+
+ {% endfor %} + +
+ + +
+
+
+
+ +{% endblock %} diff --git a/accounts_app/templates/accounts/profile_chgroup.html b/accounts_app/templates/accounts/profile_chgroup.html index 22156fa..c5ac443 100644 --- a/accounts_app/templates/accounts/profile_chgroup.html +++ b/accounts_app/templates/accounts/profile_chgroup.html @@ -2,15 +2,15 @@ {% load i18n %} {% block content %} - {% trans 'The responsibility of the administrator of the group of subscribers' %} + {% trans 'The responsibility of the staff of the group of subscribers' %}
{% csrf_token %} {% for ag in abongroups %}
@@ -21,4 +21,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/accounts_app/templates/accounts/set_abon_groups_permission.html b/accounts_app/templates/accounts/set_abon_groups_permission.html new file mode 100644 index 0000000..b431f98 --- /dev/null +++ b/accounts_app/templates/accounts/set_abon_groups_permission.html @@ -0,0 +1,25 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,accounts/ext.htm' %} +{% load i18n %} +{% block content %} + + {% trans 'The list of user groups to which the account has access' %} +
{% csrf_token %} + {% for ag in abongroups %} +
+ +
+ {% endfor %} +
+ + +
+
+ +{% endblock %} diff --git a/accounts_app/templates/accounts/settings/ext.htm b/accounts_app/templates/accounts/settings/ext.htm index 92c5b3c..572c19d 100644 --- a/accounts_app/templates/accounts/settings/ext.htm +++ b/accounts_app/templates/accounts/settings/ext.htm @@ -16,9 +16,7 @@
{% csrf_token %} - {% if user.avatar %}ava - {% else %}ava - {% endif %} + ava
@@ -36,13 +34,6 @@ {% trans 'Change self onfo' %} - {% if user.is_superuser %} -
  • - - {% trans 'Permission options' %} - -
  • - {% endif %}
    diff --git a/accounts_app/templates/accounts/settings/permissions.html b/accounts_app/templates/accounts/settings/permissions.html deleted file mode 100644 index 906b485..0000000 --- a/accounts_app/templates/accounts/settings/permissions.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends request.is_ajax|yesno:'nullcont.htm,accounts/settings/ext.htm' %} -{% block content %} - - {% csrf_token %} - {% for perm, pname in form.user_permissions.field.choices %} -
    - -
    - {% endfor %} - -{% endblock %} \ No newline at end of file diff --git a/accounts_app/templates/accounts/settings/test.html b/accounts_app/templates/accounts/settings/test.html new file mode 100644 index 0000000..62441f6 --- /dev/null +++ b/accounts_app/templates/accounts/settings/test.html @@ -0,0 +1,14 @@ +

    + + +

    diff --git a/accounts_app/templatetags/__init__.py b/accounts_app/templatetags/__init__.py new file mode 100644 index 0000000..3474bc8 --- /dev/null +++ b/accounts_app/templatetags/__init__.py @@ -0,0 +1 @@ +__author__ = 'bashmak' diff --git a/accounts_app/templatetags/acc_tags.py b/accounts_app/templatetags/acc_tags.py new file mode 100644 index 0000000..dd29299 --- /dev/null +++ b/accounts_app/templatetags/acc_tags.py @@ -0,0 +1,18 @@ +from django import template +from django.db.models import Model +from django.apps import apps +from six import string_types, class_types +register = template.Library() + + + +@register.simple_tag +def klass_name(klass): + if type(klass) is class_types and issubclass(klass, Model): + kl = klass + elif isinstance(klass, string_types): + app_label, model_name = klass.split('.', 1) + kl = apps.get_model(app_label, model_name) + else: + return 'Type not detected' + return kl._meta.verbose_name diff --git a/accounts_app/urls.py b/accounts_app/urls.py index adeb5ef..5224c1f 100644 --- a/accounts_app/urls.py +++ b/accounts_app/urls.py @@ -20,13 +20,11 @@ urlpatterns = [ url(r'^(?P\d+)$', views.profile_show, name='other_profile'), url(r'^(?P\d+)/perms$', views.perms, name='setup_perms'), + url(r'^(?P\d+)/perms/(?P[a-z_]+\.[a-zA-Z_]+)$', views.perms_klasses, name='perms_klasses'), + url(r'^(?P\d+)/perms/(?P[a-z_]+\.[a-zA-Z_]+)/(?P\d+)$', views.perms_edit, name='perms_edit'), url(r'^(?P\d+)/chgroup$', views.chgroup, name='profile_setup_group'), url(r'^(?P\d+)/del$', views.delete_profile, name='delete_profile'), - # назначить задание - url(r'^(?P\d+)/appoint_task$', views.appoint_task, name='appoint_task'), - - url(r'^group/$', views.groups, name='groups_list'), - url(r'^group/(?P\d+)$', views.group, name='group_link') + url(r'^(?P\d+)/user_group_access$', views.set_abon_groups_permission, name='set_abon_groups_permission') ] \ No newline at end of file diff --git a/accounts_app/views.py b/accounts_app/views.py index 0227436..39b5606 100644 --- a/accounts_app/views.py +++ b/accounts_app/views.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import login_required from django.contrib.auth import authenticate, login, logout from django.core.exceptions import PermissionDenied from django.core.urlresolvers import NoReverseMatch -from django.shortcuts import render, redirect, get_object_or_404, resolve_url -from django.contrib.auth.models import Group, Permission +from django.shortcuts import render, redirect, get_object_or_404 from django.contrib import messages from django.utils.translation import ugettext as _ from abonapp.models import AbonGroup @@ -12,6 +11,8 @@ from abonapp.models import AbonGroup from photo_app.models import Photo from .models import UserProfile import mydefs +from guardian.decorators import permission_required_or_403 as permission_required +from guardian.shortcuts import get_objects_for_user, assign_perm, remove_perm @login_required @@ -62,6 +63,8 @@ def profile_show(request, uid=0): return redirect('acc_app:other_profile', uid=request.user.id) usr = get_object_or_404(UserProfile, id=uid) + if request.user != usr and not request.user.has_perm('accounts_app.can_view_userprofile', usr): + raise PermissionDenied if request.method == 'POST': usr.username = request.POST.get('username') usr.fio = request.POST.get('fio') @@ -85,12 +88,14 @@ def chgroup(request, uid): usr = request.user else: usr = get_object_or_404(UserProfile, id=uid) + if usr != request.user and not request.user.has_perm('accounts_app.change_userprofile', usr): + raise PermissionDenied if request.method == 'POST': ag = request.POST.getlist('ag') usr.abon_groups.clear() usr.abon_groups.add(*[int(d) for d in ag]) usr.save() - abongroups = AbonGroup.objects.all() + abongroups = AbonGroup.objects.only('pk', 'title') return render(request, 'accounts/profile_chgroup.html', { 'uid': uid, 'userprofile': usr, @@ -155,7 +160,7 @@ def ch_info(request): @login_required -@permission_required('acc_app.add_userprofile') +@permission_required('accounts_app.add_userprofile') def create_profile(request): if request.method == 'POST': username = request.POST.get('username') @@ -194,18 +199,20 @@ def create_profile(request): @login_required @mydefs.only_admins def delete_profile(request, uid): + prf = get_object_or_404(UserProfile, id=uid) if uid != request.user.id: - if not request.user.has_perm('acc_app.delete_userprofile'): + if not request.user.has_perm('acc_app.delete_userprofile', prf): raise PermissionDenied - prf = get_object_or_404(UserProfile, id=uid) prf.delete() + messages.success(request, _('Profile has been deleted')) return redirect('acc_app:accounts_list') @login_required @mydefs.only_admins def acc_list(request): - users = UserProfile.objects.filter(is_admin=True) + users = UserProfile.objects.filter(is_admin=True).exclude(pk=request.user.pk) + users = get_objects_for_user(request.user, 'accounts_app.can_view_userprofile', users) users = mydefs.pag_mn(request, users) return render(request, 'accounts/acc_list.html', { 'users': users @@ -213,54 +220,88 @@ def acc_list(request): @login_required -@mydefs.only_admins def perms(request, uid): - profile = get_object_or_404(UserProfile, id=uid) - own_permissions = UserProfile.get_all_permissions(profile) - return render(request, 'accounts/settings/permissions.html', { - 'uid': uid, - 'own_permissions': own_permissions + if not request.user.is_superuser: + raise PermissionDenied + userprofile = get_object_or_404(UserProfile, id=uid) + klasses = ( + 'abonapp.AbonGroup', 'abonapp.Abon', 'accounts_app.UserProfile', + 'abonapp.AbonTariff', 'abonapp.AbonStreet', 'devapp.Device', + 'abonapp.PassportInfo', 'abonapp.AdditionalTelephone' + ) + return render(request, 'accounts/perms/objects_types.html', { + 'userprofile': userprofile, + 'klasses': klasses }) @login_required -@mydefs.only_admins -def groups(request): - grps = Group.objects.all() - grps = mydefs.pag_mn(request, grps) - return render(request, 'accounts/group_list.html', { - 'groups': grps +def perms_klasses(request, uid, klass_name): + if not request.user.is_superuser: + raise PermissionDenied + from django.apps import apps + userprofile = get_object_or_404(UserProfile, pk=uid) + app_label, model_name = klass_name.split('.', 1) + klass = apps.get_model(app_label, model_name) + + objects = klass.objects.all() + objects = mydefs.pag_mn(request, objects) + + return render(request, 'accounts/perms/objects_of_type.html', { + 'userprofile': userprofile, + 'klass': klass_name, + 'klass_name': klass._meta.verbose_name, + 'objects': objects }) - @login_required -@mydefs.only_admins -def group(request, uid): - uid = mydefs.safe_int(uid) - grp = get_object_or_404(Group, id=uid) - - if request.method == 'POST': - group_rights = filter(lambda x: x[0] == 'group_rights', request.POST.lists())[0][1] - grp.permissions.clear() - for grr in group_rights: - rid = mydefs.safe_int(grr) - grp.permissions.add(rid) - grp.save() - return redirect('acc_app:profile_group_link', id=uid) - - grp_rights = grp.permissions.all() - all_rights = Permission.objects.exclude(group=grp) - - return render(request, 'accounts/group.html', { - 'group': grp, - 'all_rights': all_rights, - 'grp_rights': grp_rights +def perms_edit(request, uid, klass_name, obj_id): + if not request.user.is_superuser: + raise PermissionDenied + from django.apps import apps + from .forms import MyUserObjectPermissionsForm + userprofile = get_object_or_404(UserProfile, pk=uid) + app_label, model_name = klass_name.split('.', 1) + klass = apps.get_model(app_label, model_name) + obj = get_object_or_404(klass, pk=obj_id) + + frm = MyUserObjectPermissionsForm(userprofile, obj, request.POST or None) + if request.method == 'POST' and frm.is_valid(): + frm.save_obj_perms() + messages.success(request, _('Permissions has successfully updated')) + + return render(request, 'accounts/perms/perms_edit.html', { + 'userprofile': userprofile, + 'obj': obj, + 'form': frm, + 'klass': klass_name, + 'klass_name': klass._meta.verbose_name }) @login_required -@mydefs.only_admins -def appoint_task(req, uid): - uid = mydefs.safe_int(uid) - url = resolve_url('taskapp:add') - return redirect("%s?rp=%d" % (url, uid)) +def set_abon_groups_permission(request, uid): + # Only superuser can change object permissions + if not request.user.is_superuser: + raise PermissionDenied + userprofile = get_object_or_404(UserProfile, pk=uid) + + picked_groups = get_objects_for_user(userprofile, 'abonapp.can_view_abongroup', accept_global_perms=False) + picked_groups = picked_groups.values_list('pk', flat=True) + + if request.method == 'POST': + checked_groups = [int(ag) for ag in request.POST.getlist('ag', default=0)] + for abon_group in AbonGroup.objects.all(): + if abon_group.pk in checked_groups and abon_group.pk not in picked_groups: + assign_perm('abonapp.can_view_abongroup', userprofile, obj=abon_group) + elif abon_group.pk not in checked_groups and abon_group.pk in picked_groups: + remove_perm('abonapp.can_view_abongroup', userprofile, obj=abon_group) + return redirect('acc_app:set_abon_groups_permission', uid) + abongroups = AbonGroup.objects.only('pk', 'title') + + return render(request, 'accounts/set_abon_groups_permission.html', { + 'uid': uid, + 'userprofile': userprofile, + 'abongroups': abongroups, + 'picked_groups_ids': picked_groups + }) diff --git a/agent/core.py b/agent/core.py index 8299755..3b04294 100644 --- a/agent/core.py +++ b/agent/core.py @@ -19,8 +19,6 @@ class NasNetworkError(Exception): def check_input_type(*types): def real_check(fn): def wrapped(self, *args): - if len(types) != len(args): - raise AttributeError("length of @types must be equivalent for length of @args") for param_type, param in zip(types, args): if not isinstance(param, param_type): raise TypeError("%s must be %s, but is %s" % (str(param), str(param_type), type(param))) @@ -32,12 +30,12 @@ def check_input_type(*types): # Общается с NAS'ом class BaseTransmitter(metaclass=ABCMeta): @abstractmethod - @check_input_type(AbonStruct) + @check_input_type(set) def add_user_range(self, user_list): """добавляем список абонентов в NAS""" @abstractmethod - @check_input_type(AbonStruct) + @check_input_type(set) def remove_user_range(self, users): """удаляем список абонентов""" @@ -97,7 +95,7 @@ class BaseTransmitter(metaclass=ABCMeta): """ @abstractmethod - @check_input_type(str) + @check_input_type(str, int) def ping(self, host, count=10): """ :param host: ip адрес в текстовом виде, например '192.168.0.1' @@ -126,11 +124,13 @@ class BaseTransmitter(metaclass=ABCMeta): def sync_nas(self, users_from_db): list_for_add, list_for_del = self._diff_users(users_from_db) - print('FOR DELETE') - for ld in list_for_del: - print(ld) - print('FOR ADD') - for la in list_for_add: - print(la) - self.remove_user_range( list_for_del ) - self.add_user_range( list_for_add ) + if len(list_for_del) > 0: + print('FOR DELETE') + for ld in list_for_del: + print(ld) + self.remove_user_range(list_for_del) + if len(list_for_add) > 0: + print('FOR ADD') + for la in list_for_add: + print(la) + self.add_user_range(list_for_add) diff --git a/agent/mod_mikrotik.py b/agent/mod_mikrotik.py index dcb7069..b3b6ff1 100644 --- a/agent/mod_mikrotik.py +++ b/agent/mod_mikrotik.py @@ -6,7 +6,7 @@ from hashlib import md5 from .core import BaseTransmitter, NasFailedResult, NasNetworkError from mydefs import ping from .structs import TariffStruct, AbonStruct, IpStruct -from . import settings +from . import settings as local_settings from django.conf import settings import re @@ -144,15 +144,17 @@ class ApiRos: class TransmitterManager(BaseTransmitter, metaclass=ABCMeta): def __init__(self, login=None, password=None, ip=None, port=None): - ip = ip or settings.NAS_IP + ip = ip or getattr(local_settings, 'NAS_IP') + if ip is None: + raise NasNetworkError('Не передан ip адрес NAS') if not ping(ip): raise NasNetworkError('NAS %s не пингуется' % ip) try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((ip, port or settings.NAS_PORT)) + s.connect((ip, port or getattr(local_settings, 'NAS_PORT', 8728))) self.s = s self.ar = ApiRos(s) - self.ar.login(login or settings.NAS_LOGIN, password or settings.NAS_PASSW) + self.ar.login(login or getattr(local_settings, 'NAS_LOGIN'), password or getattr(local_settings, 'NAS_PASSW')) except ConnectionRefusedError: raise NasNetworkError('Подключение к %s отклонено (Connection Refused)' % ip) @@ -246,8 +248,11 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta): return self._exec_cmd(['/queue/simple/remove', '=.id=' + getattr(q, 'queue_id', '')]) def remove_range(self, q_ids): - if q_ids is not None and len(q_ids) > 0: + try: + #q_ids = [q.queue_id for q in q_ids] return self._exec_cmd(['/queue/simple/remove', '=numbers=' + ','.join(q_ids)]) + except TypeError as e: + print(e) def update(self, user): if not isinstance(user, AbonStruct): @@ -272,10 +277,10 @@ class QueueManager(TransmitterManager, metaclass=ABCMeta): # читаем шейпер, возващаем записи о шейпере def read_queue_iter(self): - queues = self._exec_cmd_iter(['/queue/simple/print', '=detail']) - for queue in queues: - if queue[0] == '!done': return - sobj = self._build_shape_obj(queue[1]) + for code, dat in self._exec_cmd_iter(['/queue/simple/print', '=detail']): + if code == '!done': + return + sobj = self._build_shape_obj(dat) if sobj is not None: yield sobj @@ -346,7 +351,7 @@ class IpAddressListManager(TransmitterManager, metaclass=ABCMeta): if len(ids) > 0: return self._exec_cmd([ '/ip/firewall/address-list/remove', - 'numbers=' + ','.join(ids) + '=numbers=*%s' % ',*'.join(ids) ]) def find(self, ip, list_name): @@ -359,10 +364,14 @@ class IpAddressListManager(TransmitterManager, metaclass=ABCMeta): ]) def read_ips_iter(self, list_name): - return self._exec_cmd([ + ips = self._exec_cmd_iter([ '/ip/firewall/address-list/print', 'where', - '?list=%s' % list_name + '?list=%s' % list_name, + '?dynamic=no' ]) + for code, dat in ips: + if dat != {}: + yield IpAddressListObj(dat['=address'], dat['=.id']) def disable(self, user): r = IpAddressListManager.find(self, user.ip, LIST_USERS_ALLOWED) @@ -498,6 +507,15 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager): def read_users(self): # shapes is ShapeItem - # allowed_ips = IpAddressListManager.read_ips_iter(self, LIST_USERS_ALLOWED) - queues = QueueManager.read_queue_iter(self) + allowed_ips = set(IpAddressListManager.read_ips_iter(self, LIST_USERS_ALLOWED)) + queues = set(q for q in QueueManager.read_queue_iter(self) if q.ip in allowed_ips) + + ips_from_queues = set([q.ip for q in queues]) + allowed_ips = set(allowed_ips) + + # удаляем ip адреса которые есть в firewall/address-list и нет соответствующих в queues + diff = list(allowed_ips - ips_from_queues) + if len(diff) > 0: + IpAddressListManager.remove_range(self, diff) + return queues diff --git a/clientsideapp/templates/clientsideapp/ext.html b/clientsideapp/templates/clientsideapp/ext.html index b19ef15..9ec2214 100644 --- a/clientsideapp/templates/clientsideapp/ext.html +++ b/clientsideapp/templates/clientsideapp/ext.html @@ -93,7 +93,9 @@ diff --git a/cron.py b/cron.py index 049080c..0f8d6b6 100755 --- a/cron.py +++ b/cron.py @@ -10,43 +10,25 @@ from mydefs import LogicError def main(): - tm = None - users = Abon.objects.all() for user in users: try: # бдим за услугами абонента user.bill_service(user) - # если нет ip то и нет смысла лезть в NAS - if user.ip_address is None: - continue - - # а есть-ли у абонента доступ к услуге - if not user.is_access(): - continue - - # строим структуру агента - ab = user.build_agent_struct() - if ab is None: - # если не построилась структура агента, значит нет ip - # а если нет ip то и синхронизировать абонента без ip нельзя - continue - - # обновляем абонента если он статический. Иначе его обновит dhcp - if user.opt82 is None: - if tm is None: - tm = Transmitter() - tm.update_user(ab) - except (NasNetworkError, NasFailedResult) as er: print("Error:", er) except LogicError as er: print("Notice:", er) + tm = Transmitter() + users = Abon.objects.filter(is_dynamic_ip=False, is_active=True).exclude(current_tariff=None) + tm.sync_nas(users) if __name__ == "__main__": try: main() except (NasNetworkError, NasFailedResult) as e: - print('NAS:', e) + print("Error while sync nas:", e) + except LogicError as e: + print("Notice while sync nas:", e) diff --git a/devapp/locale/ru/LC_MESSAGES/django.po b/devapp/locale/ru/LC_MESSAGES/django.po index 7a6f8e3..77cfd06 100644 --- a/devapp/locale/ru/LC_MESSAGES/django.po +++ b/devapp/locale/ru/LC_MESSAGES/django.po @@ -300,3 +300,12 @@ msgstr "Посмотреть устройство" msgid "Eltex switch" msgstr "Элтекс свич" + +msgid "Can view device" +msgstr "Может видеть устройство" + +msgid "Device" +msgstr "Устройство" + +msgid "Can toggle ports" +msgstr "Может переключать порты" diff --git a/devapp/migrations/0001_initial.py b/devapp/migrations/0001_initial.py deleted file mode 100644 index 2bf13ba..0000000 --- a/devapp/migrations/0001_initial.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-06-28 23:51 - -from django.db import migrations, models -import django.db.models.deletion - -import mydefs - - -class Migration(migrations.Migration): - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Device', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('ip_address', mydefs.MyGenericIPAddressField(max_length=8, protocol='ipv4')), - ('comment', models.CharField(max_length=256)), - ('devtype', - models.CharField(choices=[('Dl', "Свич D'Link")], default='Dl', max_length=2)), - ('man_passw', models.CharField(blank=True, max_length=16, null=True)), - ], - ), - migrations.CreateModel( - name='Port', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('num', models.PositiveSmallIntegerField(default=0)), - ('speed', - models.CharField(choices=[('h', '100Mbps'), ('k', '1Gbps'), ('d', '10Gbps')], default='h', - max_length=1)), - ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')), - ], - ), - migrations.CreateModel( - name='PortStates', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('state_json_info', models.TextField()), - ('port', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Port')), - ], - ), - migrations.AlterUniqueTogether( - name='port', - unique_together={('device', 'num')}, - ), - ] diff --git a/devapp/migrations/0001_squashed_0007_auto_20170816_1109.py b/devapp/migrations/0001_squashed_0007_auto_20170816_1109.py new file mode 100644 index 0000000..bd3b9dc --- /dev/null +++ b/devapp/migrations/0001_squashed_0007_auto_20170816_1109.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-04 16:14 +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): + + initial = True + + dependencies = [ + ('mapapp', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Device', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ip_address', mydefs.MyGenericIPAddressField(max_length=8, protocol='ipv4')), + ('comment', models.CharField(max_length=256)), + ('devtype', models.CharField(choices=[('Dl', "Свич D'Link")], default='Dl', max_length=2)), + ('man_passw', models.CharField(blank=True, max_length=16, null=True)), + ], + ), + migrations.CreateModel( + name='Port', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('num', models.PositiveSmallIntegerField(default=0)), + ('speed', models.CharField(choices=[('h', '100Mbps'), ('k', '1Gbps'), ('d', '10Gbps')], default='h', max_length=1)), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')), + ], + ), + migrations.AlterUniqueTogether( + name='port', + unique_together=set([('device', 'num')]), + ), + migrations.AlterModelTable( + name='device', + table='dev', + ), + migrations.AlterModelTable( + name='port', + table='dev_port', + ), + migrations.AddField( + model_name='device', + name='map_dot', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mapapp.Dot'), + ), + migrations.AlterField( + model_name='device', + name='devtype', + field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT')], default='Dl', max_length=2), + ), + migrations.RemoveField( + model_name='port', + name='speed', + ), + migrations.AddField( + model_name='device', + name='mac_addr', + field=djing.fields.MACAddressField(blank=True, integer=True, null=True, unique=True), + ), + migrations.AddField( + model_name='device', + name='parent_dev', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), + ), + migrations.AddField( + model_name='port', + name='descr', + field=models.CharField(blank=True, max_length=60, null=True), + ), + migrations.AlterField( + model_name='device', + name='devtype', + field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT'), ('On', 'PON ONU')], default='Dl', max_length=2), + ), + 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), + ), + ] diff --git a/devapp/migrations/0002_auto_20160909_1018.py b/devapp/migrations/0002_auto_20160909_1018.py deleted file mode 100644 index b1069bb..0000000 --- a/devapp/migrations/0002_auto_20160909_1018.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-09-09 07:18 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0001_initial'), - ] - - operations = [ - migrations.AlterModelTable( - name='device', - table='dev', - ), - migrations.AlterModelTable( - name='port', - table='dev_port', - ), - ] diff --git a/devapp/migrations/0004_device_user_group.py b/devapp/migrations/0002_device_user_group.py similarity index 73% rename from devapp/migrations/0004_device_user_group.py rename to devapp/migrations/0002_device_user_group.py index 00c16f2..7fbbecb 100644 --- a/devapp/migrations/0004_device_user_group.py +++ b/devapp/migrations/0002_device_user_group.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-02-22 19:24 +# Generated by Django 1.9 on 2017-09-04 16:16 from __future__ import unicode_literals from django.db import migrations, models @@ -9,8 +9,8 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('abonapp', '0011_auto_20170222_2224'), - ('devapp', '0003_device_map_dot'), + ('abonapp', '0001_squashed_0022_auto_20170816_1109'), + ('devapp', '0001_squashed_0007_auto_20170816_1109'), ] operations = [ diff --git a/devapp/migrations/0003_auto_20170927_1838.py b/devapp/migrations/0003_auto_20170927_1838.py new file mode 100644 index 0000000..490780c --- /dev/null +++ b/devapp/migrations/0003_auto_20170927_1838.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-27 18:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('devapp', '0002_device_user_group'), + ] + + operations = [ + migrations.AlterModelOptions( + name='device', + options={'permissions': (('can_view_device', 'Can view device'),), 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'}, + ), + migrations.AlterModelOptions( + name='port', + options={'permissions': (('can_toggle_ports', 'Can toggle ports'),), 'verbose_name': 'Port', 'verbose_name_plural': 'Ports'}, + ), + ] diff --git a/devapp/migrations/0003_device_map_dot.py b/devapp/migrations/0003_device_map_dot.py deleted file mode 100644 index eca2674..0000000 --- a/devapp/migrations/0003_device_map_dot.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-01-28 22:03 -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('mapapp', '0001_initial'), - ('devapp', '0002_auto_20160909_1018'), - ] - - operations = [ - migrations.AddField( - model_name='device', - name='map_dot', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mapapp.Dot'), - ), - ] diff --git a/devapp/migrations/0005_auto_20170502_2232.py b/devapp/migrations/0005_auto_20170502_2232.py deleted file mode 100644 index 91cbe61..0000000 --- a/devapp/migrations/0005_auto_20170502_2232.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-05-02 19:32 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0004_device_user_group'), - ] - - operations = [ - migrations.AlterField( - model_name='device', - name='devtype', - field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT')], default='Dl', max_length=2), - ), - ] diff --git a/devapp/migrations/0006_auto_20170705_1403.py b/devapp/migrations/0006_auto_20170705_1403.py deleted file mode 100644 index 33d3b75..0000000 --- a/devapp/migrations/0006_auto_20170705_1403.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-07-05 14:03 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import djing.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0005_auto_20170502_2232'), - ] - - operations = [ - migrations.RemoveField( - model_name='portstates', - name='port', - ), - migrations.RemoveField( - model_name='port', - name='speed', - ), - migrations.AddField( - model_name='device', - name='mac_addr', - field=djing.fields.MACAddressField(blank=True, integer=True, null=True, unique=True), - ), - migrations.AddField( - model_name='device', - name='parent_dev', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'), - ), - migrations.AddField( - model_name='port', - name='descr', - field=models.CharField(blank=True, max_length=60, null=True), - ), - migrations.AlterField( - model_name='device', - name='devtype', - field=models.CharField(choices=[('Dl', 'DLink switch'), ('Pn', 'PON OLT'), ('On', 'PON ONU')], default='Dl', max_length=2), - ), - migrations.DeleteModel( - name='PortStates', - ), - ] diff --git a/devapp/migrations/0007_auto_20170816_1109.py b/devapp/migrations/0007_auto_20170816_1109.py deleted file mode 100644 index 3cc6c28..0000000 --- a/devapp/migrations/0007_auto_20170816_1109.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-08-16 11:09 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('devapp', '0006_auto_20170705_1403'), - ] - - operations = [ - 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), - ), - ] diff --git a/devapp/models.py b/devapp/models.py index 1de7537..5e8a4a2 100644 --- a/devapp/models.py +++ b/devapp/models.py @@ -8,6 +8,7 @@ from . import dev_types from mapapp.models import Dot from subprocess import run from django.conf import settings +from django.utils.translation import ugettext_lazy as _ DEVICE_TYPES = ( @@ -34,6 +35,11 @@ class Device(models.Model): class Meta: db_table = 'dev' + permissions = ( + ('can_view_device', _('Can view device')), + ) + verbose_name = _('Device') + verbose_name_plural = _('Devices') def get_abons(self): pass @@ -69,6 +75,11 @@ class Port(models.Model): class Meta: db_table = 'dev_port' unique_together = (('device', 'num')) + permissions = ( + ('can_toggle_ports', _('Can toggle ports')), + ) + verbose_name = _('Port') + verbose_name_plural = _('Ports') def dev_post_save_signal(sender, instance, **kwargs): diff --git a/devapp/templates/devapp/custom_dev_page/onu.html b/devapp/templates/devapp/custom_dev_page/onu.html index 0a70d20..7ebb774 100644 --- a/devapp/templates/devapp/custom_dev_page/onu.html +++ b/devapp/templates/devapp/custom_dev_page/onu.html @@ -14,25 +14,28 @@
      -
    • {% trans 'Ip address' %}: {{ dev.ip_address }}
    • -
    • {% trans 'Mac' %}: {{ dev.mac_addr }}
    • -
    • {% trans 'Description' %} {{ dev.comment }}
    • +
    • {% trans 'Ip address' %}: {{ dev.ip_address }}
    • +
    • {% trans 'Mac' %}: {{ dev.mac_addr }}
    • +
    • {% trans 'Description' %} {{ dev.comment }}
    • {% for da in dev_accs %} -
    • {% trans 'Attached user' %}: - {% if da.group %} - {{ da.get_full_name }} - {% else %} - {{ da.get_full_name }} - {% endif %} -
    • +
    • {% trans 'Attached user' %}: + {% if da.group %} + {{ da.get_full_name }} + {% else %} + {{ da.get_full_name }} + {% endif %} +
    • {% endfor %} - {% if dev.parent_dev %} -
    • - {% with pdev=dev.parent_dev pdgrp=dev.parent_dev.user_group %} - {% trans 'Parent device' %}: {{ pdev.ip_address }} {{ pdev.comment }} - {% endwith %} -
    • - {% endif %} + {% if dev.parent_dev %} +
    • + {% with pdev=dev.parent_dev pdgrp=dev.parent_dev.user_group %} + {% trans 'Parent device' %}:{{ pdev.ip_address }} {{ pdev.comment }} + {% endwith %} +
    • + {% endif %}
    diff --git a/devapp/templates/devapp/devices_null_group.html b/devapp/templates/devapp/devices_null_group.html index 569825c..816bcbe 100644 --- a/devapp/templates/devapp/devices_null_group.html +++ b/devapp/templates/devapp/devices_null_group.html @@ -38,19 +38,20 @@ + {% with can_del_dev=perms.devapp.delete_device can_change_dev=perms.devapp.change_device %} {% for dev in devices %} - {{ dev.ip_address }} + {{ dev.ip_address }} {{ dev.comment }} {{ dev.get_devtype_display }} - {% if perms.devapp.delete_device %} - + {% if can_del_dev %} + {% endif %} - {% if perms.devapp.change_device %} - + {% if can_change_dev %} + {% endif %} @@ -61,6 +62,7 @@ {% trans 'Devices does not found' %}. {% trans 'Create' %} {% endfor %} + {% endwith %} diff --git a/devapp/views.py b/devapp/views.py index f332ef7..1b45b0a 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import login_required from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.db.models import Q @@ -15,13 +15,18 @@ from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_help from .forms import DeviceForm, PortForm from abonapp.models import AbonGroup, Abon from django.conf import settings +from guardian.decorators import permission_required_or_403 as permission_required +from guardian.shortcuts import get_objects_for_user @login_required @only_admins def devices(request, grp): group = get_object_or_404(AbonGroup, pk=grp) - devs = Device.objects.filter(user_group=grp) + if not request.user.has_perm('abonapp.can_view_abongroup', group): + raise PermissionDenied + devs = Device.objects.filter(user_group=grp).only('comment', 'mac_addr', 'devtype', 'user_group', 'pk', + 'ip_address') # фильтр dr, field = order_helper(request) @@ -41,7 +46,7 @@ def devices(request, grp): @login_required @only_admins def devices_null_group(request): - devs = Device.objects.filter(user_group=None) + devs = Device.objects.filter(user_group=None).only('comment', 'devtype', 'user_group', 'pk', 'ip_address') # фильтр dr, field = order_helper(request) if field: @@ -71,10 +76,12 @@ def devdel(request, did): @login_required -@only_admins +@permission_required('devapp.can_view_device') def dev(request, grp, devid=0): - devinst = get_object_or_404(Device, id=devid) if devid != 0 else None user_group = get_object_or_404(AbonGroup, pk=grp) + if not request.user.has_perm('abonapp.can_view_abongroup', user_group): + raise PermissionDenied + devinst = get_object_or_404(Device, id=devid) if devid != 0 else None already_dev = None if request.method == 'POST': @@ -294,7 +301,7 @@ def add_single_port(request, grp, did): @login_required -@only_admins +@permission_required('devapp.can_view_device') def devview(request, did): ports = None uptime = 0 @@ -318,7 +325,7 @@ def devview(request, did): except DeviceDBException as e: messages.error(request, e) - return render(request, 'devapp/custom_dev_page/'+template_name, { + return render(request, 'devapp/custom_dev_page/' + template_name, { 'dev': dev, 'ports': ports, 'uptime': uptime, @@ -327,7 +334,7 @@ def devview(request, did): @login_required -@only_admins +@permission_required('devapp.can_toggle_ports') def toggle_port(request, did, portid, status=0): portid = int(portid) status = int(status) @@ -338,9 +345,9 @@ def toggle_port(request, did, portid, status=0): manager = dev.get_manager_klass()(dev.ip_address, dev.man_passw) ports = manager.get_ports() if status: - ports[portid-1].enable() + ports[portid - 1].enable() else: - ports[portid-1].disable() + ports[portid - 1].disable() else: messages.warning(request, _('Not Set snmp device password')) else: @@ -353,7 +360,8 @@ def toggle_port(request, did, portid, status=0): @login_required @only_admins def group_list(request): - groups = AbonGroup.objects.all() + groups = AbonGroup.objects.all().order_by('title') + groups = get_objects_for_user(request.user, 'abonapp.can_view_abongroup', klass=groups, accept_global_perms=False) return render(request, 'devapp/group_list.html', { 'groups': groups }) @@ -365,6 +373,8 @@ def search_dev(request): if word is None: results = [{'id': 0, 'text': ''}] else: - results = Device.objects.filter(Q(comment__icontains=word) | Q(ip_address=word))[:16] + results = Device.objects.filter( + Q(comment__icontains=word) | Q(ip_address=word) + ).only('pk', 'ip_address', 'comment')[:16] results = [{'id': dev.pk, 'text': "%s: %s" % (dev.ip_address, dev.comment)} for dev in results] return HttpResponse(dumps(results, ensure_ascii=False)) diff --git a/dialing_app/models.py b/dialing_app/models.py index ff6c720..e448e91 100644 --- a/dialing_app/models.py +++ b/dialing_app/models.py @@ -1,6 +1,6 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ -from djing import settings +from django.conf import settings class AsteriskCDR(models.Model): diff --git a/dialing_app/templates/index.html b/dialing_app/templates/index.html index adc5061..68fadb2 100644 --- a/dialing_app/templates/index.html +++ b/dialing_app/templates/index.html @@ -21,22 +21,22 @@ {% for log in logs %} - + - + - {{ log.calldate|date:'d E Y, H:i:s' }} + {{ log.calldate|date:'d M, H:i:s' }} {{ log.src|abon_if_telephone|safe }} {{ log.dst|abon_if_telephone|safe }} {{ log.duration }} - {{ log.start|date:'d E Y, H:i:s' }} - {{ log.answer|date:'d E Y, H:i:s' }} - {{ log.end|date:'d E Y, H:i:s' }} + {{ log.start|date:'d M, H:i:s' }} + {{ log.answer|date:'d M, H:i:s' }} + {{ log.end|date:'d M, H:i:s' }} {{ log.locate_disposition }} {% empty %} diff --git a/dialing_app/views.py b/dialing_app/views.py index 98661eb..16c3a0a 100644 --- a/dialing_app/views.py +++ b/dialing_app/views.py @@ -2,6 +2,7 @@ from django.contrib.auth.decorators import login_required from django.contrib import messages from django.shortcuts import render, redirect from django.utils.translation import ugettext_lazy as _ +from guardian.decorators import permission_required_or_403 as permission_required from abonapp.models import Abon from mydefs import only_admins, pag_mn @@ -9,6 +10,7 @@ from .models import AsteriskCDR @login_required +@permission_required('dialing_app.change_asteriskcdr') @only_admins def home(request): logs = AsteriskCDR.objects.exclude(userfield='request').order_by('-calldate') diff --git a/django_messages/__init__.py b/django_messages/__init__.py deleted file mode 100644 index a8a2926..0000000 --- a/django_messages/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -VERSION = (0, 5, 3,) -__version__ = '.'.join(map(str, VERSION)) -default_app_config = 'django_messages.apps.DjangoMessagesConfig' diff --git a/django_messages/admin.py b/django_messages/admin.py deleted file mode 100644 index 51c493c..0000000 --- a/django_messages/admin.py +++ /dev/null @@ -1,112 +0,0 @@ -from django import forms -from django.conf import settings -from django.utils.translation import gettext_lazy as _ -from django.contrib import admin -from django.contrib.auth.models import Group - -from django_messages.utils import get_user_model -User = get_user_model() - -if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from notification import models as notification -else: - notification = None - -from django_messages.models import Message - -class MessageAdminForm(forms.ModelForm): - """ - Custom AdminForm to enable messages to groups and all users. - """ - group = forms.ChoiceField(label=_('group'), required=False, - help_text=_('Creates the message optionally for all users or a group of users.')) - - def __init__(self, *args, **kwargs): - super(MessageAdminForm, self).__init__(*args, **kwargs) - self.fields['group'].choices = self._get_group_choices() - self.fields['recipient'].required = True - - def _get_group_choices(self): - return [('', u'---------'), ('all', _('All users'))] + \ - [(group.pk, group.name) for group in Group.objects.all()] - - class Meta: - model = Message - fields = ('sender', 'recipient', 'group', 'parent_msg', 'subject', - 'body', 'sent_at', 'read_at', 'replied_at', 'sender_deleted_at', - 'recipient_deleted_at') - -class MessageAdmin(admin.ModelAdmin): - form = MessageAdminForm - fieldsets = ( - (None, { - 'fields': ( - 'sender', - ('recipient', 'group'), - ), - }), - (_('Message'), { - 'fields': ( - 'parent_msg', - 'subject', 'body', - ), - 'classes': ('monospace' ), - }), - (_('Date/time'), { - 'fields': ( - 'sent_at', 'read_at', 'replied_at', - 'sender_deleted_at', 'recipient_deleted_at', - ), - 'classes': ('collapse', 'wide'), - }), - ) - list_display = ('subject', 'sender', 'recipient', 'sent_at', 'read_at') - list_filter = ('sent_at', 'sender', 'recipient') - search_fields = ('subject', 'body') - raw_id_fields = ('sender', 'recipient', 'parent_msg') - - def save_model(self, request, obj, form, change): - """ - Saves the message for the recipient and looks in the form instance - for other possible recipients. Prevents duplication by excludin the - original recipient from the list of optional recipients. - - When changing an existing message and choosing optional recipients, - the message is effectively resent to those users. - """ - obj.save() - - if notification: - # Getting the appropriate notice labels for the sender and recipients. - if obj.parent_msg is None: - sender_label = 'messages_sent' - recipients_label = 'messages_received' - else: - sender_label = 'messages_replied' - recipients_label = 'messages_reply_received' - - # Notification for the sender. - notification.send([obj.sender], sender_label, {'message': obj,}) - - if form.cleaned_data['group'] == 'all': - # send to all users - recipients = User.objects.exclude(pk=obj.recipient.pk) - else: - # send to a group of users - recipients = [] - group = form.cleaned_data['group'] - if group: - group = Group.objects.get(pk=group) - recipients.extend( - list(group.user_set.exclude(pk=obj.recipient.pk))) - # create messages for all found recipients - for user in recipients: - obj.pk = None - obj.recipient = user - obj.save() - - if notification: - # Notification for the recipient. - notification.send([user], recipients_label, {'message' : obj,}) - -admin.site.register(Message, MessageAdmin) diff --git a/django_messages/apps.py b/django_messages/apps.py deleted file mode 100644 index c7a4f26..0000000 --- a/django_messages/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ - -class DjangoMessagesConfig(AppConfig): - name = 'django_messages' - verbose_name = _('Messages') diff --git a/django_messages/context_processors.py b/django_messages/context_processors.py deleted file mode 100644 index e649412..0000000 --- a/django_messages/context_processors.py +++ /dev/null @@ -1,7 +0,0 @@ -from django_messages.models import inbox_count_for - -def inbox(request): - if request.user.is_authenticated(): - return {'messages_inbox_count': inbox_count_for(request.user)} - else: - return {} diff --git a/django_messages/fields.py b/django_messages/fields.py deleted file mode 100644 index 7cb1457..0000000 --- a/django_messages/fields.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -Based on http://www.djangosnippets.org/snippets/595/ -by sopelkin -""" - -from django.forms import widgets - -from django_messages.utils import get_user_model, get_username_field - -User = get_user_model() - - -class CommaSeparatedUserInput(widgets.Input): - input_type = 'text' - - def render(self, name, value, attrs=None): - if value is None: - value = '' - elif isinstance(value, (list, tuple)): - value = (', '.join([getattr(user, get_username_field()) for user in value])) - return super(CommaSeparatedUserInput, self).render(name, value, attrs) diff --git a/django_messages/forms.py b/django_messages/forms.py deleted file mode 100644 index 4f0c2fc..0000000 --- a/django_messages/forms.py +++ /dev/null @@ -1,67 +0,0 @@ -from django import forms -from django.conf import settings -from django.utils.translation import ugettext_lazy as _ -from django.utils import timezone - - -if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from notification import models as notification -else: - notification = None - -from django_messages.models import Message -from accounts_app.models import UserProfile - - -class ComposeForm(forms.Form): - """ - A simple default form for private messages. - """ - recipient = forms.ModelMultipleChoiceField( - label=_(u"Recipient"), - widget=forms.SelectMultiple(attrs={'class': 'form-control'}), - queryset=UserProfile.objects.filter(is_admin=True), - ) - #recipient = CommaSeparatedUserField(label=_(u"Recipient")) - subject = forms.CharField( - label=_(u"Subject"), - max_length=140, - widget=forms.TextInput(attrs={'class': 'form-control'}) - ) - body = forms.CharField(label=_(u"Body"), - widget=forms.Textarea(attrs={'rows': '12', 'cols':'55', 'class': 'form-control'})) - - - def __init__(self, *args, **kwargs): - recipient_filter = kwargs.pop('recipient_filter', None) - super(ComposeForm, self).__init__(*args, **kwargs) - if recipient_filter is not None: - self.fields['recipient']._recipient_filter = recipient_filter - - - def save(self, sender, parent_msg=None): - recipients = self.cleaned_data['recipient'] - subject = self.cleaned_data['subject'] - body = self.cleaned_data['body'] - message_list = [] - for r in recipients: - msg = Message( - sender = sender, - recipient = r, - subject = subject, - body = body, - ) - if parent_msg is not None: - msg.parent_msg = parent_msg - parent_msg.replied_at = timezone.now() - parent_msg.save() - msg.save() - message_list.append(msg) - if notification: - if parent_msg is not None: - notification.send([sender], "messages_replied", {'message': msg,}) - notification.send([r], "messages_reply_received", {'message': msg,}) - else: - notification.send([sender], "messages_sent", {'message': msg,}) - notification.send([r], "messages_received", {'message': msg,}) - return message_list diff --git a/django_messages/locale/ar/LC_MESSAGES/django.po b/django_messages/locale/ar/LC_MESSAGES/django.po deleted file mode 100644 index 027edb1..0000000 --- a/django_messages/locale/ar/LC_MESSAGES/django.po +++ /dev/null @@ -1,317 +0,0 @@ -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Ossama M. Khayat , 2009. -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-10-14 04:23+0300\n" -"PO-Revision-Date: 2009-11-02 00:41+0300\n" -"Last-Translator: Ossama M. Khayat \n" -"Language-Team: Arabic \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.0\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " -"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:8 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "المستلم" - -#: admin.py:15 -msgid "group" -msgstr "مجموعة" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "ينشئ الرسالة اختياريا لجميع المستخدمين او لمجموعة من المستخدمين." - -#: admin.py:23 -msgid "All users" -msgstr "جميع المستخدمين" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "الرسالة" - -#: admin.py:45 -msgid "Date/time" -msgstr "التاريخ/الوقت" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "أسماء المستخدمين التالي ذكرهم غير صحيحة: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:8 -#: templates/messages/outbox.html:8 templates/messages/trash.html:8 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "الموضوع" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "المحتوى" - -#: management.py:9 -msgid "Message Received" -msgstr "تم استلام الرسالة" - -#: management.py:9 -msgid "you have received a message" -msgstr "وصلتك رسالة" - -#: management.py:10 -msgid "Message Sent" -msgstr "تم إرسال الرسالة" - -#: management.py:10 -msgid "you have sent a message" -msgstr "قمت بإرسال رسالة" - -#: management.py:11 -msgid "Message Replied" -msgstr "تم الرد على الرسالة" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "قمت بالرد على الرسالة" - -#: management.py:12 -msgid "Reply Received" -msgstr "تم استلام الرد" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "استملت رداً على رسالة" - -#: management.py:13 -msgid "Message Deleted" -msgstr "تم حذف الرسالة" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "قمت بحذف رسالة" - -#: management.py:14 -msgid "Message Recovered" -msgstr "تم استرجاع الرسالة" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "قمت باسترجاع رسالة" - -#: models.py:51 templates/messages/inbox.html:8 -#: templates/messages/trash.html:8 templates/messages/view.html:8 -msgid "Sender" -msgstr "المرسل" - -#: models.py:53 -msgid "Parent message" -msgstr "الرسالة الأساسية" - -#: models.py:54 -msgid "sent at" -msgstr "أرسلت في" - -#: models.py:55 -msgid "read at" -msgstr "قُرأت في" - -#: models.py:56 -msgid "replied at" -msgstr "رُدّ عليها في" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "حذفها المُرسل في" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "حذفها المستلم في" - -#: models.py:89 -msgid "Messages" -msgstr "الرسائل" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "رسالة جديدة: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "تم إرسال الرسالة بنجاح." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"كتب %(sender)s:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "رد: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "تم حذف الرسالة بنجاح." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "تم استرجاع الرسالة بنجاح." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "الوارد" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "الرسائل المرسلة" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "رسالة جديدة" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "الحاوية" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "أكتب رسالة" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "أرسل" - -#: templates/messages/inbox.html:8 -msgid "Received" -msgstr "استُلمت" - -#: templates/messages/inbox.html:8 templates/messages/outbox.html:8 -#: templates/messages/trash.html:8 -msgid "Action" -msgstr "إجراء" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -#: templates/messages/trash.html:17 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "DATETIME_FORMAT" - -#: templates/messages/inbox.html:21 templates/messages/outbox.html:18 -msgid "delete" -msgstr "حذف" - -#: templates/messages/inbox.html:27 templates/messages/outbox.html:24 -#: templates/messages/trash.html:24 -msgid "No messages." -msgstr "لا توجد رسائل." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"مرحباً %(recipient)s،\n" -"\n" -"وصلتك رسالة خاصة من %(sender)s\n" -"تحتوي ما يلي:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "أرسلت من %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "رد" - -#: templates/messages/outbox.html:8 -msgid "Sent" -msgstr "أرسل" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "الرسائل المحذوفة" - -#: templates/messages/trash.html:8 templates/messages/view.html:10 -msgid "Date" -msgstr "التاريخ" - -#: templates/messages/trash.html:18 -msgid "undelete" -msgstr "استرجاع" - -#: templates/messages/trash.html:27 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"تتم إزالة الرسائل المحذوفة من الحاوية على فترات زمنيّة متفاوتة، " -"فلا تعتمد على هذه الميزة للتخزين الطويل المدى." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "مشاهدة الرسالة" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "حذف" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "قمت بحذف الرسالة %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"وصلتك الرسالة %(message)s " -"من %(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "قمت باسترجاع الرسالة %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"قمت بالرد الرسائل %(message_parent_msg)s " -"من %(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "أرسل لك %(message_sender)s رداً على %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"قمت بإرسالة الرسالة %(message)s إلى %" -"(message_recipient)s." - diff --git a/django_messages/locale/cs/LC_MESSAGES/django.po b/django_messages/locale/cs/LC_MESSAGES/django.po deleted file mode 100644 index 9818544..0000000 --- a/django_messages/locale/cs/LC_MESSAGES/django.po +++ /dev/null @@ -1,398 +0,0 @@ -# Czech translation. -# Radim Sückr , 2016 -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-01 12:29+0100\n" -"PO-Revision-Date: 2015-01-01 12:29+0100\n" -"Last-Translator: Radim Sückr \n" -"Language-Team: \n" -"Language: cs\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" - -#: admin.py:21 -msgid "group" -msgstr "Skupina" - -#: admin.py:22 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Volitelně vytváří zprávu pro všechny uživatele nebo skupinu uživatelů." - -#: admin.py:30 -msgid "All users" -msgstr "Všichni uživatelé" - -#: admin.py:48 models.py:91 -msgid "Message" -msgstr "Zpráva" - -#: admin.py:55 -msgid "Date/time" -msgstr "Datum/čas" - -#: apps.py:6 models.py:92 -msgid "Messages" -msgstr "Zprávy" - -#: fields.py:56 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Následující uživatelská jména nejsou správně: %(users)s" - -#: forms.py:18 models.py:55 templates/django_messages/outbox.html:10 -#: templates/django_messages/view.html:14 -msgid "Recipient" -msgstr "Příjemce" - -#: forms.py:19 models.py:52 templates/django_messages/inbox.html:10 -#: templates/django_messages/outbox.html:10 -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:8 -msgid "Subject" -msgstr "Předmět" - -#: forms.py:20 models.py:53 -msgid "Body" -msgstr "Obsah" - -#: management.py:9 -msgid "Message Received" -msgstr "Zpráva přijata" - -#: management.py:9 -msgid "you have received a message" -msgstr "přišla vám zpráva" - -#: management.py:10 -msgid "Message Sent" -msgstr "Zpráva odeslána" - -#: management.py:10 -msgid "you have sent a message" -msgstr "odeslali jste zprávu" - -#: management.py:11 -msgid "Message Replied" -msgstr "Zpráva zodpovězena" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "odpověděli jste na zprávu" - -#: management.py:12 -msgid "Reply Received" -msgstr "Odpověď přijata" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "přišla vám odpověď na zprávu" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Zpráva smazána" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "smazali jste zprávu" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Zpráva obnovena" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "obnovili jste smazanou zprávu" - -#: models.py:54 templates/django_messages/inbox.html:10 -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:10 -msgid "Sender" -msgstr "Odesílatel" - -#: models.py:56 -msgid "Parent message" -msgstr "Předchozí zpráva" - -#: models.py:57 -msgid "sent at" -msgstr "odesláno" - -#: models.py:58 -msgid "read at" -msgstr "přečteno" - -#: models.py:59 -msgid "replied at" -msgstr "zodpovězeno" - -#: models.py:60 -msgid "Sender deleted at" -msgstr "Odesílatel smazal zprávu" - -#: models.py:61 -msgid "Recipient deleted at" -msgstr "Příjemce smazal zprávu" - -#: templates/django_messages/base.html:8 templates/django_messages/inbox.html:6 -#: templates/django_messages/new_message.html:13 -msgid "Inbox" -msgstr "Příchozí zprávy" - -#: templates/django_messages/base.html:9 -#: templates/django_messages/outbox.html:6 -msgid "Sent Messages" -msgstr "Odchozí zprávy" - -#: templates/django_messages/base.html:10 -msgid "New Message" -msgstr "Nová zpráva" - -#: templates/django_messages/base.html:11 -msgid "Trash" -msgstr "Koš" - -#: templates/django_messages/compose.html:4 -msgid "Compose Message" -msgstr "Napsat zprávu" - -#: templates/django_messages/compose.html:10 -msgid "Send" -msgstr "Odeslat" - -#: templates/django_messages/inbox.html:10 -msgid "Received" -msgstr "Přijato" - -#: templates/django_messages/inbox.html:10 -#: templates/django_messages/outbox.html:10 -#: templates/django_messages/trash.html:10 -msgid "Action" -msgstr "Akce" - -#: templates/django_messages/inbox.html:22 -#: templates/django_messages/outbox.html:19 -#: templates/django_messages/trash.html:19 -#: templates/django_messages/view.html:13 -msgid "DATETIME_FORMAT" -msgstr "j. E Y, H:i" - -#: templates/django_messages/inbox.html:23 -#: templates/django_messages/outbox.html:20 -msgid "delete" -msgstr "smazat" - -#: templates/django_messages/inbox.html:29 -#: templates/django_messages/outbox.html:26 -#: templates/django_messages/trash.html:26 -msgid "No messages." -msgstr "Žádné zprávy." - -#: templates/django_messages/new_message.html:4 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Dobrý den %(recipient)s,\n" -"\n" -"máte novou soukromou zprávu od %(sender)s\n" -"s následujícím obsahem:" - -#: templates/django_messages/new_message.html:12 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Odesláno z %(site_url)s" - -#: templates/django_messages/new_message.html:14 -#: templates/django_messages/view.html:20 -msgid "Reply" -msgstr "Odpovědět" - -#: templates/django_messages/outbox.html:10 -msgid "Sent" -msgstr "Odesláno" - -#: templates/django_messages/trash.html:6 -msgid "Deleted Messages" -msgstr "Smazané zprávy" - -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:12 -msgid "Date" -msgstr "Datum" - -#: templates/django_messages/trash.html:20 -msgid "undelete" -msgstr "obnovit" - -#: templates/django_messages/trash.html:29 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Smazané zprávy jsou z koše odstraňovány v nepravidelných intervalech, " -"nespoléhejte se na koš jako dlouhodobé úložiště." - -#: templates/django_messages/view.html:6 -msgid "View Message" -msgstr "Zobrazit zprávu" - -#: templates/django_messages/view.html:22 -msgid "Delete" -msgstr "Smazat" - -#: templates/notification/messages_deleted/full.txt:1 -#, python-format -msgid "You have deleted the message '%(message)s'." -msgstr "Smazali jste zprávu '%(message)s'." - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "" -"Smazali jste zprávu %(message)s." - -#: templates/notification/messages_received/full.txt:1 -#, python-format -msgid "" -"%(message_sender)s has sent you a message:\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" -msgstr "" -"%(message_sender)s vám napsal/a zprávu:\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Přišla vám zpráva %(message)s " -"od %(message_sender)s." - -#: templates/notification/messages_received/short.txt:1 -#: templates/notification/messages_reply_received/short.txt:1 -#, python-format -msgid "%(notice)s by %(message_sender)s" -msgstr "%(notice)s od %(message_sender)s" - -#: templates/notification/messages_recovered/full.txt:1 -#, python-format -msgid "You have recovered the message '%(message)s'." -msgstr "Obnovili jste zprávu '%(message)s'." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" -"Obnovili jste zprávu %(message)s." - -#: templates/notification/messages_replied/full.txt:1 -#, python-format -msgid "" -"You have replied to '%(message_parent_msg)s' from %(message_recipient)s." -msgstr "" -"Odpověděli jste na '%(message_parent_msg)s' od %(message_recipient)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Odpověděli jste na %(message_parent_msg)s " -"od %(message_recipient)s." - -#: templates/notification/messages_reply_received/full.txt:1 -#, python-format -msgid "" -"%(message_sender)s replied to '%(message_parent_msg)s':\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" -msgstr "" -"%(message_sender)s odpověděl/a na '%(message_parent_msg)s':\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s vám poslal/a odpověď na %(message_parent_msg)s." - -#: templates/notification/messages_sent/full.txt:1 -#, python-format -msgid "You have sent the message '%(message)s' to %(message_recipient)s." -msgstr "Odeslali jste zprávu '%(message)s' uživateli %(message_recipient)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to " -"%(message_recipient)s." -msgstr "" -"Odeslali jste zprávu %(message)s uživateli " -"%(message_recipient)s." - -#: utils.py:26 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s napsal:\n" -"%(body)s" - -#: utils.py:54 -#, python-format -msgid "Re%(prefix)s: %(subject)s" -msgstr "Re%(prefix)s: %(subject)s" - -#: utils.py:60 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nová zpráva: %(subject)s" - -#: views.py:79 views.py:116 -msgid "Message successfully sent." -msgstr "Zpráva úspěšně odeslána." - -#: views.py:98 views.py:194 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:159 -msgid "Message successfully deleted." -msgstr "Zpráva úspěšně smazána." - -#: views.py:186 -msgid "Message successfully recovered." -msgstr "Zpráva úspěšně obnovena." diff --git a/django_messages/locale/da/LC_MESSAGES/django.po b/django_messages/locale/da/LC_MESSAGES/django.po deleted file mode 100644 index 1689cd8..0000000 --- a/django_messages/locale/da/LC_MESSAGES/django.po +++ /dev/null @@ -1,367 +0,0 @@ -# django-messages in Danish. -# django-messages på Dansk. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Michael Lind Mortensen , 2009. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Modtager" - -#: admin.py:15 -msgid "group" -msgstr "gruppe" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Skaber beskeden for alle brugere eller en gruppe af brugere." - -#: admin.py:23 -msgid "All users" -msgstr "Alle brugere" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Beskeder" - -#: admin.py:45 -msgid "Date/time" -msgstr "Dato/tid" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "De følgende brugernavne er forkerte: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Emne" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Indhold" - -#: management.py:9 -msgid "Message Received" -msgstr "Besked Modtaget" - -#: management.py:9 -msgid "you have received a message" -msgstr "du har modtaget en besked" - -#: management.py:10 -msgid "Message Sent" -msgstr "Besked Afsendt" - -#: management.py:10 -msgid "you have sent a message" -msgstr "du har sendt en besked" - -#: management.py:11 -msgid "Message Replied" -msgstr "Besked Besvaret" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "du har besvaret en besked" - -#: management.py:12 -msgid "Reply Received" -msgstr "Svar Modtaget" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "du har modtaget en besvarelse på en besked" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Besked Slettet" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "du har slettet en besked" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Besked Genskabt" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "du har genskabt en besked" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Afsender" - -#: models.py:53 -msgid "Parent message" -msgstr "Stambesked" - -#: models.py:54 -msgid "sent at" -msgstr "sendt" - -#: models.py:55 -msgid "read at" -msgstr "læst" - -#: models.py:56 -msgid "replied at" -msgstr "besvaret" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Afsender slettet" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Modtager slettet" - -#: models.py:89 -msgid "Messages" -msgstr "Beskeder" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Ny besked: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Besked sendt succesfuldt." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s skrev:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "SV: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Besked slettet succesfuldt." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Besked genskabt succesfuldt." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Indboks" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Sendte Beskeder" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Ny Besked" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Papirkurv" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Skriv Ny Besked" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Send" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Modtaget" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Handling" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "DATETIME_FORMAT" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "slet" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Goddag %(recipient)s,\n" -"\n" -"du har modtaget en privat besked fra %(sender)s med\n" -"følgende indhold:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Sendt fra %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Besvar" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Sendt" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Slettede Beskeder" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Dato" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "genskab" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Slettede beskeder fjernes fra papirkurven med jævne mellemrum. Lad være med " -"at regne med denne funktion til langtidslagring." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Læs Besked" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Slet" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "Du har slettet beskeden %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Du har modtaget beskeden %(message)s fra %" -"(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "Du har genskabt beskeden %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Du har besvaret %(message_parent_msg)s fra %" -"(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s har sendt dig en besvarelse på %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"Du har sendt beskeden %(message)s til %" -"(message_recipient)s." - -#, fuzzy -#~ msgid "You have deleted the message '%(message)s'." -#~ msgstr "Du har slettet beskeden '%(message)s'." - -#, fuzzy -#~ msgid "" -#~ "%(message_sender)s has sent you a message:\n" -#~ "\n" -#~ "%(message)s\n" -#~ "\n" -#~ "%(message_body)s\n" -#~ "\n" -#~ "http://%(current_site)s%(message_url)s" -#~ msgstr "" -#~ "%(message_sender)s har sendt dig en besked:\n" -#~ "\n" -#~ "%(message)s\n" -#~ "\n" -#~ "%(message_body)s\n" -#~ "\n" -#~ "http://%(current_site)s%(message_url)s" - -#~ msgid "%(notice)s by %(message_sender)s" -#~ msgstr "%(notice)s af %(message_sender)s" - -#, fuzzy -#~ msgid "You have recovered the message '%(message)s'." -#~ msgstr "Du har genskabt beskeden '%(message)s'." - -#, fuzzy -#~ msgid "" -#~ "You have replied to '%(message_parent_msg)s' from %(message_recipient)s." -#~ msgstr "Du har besvaret '%(message_parent_msg)s' fra %(message_recipient)s." - -#~ msgid "" -#~ "%(message_sender)s replied to '%(message_parent_msg)s':\n" -#~ "\n" -#~ "%(message)s\n" -#~ "\n" -#~ "%(message_body)s\n" -#~ "\n" -#~ "http://%(current_site)s%(message_url)s" -#~ msgstr "" -#~ "%(message_sender)s besvarede '%(message_parent_msg)s':\n" -#~ "\n" -#~ "%(message)s\n" -#~ "\n" -#~ "%(message_body)s\n" -#~ "\n" -#~ "http://%(current_site)s%(message_url)s" - -#, fuzzy -#~ msgid "You have sent the message '%(message)s' to %(message_recipient)s." -#~ msgstr "Du har sendt beskeden '%(message)s' til %(message_recipient)s." diff --git a/django_messages/locale/de/LC_MESSAGES/django.po b/django_messages/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 29ec615..0000000 --- a/django_messages/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,321 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Empfänger" - -#: admin.py:15 -msgid "group" -msgstr "Gruppe" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" -"Fügt die Nachricht wahlweise für jeden Benutzer der ausgewählten Gruppe " -"hinzu." - -#: admin.py:23 -msgid "All users" -msgstr "Alle Benutzer" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Nachricht" - -#: admin.py:45 -msgid "Date/time" -msgstr "Datum/Zeit" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Die folgenden Benutzernamen sind nicht korrekt: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Betreff" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Inhalt" - -#: management.py:9 -msgid "Message Received" -msgstr "Nachricht erhalten" - -#: management.py:9 -msgid "you have received a message" -msgstr "Du hast eine Nachricht erhalten" - -#: management.py:10 -msgid "Message Sent" -msgstr "Nachricht gesendet" - -#: management.py:10 -msgid "you have sent a message" -msgstr "Du hast eine Nachricht gesendet" - -#: management.py:11 -msgid "Message Replied" -msgstr "Nachricht beantwortet" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "Du hast eine Nachricht beantwortet" - -#: management.py:12 -msgid "Reply Received" -msgstr "Antwort erhalten" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "Du hast eine Antwort auf eine Nachricht erhalten" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Nachricht gelöscht" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "Du hast eine Nachricht gelöscht" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Nachricht wiederhergestellt" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "Du hast eine Nachricht wiederhergestellt" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Absender" - -#: models.py:53 -msgid "Parent message" -msgstr "Übergeordnete Nachricht" - -#: models.py:54 -msgid "sent at" -msgstr "gesendet am" - -#: models.py:55 -msgid "read at" -msgstr "gelesen am" - -#: models.py:56 -msgid "replied at" -msgstr "beantwortet am" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Vom Absender gelöscht" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Vom Empfänger gelöscht" - -#: models.py:89 -msgid "Messages" -msgstr "Nachrichten" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Neue Nachricht: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Nachricht erfolgreich gesendet." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s schrieb:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Nachricht erfolgreich gelöscht." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Nachricht erfolgreich wiederhergestellt." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Posteingang" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Gesendete Nachrichten" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Neue Nachricht" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Papierkorb" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Nachricht verfassen" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Senden" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Erhalten" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Aktion" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "j. N Y, H:i" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "löschen" - -#: templates/messages/inbox.html:27 templates/messages/outbox.html:24 -#: templates/messages/trash.html:24 -msgid "No messages." -msgstr "Keine Nachrichten." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Hallo %(recipient)s,\n" -"\n" -"du hast eine private Nachricht von %(sender)s mit\n" -"dem folgenden Inhalt erhalten:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Gesendet von %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Antworten" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Gesendet" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Gelöschte Nachrichten" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Datum" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "wiederherstellen" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Gelöschte Nachrichten werden in unregelmäßigen Intervallen entfernt, verlass " -"dich nicht drauf, dass diese Nachrichten hier lange gespeichert werden." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Nachrichtendetails" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Löschen" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "" -"Du hast die Nachricht %(message)s gelöscht." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Du hast die Nachricht %(message)s von %" -"(message_sender)s erhalten." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" -"Du hast die Nachricht %(message)s " -"wiederhergestellt." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Du hast auf die Nachricht %(message_parent_msg)" -"s von %(message_recipient)s geantwortet." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s hat dir eine Antwort auf %(message_parent_msg)s gesendet." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"Du hast die Nachricht %(message)s an %" -"(message_recipient)s gesendet." diff --git a/django_messages/locale/el/LC_MESSAGES/django.po b/django_messages/locale/el/LC_MESSAGES/django.po deleted file mode 100644 index fe21014..0000000 --- a/django_messages/locale/el/LC_MESSAGES/django.po +++ /dev/null @@ -1,291 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: 2009-09-08 15:50+0200\n" -"Last-Translator: markos \n" -"Language-Team: Markos Gogoulos \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Αποδέκτης" - -#: admin.py:15 -msgid "group" -msgstr "ομάδα" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Δημιουργεί το μήνυμα προαιρετικά για όλους τους χρήστες ή για ομάδα χρηστών." - -#: admin.py:23 -msgid "All users" -msgstr "Όλοι οι χρήστες" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Μήνυμα" - -#: admin.py:45 -msgid "Date/time" -msgstr "Ημερομηνία/Ώρα" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Τα παρακάτω usernames δεν είναι σωστά: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Θέμα" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Κυρίως μέρος" - -#: management.py:9 -msgid "Message Received" -msgstr "Το μήνυμα ελήφθη " - -#: management.py:9 -msgid "you have received a message" -msgstr "έχετε λάβει ένα μήνυμα" - -#: management.py:10 -msgid "Message Sent" -msgstr "Το μήνυμα εστάλει" - -#: management.py:10 -msgid "you have sent a message" -msgstr "έχετε στείλει ένα μήνυμα" - -#: management.py:11 -msgid "Message Replied" -msgstr "Το μήνυμα έχει απαντηθεί" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "έχετε απαντήσει σε ένα μήνυμα" - -#: management.py:12 -msgid "Reply Received" -msgstr "Η απάντηση ελήφθη" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "έχετε λάβει μια απάντηση σε ένα μήνυμα" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Το μήνυμα έχει διαγραφεί" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "διαγράψατε ένα μήνυμα" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Το μήνυμα έχει ανακληθεί" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "έχετε ανακτήσει ένα μήνυμα" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Αποστολέας" - -#: models.py:53 -msgid "Parent message" -msgstr "Μήνυμα Γονέας" - -#: models.py:54 -msgid "sent at" -msgstr "εστάλει στις" - -#: models.py:55 -msgid "read at" -msgstr "αναγνώστηκε στις" - -#: models.py:56 -msgid "replied at" -msgstr "απαντήθηκε στις" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Ο αποστολέας το διέγραψε στις" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Ο αποδέκτης το διέγραψε στις" - -#: models.py:89 -msgid "Messages" -msgstr "Μηνύματα" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "καινούργιο μήνυμα: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Το μήνυμα έχει αποσταλεί με επιτυχία." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s έγραψε:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Το μήνυμα διεγράφει." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Το μήνυμα έχει ανακληθεί επιτυχημένα" - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Εισερχόμενα" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Σταλμένα μηνύματα" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Νέο μήνυμα" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Άχρηστα" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Συντάξτε μήνυμα" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Στείλτε" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Ελήφθη" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Ενέργεια" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "DATETIME_FORMAT" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "διαγράφω" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Γειά χαρά %(recipient)s,\n" -"\n" -"έχετε λάβει ένα προσωπικό μήνυμα από τον/την %(sender)s με\n" -"το ακόλουθο περιεχόμενο:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Εστάλει απο %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Απαντήστε" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Απεσταλμένα" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Διαγραμμένα μηνύματα" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Ημερομηνία" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "ξεδιαγράψτε" - -#: templates/messages/trash.html:23 -msgid "Deleted Messages are removed from the trash at unregular intervals, don't rely on this feature for long-time storage." -msgstr "Τα διαγραμμένα μηνύματα απομακρύνονται απο τα Άχρηστα σε μη τακτά διαστήματα, μη βασίζεστε σε αυτά για μακροχρόνια αποθήκευση." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Προβολή Μηνύματος" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Διαγραφή" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "You have deleted the message %(message)s." -msgstr "Έχετε διαγράψει το μήνυμα %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "You have received the message %(message)s from %(message_sender)s." -msgstr "Έχετε λάβει το μήνυμα %(message)s από τον/την %(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "You have recovered the message %(message)s." -msgstr "Έχετε ανακτήσει το μήνυμα %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "You have replied to %(message_parent_msg)s from %(message_recipient)s." -msgstr "Έχετε απαντήσει στο %(message_parent_msg)sαπό τον/την %(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "Ο/η %(message_sender)s σας έστειλε μια απάντηση στο %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "You have sent the message %(message)s to %(message_recipient)s." -msgstr "Έχετε στείλει το μήνυμα %(message)s στον/στην %(message_recipient)s." diff --git a/django_messages/locale/es/LC_MESSAGES/django.po b/django_messages/locale/es/LC_MESSAGES/django.po deleted file mode 100644 index 49d27b3..0000000 --- a/django_messages/locale/es/LC_MESSAGES/django.po +++ /dev/null @@ -1,314 +0,0 @@ -# django-messages in Spanish. -# django-messages en Español. -# Copyright (C) 2008 -# This file is distributed under the same license as the django-messages package. -# Maria Guadalupe Paz Urrea , 2008. -# Alfonso Bernardo Harita Rascón , 2008. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Destinatario" - -#: admin.py:15 -msgid "group" -msgstr "" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" - -#: admin.py:23 -msgid "All users" -msgstr "" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Mensaje" - -#: admin.py:45 -#, fuzzy -msgid "Date/time" -msgstr "Fecha" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Los siguientes usuarios son incorrectos: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Asunto" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Cuerpo" - -#: management.py:9 -msgid "Message Received" -msgstr "Mensaje Recibido" - -#: management.py:9 -msgid "you have received a message" -msgstr "ha recibido un mensaje" - -#: management.py:10 -msgid "Message Sent" -msgstr "Mensaje Enviado" - -#: management.py:10 -msgid "you have sent a message" -msgstr "ha enviado un mensaje" - -#: management.py:11 -msgid "Message Replied" -msgstr "Mensaje Respondido" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "ha respondido un mensaje" - -#: management.py:12 -msgid "Reply Received" -msgstr "Respuesta Recibida" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "ha recibido una respuesta a un mensaje" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Mensaje Eliminado" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "ha eliminado un mensaje" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Mensaje Recuperado" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "ha recuperado un mensaje" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Emisor" - -#: models.py:53 -msgid "Parent message" -msgstr "Mensaje padre" - -#: models.py:54 -msgid "sent at" -msgstr "enviado" - -#: models.py:55 -msgid "read at" -msgstr "leído" - -#: models.py:56 -msgid "replied at" -msgstr "respondido" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Emisor borrado" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Destinatario borrado" - -#: models.py:89 -msgid "Messages" -msgstr "Mensajes" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nuevo Mensaje: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Se envió con éxito el mensaje." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s escribió:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Se eliminó con éxito el mensaje." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Se recuperó con éxito el mensaje." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Bandeja de entrada" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Mensajes Enviados" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nuevo Mensaje" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Papelera" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Redactar Mensaje" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Enviar" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Recibido" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Acción" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "eliminar" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Hola %(recipient)s,\n" -"\n" -"ha recibido un mensaje de %(sender)s con\n" -"el siguiente contenido:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Enviado desde %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Responder" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Enviado" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Mensajes Eliminados" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Fecha" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "recuperar" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Los Mensajes Eliminados son borrados de la Papelera a intérvalos irregulares," -"no se confíe en esta característica para almacenamiento a largo plazo." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Ver Mensaje" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Eliminar" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "ha borrado el mensaje %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"ha recibido el mensaje %(message)s de %" -"(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "ha recuperado el mensaje %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"ha respondido a %(message_parent_msg)s de %" -"(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s le ha enviado una respuesta a %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"ha enviado el mensaje %(message)s a %" -"(message_recipient)s." diff --git a/django_messages/locale/es_AR/LC_MESSAGES/django.po b/django_messages/locale/es_AR/LC_MESSAGES/django.po deleted file mode 100644 index 6de0f0f..0000000 --- a/django_messages/locale/es_AR/LC_MESSAGES/django.po +++ /dev/null @@ -1,312 +0,0 @@ -# django-messages in Spanish Argentina. -# django-messages en Español Argentina. -# Copyright (C) 2008 -# This file is distributed under the same license as the django-messages package. -# Cecilia Lorena Puccinelli , 2008. -# Juan José Conti , 2008. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Destinatario" - -#: admin.py:15 -msgid "group" -msgstr "" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" - -#: admin.py:23 -msgid "All users" -msgstr "" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Mensaje" - -#: admin.py:45 -#, fuzzy -msgid "Date/time" -msgstr "Fecha" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Asunto" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Cuerpo" - -#: management.py:9 -msgid "Message Received" -msgstr "Mensaje Recibido" - -#: management.py:9 -msgid "you have received a message" -msgstr "ha recibido un mensaje" - -#: management.py:10 -msgid "Message Sent" -msgstr "Mensaje Enviado" - -#: management.py:10 -msgid "you have sent a message" -msgstr "ha enviado un mensaje" - -#: management.py:11 -msgid "Message Replied" -msgstr "Mensaje Respondido" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "ha respondido un mensaje" - -#: management.py:12 -msgid "Reply Received" -msgstr "Respuesta Recibida" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "ha recibido una respuesta a un mensaje" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Mensaje Eliminado" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "ha eliminado un mensaje" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Mensaje Recuperado" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "ha recuperado un mensaje" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Emisor" - -#: models.py:53 -msgid "Parent message" -msgstr "Mensaje padre" - -#: models.py:54 -msgid "sent at" -msgstr "enviado" - -#: models.py:55 -msgid "read at" -msgstr "leído" - -#: models.py:56 -msgid "replied at" -msgstr "respondido" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Emisor borrado" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Destinatario borrado" - -#: models.py:89 -msgid "Messages" -msgstr "Mensajes" - -#: utils.py:27 -#, fuzzy, python-format -msgid "New Message: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Se envió con éxito el mensaje." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s escribió:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Se eliminó con éxito el mensaje." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Se recuperó con éxito el mensaje." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Bandeja de entrada" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Mensajes Enviados" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nuevo Mensaje" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Papelera" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Redactar Mensaje" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Enviar" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Recibido" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Acción" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "eliminar" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Enviado desde %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Responder" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Enviado" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Mensajes Eliminados" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Fecha" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "recuperar" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Los Mensajes Eliminados son borrados de la Papelera a intérvalos irregulares," -"no se confíe en esta característica para almacenamiento a largo plazo." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Ver Mensaje" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Eliminar" - -#: templates/notification/messages_deleted/notice.html:1 -#, fuzzy, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "ha eliminado el mensaje %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, fuzzy, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "ha recibido un mensaje de %(sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, fuzzy, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "ha recuperado el mensaje %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, fuzzy, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "ha respondido a %(message)s de %(recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, fuzzy, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(sender)s le ha enviado una respuesta a %(message)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" - -#~ msgid "There is no user with this username." -#~ msgstr "No hay ningún usuario con ese nombre." - -#~ msgid "you have sent a message to %(recipient)s." -#~ msgstr "ha enviado un mensaje a %(recipient)s." - -#~ msgid "New Message:" -#~ msgstr "Mensaje Nuevo" diff --git a/django_messages/locale/fa/LC_MESSAGES/django.po b/django_messages/locale/fa/LC_MESSAGES/django.po deleted file mode 100644 index b7932d4..0000000 --- a/django_messages/locale/fa/LC_MESSAGES/django.po +++ /dev/null @@ -1,357 +0,0 @@ -# django-messages fari translations -# Copyright (C) 2012 Hassan Zamani -# This file is distributed under the same license as the djagno-messages package. -# Hassan Zamani , 2012. -# -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-27 12:44+0430\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"First-Translator: Mohammad Hamidi Esfahani" -"Last-Translator: Hassan Zamani \n" -"Language-Team: LANGUAGE \n" -"Language: fa\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0\n" - -#: admin.py:19 forms.py:20 models.py:52 -#: templates/django_messages/outbox.html:8 -#: templates/django_messages/view.html:12 -msgid "Recipient" -msgstr "گیرنده" - -#: admin.py:21 -msgid "group" -msgstr "گروه" - -#: admin.py:22 -msgid "Creates the message optionally for all users or a group of users." -msgstr "ارسال پیام به همه کاربران یا گروهی از آن‌ها." - -#: admin.py:29 -msgid "All users" -msgstr "تمامی کاربران" - -#: admin.py:44 models.py:88 -msgid "Message" -msgstr "پیام" - -#: admin.py:51 -msgid "Date/time" -msgstr "تاریخ/ساعت" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "این کاربرها صحیح نمی‌باشند: %(users)s" - -#: forms.py:21 models.py:49 templates/django_messages/inbox.html:8 -#: templates/django_messages/outbox.html:8 -#: templates/django_messages/trash.html:8 -#: templates/django_messages/view.html:6 -msgid "Subject" -msgstr "موضوع" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "متن" - - -#: management.py:9 -msgid "Message Received" -msgstr "پیام دریافت‌شد" - -#: management.py:9 -msgid "you have received a message" -msgstr "شما یک پیام دریافت کرده‌اید" - -#: management.py:10 -msgid "Message Sent" -msgstr "پیام ارسال‌شد" - -#: management.py:10 -msgid "you have sent a message" -msgstr "شما یک پیام ارسال کرده‌اید" - -#: management.py:11 -msgid "Message Replied" -msgstr "پیام پاسخ داده‌شد" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "شما به یک پیام پاسخ دادید" - -#: management.py:12 -msgid "Reply Received" -msgstr "پاسخ دریافت‌شد" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "شما پاسخی به یک پیام دریافت کرده‌اید" - -#: management.py:13 -msgid "Message Deleted" -msgstr "پیام حذف گردید" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "شما یک پیام حذف کردید" - -#: management.py:14 -msgid "Message Recovered" -msgstr "پیام بازیابی‌شد" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "شما یک پیام را بازیابی کردید" - -#: models.py:51 templates/django_messages/inbox.html:8 -#: templates/django_messages/trash.html:8 -#: templates/django_messages/view.html:8 -msgid "Sender" -msgstr "فرستنده" - -#: models.py:53 -msgid "Parent message" -msgstr "پیام مرجع" - -#: models.py:54 -msgid "sent at" -msgstr "ارسال شده در" - -#: models.py:55 -msgid "read at" -msgstr "خوانده شده در" - -#: models.py:56 -msgid "replied at" -msgstr "پاسخ داده شده در" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "فرستنده حذف‌شده در" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "گیرنده خذف‌شده در" - -#: models.py:89 -msgid "Messages" -msgstr "پیام ها" - -#: utils.py:26 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s گفت:\n" -"%(body)s" - -#: utils.py:54 -#, python-format -msgid "Re%(prefix)s: %(subject)s" -msgstr "پاسخ%(prefix)s: %(subject)s" - -#: utils.py:60 -#, python-format -msgid "New Message: %(subject)s" -msgstr "پیام جدید: %(subject)s" - -#: views.py:78 views.py:114 -msgid "Message successfully sent." -msgstr "پیام با موفقیت ارسال‌شد." - -#: views.py:121 -#, python-format -msgid "Re: %(subject)s" -msgstr "پاسخ: %(subject)s" - -#: views.py:157 -msgid "Message successfully deleted." -msgstr "پیام با موفقیت حذف‌شد." - -#: views.py:184 -msgid "Message successfully recovered." -msgstr "پیام با موفقیت بازیابی‌شد." - -#: templates/django_messages/base.html:8 -#: templates/django_messages/inbox.html:4 -#: templates/django_messages/new_message.html:10 -msgid "Inbox" -msgstr "صندوق دریافتی" - -#: templates/django_messages/base.html:9 -#: templates/django_messages/outbox.html:4 -msgid "Sent Messages" -msgstr "پیام‌های ارسال‌شده" - -#: templates/django_messages/base.html:10 -msgid "New Message" -msgstr "پیام جدید" - -#: templates/django_messages/base.html:11 -msgid "Trash" -msgstr "پیام‌های حذف‌شده" - -#: templates/django_messages/compose.html:4 -msgid "Compose Message" -msgstr "ایجاد پیام جدید" - -#: templates/django_messages/compose.html:10 -msgid "Send" -msgstr "بفرست" - -#: templates/django_messages/inbox.html:8 -msgid "Received" -msgstr "دریافت‌شد" - -#: templates/django_messages/inbox.html:8 -#: templates/django_messages/outbox.html:8 -#: templates/django_messages/trash.html:8 -msgid "Action" -msgstr "عمل" - -#: templates/django_messages/inbox.html:20 -#: templates/django_messages/outbox.html:17 -#: templates/django_messages/trash.html:17 -#: templates/django_messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "" - -#: templates/django_messages/inbox.html:21 -#: templates/django_messages/outbox.html:18 -msgid "delete" -msgstr "حذف" - -#: templates/django_messages/inbox.html:27 -#: templates/django_messages/outbox.html:24 -#: templates/django_messages/trash.html:24 -msgid "No messages." -msgstr "پیامی وجود ندارد." - -#: templates/django_messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "سلام %(recipient)s,\n" -"\n" -"شما یک پیام خصوصی از %(sender)s دریافت کرده‌اید:" - -#: templates/django_messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "ارسال شده از %(site_url)s" - -#: templates/django_messages/new_message.html:11 -#: templates/django_messages/view.html:18 -msgid "Reply" -msgstr "پاسخ" - -#: templates/django_messages/outbox.html:8 -msgid "Sent" -msgstr "ارسال‌شد" - -#: templates/django_messages/trash.html:4 -msgid "Deleted Messages" -msgstr "پیام های حذف‌شده" - -#: templates/django_messages/trash.html:8 -#: templates/django_messages/view.html:10 -msgid "Date" -msgstr "تاریخ" - -#: templates/django_messages/trash.html:18 -msgid "undelete" -msgstr "بازیابی" - -#: templates/django_messages/trash.html:27 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"پیام‌های حذف‌شده در بازه‌های زمانی مشخصی از اینجا حذف می‌شوند، بنابراین برای نگهداری طولانی مدت از این‌جا استفاده نکنید." - -#: templates/django_messages/view.html:4 -msgid "View Message" -msgstr "نمایش پیام" - -#: templates/django_messages/view.html:20 -msgid "Delete" -msgstr "حذف" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "شما پیام %(message)s را حذف کردید." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "شما پیام جدید %(message)s را از %(message_sender)s دریافت کردید." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "شما پیام %(message)s را بازیابی کردید." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "شما به پیام %(message_parent_msg)s از %(message_recipient)s پاسخ‌دادید." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s پاسخی به %(message_parent_msg)s برای شما ارسال کرده." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to " -"%(message_recipient)s." -msgstr "شما پیام %(message)s را به %(message_recipient)s ارسال‌کردید." - -#~ msgid "context" -#~ msgstr "متن پیام" - -#~ msgid "received at" -#~ msgstr "دریافت شده در" - -#~ msgid "deleted by sender at" -#~ msgstr "حذف شده توسط فرستنده در" - -#~ msgid "deleted by receiver at" -#~ msgstr "حذف شده توسط گیرنده در" - -#~ msgid "Message revert successfully" -#~ msgstr "پیام با موفقیت بازگردانی شد" - -#~ msgid "send message" -#~ msgstr "ارسال پیام" - -#~ msgid "date" -#~ msgstr "تاریخ" - -#~ msgid "revert" -#~ msgstr "بازگردانی" - -#~ msgid "deleted Messages will remove from trash step by step" -#~ msgstr "پیام های حذف شده در فواصل نامنظم از سطل زباله حذف می گردند" - -#~ msgid "not replied yet" -#~ msgstr "هنوز پاسخ داده نشده است" diff --git a/django_messages/locale/fr/LC_MESSAGES/django.po b/django_messages/locale/fr/LC_MESSAGES/django.po deleted file mode 100644 index 207d87f..0000000 --- a/django_messages/locale/fr/LC_MESSAGES/django.po +++ /dev/null @@ -1,408 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: messages\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-03-18 17:46+0100\n" -"PO-Revision-Date: 2008-08-09 21:58+0100\n" -"Last-Translator: Roland Frédéric \n" -"Language-Team: Frédéric Roland \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" - -#: admin.py:21 -msgid "group" -msgstr "groupe" - -#: admin.py:22 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" -"Créé le message en option pour tous les utilisateurs ou un groupe " -"d'utilisateurs." - -#: admin.py:30 -msgid "All users" -msgstr "Tous les utilisateurs" - -#: admin.py:48 models.py:91 -msgid "Message" -msgstr "Message" - -#: admin.py:55 -msgid "Date/time" -msgstr "Date/heure" - -#: apps.py:6 models.py:92 -msgid "Messages" -msgstr "Messages" - -#: fields.py:56 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Les noms d'utilisateurs suivants sont incorrects : %(users)s" - -#: forms.py:18 models.py:55 templates/django_messages/outbox.html:10 -#: templates/django_messages/view.html:14 -msgid "Recipient" -msgstr "Destinataire" - -#: forms.py:19 models.py:52 templates/django_messages/inbox.html:10 -#: templates/django_messages/outbox.html:10 -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:8 -msgid "Subject" -msgstr "Sujet" - -#: forms.py:20 models.py:53 -msgid "Body" -msgstr "Message" - -#: management.py:9 -msgid "Message Received" -msgstr "Message Reçu" - -#: management.py:9 -msgid "you have received a message" -msgstr "vous avez reçu un message" - -#: management.py:10 -msgid "Message Sent" -msgstr "Message Envoyé" - -#: management.py:10 -msgid "you have sent a message" -msgstr "vous avez envoyé un message" - -#: management.py:11 -msgid "Message Replied" -msgstr "Message Répondu" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "vous avez répondu à un message" - -#: management.py:12 -msgid "Reply Received" -msgstr "Réponse Reçue" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "vous avez reçu une réponse à un message" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Message Effacé" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "vous avez effacé un message" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Message Récupéré" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "vous avez récupéré un message" - -#: models.py:54 templates/django_messages/inbox.html:10 -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:10 -msgid "Sender" -msgstr "Expéditeur" - -#: models.py:56 -msgid "Parent message" -msgstr "Message parent" - -#: models.py:57 -msgid "sent at" -msgstr "envoyé à" - -#: models.py:58 -msgid "read at" -msgstr "lu à" - -#: models.py:59 -msgid "replied at" -msgstr "répondu à" - -#: models.py:60 -msgid "Sender deleted at" -msgstr "Expéditeur effacé à" - -#: models.py:61 -msgid "Recipient deleted at" -msgstr "Destinataire effacé à" - -#: templates/django_messages/base.html:8 -#: templates/django_messages/inbox.html:6 -#: templates/django_messages/new_message.html:13 -msgid "Inbox" -msgstr "Boîte de réception" - -#: templates/django_messages/base.html:9 -#: templates/django_messages/outbox.html:6 -msgid "Sent Messages" -msgstr "Messages envoyés" - -#: templates/django_messages/base.html:10 -msgid "New Message" -msgstr "Nouveau Message" - -#: templates/django_messages/base.html:11 -msgid "Trash" -msgstr "Poubelle" - -#: templates/django_messages/compose.html:4 -msgid "Compose Message" -msgstr "Composer Message" - -#: templates/django_messages/compose.html:10 -msgid "Send" -msgstr "Envoyer" - -#: templates/django_messages/inbox.html:10 -msgid "Received" -msgstr "Reçu" - -#: templates/django_messages/inbox.html:10 -#: templates/django_messages/outbox.html:10 -#: templates/django_messages/trash.html:10 -msgid "Action" -msgstr "Action" - -#: templates/django_messages/inbox.html:22 -#: templates/django_messages/outbox.html:19 -#: templates/django_messages/trash.html:19 -#: templates/django_messages/view.html:13 -msgid "DATETIME_FORMAT" -msgstr "j F Y, G:i" - -#: templates/django_messages/inbox.html:23 -#: templates/django_messages/outbox.html:20 -msgid "delete" -msgstr "effacer" - -#: templates/django_messages/inbox.html:29 -#: templates/django_messages/outbox.html:26 -#: templates/django_messages/trash.html:26 -msgid "No messages." -msgstr "Aucun message." - -#: templates/django_messages/new_message.html:4 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Bonjour %(recipient)s,\n" -"\n" -"vous avez reçu un message privé de %(sender)s avec\n" -"le contenu suivant :" - -#: templates/django_messages/new_message.html:12 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Envoyé depuis %(site_url)s" - -#: templates/django_messages/new_message.html:14 -#: templates/django_messages/view.html:20 -msgid "Reply" -msgstr "Répondre" - -#: templates/django_messages/outbox.html:10 -msgid "Sent" -msgstr "Envoyé" - -#: templates/django_messages/trash.html:6 -msgid "Deleted Messages" -msgstr "Messages Effacés" - -#: templates/django_messages/trash.html:10 -#: templates/django_messages/view.html:12 -msgid "Date" -msgstr "Date" - -#: templates/django_messages/trash.html:20 -msgid "undelete" -msgstr "restaurer" - -#: templates/django_messages/trash.html:29 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Les Messages Effacés sont enlevé de la poubelle a intervalles irréguliers, " -"ne comptez pas sur cette fonctionnalité pour du stockage à long terme." - -#: templates/django_messages/view.html:6 -msgid "View Message" -msgstr "Voir Message" - -#: templates/django_messages/view.html:22 -msgid "Delete" -msgstr "Effacer" - -#: templates/notification/messages_deleted/full.txt:1 -#, python-format -msgid "You have deleted the message '%(message)s'." -msgstr "Vous avez effacé le message '%(message)s'." - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "" -"Vous avez effacé le message %(message)s." - -#: templates/notification/messages_received/full.txt:1 -#, fuzzy, python-format -#| msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgid "" -"%(message_sender)s has sent you a message:\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" -msgstr "" -"%(message_sender)s vous a envoyé une réponse à %(message_parent_msg)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Vous avez reçu le message %(message)s de " -"%(message_sender)s." - -#: templates/notification/messages_received/short.txt:1 -#: templates/notification/messages_reply_received/short.txt:1 -#, python-format -msgid "%(notice)s by %(message_sender)s" -msgstr "" - -#: templates/notification/messages_recovered/full.txt:1 -#, python-format -msgid "You have recovered the message '%(message)s'." -msgstr "vous avez récupéré le message '%(message)s'." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" -"Vous avez récupéré le message %(message)s." - -#: templates/notification/messages_replied/full.txt:1 -#, python-format -msgid "" -"You have replied to '%(message_parent_msg)s' from %(message_recipient)s." -msgstr "" -"Vous avez répondu à '%(message_parent_msg)s' de %(message_recipient)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Vous avez répondu à %(message_parent_msg)s " -"de %(message_recipient)s." - -#: templates/notification/messages_reply_received/full.txt:1 -#, python-format -msgid "" -"%(message_sender)s replied to '%(message_parent_msg)s':\n" -"\n" -"%(message)s\n" -"\n" -"%(message_body)s\n" -"\n" -"http://%(current_site)s%(message_url)s" -msgstr "" - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s vous a envoyé une réponse à %(message_parent_msg)s." - -#: templates/notification/messages_sent/full.txt:1 -#, python-format -msgid "You have sent the message '%(message)s' to %(message_recipient)s." -msgstr "Vous avez envoyé le message '%(message)s' à %(message_recipient)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to " -"%(message_recipient)s." -msgstr "" -"Vous avez envoyé le message %(message)s à " -"%(message_recipient)s." - -#: utils.py:26 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s a écrit:\n" -"%(body)s" - -#: utils.py:54 -#, fuzzy, python-format -#| msgid "Re: %(subject)s" -msgid "Re%(prefix)s: %(subject)s" -msgstr "Re: %(subject)s" - -#: utils.py:60 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nouveau message: %(subject)s" - -#: views.py:79 views.py:116 -msgid "Message successfully sent." -msgstr "Message envoyé avec succès." - -#: views.py:98 views.py:194 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:159 -msgid "Message successfully deleted." -msgstr "Message effacé avec succès." - -#: views.py:186 -msgid "Message successfully recovered." -msgstr "Message récupéré avec succès." - -#~ msgid "There is no user with this username." -#~ msgstr "Il n'y a pas d'utilisateur avec ce nom d'utilisateur." - -#~ msgid "New Message:" -#~ msgstr "Nouveau Message:" - -#~ msgid "You have received a message from %(message_sender)s." -#~ msgstr "Vous avez reçu un message de %(message_sender)s." - -#~ msgid "" -#~ "%(message_sender)s has sent you a reply to " -#~ "'%(message_parent_msg)s'." -#~ msgstr "" -#~ "%(message_sender)s vous a envoyé une " -#~ "réponse à '%(message_parent_msg)s'." diff --git a/django_messages/locale/it/LC_MESSAGES/django.po b/django_messages/locale/it/LC_MESSAGES/django.po deleted file mode 100644 index caf7f9d..0000000 --- a/django_messages/locale/it/LC_MESSAGES/django.po +++ /dev/null @@ -1,317 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Sergio Morstabilini , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: messages\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-03-03 12:31-0700\n" -"PO-Revision-Date: 2010-03-03 21:58+0100\n" -"Last-Translator: Sergio Morstabilini \n" -"Language-Team: Sergio Morstabilini \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-Language: Italian\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Destinatario" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Messaggio" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Oggetto" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Messaggio" - -#: management.py:9 -msgid "Message Received" -msgstr "Messaggio Ricevuto" - -#: management.py:9 -msgid "you have received a message" -msgstr "hai ricevuto un messaggio" - -#: management.py:10 -msgid "Message Sent" -msgstr "Messaggio Inviato" - -#: management.py:10 -msgid "you have sent a message" -msgstr "hai inviato un messaggio" - -#: management.py:11 -msgid "Message Replied" -msgstr "Risposta Inviata" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "hai risposto ad un messaggio" - -#: management.py:12 -msgid "Reply Received" -msgstr "Risposta Ricevuta" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "hai ricevuto una risposta ad un messaggio" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Messaggio Cancellato" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "hai cancellato un messaggio" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Messaggio Ripristinato" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "hai ripristinato un messaggio" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Mittente" - -#: models.py:53 -msgid "Parent message" -msgstr "In risposta a" - -#: models.py:54 -msgid "sent at" -msgstr "inviato il" - -#: models.py:55 -msgid "read at" -msgstr "letto il" - -#: models.py:56 -msgid "replied at" -msgstr "risposto il" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Mittente cancellato il" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Destinatario cancellato il" - -#: models.py:89 -msgid "Messages" -msgstr "Messaggi" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Messaggio inviato con successo." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s ha scritto:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Messaggio cancellato con successo." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Messaggio recuperato con successo." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Messaggi Ricevuti" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Messaggi Inviati" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nuovo Messaggio" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Cestino" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Scrivi Messaggio" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Invia" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Ricevuto" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Azione" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "j F Y, G:i" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "cancella" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Spedito da %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Rispondi" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Spedito" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Messaggi Cancellati" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Data" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "ripristina" - -#: templates/messages/trash.html:23 -msgid "Deleted Messages are removed from the trash at unregular intervals, don't rely on this feature for long-time storage." -msgstr "I messaggi cancellati sono rimossi dal cestino ad intervalli irregolari, non affidatevi a questa cartella per salvare messaggi a lungo termine." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Vedi Messaggio" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Cancella" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "You have deleted the message %(message)s." -msgstr "Hai cancellato il messaggio %(message)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "You have recovered the message %(message)s." -msgstr "Hai ripristinato il messaggio %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "You have received the message %(message)s from %(message_sender)s." -msgstr "Hai ricevuto il messaggio %(message)s da %(message_sender)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s ha mandato una risposta a %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "You have sent the message %(message)s to %(message_recipient)s." -msgstr "Hai inviato il messaggio %(message)s a %(message_recipient)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "You have replied to %(message_parent_msg)s from %(message_recipient)s." -msgstr "Hai risposto a %(message_parent_msg)s ricevuto da %(message_recipient)s." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Ciao %(recipient)s,\n" -"\n" -"hai ricevuto un messaggio privato da %(sender)s con\n" -"il seguente contenuto:" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Crea il messaggio facoltativamente per tutti gli utenti o per un gruppo di utenti." - -#: admin.py:15 -msgid "group" -msgstr "gruppo" - -#: admin.py:23 -msgid "All users" -msgstr "Tutti gli utenti" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "I seguenti nomi utente sono incorretti: %(users)s" - -#: admin.py:45 -msgid "Date/time" -msgstr "Data/ora" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nuovo Messaggio: %(subject)s" - -#~ msgid "There is no user with this username." -#~ msgstr "Non esiste un utente con questo nome." - -#~ msgid "New Message:" -#~ msgstr "Nuovo Messaggio:" - -#~ msgid "You have deleted the message '%(message)s'." -#~ msgstr "Hai cancellato il messaggio '%(message)s'." - -#~ msgid "You have received a message from %(message_sender)s." -#~ msgstr "Hai ricevuto un messaggio da %(message_sender)s." - -#~ msgid "You have recovered the message '%(message)s'." -#~ msgstr "Hai ripristinato il messaggio '%(message)s'." - -#~ msgid "You have replied to '%(message_parent_msg)s' from %(message_recipient)s." -#~ msgstr "Hai risposto a '%(message_parent_msg)s' ricevuto da %(message_recipient)s." - -#~ msgid "%(message_sender)s has sent you a reply to '%(message_parent_msg)s'." -#~ msgstr "%(message_sender)s ha risposto a '%(message_parent_msg)s'." - -#~ msgid "You have sent the message '%(message)s' to %(message_recipient)s." -#~ msgstr "Hai spedito il messaggio '%(message)s' a %(message_recipient)s." diff --git a/django_messages/locale/ko/LC_MESSAGES/django.po b/django_messages/locale/ko/LC_MESSAGES/django.po deleted file mode 100644 index 4e810c7..0000000 --- a/django_messages/locale/ko/LC_MESSAGES/django.po +++ /dev/null @@ -1,292 +0,0 @@ -# django-messages translation for Korean. -# Copyright (C) 2012 Jeong YunWon -# This file is distributed under the same license as the django-messages package. -# Jeong YunWon , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: messages\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: 2012-02-04 10:58+0900\n" -"Last-Translator: Jeong YunWon \n" -"Language-Team: Jeong YunWon \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Korean\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "받는이" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "쪽지" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "제목" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "내용" - -#: management.py:9 -msgid "Message Received" -msgstr "받은 시각" - -#: management.py:9 -msgid "you have received a message" -msgstr "쪽지를 받았습니다" - -#: management.py:10 -msgid "Message Sent" -msgstr "쪽지 보냄" - -#: management.py:10 -msgid "you have sent a message" -msgstr "쪽지를 보냈습니다" - -#: management.py:11 -msgid "Message Replied" -msgstr "쪽지 답장" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "쪽지에 답장하였습니다" - -#: management.py:12 -msgid "Reply Received" -msgstr "답장 받음" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "쪽지에 답장을 받았습니다" - -#: management.py:13 -msgid "Message Deleted" -msgstr "쪽지 지움" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "쪽지를 지웠습니다" - -#: management.py:14 -msgid "Message Recovered" -msgstr "쪽지 되살림" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "쪽지를 되살렸습니다" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "보낸이" - -#: models.py:53 -msgid "Parent message" -msgstr "이전 쪽지" - -#: models.py:54 -msgid "sent at" -msgstr "보낸 시각:" - -#: models.py:55 -msgid "read at" -msgstr "읽은 시각:" - -#: models.py:56 -msgid "replied at" -msgstr "답장 시각:" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "보낸이가 지운 시각:" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "받는이가 지운 시각:" - -#: models.py:89 -msgid "Messages" -msgstr "쪽지" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "쪽지를 보냈습니다." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s 님의 글:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "쪽지를 지웠습니다." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "쪽지를 되살렸습니다." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "받은 편지함" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "보낸 편지함" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "새 쪽지" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "휴지통" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "새 쪽지 쓰기" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "보내기" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "받은 시각" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "할일" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "Y-m-d G:i" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "지우기" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "%(site_url)s 에서 보냄" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "답장" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "보낸 시각" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "지운 쪽지" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "날짜" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "되살리기" - -#: templates/messages/trash.html:23 -msgid "Deleted Messages are removed from the trash at unregular intervals, don't rely on this feature for long-time storage." -msgstr "지운 쪽지는 비정기적으로 휴지통에서 완전히 삭제됩니다. 오래 보관해야 하는 쪽지에 이 기능을 사용하지 마세요." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "쪽지 보기" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "지우기" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "You have deleted the message %(message)s." -msgstr "%(message)s 지윘습니다." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "You have recovered the message %(message)s." -msgstr "%(message)s 되살렸습니다." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "You have received the message %(message)s from %(message_sender)s." -msgstr "%(message_sender)s 님에게 %(message)s 받았습니다." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s 님이 %(message_parent_msg)s 에 답장을 보냈습니다." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "You have sent the message %(message)s to %(message_recipient)s." -msgstr "%(message_recipient)s 님에게 %(message)s 보냈습니다." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "You have replied to %(message_parent_msg)s from %(message_recipient)s." -msgstr "%(message_recipient)s 님의 %(message_parent_msg)s 에 답장하였습니다." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"%(recipient)s 님\n" -"\n" -"%(sender)s 님께 다음 내용으로 쪽지를 받았습니다:" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Creates the message optionally for all users or a group of users." - -#: admin.py:15 -msgid "group" -msgstr "그룹" - -#: admin.py:23 -msgid "All users" -msgstr "모든 사용자" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "올바르지 않은 사용자 이름을 입력하였습니다: %(users)s" - -#: admin.py:45 -msgid "Date/time" -msgstr "날짜/시각" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "새 쪽지: %(subject)s" - diff --git a/django_messages/locale/lt/LC_MESSAGES/django.po b/django_messages/locale/lt/LC_MESSAGES/django.po deleted file mode 100644 index 14a833f..0000000 --- a/django_messages/locale/lt/LC_MESSAGES/django.po +++ /dev/null @@ -1,320 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: 2015-03-24 10:53+0200\n" -"Last-Translator: Saulius Zemaitaitis \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Gavėjas" - -#: admin.py:15 -msgid "group" -msgstr "Grupė" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" -"Sukuria žinutę visiems vartotojams arba grupei pasirinktinai " - - -#: admin.py:23 -msgid "All users" -msgstr "Visi vartotojai" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Žinutė" - -#: admin.py:45 -msgid "Date/time" -msgstr "Data/Laikas" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Šie vartotojų vardai yra neteisingi: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Tema" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Turinys" - -#: management.py:9 -msgid "Message Received" -msgstr "Gauta žinutė" - -#: management.py:9 -msgid "you have received a message" -msgstr "jūs gavote žinutę" - -#: management.py:10 -msgid "Message Sent" -msgstr "Žinutė Išsiųsta" - -#: management.py:10 -msgid "you have sent a message" -msgstr "jūs išsiuntėte žinutę" - -#: management.py:11 -msgid "Message Replied" -msgstr "Žinutė atsakyta" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "jūs atsakėte į žinutę" - -#: management.py:12 -msgid "Reply Received" -msgstr "Gautas atsakymas" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "jūs gavote atsakymą į žinutę" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Žinutė ištrinta" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "jūs ištrynėte žinutę" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Žinutė Atstatyta" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "jūs atstatėte ištrintą žinutę" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Siuntėjas" - -#: models.py:53 -msgid "Parent message" -msgstr "Pirminė žinutė" - -#: models.py:54 -msgid "sent at" -msgstr "išsiųsta" - -#: models.py:55 -msgid "read at" -msgstr "perskaityta" - -#: models.py:56 -msgid "replied at" -msgstr "atsakyta" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Siuntėjas ištrynė" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Gavėjas ištrynė" - -#: models.py:89 -msgid "Messages" -msgstr "Žinutės" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nauja žinutė: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Žinutė sėkmingai išsiųsta." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s parašė:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Ats: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Žinutė sėkmingai ištrinta." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Žinutė sėkmingai atstatyta." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Gautos" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Išsiųstos žinutės" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nauja žinutė" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Ištrintos" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Kurti žinutę" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Siųsti" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Gauta" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Veiksmas" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "Y j. N, H:i" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "ištrinti" - -#: templates/messages/inbox.html:27 templates/messages/outbox.html:24 -#: templates/messages/trash.html:24 -msgid "No messages." -msgstr "Žinučių nėra." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"%(recipient)s,\n" -"\n" -"Gavote asmeninę žinutę nuo %(sender)s su\n" -"šiuo turiniu:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Siųsta iš %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Atsakyti" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Išsiųsta" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Ištrintos žinutės" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Data" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "atstatyti" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Ištrintos žinutės pašalinamos periodiškai, nelaikykite ilgalaikių žinučių " -"šiukšliadėžėje." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Peržiūrėti žinutę" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Ištrinti" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "" -"Ištrynėte žinutę %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Gavote žinutę %(message)s nuo %" -"(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" -"Atstatėte žinutę %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Jūs atsakėte į žinutę %(message_parent_msg)" -"s nuo %(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s atsiuntė atsakymą į %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"Išsiuntėte žinutę %(message)s %" -"(message_recipient)s." diff --git a/django_messages/locale/nl/LC_MESSAGES/django.po b/django_messages/locale/nl/LC_MESSAGES/django.po deleted file mode 100755 index c5b7981..0000000 --- a/django_messages/locale/nl/LC_MESSAGES/django.po +++ /dev/null @@ -1,314 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: django-messages-0.4.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: krisje8 \n" -"Language-Team: krisje8 %(message)s." -msgstr "" -"Je hebt het bericht %(message)s verwijderd." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Je hebt het bericht %(message)s ontvangen " -"van %(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" -"Je hebt het bericht %(message)s hersteld." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Je hebt op %(message_parent_msg)s van %" -"(message_recipient)s geantwoord." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s heeft je een antwoord op %(message_parent_msg)s gestuurd." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"Je hebt het bericht %(message)s naar %" -"(message_recipient)s gestuurd." diff --git a/django_messages/locale/pl/LC_MESSAGES/django.po b/django_messages/locale/pl/LC_MESSAGES/django.po deleted file mode 100644 index bb15d5b..0000000 --- a/django_messages/locale/pl/LC_MESSAGES/django.po +++ /dev/null @@ -1,305 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Odbiorca" - -#: admin.py:15 -msgid "group" -msgstr "" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" - -#: admin.py:23 -msgid "All users" -msgstr "" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Wiadomość" - -#: admin.py:45 -#, fuzzy -msgid "Date/time" -msgstr "Data" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Te nazwy użytkowników są niewłaściwe: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Temat" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Treść" - -#: management.py:9 -msgid "Message Received" -msgstr "Wiadomość otrzymana" - -#: management.py:9 -msgid "you have received a message" -msgstr "otrzymałeś wiadomość" - -#: management.py:10 -msgid "Message Sent" -msgstr "Wiadomość wysłana" - -#: management.py:10 -msgid "you have sent a message" -msgstr "wysłałeś wiadomość" - -#: management.py:11 -msgid "Message Replied" -msgstr "Odpowiedź wysłana" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "odpowiedziałeś na wiadomość" - -#: management.py:12 -msgid "Reply Received" -msgstr "Odpowiedź otrzymana" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "Dostałeś odpowiedź na wiadomość" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Wiadomość skasowana" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "skasowałeś wiadomość" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Wiadomość odzyskana" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "Odzyskałeś skasowaną wiadomość" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Nadawca" - -#: models.py:53 -msgid "Parent message" -msgstr "Poprzednia wiadomość" - -#: models.py:54 -msgid "sent at" -msgstr "wysłano" - -#: models.py:55 -msgid "read at" -msgstr "przeczytano" - -#: models.py:56 -msgid "replied at" -msgstr "odpowiedziano" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Nadawcę skasowano" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Adresata skasowano" - -#: models.py:89 -msgid "Messages" -msgstr "Wiadomości" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nowa wiadomość: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Wiadomość wysłana" - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s napisał:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Odp: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Wiadomość skasowana" - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Wiadomość odzyskana" - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Wiadomości otrzymane" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Wiadomości wysłane" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nowa wiadomość" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Kosz" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Stwórz wiadomość" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Wyślij" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Otrzymane" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "akcja" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "usuń" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Witaj, %(recipient)s,\n" -"\n" -"otrzymałeś od użytkownika %(sender)s wiadomość\n" -"o następującej treści:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Wysłane z adresu %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Odpowiedz" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Wiadomości wysłane" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Wiadomości skasowane" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Data" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "odzyskaj" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Wiadomości są usuwane z Kosza nieregularnie. Nie licz, że zastaniesz je " -"tutaj po dłuższym czasie" - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Zobacz wiadomość" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Usuń" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "" - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "" - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" diff --git a/django_messages/locale/pt_BR/LC_MESSAGES/django.po b/django_messages/locale/pt_BR/LC_MESSAGES/django.po deleted file mode 100644 index ef36d4f..0000000 --- a/django_messages/locale/pt_BR/LC_MESSAGES/django.po +++ /dev/null @@ -1,314 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Diego Martins , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-01 10:24+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: admin.py:19 forms.py:20 models.py:52 templates/messages/outbox.html:8 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Usuário" - -#: admin.py:21 -msgid "group" -msgstr "grupo" - -#: admin.py:22 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Cria a mensagem para todos os usuários ou para um grupo de usuários." - -#: admin.py:29 -msgid "All users" -msgstr "Todos os usuários" - -#: admin.py:44 models.py:88 -msgid "Message" -msgstr "Mensagem" - -#: admin.py:51 -msgid "Date/time" -msgstr "Data/Hora" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Os seguintes nome de usuário estão incorretos: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:8 -#: templates/messages/outbox.html:8 templates/messages/trash.html:8 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Assunto" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Mensagem" - -#: management.py:9 -msgid "Message Received" -msgstr "Mensagem Recebida" - -#: management.py:9 -msgid "you have received a message" -msgstr "Você recebeu uma mensagem" - -#: management.py:10 -msgid "Message Sent" -msgstr "Mensagem Enviada" - -#: management.py:10 -msgid "you have sent a message" -msgstr "Você enviou uma mensagem" - -#: management.py:11 -msgid "Message Replied" -msgstr "Mensagem Respondida" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "Você respondeu uma mensagem" - -#: management.py:12 -msgid "Reply Received" -msgstr "Resposta Recebida" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "Você recebeu uma resposta de uma mensagem" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Mensagem excluída" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "Você excluiu uma mensagem" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Mensagem Recuperada" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "Você recuperou uma mensagem" - -#: models.py:51 templates/messages/inbox.html:8 -#: templates/messages/trash.html:8 templates/messages/view.html:8 -msgid "Sender" -msgstr "Remetente" - -#: models.py:53 -msgid "Parent message" -msgstr "Mensagem pai" - -#: models.py:54 -msgid "sent at" -msgstr "enviado à" - -#: models.py:55 -msgid "read at" -msgstr "lido à" - -#: models.py:56 -msgid "replied at" -msgstr "respondido à" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Remetente excluiu à" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Destinatário excluiu à" - -#: models.py:89 -msgid "Messages" -msgstr "Mensagens" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Nova Mensagem: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Mensagem enviada com sucesso." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s escreveu:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Mensagem excluida com sucesso." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Mensagem recuperada com sucesso." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Caixa de Entrada" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Mensagens Enviadas" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Nova Mensagem" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Lixeira" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Escrever Mensagem" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Enviar" - -#: templates/messages/inbox.html:8 -msgid "Received" -msgstr "Recebida" - -#: templates/messages/inbox.html:8 templates/messages/outbox.html:8 -#: templates/messages/trash.html:8 -msgid "Action" -msgstr "Ação" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -#: templates/messages/trash.html:17 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "DATETIME_FORMAT" - -#: templates/messages/inbox.html:21 templates/messages/outbox.html:18 -msgid "delete" -msgstr "excluir" - -#: templates/messages/inbox.html:27 templates/messages/outbox.html:24 -#: templates/messages/trash.html:24 -msgid "No messages." -msgstr "" - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Ola %(recipient)s,\n" -"\n" -"Você recebeu uma mensagem privada de %(sender)s com\n" -"o seguinte conteúdo:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Enviado de %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Responder" - -#: templates/messages/outbox.html:8 -msgid "Sent" -msgstr "Enviada" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Mensagens Excluidas" - -#: templates/messages/trash.html:8 templates/messages/view.html:10 -msgid "Date" -msgstr "Data" - -#: templates/messages/trash.html:18 -msgid "undelete" -msgstr "recuperar" - -#: templates/messages/trash.html:27 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Mensagens excluidas são removidas da lixeira em intervalos de tempo não " -"regulares,não use a lixeira para armazenar mensagens por muito tempo." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Ver Mensagem" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Excluir" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "Você excluiu a mensagem %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Você recebeu a mensagem %(message)s de %" -"(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "Você recuperou a mensagem %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Você respondeu a mensagem %(message_parent_msg)" -"s de %(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s lhe enviou uma resposta a %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"Você enviou a mensagem %(message)s para %" -"(message_recipient)s." diff --git a/django_messages/locale/ro/LC_MESSAGES/django.po b/django_messages/locale/ro/LC_MESSAGES/django.po deleted file mode 100644 index 9098732..0000000 --- a/django_messages/locale/ro/LC_MESSAGES/django.po +++ /dev/null @@ -1,317 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-11 12:31-0700\n" -"PO-Revision-Date: 2014-05-14 16:59+0200\n" -"Last-Translator: Eduard Luca \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.4\n" - -#: admin.py:13 forms.py:20 models.py:52 templates/messages/outbox.html:7 -#: templates/messages/view.html:12 -msgid "Recipient" -msgstr "Destinatar" - -#: admin.py:15 -msgid "group" -msgstr "grup" - -#: admin.py:16 -msgid "Creates the message optionally for all users or a group of users." -msgstr "" -"Creaza mesajul optional pentru toti utilizatorii sau pentru un grup de " -"utilizatori." - -#: admin.py:23 -msgid "All users" -msgstr "Toti utilizatorii" - -#: admin.py:38 models.py:88 -msgid "Message" -msgstr "Mesaj" - -#: admin.py:45 -msgid "Date/time" -msgstr "Data/ora" - -#: fields.py:53 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "Urmatoarele nume de utilizatori nu sunt corecte: %(users)s" - -#: forms.py:21 models.py:49 templates/messages/inbox.html:7 -#: templates/messages/outbox.html:7 templates/messages/trash.html:7 -#: templates/messages/view.html:6 -msgid "Subject" -msgstr "Subiect" - -#: forms.py:22 models.py:50 -msgid "Body" -msgstr "Continut" - -#: management.py:9 -msgid "Message Received" -msgstr "Mesaj Primit" - -#: management.py:9 -msgid "you have received a message" -msgstr "ati primit un mesaj nou" - -#: management.py:10 -msgid "Message Sent" -msgstr "Mesaj Trimis" - -#: management.py:10 -msgid "you have sent a message" -msgstr "ati trimis un mesaj" - -#: management.py:11 -msgid "Message Replied" -msgstr "Mesaj Raspuns" - -#: management.py:11 -msgid "you have replied to a message" -msgstr "ati raspuns la un mesaj" - -#: management.py:12 -msgid "Reply Received" -msgstr "Raspuns Primit" - -#: management.py:12 -msgid "you have received a reply to a message" -msgstr "ati primit un raspuns la un mesaj" - -#: management.py:13 -msgid "Message Deleted" -msgstr "Mesaj Sters" - -#: management.py:13 -msgid "you have deleted a message" -msgstr "ati sters un mesaj" - -#: management.py:14 -msgid "Message Recovered" -msgstr "Mesaj Recuperat" - -#: management.py:14 -msgid "you have undeleted a message" -msgstr "ati recuperat un mesaj" - -#: models.py:51 templates/messages/inbox.html:7 -#: templates/messages/trash.html:7 templates/messages/view.html:8 -msgid "Sender" -msgstr "Expeditor" - -#: models.py:53 -msgid "Parent message" -msgstr "Mesaj parinte" - -#: models.py:54 -msgid "sent at" -msgstr "trimis" - -#: models.py:55 -msgid "read at" -msgstr "citit" - -#: models.py:56 -msgid "replied at" -msgstr "raspuns in" - -#: models.py:57 -msgid "Sender deleted at" -msgstr "Sters la expeditor" - -#: models.py:58 -msgid "Recipient deleted at" -msgstr "Sters la destinatar" - -#: models.py:89 -msgid "Messages" -msgstr "Mesaje" - -#: utils.py:27 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Mesaj Nou: %(subject)s" - -#: views.py:78 views.py:112 -msgid "Message successfully sent." -msgstr "Mesaj trimis cu succes." - -#: views.py:118 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s a scris:\n" -"%(body)s" - -#: views.py:122 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: views.py:158 -msgid "Message successfully deleted." -msgstr "Mesaj sters cu succes." - -#: views.py:185 -msgid "Message successfully recovered." -msgstr "Mesaj recuperat cu succes." - -#: templates/messages/base.html:8 templates/messages/inbox.html:4 -#: templates/messages/new_message.html:10 -msgid "Inbox" -msgstr "Primite" - -#: templates/messages/base.html:9 templates/messages/outbox.html:4 -msgid "Sent Messages" -msgstr "Trimise" - -#: templates/messages/base.html:10 -msgid "New Message" -msgstr "Mesaj Nou" - -#: templates/messages/base.html:11 -msgid "Trash" -msgstr "Cos de Gunoi" - -#: templates/messages/compose.html:4 -msgid "Compose Message" -msgstr "Scrie un Mesaj" - -#: templates/messages/compose.html:9 -msgid "Send" -msgstr "Trimite" - -#: templates/messages/inbox.html:7 -msgid "Received" -msgstr "Primit" - -#: templates/messages/inbox.html:7 templates/messages/outbox.html:7 -#: templates/messages/trash.html:7 -msgid "Action" -msgstr "Actiune" - -#: templates/messages/inbox.html:19 templates/messages/outbox.html:16 -#: templates/messages/trash.html:16 templates/messages/view.html:11 -msgid "DATETIME_FORMAT" -msgstr "j. N Y, H:i" - -#: templates/messages/inbox.html:20 templates/messages/outbox.html:17 -msgid "delete" -msgstr "sterge" - -#: templates/messages/inbox.html:27 templates/messages/outbox.html:24 -#: templates/messages/trash.html:24 -msgid "No messages." -msgstr "Nu sunt mesaje." - -#: templates/messages/new_message.html:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Buna %(recipient)s,\n" -"\n" -"ati primit un mesaj privat de la %(sender)s cu\n" -"continutul:" - -#: templates/messages/new_message.html:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Trimis de %(site_url)s" - -#: templates/messages/new_message.html:11 templates/messages/view.html:18 -msgid "Reply" -msgstr "Raspunde" - -#: templates/messages/outbox.html:7 -msgid "Sent" -msgstr "Trimis" - -#: templates/messages/trash.html:4 -msgid "Deleted Messages" -msgstr "Mesaje Sterse" - -#: templates/messages/trash.html:7 templates/messages/view.html:10 -msgid "Date" -msgstr "Data" - -#: templates/messages/trash.html:17 -msgid "undelete" -msgstr "recupereaza" - -#: templates/messages/trash.html:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Mesajele sterse sunt inlaturate din sistem la intervale neregulate, nu va " -"bazati pe stocarea acestor date." - -#: templates/messages/view.html:4 -msgid "View Message" -msgstr "Vizualizati Mesaj" - -#: templates/messages/view.html:20 -msgid "Delete" -msgstr "Stergere" - -#: templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "Ati sters mesajul %(message)s." - -#: templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Ati primit mesajul %(message)s von " -"%(message_sender)s." - -#: templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "Ati recuperat mesajul %(message)s." - -#: templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Ati raspuns la mesajul %(message_parent_msg)s von %(message_recipient)s." - -#: templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s a raspuns la mesajul %(message_parent_msg)s." - -#: templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to " -"%(message_recipient)s." -msgstr "" -"Ati trimis mesajul %(message)s an " -"%(message_recipient)s." diff --git a/django_messages/locale/ru/LC_MESSAGES/django.po b/django_messages/locale/ru/LC_MESSAGES/django.po deleted file mode 100644 index e1f590c..0000000 --- a/django_messages/locale/ru/LC_MESSAGES/django.po +++ /dev/null @@ -1,332 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Michail Sychev m.sychev@axion-rti.ru, 2009 -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-28 12:46+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" - -#: django_messages/admin.py:21 -msgid "group" -msgstr "Группа" - -#: django_messages/admin.py:22 -msgid "Creates the message optionally for all users or a group of users." -msgstr "Создать сообщения опционально для всех пользователей или группы" - -#: django_messages/admin.py:30 -msgid "All users" -msgstr "Все пользователи" - -#: django_messages/admin.py:48 django_messages/models.py:91 -msgid "Message" -msgstr "Сообщение" - -#: django_messages/admin.py:55 -msgid "Date/time" -msgstr "Дата/Время" - -#: django_messages/apps.py:6 django_messages/models.py:92 -msgid "Messages" -msgstr "Сообщения" - -#: django_messages/forms.py:21 django_messages/models.py:55 -#: django_messages/templates/django_messages/compose.html:14 -#: django_messages/templates/django_messages/outbox.html:9 -#: django_messages/templates/django_messages/view.html:13 -msgid "Recipient" -msgstr "Получатель" - -#: django_messages/forms.py:27 django_messages/models.py:52 -#: django_messages/templates/django_messages/compose.html:23 -#: django_messages/templates/django_messages/inbox.html:9 -#: django_messages/templates/django_messages/outbox.html:9 -#: django_messages/templates/django_messages/trash.html:9 -#: django_messages/templates/django_messages/view.html:7 -msgid "Subject" -msgstr "Тема" - -#: django_messages/forms.py:31 django_messages/models.py:53 -#: django_messages/templates/django_messages/compose.html:32 -msgid "Body" -msgstr "Сообщение" - -#: django_messages/management.py:9 -msgid "Message Received" -msgstr "Сообщение получено" - -#: django_messages/management.py:9 -msgid "you have received a message" -msgstr "вы получили сообщение" - -#: django_messages/management.py:10 -msgid "Message Sent" -msgstr "Сообщение отправлено" - -#: django_messages/management.py:10 -msgid "you have sent a message" -msgstr "Вы отправили сообщение" - -#: django_messages/management.py:11 -msgid "Message Replied" -msgstr "Сообщение отвечено" - -#: django_messages/management.py:11 -msgid "you have replied to a message" -msgstr "вы ответили на сообщение" - -#: django_messages/management.py:12 -msgid "Reply Received" -msgstr "Ответ получен" - -#: django_messages/management.py:12 -msgid "you have received a reply to a message" -msgstr "вы получили ответ на сообщение" - -#: django_messages/management.py:13 -msgid "Message Deleted" -msgstr "Сообщение удалено" - -#: django_messages/management.py:13 -msgid "you have deleted a message" -msgstr "вы удалили сообщение" - -#: django_messages/management.py:14 -msgid "Message Recovered" -msgstr "Сообщение восстановлено" - -#: django_messages/management.py:14 -msgid "you have undeleted a message" -msgstr "вы восстановили сообщение" - -#: django_messages/models.py:54 -#: django_messages/templates/django_messages/inbox.html:9 -#: django_messages/templates/django_messages/trash.html:9 -#: django_messages/templates/django_messages/view.html:9 -msgid "Sender" -msgstr "Отправитель" - -#: django_messages/models.py:56 -msgid "Parent message" -msgstr "Родительское сообщение" - -#: django_messages/models.py:57 -msgid "sent at" -msgstr "отправлено" - -#: django_messages/models.py:58 -msgid "read at" -msgstr "прочитано" - -#: django_messages/models.py:59 -msgid "replied at" -msgstr "отвечено" - -#: django_messages/models.py:60 -msgid "Sender deleted at" -msgstr "Отправитель удалил" - -#: django_messages/models.py:61 -msgid "Recipient deleted at" -msgstr "Получатель удалил" - -#: django_messages/templates/django_messages/compose.html:8 -msgid "Compose Message" -msgstr "Новое сообщение" - -#: django_messages/templates/django_messages/compose.html:42 -msgid "Send" -msgstr "Отправить" - -#: django_messages/templates/django_messages/inbox.html:5 -#: django_messages/templates/django_messages/new_message.html:12 -msgid "Inbox" -msgstr "Входящие" - -#: django_messages/templates/django_messages/inbox.html:9 -msgid "Received" -msgstr "Получено" - -#: django_messages/templates/django_messages/inbox.html:9 -#: django_messages/templates/django_messages/outbox.html:9 -#: django_messages/templates/django_messages/trash.html:9 -msgid "Action" -msgstr "Действия" - -#: django_messages/templates/django_messages/inbox.html:21 -#: django_messages/templates/django_messages/outbox.html:18 -#: django_messages/templates/django_messages/trash.html:18 -#: django_messages/templates/django_messages/view.html:12 -msgid "DATETIME_FORMAT" -msgstr "j. N Y, H:i" - -#: django_messages/templates/django_messages/inbox.html:22 -#: django_messages/templates/django_messages/outbox.html:19 -msgid "delete" -msgstr "удалить" - -#: django_messages/templates/django_messages/inbox.html:28 -#: django_messages/templates/django_messages/outbox.html:25 -#: django_messages/templates/django_messages/trash.html:25 -msgid "No messages." -msgstr "Сообщений нет." - -#: django_messages/templates/django_messages/new_message.html:3 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"Hallo %(recipient)s,\n" -"\n" -"Вы получили сообщение от %(sender)s\n" -"со следующим содержанием:" - -#: django_messages/templates/django_messages/new_message.html:11 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "Отправлено %(site_url)s" - -#: django_messages/templates/django_messages/new_message.html:13 -#: django_messages/templates/django_messages/view.html:19 -msgid "Reply" -msgstr "Ответить" - -#: django_messages/templates/django_messages/outbox.html:5 -msgid "Sent Messages" -msgstr "Исходящие" - -#: django_messages/templates/django_messages/outbox.html:9 -msgid "Sent" -msgstr "Отправлено" - -#: django_messages/templates/django_messages/trash.html:5 -msgid "Deleted Messages" -msgstr "Удалённые сообщения" - -#: django_messages/templates/django_messages/trash.html:9 -#: django_messages/templates/django_messages/view.html:11 -msgid "Date" -msgstr "Дата" - -#: django_messages/templates/django_messages/trash.html:19 -msgid "undelete" -msgstr "восстановить" - -#: django_messages/templates/django_messages/trash.html:28 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"Удалённые сообщения очищаются из корзины через произвольные интервалы,не " -"используйте эту возможность как долгосрочное хранилище." - -#: django_messages/templates/django_messages/view.html:5 -msgid "View Message" -msgstr "Просмотр сообщений" - -#: django_messages/templates/django_messages/view.html:21 -msgid "Delete" -msgstr "Удалить" - -#: django_messages/templates/notification/messages_deleted/notice.html:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "Вы удалили сообщение %(message)s." - -#: django_messages/templates/notification/messages_received/notice.html:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"Вы получили сообщение %(message)s от " -"%(message_sender)s." - -#: django_messages/templates/notification/messages_recovered/notice.html:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "Вы восстановили сообщение %(message)s." - -#: django_messages/templates/notification/messages_replied/notice.html:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"Вы ответили на %(message_parent_msg)s от " -"%(message_recipient)s." - -#: django_messages/templates/notification/messages_reply_received/notice.html:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "%(message_sender)s ответил на %(message_parent_msg)s." - -#: django_messages/templates/notification/messages_sent/notice.html:2 -#, python-format -msgid "" -"You have sent the message %(message)s to " -"%(message_recipient)s." -msgstr "" -"Вы отправили сообщение %(message)s " -"получателям %(message_recipient)s." - -#: django_messages/utils.py:20 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s написал:\n" -"%(body)s" - -#: django_messages/utils.py:49 -#, fuzzy, python-format -#| msgid "Re: %(subject)s" -msgid "Re%(prefix)s: %(subject)s" -msgstr "Re: %(subject)s" - -#: django_messages/utils.py:56 -#, python-format -msgid "New Message: %(subject)s" -msgstr "Новое сообщение: %(subject)s" - -#: django_messages/views.py:83 django_messages/views.py:121 -msgid "Message successfully sent." -msgstr "Сообщение успешно отправлено." - -#: django_messages/views.py:103 django_messages/views.py:202 -#, python-format -msgid "Re: %(subject)s" -msgstr "Re: %(subject)s" - -#: django_messages/views.py:165 -msgid "Message successfully deleted." -msgstr "Сообщение успешно удалено." - -#: django_messages/views.py:193 -msgid "Message successfully recovered." -msgstr "Сообщение успешно восстановлено." - -#~ msgid "The following usernames are incorrect: %(users)s" -#~ msgstr "Некорректные имена пользователей: %(users)s" - -#~ msgid "New Message" -#~ msgstr "Новое сообщение" - -#~ msgid "Trash" -#~ msgstr "Удалённые" diff --git a/django_messages/locale/zh_CN/LC_MESSAGES/django.po b/django_messages/locale/zh_CN/LC_MESSAGES/django.po deleted file mode 100644 index 6d91738..0000000 --- a/django_messages/locale/zh_CN/LC_MESSAGES/django.po +++ /dev/null @@ -1,299 +0,0 @@ -# django-messages in Simplify Chinese. -# django-messages 简体中文. -# Copyright (C) 2008 -# This file is distributed under the same license as the django-messages package. -# Gene Wu , 2008. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-10-04 12:00-0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: GENE WU \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: fields.py:39 -#, python-format -msgid "The following usernames are incorrect: %(users)s" -msgstr "以下用户名不正确: %(users)s" - -#: forms.py:23 models.py:53 templates\messages\outbox.html.py:7 -#: templates\messages\view.html.py:12 -msgid "Recipient" -msgstr "收信人" - -#: forms.py:24 models.py:50 templates\messages\inbox.html.py:7 -#: templates\messages\outbox.html.py:7 templates\messages\trash.html.py:7 -#: templates\messages\view.html.py:6 -msgid "Subject" -msgstr "主题" - -#: forms.py:25 models.py:51 -msgid "Body" -msgstr "消息主体" - -#: management.py:10 -msgid "Message Received" -msgstr "收到的消息" - -#: management.py:10 -msgid "you have received a message" -msgstr "你受到了一条消息" - -#: management.py:11 -msgid "Message Sent" -msgstr "消息已发出" - -#: management.py:11 -msgid "you have sent a message" -msgstr "你已发出了一条消息" - -#: management.py:12 -msgid "Message Replied" -msgstr "消息已回复" - -#: management.py:12 -msgid "you have replied to a message" -msgstr "你已回复了一条消息" - -#: management.py:13 -msgid "Reply Received" -msgstr "回复已收到" - -#: management.py:13 -msgid "you have received a reply to a message" -msgstr "你已收到了消息的一条回复" - -#: management.py:14 -msgid "Message Deleted" -msgstr "消息已删除" - -#: management.py:14 -msgid "you have deleted a message" -msgstr "你已删除了一条消息" - -#: management.py:15 -msgid "Message Recovered" -msgstr "消息已恢复" - -#: management.py:15 -msgid "you have undelete a message" -msgstr "你已恢复了一条消息" - -#: models.py:52 templates\messages\inbox.html.py:7 -#: templates\messages\trash.html.py:7 templates\messages\view.html.py:8 -msgid "Sender" -msgstr "发信人" - -#: models.py:54 -msgid "Parent message" -msgstr "原消息" - -#: models.py:55 -msgid "sent at" -msgstr "发送于" - -#: models.py:56 -msgid "read at" -msgstr "阅读于" - -#: models.py:57 -msgid "replied at" -msgstr "回复于" - -#: models.py:58 -msgid "Sender deleted at" -msgstr "发信人删除于" - -#: models.py:59 -msgid "Recipient deleted at" -msgstr "收件人删除于" - -#: models.py:89 -msgid "Message" -msgstr "消息" - -#: models.py:90 -msgid "Messages" -msgstr "消息" - -#: utils.py:29 -#, python-format -msgid "New Message: %(subject)s" -msgstr "新消息: %(subject)s" - -#: views.py:80 views.py:108 -msgid "Message successfully sent." -msgstr "消息已成功发送。" - -#: views.py:114 -#, python-format -msgid "" -"%(sender)s wrote:\n" -"%(body)s" -msgstr "" -"%(sender)s 写道:\n" -"%(body)s" - -#: views.py:118 -#, python-format -msgid "Re: %(subject)s" -msgstr "回复: %(subject)s" - -#: views.py:154 -msgid "Message successfully deleted." -msgstr "消息已成功删除。" - -#: views.py:181 -msgid "Message successfully recovered." -msgstr "消息已成功恢复。" - -#: templates\messages\base.html.py:8 templates\messages\inbox.html.py:4 -#: templates\messages\new_message.html.py:10 -msgid "Inbox" -msgstr "收件箱" - -#: templates\messages\base.html.py:9 templates\messages\outbox.html.py:4 -msgid "Sent Messages" -msgstr "发送的消息" - -#: templates\messages\base.html.py:10 -msgid "New Message" -msgstr "新消息" - -#: templates\messages\base.html.py:11 -msgid "Trash" -msgstr "回收站" - -#: templates\messages\compose.html.py:4 -msgid "Compose Message" -msgstr "撰写消息" - -#: templates\messages\compose.html.py:9 -msgid "Send" -msgstr "发送" - -#: templates\messages\inbox.html.py:7 -msgid "Received" -msgstr "受到于" - -#: templates\messages\inbox.html.py:7 templates\messages\outbox.html.py:7 -#: templates\messages\trash.html.py:7 -msgid "Action" -msgstr "动作" - -#: templates\messages\inbox.html.py:19 -#: templates\messages\outbox.html.py:16 -#: templates\messages\trash.html.py:16 templates\messages\view.html.py:11 -msgid "DATETIME_FORMAT" -msgstr "" - -#: templates\messages\inbox.html.py:20 -#: templates\messages\outbox.html.py:17 -msgid "delete" -msgstr "删除" - -#: templates\messages\new_message.html.py:1 -#, python-format -msgid "" -"Hello %(recipient)s,\n" -"\n" -"you received a private message from %(sender)s with\n" -"the following contents:" -msgstr "" -"%(recipient)s:\n" -"\n" -"你受到一条从%(sender)s发出的私人信息有\n" -"以下内容:" - -#: templates\messages\new_message.html.py:9 -#, python-format -msgid "Sent from %(site_url)s" -msgstr "消息已从%(site_url)s发出" - -#: templates\messages\new_message.html.py:11 -#: templates\messages\view.html.py:18 -msgid "Reply" -msgstr "回复" - -#: templates\messages\outbox.html.py:7 -msgid "Sent" -msgstr "已发出" - -#: templates\messages\trash.html.py:4 -msgid "Deleted Messages" -msgstr "删除的消息" - -#: templates\messages\trash.html.py:7 templates\messages\view.html.py:10 -msgid "Date" -msgstr "日期" - -#: templates\messages\trash.html.py:17 -msgid "undelete" -msgstr "恢复" - -#: templates\messages\trash.html.py:23 -msgid "" -"Deleted Messages are removed from the trash at unregular intervals, don't " -"rely on this feature for long-time storage." -msgstr "" -"删除的消息将定期删除,不要依赖此功能作为长期存储。" -"" - -#: templates\messages\view.html.py:4 -msgid "View Message" -msgstr "浏览消息" - -#: templates\messages\view.html.py:20 -msgid "Delete" -msgstr "删除" - -#: templates\notification\messages_deleted\notice.html.py:1 -#, python-format -msgid "" -"You have deleted the message %(message)s." -msgstr "你已删除了消息%(message)s." - -#: templates\notification\messages_received\notice.html.py:2 -#, python-format -msgid "" -"You have received the message %(message)s " -"from %(message_sender)s." -msgstr "" -"你已收到%(message_sender)s的消息%(message)s。" -"" - -#: templates\notification\messages_recovered\notice.html.py:1 -#, python-format -msgid "" -"You have recovered the message %(message)s." -msgstr "你已恢复了消息%(message)s." - -#: templates\notification\messages_replied\notice.html.py:2 -#, python-format -msgid "" -"You have replied to %(message_parent_msg)s " -"from %(message_recipient)s." -msgstr "" -"你已回复了%(message_recipient)s.发出的消息%(message_parent_msg)s" -"" - -#: templates\notification\messages_reply_received\notice.html.py:2 -#, python-format -msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s." -msgstr "" -"%(message_sender)s已回复你发出的消息:%(message_parent_msg)s." - -#: templates\notification\messages_sent\notice.html.py:2 -#, python-format -msgid "" -"You have sent the message %(message)s to %" -"(message_recipient)s." -msgstr "" -"你已发送消息%(message)s到%" -"(message_recipient)s." diff --git a/django_messages/management.py b/django_messages/management.py deleted file mode 100644 index 2172a0f..0000000 --- a/django_messages/management.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.db.models import signals -from django.conf import settings -from django.utils.translation import ugettext_noop as _ - -if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from notification import models as notification - - def create_notice_types(app, created_models, verbosity, **kwargs): - notification.create_notice_type("messages_received", _("Message Received"), _("you have received a message"), default=2) - notification.create_notice_type("messages_sent", _("Message Sent"), _("you have sent a message"), default=1) - notification.create_notice_type("messages_replied", _("Message Replied"), _("you have replied to a message"), default=1) - notification.create_notice_type("messages_reply_received", _("Reply Received"), _("you have received a reply to a message"), default=2) - notification.create_notice_type("messages_deleted", _("Message Deleted"), _("you have deleted a message"), default=1) - notification.create_notice_type("messages_recovered", _("Message Recovered"), _("you have undeleted a message"), default=1) - - signals.post_syncdb.connect(create_notice_types, sender=notification) -else: - print("Skipping creation of NoticeTypes as notification app not found") diff --git a/django_messages/management/commands/delete_deleted_messages.py b/django_messages/management/commands/delete_deleted_messages.py deleted file mode 100644 index e79483d..0000000 --- a/django_messages/management/commands/delete_deleted_messages.py +++ /dev/null @@ -1,32 +0,0 @@ -import datetime -from django.core.management.base import BaseCommand, CommandError -from django.utils import timezone -from ...models import Message - - -class Command(BaseCommand): - args = '' - help = ( - 'Deletes messages that have been marked as deleted by both the sender ' - 'and recipient. You must provide the minimum age in days.' - ) - - def handle(self, *args, **options): - if len(args) == 0: - raise CommandError('You must provide the minimum age in days.') - elif len(args) > 1: - raise CommandError( - 'This management command accepts only one argument.' - ) - - try: - age_in_days = int(args[0]) - except ValueError: - raise CommandError('"%s" is not an integer.' % args[0]) - - the_date = timezone.now() - datetime.timedelta(days=age_in_days) - - Message.objects.filter( - recipient_deleted_at__lte=the_date, - sender_deleted_at__lte=the_date, - ).delete() diff --git a/django_messages/migrations/0001_initial.py b/django_messages/migrations/0001_initial.py deleted file mode 100644 index 0d7e96e..0000000 --- a/django_messages/migrations/0001_initial.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Message', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('subject', models.CharField(max_length=120, verbose_name='Subject')), - ('body', models.TextField(verbose_name='Body')), - ('sent_at', models.DateTimeField(null=True, verbose_name='sent at', blank=True)), - ('read_at', models.DateTimeField(null=True, verbose_name='read at', blank=True)), - ('replied_at', models.DateTimeField(null=True, verbose_name='replied at', blank=True)), - ('sender_deleted_at', models.DateTimeField(null=True, verbose_name='Sender deleted at', blank=True)), - ('recipient_deleted_at', models.DateTimeField(null=True, verbose_name='Recipient deleted at', blank=True)), - ('parent_msg', models.ForeignKey(related_name='next_messages', verbose_name='Parent message', blank=True, to='django_messages.Message', null=True)), - ('recipient', models.ForeignKey(related_name='received_messages', verbose_name='Recipient', blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ('sender', models.ForeignKey(related_name='sent_messages', verbose_name='Sender', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ['-sent_at'], - 'verbose_name': 'Message', - 'verbose_name_plural': 'Messages', - }, - bases=(models.Model,), - ), - ] diff --git a/django_messages/migrations/0002_auto_20160607_0852.py b/django_messages/migrations/0002_auto_20160607_0852.py deleted file mode 100644 index ce46289..0000000 --- a/django_messages/migrations/0002_auto_20160607_0852.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_messages', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='message', - name='subject', - field=models.CharField(max_length=140, verbose_name='Subject'), - preserve_default=True, - ), - ] diff --git a/django_messages/migrations/__init__.py b/django_messages/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/django_messages/models.py b/django_messages/models.py deleted file mode 100644 index b2f0ae6..0000000 --- a/django_messages/models.py +++ /dev/null @@ -1,105 +0,0 @@ -from django.conf import settings -from django.db import models -from django.utils import timezone -from django.utils.encoding import python_2_unicode_compatible -from django.utils.translation import ugettext_lazy as _ - - -AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User') - - -class MessageManager(models.Manager): - - def inbox_for(self, user): - """ - Returns all messages that were received by the given user and are not - marked as deleted. - """ - return self.filter( - recipient=user, - recipient_deleted_at__isnull=True, - ) - - def outbox_for(self, user): - """ - Returns all messages that were sent by the given user and are not - marked as deleted. - """ - return self.filter( - sender=user, - sender_deleted_at__isnull=True, - ) - - def trash_for(self, user): - """ - Returns all messages that were either received or sent by the given - user and are marked as deleted. - """ - return self.filter( - recipient=user, - recipient_deleted_at__isnull=False, - ) | self.filter( - sender=user, - sender_deleted_at__isnull=False, - ) - - -@python_2_unicode_compatible -class Message(models.Model): - """ - A private message from user to user - """ - subject = models.CharField(_("Subject"), max_length=140) - body = models.TextField(_("Body")) - sender = models.ForeignKey(AUTH_USER_MODEL, related_name='sent_messages', verbose_name=_("Sender")) - recipient = models.ForeignKey(AUTH_USER_MODEL, related_name='received_messages', null=True, blank=True, verbose_name=_("Recipient")) - parent_msg = models.ForeignKey('self', related_name='next_messages', null=True, blank=True, verbose_name=_("Parent message")) - sent_at = models.DateTimeField(_("sent at"), null=True, blank=True) - read_at = models.DateTimeField(_("read at"), null=True, blank=True) - replied_at = models.DateTimeField(_("replied at"), null=True, blank=True) - sender_deleted_at = models.DateTimeField(_("Sender deleted at"), null=True, blank=True) - recipient_deleted_at = models.DateTimeField(_("Recipient deleted at"), null=True, blank=True) - - objects = MessageManager() - - def new(self): - """returns whether the recipient has read the message or not""" - if self.read_at is not None: - return False - return True - - def replied(self): - """returns whether the recipient has written a reply to this message""" - if self.replied_at is not None: - return True - return False - - def __str__(self): - return self.subject - - def get_absolute_url(self): - return 'django_messages:messages_detail', [self.id] - get_absolute_url = models.permalink(get_absolute_url) - - def save(self, **kwargs): - if not self.id: - self.sent_at = timezone.now() - super(Message, self).save(**kwargs) - - class Meta: - ordering = ['-sent_at'] - verbose_name = _("Message") - verbose_name_plural = _("Messages") - - -def inbox_count_for(user): - """ - returns the number of unread messages for the given user but does not - mark them seen - """ - return Message.objects.filter(recipient=user, read_at__isnull=True, recipient_deleted_at__isnull=True).count() - -# fallback for email notification if django-notification could not be found -#if "notification" not in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): -# from django_messages.utils import new_message_email -# signals.post_save.connect(new_message_email, sender=Message) diff --git a/django_messages/templates/base.html b/django_messages/templates/base.html deleted file mode 100644 index 06a5dba..0000000 --- a/django_messages/templates/base.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -{% block content %} - -{% endblock %} - - diff --git a/django_messages/templates/django_messages/compose.html b/django_messages/templates/django_messages/compose.html deleted file mode 100644 index 14d2fbd..0000000 --- a/django_messages/templates/django_messages/compose.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends request.is_ajax|yesno:'nullcont.htm,django_messages/ext.htm' %} -{% load i18n %} - -{% block content %} - -
    -
    -

    {% trans "Compose Message"%}

    -
    -
    -
    {% csrf_token %} - -
    - - -
    - - {{ form.recipient }}{{ form.recipient.errors }} -
    -
    - -
    - - -
    - - {{ form.subject }}{{ form.subject.errors }} -
    -
    - -
    - - -
    - - {{ form.body }}{{ form.body.errors }} -
    -
    - -
    - - -
    - -
    -
    -
    - -{% endblock %} diff --git a/django_messages/templates/django_messages/ext.htm b/django_messages/templates/django_messages/ext.htm deleted file mode 100644 index 1b7e5f4..0000000 --- a/django_messages/templates/django_messages/ext.htm +++ /dev/null @@ -1,43 +0,0 @@ -{% extends request.is_ajax|yesno:'bajax.html,base.html' %} -{% load i18n %} - -{% block main %} - - - - {% include 'message_block.html' %} - - - -
    -
    - {% block content %}{% endblock %} -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/django_messages/templates/django_messages/inbox.html b/django_messages/templates/django_messages/inbox.html deleted file mode 100644 index bda0f48..0000000 --- a/django_messages/templates/django_messages/inbox.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block content %} -

    {% trans "Inbox" %}

    -{% if message_list %} - - - - - -{% for message in message_list %} - - - - - - -{% endfor %} - -
    {% trans "Sender" %}{% trans "Subject" %}{% trans "Received" %}{% trans "Action" %}
    {{ message.sender }} - {% if message.new %}{% endif %} - {% if message.replied %}{% endif %} - {{ message.subject }} - {% if message.replied %}{% endif %} - {% if message.new %}{% endif %}{{ message.sent_at|date:_("DATETIME_FORMAT") }}{% trans "delete" %}
    -{% else %} -

    {% trans "No messages." %}

    -{% endif %} -{% endblock %} \ No newline at end of file diff --git a/django_messages/templates/django_messages/new_message.html b/django_messages/templates/django_messages/new_message.html deleted file mode 100644 index 286fdbf..0000000 --- a/django_messages/templates/django_messages/new_message.html +++ /dev/null @@ -1,13 +0,0 @@ -{% load i18n %} - -{% blocktrans with recipient=message.recipient sender=message.sender %}Hello {{ recipient }}, - -you received a private message from {{ sender }} with -the following contents:{% endblocktrans %} - -{{ message.body|safe }} - --- -{% blocktrans %}Sent from {{ site_url }}{% endblocktrans %} -{% trans "Inbox" %}: {{ site_url }}{% url 'django_messages:messages_inbox' %} -{% trans "Reply" %}: {{ site_url }}{% url 'django_messages:messages_reply' message.pk %} \ No newline at end of file diff --git a/django_messages/templates/django_messages/outbox.html b/django_messages/templates/django_messages/outbox.html deleted file mode 100644 index 8edf7d6..0000000 --- a/django_messages/templates/django_messages/outbox.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "django_messages/base.html" %} -{% load i18n %} - -{% block content %} -

    {% trans "Sent Messages" %}

    -{% if message_list %} - - - - - -{% for message in message_list %} - - - - - - -{% endfor %} - -
    {% trans "Recipient" %}{% trans "Subject" %}{% trans "Sent" %}{% trans "Action" %}
    {{ message.recipient }} - {{ message.subject }} - {{ message.sent_at|date:_("DATETIME_FORMAT") }}{% trans "delete" %}
    -{% else %} -

    {% trans "No messages." %}

    -{% endif %} -{% endblock %} \ No newline at end of file diff --git a/django_messages/templates/django_messages/trash.html b/django_messages/templates/django_messages/trash.html deleted file mode 100644 index 92f6d34..0000000 --- a/django_messages/templates/django_messages/trash.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends "django_messages/base.html" %} -{% load i18n %} - -{% block content %} -

    {% trans "Deleted Messages" %}

    -{% if message_list %} - - - - - -{% for message in message_list %} - - - - - - -{% endfor %} - -
    {% trans "Sender" %}{% trans "Subject" %}{% trans "Date" %}{% trans "Action" %}
    {{ message.sender }} - {{ message.subject }} - {{ message.sent_at|date:_("DATETIME_FORMAT") }}{% trans "undelete" %}
    -{% else %} -

    {% trans "No messages." %}

    -{% endif %} -
    -

    {% trans "Deleted Messages are removed from the trash at unregular intervals, don't rely on this feature for long-time storage." %}

    -{% endblock %} \ No newline at end of file diff --git a/django_messages/templates/django_messages/view.html b/django_messages/templates/django_messages/view.html deleted file mode 100644 index 967565a..0000000 --- a/django_messages/templates/django_messages/view.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "django_messages/base.html" %} -{% load i18n %} - -{% block content %} -

    {% trans "View Message" %}

    -
    -
    {% trans "Subject" %}
    -
    {{ message.subject }}
    -
    {% trans "Sender" %}
    -
    {{ message.sender }}
    -
    {% trans "Date" %}
    -
    {{ message.sent_at|date:_("DATETIME_FORMAT")}}
    -
    {% trans "Recipient" %}
    -
    {{ message.recipient }}
    -
    -{{ message.body|linebreaksbr }}

    - -{% ifequal message.recipient.pk user.pk %} -{% trans "Reply" %} -{% endifequal %} -{% trans "Delete" %} - -{% comment %}Example reply_form integration -{% if reply_form %} -

    {% trans "Compose reply"%}

    -
    -{% csrf_token %} - -{{ reply_form.as_table }} -
    - -
    -{% endif %} -{% endcomment %} -{% endblock %} \ No newline at end of file diff --git a/django_messages/templates/notification/messages_deleted/notice.html b/django_messages/templates/notification/messages_deleted/notice.html deleted file mode 100644 index c4c074d..0000000 --- a/django_messages/templates/notification/messages_deleted/notice.html +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans with message.get_absolute_url as message_url %}You have deleted the message {{ message }}.{% endblocktrans %} diff --git a/django_messages/templates/notification/messages_received/notice.html b/django_messages/templates/notification/messages_received/notice.html deleted file mode 100644 index f8323d7..0000000 --- a/django_messages/templates/notification/messages_received/notice.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with message.get_absolute_url as message_url and message.sender as message_sender %}You have received the message {{ message }} from {{ message_sender }}.{% endblocktrans %} diff --git a/django_messages/templates/notification/messages_recovered/notice.html b/django_messages/templates/notification/messages_recovered/notice.html deleted file mode 100644 index 421a712..0000000 --- a/django_messages/templates/notification/messages_recovered/notice.html +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans with message.get_absolute_url as message_url %}You have recovered the message {{ message }}.{% endblocktrans %} diff --git a/django_messages/templates/notification/messages_replied/notice.html b/django_messages/templates/notification/messages_replied/notice.html deleted file mode 100644 index 386f125..0000000 --- a/django_messages/templates/notification/messages_replied/notice.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with message.parent_msg.get_absolute_url as message_url and message.parent_msg as message_parent_msg and message.recipient as message_recipient %}You have replied to {{ message_parent_msg }} from {{ message_recipient }}.{% endblocktrans %} diff --git a/django_messages/templates/notification/messages_reply_received/notice.html b/django_messages/templates/notification/messages_reply_received/notice.html deleted file mode 100644 index b1c62b6..0000000 --- a/django_messages/templates/notification/messages_reply_received/notice.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with message.get_absolute_url as message_url and message.sender as message_sender and message.parent_msg as message_parent_msg %}{{ message_sender }} has sent you a reply to {{ message_parent_msg }}.{% endblocktrans %} diff --git a/django_messages/templates/notification/messages_sent/notice.html b/django_messages/templates/notification/messages_sent/notice.html deleted file mode 100644 index d30ba14..0000000 --- a/django_messages/templates/notification/messages_sent/notice.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with message.get_absolute_url as message_url and message.recipient as message_recipient %}You have sent the message {{ message }} to {{ message_recipient }}.{% endblocktrans %} diff --git a/django_messages/templatetags/__init__.py b/django_messages/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/django_messages/templatetags/inbox.py b/django_messages/templatetags/inbox.py deleted file mode 100644 index 9b65e34..0000000 --- a/django_messages/templatetags/inbox.py +++ /dev/null @@ -1,45 +0,0 @@ -from django.template import Library, Node, TemplateSyntaxError - -class InboxOutput(Node): - def __init__(self, varname=None): - self.varname = varname - - def render(self, context): - try: - user = context['user'] - count = user.received_messages.filter(read_at__isnull=True, recipient_deleted_at__isnull=True).count() - except (KeyError, AttributeError): - count = '' - if self.varname is not None: - context[self.varname] = count - return "" - else: - return "%s" % (count) - -def do_print_inbox_count(parser, token): - """ - A templatetag to show the unread-count for a logged in user. - Returns the number of unread messages in the user's inbox. - Usage:: - - {% load inbox %} - {% inbox_count %} - - {# or assign the value to a variable: #} - - {% inbox_count as my_var %} - {{ my_var }} - - """ - bits = token.contents.split() - if len(bits) > 1: - if len(bits) != 3: - raise TemplateSyntaxError("inbox_count tag takes either no arguments or exactly two arguments") - if bits[1] != 'as': - raise TemplateSyntaxError("first argument to inbox_count tag must be 'as'") - return InboxOutput(bits[2]) - else: - return InboxOutput() - -register = Library() -register.tag('inbox_count', do_print_inbox_count) diff --git a/django_messages/tests.py b/django_messages/tests.py deleted file mode 100644 index 1f63722..0000000 --- a/django_messages/tests.py +++ /dev/null @@ -1,178 +0,0 @@ -from django.test import TestCase -from django.test.client import Client -from django.core.urlresolvers import reverse -from django.utils import timezone -from django_messages.models import Message -from django_messages.utils import format_subject, format_quote - -from .utils import get_user_model - -User = get_user_model() - - -class SendTestCase(TestCase): - def setUp(self): - self.user1 = User.objects.create_user( - 'user1', 'user1@example.com', '123456') - self.user2 = User.objects.create_user( - 'user2', 'user2@example.com', '123456') - self.msg1 = Message(sender=self.user1, recipient=self.user2, - subject='Subject Text', body='Body Text') - self.msg1.save() - - def testBasic(self): - self.assertEqual(self.msg1.sender, self.user1) - self.assertEqual(self.msg1.recipient, self.user2) - self.assertEqual(self.msg1.subject, 'Subject Text') - self.assertEqual(self.msg1.body, 'Body Text') - self.assertEqual(self.user1.sent_messages.count(), 1) - self.assertEqual(self.user1.received_messages.count(), 0) - self.assertEqual(self.user2.received_messages.count(), 1) - self.assertEqual(self.user2.sent_messages.count(), 0) - - -class DeleteTestCase(TestCase): - def setUp(self): - self.user1 = User.objects.create_user( - 'user3', 'user3@example.com', '123456') - self.user2 = User.objects.create_user( - 'user4', 'user4@example.com', '123456') - self.msg1 = Message(sender=self.user1, recipient=self.user2, - subject='Subject Text 1', body='Body Text 1') - self.msg2 = Message(sender=self.user1, recipient=self.user2, - subject='Subject Text 2', body='Body Text 2') - self.msg1.sender_deleted_at = timezone.now() - self.msg2.recipient_deleted_at = timezone.now() - self.msg1.save() - self.msg2.save() - - def testBasic(self): - self.assertEqual(Message.objects.outbox_for(self.user1).count(), 1) - self.assertEqual( - Message.objects.outbox_for(self.user1)[0].subject, - 'Subject Text 2' - ) - self.assertEqual(Message.objects.inbox_for(self.user2).count(), 1) - self.assertEqual( - Message.objects.inbox_for(self.user2)[0].subject, - 'Subject Text 1' - ) - #undelete - self.msg1.sender_deleted_at = None - self.msg2.recipient_deleted_at = None - self.msg1.save() - self.msg2.save() - self.assertEqual(Message.objects.outbox_for(self.user1).count(), 2) - self.assertEqual(Message.objects.inbox_for(self.user2).count(), 2) - - -class IntegrationTestCase(TestCase): - """ - Test the app from a user perpective using Django's Test-Client. - """ - - T_USER_DATA = [{'username': 'user_1', 'password': '123456', - 'email': 'user_1@example.com'}, - {'username': 'user_2', 'password': '123456', - 'email': 'user_2@example.com'}] - T_MESSAGE_DATA = [{'subject': 'Test Subject 1', - 'body': 'Lorem ipsum\ndolor sit amet\n\nconsectur.'}] - - def setUp(self): - """ create 2 users and a test-client logged in as user_1 """ - self.user_1 = User.objects.create_user(**self.T_USER_DATA[0]) - self.user_2 = User.objects.create_user(**self.T_USER_DATA[1]) - self.c = Client() - self.c.login(username=self.T_USER_DATA[0]['username'], - password=self.T_USER_DATA[0]['password']) - - def testInboxEmpty(self): - """ request the empty inbox """ - response = self.c.get(reverse('django_messages:messages_inbox')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/inbox.html') - self.assertEqual(len(response.context['message_list']), 0) - - def testOutboxEmpty(self): - """ request the empty outbox """ - response = self.c.get(reverse('django_messages:messages_outbox')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/outbox.html') - self.assertEqual(len(response.context['message_list']), 0) - - def testTrashEmpty(self): - """ request the empty trash """ - response = self.c.get(reverse('django_messages:messages_trash')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/trash.html') - self.assertEqual(len(response.context['message_list']), 0) - - def testCompose(self): - """ compose a message step by step """ - response = self.c.get(reverse('django_messages:messages_compose')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/compose.html') - response = self.c.post( - reverse('django_messages:messages_compose'), - { - 'recipient': self.T_USER_DATA[1]['username'], - 'subject': self.T_MESSAGE_DATA[0]['subject'], - 'body': self.T_MESSAGE_DATA[0]['body'] - }) - # successfull sending should redirect to inbox - self.assertEqual(response.status_code, 302) - if 'http' in response['Location']: - self.assertEqual(response['Location'], - "http://testserver%s" % reverse('django_messages:messages_inbox')) - else: - self.assertEqual(response['Location'], reverse('django_messages:messages_inbox')) - - # make sure the message exists in the outbox after sending - response = self.c.get(reverse('django_messages:messages_outbox')) - self.assertEqual(len(response.context['message_list']), 1) - - def testReply(self): - """ test that user_2 can reply """ - # create a message for this test - Message.objects.create(sender=self.user_1, - recipient=self.user_2, - subject=self.T_MESSAGE_DATA[0]['subject'], - body=self.T_MESSAGE_DATA[0]['body']) - # log the user_2 in and check the inbox - self.c.login(username=self.T_USER_DATA[1]['username'], - password=self.T_USER_DATA[1]['password']) - response = self.c.get(reverse('django_messages:messages_inbox')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/inbox.html') - self.assertEqual(len(response.context['message_list']), 1) - pk = getattr(response.context['message_list'][0], 'pk') - # reply to the first message - response = self.c.get(reverse('django_messages:messages_reply', - kwargs={'message_id': pk})) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.templates[0].name, - 'django_messages/compose.html') - self.assertEqual( - response.context['form'].initial['body'], - format_quote(self.user_1, self.T_MESSAGE_DATA[0]['body']) - ) - self.assertEqual( - response.context['form'].initial['subject'], - u"Re: %(subject)s" % {'subject': self.T_MESSAGE_DATA[0]['subject']} - ) - - -class FormatTestCase(TestCase): - """ some tests for helper functions """ - def testSubject(self): - """ test that reply counting works as expected """ - self.assertEqual(format_subject(u"foo bar"), u"Re: foo bar") - self.assertEqual(format_subject(u"Re: foo bar"), u"Re[2]: foo bar") - self.assertEqual(format_subject(u"Re[2]: foo bar"), u"Re[3]: foo bar") - self.assertEqual(format_subject(u"Re[10]: foo bar"), - u"Re[11]: foo bar") diff --git a/django_messages/urls.py b/django_messages/urls.py deleted file mode 100644 index b736988..0000000 --- a/django_messages/urls.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.conf.urls import url - -from django_messages.views import * - -urlpatterns = [ - url(r'^$', inbox, name='messages_inbox'), - url(r'^outbox/$', outbox, name='messages_outbox'), - url(r'^compose/$', compose, name='messages_compose'), - url(r'^compose/(?P[\w.@+-]+)/$', compose, name='messages_compose_to'), - url(r'^reply/(?P[\d]+)/$', reply, name='messages_reply'), - url(r'^view/(?P[\d]+)/$', view, name='messages_detail'), - url(r'^delete/(?P[\d]+)/$', delete, name='messages_delete'), - url(r'^undelete/(?P[\d]+)/$', undelete, name='messages_undelete'), - url(r'^trash/$', trash, name='messages_trash'), -] diff --git a/django_messages/utils.py b/django_messages/utils.py deleted file mode 100644 index a2a1b8b..0000000 --- a/django_messages/utils.py +++ /dev/null @@ -1,99 +0,0 @@ -import re -import django -from django.utils.text import wrap -from django.utils.translation import ugettext, ugettext_lazy as _ -from django.template.loader import render_to_string -from django.conf import settings -from django.core.mail import send_mail - - -def format_quote(sender, body): - """ - Wraps text at 55 chars and prepends each - line with `> `. - Used for quoting messages in replies. - """ - lines = wrap(body, 55).split('\n') - for i, line in enumerate(lines): - lines[i] = "> %s" % line - quote = '\n'.join(lines) - return ugettext(u"%(sender)s wrote:\n%(body)s") % { - 'sender': sender, - 'body': quote - } - - -def format_subject(subject): - """ - Prepends 'Re:' to the subject. To avoid multiple 'Re:'s - a counter is added. - NOTE: Currently unused. First step to fix Issue #48. - FIXME: Any hints how to make this i18n aware are very welcome. - - """ - subject_prefix_re = r'^Re\[(\d*)\]:\ ' - m = re.match(subject_prefix_re, subject, re.U) - prefix = u"" - if subject.startswith('Re: '): - prefix = u"[2]" - subject = subject[4:] - elif m is not None: - try: - num = int(m.group(1)) - prefix = u"[%d]" % (num+1) - subject = subject[6+len(str(num)):] - except: - # if anything fails here, fall back to the old mechanism - pass - - return ugettext(u"Re%(prefix)s: %(subject)s") % { - 'subject': subject, - 'prefix': prefix - } - - -def new_message_email(sender, instance, signal, - subject_prefix=_(u'New Message: %(subject)s'), - template_name="django_messages/new_message.html", - default_protocol=None, - *args, **kwargs): - """ - This function sends an email and is called via Django's signal framework. - Optional arguments: - ``template_name``: the template to use - ``subject_prefix``: prefix for the email subject. - ``default_protocol``: default protocol in site URL passed to template - """ - if default_protocol is None: - default_protocol = getattr(settings, 'DEFAULT_HTTP_PROTOCOL', 'http') - - if 'created' in kwargs and kwargs['created']: - try: - current_domain = getattr(settings, 'DEFAULT_DOMAIN_NAME', 'example.com') - subject = subject_prefix % {'subject': instance.subject} - message = render_to_string(template_name, { - 'site_url': '%s://%s' % (default_protocol, current_domain), - 'message': instance, - }) - if instance.recipient.email != "": - send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, - [instance.recipient.email,]) - except Exception as e: - #print e - pass #fail silently - - -def get_user_model(): - if django.VERSION[:2] >= (1, 5): - from django.contrib.auth import get_user_model - return get_user_model() - else: - from django.contrib.auth.models import User - return User - - -def get_username_field(): - if django.VERSION[:2] >= (1, 5): - return get_user_model().USERNAME_FIELD - else: - return 'username' diff --git a/django_messages/views.py b/django_messages/views.py deleted file mode 100644 index 6c7f556..0000000 --- a/django_messages/views.py +++ /dev/null @@ -1,231 +0,0 @@ -from django.http import Http404, HttpResponseRedirect -from django.shortcuts import render, get_object_or_404 -from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.utils.translation import ugettext as _ -from django.utils import timezone -from django.core.urlresolvers import reverse -from django.conf import settings - -from django_messages.models import Message -from django_messages.forms import ComposeForm -from django_messages.utils import format_quote, get_user_model, get_username_field - - -User = get_user_model() - -if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from notification import models as notification -else: - notification = None - - -@login_required -def inbox(request, template_name='django_messages/inbox.html'): - """ - Displays a list of received messages for the current user. - Optional Arguments: - ``template_name``: name of the template to use. - """ - message_list = Message.objects.inbox_for(request.user) - return render(request, template_name, { - 'message_list': message_list, - }) - - -@login_required -def outbox(request, template_name='django_messages/outbox.html'): - """ - Displays a list of sent messages by the current user. - Optional arguments: - ``template_name``: name of the template to use. - """ - message_list = Message.objects.outbox_for(request.user) - return render(request, template_name, { - 'message_list': message_list, - }) - - -@login_required -def trash(request, template_name='django_messages/trash.html'): - """ - Displays a list of deleted messages. - Optional arguments: - ``template_name``: name of the template to use - Hint: A Cron-Job could periodicly clean up old messages, which are deleted - by sender and recipient. - """ - message_list = Message.objects.trash_for(request.user) - return render(request, template_name, { - 'message_list': message_list, - }) - - -@login_required -def compose(request, recipient=None, form_class=ComposeForm, - template_name='django_messages/compose.html', success_url=None, recipient_filter=None): - """ - Displays and handles the ``form_class`` form to compose new messages. - Required Arguments: None - Optional Arguments: - ``recipient``: username of a `django.contrib.auth` User, who should - receive the message, optionally multiple usernames - could be separated by a '+' - ``form_class``: the form-class to use - ``template_name``: the template to use - ``success_url``: where to redirect after successfull submission - """ - a = request.GET.get('a') - if request.method == "POST": - form = form_class(request.POST, recipient_filter=recipient_filter) - if form.is_valid(): - form.save(sender=request.user) - messages.info(request, _(u"Message successfully sent.")) - if success_url is None: - success_url = reverse('django_messages:messages_inbox') - if 'next' in request.GET: - success_url = request.GET['next'] - return HttpResponseRedirect(success_url) - else: - form = form_class(initial={'recipient': User.objects.filter(pk=a) }) - if recipient is not None: - recipients = [u for u in User.objects.filter(**{'%s__in' % get_username_field(): [r.strip() for r in recipient.split('+')]})] - form.fields['recipient'].initial = recipients - return render(request, template_name, { - 'form': form, - }) - - -@login_required -def reply(request, message_id, form_class=ComposeForm, - template_name='django_messages/compose.html', success_url=None, - recipient_filter=None, quote_helper=format_quote, - subject_template=_(u"Re: %(subject)s"),): - """ - Prepares the ``form_class`` form for writing a reply to a given message - (specified via ``message_id``). Uses the ``format_quote`` helper from - ``messages.utils`` to pre-format the quote. To change the quote format - assign a different ``quote_helper`` kwarg in your url-conf. - - """ - parent = get_object_or_404(Message, id=message_id) - - if parent.sender != request.user and parent.recipient != request.user: - raise Http404 - - if request.method == "POST": - sender = request.user - form = form_class(request.POST, recipient_filter=recipient_filter) - if form.is_valid(): - form.save(sender=request.user, parent_msg=parent) - messages.info(request, _(u"Message successfully sent.")) - if success_url is None: - success_url = reverse('django_messages:messages_inbox') - return HttpResponseRedirect(success_url) - else: - form = form_class(initial={ - 'body': quote_helper(parent.sender, parent.body), - 'subject': subject_template % {'subject': parent.subject}, - 'recipient': [parent.sender,] - }) - return render(request, template_name, { - 'form': form, - }) - - -@login_required -def delete(request, message_id, success_url=None): - """ - Marks a message as deleted by sender or recipient. The message is not - really removed from the database, because two users must delete a message - before it's save to remove it completely. - A cron-job should prune the database and remove old messages which are - deleted by both users. - As a side effect, this makes it easy to implement a trash with undelete. - - You can pass ?next=/foo/bar/ via the url to redirect the user to a different - page (e.g. `/foo/bar/`) than ``success_url`` after deletion of the message. - """ - user = request.user - now = timezone.now() - message = get_object_or_404(Message, id=message_id) - deleted = False - if success_url is None: - success_url = reverse('django_messages:messages_inbox') - if 'next' in request.GET: - success_url = request.GET['next'] - if message.sender == user: - message.sender_deleted_at = now - deleted = True - if message.recipient == user: - message.recipient_deleted_at = now - deleted = True - if deleted: - message.save() - messages.info(request, _(u"Message successfully deleted.")) - if notification: - notification.send([user], "messages_deleted", {'message': message,}) - return HttpResponseRedirect(success_url) - raise Http404 - - -@login_required -def undelete(request, message_id, success_url=None): - """ - Recovers a message from trash. This is achieved by removing the - ``(sender|recipient)_deleted_at`` from the model. - """ - user = request.user - message = get_object_or_404(Message, id=message_id) - undeleted = False - if success_url is None: - success_url = reverse('django_messages:messages_inbox') - if 'next' in request.GET: - success_url = request.GET['next'] - if message.sender == user: - message.sender_deleted_at = None - undeleted = True - if message.recipient == user: - message.recipient_deleted_at = None - undeleted = True - if undeleted: - message.save() - messages.info(request, _(u"Message successfully recovered.")) - if notification: - notification.send([user], "messages_recovered", {'message': message,}) - return HttpResponseRedirect(success_url) - raise Http404 - - -@login_required -def view(request, message_id, form_class=ComposeForm, quote_helper=format_quote, - subject_template=_(u"Re: %(subject)s"), - template_name='django_messages/view.html'): - """ - Shows a single message.``message_id`` argument is required. - The user is only allowed to see the message, if he is either - the sender or the recipient. If the user is not allowed a 404 - is raised. - If the user is the recipient and the message is unread - ``read_at`` is set to the current datetime. - If the user is the recipient a reply form will be added to the - tenplate context, otherwise 'reply_form' will be None. - """ - user = request.user - now = timezone.now() - message = get_object_or_404(Message, id=message_id) - if (message.sender != user) and (message.recipient != user): - raise Http404 - if message.read_at is None and message.recipient == user: - message.read_at = now - message.save() - - context = {'message': message, 'reply_form': None} - if message.recipient == user: - form = form_class(initial={ - 'body': quote_helper(message.sender, message.body), - 'subject': subject_template % {'subject': message.subject}, - 'recipient': [message.sender,] - }) - context['reply_form'] = form - return render(request, template_name, context) diff --git a/djing/settings_example.py b/djing/settings_example.py index fc038d8..6529303 100644 --- a/djing/settings_example.py +++ b/djing/settings_example.py @@ -16,6 +16,11 @@ DEBUG = True ALLOWED_HOSTS = ['*'] +# required for django-guardian +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', # default + 'guardian.backends.ObjectPermissionBackend' +) # Application definition @@ -37,8 +42,9 @@ INSTALLED_APPS = [ 'taskapp', 'clientsideapp', 'chatbot', - 'django_messages', - 'dialing_app' + 'msg_app', + 'dialing_app', + 'guardian' ] MIDDLEWARE_CLASSES = [ @@ -66,7 +72,8 @@ TEMPLATES = [ 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'taskapp.context_proc.get_active_tasks_count', - 'global_context_processors.context_processor_additional_profile' + 'global_context_processors.context_processor_additional_profile', + 'msg_app.context_processors.get_new_messages_count' ], }, }, @@ -149,7 +156,7 @@ DATE_FORMAT = 'd E Y' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' -DEFAULT_PICTURE = '/static/images/default-avatar.png' +DEFAULT_PICTURE = '/static/img/user_ava.gif' AUTH_USER_MODEL = 'accounts_app.UserProfile' LOGIN_URL = reverse_lazy('acc_app:login') @@ -158,8 +165,8 @@ LOGOUT_URL = reverse_lazy('acc_app:logout_link') PAGINATION_ITEMS_PER_PAGE=10 -pay_SERV_ID = '' -pay_SECRET = '' +PAY_SERV_ID = '' +PAY_SECRET = '' DIALING_MEDIA = 'path/to/asterisk_records' diff --git a/djing/urls.py b/djing/urls.py index e057649..ed0f6de 100644 --- a/djing/urls.py +++ b/djing/urls.py @@ -16,7 +16,7 @@ urlpatterns = [ url(r'^statistic/', include('statistics.urls', namespace='statistics')), url(r'^tasks/', include('taskapp.urls', namespace='taskapp')), url(r'^client/', include('clientsideapp.urls', namespace='client_side')), - url(r'^msg/', include('django_messages.urls', namespace='django_messages')), + url(r'^msg/', include('msg_app.urls', namespace='msg_app')), url(r'^dialing/', include('dialing_app.urls', namespace='dialapp')), url(r'^admin/', admin.site.urls) ] diff --git a/docs/install.md b/docs/install.md index 62ecd2a..4c38a41 100644 --- a/docs/install.md +++ b/docs/install.md @@ -198,7 +198,7 @@ plugin=python3 **PAGINATION_ITEMS_PER_PAGE** — Количество выводимых элементов списка на странце с таблицей. Например, если поставить 30, то на странице абонентов на одной странице будет выведено 30 строк абонентов. -**pay_SERV_ID** — Эта опция, так же как и **pay_SECRET** опции для платёжной системы *AllTime24*, если вы используете любую +**PAY_SERV_ID** — Эта опция, так же как и **PAY_SECRET** опции для платёжной системы *AllTime24*, если вы используете любую другую платёжную систему то можете удалить эти опции. **DIALING_MEDIA** — Путь, где биллинг сможет найти файлы записей asterisk чтоб вывести статистику звонков. @@ -222,7 +222,7 @@ plugin=python3 ``` $ ./manage.py migrate Operations to perform: - Apply all migrations: mapapp, contenttypes, dialing_app, django_messages, taskapp, photo_app, accounts_app, devapp, statistics, tariff_app, admin, sessions, chatbot, auth, abonapp + Apply all migrations: mapapp, contenttypes, dialing_app, msg_app, taskapp, photo_app, accounts_app, devapp, statistics, tariff_app, admin, sessions, chatbot, auth, abonapp Running migrations: Rendering model states... DONE Applying mapapp.0001_initial... OK diff --git a/mapapp/views.py b/mapapp/views.py index afb60ad..acdf717 100644 --- a/mapapp/views.py +++ b/mapapp/views.py @@ -1,5 +1,5 @@ from django.contrib import messages -from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import login_required from django.contrib.gis.shortcuts import render_to_text from django.core.exceptions import PermissionDenied from django.http import HttpResponse @@ -9,6 +9,7 @@ from .models import Dot from .forms import DotForm from mydefs import pag_mn from devapp.models import Device +from guardian.decorators import permission_required_or_403 as permission_required @login_required diff --git a/django_messages/management/__init__.py b/msg_app/__init__.py similarity index 100% rename from django_messages/management/__init__.py rename to msg_app/__init__.py diff --git a/msg_app/admin.py b/msg_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/msg_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/msg_app/apps.py b/msg_app/apps.py new file mode 100644 index 0000000..95ca63f --- /dev/null +++ b/msg_app/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class MsgAppConfig(AppConfig): + name = 'msg_app' diff --git a/msg_app/context_processors.py b/msg_app/context_processors.py new file mode 100644 index 0000000..ef283e1 --- /dev/null +++ b/msg_app/context_processors.py @@ -0,0 +1,9 @@ +from .models import Conversation + + +def get_new_messages_count(request): + if request.user.is_anonymous(): + count = 0 + else: + count = Conversation.objects.get_new_messages_count(request.user) + return {'new_messages_count': count} diff --git a/msg_app/forms.py b/msg_app/forms.py new file mode 100644 index 0000000..fd99831 --- /dev/null +++ b/msg_app/forms.py @@ -0,0 +1,63 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ +from .models import Conversation, Message, MessageError +from accounts_app.models import UserProfile + + +class ConversationForm(forms.ModelForm): + + def __init__(self, *args, **kwargs): + super(ConversationForm, self).__init__(*args, **kwargs) + user_profile_queryset = UserProfile.objects.filter(is_admin=True) + if user_profile_queryset is not None: + self.fields['participants'].choices = [(up.pk, up.get_full_name()) for up in user_profile_queryset] + + title = forms.CharField(max_length=32, required=False, widget=forms.TextInput(attrs={'class': 'form-control', 'maxlength': '32'})) + participants = forms.MultipleChoiceField(required=False, widget=forms.SelectMultiple(attrs={'class': 'form-control'})) + + class Meta: + model = Conversation + exclude = ['date_create', 'author'] + + def create(self, author): + participants = self.cleaned_data['participants'] + if not participants: + raise MessageError(_('you must choose at least 1 participants')) + conversation = Conversation.objects.create_conversation( + author=author, title=self.cleaned_data['title'], + other_participants=participants + ) + return conversation + + # must be use create() + def save(self, commit=True): + # You must use ConversationForm.create() for save the form + raise NotImplementedError + + +class MessageForm(forms.ModelForm): + + class Meta: + model = Message + exclude = ['sent_at', 'author', 'conversation', 'account_status'] + widgets = { + 'text': forms.Textarea(attrs={'class': 'form-control'}), + 'attachment': forms.FileInput(attrs={'class': 'form-control'}) + } + + def create(self, conversation, author): + if not isinstance(conversation, Conversation): + raise TypeError + if not isinstance(author, UserProfile): + raise TypeError + msg = conversation.new_message( + text=self.cleaned_data['text'], + attachment=self.cleaned_data['attachment'], + author=author + ) + return msg + + + def save(self, commit=True): + # You must use MessageForm.create() for save the form + raise NotImplementedError diff --git a/msg_app/locale/ru/LC_MESSAGES/django.po b/msg_app/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000..de5da31 --- /dev/null +++ b/msg_app/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,161 @@ +# 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-10-04 17:52+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" + +#: forms.py:25 +msgid "you must choose at least 1 participants" +msgstr "вы должны выбрать как минимум одного участника" + +#: models.py:14 templates/msg_app/conversations.html.py:54 +msgid "New" +msgstr "Новая" + +#: models.py:15 +msgid "Seen" +msgstr "Просмотренное" + +#: models.py:16 +msgid "Deleted" +msgstr "Удалённое" + +#: models.py:28 +msgid "Message status" +msgstr "Статус сообщения" + +#: models.py:29 +msgid "Messages statuses" +msgstr "Статусы сообщений" + +#: models.py:33 +msgid "Body" +msgstr "Тело" + +#: models.py:34 +msgid "sent at" +msgstr "отправлено" + +#: models.py:36 models.py:234 +msgid "Conversation" +msgstr "Беседа" + +#: models.py:66 +msgid "Message" +msgstr "Сообщение" + +#: models.py:67 +msgid "Messages" +msgstr "Сообщения" + +#: models.py:69 +msgid "Can view messages" +msgstr "может просматривать сообщения" + +#: models.py:77 +msgid "Admin" +msgstr "Админ" + +#: models.py:78 +msgid "Guest" +msgstr "Гость" + +#: models.py:79 +msgid "Banned user" +msgstr "Запрещённый пользователь" + +#: models.py:80 +msgid "Inviter" +msgstr "Создатель" + +#: models.py:90 +msgid "Conversation membership" +msgstr "Членство в беседе" + +#: models.py:91 +msgid "Conversation memberships" +msgstr "Членства в беседах" + +#: models.py:100 +msgid "Participant profile does not found" +msgstr "Учётная запись участника не найдена" + +#: models.py:110 +msgid "No name" +msgstr "Без имени" + +#: models.py:235 templates/msg_app/conversations.html.py:14 +msgid "Conversations" +msgstr "Беседы" + +#: models.py:237 +msgid "Can view conversation" +msgstr "Может просматривать беседы" + +#: templates/msg_app/chat.html:7 templates/msg_app/conversations.html.py:7 +msgid "Private messages" +msgstr "Личные сообщения" + +#: templates/msg_app/chat.html:16 +msgid "peoples" +msgstr "участников" + +#: templates/msg_app/chat.html:26 +msgid "Delete" +msgstr "Удалить" + +#: templates/msg_app/chat.html:58 +msgid "Message history is empty" +msgstr "История сообщений пуста" + +#: templates/msg_app/chat.html:75 +msgid "Send" +msgstr "Отправить" + +#: templates/msg_app/conversations.html:32 +#, python-format +msgid "%(participants_count)s participants, %(msg_count)s messages" +msgstr "%(participants_count)s участников, %(msg_count)s сообщений" + +#: templates/msg_app/conversations.html:38 +msgid "No messages found" +msgstr "Сообщения не найдены" + +#: templates/msg_app/conversations.html:47 +msgid "Any conversations not found" +msgstr "Не найдено ни одной беседы" + +#: templates/msg_app/modal_new_conversation.html:5 +msgid "Create conversation" +msgstr "Создать беседу" + +#: templates/msg_app/modal_new_conversation.html:19 +msgid "for select multiple press ctrl and click on field" +msgstr "Для выбора нескольких ывриантов зажмите ctrl и кликните вариант" + +#: templates/msg_app/modal_new_conversation.html:28 +msgid "Add" +msgstr "Добавить" + +#: views.py:26 +msgid "Conversation has been created" +msgstr "Беседа создана" + +#: views.py:29 views.py:48 +msgid "fix form errors" +msgstr "заполните все поля в соответствии с их форматом" diff --git a/msg_app/migrations/0001_initial.py b/msg_app/migrations/0001_initial.py new file mode 100644 index 0000000..c47429f --- /dev/null +++ b/msg_app/migrations/0001_initial.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-10-04 17:44 +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): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Conversation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=32)), + ('date_create', models.DateTimeField(auto_now_add=True)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Conversation', + 'verbose_name_plural': 'Conversations', + 'db_table': 'conversations', + 'permissions': (('can_view_conversation', 'Can view conversation'),), + }, + ), + migrations.CreateModel( + name='ConversationMembership', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.CharField(choices=[('adm', 'Admin'), ('gst', 'Guest'), ('ban', 'Banned user'), ('inv', 'Inviter')], default='gst', max_length=3)), + ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to=settings.AUTH_USER_MODEL)), + ('conversation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='msg_app.Conversation')), + ('who_invite_that_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='self_conversations', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Conversation membership', + 'verbose_name_plural': 'Conversation memberships', + 'db_table': 'conversation_memberships', + }, + ), + migrations.CreateModel( + name='Message', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(verbose_name='Body')), + ('sent_at', models.DateTimeField(auto_now_add=True, verbose_name='sent at')), + ('attachment', models.FileField(blank=True, null=True, upload_to='messages_attachments/%Y_%m_%d')), + ], + options={ + 'verbose_name': 'Message', + 'verbose_name_plural': 'Messages', + 'db_table': 'messages', + 'ordering': ['-sent_at'], + 'permissions': (('can_view_messages', 'Can view messages'),), + }, + ), + migrations.CreateModel( + name='MessageStatus', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('state', models.CharField(choices=[('new', 'New'), ('old', 'Seen'), ('del', 'Deleted')], default='new', max_length=3)), + ('msg', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='msg_statuses', to='msg_app.Message')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='usr_msg_status', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Message status', + 'verbose_name_plural': 'Messages statuses', + 'db_table': 'message_status', + }, + ), + migrations.AddField( + model_name='message', + name='account_status', + field=models.ManyToManyField(through='msg_app.MessageStatus', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='message', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='message', + name='conversation', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='msg_app.Conversation', verbose_name='Conversation'), + ), + migrations.AddField( + model_name='conversation', + name='participants', + field=models.ManyToManyField(related_name='conversations', through='msg_app.ConversationMembership', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterUniqueTogether( + name='messagestatus', + unique_together=set([('msg', 'user', 'state')]), + ), + ] diff --git a/django_messages/management/commands/__init__.py b/msg_app/migrations/__init__.py similarity index 100% rename from django_messages/management/commands/__init__.py rename to msg_app/migrations/__init__.py diff --git a/msg_app/models.py b/msg_app/models.py new file mode 100644 index 0000000..a1d0eaa --- /dev/null +++ b/msg_app/models.py @@ -0,0 +1,237 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from accounts_app.models import UserProfile + + +class MessageError(Exception): + pass + + +class MessageStatus(models.Model): + msg = models.ForeignKey('Message', related_name='msg_statuses') + user = models.ForeignKey(UserProfile, related_name='usr_msg_status') + MESSAGE_STATES = ( + ('new', _('New')), + ('old', _('Seen')), + ('del', _('Deleted')) + ) + state = models.CharField(max_length=3, choices=MESSAGE_STATES, default='new') + + def __str__(self): + return "%s for %s (%s)" % (self.get_state_display(), self.user, self.msg) + + class Meta: + db_table = 'message_status' + unique_together = ( + ('msg', 'user', 'state') + ) + verbose_name = _('Message status') + verbose_name_plural = _('Messages statuses') + + +class Message(models.Model): + text = models.TextField(_("Body")) + sent_at = models.DateTimeField(_("sent at"), auto_now_add=True) + author = models.ForeignKey(UserProfile, related_name='messages') + conversation = models.ForeignKey('Conversation', verbose_name=_('Conversation')) + attachment = models.FileField(upload_to='messages_attachments/%Y_%m_%d', blank=True, null=True) + account_status = models.ManyToManyField(UserProfile, through=MessageStatus, through_fields=('msg', 'user')) + + def __str__(self): + return self.text[:9] + + def _set_status(self, account, code): + try: + ms = MessageStatus.objects.get(msg=self, user=account) + if ms.status == code: + return False + ms.status = code + ms.save(update_fields=['status']) + return True + except MessageStatus.DoesNotExist: + return False + + def set_status_old(self, account): + return self._set_status(account, 'old') + + def set_status_del(self, account): + return self._set_status(account, 'del') + + def set_status_new(self, account): + return self._set_status(account, 'new') + + class Meta: + db_table = 'messages' + ordering = ['-sent_at'] + verbose_name = _("Message") + verbose_name_plural = _("Messages") + permissions = ( + ('can_view_messages', _('Can view messages')), + ) + + +class ConversationMembership(models.Model): + account = models.ForeignKey(UserProfile, related_name='memberships') + conversation = models.ForeignKey('Conversation') + PARTICIPANT_STATUS = ( + ('adm', _('Admin')), + ('gst', _('Guest')), + ('ban', _('Banned user')), + ('inv', _('Inviter')) + ) + status = models.CharField(max_length=3, choices=PARTICIPANT_STATUS, default='gst') + who_invite_that_user = models.ForeignKey(UserProfile, null=True, blank=True, related_name='self_conversations') + + def __str__(self): + return "%s < %s" % (self.conversation, self.account) + + class Meta: + db_table = 'conversation_memberships' + verbose_name = _("Conversation membership") + verbose_name_plural = _("Conversation memberships") + + +def id_to_userprofile(acc): + if isinstance(acc, UserProfile): + return acc + try: + return UserProfile.objects.get(pk=acc) + except UserProfile.DoesNotExist: + raise MessageError(_('Participant profile does not found')) + + +class ConversationManager(models.Manager): + + def create_conversation(self, author, other_participants, title=None): + other_participants = [id_to_userprofile(acc) for acc in other_participants] + if not title: + usernames = [acc.username for acc in other_participants] + if not usernames: + title = _('No name') + else: + title = ', '.join(usernames) + conversation = self.create(title=title, author=author) + for acc in other_participants: + ConversationMembership.objects.create( + account=acc, conversation=conversation, status='adm', who_invite_that_user=author + ) + + ConversationMembership.objects.create( + account=author, conversation=conversation, status='inv' + ) + return conversation + + def get_new_messages_count(self, account): + ms_count = MessageStatus.objects.filter(user=account, state='new').count() + return ms_count + + def fetch(self, account): + conversations = self.filter(models.Q(author=account) | models.Q(participants__in=[account])).annotate( + msg_count=models.Count('message', distinct=True) + ) + return conversations + + +class Conversation(models.Model): + title = models.CharField(max_length=32) + participants = models.ManyToManyField(UserProfile, related_name='conversations', + through='ConversationMembership', + through_fields=('conversation', 'account')) + author = models.ForeignKey(UserProfile) + date_create = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.title + + objects = ConversationManager() + + def get_messages(self): + return Message.objects.filter(conversation=self).order_by('sent_at')[:10] + + def get_messages_new_count(self, account): + msgs = Message.objects.filter(conversation=self) + return MessageStatus.objects.filter(user=account, msg__in=msgs, state='new').count() + + def last_message(self): + messages = Message.objects.filter(conversation=self) + if messages.count() > 0: + return messages[0] + + def new_message(self, text, attachment, author, with_status=True): + msg = Message.objects.create( + text=text, conversation=self, attachment=attachment, author=author + ) + if with_status: + for participant in self.participants.all(): + if participant == author: + continue + MessageStatus.objects.create(msg=msg, user=participant) + return msg + + def remove_message(self, msg): + if isinstance(msg, Message): + m = msg + else: + m = Message.objects.get(pk=int(msg)) + if m is None: + return False + else: + m.delete() + return True + + def _make_participant_status(self, user, status, cm=None): + if cm is None: + cm = ConversationMembership.objects.get(account=user, conversation=self) + else: + if not isinstance(cm, ConversationMembership): + raise TypeError('cm must be instance of msg_app.ConversationMembership') + cm.status = status + cm.save(update_fields=['status']) + return cm + + def make_participant_status_admin(self, user): + return self._make_participant_status(user, 'adm') + + def make_participant_status_guest(self, user): + return self._make_participant_status(user, 'gst') + + def make_participant_status_ban(self, user): + return self._make_participant_status(user, 'ban') + + def make_participant_status_inviter(self, user): + return self._make_participant_status(user, 'inv') + + def remove_participant(self, user): + try: + cm = ConversationMembership.objects.get(account=user, conversation=self) + cm.delete() + except ConversationMembership.DoesNotExist: + pass + + def add_participant(self, author, user): + return ConversationMembership.objects.create( + account=user, conversation=self, status='gst', who_invite_that_user=author + ) + + def find_messages_by_text(self, text): + return Message.objects.filter(text__icontains=text, conversation=self) + + def _make_messages_status(self, account, status): + qs = MessageStatus.objects.filter(msg__conversation=self, user=account).exclude(state='del') + if status != 'del': + qs = qs.exclude(state=status) + return qs.update(state=status) + + def make_messages_status_new(self, account): + return self._make_messages_status(account, 'new') + + def make_messages_status_old(self, account): + return self._make_messages_status(account, 'old') + + class Meta: + db_table = 'conversations' + verbose_name = _("Conversation") + verbose_name_plural = _("Conversations") + permissions = ( + ('can_view_conversation', _('Can view conversation')), + ) diff --git a/msg_app/templates/msg_app/chat.html b/msg_app/templates/msg_app/chat.html new file mode 100644 index 0000000..5ee0394 --- /dev/null +++ b/msg_app/templates/msg_app/chat.html @@ -0,0 +1,87 @@ +{% extends request.is_ajax|yesno:'bajax.html,base.html' %} +{% load i18n %} +{% block main %} + + + + {% include 'message_block.html' %} + +
    +
    +

    {{ conv.title }} + {{ conv.participants.count }} {% trans 'peoples' %} +

    +
    +
    + + {% with can_view_profile=perms.accounts_app.can_view_userprofile %} + {% for msg in msg_list %} + {% with author=msg.author %} +
    + {% if msg.author == request.user %} + + + + {% endif %} +
    +
    + {% if can_view_profile %} + + ava + + {% else %} + ava + {% endif %} +
    +
    +
    {{ author.get_short_name }} + {{ msg.sent_at|date:'d M, H:i:s' }} +
    + +

    {{ msg.text }}

    + {% if msg.attachment %} + + {{ msg.attachment }} + + {% endif %} + +
    +
    +
    + {% endwith %} + {% empty %} +
    +

    {% trans 'Message history is empty' %}

    +
    + {% endfor %} + {% endwith %} +
    +
    {% csrf_token %} + +
    +
    + +{% endblock %} diff --git a/msg_app/templates/msg_app/conversations.html b/msg_app/templates/msg_app/conversations.html new file mode 100644 index 0000000..b39e2e0 --- /dev/null +++ b/msg_app/templates/msg_app/conversations.html @@ -0,0 +1,62 @@ +{% extends request.is_ajax|yesno:'bajax.html,base.html' %} +{% load i18n %} +{% block main %} + + + + {% include 'message_block.html' %} + + + + {% include 'toolbar_page.html' with pag=conversations %} + +{% endblock %} diff --git a/msg_app/templates/msg_app/modal_new_conversation.html b/msg_app/templates/msg_app/modal_new_conversation.html new file mode 100644 index 0000000..cf65bd7 --- /dev/null +++ b/msg_app/templates/msg_app/modal_new_conversation.html @@ -0,0 +1,33 @@ +{% load i18n %} +
    {% csrf_token %} + + + + +
    diff --git a/msg_app/tests.py b/msg_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/msg_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/msg_app/urls.py b/msg_app/urls.py new file mode 100644 index 0000000..ff34b05 --- /dev/null +++ b/msg_app/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import url +from . import views + + +urlpatterns = [ + url(r'^$', views.home, name='home'), + url(r'^new$', views.new_conversation, name='new_conversation'), + url(r'^(?P\d+)/$', views.to_conversation, name='to_conversation'), + url(r'^(?P\d+)/(?P\d+)/del$', views.remove_msg, name='remove_msg') +] diff --git a/msg_app/views.py b/msg_app/views.py new file mode 100644 index 0000000..5e6d62c --- /dev/null +++ b/msg_app/views.py @@ -0,0 +1,72 @@ +from django.contrib.auth.decorators import login_required +from django.contrib.gis.shortcuts import render_to_text +from django.core.exceptions import PermissionDenied +from django.utils.translation import ugettext_lazy as _ +from django.contrib import messages +from django.shortcuts import render, redirect, get_object_or_404 + +from mydefs import pag_mn +from .models import Conversation, MessageError, Message +from .forms import ConversationForm, MessageForm + + +@login_required +def home(request): + # TODO: optimise queries + conversations = Conversation.objects.fetch(request.user) + conversations = pag_mn(request, conversations, 8) + return render(request, 'msg_app/conversations.html', { + 'conversations': conversations + }) + + +@login_required +def new_conversation(request): + try: + frm = ConversationForm(request.POST or None) + if request.method == 'POST': + if frm.is_valid(): + conv = frm.create(request.user) + messages.success(request, _('Conversation has been created')) + return redirect('msg_app:to_conversation', conv.pk) + else: + messages.error(request, _('fix form errors')) + else: + return render_to_text('msg_app/modal_new_conversation.html', { + 'form': frm + }, request=request) + except MessageError as e: + messages.error(request, e) + return redirect('msg_app:home') + + +@login_required +def to_conversation(request, conv_id): + conv = get_object_or_404(Conversation, pk=conv_id) + try: + if request.method == 'POST': + frm = MessageForm(request.POST, request.FILES) + if frm.is_valid(): + frm.create(conv, request.user) + else: + messages.error(request, _('fix form errors')) + else: + conv.make_messages_status_old(request.user) + msg_list = conv.get_messages() + return render(request, 'msg_app/chat.html', { + 'conv': conv, + 'msg_list': msg_list + }) + except MessageError as e: + messages.error(request, e) + return redirect('msg_app:home') + + +@login_required +def remove_msg(request, conv_id, msg_id): + msg = get_object_or_404(Message, pk=msg_id) + if msg.author != request.user: + raise PermissionDenied + conversation_id = msg.conversation.pk + msg.delete() + return redirect('msg_app:to_conversation', conversation_id) diff --git a/requirements.txt b/requirements.txt index 7d485d0..9dcb617 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ mysqlclient easysnmp rq pid +django-guardian diff --git a/tariff_app/views.py b/tariff_app/views.py index 9b8cd0c..4c766f9 100644 --- a/tariff_app/views.py +++ b/tariff_app/views.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import login_required from django.contrib.gis.shortcuts import render_to_text from django.utils.translation import ugettext as _ from django.shortcuts import render, get_object_or_404, redirect from django.contrib import messages from django.core.exceptions import PermissionDenied +from guardian.decorators import permission_required_or_403 as permission_required from .models import Tariff import mydefs diff --git a/taskapp/migrations/0001_initial.py b/taskapp/migrations/0001_initial.py index ffd281f..eec2166 100644 --- a/taskapp/migrations/0001_initial.py +++ b/taskapp/migrations/0001_initial.py @@ -13,7 +13,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('devapp', '0002_auto_20160909_1018'), + ('devapp', '0001_squashed_0007_auto_20170816_1109'), ] operations = [ diff --git a/taskapp/migrations/0001_squashed_0015_auto_20170816_1109.py b/taskapp/migrations/0001_squashed_0015_auto_20170816_1109.py new file mode 100644 index 0000000..d3e3853 --- /dev/null +++ b/taskapp/migrations/0001_squashed_0015_auto_20170816_1109.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-05 12:23 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import taskapp.models + + +class Migration(migrations.Migration): + + replaces = [('taskapp', '0001_initial'), ('taskapp', '0002_auto_20161006_0027'), ('taskapp', '0003_auto_20161130_1815'), ('taskapp', '0004_auto_20161202_1230'), ('taskapp', '0005_auto_20161206_0013'), ('taskapp', '0006_auto_20161206_2135'), ('taskapp', '0007_auto_20161206_2303'), ('taskapp', '0008_auto_20161213_1932'), ('taskapp', '0009_auto_20161216_2214'), ('taskapp', '0010_auto'), ('taskapp', '0011_auto_20170116_0126'), ('taskapp', '0012_auto_20170407_0124'), ('taskapp', '0013_auto_20170413_1944'), ('taskapp', '0014_auto_20170416_1029'), ('taskapp', '0015_auto_20170816_1109')] + + initial = True + + dependencies = [ + ('devapp', '0001_squashed_0007_auto_20170816_1109'), + ('abonapp', '0001_squashed_0022_auto_20170816_1109'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('descr', models.CharField(max_length=128)), + ('priority', models.CharField(choices=[('A', 'Высший'), ('B', 'Выше среднего'), ('C', 'Средний'), ('D', 'Ниже среднего'), ('E', 'Низкий')], default='C', max_length=1)), + ('out_date', models.DateField(blank=True, default=taskapp.models._delta_add_days, null=True)), + ('time_of_create', models.DateTimeField(auto_now_add=True)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dev', to='devapp.Device')), + ('recipient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'task', + }, + ), + migrations.AlterModelOptions( + name='task', + options={'ordering': ('-id',)}, + ), + migrations.AddField( + model_name='task', + name='state', + field=models.CharField(choices=[('S', 'Новая'), ('C', 'На выполнении'), ('F', 'Выполнена')], default='S', max_length=1), + ), + migrations.AddField( + model_name='task', + name='attachment', + field=models.ImageField(blank=True, null=True, upload_to='task_attachments/%Y.%m.%d'), + ), + migrations.AddField( + model_name='task', + name='mode', + field=models.CharField(choices=[('na', 'не выбрано'), ('yt', 'жёлтый треугольник'), ('rc', 'красный крестик'), ('ls', 'слабая скорость'), ('cf', 'обрыв кабеля'), ('cn', 'подключение'), ('pf', 'переодическое пропадание'), ('cr', 'настройка роутера'), ('co', 'настроить onu'), ('fc', 'обжать кабель'), ('ot', 'другое')], default='na', max_length=2), + ), + migrations.AddField( + model_name='task', + name='abon', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='abonapp.Abon'), + ), + migrations.AlterField( + model_name='task', + name='priority', + field=models.CharField(choices=[('A', 'Высший'), ('C', 'Средний'), ('E', 'Низкий')], default='E', max_length=1), + ), + migrations.CreateModel( + name='ChangeLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('act_type', models.CharField(choices=[('e', 'Изменение задачи'), ('c', 'Создание задачи'), ('d', 'Удаление задачи')], max_length=1)), + ('when', models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.AlterModelOptions( + name='task', + options={'ordering': ('-id',), 'permissions': (('can_viewall', 'Доступ ко всем задачам'),)}, + ), + migrations.AddField( + model_name='changelog', + name='task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='taskapp.Task'), + ), + migrations.AddField( + model_name='changelog', + name='who', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL), + ), + migrations.RemoveField( + model_name='task', + name='device', + ), + migrations.RemoveField( + model_name='task', + name='recipient', + ), + migrations.AddField( + model_name='task', + name='recipients', + field=models.ManyToManyField(related_name='them_task', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterModelOptions( + name='task', + options={'ordering': ('-id',), 'permissions': (('can_viewall', 'Доступ ко всем задачам'), ('can_remind', 'Напоминания о задачах'))}, + ), + migrations.AlterField( + model_name='changelog', + name='act_type', + field=models.CharField(choices=[('e', 'Изменение задачи'), ('c', 'Создание задачи'), ('d', 'Удаление задачи'), ('f', 'Завершение задачи'), ('b', 'Задача начата')], max_length=1), + ), + migrations.AlterField( + model_name='task', + name='descr', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AlterField( + model_name='task', + name='attachment', + field=models.ImageField(blank=True, null=True, upload_to='media/task_attachments/%Y.%m.%d'), + ), + migrations.AlterField( + model_name='task', + name='attachment', + field=models.ImageField(blank=True, null=True, upload_to='task_attachments/%Y.%m.%d'), + ), + migrations.AlterField( + model_name='task', + name='abon', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon'), + ), + migrations.AlterField( + model_name='task', + name='author', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='changelog', + name='act_type', + field=models.CharField(choices=[('e', 'Изменение задачи'), ('c', 'Создание задачи'), ('d', 'Удаление задачи'), ('f', 'Завершение задачи'), ('b', 'Задача провалена')], max_length=1), + ), + migrations.AlterField( + model_name='task', + name='state', + field=models.CharField(choices=[('S', 'Новая'), ('C', 'Провалена'), ('F', 'Выполнена')], default='S', max_length=1), + ), + ] diff --git a/taskapp/migrations/0005_auto_20161206_0013.py b/taskapp/migrations/0005_auto_20161206_0013.py index 8891a9b..f6e2423 100644 --- a/taskapp/migrations/0005_auto_20161206_0013.py +++ b/taskapp/migrations/0005_auto_20161206_0013.py @@ -8,7 +8,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('abonapp', '0001_initial'), + ('abonapp', '0001_squashed_0022_auto_20170816_1109'), ('taskapp', '0004_auto_20161202_1230'), ] diff --git a/taskapp/templates/taskapp/tasklist.html b/taskapp/templates/taskapp/tasklist.html index 860b025..f84b0cb 100644 --- a/taskapp/templates/taskapp/tasklist.html +++ b/taskapp/templates/taskapp/tasklist.html @@ -45,8 +45,13 @@ {{ task.get_mode_display }} {{ task.descr }} - {{ task.author.username }} + + {% if task.author %} + {{ task.author.username }} + {% else %} + {% trans 'Author does not exist' %} + {% endif %} + {{ task.time_of_create|date:'d E H:i' }} diff --git a/taskapp/views.py b/taskapp/views.py index d8ec471..285f38f 100644 --- a/taskapp/views.py +++ b/taskapp/views.py @@ -1,11 +1,12 @@ # coding=utf-8 -from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.shortcuts import render, redirect, get_object_or_404 from django.contrib import messages from abonapp.models import Abon from django.utils.translation import ugettext as _ from datetime import date +from guardian.decorators import permission_required_or_403 as permission_required from .handle import TaskException from .models import Task @@ -181,8 +182,11 @@ def task_finish(request, task_id): @login_required @only_admins def task_failed(request, task_id): - task = get_object_or_404(Task, id=task_id) - task.do_fail(request.user) + try: + task = get_object_or_404(Task, id=task_id) + task.do_fail(request.user) + except TaskException as e: + messages.error(request, e) return redirect('taskapp:home') diff --git a/templates/404.html b/templates/404.html index 0eb1ccd..7bb769f 100644 --- a/templates/404.html +++ b/templates/404.html @@ -37,7 +37,7 @@

    404 - Страница не найдена

    -

    Такого пути '{{ request.path }}' нет нет на сервере

    +

    Такого пути '{{ request.path }}' нет на сервере

    На главную
    diff --git a/templates/all_base.html b/templates/all_base.html index 956692e..9c89b2d 100644 --- a/templates/all_base.html +++ b/templates/all_base.html @@ -47,7 +47,7 @@
    +{% endif %}