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. 206
      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. 113
      packages/cmsplugin_tabs/migrations/0001_initial.py
  22. 78
      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. 69
      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. 21
      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
frontend/static/
zsite/static/vendor/
_env/
media/
app/local.py
/static/vendor/
/static/

@ -12,11 +12,27 @@ $ source _env/bin/activate
```
Часть внешник пакетов лежит в папке 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
```

@ -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!
# Prod
DEBUG = False
DEBUG = True
TEMPLATE_DEBUG = False
ALLOWED_HOSTS = [
'.zuykov.com', # Allow domain and subdomains
@ -101,7 +101,7 @@ STATICFILES_FINDERS = (
)
PIPELINE = {
'PIPELINE_ENABLED': True,
'PIPELINE_ENABLED': False,
'JAVASCRIPT': {
'main': {
'source_filenames': (
@ -167,7 +167,7 @@ MIDDLEWARE_CLASSES = (
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', # WARNING: В продакшене должно быть включено
# 'django.middleware.cache.FetchFromCacheMiddleware', # WARNING: В продакшене должно быть включено
'country_segment.middleware.ResolveCountryCodeMiddleware',
'promo.middleware.cookies.PageHistoryMiddleware',
'django.middleware.gzip.GZipMiddleware',

@ -2,12 +2,13 @@
from __future__ import unicode_literals
from django.db import models, migrations
import filer
class Migration(migrations.Migration):
dependencies = [
('aldryn_people', '0003_auto_20150425_2103'),
('filer', '0002_auto_20150606_2003'),
]
operations = [
@ -31,4 +32,46 @@ class Migration(migrations.Migration):
field=models.CharField(max_length=15, verbose_name='Language', db_index=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)
vcard_enabled = models.BooleanField(
verbose_name=_('enable vCard download'), default=True)
user = models.ForeignKey(
user = models.OneToOneField(
getattr(settings, 'AUTH_USER_MODEL', 'auth.User'),
null=True, blank=True, unique=True)
null=True, blank=True)
class Meta:
verbose_name = _('Person')
@ -218,7 +218,7 @@ class BasePeoplePlugin(CMSPlugin):
_('Style'), choices=STYLE_CHOICES,
default=STYLE_CHOICES[0][0], max_length=50)
people = aldryn_common.admin_fields.sortedm2m.SortedM2MModelField(
Person, blank=True, null=True)
Person, blank=True)
group_by_group = models.BooleanField(
verbose_name=_('group by group'),
default=True,

@ -1,125 +1,83 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# 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'
db.create_table(u'aldryn_segmentation_fallbacksegmentpluginmodel', (
(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'
db.create_table(u'aldryn_segmentation_switchsegmentpluginmodel', (
(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)),
('on_off', self.gf('django.db.models.fields.BooleanField')(default=True)),
))
db.send_create_signal(u'aldryn_segmentation', ['SwitchSegmentPluginModel'])
# 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': {
'Meta': {'object_name': 'FallbackSegmentPluginModel'},
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.segment': {
'Meta': {'object_name': 'Segment', 'managed': 'False'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'aldryn_segmentation.segmentlimitpluginmodel': {
'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'}),
'label': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '128', 'blank': 'True'}),
'max_children': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'})
},
u'aldryn_segmentation.switchsegmentpluginmodel': {
'Meta': {'object_name': 'SwitchSegmentPluginModel'},
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'}),
'on_off': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'cms.cmsplugin': {
'Meta': {'object_name': 'CMSPlugin'},
'changed_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
u'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'}),
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']
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('cms', '0012_auto_20150607_2207'),
]
operations = [
migrations.CreateModel(
name='Segment',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
],
options={
'managed': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
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,
},
bases=('cms.cmsplugin',),
),
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,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='FallbackSegmentPluginModel',
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,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SegmentLimitPluginModel',
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,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SwitchSegmentPluginModel',
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)),
('on_off', models.BooleanField(default=True, help_text='Uncheck to always hide child plugins.', verbose_name='Always on?')),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
]

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

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

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

@ -19,7 +19,7 @@ class Migration(migrations.Migration):
('cms', '0003_auto_20140926_2347'),
('taggit', '__first__'),
('filer', '0001_initial'),
('cmsplugin_filer_image', '0001_initial'),
# ('cmsplugin_filer_image', '0001_initial'),
]
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')
)
sites = models.ManyToManyField(Site, verbose_name=_(u'Site(s)'), blank=True,
null=True,
help_text=_(u'Select sites in which to show the post. '
u'If none is set it will be '
u'visible in all the configured sites.')
@ -266,13 +265,19 @@ class LatestPostsPlugin(BasePostPlugin):
categories = models.ManyToManyField('BlogCategory', blank=True,
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):
return u'%s latest articles by category' % self.latest_posts
def get_posts(self, request):
posts = self.post_queryset(request)
if self.tags.exists():
posts = posts.filter(tags__in=list(self.tags.all()))
if self.categories.exists():
posts = posts.filter(categories__in=list(self.categories.all()))

@ -13,11 +13,11 @@
</ul>
{% endblock breadcrumb %}
{% block content_blog %}{% spaceless %}
{% block content_blog %}
<article id="post-{{ post.slug }}" class="post-item post-detail">
<content>
<header>
<h1>{% render_model post "title" %}</h1>
<h1>{{ post.title }}</h1>
<p class="date">{{ post.date_published|date:"DATE_FORMAT" }}</p>
</header>
{% 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 }}" />
</div>
{% endif %}
{% endspaceless %}
<div class="blog-content">{% render_model post "abstract" %}</div>
<div class="blog-content">{{ post.abstract|safe }}</div>
</content>
<side>
<author>

