<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from django.core.cache import cache
from django.utils import timezone
from django.conf import settings

from .signals import shorturl_generate, delete_container
from opps.core.cache import _cache_key
from opps.core.models import Publishable, Slugged, Channeling, Imaged
from opps.boxes.models import BaseBox

from taggit.managers import TaggableManager


class Container(Publishable, Slugged, Channeling, Imaged):
    title = models.CharField(_(u"Title"), max_length=140, db_index=True)
    hat = models.CharField(
        _(u"Hat"),
        max_length=140,
        null=True, blank=True,
    )
    short_url = models.URLField(
        _("Short URL"),
        null=True, blank=True,
    )
    child_class = models.CharField(
        _(u'Child class'),
        max_length=30,
        null=True, blank=True,
        db_index=True
    )
    child_module = models.CharField(
        _(u'Child module'),
        max_length=120,
        null=True, blank=True,
        db_index=True
    )
    child_app_label = models.CharField(
        _(u'Child app label'),
        max_length=30,
        null=True, blank=True,
        db_index=True
    )
    tags = TaggableManager(blank=True, verbose_name=u'Tags')
    show_on_root_channel = models.BooleanField(
        _(u"Show on root channel?"),
        default=True
    )
    sources = models.ManyToManyField(
        'sources.Source',
        null=True, blank=True,
        through='containers.ContainerSource')

    def __unicode__(self):
        return u"{}".format(self.get_absolute_url())

    class Meta:
        ordering = ['-date_available', 'title', 'channel_long_slug']
        verbose_name = _('Container')
        verbose_name_plural = _('Containers')
        unique_together = ("site", "child_class", "channel_long_slug", "slug")

    def save(self, *args, **kwargs):
        self.channel_name = self.channel.name
        self.channel_long_slug = self.channel.long_slug
        self.child_class = self.__class__.__name__
        self.child_module = self.__class__.__module__
        self.child_app_label = self._meta.app_label

        models.signals.post_save.connect(shorturl_generate,
                                         sender=self.__class__)
        super(Container, self).save(*args, **kwargs)

    def get_absolute_url(self):
        """
        TODO: get_absolute_url from child_app_label/child_class
        """
        if self.child_class != "Post":
            return u"/{}/{}/{}".format(self.child_class.lower(),
                                       self.channel_long_slug, self.slug)
        return u"/{}/{}".format(self.channel_long_slug, self.slug)

    def get_thumb(self):
        return self.main_image

    @property
    def search_category(self):
        """for use in search result"""
        return _(self.child_class)

    def get_http_absolute_url(self):
        return "http://{}{}".format(self.site_domain, self.get_absolute_url())
    get_http_absolute_url.short_description = 'URL'

    def recommendation(self):

        now = timezone.now()
        start = now - timezone.timedelta(
            days=settings.OPPS_RECOMMENDATION_RANGE_DAYS
        )

        cachekey = _cache_key(
            '{}-recommendation'.format(self.__class__.__name__),
            self.__class__, self.site_domain,
            u"{}-{}".format(self.channel_long_slug, self.slug))
        getcache = cache.get(cachekey)
        if getcache:
            return getcache

        tag_list = [t for t in self.tags.all()[:3]]
        _list = [a for a in Container.objects.filter(
            site_domain=self.site_domain,
            child_class=self.child_class,
            channel_long_slug=self.channel_long_slug,
            date_available__range=(start, now),
            published=True,
            tags__in=tag_list
        ).exclude(pk=self.pk).distinct().order_by('-date_available')[:10]]

        cache.set(cachekey, _list)
        return _list


# DOES NOT WORKS, IT CREATES A TABLE WITH A WRONG NAME
# class ContainerThrough(models.Model):
#     container = models.ForeignKey(
#         'containers.Container',
#         null=True, blank=True,
#         on_delete=models.SET_NULL,
#         verbose_name=_(u'Container'),
#     )
#     order = models.PositiveIntegerField(_(u'Order'), default=0)

#     class META:
#         abstract = True


class ContainerSource(models.Model):
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    source = models.ForeignKey(
        'sources.Source',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name='containersource_sources',
        verbose_name=_(u'Source'),
    )

    class META:
        verbose_name = _(u'Container source')
        verbose_name_plural = _(u'Container sources')
        ordering = ('order',)

    def __unicode__(self):
        return u"{}".format(self.source.slug)


