Compare commits

..

22 Commits
master ... dev

Author SHA1 Message Date
Dmitriy Shesterkin 1e00fd21bf add locale 9 years ago
Dmitriy Shesterkin 14362ddf3c Merge commit 'afefcfc5c0d7c60eb406640e7b6a53852a4bed49' into dev 9 years ago
Dmitriy Shesterkin 701de1f5d0 add tags in plugin 9 years ago
Alexander Kondratyev afefcfc5c0 Обновление версий в зависимостях и правка сопутствующих багов 9 years ago
Alexander Kondratyev c0c6f39f19 Возможно, починил миграцию 9 years ago
Dmitriy Shesterkin 765721e2e0 Красявость-Заглавные у тегов 9 years ago
Dmitriy Shesterkin 0b5d5a8f8c Добавил вывод тегов на страницу со статьями 9 years ago
Dmitriy Shesterkin 3d58880607 local settings, readme file 9 years ago
Dmitriy Shesterkin ca2db7b936 settings, requirements 9 years ago
Alexander Kondratyev b06fba71f4 Убрал дублирование заголовков + теперь только статьи отображаются 9 years ago
Alexander Kondratyev cf9b7b2ec2 Поиск по базе Розмарин и мелкие баги 9 years ago
Alexander Kondratyev 8a1cd0db26 Хлебные крошки + ширина поисковой строки 9 years ago
Alexander Kondratyev b75cd39163 Случайные просроченные товарные знаки, упрощённая реализация 9 years ago
Alexander Kondratyev 3d1845d236 Simple random trademark implementation 9 years ago
Alexander Kondratyev 0b9a1c4755 Limit for expired tm loading - fix too long query 9 years ago
Alexander Kondratyev c8b8cf2bcd Не кешировать шаблоны. Нужно чтобы не перезагружать сервер при разработке 9 years ago
Alexander Kondratyev af34f6f947 Лэндинг для онлайн поиска + мелкие исправления 9 years ago
Alexander Kondratyev b46a4194c7 Перелинкова на каталог МКТУ из результатов поиска + Заголовки 9 years ago
Dmitriy Shesterkin 5330881dad sketch with ico 9 years ago
Dmitriy Shesterkin 739dc139dc fix gitignore 9 years ago
Dmitriy Shesterkin 486e62d43c api random trademarks 9 years ago
Alexander Kondratyev ccadd9886a Dev settings 9 years ago
  1. 37
      .editorconfig
  2. 6
      .gitignore
  3. 18
      README.md
  4. 16
      app/__init__.py
  5. 28
      app/local.py.example
  6. 6
      app/settings.py
  7. 45
      packages/aldryn_people/migrations/0004_auto_20150622_1606.py
  8. 28
      packages/aldryn_people/migrations/0005_auto_20170401_2345.py
  9. 6
      packages/aldryn_people/models.py
  10. 184
      packages/aldryn_segmentation/migrations/0001_initial.py
  11. 14
      packages/blog/admin.py
  12. 1
      packages/blog/cms_plugins.py
  13. 191
      packages/blog/locale/ru/LC_MESSAGES/django.po
  14. 2
      packages/blog/migrations/0001_initial.py
  15. 20
      packages/blog/migrations/0010_auto_20170401_1032.py
  16. 20
      packages/blog/migrations/0011_auto_20170401_2345.py
  17. 9
      packages/blog/models.py
  18. 8
      packages/blog/templates/blog/post_detail.html
  19. 10
      packages/blog/templates/blog/post_list.html
  20. 5
      packages/blog/views.py
  21. 99
      packages/cmsplugin_tabs/migrations/0001_initial.py
  22. 66
      packages/country_segment/migrations/0001_initial.py
  23. 9
      packages/djangocms_forms/templates/djangocms_forms/form_template/default.html
  24. 1
      promo/fixtures/data.json
  25. 16
      promo/migrations/0001_initial.py
  26. 1
      requirements.txt
  27. 31
      requirements/common.txt
  28. 3
      requirements/dev.txt
  29. 1
      requirements/prod.txt
  30. 1
      trademark/fixtures/nice.json
  31. 20
      trademark/lib/poiskznakov.py
  32. 24
      trademark/migrations/0001_initial.py
  33. 20
      trademark/migrations/0002_nice_glyph.py
  34. 67
      trademark/models.py
  35. 24
      trademark/static/trademark/js/landing.js
  36. 32
      trademark/static/trademark/less/landing.less
  37. 1
      trademark/static/trademark/less/main.less
  38. 20
      trademark/static/trademark/less/result.less
  39. 35
      trademark/templates/trademark/index.html
  40. 4
      trademark/templates/trademark/nice_block_busy.html
  41. 6
      trademark/templates/trademark/nice_detail.html
  42. 3
      trademark/templates/trademark/nices_catalog.html
  43. 22
      trademark/templates/trademark/product_detail.html
  44. 12
      trademark/templates/trademark/search_detail.html
  45. 8
      trademark/templates/trademark/search_list_item.html
  46. 17
      trademark/templates/trademark/trademark_detail.html
  47. 1
      trademark/urls.py
  48. 60
      trademark/views.py
  49. 11
      zsite/static/less/blog.less
  50. 3
      zsite/static/less/nice.less
  51. 7
      zsite/templates/aldryn_people/includes/people_item.html
  52. 12
      zsite/templatetags/query.py

@ -0,0 +1,37 @@
# For more information about the properties used in
# this file, please see the EditorConfig documentation:
# http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[{*.scss, *.css}]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.html]
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[{.travis.yml, package.json}]
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
indent_size = 2
indent_style = space

6
.gitignore vendored

@ -1,6 +1,8 @@
static/
*.pyc *.pyc
frontend/static/
zsite/static/vendor/ zsite/static/vendor/
_env/ _env/
media/ media/
app/local.py
/static/vendor/
/static/

@ -12,11 +12,27 @@ $ source _env/bin/activate
``` ```
Часть внешник пакетов лежит в папке packages, нужно её связаться с PYTHONPATH Часть внешник пакетов лежит в папке packages, нужно её связаться с PYTHONPATH
```
$ pip install -r requirements.txt
```
### Установка библиотек для фронта
В проекте используется [пакетный менеджер bower](https://bower.io/).Ставим его в систему так
``` ```
$ pip install -r app/requirements.txt $ npm install -g bower
```
Установив bower, из корня проекта запускаем команду
```
$ cd zsite/static && bower i
``` ```
### Запуск ### Запуск
``` ```
$ ./manage.py runserver $ ./manage.py runserver
``` ```

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
import sys
from .settings import *
try:
from .local import *
except ImportError:
print("Can't find module settings.local! Make it from local.py.example")
# if manage.py test was called, use test settings
if 'test' in sys.argv or 'jenkins' in sys.argv:
try:
from .testing import *
except ImportError:
pass

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from .settings import INSTALLED_APPS
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '...'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
#INSTALLED_APPS += ('debug_toolbar', )
#MIDDLEWARE_CLASSES = ('debug_toolbar.middleware.DebugToolbarMiddleware', ) + MIDDLEWARE_CLASSES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': u'...',
'USER': u'...',
'PASSWORD': u'...',
'HOST': '',
'PORT': '',
}
}
ALLOWED_HOSTS = ['127.0.0.1']