@ -11,12 +11,20 @@
<h2>
{% if author %}{% trans "Articles by" %} {{ author.get_full_name }}
{% 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 %}
{{ category }}
</h2>
</header>
{% 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="blog-list-older">
{% for post in post_list %}

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

@ -1,71 +1,44 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# 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'
db.create_table('cmsplugin_tabs_singletab', (
('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'])
def backwards(self, orm):
# Deleting model 'CMSTabsList'
db.delete_table('cmsplugin_cmstabslist')
# Deleting model 'SingleTab'
db.delete_table('cmsplugin_tabs_singletab')
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': {
'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'})
},
'cmsplugin_tabs.singletab': {
'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']
from __future__ import unicode_literals
from django.db import models, migrations
import tinymce.models
class Migration(migrations.Migration):
dependencies = [
('cms', '0003_auto_20140926_2347'),
]
operations = [
migrations.CreateModel(
name='CMSTabsList',
fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('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')])),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
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',
},
bases=(models.Model,),
),
]

File diff suppressed because one or more lines are too long

@ -93,13 +93,4 @@ var form = {
</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 parler.models
import djangocms_text_ckeditor.fields
import cms
class Migration(migrations.Migration):
operations = [
@ -43,4 +43,18 @@ class Migration(migrations.Migration):
name='promotranslation',
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-boilerplates==0.7.3
aldryn-bootstrap3==0.5.2
aldryn-common==0.1.4
aldryn-boilerplates==0.7.4
aldryn-bootstrap3==1.1.2 # Up: 1.04.2017
aldryn-common==1.0.4 # Up: 1.04.2017
aldryn-translation-tools==0.2.1
cmsplugin-filer==0.10.2
cmsplugin-filer==1.0.1
dj-database-url==0.3.0
Django==1.7.8
Django==1.7.11
django-admin-enhancer==1.0.0
django-admin-extend==0.0.3
django-appconf==1.0.1
django-appdata==0.1.4
django-appconf==1.0.2
django-appdata==0.1.5
django-classy-tags==0.6.2
django-cms==3.1.3
django-debug-toolbar==1.4
django-cms==3.2.5
django-durationfield==0.5.2
django-easy-select2==1.3.3
django-filer==0.9.12
django-filer==1.1.1
django-formtools==1.0
django-ipware==1.1.1
django-meta==0.3.1
django-meta-mixin==0.2.1
django-meta==1.3.2
django-meta-mixin==0.3.0
django-mptt==0.7.4
django-multipleformwizard==0.2.16
django-parler==1.5.1
@ -27,7 +26,7 @@ django-phonenumber-field==0.7.2
django-pipeline==1.6.12
django-polymorphic==0.7.2
django-reversion==1.9.3
django-sekizai==0.8.2
django-sekizai==0.10.0
Django-Select2==4.3.2
django-sortedm2m==1.0.2
django-taggit==0.17.3
@ -39,13 +38,13 @@ djangocms-column==1.5
djangocms-file==0.1
djangocms-flash==0.2.0
djangocms-googlemap==0.3
djangocms-inherit==0.1
djangocms-inherit==0.1.1
djangocms-installer==0.8.1
djangocms-link==1.7.1
djangocms-picture==0.1
djangocms-style==1.5
djangocms-teaser==0.1
djangocms-text-ckeditor==2.6.0
djangocms-text-ckeditor==2.8.1
djangocms-video==0.1
easy-thumbnails==2.2
futures==3.0.3
@ -64,14 +63,12 @@ pytz==2015.7
pyuca==1.1
requests==2.8.1
six==1.10.0
South==1.0.2
sqlparse==0.1.18
tablib==0.10.0
tzlocal==1.2
Unidecode==0.4.18
vobject==0.6.6
YURL==0.13
#
pymorphy2==0.8
pymorphy2-dicts==2.4.393442.3710985
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 -*-
import urllib2
@ -75,12 +74,20 @@ class TrademarkSearchAPI():
'module': 'search',
'procedure': 'get_result',
'search_id': search_id,
'databases': [21]
'databases': [21, 23]
}
data = self.send_request(request)
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:
return None, status
@ -94,7 +101,12 @@ class TrademarkSearchAPI():
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'),
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 timedelta
from dateutil.parser import parse
# from .cms_appconfig import TrademarkConfig
from collections import defaultdict
import re
TrademarkAPI = TrademarkSearchAPI()
class Owner(models.Model):
@ -70,7 +72,7 @@ class Nice(models.Model):
alphabet = defaultdict(lambda : defaultdict(list))
for product in self.popular_products:
letter = product.title[0].upper()
first_word = product.title.split(' ')[0]
first_word = product.title.split(' ')[0].replace(',', '')
# if title_sense:
alphabet[letter][first_word.capitalize()].append(product)
@ -82,23 +84,23 @@ class Nice(models.Model):
if len(products) == 1:
del alphabet[letter][first_word]
product = products.pop()
words = product.title
words = product.title.strip()
alphabet[letter][words] = product.id
else:
words = []
for product in alphabet[letter][first_word]:
title = re.sub("[\(\[].*?[\)\]]", "", product.title)
title_sense = title.replace(first_word, '').strip()
title_sense = title.replace(first_word, '')
if title_sense:
if title_sense[0] == ',':
title_sense = title_sense[1:].strip()
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]
alphabet[letter] = sorted(letter_items.items(), key=lambda x: type(x[1]))
# alphabet[letter] = letter_items.items()
print alphabet
return sorted(alphabet.items())
@ -121,9 +123,9 @@ class Product(models.Model):
class Trademark(models.Model):
title = models.CharField(max_length=255, null=True)
ext_id = models.CharField(max_length=20, unique=True)
application_id = models.CharField(max_length=12, null=True)
cert_id = models.CharField(max_length=12, null=True)
ext_id = models.CharField(max_length=50, unique=True)
application_id = models.CharField(max_length=50, null=True)
cert_id = models.CharField(max_length=50, null=True)
owner = models.TextField(null=True)
image_url = models.URLField(null=True)
nices = models.ManyToManyField(Nice)
@ -306,19 +308,40 @@ class Search(models.Model):
if not created:
continue
instance.title = trademark['wdesc']
instance.application_id = trademark['appnum']
instance.cert_id = trademark['certnum']
instance.owner = trademark['owner'][0]['name'].encode('utf-8')
instance.title = trademark.get('wdesc', '')
instance.application_id = trademark.get('appnum', '')
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.status = trademark['status']
instance.status = trademark.get('status', '')
instance.application_at = trademark['dateapp']
instance.registration_at = trademark['datereg']
application_at = trademark.get('dateapp', None)
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.get('access_key', '')
try:
instance.save()
except:
print "Error"
print trademark
instance.access_key = trademark['access_key']
instance.save()
for nice_id in trademark.get('icgs', []):
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():
instance = Trademark.objects.get(ext_id=trademark['id'])
instance.source_url = trademark.get('source', '')
instance.expiration_at = trademark.get('dateexp', '')
instance.renewed_at = trademark.get('renewed', '')
expiration_at = trademark.get('dateexp', None)
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():
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 'detail.less';
@import 'loading.less';

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

