<commit_before>
from datetime import datetime

from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models.base import ModelBase
from django.template.defaultfilters import truncatewords_html
from django.utils.html import strip_tags
from django.utils.translation import ugettext, ugettext_lazy as _

from mezzanine.core.fields import RichTextField
from mezzanine.core.managers import DisplayableManager
from mezzanine.generic.fields import KeywordsField
from mezzanine.utils.models import base_concrete_model
from mezzanine.utils.urls import slugify


class Slugged(models.Model):
    """
    Abstract model that handles auto-generating slugs.
    """

    title = models.CharField(_("Title"), max_length=100)
    slug = models.CharField(_("URL"), max_length=100, blank=True, null=True)

    class Meta:
        abstract = True
        ordering = ("title",)

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Create a unique slug by appending an index.
        """
        if not self.slug:
            # For custom content types, use the ``Page`` instance for
            # slug lookup.
            concrete_model = base_concrete_model(Slugged, self)
            self.slug = self.get_slug()
            i = 0
            while True:
                if i > 0:
                    if i > 1:
                        self.slug = self.slug.rsplit("-", 1)[0]
                    self.slug = "%s-%s" % (self.slug, i)
                qs = concrete_model.objects.all()
                if self.id is not None:
                    qs = qs.exclude(id=self.id)
                try:
                    qs.get(slug=self.slug)
                except ObjectDoesNotExist:
                    break
                i += 1
        super(Slugged, self).save(*args, **kwargs)

    def natural_key(self):
        return (self.slug,)

    def get_slug(self):
        """
        Allows subclasses to implement their own slug creation logic.
        """
        return slugify(self.title)


CONTENT_STATUS_DRAFT = 1
CONTENT_STATUS_PUBLISHED = 2
CONTENT_STATUS_CHOICES = (
    (CONTENT_STATUS_DRAFT, _("Draft")),
    (CONTENT_STATUS_PUBLISHED, _("Published")),
)


class Displayable(Slugged):
    """
    Abstract model that provides features of a visible page on the
    website such as publishing fields and meta data.
    """

    status = models.IntegerField(_("Status"),
        choices=CONTENT_STATUS_CHOICES, default=CONTENT_STATUS_DRAFT)
    publish_date = models.DateTimeField(_("Published from"),
        help_text=_("With published checked, won't be shown until this time"),
        blank=True, null=True)
    expiry_date = models.DateTimeField(_("Expires on"),
        help_text=_("With published checked, won't be shown after this time"),
        blank=True, null=True)
    description = models.TextField(_("Description"), blank=True)
    keywords = KeywordsField(verbose_name=_("Keywords"))
    short_url = models.URLField(blank=True, null=True)
    site = models.ForeignKey(Site, editable=False)

    objects = DisplayableManager()
    search_fields = {"keywords": 10, "title": 5}

    class Meta:
        abstract = True

    def save(self, update_site=True, *args, **kwargs):
        """
        Set default for ``publsh_date`` and ``description`` if none
        given. Unless the ``update_site`` argument is ``False``, set
        the site to the current site.
        """
        if self.publish_date is None:
            # publish_date will be blank when a blog post is created
            # from the quick blog form in the admin dashboard.
            self.publish_date = datetime.now()
        if not self.description:
            self.description = strip_tags(self.description_from_content())
        if update_site:
            self.site = Site.objects.get_current()
        super(Displayable, self).save(*args, **kwargs)

    def description_from_content(self):<commit_msg>Moved description and keywords fields out of Displayable and into their own MetaData abstract model.<commit_after>
from datetime import datetime

from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models.base import ModelBase
from django.template.defaultfilters import truncatewords_html
from django.utils.html import strip_tags
from django.utils.translation import ugettext, ugettext_lazy as _

from mezzanine.core.fields import RichTextField
from mezzanine.core.managers import DisplayableManager
from mezzanine.generic.fields import KeywordsField
from mezzanine.utils.models import base_concrete_model
from mezzanine.utils.urls import slugify


class Slugged(models.Model):
    """
    Abstract model that handles auto-generating slugs.
    """

    title = models.CharField(_("Title"), max_length=100)
    slug = models.CharField(_("URL"), max_length=100, blank=True, null=True)

    class Meta:
        abstract = True
        ordering = ("title",)

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        """
        Create a unique slug by appending an index.
        """
        if not self.slug:
            # For custom content types, use the ``Page`` instance for
            # slug lookup.
            concrete_model = base_concrete_model(Slugged, self)
            self.slug = self.get_slug()
            i = 0
            while True:
                if i > 0:
                    if i > 1:
                        self.slug = self.slug.rsplit("-", 1)[0]
                    self.slug = "%s-%s" % (self.slug, i)
                qs = concrete_model.objects.all()
                if self.id is not None:
                    qs = qs.exclude(id=self.id)
                try:
                    qs.get(slug=self.slug)
                except ObjectDoesNotExist:
                    break
                i += 1
        super(Slugged, self).save(*args, **kwargs)

    def natural_key(self):
        return (self.slug,)

    def get_slug(self):
        """
        Allows subclasses to implement their own slug creation logic.
        """
        return slugify(self.title)


class MetaData(models.Model):
    """
    Abstract model that provides meta data for content.
    """

    description = models.TextField(_("Description"), blank=True)
    keywords = KeywordsField(verbose_name=_("Keywords"))

    class Meta:
        abstract = True


CONTENT_STATUS_DRAFT = 1
CONTENT_STATUS_PUBLISHED = 2
CONTENT_STATUS_CHOICES = (
    (CONTENT_STATUS_DRAFT, _("Draft")),
    (CONTENT_STATUS_PUBLISHED, _("Published")),
)


class Displayable(Slugged, MetaData):
    """
    Abstract model that provides features of a visible page on the
    website such as publishing fields. Basis of Mezzanine pages and
    blog posts.
    """

    status = models.IntegerField(_("Status"),
        choices=CONTENT_STATUS_CHOICES, default=CONTENT_STATUS_DRAFT)
    publish_date = models.DateTimeField(_("Published from"),
        help_text=_("With published checked, won't be shown until this time"),
        blank=True, null=True)
    expiry_date = models.DateTimeField(_("Expires on"),
        help_text=_("With published checked, won't be shown after this time"),
        blank=True, null=True)
    short_url = models.URLField(blank=True, null=True)
    site = models.ForeignKey(Site, editable=False)

    objects = DisplayableManager()
    search_fields = {"keywords": 10, "title": 5}

    class Meta:
        abstract = True

    def save(self, update_site=True, *args, **kwargs):
        """
        Set default for ``publsh_date`` and ``description`` if none
        given. Unless the ``update_site`` argument is ``False``, set
        the site to the current site.
        """
        if self.publish_date is None:
            # publish_date will be blank when a blog post is created
            # from the quick blog form in the admin dashboard.
            self.publish_date = datetime.now()
        if not self.description:
            self.description = strip_tags(self.description_from_content())
        if update_site:
            self.site = Site.objects.get_current()
        super(Displayable, self).save(*args, **kwargs)

    def description_from_content(self):
{'fraction_non_alphanumeric': 0.09706871696299856, 'fraction_numerical': 0.004084574723690533, 'mean_word_length': 2.5290377278507843, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '779545', 'n_tokens_mistral': 2418, 'n_tokens_neox': 2303, 'n_words': 662}