Initial commit
This commit is contained in:
160
env/lib/python3.10/site-packages/wagtail/contrib/search_promotions/models.py
vendored
Normal file
160
env/lib/python3.10/site-packages/wagtail/contrib/search_promotions/models.py
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.search.utils import MAX_QUERY_STRING_LENGTH, normalise_query_string
|
||||
|
||||
|
||||
class Query(models.Model):
|
||||
query_string = models.CharField(max_length=MAX_QUERY_STRING_LENGTH, unique=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Normalise query string
|
||||
self.query_string = normalise_query_string(self.query_string)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def add_hit(self, date=None):
|
||||
if date is None:
|
||||
date = timezone.now().date()
|
||||
daily_hits, created = QueryDailyHits.objects.get_or_create(
|
||||
query=self, date=date
|
||||
)
|
||||
daily_hits.hits = models.F("hits") + 1
|
||||
daily_hits.save()
|
||||
|
||||
def __str__(self):
|
||||
return self.query_string
|
||||
|
||||
@property
|
||||
def hits(self):
|
||||
hits = self.daily_hits.aggregate(models.Sum("hits"))["hits__sum"]
|
||||
return hits if hits else 0
|
||||
|
||||
@classmethod
|
||||
def garbage_collect(cls):
|
||||
"""
|
||||
Deletes all Query records that have no daily hits or editors picks
|
||||
"""
|
||||
extra_filter_kwargs = (
|
||||
{
|
||||
"editors_picks__isnull": True,
|
||||
}
|
||||
if hasattr(cls, "editors_picks")
|
||||
else {}
|
||||
)
|
||||
cls.objects.filter(daily_hits__isnull=True, **extra_filter_kwargs).delete()
|
||||
|
||||
@classmethod
|
||||
def get(cls, query_string):
|
||||
return cls.objects.get_or_create(
|
||||
query_string=normalise_query_string(query_string)
|
||||
)[0]
|
||||
|
||||
@classmethod
|
||||
def get_most_popular(cls, date_since=None):
|
||||
objects = cls.objects.filter(daily_hits__isnull=False)
|
||||
|
||||
if date_since:
|
||||
objects = objects.filter(daily_hits__date__gte=date_since)
|
||||
|
||||
return (
|
||||
objects.annotate(_hits=models.Sum("daily_hits__hits"))
|
||||
.distinct()
|
||||
.order_by("-_hits")
|
||||
)
|
||||
|
||||
|
||||
class QueryDailyHits(models.Model):
|
||||
query = models.ForeignKey(
|
||||
Query, db_index=True, related_name="daily_hits", on_delete=models.CASCADE
|
||||
)
|
||||
date = models.DateField()
|
||||
hits = models.IntegerField(default=0)
|
||||
|
||||
@classmethod
|
||||
def garbage_collect(cls, days=None):
|
||||
"""
|
||||
Deletes all QueryDailyHits records that are older than a set number of days
|
||||
"""
|
||||
days = (
|
||||
getattr(settings, "WAGTAILSEARCH_HITS_MAX_AGE", 7) if days is None else days
|
||||
)
|
||||
min_date = timezone.now().date() - datetime.timedelta(days)
|
||||
|
||||
cls.objects.filter(date__lt=min_date).delete()
|
||||
|
||||
class Meta:
|
||||
unique_together = (("query", "date"),)
|
||||
verbose_name = _("Query Daily Hits")
|
||||
verbose_name_plural = _("Query Daily Hits")
|
||||
|
||||
|
||||
class SearchPromotion(models.Model):
|
||||
query = models.ForeignKey(
|
||||
Query, db_index=True, related_name="editors_picks", on_delete=models.CASCADE
|
||||
)
|
||||
page = models.ForeignKey(
|
||||
"wagtailcore.Page",
|
||||
verbose_name=_("page"),
|
||||
help_text=_("Choose an internal page for this promotion"),
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
external_link_url = models.URLField(
|
||||
_("External link URL"),
|
||||
help_text=_("Alternatively, use an external link for this promotion"),
|
||||
blank=True,
|
||||
)
|
||||
external_link_text = models.CharField(
|
||||
max_length=200,
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
description = models.TextField(
|
||||
verbose_name=_("description"),
|
||||
help_text=_("Applies to internal page or external link"),
|
||||
blank=True,
|
||||
)
|
||||
sort_order = models.IntegerField(null=True, blank=True, editable=False)
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
if self.page:
|
||||
prop = self.page.title
|
||||
else:
|
||||
prop = self.external_link_text
|
||||
return prop
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
if self.page:
|
||||
prop = self.page
|
||||
else:
|
||||
prop = self.external_link_url
|
||||
return prop
|
||||
|
||||
def __repr__(self):
|
||||
if self.page:
|
||||
label = "page"
|
||||
else:
|
||||
label = "external link"
|
||||
|
||||
return (
|
||||
'SearchPromotion(query="'
|
||||
+ self.query.query_string
|
||||
+ f'", {label}="'
|
||||
+ self.title
|
||||
+ '")'
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.query.query_string} - {self.title}"
|
||||
|
||||
class Meta:
|
||||
ordering = ("sort_order",)
|
||||
verbose_name = _("search promotion")
|
||||
Reference in New Issue
Block a user