@ -1,11 +1,42 @@
{% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %}
{% block trademark_content %}
<h1>Онлайн-поиск товарных знаков <small>по базе свидетельств Роспатента</small>
</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' %}
</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>
<p>Исключительные права на эти товарные знаки не продлили, поэтому их <a href="http://zuykov.com/ru/trademarks/registraciya-tovarnogo-znaka/">регистрация</a> возможна после проведения <a href="http://zuykov.com/ru/trademarks/poisk-tovarnogo-znaka/">полного поиска</a>.</p>
<ul class='list-inline trademark-search-landing-examples'>
<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 %}

@ -5,10 +5,10 @@
<ul class="list-unstyled load-more-results" list-type="nices">
{% for nice in nice_busy %}
{% 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>
{% 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 %}
{% endfor %}

@ -1,13 +1,15 @@
{% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %}
{% block title %}Класс {{ nice.nice_id }} — {{ nice.title }} — Каталог МКТУ{% endblock %}
{% block trademark_content %}
<div class="nice-landing nice-detail">
<div class="row">
<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">
<li property="itemListElement" typeof="ListItem">
@ -30,6 +32,8 @@
<p>{{ nice.description }}</p>
<p>Каждый товарный знак регистрируется в отношении определённых товаров и услуг, распределенных по классам. Всего таких классов на сегодняшний день 45 (34 — товаров и 11 — услуг), они установлены Международной классификацией товаров и услуг для регистрации знаков (МКТУ).</p>
</div>
<div class="col-xs-12 col-sm-4 no-print">
<div class="trademark-search-block">

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

@ -1,5 +1,6 @@
{% extends "trademark/base.html" %}
{% load i18n menu_tags cms_tags %}
{% block title %}{{ product.title }} — Класс {{ nice.nice_id }} — Каталог МКТУ{% endblock %}
{% block trademark_content %}
<div class="nice-landing">
@ -27,6 +28,7 @@
<meta property="position" content="5">
</li>
</ol>
<div class="row">
<div class="col-xs-12 col-sm-8">
@ -49,15 +51,14 @@
</div>
<div class="app-trademark">
{% if trademarks_expired %}
{% if trademarks_acting %}
<ul class="trademark-search-results load-more-results list-inline list-unstyled">
<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>
<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>
{% for tm in trademarks_expired %}
{% for tm in trademarks_acting %}
{% include 'trademark/search_list_item.html' with tm=tm %}
{% endfor %}
<li class="load-more-li">
@ -66,14 +67,15 @@
</ul>
{% endif %}
{% if trademarks_acting %}
{% if trademarks_expired %}
<ul class="trademark-search-results load-more-results list-inline list-unstyled">
<li class="trademark-search-results-detail">
<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>
<h3>Товарные знаки в {{ nice.nice_id }} классе с истёкшим сроком действия</h3>
<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>
{% for tm in trademarks_acting %}
{% for tm in trademarks_expired %}
{% include 'trademark/search_list_item.html' with tm=tm %}
{% endfor %}
<li class="load-more-li">
@ -81,7 +83,9 @@
</li>
</ul>
{% endif %}
</div>
</div>
<script type="text/javascript">

@ -32,11 +32,13 @@
{% 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 }}'>
<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 %}
<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 %}
</div>
<p>{{ tm.title|title }}</p>
{% if tm.nices.count != 44 %}
@ -48,7 +50,7 @@
</span>
{% else %}
<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 %}
{% endif %}
@ -84,7 +86,7 @@
{% endif %}
{% 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>

@ -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 %}'>
<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 %}
<h4>{{ tm.title|title }}</h4>
{% endif %}
<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 %}
<p>{{ tm.title|title }}</p>
</a>
</li>