@ -17,7 +17,7 @@ SECRET_KEY = '=%%a@whz46w1#=8ffk^a+8vya5fg-kz0ztyz!_@hdg-(5a9q+s'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
# Prod # Prod
DEBUG = False DEBUG = True
TEMPLATE_DEBUG = False TEMPLATE_DEBUG = False
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
'.zuykov.com', # Allow domain and subdomains '.zuykov.com', # Allow domain and subdomains
@ -101,7 +101,7 @@ STATICFILES_FINDERS = (
) )
PIPELINE = { PIPELINE = {
'PIPELINE_ENABLED': True, 'PIPELINE_ENABLED': False,
'JAVASCRIPT': { 'JAVASCRIPT': {
'main': { 'main': {
'source_filenames': ( 'source_filenames': (
@ -167,7 +167,7 @@ MIDDLEWARE_CLASSES = (
'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware', 'cms.middleware.language.LanguageCookieMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', # WARNING: В продакшене должно быть включено # 'django.middleware.cache.FetchFromCacheMiddleware', # WARNING: В продакшене должно быть включено
'country_segment.middleware.ResolveCountryCodeMiddleware', 'country_segment.middleware.ResolveCountryCodeMiddleware',
'promo.middleware.cookies.PageHistoryMiddleware', 'promo.middleware.cookies.PageHistoryMiddleware',
'django.middleware.gzip.GZipMiddleware', 'django.middleware.gzip.GZipMiddleware',

@ -2,12 +2,13 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
import filer
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('aldryn_people', '0003_auto_20150425_2103'), ('aldryn_people', '0003_auto_20150425_2103'),
('filer', '0002_auto_20150606_2003'),
] ]
operations = [ operations = [
@ -31,4 +32,46 @@ class Migration(migrations.Migration):
field=models.CharField(max_length=15, verbose_name='Language', db_index=True), field=models.CharField(max_length=15, verbose_name='Language', db_index=True),
preserve_default=True, preserve_default=True,
), ),
migrations.RemoveField(
model_name='group',
name='address',
),
migrations.RemoveField(
model_name='group',
name='city',
),
migrations.RemoveField(
model_name='person',
name='name',
),
migrations.AddField(
model_name='grouptranslation',
name='address',
field=models.TextField(verbose_name='address', blank=True),
preserve_default=True,
),
migrations.AddField(
model_name='grouptranslation',
name='city',
field=models.CharField(max_length=255, verbose_name='city', blank=True),
preserve_default=True,
),
migrations.AddField(
model_name='person',
name='visual_portrait',
field=filer.fields.image.FilerImageField(related_name='visual_portrait', on_delete=models.deletion.SET_NULL, default=None, blank=True, to='filer.Image', null=True),
preserve_default=True,
),
migrations.AddField(
model_name='persontranslation',
name='name',
field=models.CharField(default='', max_length=255, verbose_name='name'),
preserve_default=False,
),
migrations.AlterField(
model_name='person',
name='visual',
field=filer.fields.image.FilerImageField(related_name='visual', on_delete=models.deletion.SET_NULL, default=None, blank=True, to='filer.Image', null=True),
preserve_default=True,
)
] ]

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
import aldryn_common.admin_fields.sortedm2m
class Migration(migrations.Migration):
dependencies = [
('aldryn_people', '0004_auto_20150622_1606'),
]
operations = [
migrations.AlterField(
model_name='peopleplugin',
name='people',
field=aldryn_common.admin_fields.sortedm2m.SortedM2MModelField(help_text=None, to='aldryn_people.Person', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='person',
name='user',
field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL),
preserve_default=True,
),
]

@ -104,9 +104,9 @@ class Person(TranslatableModel):
unique=True) unique=True)
vcard_enabled = models.BooleanField( vcard_enabled = models.BooleanField(
verbose_name=_('enable vCard download'), default=True) verbose_name=_('enable vCard download'), default=True)
user = models.ForeignKey( user = models.OneToOneField(
getattr(settings, 'AUTH_USER_MODEL', 'auth.User'), getattr(settings, 'AUTH_USER_MODEL', 'auth.User'),
null=True, blank=True, unique=True) null=True, blank=True)
class Meta: class Meta:
verbose_name = _('Person') verbose_name = _('Person')
@ -218,7 +218,7 @@ class BasePeoplePlugin(CMSPlugin):
_('Style'), choices=STYLE_CHOICES, _('Style'), choices=STYLE_CHOICES,
default=STYLE_CHOICES[0][0], max_length=50) default=STYLE_CHOICES[0][0], max_length=50)
people = aldryn_common.admin_fields.sortedm2m.SortedM2MModelField( people = aldryn_common.admin_fields.sortedm2m.SortedM2MModelField(
Person, blank=True, null=True) Person, blank=True)
group_by_group = models.BooleanField( group_by_group = models.BooleanField(
verbose_name=_('group by group'), verbose_name=_('group by group'),
default=True, default=True,

@ -1,125 +1,83 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime from __future__ import unicode_literals
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from django.db import models, migrations
class Migration(SchemaMigration):
def forwards(self, orm): class Migration(migrations.Migration):
# Adding model 'SegmentLimitPluginModel'
db.create_table(u'aldryn_segmentation_segmentlimitpluginmodel', (
(u'cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
('label', self.gf('django.db.models.fields.CharField')(default=u'', max_length=128, blank=True)),
('max_children', self.gf('django.db.models.fields.PositiveIntegerField')(default=1)),
))
db.send_create_signal(u'aldryn_segmentation', ['SegmentLimitPluginModel'])
# Adding model 'FallbackSegmentPluginModel' dependencies = [
db.create_table(u'aldryn_segmentation_fallbacksegmentpluginmodel', ( ('cms', '0012_auto_20150607_2207'),
(u'cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)), ]
('label', self.gf('django.db.models.fields.CharField')(default=u'', max_length=128, blank=True)),
))
db.send_create_signal(u'aldryn_segmentation', ['FallbackSegmentPluginModel'])
# Adding model 'SwitchSegmentPluginModel' operations = [
db.create_table(u'aldryn_segmentation_switchsegmentpluginmodel', ( migrations.CreateModel(
(u'cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)), name='Segment',
('label', self.gf('django.db.models.fields.CharField')(default=u'', max_length=128, blank=True)), fields=[
('on_off', self.gf('django.db.models.fields.BooleanField')(default=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
)) ],
db.send_create_signal(u'aldryn_segmentation', ['SwitchSegmentPluginModel']) options={
'managed': False,
# Adding model 'CookieSegmentPluginModel'
db.create_table(u'aldryn_segmentation_cookiesegmentpluginmodel', (
(u'cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
('label', self.gf('django.db.models.fields.CharField')(default=u'', max_length=128, blank=True)),
('cookie_key', self.gf('django.db.models.fields.CharField')(default=u'', max_length=4096)),
('cookie_value', self.gf('django.db.models.fields.CharField')(default=u'', max_length=4096)),
))
db.send_create_signal(u'aldryn_segmentation', ['CookieSegmentPluginModel'])
# Adding model 'AuthenticatedSegmentPluginModel'
db.create_table(u'aldryn_segmentation_authenticatedsegmentpluginmodel', (
(u'cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
('label', self.gf('django.db.models.fields.CharField')(default=u'', max_length=128, blank=True)),
))
db.send_create_signal(u'aldryn_segmentation', ['AuthenticatedSegmentPluginModel'])
def backwards(self, orm):
# Deleting model 'SegmentLimitPluginModel'
db.delete_table(u'aldryn_segmentation_segmentlimitpluginmodel')
# Deleting model 'FallbackSegmentPluginModel'
db.delete_table(u'aldryn_segmentation_fallbacksegmentpluginmodel')
# Deleting model 'SwitchSegmentPluginModel'
db.delete_table(u'aldryn_segmentation_switchsegmentpluginmodel')
# Deleting model 'CookieSegmentPluginModel'
db.delete_table(u'aldryn_segmentation_cookiesegmentpluginmodel')
# Deleting model 'AuthenticatedSegmentPluginModel'
db.delete_table(u'aldryn_segmentation_authenticatedsegmentpluginmodel')
models = {
u'aldryn_segmentation.authenticatedsegmentpluginmodel': {
'Meta': {'object_name': 'AuthenticatedSegmentPluginModel'},
u'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'})
},
u'aldryn_segmentation.cookiesegmentpluginmodel': {
'Meta': {'object_name': 'CookieSegmentPluginModel'},
u'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
'cookie_key': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '4096'}),
'cookie_value': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '4096'}),
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'})
}, },
u'aldryn_segmentation.fallbacksegmentpluginmodel': { bases=(models.Model,),
'Meta': {'object_name': 'FallbackSegmentPluginModel'}, ),
u'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}), migrations.CreateModel(
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'}) name='AuthenticatedSegmentPluginModel',
fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('label', models.CharField(default='', max_length=128, verbose_name='label', blank=True)),
],
options={
'abstract': False,
}, },
u'aldryn_segmentation.segment': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'Segment', 'managed': 'False'}, ),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) migrations.CreateModel(
name='CookieSegmentPluginModel',
fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('label', models.CharField(default='', max_length=128, verbose_name='label', blank=True)),
('cookie_key', models.CharField(default='', help_text='Name of cookie to consider.', max_length=4096, verbose_name='name of cookie')),
('cookie_value', models.CharField(default='', help_text='Value to consider.', max_length=4096, verbose_name='value to compare')),
],
options={
'abstract': False,
}, },
u'aldryn_segmentation.segmentlimitpluginmodel': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'SegmentLimitPluginModel', '_ormbases': ['cms.CMSPlugin']}, ),
u'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}), migrations.CreateModel(
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'}), name='FallbackSegmentPluginModel',
'max_children': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}) fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('label', models.CharField(default='', max_length=128, verbose_name='label', blank=True)),
],
options={
'abstract': False,
}, },
u'aldryn_segmentation.switchsegmentpluginmodel': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'SwitchSegmentPluginModel'}, ),
u'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}), migrations.CreateModel(
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'}), name='SegmentLimitPluginModel',
'on_off': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('label', models.CharField(default='', help_text='Optionally set a label for this limit block.', max_length=128, verbose_name='label', blank=True)),
('max_children', models.PositiveIntegerField(default=1, help_text='Display up to how many matching segments?', verbose_name='# of matches to display')),
],
options={
'abstract': False,
}, },
'cms.cmsplugin': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'CMSPlugin'}, ),
'changed_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), migrations.CreateModel(
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), name='SwitchSegmentPluginModel',
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), fields=[
'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}), ('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), ('label', models.CharField(default='', max_length=128, verbose_name='label', blank=True)),
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), ('on_off', models.BooleanField(default=True, help_text='Uncheck to always hide child plugins.', verbose_name='Always on?')),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}), ],
'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}), options={
'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}), 'abstract': False,
'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
}, },
'cms.placeholder': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'Placeholder'}, ),
'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}), ]
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
}
}
complete_apps = ['aldryn_segmentation']

