From 838530bb882b70d2adcb75111bb7122d8e602b02 Mon Sep 17 00:00:00 2001 From: fefa4ka Date: Tue, 8 Nov 2016 04:29:21 +0300 Subject: [PATCH] trademark update --- app/settings.py | 3 +- trademark/lib/poiskznakov.py | 9 +- trademark/models.py | 86 +++++++--- trademark/templates/trademark/form.html | 139 ---------------- .../templates/trademark/nice_block_busy.html | 14 +- .../templates/trademark/registration.html | 2 +- .../templates/trademark/search_detail.html | 26 +-- .../templates/trademark/search_list_item.html | 8 + .../templates/trademark/trademark_detail.html | 55 ++++++ trademark/urls.py | 1 + trademark/views.py | 39 ++++- zsite/static/js/trademarks.js | 157 ++++++++++++++++++ zsite/static/less/search.less | 49 ++++++ 13 files changed, 395 insertions(+), 193 deletions(-) create mode 100644 trademark/templates/trademark/search_list_item.html create mode 100644 trademark/templates/trademark/trademark_detail.html create mode 100644 zsite/static/js/trademarks.js diff --git a/app/settings.py b/app/settings.py index 13f1124..7f37405 100644 --- a/app/settings.py +++ b/app/settings.py @@ -112,7 +112,8 @@ PIPELINE_JS = { 'js/app.js', 'js/forms.js', 'js/snippets.js', - 'js/nice.js' + 'js/nice.js', + 'js/trademarks.js', ), 'output_filename': 'js/zuykov.js', }, diff --git a/trademark/lib/poiskznakov.py b/trademark/lib/poiskznakov.py index 53dfcb8..4e97167 100644 --- a/trademark/lib/poiskznakov.py +++ b/trademark/lib/poiskznakov.py @@ -86,13 +86,8 @@ class TrademarkSearchAPI(): 'marks': ids, 'access_keys': keys } - - try: - data = self.send_request(request) - - return data['records_list']['21']['records'] - except: - return None + data = self.send_request(request) + return data['records_list']['21']['records'] class SearchResultsThread(threading.Thread): diff --git a/trademark/models.py b/trademark/models.py index 1844212..b739afd 100644 --- a/trademark/models.py +++ b/trademark/models.py @@ -11,7 +11,6 @@ from unidecode import unidecode from django.template.defaultfilters import slugify # from .cms_appconfig import TrademarkConfig - TrademarkAPI = TrademarkSearchAPI() class Owner(models.Model): @@ -47,24 +46,71 @@ class Nice(models.Model): return self.title +class Product(models.Model): + title = models.TextField() + nice = models.ForeignKey(Nice) + + class Meta: + verbose_name = _('product') + verbose_name_plural = _('products') + + def __unicode__(self): # Python 3: def __str__(self): + return self.title + + def __str__(self): + return self.title + + @property + def cap_title(self): + line = self.title.strip().replace('[', '(').replace(']', ')') + if line[-1] == ".": + cap_line = line[0].upper() + line[1:-1] + else: + cap_line = line[0].upper() + line[1:] + + return cap_line + + @property + def titles(self): + titles = self.title.split(';') + try: + if len(titles) > 1: + capitalized = [] + for line in titles: + line = line.strip().replace('[', '(').replace(']', ')') + if line[-1] == ".": + cap_line = line[0].upper() + line[1:-1] + else: + cap_line = line[0].upper() + line[1:] + + capitalized.append(cap_line) + + return capitalized + else: + return [] + except: + return [] + + class Trademark(models.Model): - title = models.CharField(max_length=255) + title = models.CharField(max_length=255, null=True) ext_id = models.CharField(max_length=20, unique=True) - application_id = models.IntegerField() - cert_id = models.IntegerField() - owner = models.TextField() - image_url = models.URLField(blank=True) + application_id = models.CharField(max_length=12, null=True) + cert_id = models.CharField(max_length=12, null=True) + owner = models.TextField(null=True) + image_url = models.URLField(null=True) nices = models.ManyToManyField(Nice) + products = models.ManyToManyField(Product) status = models.CharField(max_length=20) - source_url = models.URLField(blank=True) + source_url = models.URLField(null=True) - application_at = models.DateField(blank=True) - registration_at = models.DateField(blank=True) - expiration_at = models.DateField(blank=True) - renewed_at = models.DateField(blank=True) - priority_at = models.DateField(blank=True) + application_at = models.DateField(null=True) + registration_at = models.DateField(null=True) + expiration_at = models.DateField(null=True) + renewed_at = models.DateField(null=True) + priority_at = models.DateField(null=True) - access_key = models.CharField(max_length=20) + access_key = models.CharField(max_length=20, null=True) class Meta: verbose_name = _('trademark') @@ -98,7 +144,7 @@ class Keyword(models.Model): search = self.searches.filter(similarity=100)[0] return search.results.all().order_by('similarity') - + def create_searches(self): identity = Search(keyword_id=self.id, similarity=146) @@ -156,7 +202,6 @@ class Search(models.Model): def get_results(self): results, status = TrademarkAPI.get_results(self.search_id) - # print status['search_status'] if status['search_status'] == 'failed': self.send_request return @@ -175,7 +220,7 @@ class Search(models.Model): continue instance, created = Trademark.objects.get_or_create(ext_id=trademark['id']) - + result = SearchResult(search=self, trademark=instance, similarity=trademark['siml']) result.save() @@ -202,7 +247,7 @@ class Search(models.Model): trademark_ids = [ext_id for ext_id in self.results.values_list('ext_id', flat=True)] - trademark_keys = [str(key) for key in self.results.values_list('access_key', flat=True)] + trademark_keys = [key for key in self.results.values_list('access_key', flat=True)] if len(trademark_ids) == 0: return @@ -219,9 +264,12 @@ class Search(models.Model): instance.expiration_at = trademark.get('dateexp', '') instance.renewed_at = trademark.get('renewed', '') - instance.save() - + for nice_id, nice_description in trademark['icgs'].iteritems(): + nice_obj, created = Nice.objects.get_or_create(nice_id=nice_id) + product, created = Product.objects.get_or_create(nice=nice_obj, title=nice_description) + instance.products.add(product) + instance.save() class SearchResult(models.Model): diff --git a/trademark/templates/trademark/form.html b/trademark/templates/trademark/form.html index d55cd0c..45554cc 100644 --- a/trademark/templates/trademark/form.html +++ b/trademark/templates/trademark/form.html @@ -70,144 +70,5 @@ - {% endblock %} \ No newline at end of file diff --git a/trademark/templates/trademark/nice_block_busy.html b/trademark/templates/trademark/nice_block_busy.html index 5735373..6ee98c5 100644 --- a/trademark/templates/trademark/nice_block_busy.html +++ b/trademark/templates/trademark/nice_block_busy.html @@ -1,10 +1,16 @@
-