class ContainerImage(models.Model):
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    image = models.ForeignKey(
        'images.Image',
        verbose_name=_(u'Image'),
        null=True, blank=True,
        on_delete=models.SET_NULL
    )

    caption = models.CharField(
        _(u"Caption"),
        max_length=255,
        blank=True,
        null=True
    )

    class META:
        verbose_name = _('Container image')
        verbose_name_plural = _('Container images')
        ordering = ('order',)

    def __unicode__(self):
        return u"{}".format(self.image.title)


class ContainerBox(BaseBox):

    title = models.CharField(
        _(u"Title"),
        null=True,
        blank=True,
        max_length=140,
    )
    containers = models.ManyToManyField(
        'containers.Container',
        null=True, blank=True,
        verbose_name=_(u'Container'),
        related_name='containerbox_containers',
        through='containers.ContainerBoxContainers'
    )
    queryset = models.ForeignKey(
        'boxes.QuerySet',
        null=True, blank=True,
        related_name='containerbox_querysets',
        verbose_name=_(u'Query Set')
    )

    class META:
        verbose_name = _('Container box')
        verbose_name_plural = _('Containers boxes')

    def ordered_containers(self, field='order'):
        now = timezone.now()
        qs = self.containers.filter(
            published=True,
            date_available__lte=now,
            containerboxcontainers__date_available__lte=now
        ).filter(
            models.Q(containerboxcontainers__date_end__gte=now) |
            models.Q(containerboxcontainers__date_end__isnull=True)
        )
        return qs.order_by('containerboxcontainers__order'
                           ).distinct()

    def get_queryset(self):
        """
        for backwards compatibility
        """
        return self.queryset.get_queryset()


class ContainerBoxContainers(models.Model):
    containerbox = models.ForeignKey(
        'containers.ContainerBox',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container Box'),
    )
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    date_available = models.DateTimeField(_(u"Date available"),
                                          default=timezone.now, null=True)
    date_end = models.DateTimeField(_(u"End date"), null=True, blank=True)

    class Meta:
        ordering = ('order',)
        verbose_name = _('Article box articles')
        verbose_name_plural = _('Article boxes articles')

    def __unicode__(self):
        return u"{0}-{1}".format(self.containerbox.slug, self.container.slug)

    def clean(self):

        if not self.container.published:
            raise ValidationError(_(u'Article not published!'))


models.signals.post_delete.connect(delete_container, sender=Container)
<commit_msg>get_absolute_url do not use child_class<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from django.core.cache import cache
from django.utils import timezone
from django.conf import settings

from .signals import shorturl_generate, delete_container
from opps.core.cache import _cache_key
from opps.core.models import Publishable, Slugged, Channeling, Imaged
from opps.boxes.models import BaseBox

from taggit.managers import TaggableManager