@ -9,15 +9,19 @@
<div class="row">
<div class="col-xs-12 col-sm-8">
<h1>Товарный знак «{{ tm.title }}»</h1>
<h1>Товарный знак «{{ tm.title }}» № {{ tm.cert_id }}</h1>
<ul class="list-unstyled row">
{% if tm.application_at or tm.application_id %}
<li class='col-xs-4'>
<h2>Подана заявка <nobr>{{ tm.application_at }}</nobr></h2>
<p>Номер <nobr>№ {{ tm.application_id }}</nobr></p>
{% if tm.application_at %}<h2>Подана заявка <nobr>{{ tm.application_at }}</nobr></h2>{% endif %}
{% if tm.application_id %}<p>Номер <nobr>№ {{ tm.application_id }}</nobr></p>{% endif %}
</li>
<li class='col-xs-2 trademark-detail-arrow'>
</li>
{% endif %}
<li class='col-xs-6'>
{% if tm.expiration_at %}
{% if tm.status == 'Acting' %}
@ -36,7 +40,7 @@
<p><strong>Действует</strong></p>
{% endif %}
{% 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 %}
</li>
@ -44,8 +48,10 @@
<div class="trademark-detail-description row">
<div class="col-xs-6 trademark-detail-description-visual">
<h4>Изображение знака:</h3>
<img src="{{ tm.image_url }}"/>
{% if tm.image_url %}
<h4>Изображение знака:</h3>
<img src="{{ tm.image_url }}"/>
{% endif %}
</div>
<div class="col-xs-6 trademark-detail-text">
<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 %}
{% if tm.source_url %}
<h4>Источник: Федеральная Cлужба по Интеллектуальной Собственности</h4>
<small><a href="{{ tm.source_url }}" target="blank">{{ tm.source_url }}</a></small>
{% endif %}
</div>