@ -21,16 +21,16 @@ class BlogCategoryAdmin(EnhancedModelAdminMixin, TranslatableAdmin):
class Media: class Media:
css = { css = {
'all': ('%sblog/css/%s' % (settings.STATIC_URL, 'all': ('%sblog/css/%s' % (settings.STATIC_URL, 'djangocms_blog_admin'),)
'blog_admin.css'),)
} }
class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin,
PlaceholderAdminMixin, TranslatableAdmin, admin.ModelAdmin): PlaceholderAdminMixin, TranslatableAdmin, admin.ModelAdmin):
form = PostAdminForm form = PostAdminForm
list_display = ['title', 'author', 'date_published', 'date_published_end'] list_display = ['title', 'author', 'date_published']
date_hierarchy = 'date_published' date_hierarchy = 'date_published'
list_filter = ('categories', 'author')
raw_id_fields = ['author'] raw_id_fields = ['author']
frontend_editable_fields = ('title', 'abstract', 'post_text') frontend_editable_fields = ('title', 'abstract', 'post_text')
enhance_exclude = ('main_image', 'tags') enhance_exclude = ('main_image', 'tags')
@ -75,12 +75,6 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin,
obj.author = user obj.author = user
super(PostAdmin, self).save_model(request, obj, form, change) super(PostAdmin, self).save_model(request, obj, form, change)
class Media:
css = {
'all': ('%sblog/css/%s' % (settings.STATIC_URL,
'blog_admin.css'),)
}
class BlogConfigAdmin( class BlogConfigAdmin(
PlaceholderAdminMixin, PlaceholderAdminMixin,
@ -90,7 +84,7 @@ class BlogConfigAdmin(
def get_config_fields(self): def get_config_fields(self):
return ( return (
'app_title', 'category_slug', 'app_title', 'category_slug',
'paginate_by' ) 'paginate_by')
admin.site.register(BlogConfig, BlogConfigAdmin) admin.site.register(BlogConfig, BlogConfigAdmin)

@ -19,6 +19,7 @@ class BlogLatestEntriesPlugin(BlogPlugin):
Non cached plugin which returns the latest posts taking into account the Non cached plugin which returns the latest posts taking into account the
user / toolbar state user / toolbar state
""" """
fields = ['app_config', 'latest_posts', 'tags', 'categories']
render_template = 'blog/plugins/latest_entries.html' render_template = 'blog/plugins/latest_entries.html'
name = _('Latest Blog Articles') name = _('Latest Blog Articles')
model = LatestPostsPlugin model = LatestPostsPlugin

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: djangocms-blog\n" "Project-Id-Version: djangocms-blog\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-08-04 00:08+0300\n" "POT-Creation-Date: 2017-04-07 18:38+0300\n"
"PO-Revision-Date: 2014-11-30 11:49+0000\n" "PO-Revision-Date: 2014-11-30 11:49+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n" "Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/djangocms-blog/" "Language-Team: Russian (http://www.transifex.com/projects/p/djangocms-blog/"
@ -20,219 +20,233 @@ msgstr ""
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 1.5\n" "X-Generator: Lokalize 1.5\n"
#: blog/cms_app.py:11 blog/cms_plugins.py:60 blog/cms_plugins.py:74 #: packages/blog/cms_app.py:11 packages/blog/cms_plugins.py:61
#: blog/cms_plugins.py:86 blog/cms_plugins.py:98 blog/cms_toolbar.py:18 #: packages/blog/cms_plugins.py:75 packages/blog/cms_plugins.py:87
#: packages/blog/cms_plugins.py:99 packages/blog/cms_toolbar.py:18
msgid "Blog" msgid "Blog"
msgstr "Блог" msgstr "Блог"
#: blog/cms_appconfig.py:22 #: packages/blog/cms_appconfig.py:22
msgid "application title" msgid "application title"
msgstr "" msgstr "название приложения"
#: blog/cms_appconfig.py:26 #: packages/blog/cms_appconfig.py:26
#, fuzzy #, fuzzy
#| msgid "Category" #| msgid "Category"
msgid "Category slug" msgid "Category slug"
msgstr "Категория" msgstr "Категория"
#: blog/cms_appconfig.py:29 #: packages/blog/cms_appconfig.py:29
msgid "Only category to display" msgid "Only category to display"
msgstr "" msgstr ""
#: blog/cms_appconfig.py:33 #: packages/blog/cms_appconfig.py:33
msgid "Paginate size" msgid "Paginate size"
msgstr "" msgstr "Пагинация"
#: blog/cms_appconfig.py:36 #: packages/blog/cms_appconfig.py:36
msgid "When paginating list views, how many articles per page?" msgid "When paginating list views, how many articles per page?"
msgstr "" msgstr "Количество статей на страницу"
#: blog/cms_appconfig.py:75 #: packages/blog/cms_appconfig.py:75
#, fuzzy #, fuzzy
#| msgid "Title" #| msgid "Title"
msgid "untitled" msgid "untitled"
msgstr "Заголовок" msgstr "Заголовок"
#: blog/cms_appconfig.py:80 #: packages/blog/cms_appconfig.py:80
msgid "Post published by default" msgid "Post published by default"
msgstr "" msgstr ""
#: blog/cms_plugins.py:23 blog/cms_plugins.py:47 #: packages/blog/cms_plugins.py:24 packages/blog/cms_plugins.py:48
msgid "Latest Blog Articles" msgid "Latest Blog Articles"
msgstr "Последние статьи блога" msgstr "Последние статьи блога"
#: blog/cms_plugins.py:61 #: packages/blog/cms_plugins.py:62
msgid "Author Blog Articles" msgid "Author Blog Articles"
msgstr "Автор" msgstr "Автор"
#: blog/cms_plugins.py:75 blog/templates/blog/plugins/tags.html:4 #: packages/blog/cms_plugins.py:76
#: packages/blog/templates/blog/plugins/tags.html:4
msgid "Tags" msgid "Tags"
msgstr "Тэги" msgstr "Тэги"
#: blog/cms_plugins.py:87 blog/templates/blog/plugins/categories.html:4 #: packages/blog/cms_plugins.py:88
#: packages/blog/templates/blog/plugins/categories.html:4
msgid "Categories" msgid "Categories"
msgstr "Categories" msgstr "Categories"
#: blog/cms_plugins.py:99 blog/templates/blog/plugins/archive.html:4 #: packages/blog/cms_plugins.py:100
#: blog/templates/blog/post_list.html:13 #: packages/blog/templates/blog/plugins/archive.html:4
#: packages/blog/templates/blog/post_list.html:13
msgid "Archive" msgid "Archive"
msgstr "Архив" msgstr "Архив"
#: blog/cms_toolbar.py:20 #: packages/blog/cms_toolbar.py:20
msgid "Post list" msgid "Post list"
msgstr "Список статей" msgstr "Список статей"
#: blog/cms_toolbar.py:22 #: packages/blog/cms_toolbar.py:22
msgid "Add post" msgid "Add post"
msgstr "Добавить статью" msgstr "Добавить статью"
#: blog/cms_toolbar.py:26 #: packages/blog/cms_toolbar.py:26
msgid "Edit Post" msgid "Edit Post"
msgstr "" msgstr "Редактировать статью"
#: blog/feeds.py:16 #: packages/blog/feeds.py:16
#, python-format #, python-format
msgid "Blog articles on %(site_name)s" msgid "Blog articles on %(site_name)s"
msgstr "Статьи из блог на %(site_name)s" msgstr "Статьи из блог на %(site_name)s"
#: blog/models.py:34 #: packages/blog/models.py:34
msgid "parent" msgid "parent"
msgstr "предок" msgstr "предок"
#: blog/models.py:36 #: packages/blog/models.py:36
msgid "created at" msgid "created at"
msgstr "время создания" msgstr "время создания"
#: blog/models.py:37 #: packages/blog/models.py:37
msgid "modified at" msgid "modified at"
msgstr "время изменения" msgstr "время изменения"
#: blog/models.py:40 #: packages/blog/models.py:40
msgid "name" msgid "name"
msgstr "название" msgstr "название"
#: blog/models.py:41 blog/models.py:118 #: packages/blog/models.py:41 packages/blog/models.py:117
msgid "slug" msgid "slug"
msgstr "URL" msgstr "URL"
#: blog/models.py:48 #: packages/blog/models.py:48
msgid "blog category" msgid "blog category"
msgstr "категория блога" msgstr "категория блога"
#: blog/models.py:49 #: packages/blog/models.py:49
msgid "blog categories" msgid "blog categories"
msgstr "категории блога" msgstr "категории блога"
#: blog/models.py:80 #: packages/blog/models.py:80
msgid "Author" msgid "Author"
msgstr "Автор" msgstr "Автор"
#: blog/models.py:85 #: packages/blog/models.py:85
msgid "Published Since" msgid "Published Since"
msgstr "Опубликована с" msgstr "Опубликована с"
#: blog/models.py:87 #: packages/blog/models.py:87
msgid "Published Until" msgid "Published Until"
msgstr "Опубликована до" msgstr "Опубликована до"
#: blog/models.py:89 #: packages/blog/models.py:89
msgid "Publish" msgid "Publish"
msgstr "Показывать на сайте" msgstr "Показывать на сайте"
#: blog/models.py:90 #: packages/blog/models.py:90
msgid "category" msgid "category"
msgstr "категория" msgstr "категория"
#: blog/models.py:92 #: packages/blog/models.py:92
msgid "Main image" msgid "Main image"
msgstr "Картинка для статьи" msgstr "Картинка для статьи"
#: blog/models.py:96 #: packages/blog/models.py:96
msgid "Main image thumbnail" msgid "Main image thumbnail"
msgstr "Уменьшенная копия" msgstr "Уменьшенная копия"
#: blog/models.py:101 #: packages/blog/models.py:101
msgid "Main image full" msgid "Main image full"
msgstr "Полный размер" msgstr "Полный размер"
#: blog/models.py:106 #: packages/blog/models.py:106
msgid "Enable comments on post" msgid "Enable comments on post"
msgstr "" msgstr "Разрешено комментировать статью"
#: blog/models.py:109 #: packages/blog/models.py:109
msgid "Site(s)" msgid "Site(s)"
msgstr "" msgstr "Сайты"
#: blog/models.py:111 #: packages/blog/models.py:110
msgid "" msgid ""
"Select sites in which to show the post. If none is set it will be visible in " "Select sites in which to show the post. If none is set it will be visible in "
"all the configured sites." "all the configured sites."
msgstr "" msgstr "Выберите сайты, на которых можно показать эту статью. Если ни один не выбран,"
"она будет видена на всех настроенных сайтах."
#: blog/models.py:117 #: packages/blog/models.py:116
msgid "Title" msgid "Title"
msgstr "Заголовок" msgstr "Заголовок"
#: blog/models.py:119 #: packages/blog/models.py:118
msgid "Abstract" msgid "Abstract"
msgstr "" msgstr ""
#: blog/models.py:120 #: packages/blog/models.py:119
msgid "Post meta description" msgid "Post meta description"
msgstr "" msgstr "Тег <description>"
#: blog/models.py:122 #: packages/blog/models.py:121
msgid "Post meta keywords" msgid "Post meta keywords"
msgstr "" msgstr "Тег <keywords>"
#: blog/models.py:124 #: packages/blog/models.py:123
msgid "Post meta title" msgid "Post meta title"
msgstr "" msgstr "Тег <title>"
#: blog/models.py:125 #: packages/blog/models.py:124
msgid "used in title tag and social sharing" msgid "used in title tag and social sharing"
msgstr "" msgstr "использовать в теге <title> соцсети"
#: blog/models.py:128 #: packages/blog/models.py:127
msgid "Text" msgid "Text"
msgstr "" msgstr "Текст"
#: blog/models.py:191 #: packages/blog/models.py:190
msgid "blog article" msgid "blog article"
msgstr "статья блога" msgstr "статья блога"
#: blog/models.py:192 #: packages/blog/models.py:191
msgid "blog articles" msgid "blog articles"
msgstr "статьи блога" msgstr "статьи блога"
#: blog/models.py:264 blog/models.py:288 #: packages/blog/models.py:263 packages/blog/models.py:293
msgid "Articles" msgid "Articles"
msgstr "Статьи" msgstr "Статьи"
#: blog/models.py:265 #: packages/blog/models.py:264
msgid "The number of latests articles to be displayed." msgid "The number of latests articles to be displayed."
msgstr "Количество показываемых последних статей." msgstr "Количество показываемых последних статей."
#: blog/models.py:267 #: packages/blog/models.py:266
msgid "Show only the blog articles tagged with chosen categories." msgid "Show only the blog articles tagged with chosen categories."
msgstr "Показывать только статьи из выбранныех категорий." msgstr "Показывать только статьи из выбранныех категорий."
#: blog/models.py:284 blog/templates/blog/plugins/authors.html:3 #: packages/blog/models.py:268
msgid "filter by tag"
msgstr "фильтр по тегу"
#: packages/blog/models.py:269
msgid "Show only the blog articles tagged with chosen tags."
msgstr "Показывать только статьи с выбранными тэгами."
#: packages/blog/models.py:289
#: packages/blog/templates/blog/plugins/authors.html:3
msgid "Authors" msgid "Authors"
msgstr "Авторы" msgstr "Авторы"
#: blog/models.py:289 #: packages/blog/models.py:294
msgid "The number of author articles to be displayed." msgid "The number of author articles to be displayed."
msgstr "Количество статей автора, которые будут показаны." msgstr "Количество статей автора, которые будут показаны."
#: blog/templates/blog/includes/blog_meta.html:7 #: packages/blog/templates/blog/includes/blog_meta.html:7
msgid "by" msgid "by"
msgstr "создана" msgstr "создана"
#: blog/templates/blog/plugins/archive.html:18 #: packages/blog/templates/blog/plugins/archive.html:18
#: blog/templates/blog/plugins/authors.html:10 #: packages/blog/templates/blog/plugins/authors.html:10
#: blog/templates/blog/plugins/categories.html:11 #: packages/blog/templates/blog/plugins/categories.html:11
#: blog/templates/blog/plugins/tags.html:11 #: packages/blog/templates/blog/plugins/tags.html:11
#, python-format #, python-format
msgid "1 article" msgid "1 article"
msgid_plural "%(articles)s articles" msgid_plural "%(articles)s articles"
@ -240,62 +254,59 @@ msgstr[0] "%(articles)s статья"
msgstr[1] "%(articles)s статьи" msgstr[1] "%(articles)s статьи"
msgstr[2] "%(articles)s статей" msgstr[2] "%(articles)s статей"
#: blog/templates/blog/plugins/archive.html:19 #: packages/blog/templates/blog/plugins/archive.html:19
#: blog/templates/blog/plugins/authors.html:11 #: packages/blog/templates/blog/plugins/authors.html:11
#: blog/templates/blog/plugins/categories.html:12 #: packages/blog/templates/blog/plugins/categories.html:12
#: blog/templates/blog/plugins/tags.html:12 #: packages/blog/templates/blog/plugins/tags.html:12
msgid "0 articles" msgid "0 articles"
msgstr "0 статей" msgstr "0 статей"
#: blog/templates/blog/plugins/archive.html:27 #: packages/blog/templates/blog/plugins/archive.html:27
#: blog/templates/blog/plugins/authors.html:15 #: packages/blog/templates/blog/plugins/authors.html:15
#: blog/templates/blog/plugins/latest_entries.html:10 #: packages/blog/templates/blog/plugins/latest_entries.html:10
#: blog/templates/blog/plugins/tags.html:16 #: packages/blog/templates/blog/plugins/tags.html:16
#: blog/templates/blog/post_list.html:30 #: packages/blog/templates/blog/post_list.html:38
msgid "No article found." msgid "No article found."
msgstr "Не найдено ни одной статьи." msgstr "Не найдено ни одной статьи."
#: blog/templates/blog/plugins/categories.html:16 #: packages/blog/templates/blog/plugins/categories.html:16
#, fuzzy #, fuzzy
#| msgid "No article found." #| msgid "No article found."
msgid "No categories found." msgid "No categories found."
msgstr "Не найдено ни одной статьи." msgstr "Не найдено ни одной статьи."
#: blog/templates/blog/post_list.html:12 #: packages/blog/templates/blog/post_list.html:12
msgid "Articles by" msgid "Articles by"
msgstr "Статьи созданы" msgstr "Статьи созданы"
#: blog/templates/blog/post_list.html:14 #: packages/blog/templates/blog/post_list.html:14
msgid "Tag" msgid "Tag"
msgstr "Тэг" msgstr "Тэг"
#: blog/templates/blog/post_list.html:15 #: packages/blog/templates/blog/post_list.html:15
msgid "Category" msgid "Category"
msgstr "Категория" msgstr "Категория"
#: blog/templates/blog/post_list.html:34 #: packages/blog/templates/blog/post_list.html:42
msgid "Back" msgid "Back"
msgstr "Назад" msgstr "Назад"
#: blog/templates/blog/post_list.html:39 #: packages/blog/templates/blog/post_list.html:47
msgid "previous" msgid "previous"
msgstr "предыдущая" msgstr "предыдущая"
#: blog/templates/blog/post_list.html:42 #: packages/blog/templates/blog/post_list.html:50
msgid "Page" msgid "Page"
msgstr "Страница" msgstr "Страница"
#: blog/templates/blog/post_list.html:42 #: packages/blog/templates/blog/post_list.html:50
msgid "of" msgid "of"
msgstr "из" msgstr "из"
#: blog/templates/blog/post_list.html:45 #: packages/blog/templates/blog/post_list.html:53
msgid "next" msgid "next"
msgstr "следующая" msgstr "следующая"
#~ msgid "Show only the blog articles tagged with chosen tags."
#~ msgstr "Показывать только статьи с выбранными тэгами."
#~ msgid "read more" #~ msgid "read more"
#~ msgstr "продолжение" #~ msgstr "продолжение"

@ -19,7 +19,7 @@ class Migration(migrations.Migration):
('cms', '0003_auto_20140926_2347'), ('cms', '0003_auto_20140926_2347'),
('taggit', '__first__'), ('taggit', '__first__'),
('filer', '0001_initial'), ('filer', '0001_initial'),
('cmsplugin_filer_image', '0001_initial'), # ('cmsplugin_filer_image', '0001_initial'),
] ]
operations = [ operations = [

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('blog', '0009_auto_20150726_2021'),
]
operations = [
migrations.AlterField(
model_name='post',
name='author',
field=models.ForeignKey(related_name='blog_post_author', verbose_name='Author', blank=True, to='aldryn_people.Person', null=True),
preserve_default=True,
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('blog', '0010_auto_20170401_1032'),
]
operations = [
migrations.AlterField(
model_name='post',
name='sites',
field=models.ManyToManyField(help_text='Select sites in which to show the post. If none is set it will be visible in all the configured sites.', to='sites.Site', verbose_name='Site(s)', blank=True),
preserve_default=True,
),
]

@ -107,7 +107,6 @@ class Post(ModelMeta, TranslatableModel):
default=get_setting('ENABLE_COMMENTS') default=get_setting('ENABLE_COMMENTS')
) )
sites = models.ManyToManyField(Site, verbose_name=_(u'Site(s)'), blank=True, sites = models.ManyToManyField(Site, verbose_name=_(u'Site(s)'), blank=True,
null=True,
help_text=_(u'Select sites in which to show the post. ' help_text=_(u'Select sites in which to show the post. '
u'If none is set it will be ' u'If none is set it will be '
u'visible in all the configured sites.') u'visible in all the configured sites.')
@ -266,13 +265,19 @@ class LatestPostsPlugin(BasePostPlugin):
categories = models.ManyToManyField('BlogCategory', blank=True, categories = models.ManyToManyField('BlogCategory', blank=True,
help_text=_('Show only the blog articles tagged with chosen categories.')) help_text=_('Show only the blog articles tagged with chosen categories.'))
tags = TaggableManager(_('filter by tag'), blank=True,
help_text=_('Show only the blog articles tagged with chosen tags.'),
related_name='djangocms_blog_latest_post')
def __str__(self): def __str__(self):
return u'%s latest articles by category' % self.latest_posts return u'%s latest articles by category' % self.latest_posts
def get_posts(self, request): def get_posts(self, request):
posts = self.post_queryset(request) posts = self.post_queryset(request)
if self.tags.exists():
posts = posts.filter(tags__in=list(self.tags.all()))
if self.categories.exists(): if self.categories.exists():
posts = posts.filter(categories__in=list(self.categories.all())) posts = posts.filter(categories__in=list(self.categories.all()))

@ -13,11 +13,11 @@
</ul> </ul>
{% endblock breadcrumb %} {% endblock breadcrumb %}
{% block content_blog %}{% spaceless %} {% block content_blog %}
<article id="post-{{ post.slug }}" class="post-item post-detail"> <article id="post-{{ post.slug }}" class="post-item post-detail">
<content> <content>
<header> <header>
<h1>{% render_model post "title" %}</h1> <h1>{{ post.title }}</h1>
<p class="date">{{ post.date_published|date:"DATE_FORMAT" }}</p> <p class="date">{{ post.date_published|date:"DATE_FORMAT" }}</p>
</header> </header>
{% if post.main_image_id %} {% if post.main_image_id %}
@ -26,9 +26,9 @@
<img src="{{ thumb.url }}" alt="{{ post.main_image.default_alt_text }}" width="{{ thumb.width }}" height="{{ thumb.height }}" /> <img src="{{ thumb.url }}" alt="{{ post.main_image.default_alt_text }}" width="{{ thumb.width }}" height="{{ thumb.height }}" />
</div> </div>
{% endif %} {% endif %}
{% endspaceless %}
<div class="blog-content">{% render_model post "abstract" %}</div>
<div class="blog-content">{{ post.abstract|safe }}</div>
</content> </content>
<side> <side>
<author> <author>

@ -11,12 +11,20 @@
<h2> <h2>
{% if author %}{% trans "Articles by" %} {{ author.get_full_name }} {% if author %}{% trans "Articles by" %} {{ author.get_full_name }}
{% elif archive_date %}{% trans "Archive" %} &ndash; {% if month %}{{ archive_date|date:'F' }} {% endif %}{{ year }} {% elif archive_date %}{% trans "Archive" %} &ndash; {% if month %}{{ archive_date|date:'F' }} {% endif %}{{ year }}
{% elif tagged_entries %}{% trans "Tag" %} &ndash; {{ tagged_entries|capfirst }} {% elif tagged_entries %}{% trans "Tag" %} &ndash; {{ tag|capfirst }}
{% elif category %}{% trans "Category" %} &ndash; {{ category }}{% endif %} {% elif category %}{% trans "Category" %} &ndash; {{ category }}{% endif %}
{{ category }} {{ category }}
</h2> </h2>
</header> </header>
{% endblock %} {% endblock %}
{% if tags %}
<ul class="blog-tags">
{% for tag in tags %}
{{ tag.count }}
<li class="blog-tag"><a class="btn btn-xs btn-default" href="{% url "blog:posts-tagged" tag=tag.slug %}">{{ tag.name|capfirst }}</a></li>
{% endfor %}
</ul>
{% endif %}
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="blog-list-older"> <div class="blog-list-older">
{% for post in post_list %} {% for post in post_list %}

@ -8,7 +8,7 @@ from django.views.generic import ListView, DetailView
from parler.views import ViewUrlMixin, TranslatableSlugMixin from parler.views import ViewUrlMixin, TranslatableSlugMixin
from aldryn_apphooks_config.mixins import AppConfigMixin from aldryn_apphooks_config.mixins import AppConfigMixin
from taggit.models import Tag
from .models import Post, BlogCategory, BLOG_CURRENT_POST_IDENTIFIER from .models import Post, BlogCategory, BLOG_CURRENT_POST_IDENTIFIER
from .settings import get_setting from .settings import get_setting
@ -45,6 +45,7 @@ class PostListView(BaseBlogView, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs) context = super(PostListView, self).get_context_data(**kwargs)
context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT') context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT')
context['tags'] = Tag.objects.all()
return context return context
@ -106,6 +107,8 @@ class TaggedListView(BaseBlogView, ListView):
kwargs['tagged_entries'] = (self.kwargs.get('tag') kwargs['tagged_entries'] = (self.kwargs.get('tag')
if 'tag' in self.kwargs else None) if 'tag' in self.kwargs else None)
context = super(TaggedListView, self).get_context_data(**kwargs) context = super(TaggedListView, self).get_context_data(**kwargs)
if kwargs['tagged_entries']:
context['tag'] = Tag.objects.get(slug=kwargs['tagged_entries'])
context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT') context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT')
return context return context

@ -1,71 +1,44 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime from __future__ import unicode_literals
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from django.db import models, migrations
import tinymce.models
class Migration(SchemaMigration):
def forwards(self, orm): class Migration(migrations.Migration):
# Adding model 'CMSTabsList'
db.create_table('cmsplugin_cmstabslist', (
('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
))
db.send_create_signal('cmsplugin_tabs', ['CMSTabsList'])
# Adding model 'SingleTab' dependencies = [
db.create_table('cmsplugin_tabs_singletab', ( ('cms', '0003_auto_20140926_2347'),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ]
('plugin', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tabs', to=orm['cmsplugin_tabs.CMSTabsList'])),
('title', self.gf('django.db.models.fields.CharField')(max_length=32)),
('content', self.gf('django.db.models.fields.TextField')()),
('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, db_index=True)),
))
db.send_create_signal('cmsplugin_tabs', ['SingleTab'])
operations = [
def backwards(self, orm): migrations.CreateModel(
# Deleting model 'CMSTabsList' name='CMSTabsList',
db.delete_table('cmsplugin_cmstabslist') fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
# Deleting model 'SingleTab' ('template', models.CharField(default=b'cmsplugin_tabs/tabs.html', max_length=255, verbose_name='Template', choices=[(b'cmsplugin_tabs/tabs.html', 'Tabs'), (b'cmsplugin_tabs/accordion.html', 'Accordion')])),
db.delete_table('cmsplugin_tabs_singletab') ],
options={
'abstract': False,
models = {
'cms.cmsplugin': {
'Meta': {'object_name': 'CMSPlugin'},
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
},
'cms.placeholder': {
'Meta': {'object_name': 'Placeholder'},
'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
}, },
'cmsplugin_tabs.cmstabslist': { bases=('cms.cmsplugin',),
'Meta': {'object_name': 'CMSTabsList', 'db_table': "'cmsplugin_cmstabslist'", '_ormbases': ['cms.CMSPlugin']}, ),
'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}) migrations.CreateModel(
name='SingleTab',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(max_length=255, verbose_name='Title')),
('content', tinymce.models.HTMLField(verbose_name='Content')),
('slug', models.SlugField(default=b'', max_length=32, verbose_name='Slug', blank=True)),
('order', models.PositiveIntegerField(default=1, verbose_name='Order', db_index=True)),
('is_strong', models.BooleanField(default=False, help_text='When True then label of the tab will be bold', verbose_name='Strong')),
('plugin', models.ForeignKey(related_name='tabs', to='cmsplugin_tabs.CMSTabsList')),
],
options={
'ordering': ['order'],
'verbose_name': 'Tab',
'verbose_name_plural': 'Tabs',
}, },
'cmsplugin_tabs.singletab': { bases=(models.Model,),
'Meta': {'ordering': "['order']", 'object_name': 'SingleTab'}, ),
'content': ('django.db.models.fields.TextField', [], {}), ]
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
'plugin': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tabs'", 'to': "orm['cmsplugin_tabs.CMSTabsList']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '32'})
}
}
complete_apps = ['cmsplugin_tabs']