class Container(Publishable, Slugged, Channeling, Imaged):
    title = models.CharField(_(u"Title"), max_length=140, db_index=True)
    hat = models.CharField(
        _(u"Hat"),
        max_length=140,
        null=True, blank=True,
    )
    short_url = models.URLField(
        _("Short URL"),
        null=True, blank=True,
    )
    child_class = models.CharField(
        _(u'Child class'),
        max_length=30,
        null=True, blank=True,
        db_index=True
    )
    child_module = models.CharField(
        _(u'Child module'),
        max_length=120,
        null=True, blank=True,
        db_index=True
    )
    child_app_label = models.CharField(
        _(u'Child app label'),
        max_length=30,
        null=True, blank=True,
        db_index=True
    )
    tags = TaggableManager(blank=True, verbose_name=u'Tags')
    show_on_root_channel = models.BooleanField(
        _(u"Show on root channel?"),
        default=True
    )
    sources = models.ManyToManyField(
        'sources.Source',
        null=True, blank=True,
        through='containers.ContainerSource')

    def __unicode__(self):
        return u"{}".format(self.get_absolute_url())

    class Meta:
        ordering = ['-date_available', 'title', 'channel_long_slug']
        verbose_name = _('Container')
        verbose_name_plural = _('Containers')
        unique_together = ("site", "child_class", "channel_long_slug", "slug")

    def save(self, *args, **kwargs):
        self.channel_name = self.channel.name
        self.channel_long_slug = self.channel.long_slug
        self.child_class = self.__class__.__name__
        self.child_module = self.__class__.__module__
        self.child_app_label = self._meta.app_label

        models.signals.post_save.connect(shorturl_generate,
                                         sender=self.__class__)
        super(Container, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return u"/{}/{}".format(self.channel_long_slug, self.slug)

    def get_thumb(self):
        return self.main_image

    @property
    def search_category(self):
        """for use in search result"""
        return _(self.child_class)

    def get_http_absolute_url(self):
        return "http://{}{}".format(self.site_domain, self.get_absolute_url())
    get_http_absolute_url.short_description = 'URL'

    def recommendation(self):

        now = timezone.now()
        start = now - timezone.timedelta(
            days=settings.OPPS_RECOMMENDATION_RANGE_DAYS
        )

        cachekey = _cache_key(
            '{}-recommendation'.format(self.__class__.__name__),
            self.__class__, self.site_domain,
            u"{}-{}".format(self.channel_long_slug, self.slug))
        getcache = cache.get(cachekey)
        if getcache:
            return getcache

        tag_list = [t for t in self.tags.all()[:3]]
        _list = [a for a in Container.objects.filter(
            site_domain=self.site_domain,
            child_class=self.child_class,
            channel_long_slug=self.channel_long_slug,
            date_available__range=(start, now),
            published=True,
            tags__in=tag_list
        ).exclude(pk=self.pk).distinct().order_by('-date_available')[:10]]

        cache.set(cachekey, _list)
        return _list


# DOES NOT WORKS, IT CREATES A TABLE WITH A WRONG NAME
# class ContainerThrough(models.Model):
#     container = models.ForeignKey(
#         'containers.Container',
#         null=True, blank=True,
#         on_delete=models.SET_NULL,
#         verbose_name=_(u'Container'),
#     )
#     order = models.PositiveIntegerField(_(u'Order'), default=0)

#     class META:
#         abstract = True


class ContainerSource(models.Model):
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    source = models.ForeignKey(
        'sources.Source',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name='containersource_sources',
        verbose_name=_(u'Source'),
    )

    class META:
        verbose_name = _(u'Container source')
        verbose_name_plural = _(u'Container sources')
        ordering = ('order',)

    def __unicode__(self):
        return u"{}".format(self.source.slug)


class ContainerImage(models.Model):
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    image = models.ForeignKey(
        'images.Image',
        verbose_name=_(u'Image'),
        null=True, blank=True,
        on_delete=models.SET_NULL
    )

    caption = models.CharField(
        _(u"Caption"),
        max_length=255,
        blank=True,
        null=True
    )

    class META:
        verbose_name = _('Container image')
        verbose_name_plural = _('Container images')
        ordering = ('order',)

    def __unicode__(self):
        return u"{}".format(self.image.title)


class ContainerBox(BaseBox):

    title = models.CharField(
        _(u"Title"),
        null=True,
        blank=True,
        max_length=140,
    )
    containers = models.ManyToManyField(
        'containers.Container',
        null=True, blank=True,
        verbose_name=_(u'Container'),
        related_name='containerbox_containers',
        through='containers.ContainerBoxContainers'
    )
    queryset = models.ForeignKey(
        'boxes.QuerySet',
        null=True, blank=True,
        related_name='containerbox_querysets',
        verbose_name=_(u'Query Set')
    )

    class META:
        verbose_name = _('Container box')
        verbose_name_plural = _('Containers boxes')

    def ordered_containers(self, field='order'):
        now = timezone.now()
        qs = self.containers.filter(
            published=True,
            date_available__lte=now,
            containerboxcontainers__date_available__lte=now
        ).filter(
            models.Q(containerboxcontainers__date_end__gte=now) |
            models.Q(containerboxcontainers__date_end__isnull=True)
        )
        return qs.order_by('containerboxcontainers__order'
                           ).distinct()

    def get_queryset(self):
        """
        for backwards compatibility
        """
        return self.queryset.get_queryset()


class ContainerBoxContainers(models.Model):
    containerbox = models.ForeignKey(
        'containers.ContainerBox',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container Box'),
    )
    container = models.ForeignKey(
        'containers.Container',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_(u'Container'),
    )
    order = models.PositiveIntegerField(_(u'Order'), default=0)
    date_available = models.DateTimeField(_(u"Date available"),
                                          default=timezone.now, null=True)
    date_end = models.DateTimeField(_(u"End date"), null=True, blank=True)

    class Meta:
        ordering = ('order',)
        verbose_name = _('Article box articles')
        verbose_name_plural = _('Article boxes articles')

    def __unicode__(self):
        return u"{0}-{1}".format(self.containerbox.slug, self.container.slug)

    def clean(self):

        if not self.container.published:
            raise ValidationError(_(u'Article not published!'))


models.signals.post_delete.connect(delete_container, sender=Container)

{'fraction_non_alphanumeric': 0.11302270011947431, 'fraction_numerical': 0.0034647550776583033, 'mean_word_length': 2.5878696956708103, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5292658', 'n_tokens_mistral': 5105, 'n_tokens_neox': 4958, 'n_words': 889}