forked from readthedocs/readthedocs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.py
96 lines (79 loc) · 2.92 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""Search Queries."""
from django.db import models
from django.db.models import Count
from django.db.models.functions import TruncDate
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django_extensions.db.models import TimeStampedModel
from readthedocs.builds.models import Version
from readthedocs.projects.models import Project
from readthedocs.projects.querysets import RelatedProjectQuerySet
from readthedocs.search.utils import _last_30_days_iter
class SearchQuery(TimeStampedModel):
"""Information about the search queries."""
project = models.ForeignKey(
Project,
related_name='search_queries',
on_delete=models.CASCADE,
)
version = models.ForeignKey(
Version,
verbose_name=_('Version'),
related_name='search_queries',
on_delete=models.CASCADE,
)
query = models.CharField(
_('Query'),
max_length=4092,
)
total_results = models.IntegerField(
_('Total results'),
default=0,
)
objects = RelatedProjectQuerySet.as_manager()
class Meta:
verbose_name = 'Search query'
verbose_name_plural = 'Search queries'
def __str__(self):
return f'[{self.project.slug}:{self.version.slug}]: {self.query}'
@classmethod
def generate_queries_count_of_one_month(cls, project_slug):
"""
Returns the total queries performed each day of the last 30 days (including today).
Structure of returned data is compatible to make graphs.
Sample returned data::
{
'labels': ['01 Jul', '02 Jul', '03 Jul'],
'int_data': [150, 200, 143]
}
This data shows that there were 150 searches were made on 01 July,
200 searches on 02 July and 143 searches on 03 July.
"""
today = timezone.now().date()
last_30th_day = timezone.now().date() - timezone.timedelta(days=30)
qs = cls.objects.filter(
project__slug=project_slug,
created__date__lte=today,
created__date__gte=last_30th_day,
).order_by('-created')
# dict containing the total number of queries
# of each day for the past 30 days (if present in database).
count_dict = dict(
qs.annotate(created_date=TruncDate('created'))
.values('created_date')
.order_by('created_date')
.annotate(count=Count('id'))
.values_list('created_date', 'count')
)
count_data = [count_dict.get(date) or 0 for date in _last_30_days_iter()]
# format the date value to a more readable form
# Eg. `16 Jul`
last_30_days_str = [
timezone.datetime.strftime(date, '%d %b')
for date in _last_30_days_iter()
]
final_data = {
'labels': last_30_days_str,
'int_data': count_data,
}
return final_data