File diff suppressed because one or more lines are too long

@ -93,13 +93,4 @@ var form = {
</div> </div>
</div> </div>
{% addtoblock "js" %}
<script src="{% static 'js/djangocms_forms/libs/jquery.form.min.js' %}"></script>
<script src="{% static 'js/djangocms_forms/djangocms_forms.js' %}"></script>
<script type="application/javascript">
$(function() {
$('.forms').djangocms_forms();
});
</script>
{% endaddtoblock %}

File diff suppressed because one or more lines are too long

@ -5,7 +5,7 @@ from django.db import models, migrations
import django.db.models.deletion import django.db.models.deletion
import parler.models import parler.models
import djangocms_text_ckeditor.fields import djangocms_text_ckeditor.fields
import cms
class Migration(migrations.Migration): class Migration(migrations.Migration):
operations = [ operations = [
@ -43,4 +43,18 @@ class Migration(migrations.Migration):
name='promotranslation', name='promotranslation',
unique_together=set([('language_code', 'master')]), unique_together=set([('language_code', 'master')]),
), ),
migrations.AlterModelOptions(
name='promo',
options={'verbose_name': 'promo', 'verbose_name_plural': 'promos'},
),
migrations.RemoveField(
model_name='promotranslation',
name='title',
),
migrations.AlterField(
model_name='promo',
name='page_link',
field=cms.models.fields.PageField(on_delete=models.deletion.SET_NULL, blank=True, to='cms.Page', help_text='A link to a page has priority over a text link.', null=True, verbose_name='page'),
preserve_default=True,
),
] ]