«{{ keyword|title }}» нельзя использовать в следующих сферах

+

«{{ keyword|title }}» уже используется в следующих сферах

-
\ No newline at end of file diff --git a/trademark/templates/trademark/registration.html b/trademark/templates/trademark/registration.html index 19bb053..a2eeb31 100644 --- a/trademark/templates/trademark/registration.html +++ b/trademark/templates/trademark/registration.html @@ -1,6 +1,6 @@ {% if nice_available.count > 0 %}
-

Зарегистрируйте товарный знак «{{ keyword.request|title }}»

+

Зарегистрируйте знак «{{ trademark_title|title }}»

Регистрация доступна в {{ nice_available.count }} классах товаров и услуг.

diff --git a/trademark/templates/trademark/search_detail.html b/trademark/templates/trademark/search_detail.html index cc8bc59..3804eb3 100644 --- a/trademark/templates/trademark/search_detail.html +++ b/trademark/templates/trademark/search_detail.html @@ -12,7 +12,7 @@
    {% for tm in identity %} -
  • +
  • {% if not tm.image_url %}

    {{ tm.title|title }}

    @@ -42,7 +42,7 @@
{% if nice_busy.count < 45 %} - {% include 'trademark/nice_block_busy.html' with keyword=keyword.request nice_busy=nice_busy %} + {% include 'trademark/nice_block_busy.html' with keyword=keyword.request nice_busy=nice_busy products_busy=products_busy %} {% endif %} {% else %} @@ -73,14 +73,7 @@

Похожие на «{{ keyword.request|title }}» торговые марки

    {% for tm in contains %} -
  • -
    - {% if not tm.image_url %} -

    {{ tm.title|title }}

    - {% endif %} -
    -

    {{ tm.title|title }}

    -
  • + {% include 'trademark/search_list_item.html' with tm=tm %} {% endfor %}
{% endif %} @@ -89,16 +82,11 @@

Знаки включающие в себя части от «{{ keyword.request|title }}»

    {% for tm in similar %} -
  • -
    - {% if not tm.image_url %} -

    {{ tm.title|title }}

    - {% endif %} -
    -

    {{ tm.title|title }}

    -
  • + {% include 'trademark/search_list_item.html' with tm=tm %} {% endfor %}
{% endif %} -{% endblock %} \ No newline at end of file + +{% endblock %} + diff --git a/trademark/templates/trademark/search_list_item.html b/trademark/templates/trademark/search_list_item.html new file mode 100644 index 0000000..93361d4 --- /dev/null +++ b/trademark/templates/trademark/search_list_item.html @@ -0,0 +1,8 @@ +
  • +
    +{% if not tm.image_url %} +

    {{ tm.title|title }}

    +{% endif %} +
    +

    {{ tm.title|title }}

    +
  • \ No newline at end of file diff --git a/trademark/templates/trademark/trademark_detail.html b/trademark/templates/trademark/trademark_detail.html new file mode 100644 index 0000000..3abf951 --- /dev/null +++ b/trademark/templates/trademark/trademark_detail.html @@ -0,0 +1,55 @@ +{% extends "trademark/base.html" %} + +{% block trademark_content %} +
    +
    +

    Товарный знак «{{ tm.title }}»

    +
      +
    • +

      Подана заявка {{ tm.application_at }}

      +

      Номер № {{ tm.application_id }}

      +
    • +
    • + → +
    • +
    • +

      Регистрация {{ tm.registration_at }}

      +

      Номер свидетельства № {{ tm.cert_id }}

      +
    • +
    + +
    +
    +

    Изобразительный знак:

    + +
    +
    +

    Правообладатель:

    +

    {{ tm.owner }}

    +
    +
    + + + {% include 'trademark/nice_block_busy.html' with keyword=tm.title nice_busy=tm.nices.all products_busy=tm.products.all %} + +

    Данные ФИПС Федеральной службы по интеллектуальной собственности

    + {{ tm.source_url }} +
    + +
    + +
    + +
    +
    +

    Попробуйте проверить другой товарный знак

    + {% include 'trademark/form.html' %} +
    + + {% if nice_available.count > 0 %} + {% include 'trademark/registration.html' with trademark_title=tm.title nice_available=nice_available nice_busy=tm.nices %} + {% endif %} + +
    +
    +{% endblock %} \ No newline at end of file diff --git a/trademark/urls.py b/trademark/urls.py index 7b99dad..d5f72e7 100644 --- a/trademark/urls.py +++ b/trademark/urls.py @@ -7,6 +7,7 @@ from . import views urlpatterns = patterns('', url(r'^$', views.IndexView.as_view(), name='index'), url(r'^results/(?P[\w-]+)/$', views.SearchDetailView.as_view(), name='search-detail'), + url(r'^trademark/(?P[\w-]+)/$', views.TrademarkDetailView.as_view(), name='trademark-detail'), url(r'^request/(?P[\w-]+)/$', views.Search.as_view(), name='search-detail'), url(r'^request/$', views.Search.as_view(), name='search'), ) diff --git a/trademark/views.py b/trademark/views.py index f76bfcb..9851a96 100644 --- a/trademark/views.py +++ b/trademark/views.py @@ -29,19 +29,52 @@ class SearchDetailView(generic.DetailView): nice_busy_ids = identity_results.values_list('nices__nice_id', flat=True).distinct() contains = self.get_object().searches.filter(similarity=100)[0] - contains_results = contains.results.all().exclude(id__in=identity_ids) - context['contains'] = contains_results + contains_results = contains.results.filter(title__isnull=False).exclude(id__in=identity_ids) + context['contains'] = contains_results[:30] contains_ids = contains_results.values_list('id', flat=True) similar = self.get_object().searches.filter(similarity=97)[0] - context['similar'] = similar.results.all().exclude(id__in=contains_ids | identity_ids) + context['similar'] = similar.results.all().exclude(id__in=contains_ids | identity_ids)[:30] context['nice_busy'] = Nice.objects.filter(nice_id__in=nice_busy_ids).order_by('nice_id') + context['products_busy'] = Product.objects.filter(id__in=identity_results.values_list('products__id')).order_by('nice__nice_id') context['nice_available'] = Nice.objects.filter(nice_id__in=[x for x in range(1,46) if x not in nice_busy_ids]).order_by('nice_id') return context +class TrademarkDetailView(generic.DetailView): + model = Trademark + context_object_name = 'trademark' + template_name = 'trademark/trademark_detail.html' + view_url_name = 'trademark:trademark-detail' + + def get_context_data(self, **kwargs): + context = super(TrademarkDetailView, self).get_context_data(**kwargs) + + tm = self.get_object() + context['tm'] = tm + context['nice_available'] = Nice.objects.filter(nice_id__in=[x for x in range(1,46) if x not in tm.nices.values_list('nice_id', flat=True)]).order_by('nice_id') + # identity = self.get_object().searches.filter(similarity=146)[0] + # identity_results = identity.results.all() + # context['identity'] = identity_results + # identity_ids = identity_results.values_list('id', flat=True) + # nice_busy_ids = identity_results.values_list('nices__nice_id', flat=True).distinct() + + # contains = self.get_object().searches.filter(similarity=100)[0] + # contains_results = contains.results.filter(title__isnull=False).exclude(id__in=identity_ids) + # context['contains'] = contains_results[:30] + # contains_ids = contains_results.values_list('id', flat=True) + + # similar = self.get_object().searches.filter(similarity=97)[0] + # context['similar'] = similar.results.all().exclude(id__in=contains_ids | identity_ids)[:30] + + # context['nice_busy'] = Nice.objects.filter(nice_id__in=nice_busy_ids).order_by('nice_id') + # context['products_busy'] = Product.objects.filter(id__in=identity_results.values_list('products__id')).order_by('nice__nice_id') + + return context + + class IndexView(generic.ListView): template_name = 'trademark/index.html' context_object_name = 'trademarks' diff --git a/zsite/static/js/trademarks.js b/zsite/static/js/trademarks.js new file mode 100644 index 0000000..fc914b9 --- /dev/null +++ b/zsite/static/js/trademarks.js @@ -0,0 +1,157 @@ +$(function(){ + // SearchForm + function send () { + var request = $("#trademark-search-request").val(), + $form = $('.trademark-search-form'), + $loading = $('.trademark-search-loading'), + $status_list = $('.trademark-search-loading-status'), + $count = $('#trademark-search-count'), + $title = $('#trademark-search-request-value'), + $sending = $('#trademark-search-sending'), + $identity = $('#trademark-search-identity'), + $contains = $('#trademark-search-contains'), + $similar = $('#trademark-search-similar'), + $wait = $('#trademark-search-wait'), + slug = '', + iteration = 0; + + function update_status(data) { + var identity = data['identity'], + contains = data['contains'], + similar = data['similar'], + completed = identity['status'] == 'finished' && contains['status'] == 'finished' && similar['status'] == 'finished', + almost_completed = identity['status'] == 'finished' && contains['status'] == 'finished' && identity['count'] > 0, + show_link = identity['status'] == 'finished' || contains['status'] == 'finished' || similar['status'] == 'finished', + tm_url = '/ru/trademarks/online-search/results/' + slug + '/'; + + if(identity['status'] == 'finished') { + var count = identity['count']; + if(count > 0) { + $identity.text(GetNoun(count, 'Найден', 'Найдены', 'Найдено') + ' '+ count + ' ' + GetAdj(count, 'такой', 'таких') + ' ' + GetNoun(count, 'знак', 'знака', 'знаков')+ ' в ' + identity['nices'] + ' ' + GetNoun(identity['nices'], 'классе', 'классах', 'классах')); + } else { + $identity.text('Точно таких же знаков не найдено'); + } + } + + if(contains['status'] == 'finished') { + var count = contains['count']; + if(count > 0) { + $contains.text(GetNoun(count, 'Обнаружен', 'Обнаружены', 'Обнаружено') + ' ' + count + ' ' + GetAdj(count, 'похожий', 'похожих') + ' ' + GetNoun(count, 'знак', 'знака', 'знаков')); + } else { + $contains.text('Похожих знаков не обнаружено'); + } + } + + if(similar['status'] == 'finished') { + var count = similar['count']; + if(count > 0) { + $similar.text(GetNoun(count, 'Подобран', 'Подобраны', 'Подобрано') + ' ' + count + ' ' + GetAdj(count, 'производный', 'производных') + ' ' + GetNoun(count, 'знак', 'знака', 'знаков')); + } else { + $similar.text('Не удалось подобрать производных знаков'); + } + } + + if(iteration > 3) { + $wait.show(500); + } + + if(show_link && iteration > 5) { + var href = '' + $wait.html('Остановить поиск и перейти к результатам'); + } else { + console.log(iteration); + } + + if(completed || almost_completed) { + yaCounter950321.reachGoal('TrademarkSearchResults'); + ga('send', 'event', 'TrademarkSearch', 'results', document.title); + + document.location.href = tm_url; + } else { + iteration += 1; + setTimeout(function () { + get_status(slug); + }, 10000); + } + + } + + function get_status(slug) { + try { + $.get("/ru/trademarks/online-search/request/" + slug + "/").done(function(data) { + update_status(data); + }); + } catch (err) { + setTimeout(function () { + get_status(slug); + }, 5000); + } + } + + yaCounter950321.reachGoal('TrademarkSearchClick'); + ga('send', 'event', 'TrademarkSearch', 'click', document.title); + + // Show Loading Block + $title.text(request); + $form.hide(); + $loading.show(); + $sending.show(); + + $.post("/ru/trademarks/online-search/request/", + { 'keyword': request}).done(function(data) { + var tm_count = Math.floor(Math.random() * (3000000 - 1000000) + 1000000); + $('.trademark-search-count').text(tm_count.toLocaleString() + ' знаков') + $count.show(500); + $identity.delay(3000).show(500); + $contains.delay(6000).show(500); + $similar.delay(12000).show(500); + + slug = data['slug']; + update_status(data); + + }) + .fail(function(data) { + console.log( "error " ); + console.log(data); + }) + .always(function(data) { + console.log( "finished" ); + console.log(data); + $sending.hide() + }); + } + $('#trademark-search-example').click(function(event) { + event.preventDefault(); + $("#trademark-search-request").val('Yandex'); + }); + + $('#trademark-search-request').keypress(function (e) { + if (e.which == 13) { + send(); + return false; //<---- Add this line + } + }); + $('#trademark-search-submit').click(function(){ + send(); + }); + + + + // Results + $('.trademark-search-show-products').each(function() { + var product_id = $(this).attr('product-id') + $(this).click(function () { + var $list = $(''); + + $('.trademark-search-nice-busy-products[product-id=' + product_id + ']').slideToggle('slow'); + }); + }); + + $('.trademark-search-result').click(function() { + var tm_id = $(this).attr('trademark-id'); + + document.location.href = '/ru/trademarks/online-search/trademark/' + tm_id + '/'; + }); + + + }); \ No newline at end of file diff --git a/zsite/static/less/search.less b/zsite/static/less/search.less index ac83000..e5c08c3 100644 --- a/zsite/static/less/search.less +++ b/zsite/static/less/search.less @@ -89,6 +89,22 @@ margin-left: -15px; margin-top: 10px; + .trademark-search-nice-busy-product { + margin-top: 10px; + } + + .trademark-search-nice-busy-products { + font-size: 11px; + margin-top: 5px; + + li { + margin-bottom: 5px; + padding-left: 0; + } + + + } + .description { margin: 5px 0; } @@ -205,4 +221,37 @@ transform: scaleY(1.0); -webkit-transform: scaleY(1.0); } +} + + + + +// Trademark detail + +.trademark-detail-fips-wrap { width: 100%; padding: 0; overflow: hidden; float: left; + +.frame { width: 120%; height: 900px; border: 1px solid black} + +.frame { + // zoom: 0.25; + -moz-transform: scale(0.8); + -moz-transform-origin: 0 0; + -o-transform: scale(0.8); + -o-transform-origin: 0 0; + -webkit-transform: scale(0.8); + -webkit-transform-origin: 0 0; +} + +} + +.trademark-detail-arrow { + font-size: 40px; +} + +.trademark-detail-description { + .trademark-detail-description-visual { + img { + width: 100%; + } + } } \ No newline at end of file