@ -10,6 +10,7 @@ urlpatterns = patterns('',
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'^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'^request/(?P<slug>[\w-]+)/$', views.Search.as_view(), name='search-detail'),
url(r'^request/$', views.Search.as_view(), name='search'),

@ -10,7 +10,9 @@ import json
from .models import *
from django.views.decorators.cache import never_cache
from django.db.models import Count
import pymorphy2
class SearchDetailView(generic.DetailView):
@ -119,8 +121,8 @@ class ProductDetailView(generic.DetailView):
context['product'] = product
context['nice'] = Nice.objects.get(nice_id=product.nice_id)
context['trademarks_expired'] = product.trademark_set.filter(status='Expired').order_by('?')[:42]
context['trademarks_acting'] = product.trademark_set.filter(status='Acting').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.annotate(num_nices=Count('nices')).filter(status='Acting', num_nices__lt=4).order_by('?')[:42]
return context
@ -218,3 +220,57 @@ class Search(generic.View):
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 {
i {
width: 25px;
vertical-align: middle;
text-align: right;
padding-right: 10px;
}
a {
a, strong {
margin-right: 10px;
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 %}
@ -28,8 +28,9 @@
{% spaceless %}
<h2>Статьи</h2>
<ul class="articles list-unstyled">
{% for article in person.blog_post_author.all %}
{{ article }}
{% query person.blog_post_author categories__id=4 as articles %}
{% for article in articles %}
<li><a href="{{ article.get_absolute_url }}">{{ article.title }}</a>
&nbsp;<small class="date">{{ article.date_published|date:"DATE_FORMAT" }}</small></li>
{% 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