@ -0,0 +1 @@
-r requirements/prod.txt

@ -1,25 +1,24 @@
aldryn-apphooks-config==0.2.6 aldryn-apphooks-config==0.2.6
aldryn-boilerplates==0.7.3 aldryn-boilerplates==0.7.4
aldryn-bootstrap3==0.5.2 aldryn-bootstrap3==1.1.2 # Up: 1.04.2017
aldryn-common==0.1.4 aldryn-common==1.0.4 # Up: 1.04.2017
aldryn-translation-tools==0.2.1 aldryn-translation-tools==0.2.1
cmsplugin-filer==0.10.2 cmsplugin-filer==1.0.1
dj-database-url==0.3.0 dj-database-url==0.3.0
Django==1.7.8 Django==1.7.11
django-admin-enhancer==1.0.0 django-admin-enhancer==1.0.0
django-admin-extend==0.0.3 django-admin-extend==0.0.3
django-appconf==1.0.1 django-appconf==1.0.2
django-appdata==0.1.4 django-appdata==0.1.5
django-classy-tags==0.6.2 django-classy-tags==0.6.2
django-cms==3.1.3 django-cms==3.2.5
django-debug-toolbar==1.4
django-durationfield==0.5.2 django-durationfield==0.5.2
django-easy-select2==1.3.3 django-easy-select2==1.3.3
django-filer==0.9.12 django-filer==1.1.1
django-formtools==1.0 django-formtools==1.0
django-ipware==1.1.1 django-ipware==1.1.1
django-meta==0.3.1 django-meta==1.3.2
django-meta-mixin==0.2.1 django-meta-mixin==0.3.0
django-mptt==0.7.4 django-mptt==0.7.4
django-multipleformwizard==0.2.16 django-multipleformwizard==0.2.16
django-parler==1.5.1 django-parler==1.5.1
@ -27,7 +26,7 @@ django-phonenumber-field==0.7.2
django-pipeline==1.6.12 django-pipeline==1.6.12
django-polymorphic==0.7.2 django-polymorphic==0.7.2
django-reversion==1.9.3 django-reversion==1.9.3
django-sekizai==0.8.2 django-sekizai==0.10.0
Django-Select2==4.3.2 Django-Select2==4.3.2
django-sortedm2m==1.0.2 django-sortedm2m==1.0.2
django-taggit==0.17.3 django-taggit==0.17.3
@ -39,13 +38,13 @@ djangocms-column==1.5
djangocms-file==0.1 djangocms-file==0.1
djangocms-flash==0.2.0 djangocms-flash==0.2.0
djangocms-googlemap==0.3 djangocms-googlemap==0.3
djangocms-inherit==0.1 djangocms-inherit==0.1.1
djangocms-installer==0.8.1 djangocms-installer==0.8.1
djangocms-link==1.7.1 djangocms-link==1.7.1
djangocms-picture==0.1 djangocms-picture==0.1
djangocms-style==1.5 djangocms-style==1.5
djangocms-teaser==0.1 djangocms-teaser==0.1
djangocms-text-ckeditor==2.6.0 djangocms-text-ckeditor==2.8.1
djangocms-video==0.1 djangocms-video==0.1
easy-thumbnails==2.2 easy-thumbnails==2.2
futures==3.0.3 futures==3.0.3
@ -64,14 +63,12 @@ pytz==2015.7
pyuca==1.1 pyuca==1.1
requests==2.8.1 requests==2.8.1
six==1.10.0 six==1.10.0
South==1.0.2
sqlparse==0.1.18 sqlparse==0.1.18
tablib==0.10.0 tablib==0.10.0
tzlocal==1.2 tzlocal==1.2
Unidecode==0.4.18 Unidecode==0.4.18
vobject==0.6.6 vobject==0.6.6
YURL==0.13 YURL==0.13
#
pymorphy2==0.8 pymorphy2==0.8
pymorphy2-dicts==2.4.393442.3710985 pymorphy2-dicts==2.4.393442.3710985
DAWG-Python==0.7.2 DAWG-Python==0.7.2

@ -0,0 +1,3 @@
-r common.txt
django-debug-toolbar==1.4
deployer-0.3.10

@ -0,0 +1 @@
-r common.txt

File diff suppressed because one or more lines are too long

@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import urllib2 import urllib2
@ -75,12 +74,20 @@ class TrademarkSearchAPI():
'module': 'search', 'module': 'search',
'procedure': 'get_result', 'procedure': 'get_result',
'search_id': search_id, 'search_id': search_id,
'databases': [21] 'databases': [21, 23]
} }
data = self.send_request(request) data = self.send_request(request)
if int(data['total_records_found']) > 0: if int(data['total_records_found']) > 0:
return data['records_list']['21']['records'], status records = data['records_list']
trademarks = {}
if records.get('21', None):
trademarks = records['21']['records'].copy()
if records.get('23', None):
trademarks.update(records['23']['records'])
return trademarks, status
else: else:
return None, status return None, status
@ -94,7 +101,12 @@ class TrademarkSearchAPI():
data = self.send_request(request) data = self.send_request(request)
return data['records_list']['21']['records'] rospatent = data['records_list'].get('21', {}).get('records', {})
romarin = data['records_list'].get('23', {}).get('records', {})
rospatent.update(romarin)
return rospatent

@ -137,4 +137,28 @@ class Migration(migrations.Migration):
field=models.ManyToManyField(to='trademark.Trademark', through='trademark.SearchResult'), field=models.ManyToManyField(to='trademark.Trademark', through='trademark.SearchResult'),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField(
model_name='nice',
name='glyph',
field=models.CharField(default='', max_length=255),
preserve_default=False,
),
migrations.AlterField(
model_name='trademark',
name='application_id',
field=models.CharField(max_length=50, null=True),
preserve_default=True,
),
migrations.AlterField(
model_name='trademark',
name='cert_id',
field=models.CharField(max_length=50, null=True),
preserve_default=True,
),
migrations.AlterField(
model_name='trademark',
name='ext_id',
field=models.CharField(unique=True, max_length=50),
preserve_default=True,
),
] ]

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('trademark', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='nice',
name='glyph',
field=models.CharField(default='', max_length=255),
preserve_default=False,
),
]

