Source code for meta.models
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals
import contextlib
from copy import copy
from django.conf import settings as dj_settings
from . import settings
NEED_REQUEST_OBJECT_ERR_MSG = """
Meta models needs request objects when initializing if sites framework is not used.
""".strip()
[docs]class ModelMeta(object):
"""
Meta information mixin.
"""
_metadata = {}
_metadata_default = {
'title': False,
'description': False,
'og_description': False,
'twitter_description': False,
'gplus_description': False,
'keywords': False,
'image': settings.DEFAULT_IMAGE,
'object_type': settings.DEFAULT_TYPE,
'og_type': settings.FB_TYPE,
'og_app_id': settings.FB_APPID,
'og_profile_id': settings.FB_PROFILE_ID,
'og_publisher': settings.FB_PUBLISHER,
'og_author_url': settings.FB_AUTHOR_URL,
'fb_pages': settings.FB_PAGES,
'twitter_type': settings.TWITTER_TYPE,
'twitter_site': settings.TWITTER_SITE,
'twitter_author': settings.TWITTER_AUTHOR,
'gplus_type': settings.GPLUS_TYPE,
'gplus_author': settings.GPLUS_AUTHOR,
'gplus_publisher': settings.GPLUS_PUBLISHER,
'published_time': False,
'modified_time': False,
'expiration_time': False,
'tag': False,
'url': False,
'locale': False,
'custom_namespace': settings.OG_NAMESPACES,
}
[docs] def get_meta(self, request=None):
"""
Retrieve the meta data configuration
"""
metadata = copy(self._metadata_default)
metadata.update(self._metadata)
return metadata
def _retrieve_data(self, request, metadata):
"""
Build the data according to the metadata configuration
"""
with self._set_request(request):
for field, value in metadata.items():
if value:
data = self._get_meta_value(field, value)
yield field, data
def _get_meta_value(self, field, value):
"""
Build the data according to a
:param field: metadata field name
:param value: provided value
:return: data
"""
if value:
attr = getattr(self, value, False)
if attr is not False:
if callable(attr):
try:
data = attr(field)
except TypeError:
data = attr()
else:
data = attr
else:
data = value
return data
[docs] def as_meta(self, request=None):
"""
Method that generates the Meta object (from django-meta)
"""
from meta.views import Meta
metadata = self.get_meta(request)
meta = Meta(request=request)
for field, data in self._retrieve_data(request, metadata):
setattr(meta, field, data)
for field in ('og_description', 'twitter_description', 'gplus_description'):
generaldesc = getattr(meta, 'description', False)
if not getattr(meta, field, False) and generaldesc:
setattr(meta, field, generaldesc)
return meta
@contextlib.contextmanager
def _set_request(self, request):
"""
Context processor that sets the requst on the current instance
"""
self._request = request
yield
delattr(self, '_request')
[docs] def get_request(self):
"""
Retrieve request from current instance
"""
return getattr(self, '_request', None)
[docs] def get_author(self):
"""
Retrieve the author object. This is meant to be overridden in the model
to return the actual author instance (e.g.: the user object).
"""
class Author(object):
fb_url = None
twitter_profile = None
gplus_profile = None
def get_full_name(self): # pragma: no cover
return None
return Author()
[docs] def get_author_url(self):
"""
Sample method to return the author facebook URL
"""
try:
return self.get_author().fb_url
except AttributeError: # pragma: no cover
return ''
[docs] def get_author_name(self):
"""
Sample method to return the author full name
"""
try:
return self.get_author().get_full_name()
except AttributeError: # pragma: no cover
return ''
[docs] def get_author_twitter(self):
"""
Sample method to return the author twitter account
"""
try:
return self.get_author().twitter_profile
except AttributeError: # pragma: no cover
return ''
[docs] def get_author_gplus(self):
"""
Sample method to return the author google plus URL
"""
try:
return self.get_author().gplus_profile
except AttributeError: # pragma: no cover
return ''
[docs] def get_meta_protocol(self):
"""
Current http protocol
"""
return dj_settings.META_SITE_PROTOCOL
[docs] def build_absolute_uri(self, url):
"""
Return the full url for the provided url argument
"""
request = self.get_request()
if request:
return request.build_absolute_uri(url)
if not dj_settings.META_USE_SITES:
raise RuntimeError(NEED_REQUEST_OBJECT_ERR_MSG)
from django.contrib.sites.models import Site
s = Site.objects.get_current()
meta_protocol = self.get_meta_protocol()
if url.startswith('http'):
return url
if s.domain.find('http') > -1:
return '{0}{1}'.format(s.domain, url) # pragma: no cover
else:
if url.startswith('/'):
return '{0}://{1}{2}'.format(meta_protocol, s.domain, url)
else:
return '{0}://{1}/{2}'.format(meta_protocol, s.domain, url)