Esempio n. 1
0
    def get(self, request, obj_id=None):
        from apps.realms import get_realms
        if obj_id is None:  # Запрошен список всех известных категорий.
            item = get_category_lists(
                init_kwargs={
                    'show_title': True,
                    'show_links': lambda cat: reverse(self.realm.get_details_urlname(), args=[cat.id])
                },
                additional_parents_aliases=get_category_aliases_under())
            return self.render(request, {'item': item})

        # Выводим список материалов (разбитых по областям сайта) для конкретной категории.
        category_model = get_category_model()
        category = get_object_or_404(category_model.objects.select_related('parent'), pk=obj_id)

        realm_list = []
        for realm in get_realms():
            if hasattr(realm.model, 'categories'):  # ModelWithCategory
                objs = realm.model.get_objects_in_category(category)[:5]
                if objs:
                    realm_list.append({
                        'objects': objs,
                        'url': reverse(realm.get_tags_urlname(), args=[category.id]),
                        'realm': realm
                    })

        return self.render(request, {self.realm.name: category, 'item': category, 'realm_list': realm_list})
Esempio n. 2
0
    def get(self, request, obj_id=None):
        from apps.realms import get_realms
        realms = get_realms().values()

        if obj_id is None:  # Запрошен список всех известных категорий.
            item = get_category_lists(
                init_kwargs={
                    'show_title':
                    True,
                    'show_links':
                    lambda cat: reverse(self.realm.get_details_urlname(),
                                        args=[cat.id])
                },
                additional_parents_aliases=get_category_aliases_under())
            return self.render(request, {'item': item, 'realms': realms})

        # Выводим список материалов (разбитых по областям сайта) для конкретной категории.
        category_model = get_category_model()
        category = get_object_or_404(
            category_model.objects.select_related('parent'), pk=obj_id)

        realms_links = OrderedDict()
        for realm in realms:
            realm_model = realm.model

            if not hasattr(realm_model, 'categories'):  # ModelWithCategory
                continue

            items = realm_model.get_objects_in_category(category)

            if not items:
                continue

            realm_title = realm_model.get_verbose_name_plural()

            _, plural = realm.get_names()

            realms_links[realm_title] = (plural, items)

        return self.render(
            request, {
                self.realm.name: category,
                'item': category,
                'realms_links': realms_links
            })