@ -13,11 +13,13 @@ from django.template.defaultfilters import slugify
from datetime import date from datetime import date
from datetime import timedelta from datetime import timedelta
from dateutil.parser import parse
# from .cms_appconfig import TrademarkConfig # from .cms_appconfig import TrademarkConfig
from collections import defaultdict from collections import defaultdict
import re import re
TrademarkAPI = TrademarkSearchAPI() TrademarkAPI = TrademarkSearchAPI()
class Owner(models.Model): class Owner(models.Model):
@ -70,7 +72,7 @@ class Nice(models.Model):
alphabet = defaultdict(lambda : defaultdict(list)) alphabet = defaultdict(lambda : defaultdict(list))
for product in self.popular_products: for product in self.popular_products:
letter = product.title[0].upper() letter = product.title[0].upper()
first_word = product.title.split(' ')[0] first_word = product.title.split(' ')[0].replace(',', '')
# if title_sense: # if title_sense:
alphabet[letter][first_word.capitalize()].append(product) alphabet[letter][first_word.capitalize()].append(product)
@ -82,23 +84,23 @@ class Nice(models.Model):
if len(products) == 1: if len(products) == 1:
del alphabet[letter][first_word] del alphabet[letter][first_word]
product = products.pop() product = products.pop()
words = product.title words = product.title.strip()
alphabet[letter][words] = product.id alphabet[letter][words] = product.id
else: else:
words = [] words = []
for product in alphabet[letter][first_word]: for product in alphabet[letter][first_word]:
title = re.sub("[\(\[].*?[\)\]]", "", product.title) title = re.sub("[\(\[].*?[\)\]]", "", product.title)
title_sense = title.replace(first_word, '').strip() title_sense = title.replace(first_word, '')
if title_sense: if title_sense:
if title_sense[0] == ',':
title_sense = title_sense[1:].strip()
words.append(title_sense) words.append(title_sense)
# words = [product.title for product in alphabet[letter][first_word]]
alphabet[letter][first_word] = ', '.join(set(words)) alphabet[letter][first_word] = ', '.join([word for word in set(words) if word])
letter_items = alphabet[letter] letter_items = alphabet[letter]
alphabet[letter] = sorted(letter_items.items(), key=lambda x: type(x[1])) alphabet[letter] = sorted(letter_items.items(), key=lambda x: type(x[1]))
# alphabet[letter] = letter_items.items()
print alphabet
return sorted(alphabet.items()) return sorted(alphabet.items())
@ -121,9 +123,9 @@ class Product(models.Model):
class Trademark(models.Model): class Trademark(models.Model):
title = models.CharField(max_length=255, null=True) title = models.CharField(max_length=255, null=True)
ext_id = models.CharField(max_length=20, unique=True) ext_id = models.CharField(max_length=50, unique=True)
application_id = models.CharField(max_length=12, null=True) application_id = models.CharField(max_length=50, null=True)
cert_id = models.CharField(max_length=12, null=True) cert_id = models.CharField(max_length=50, null=True)
owner = models.TextField(null=True) owner = models.TextField(null=True)
image_url = models.URLField(null=True) image_url = models.URLField(null=True)
nices = models.ManyToManyField(Nice) nices = models.ManyToManyField(Nice)
@ -306,19 +308,40 @@ class Search(models.Model):
if not created: if not created:
continue continue
instance.title = trademark['wdesc'] instance.title = trademark.get('wdesc', '')
instance.application_id = trademark['appnum']
instance.cert_id = trademark['certnum'] instance.application_id = trademark.get('appnum', '')
instance.owner = trademark['owner'][0]['name'].encode('utf-8') instance.cert_id = trademark.get('certnum', '')
try:
owner = trademark['owner'].pop()
name = owner.get('name', None)
addr = owner.get('addr', None)
country = owner.get('country', None)
legnat = owner.get('legnat', None)
owner_list = [item for item in set([name, legnat, addr, country]) if item]
instance.owner = ', '.join(owner_list)
except:
pass
instance.image_url = trademark.get('image', '') instance.image_url = trademark.get('image', '')
instance.status = trademark['status'] instance.status = trademark.get('status', '')
instance.application_at = trademark['dateapp'] application_at = trademark.get('dateapp', None)
instance.registration_at = trademark['datereg'] if application_at:
instance.application_at = parse(application_at)
registration_at = trademark.get('datereg', None)
if registration_at:
instance.registration_at = parse(registration_at)
instance.access_key = trademark['access_key'] instance.access_key = trademark.get('access_key', '')
try:
instance.save() instance.save()
except:
print "Error"
print trademark
for nice_id in trademark.get('icgs', []): for nice_id in trademark.get('icgs', []):
nice, created = Nice.objects.get_or_create(nice_id=nice_id) nice, created = Nice.objects.get_or_create(nice_id=nice_id)
@ -337,8 +360,12 @@ class Search(models.Model):
for key, trademark in details.iteritems(): for key, trademark in details.iteritems():
instance = Trademark.objects.get(ext_id=trademark['id']) instance = Trademark.objects.get(ext_id=trademark['id'])
instance.source_url = trademark.get('source', '') instance.source_url = trademark.get('source', '')
instance.expiration_at = trademark.get('dateexp', '') expiration_at = trademark.get('dateexp', None)
instance.renewed_at = trademark.get('renewed', '') if expiration_at:
instance.expiration_at = expiration_at
renewed_at = trademark.get('renewed', None)
if renewed_at:
instance.renewed_at = renewed_at
for nice_id, nice_description in trademark.get('icgs', {}).iteritems(): for nice_id, nice_description in trademark.get('icgs', {}).iteritems():
nice_obj, created = Nice.objects.get_or_create(nice_id=nice_id) nice_obj, created = Nice.objects.get_or_create(nice_id=nice_id)

@ -0,0 +1,24 @@
angular.module('zuykov')
.controller('TrademarkSearchLandingCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.load = function () {
$scope.trademarks = [];
$scope.loading = true;
$scope.loading_text = 'Загрузка';
$http.get('/ru/trademarks/online-search/random-trademarks/').
success(function(data, status, headers, config) {
$scope.trademarks = data.items;
$scope.loading = false;
$scope.loading_text = 'Показать ещё';
}).
error(function(data, status, headers, config) {
$scope.loading = false;
$scope.loading_text = 'Показать ещё';
});
};
$scope.load();
}]);

@ -0,0 +1,32 @@
.trademark-search-landing-examples {
margin: 0 auto;
width: 75%;
.trademark-search-landing-examples-loading {
width: 100%;
text-align: center;
}
.trademark-search-landing-examples-item {
text-align: center;
width: 45%;
margin-top: 15px;
}
i {
margin-right: 5px;
}
.glyphicon-refresh-animate {
-animation: spin 1s infinite linear;
-webkit-animation: spin2 1s infinite linear;
}
@-webkit-keyframes spin2 {
from { -webkit-transform: rotate(0deg);}
to { -webkit-transform: rotate(360deg);}
}
@keyframes spin {
from { transform: scale(1) rotate(0deg);}
to { transform: scale(1) rotate(360deg);}
}
}

@ -1,3 +1,4 @@
@import 'landing.less';
@import 'result.less'; @import 'result.less';
@import 'detail.less'; @import 'detail.less';
@import 'loading.less'; @import 'loading.less';

