diff --git a/MANIFEST.in b/MANIFEST.in index 66ef6b8..c29f6ab 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ include MANIFEST.in README.rst AUTHORS.txt LICENSE.txt CHANGELOG.rst -recursive-include notifications *.py *.html *.txt *.po +recursive-include notifications *.py *.html *.js *.txt *.mo *.po diff --git a/notifications/apps.py b/notifications/apps.py index 2a1a387..346d5a0 100644 --- a/notifications/apps.py +++ b/notifications/apps.py @@ -1,10 +1,12 @@ ''' Django notifications apps file ''' # -*- coding: utf-8 -*- from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class Config(AppConfig): name = "notifications" + verbose_name = _("Notifications") def ready(self): super(Config, self).ready() diff --git a/notifications/base/models.py b/notifications/base/models.py index f565a5f..05eaac4 100644 --- a/notifications/base/models.py +++ b/notifications/base/models.py @@ -11,9 +11,9 @@ from django.core.exceptions import ImproperlyConfigured from django.db import models from django.db.models.query import QuerySet from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from jsonfield.fields import JSONField from model_utils import Choices - from notifications import settings as notifications_settings from notifications.signals import notify from notifications.utils import id2slug @@ -167,45 +167,62 @@ class AbstractNotification(models.Model): """ LEVELS = Choices('success', 'info', 'warning', 'error') - level = models.CharField(choices=LEVELS, default=LEVELS.info, max_length=20) + level = models.CharField(_('level'), choices=LEVELS, default=LEVELS.info, max_length=20) recipient = models.ForeignKey( settings.AUTH_USER_MODEL, - blank=False, + on_delete=models.CASCADE, related_name='notifications', - on_delete=models.CASCADE + verbose_name=_('recipient'), + blank=False, ) - unread = models.BooleanField(default=True, blank=False, db_index=True) + unread = models.BooleanField(_('unread'), default=True, blank=False, db_index=True) - actor_content_type = models.ForeignKey(ContentType, related_name='notify_actor', on_delete=models.CASCADE) - actor_object_id = models.CharField(max_length=255) + actor_content_type = models.ForeignKey( + ContentType, + on_delete=models.CASCADE, + related_name='notify_actor', + verbose_name=_('actor content type') + ) + actor_object_id = models.CharField(_('actor object id'), max_length=255) actor = GenericForeignKey('actor_content_type', 'actor_object_id') + actor.short_description = _('actor') - verb = models.CharField(max_length=255) - description = models.TextField(blank=True, null=True) + verb = models.CharField(_('verb'), max_length=255) + description = models.TextField(_('description'), blank=True, null=True) target_content_type = models.ForeignKey( ContentType, + on_delete=models.CASCADE, related_name='notify_target', + verbose_name=_('target content type'), blank=True, - null=True, - on_delete=models.CASCADE + null=True ) - target_object_id = models.CharField(max_length=255, blank=True, null=True) + target_object_id = models.CharField(_('target object id'), max_length=255, blank=True, null=True) target = GenericForeignKey('target_content_type', 'target_object_id') + target.short_description = _('target') - action_object_content_type = models.ForeignKey(ContentType, blank=True, null=True, - related_name='notify_action_object', on_delete=models.CASCADE) - action_object_object_id = models.CharField(max_length=255, blank=True, null=True) + action_object_content_type = models.ForeignKey( + ContentType, + on_delete=models.CASCADE, + related_name='notify_action_object', + verbose_name=_('action object content type'), + blank=True, + null=True + ) + action_object_object_id = models.CharField(_('action object object id'), max_length=255, blank=True, null=True) action_object = GenericForeignKey('action_object_content_type', 'action_object_object_id') + action_object.short_description = _('action object') - timestamp = models.DateTimeField(default=timezone.now, db_index=True) + timestamp = models.DateTimeField(_('timestamp'), default=timezone.now, db_index=True) - public = models.BooleanField(default=True, db_index=True) - deleted = models.BooleanField(default=False, db_index=True) - emailed = models.BooleanField(default=False, db_index=True) + public = models.BooleanField(_('public'), default=True, db_index=True) + deleted = models.BooleanField(_('deleted'), default=False, db_index=True) + emailed = models.BooleanField(_('emailed'), default=False, db_index=True) - data = JSONField(blank=True, null=True) + data = JSONField(_('data'), blank=True, null=True) + objects = NotificationQuerySet.as_manager() class Meta: @@ -213,6 +230,8 @@ class AbstractNotification(models.Model): ordering = ('-timestamp',) # speed up notifications count query index_together = ('recipient', 'unread') + verbose_name = _('Notification') + verbose_name_plural = _('Notifications') def __str__(self): ctx = { @@ -224,11 +243,11 @@ class AbstractNotification(models.Model): } if self.target: if self.action_object: - return u'%(actor)s %(verb)s %(action_object)s on %(target)s %(timesince)s ago' % ctx - return u'%(actor)s %(verb)s %(target)s %(timesince)s ago' % ctx + return _('%(actor)s %(verb)s %(action_object)s on %(target)s %(timesince)s ago') % ctx + return _('%(actor)s %(verb)s %(target)s %(timesince)s ago') % ctx if self.action_object: - return u'%(actor)s %(verb)s %(action_object)s %(timesince)s ago' % ctx - return u'%(actor)s %(verb)s %(timesince)s ago' % ctx + return _('%(actor)s %(verb)s %(action_object)s %(timesince)s ago') % ctx + return _('%(actor)s %(verb)s %(timesince)s ago') % ctx def timesince(self, now=None): """ diff --git a/notifications/locale/ru/LC_MESSAGES/django.mo b/notifications/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000..3a71e4e Binary files /dev/null and b/notifications/locale/ru/LC_MESSAGES/django.mo differ diff --git a/notifications/locale/ru/LC_MESSAGES/django.po b/notifications/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000..677cacb --- /dev/null +++ b/notifications/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,122 @@ +# 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: 2021-04-05 08:47-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: notifications/apps.py:9 notifications/base/models.py:234 +msgid "Notifications" +msgstr "Уведомления" + +#: notifications/base/models.py:170 +msgid "level" +msgstr "уровень" + +#: notifications/base/models.py:176 +msgid "recipient" +msgstr "получатель" + +#: notifications/base/models.py:179 +msgid "unread" +msgstr "не прочитано" + +#: notifications/base/models.py:185 +msgid "actor content type" +msgstr "тип содержимого (действующее лицо)" + +#: notifications/base/models.py:187 +msgid "actor object id" +msgstr "идентификатор объекта (действующее лицо)" + +#: notifications/base/models.py:189 +msgid "actor" +msgstr "действующее лицо" + +#: notifications/base/models.py:191 +msgid "verb" +msgstr "глагол" + +#: notifications/base/models.py:192 +msgid "description" +msgstr "описание" + +#: notifications/base/models.py:198 +msgid "target content type" +msgstr "тип содержимого (целевой объект)" + +#: notifications/base/models.py:202 +msgid "target object id" +msgstr "идентификатор объекта (целевой объект)" + +#: notifications/base/models.py:204 +msgid "target" +msgstr "целевой объект" + +#: notifications/base/models.py:210 +msgid "action object content type" +msgstr "тип содержимого (объект действия)" + +#: notifications/base/models.py:214 +msgid "action object object id" +msgstr "идентификатор объекта (объект действия)" + +#: notifications/base/models.py:216 +msgid "action object" +msgstr "объект действия" + +#: notifications/base/models.py:218 +msgid "timestamp" +msgstr "отметка времени" + +#: notifications/base/models.py:220 +msgid "public" +msgstr "публичный" + +#: notifications/base/models.py:221 +msgid "deleted" +msgstr "удален" + +#: notifications/base/models.py:222 +msgid "emailed" +msgstr "отправлено по электронной почте" + +#: notifications/base/models.py:224 +msgid "data" +msgstr "данные" + +#: notifications/base/models.py:233 +msgid "Notification" +msgstr "Уведомление" + +#: notifications/base/models.py:246 +#, python-format +msgid "%(actor)s %(verb)s %(action_object)s on %(target)s %(timesince)s ago" +msgstr "%(actor)s %(verb)s %(action_object)s %(target)s %(timesince)s назад" + +#: notifications/base/models.py:247 +#, python-format +msgid "%(actor)s %(verb)s %(target)s %(timesince)s ago" +msgstr "%(actor)s %(verb)s %(target)s %(timesince)s назад" + +#: notifications/base/models.py:249 +#, python-format +msgid "%(actor)s %(verb)s %(action_object)s %(timesince)s ago" +msgstr "%(actor)s %(verb)s %(action_object)s %(timesince)s назад" + +#: notifications/base/models.py:250 +#, python-format +msgid "%(actor)s %(verb)s %(timesince)s ago" +msgstr "%(actor)s %(verb)s %(timesince)s назад" diff --git a/setup.py b/setup.py index 9f4e29b..397f7a4 100755 --- a/setup.py +++ b/setup.py @@ -44,9 +44,6 @@ setup( 'notifications.templatetags', 'notifications.migrations', ], - package_data={ - 'notifications': ['templates/notifications/*.html', 'static/notifications/*.js'] - }, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment',