You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
8.0 KiB
228 lines
8.0 KiB
# -*- coding: utf-8 -*-
|
|
import copy
|
|
|
|
from django.db import models
|
|
from django.db.models.signals import post_save
|
|
from django.utils import translation
|
|
from django.utils.html import strip_tags
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.conf import settings
|
|
from django.core.cache import cache
|
|
|
|
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
|
|
from pymorphy.django_conf import default_morph as morph
|
|
|
|
from functions.signal_handlers import post_save_handler
|
|
|
|
|
|
# additional funcs
|
|
def get_month_inflect(value, key):
|
|
MONTHES = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
|
|
'may': _(u'мае'), 'jun': _(u'июне'), u'jul': _(u'июле'), 'aug': _(u'августе'),
|
|
'sep': _(u'сентябре'), 'oct': _(u'октябре'), 'nov': _(u'ноябре'), 'dec': _(u'декабре'),}
|
|
|
|
return {key: MONTHES.get(value, '') }
|
|
|
|
|
|
def get_obj_inflect(obj, key):
|
|
if translation.get_language() == 'ru':
|
|
result = {key: getattr(obj, 'inflect', '')}
|
|
else:
|
|
result = {key: getattr(obj, 'name', '')}
|
|
return result
|
|
|
|
|
|
def get_theme_inflect(obj, key):
|
|
if translation.get_language() == 'ru':
|
|
result = {'theme_inflect': getattr(obj, 'inflect', ''),
|
|
'theme_name': getattr(obj, 'name', '')}
|
|
else:
|
|
result = {'theme_inflect': getattr(obj, 'name', ''),
|
|
'theme_name': getattr(obj, 'name', '')}
|
|
return result
|
|
|
|
|
|
def get_tag_inflect(obj, key):
|
|
if translation.get_language() == 'ru':
|
|
result = {'tag_inflect': getattr(obj, 'inflect', ''),
|
|
'tag_name': getattr(obj, 'name', '')}
|
|
else:
|
|
result = {'tag_inflect': getattr(obj, 'name', ''),
|
|
'tag_name': getattr(obj, 'name', '')}
|
|
return result
|
|
|
|
|
|
class MetaSetting(TranslatableModel):
|
|
"""
|
|
setting that generates meta fields
|
|
"""
|
|
name = models.CharField(max_length=100, unique=True)
|
|
translations = TranslatedFields(
|
|
title=models.CharField(max_length=255, blank=True),
|
|
description=models.CharField(max_length=255, blank=True),
|
|
keywords=models.CharField(max_length=255, blank=True),
|
|
h1=models.CharField(max_length=255, blank=True),
|
|
)
|
|
# params that handles for objects
|
|
object_params = {
|
|
'object_name': 'name',
|
|
'object_title': 'main_title',
|
|
'object_title_l': lambda obj: getattr(obj, 'main_title', '')[:1].lower() + getattr(obj, 'main_title', '')[1:] if getattr(obj, 'main_title', None) else '',
|
|
'city': 'city',
|
|
'country': 'country',
|
|
'object_dates': 'get_dates',
|
|
'object_place': 'get_place_name'
|
|
|
|
}
|
|
# default params
|
|
params = {'month': get_month_inflect, 'country': get_obj_inflect, 'city': get_obj_inflect,
|
|
'theme': get_theme_inflect, 'tag': get_tag_inflect}
|
|
|
|
monthes = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
|
|
'may': _(u'мае'), 'jun': _(u'июне'), u'jul': _(u'июле'), 'aug': _(u'августе'),
|
|
'sep': _(u'сентябре'), 'oct': _(u'октябре'), 'nov': _(u'ноябре'), 'dec': _(u'декабре'),}
|
|
|
|
def __unicode__(self):
|
|
return self.name
|
|
|
|
def generate_meta(self, params, obj=None):
|
|
"""
|
|
generating meta fields by given params and current object fields
|
|
|
|
obj must be in current language
|
|
"""
|
|
# current language
|
|
lang = translation.get_language()
|
|
|
|
updates = {}
|
|
if obj:
|
|
# if objects - generate fields from object_params field
|
|
for key, value in self.object_params.iteritems():
|
|
if callable(value):
|
|
updates.update({key: value(obj)})
|
|
else:
|
|
updates.update({key: getattr(obj, value, '')})
|
|
|
|
for key, value in params.iteritems():
|
|
# iterate through default params
|
|
if key in self.params:
|
|
updates.update(self.params[key](value, key))
|
|
params.update(updates)
|
|
|
|
# current translation object
|
|
tr = self.translations.get(language_code=lang)
|
|
title, description, h1 = '', '', ''
|
|
keywords = [] #tr.keywords.format(**params) uncoment if keywords need
|
|
|
|
try:
|
|
title = tr.title.format(**params)
|
|
description = tr.description.format(**params)
|
|
h1 = tr.h1.format(**params)
|
|
except:
|
|
pass
|
|
|
|
if obj and getattr(obj, 'description', None):
|
|
try:
|
|
description = strip_tags(obj.description).strip('\n').splitlines()[0][:200]
|
|
except (IndexError, ):
|
|
pass
|
|
|
|
return {'title': title, 'description': description, 'keywords': keywords, 'h1': h1}
|
|
|
|
def get_param(self, obj, field):
|
|
param = self.params.get(field)
|
|
if not param:
|
|
return ''
|
|
s = getattr(obj, param['name'], '')
|
|
if param.get('inflected'):
|
|
s = morph.inflect_ru(s, u'пр')
|
|
return s
|
|
|
|
def get_title(self):
|
|
title = self.title
|
|
return title
|
|
|
|
def get_h1(self):
|
|
h1 = self.h1
|
|
return h1
|
|
|
|
def get_description(self):
|
|
description = self.description
|
|
return description
|
|
|
|
def get_keywords(self):
|
|
keywords = self.keywords
|
|
return []
|
|
|
|
|
|
class SeoTextManager(TranslationManager):
|
|
cache_time = 3600
|
|
|
|
def cache_get(self, *args, **kwargs):
|
|
url = kwargs.get('url')
|
|
lang = kwargs.get('lang')[:2] or translation.get_language()[:2]
|
|
key = 'seo_text_cache'
|
|
result = cache.get(key)
|
|
if result is None:
|
|
qs = list(SeoText.objects.language('all'))
|
|
result = {obj.language_code+'_'+obj.url: obj for obj in qs}
|
|
cache.set(key, result, self.cache_time)
|
|
return result.get("%s_%s" % (lang, url), None)
|
|
|
|
|
|
class SeoText(TranslatableModel):
|
|
"""
|
|
store seo data for specified urls
|
|
"""
|
|
url = models.CharField(max_length=50, unique=True, verbose_name=_(u"URL: www.expomap.ru"))
|
|
|
|
translations = TranslatedFields(
|
|
title=models.CharField(max_length=255, verbose_name=_(u"Заголовок")),
|
|
page_title=models.CharField(max_length=255, verbose_name=_(u"Тайтл страницы")),
|
|
description=models.CharField(max_length=1000, verbose_name=_(u"Дескрипшн")),
|
|
body=models.TextField(verbose_name=_(u"Текст"))
|
|
)
|
|
|
|
objects = SeoTextManager()
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(SeoText, self).__init__(*args, **kwargs)
|
|
self.cache_fields = ['title', 'body', 'page_title', 'description']
|
|
self.is_new = True
|
|
|
|
def get_absolute_url(self):
|
|
return self.url
|
|
|
|
def save(self, *args, **kwargs):
|
|
super(SeoText, self).save(*args, **kwargs)
|
|
self.initial_language = 'ru'
|
|
|
|
new_values = {field: getattr(self, field) for field in self.cache_fields}
|
|
langs = [code for code, _ in settings.LANGUAGES]
|
|
if self.is_new:
|
|
for lang in langs:
|
|
if lang not in self.get_available_languages():
|
|
self.translate(lang)
|
|
for key, value in new_values.items():
|
|
setattr(self, key, value)
|
|
self.save_translations(self)
|
|
else:
|
|
translations = {obj.language_code:obj for obj in list(self.translations.all())}
|
|
for lang in langs:
|
|
if lang is not self.initial_language:
|
|
tr = translations[lang]
|
|
for key, value in new_values.items():
|
|
#if u'%s' % getattr(self, key) is u'' or getattr(self, key) is u'%s' % self.var_cache[key]:
|
|
setattr(tr, key, value)
|
|
tr.save()
|
|
|
|
self.lazy_translation_getter(self.initial_language)
|
|
self.var_cache = {var: copy.copy(getattr(self, var)) for var in self.cache_fields}
|
|
self.is_new = False
|
|
return self
|
|
|
|
def __unicode__(self):
|
|
return self.url
|
|
|
|
|
|
post_save.connect(post_save_handler, sender=MetaSetting)
|
|
|