@ -72,6 +72,14 @@
.trademark-search-result-image { .trademark-search-result-image {
height: 100px; height: 100px;
} }
.trademark-search-result-title {
line-height: 100px;
display: block;
font-size: 20px;
color: #000;
font-weight: bold;
}
} }
.trademark-search-result-contains { .trademark-search-result-contains {
@ -80,7 +88,19 @@
.trademark-search-result-image { .trademark-search-result-image {
height: 60px; height: 60px;
}
.trademark-search-result-title {
line-height: 60px;
display: block;
font-size: 18px;
color: #000;
font-weight: bold;
} }
} }
.trademark-search-result-expired { .trademark-search-result-expired {

@ -1,11 +1,42 @@
{% extends "trademark/base.html" %} {% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %}
{% block trademark_content %} {% block trademark_content %}
<h1>Онлайн-поиск товарных знаков <small>по базе свидетельств Роспатента</small> <h1>Онлайн-поиск товарных знаков <small>по базе свидетельств Роспатента</small>
</h1> </h1>
<ol class="list-unstyled list-inline breadcrumb" vocab="http://schema.org/" typeof="BreadcrumbList">
<li property="itemListElement" typeof="ListItem">
<a href="{% page_url "main" %}" property="item" typeof="WebPage"><span property="name">Главная страница</span></a>
<meta property="position" content="1">
</li>
<li property="itemListElement" typeof="ListItem">
<a href="{% page_url "trademarks" %}" property="item" typeof="WebPage"><span property="name">Товарные знаки</span></a>
<meta property="position" content="2">
</li>
<li property="itemListElement" typeof="ListItem">
<span property="name">Онлайн поиск товарных знаков</span>
<meta property="position" content="3">
</li>
</ol>
<div class="row">
<div class="col-xs-12 col-sm-7">
{% include 'trademark/form.html' %} {% include 'trademark/form.html' %}
</div>
</div>
{% verbatim %}
<div ng-controller="TrademarkSearchLandingCtrl" ng-show="trademarks">
<h3>Для вдохновения</h3>
<p>Исключительные права на эти товарные знаки не продлили, поэтому их <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрация</a> возможна после проведения <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">полного поиска</a>.</p>
<h3>Для вдохновения</h3> <ul class='list-inline trademark-search-landing-examples'>
<p>Исключительные права на эти товарные знаки не продлили, поэтому их <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрация</a> возможна после проведения <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">полного поиска</a>.</p> <li class="trademark-search-landing-examples-loading">
<button class="btn btn-primary" ng-click='load()'><i class="fa fa-refresh" area-hidden="true" ng-class="{ 'glyphicon-refresh-animate': loading }"></i><span>{{loading_text}}</span></button>
</li>
<li class="trademark-search-landing-examples-item" ng-repeat="trademark in trademarks"><h3><i class="fa {{ trademark.glyph }}" aria-hidden="true"></i></h3><span class="text-nowrap">{{trademark.product}} </span>«<a class="text-nowrap" href="/ru/trademarks/online-search/trademark/{{trademark.trademark}}/">{{trademark.name}}</a>»</li>
</ul>
</div>
{% endverbatim %}
{% endblock %} {% endblock %}

@ -5,10 +5,10 @@
<ul class="list-unstyled load-more-results" list-type="nices"> <ul class="list-unstyled load-more-results" list-type="nices">
{% for nice in nice_busy %} {% for nice in nice_busy %}
{% if products_busy|getitem:nice.nice_id|length > 1 %} {% if products_busy|getitem:nice.nice_id|length > 1 %}
<li class="trademark-search-nice-busy-product load-more-result c{{ nice.nice_id }}"><button class="btn btn-xs btn-default" popover="{% if nice.description %}{{ nice.description }}{% else %}{{ nice.title }}{% endif %}" popover-title="{{ nice.title }}" popover-trigger="mouseenter" popover-placement="right">{{ nice.nice_id }} класс</button> <button class="btn btn-xs btn-default trademark-search-show-products" product-id="{{ nice.nice_id }}">{{ products_busy|getitem:nice.nice_id|length }} категорий <span class="caret"> </span></button> {{ nice.title }}</li> <li class="trademark-search-nice-busy-product load-more-result c{{ nice.nice_id }}"><a href="{% url 'trademark:nice-detail' pk=nice.id %}" class="btn btn-xs btn-default" popover="{% if nice.description %}{{ nice.description }}{% else %}{{ nice.title }}{% endif %}" popover-title="{{ nice.title }}" popover-trigger="mouseenter" popover-placement="right">{{ nice.nice_id }} класс</a> <button class="btn btn-xs btn-default trademark-search-show-products" product-id="{{ nice.nice_id }}">{{ products_busy|getitem:nice.nice_id|length }} категорий <span class="caret"> </span></button> {{ nice.title }}</li>
<ul class="trademark-search-nice-busy-products row" style="display: none;" product-id="{{ nice.nice_id }}">{% for product in products_busy|getitem:nice.nice_id %}<li class="col-xs-6">{{ product.title }}</li>{% endfor %}</ul> <ul class="trademark-search-nice-busy-products row" style="display: none;" product-id="{{ nice.nice_id }}">{% for product in products_busy|getitem:nice.nice_id %}<li class="col-xs-6">{{ product.title }}</li>{% endfor %}</ul>
{% else %} {% else %}
<li class="trademark-search-nice-busy-product load-more-result"><button class="btn btn-xs btn-default" popover="{% if nice.description %}{{ nice.description }}{% else %}{{ nice.title }}{% endif %}" popover-title="{{ nice.title }}" popover-trigger="mouseenter" popover-placement="right">{{ nice.nice_id }} класс</button> {{ products_busy|getitem:nice.nice_id|first }}</li> <li class="trademark-search-nice-busy-product load-more-result"><a href="{% url 'trademark:nice-detail' pk=nice.id %}" class="btn btn-xs btn-default" popover="{% if nice.description %}{{ nice.description }}{% else %}{{ nice.title }}{% endif %}" popover-title="{{ nice.title }}" popover-trigger="mouseenter" popover-placement="right">{{ nice.nice_id }} класс</a> {% if products_busy|getitem:nice.nice_id|first %} {{ products_busy|getitem:nice.nice_id|first }} {% else %} {{ nice.title }}{% endif %}</li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}

@ -1,13 +1,15 @@
{% extends "trademark/base.html" %} {% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %} {% load i18n menu_tags cms_tags %}
{% block title %}Класс {{ nice.nice_id }} — {{ nice.title }} — Каталог МКТУ{% endblock %}
{% block trademark_content %} {% block trademark_content %}
<div class="nice-landing nice-detail"> <div class="nice-landing nice-detail">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
<h1 class="nice-title"><i class="fa {{ nice.glyph }}" aria-hidden="true"></i> <strong>Класс {{ nice.nice_id }}</strong> <small>{{ nice.title }}</small></h1> <h1 class="nice-title"><i class="fa {{ nice.glyph }}" aria-hidden="true"></i><strong>Класс {{ nice.nice_id }}</strong><small>{{ nice.title }}</small></h1>
<ol class="list-unstyled list-inline breadcrumb" vocab="http://schema.org/" typeof="BreadcrumbList"> <ol class="list-unstyled list-inline breadcrumb" vocab="http://schema.org/" typeof="BreadcrumbList">
<li property="itemListElement" typeof="ListItem"> <li property="itemListElement" typeof="ListItem">
@ -30,6 +32,8 @@
<p>{{ nice.description }}</p> <p>{{ nice.description }}</p>
<p>Каждый товарный знак регистрируется в отношении определённых товаров и услуг, распределенных по классам. Всего таких классов на сегодняшний день 45 (34 — товаров и 11 — услуг), они установлены Международной классификацией товаров и услуг для регистрации знаков (МКТУ).</p>
</div> </div>
<div class="col-xs-12 col-sm-4 no-print"> <div class="col-xs-12 col-sm-4 no-print">
<div class="trademark-search-block"> <div class="trademark-search-block">

@ -1,6 +1,9 @@
{% extends "trademark/base.html" %} {% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags cache %} {% load i18n menu_tags cms_tags cache %}
{% block title %}Каталог МКТУ — Международной классификацией товаров и услуг{% endblock %}
{% block trademark_content %} {% block trademark_content %}
<div class="nice-landing"> <div class="nice-landing">

@ -1,5 +1,6 @@
{% extends "trademark/base.html" %} {% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %} {% load i18n menu_tags cms_tags %}
{% block title %}{{ product.title }} — Класс {{ nice.nice_id }} — Каталог МКТУ{% endblock %}
{% block trademark_content %} {% block trademark_content %}
<div class="nice-landing"> <div class="nice-landing">
@ -27,6 +28,7 @@
<meta property="position" content="5"> <meta property="position" content="5">
</li> </li>
</ol> </ol>
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
@ -49,15 +51,14 @@
</div> </div>
<div class="app-trademark"> <div class="app-trademark">
{% if trademarks_expired %} {% if trademarks_acting %}
<ul class="trademark-search-results load-more-results list-inline list-unstyled"> <ul class="trademark-search-results load-more-results list-inline list-unstyled">
<li class="trademark-search-results-detail"> <li class="trademark-search-results-detail">
<h3>Товарные знаки в {{ nice.nice_id }} классе, для которых возможна регистрация</h3> <h3>Товарные знаки в {{ nice.nice_id }} классе <small>{{ nice.title }}</small></h3>
<p>Товарные знаки, зарегистрированные в классе про <a href="{% url 'trademark:nice-detail' pk=nice.id %}">{{ nice.title|lower }}</a> в категории {% if nice.nice_id > 38 %}услуг{% else %}товаров{% endif %} {{ product.title|lower }}.</p>
<h5 class="trademark-search-results-detail-count"></h5> <h5 class="trademark-search-results-detail-count"></h5>
<p>Исключительные права на эти товарные знаки не продлили, поэтому их <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрация</a> возможна после проведения <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">полного поиска</a>.</p>
<p>Эти товарные знаки были зарегистрированы в классе про <a href="{% url 'trademark:nice-detail' pk=nice.id %}">{{ nice.title|lower }}</a> в категории {% if nice.nice_id > 38 %}услуг{% else %}товаров{% endif %} {{ product.title|lower }}.</p>
</li> </li>
{% for tm in trademarks_expired %} {% for tm in trademarks_acting %}
{% include 'trademark/search_list_item.html' with tm=tm %} {% include 'trademark/search_list_item.html' with tm=tm %}
{% endfor %} {% endfor %}
<li class="load-more-li"> <li class="load-more-li">
@ -66,14 +67,15 @@
</ul> </ul>
{% endif %} {% endif %}
{% if trademarks_acting %} {% if trademarks_expired %}
<ul class="trademark-search-results load-more-results list-inline list-unstyled"> <ul class="trademark-search-results load-more-results list-inline list-unstyled">
<li class="trademark-search-results-detail"> <li class="trademark-search-results-detail">
<h3>Товарные знаки в {{ nice.nice_id }} классе <small>{{ nice.title }}</small></h3> <h3>Товарные знаки в {{ nice.nice_id }} классе с истёкшим сроком действия</h3>
<p>Товарные знаки, зарегистрированные в классе про <a href="{% url 'trademark:nice-detail' pk=nice.id %}">{{ nice.title|lower }}</a> в категории {% if nice.nice_id > 38 %}услуг{% else %}товаров{% endif %} {{ product.title|lower }}.</p>
<h5 class="trademark-search-results-detail-count"></h5> <h5 class="trademark-search-results-detail-count"></h5>
<p>Исключительные права на эти товарные знаки не продлили, поэтому их <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрация</a> возможна после проведения <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">полного поиска</a>.</p>
<p>Эти товарные знаки были зарегистрированы в классе про <a href="{% url 'trademark:nice-detail' pk=nice.id %}">{{ nice.title|lower }}</a> в категории {% if nice.nice_id > 38 %}услуг{% else %}товаров{% endif %} {{ product.title|lower }}.</p>
</li> </li>
{% for tm in trademarks_acting %} {% for tm in trademarks_expired %}
{% include 'trademark/search_list_item.html' with tm=tm %} {% include 'trademark/search_list_item.html' with tm=tm %}
{% endfor %} {% endfor %}
<li class="load-more-li"> <li class="load-more-li">
@ -81,7 +83,9 @@
</li> </li>
</ul> </ul>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">

@ -32,11 +32,13 @@
{% for tm in identity %} {% for tm in identity %}
<li class="trademark-search-result-identity load-more-result trademark-search-result {% for class in tm.nices.all %}c{{ class.nice_id }} {% endfor %}" trademark-id='{{ tm.id }}'> <li class="trademark-search-result-identity load-more-result trademark-search-result {% for class in tm.nices.all %}c{{ class.nice_id }} {% endfor %}" trademark-id='{{ tm.id }}'>
<a href='/ru/trademarks/online-search/trademark/{{ tm.id }}/'> <a href='/ru/trademarks/online-search/trademark/{{ tm.id }}/'>
<div class='trademark-search-result-image' style="background-image: url({{ tm.image_url }});">
{% if not tm.image_url %} {% if not tm.image_url %}
<h4>{{ tm.title|title }}</h4> <span class='trademark-search-result-title'>{{ tm.title|title }}</span>
{% else %}
<div class='trademark-search-result-image' style="background-image: url({{ tm.image_url }});"></div>
{% endif %} {% endif %}
</div>
<p>{{ tm.title|title }}</p> <p>{{ tm.title|title }}</p>
{% if tm.nices.count != 44 %} {% if tm.nices.count != 44 %}
@ -48,7 +50,7 @@
</span> </span>
{% else %} {% else %}
<span>{% for class in tm.nices.all %} <span>{% for class in tm.nices.all %}
<button class="btn btn-xs btn-default trademark-search-nice-button" ng-show="true" popover="{{class.description}}" popover-title="{{class.title}}" popover-trigger="mouseenter" popover-placement="right" class="btn btn-xs btn-default">{{ class.nice_id }}</button></span> <a href="{% url 'trademark:nice-detail' pk=class.id %}" class="btn btn-xs btn-default trademark-search-nice-button" ng-show="true" popover="{{class.description}}" popover-title="{{class.title}}" popover-trigger="mouseenter" popover-placement="right" class="btn btn-xs btn-default">{{ class.nice_id }}</a></span>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
@ -84,7 +86,7 @@
{% endif %} {% endif %}
{% else %} {% else %}
<h2>Товарный знак «{{ keyword.request|title }}» не зарегистрирован в базе свидетельств Роспатента {% if keyword.nice_objects|length > 0 %}в выбранных классах{% endif %}</h2> <h2>Товарный знак «{{ keyword.request|title }}» не зарегистрирован в международной базе Ромарин и базе свидетельств Роспатента {% if keyword.nice_objects|length > 0 %}в выбранных классах{% endif %}</h2>
<p> <p>
Существует ряд законодательных требований, которым должен соответствовать знак, не выполнение которых может привести к отказу в регистрации вашего знака.</p> Существует ряд законодательных требований, которым должен соответствовать знак, не выполнение которых может привести к отказу в регистрации вашего знака.</p>
<p> <p>

@ -1,10 +1,12 @@
<li class='trademark-search-result-contains load-more-result trademark-search-result {% for class in tm.nices.all %}c{{ class.nice_id }} {% endfor %} {% if tm.status == "Expired" %}trademark-search-result-expired{% endif %}'> <li class='trademark-search-result-contains load-more-result trademark-search-result {% for class in tm.nices.all %}c{{ class.nice_id }} {% endfor %} {% if tm.status == "Expired" %}trademark-search-result-expired{% endif %}'>
<a href='/ru/trademarks/online-search/trademark/{{ tm.id }}/'> <a href='/ru/trademarks/online-search/trademark/{{ tm.id }}/'>
<div class='trademark-search-result-image' style="background-image: url({{ tm.image_url }});">
{% if not tm.image_url %} {% if not tm.image_url %}
<h4>{{ tm.title|title }}</h4> <span class="trademark-search-result-title">{{ tm.title|title }}</span>
{% endif %} {% else %}
<div class='trademark-search-result-image' style="background-image: url({{ tm.image_url }});">
</div> </div>
{% endif %}
<p>{{ tm.title|title }}</p> <p>{{ tm.title|title }}</p>
</a> </a>
</li> </li>

@ -9,15 +9,19 @@
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
<h1>Товарный знак «{{ tm.title }}»</h1> <h1>Товарный знак «{{ tm.title }}» № {{ tm.cert_id }}</h1>
<ul class="list-unstyled row"> <ul class="list-unstyled row">
{% if tm.application_at or tm.application_id %}
<li class='col-xs-4'> <li class='col-xs-4'>
<h2>Подана заявка <nobr>{{ tm.application_at }}</nobr></h2> {% if tm.application_at %}<h2>Подана заявка <nobr>{{ tm.application_at }}</nobr></h2>{% endif %}
<p>Номер <nobr>№ {{ tm.application_id }}</nobr></p> {% if tm.application_id %}<p>Номер <nobr>№ {{ tm.application_id }}</nobr></p>{% endif %}
</li> </li>
<li class='col-xs-2 trademark-detail-arrow'> <li class='col-xs-2 trademark-detail-arrow'>
</li> </li>
{% endif %}
<li class='col-xs-6'> <li class='col-xs-6'>
{% if tm.expiration_at %} {% if tm.expiration_at %}
{% if tm.status == 'Acting' %} {% if tm.status == 'Acting' %}
@ -36,7 +40,7 @@
<p><strong>Действует</strong></p> <p><strong>Действует</strong></p>
{% endif %} {% endif %}
{% else %} {% else %}
<p><strong>Не действует. Доступен для <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрации</a></strong>.</p> <p><strong>Не действует. <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">Проверьте</a>, возможно, доступен для <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрации</a></strong>.</p>
{% endif %} {% endif %}
</li> </li>
@ -44,8 +48,10 @@
<div class="trademark-detail-description row"> <div class="trademark-detail-description row">
<div class="col-xs-6 trademark-detail-description-visual"> <div class="col-xs-6 trademark-detail-description-visual">
{% if tm.image_url %}
<h4>Изображение знака:</h3> <h4>Изображение знака:</h3>
<img src="{{ tm.image_url }}"/> <img src="{{ tm.image_url }}"/>
{% endif %}
</div> </div>
<div class="col-xs-6 trademark-detail-text"> <div class="col-xs-6 trademark-detail-text">
<h4>Правообладатель:</h3> <h4>Правообладатель:</h3>
@ -55,9 +61,10 @@
{% include 'trademark/nice_block_busy.html' with keyword=tm.title nice_busy=tm.nices.all products_busy=products_busy %} {% include 'trademark/nice_block_busy.html' with keyword=tm.title nice_busy=tm.nices.all products_busy=products_busy %}
{% if tm.source_url %}
<h4>Источник: Федеральная Cлужба по Интеллектуальной Собственности</h4> <h4>Источник: Федеральная Cлужба по Интеллектуальной Собственности</h4>
<small><a href="{{ tm.source_url }}" target="blank">{{ tm.source_url }}</a></small> <small><a href="{{ tm.source_url }}" target="blank">{{ tm.source_url }}</a></small>
{% endif %}
</div> </div>

@ -10,6 +10,7 @@ urlpatterns = patterns('',
url(r'^nices/(?P<pk>[\w-]+)/$', views.NiceDetailView.as_view(), name='nice-detail'), url(r'^nices/(?P<pk>[\w-]+)/$', views.NiceDetailView.as_view(), name='nice-detail'),
url(r'^products/(?P<pk>[\w-]+)/$', views.ProductDetailView.as_view(), name='product-detail'), url(r'^products/(?P<pk>[\w-]+)/$', views.ProductDetailView.as_view(), name='product-detail'),
url(r'^results/(?P<slug>[\w-]+)/$', views.SearchDetailView.as_view(), name='search-detail'), url(r'^results/(?P<slug>[\w-]+)/$', views.SearchDetailView.as_view(), name='search-detail'),
url(r'^random-trademarks/', views.get_random_list_trademarks, name='random-trademarks'),
url(r'^trademark/(?P<pk>[\w-]+)/$', views.TrademarkDetailView.as_view(), name='trademark-detail'), url(r'^trademark/(?P<pk>[\w-]+)/$', views.TrademarkDetailView.as_view(), name='trademark-detail'),
url(r'^request/(?P<slug>[\w-]+)/$', views.Search.as_view(), name='search-detail'), url(r'^request/(?P<slug>[\w-]+)/$', views.Search.as_view(), name='search-detail'),
url(r'^request/$', views.Search.as_view(), name='search'), url(r'^request/$', views.Search.as_view(), name='search'),

@ -10,7 +10,9 @@ import json
from .models import * from .models import *
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.db.models import Count
import pymorphy2
class SearchDetailView(generic.DetailView): class SearchDetailView(generic.DetailView):
@ -119,8 +121,8 @@ class ProductDetailView(generic.DetailView):
context['product'] = product context['product'] = product
context['nice'] = Nice.objects.get(nice_id=product.nice_id) context['nice'] = Nice.objects.get(nice_id=product.nice_id)
context['trademarks_expired'] = product.trademark_set.filter(status='Expired').order_by('?')[:42] context['trademarks_expired'] = product.trademark_set.annotate(num_nices=Count('nices')).filter(status='Expired', num_nices__lt=4).order_by('?')[:42]
context['trademarks_acting'] = product.trademark_set.filter(status='Acting').order_by('?')[:42] context['trademarks_acting'] = product.trademark_set.annotate(num_nices=Count('nices')).filter(status='Acting', num_nices__lt=4).order_by('?')[:42]
return context return context
@ -218,3 +220,57 @@ class Search(generic.View):
return HttpResponse(json.dumps(response), content_type="application/json") return HttpResponse(json.dumps(response), content_type="application/json")
@never_cache
def get_random_list_trademarks(request, status='Expired', count=10):
morph = pymorphy2.MorphAnalyzer()
trademark_list = []
expired_trademarks = Trademark.objects.filter(status=status).order_by('?')[:count*2]
for trademark in expired_trademarks:
if len(trademark.title.split(' ')) > 3:
continue
nice_id = None
normalize_title = None
for product in trademark.products.all():
words = product.title.split(' ')
normalize_title = None
if len(words) <= 3:
first_word = morph.parse(words[0])[0]
if first_word.tag.POS == 'NOUN':
normalize_title = product.title
if len(words) == 1:
try:
normalize_title = word.inflect({'sing', 'nomn'}).word
except:
continue
nice_id = product.nice_id
break
if not normalize_title:
continue
try:
glyph = Nice.objects.get(nice_id=nice_id).glyph or 'fa-snowflake-o'
except Nice.DoesNotExist:
# Быть такого не должно
glyph = 'fa-snowflake-o'
trademark_list.append({
'product': normalize_title.capitalize(),
'name': trademark.title.title(),
'trademark': trademark.id,
'glyph': glyph
})
response = {
'count': len(trademark_list),
'status': 'ok',
'items': trademark_list[:count]
}
return HttpResponse(json.dumps(response), content_type="application/json")

@ -105,3 +105,14 @@ article.post-item {
} }
/* block tags template blog/post_list.html line 21 */
.blog-tags {
padding-left: 0;
}
.blog-tag {
display: inline-block;
margin: 2px 0;
}

@ -80,14 +80,13 @@
.nice-title { .nice-title {
i { i {
width: 25px;
vertical-align: middle; vertical-align: middle;
text-align: right; text-align: right;
padding-right: 10px; padding-right: 10px;
} }
a { a, strong {
margin-right: 10px; margin-right: 10px;
margin-left: 5px; margin-left: 5px;
} }

@ -1,4 +1,4 @@
{% load menu_tags aldryn_people_tags cms_tags i18n thumbnail %} {% load menu_tags aldryn_people_tags cms_tags i18n thumbnail query %}
{% show_breadcrumb 2 %} {% show_breadcrumb 2 %}
@ -28,8 +28,9 @@
{% spaceless %} {% spaceless %}
<h2>Статьи</h2> <h2>Статьи</h2>
<ul class="articles list-unstyled"> <ul class="articles list-unstyled">
{% for article in person.blog_post_author.all %} {% query person.blog_post_author categories__id=4 as articles %}
{{ article }}
{% for article in articles %}
<li><a href="{{ article.get_absolute_url }}">{{ article.title }}</a> <li><a href="{{ article.get_absolute_url }}">{{ article.title }}</a>
&nbsp;<small class="date">{{ article.date_published|date:"DATE_FORMAT" }}</small></li> &nbsp;<small class="date">{{ article.date_published|date:"DATE_FORMAT" }}</small></li>
{% endfor %} {% endfor %}

@ -0,0 +1,12 @@
from django import template
register = template.Library()
@register.assignment_tag
def query(qs, **kwargs):
""" template tag which allows queryset filtering. Usage:
{% query books author=author as mybooks %}
{% for book in mybooks %}
...
{% endfor %}
"""
return qs.filter(**kwargs)
Loading…
Cancel
Save