Esempio n. 3
0
class CategoryRealm(RealmBase):
    """
    Область с категориями.
    """

    view_listing_description = 'Карта категорий материалов по языку программирования Python доступных на сайте.'
    view_listing_keywords = 'материалы по питону, python по категориям'

    model = get_category_model()
    icon = 'tag'
    name = 'category'
    name_plural = 'categories'
    allowed_views = ('listing', 'details')
    ready_for_digest = False
    sitemap_enabled = False

    show_on_main = False
    show_on_top = False

    view_listing_title = 'Путеводитель'
    view_listing_base_class = CategoryListingView
    view_details_base_class = CategoryListingView

    SYNDICATION_NAMESPACE = 'category_feeds'

    @classmethod
    def get_sitetree_details_item(cls):
        return item(
            'Категория «{{ category.parent.title }} — {{ category.title }}»',
            'categories:details category.id',
            in_menu=False,
            in_sitetree=False)

    @classmethod
    def init(cls):
        # Включаем прослушивание сигналов, необходимое для функционировая области.
        tie_model = get_tie_model()
        # url-синдикации будут обновлены в случае добавления/удаления связи сущности с категорией.
        signals.post_save.connect(cls.update_syndication_urls,
                                  sender=tie_model)
        signals.post_delete.connect(cls.update_syndication_urls,
                                    sender=tie_model)

    @classmethod
    def get_urls(cls):
        urls = super().get_urls()
        urls += CategoryRealm.get_syndication_urls()
        return urls

    @classmethod
    def get_syndication_url(cls):
        return 'feed/'

    @classmethod
    def update_syndication_urls(cls, **kwargs):
        """Обновляет url-шаблоны синдикации, заменяя старые новыми."""
        target_namespace = cls.SYNDICATION_NAMESPACE
        linked_category_id_str = 'category_%s' % kwargs['instance'].category_id
        pattern_idx = -1

        resolver = get_resolver(None)
        urlpatterns = getattr(resolver.urlconf_module, 'urlpatterns',
                              resolver.urlconf_module)

        for idx, pattern in enumerate(urlpatterns):
            if getattr(pattern, 'namespace', '') == target_namespace:
                pattern_idx = idx
                if linked_category_id_str in pattern.reverse_dict.keys():
                    # Категория была известна и ранее, перепривязка URL не требуется.
                    return
                break

        if pattern_idx > -1:
            del urlpatterns[pattern_idx]
            urlpatterns += cls.get_syndication_urls()

    @classmethod
    def get_syndication_urls(cls):
        """Возвращает url-шаблоны с привязанными сгенерированными представлениями
         для потоков синдикации (RSS) с перечислением новых материалов в категориях.

        :return:
        """
        feeds = []
        tie_model = get_tie_model()
        categories = tie_model.get_linked_objects(by_category=True)

        def get_in_category(category_id):
            """Возвращает объекты из разных областей в указанной категории."""
            linked = tie_model.get_linked_objects(
                filter_kwargs={'category_id': category_id}, id_only=True)
            result = []
            for model, ids in linked.items():
                result.extend(model.get_actual().filter(
                    id__in=ids)[:SYNDICATION_ITEMS_LIMIT])
            result = sorted(result,
                            key=attrgetter('time_published'),
                            reverse=True)
            return result[:SYNDICATION_ITEMS_LIMIT]

        for category in categories.keys():
            title = category.title
            category_id = category.id
            feed = RealmBase._get_syndication_feed(
                title=title,
                description='Материалы в категории «%s». %s' %
                (title, category.note),
                func_link=lambda self: reverse(CategoryRealm.
                                               get_details_urlname(),
                                               args=[self.category_id]),
                func_items=lambda self: get_in_category(self.category_id),
                cls_name='Category%s' % category_id)
            feed.category_id = category_id

            feeds.append(
                url(r'^%s/%s/$' % (category_id, SYNDICATION_URL_MARKER),
                    feed,
                    name='category_%s' % category_id))

        _, realm_name_plural = CategoryRealm.get_names()

        return [
            url(r'^%s/' % realm_name_plural,
                (feeds, realm_name_plural, cls.SYNDICATION_NAMESPACE))
        ]
Esempio n. 4
0
from uuid import uuid4

import pytest
from django.db.utils import IntegrityError
from django.template.base import TemplateSyntaxError
from django.template.context import Context

from sitecats.exceptions import SitecatsLockedCategoryDelete, SitecatsConfigurationError
from sitecats.models import Category, Tie
from sitecats.settings import UNRESOLVED_URL_MARKER
from sitecats.toolbox import CategoryList, get_category_aliases_under, get_tie_model, \
    get_category_model

MODEL_TIE = get_tie_model()
MODEL_CATEGORY = get_category_model()

from sitecats.tests.testapp.models import Comment, Article


@pytest.fixture
def create_comment():
    from sitecats.tests.testapp.models import Comment

    def create_comment_():
        comment = Comment(title='comment%s' % uuid4().hex)
        comment.save()
        return comment

    return create_comment_

Esempio n. 5
0
from uuid import uuid4

import pytest
from django.db.utils import IntegrityError
from django.template.base import TemplateSyntaxError
from django.template.context import Context

from sitecats.exceptions import SitecatsLockedCategoryDelete, SitecatsConfigurationError
from sitecats.models import Category, Tie
from sitecats.settings import UNRESOLVED_URL_MARKER
from sitecats.toolbox import CategoryList, get_category_aliases_under, get_tie_model, \
    get_category_model

MODEL_TIE = get_tie_model()
MODEL_CATEGORY = get_category_model()

from sitecats.tests.testapp.models import Comment, Article


@pytest.fixture
def create_comment():
    from sitecats.tests.testapp.models import Comment

    def create_comment_():
        comment = Comment(title='comment%s' % uuid4().hex)
        comment.save()
        return comment

    return create_comment_