Skip to content

Commit 6f19764

Browse files
authored
Merge pull request #147 from dtinit/fix-analytics
fix(analytics): Optimize memory usage in analytics view
2 parents 149f6ee + c00fd20 commit 6f19764

File tree

1 file changed

+56
-48
lines changed

1 file changed

+56
-48
lines changed

portmap/core/admin.py

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -103,59 +103,67 @@ def analytics(request):
103103
datatype_interest_counts = {}
104104
datatype_provider_query_counts = {}
105105

106-
for article in Article.objects.all():
107-
if article.datatype not in datatype_interest_counts:
108-
datatype_interest_counts[article.datatype] = {
109-
'views': 0,
110-
'queries': 0
111-
}
112-
113-
for query in QueryLog.objects.all():
114-
# Query logs have datatypes stored
115-
# with underscores instead of spaces
106+
for datatype in Article.datatypes().values_list('datatype', flat=True):
107+
datatype_interest_counts[datatype] = {
108+
'views': 0,
109+
'queries': 0
110+
}
111+
112+
# Process query logs
113+
for query in QueryLog.objects.iterator():
116114
datatype_name = " ".join(query.datatype.split("_"))
117115
if datatype_name in datatype_interest_counts:
118-
datatype_interest_counts[datatype_name]['queries'] += 1
119-
120-
if datatype_name not in datatype_provider_query_counts:
121-
datatype_provider_query_counts[datatype_name] = {
122-
'sources': {},
123-
'destinations': {},
124-
'transitions': {}
125-
}
126-
if query.source in datatype_provider_query_counts[datatype_name]['sources']:
127-
datatype_provider_query_counts[datatype_name]['sources'][query.source] += 1;
128-
else:
129-
datatype_provider_query_counts[datatype_name]['sources'][query.source] = 1;
130-
131-
destination = query.destination if query.destination else 'None selected'
132-
if destination in datatype_provider_query_counts[datatype_name]['destinations']:
133-
datatype_provider_query_counts[datatype_name]['destinations'][destination] += 1;
134-
else:
135-
datatype_provider_query_counts[datatype_name]['destinations'][destination] = 1;
136-
137-
transition = query.source + ' -> ' + destination
138-
139-
if transition in datatype_provider_query_counts[datatype_name]['transitions']:
140-
datatype_provider_query_counts[datatype_name]['transitions'][transition] += 1
141-
else:
142-
datatype_provider_query_counts[datatype_name]['transitions'][transition] = 1
143-
144-
for view in TrackArticleView.objects.select_related("article").all():
145-
datatype_interest_counts[view.article.datatype]['views'] += 1
146-
147-
148-
sentiment_query = Article.objects.annotate(happy_count=Count("feedback", filter=Q(feedback__reaction='happy')),
149-
sad_count = Count("feedback", filter=Q(feedback__reaction='sad')))
150-
article_sentiment = [{'name': article.name,
151-
'title': textwrap.shorten(article.title, width=50),
152-
'happy_count': range(article.happy_count),
153-
'sad_count': range(article.sad_count)} for article in sentiment_query.order_by('-sad_count')]
154-
116+
datatype_interest_counts[datatype_name]['queries'] += 1
117+
118+
if datatype_name not in datatype_provider_query_counts:
119+
datatype_provider_query_counts[datatype_name] = {
120+
'sources': {},
121+
'destinations': {},
122+
'transitions': {}
123+
}
124+
125+
sources = datatype_provider_query_counts[datatype_name]['sources']
126+
sources[query.source] = sources.get(query.source, 0) + 1
127+
128+
# Update destination counts
129+
destination = query.destination if query.destination else 'None selected'
130+
destinations = datatype_provider_query_counts[datatype_name]['destinations']
131+
destinations[destination] = destinations.get(destination, 0) + 1
132+
133+
# Update transition counts
134+
transition = f"{query.source} -> {destination}"
135+
transitions = datatype_provider_query_counts[datatype_name]['transitions']
136+
transitions[transition] = transitions.get(transition, 0) + 1
137+
138+
# Count views using database aggregation
139+
view_counts = (TrackArticleView.objects
140+
.values('article__datatype')
141+
.annotate(total=Count('id')))
142+
143+
for vc in view_counts:
144+
datatype = vc['article__datatype']
145+
if datatype in datatype_interest_counts:
146+
datatype_interest_counts[datatype]['views'] = vc['total']
147+
148+
sentiment_query = (Article.objects
149+
.values('name', 'title')
150+
.annotate(
151+
happy_count=Count('feedback', filter=Q(feedback__reaction='happy')),
152+
sad_count=Count('feedback', filter=Q(feedback__reaction='sad'))
153+
)
154+
.order_by('-sad_count'))
155+
156+
article_sentiment = [{
157+
'name': article['name'],
158+
'title': textwrap.shorten(article['title'], width=50),
159+
'happy_count': range(article['happy_count']),
160+
'sad_count': range(article['sad_count'])
161+
} for article in sentiment_query]
155162

156163
stats = json.dumps({
157164
'datatypeInterest': datatype_interest_counts,
158165
'providerQueriesByDatatype': datatype_provider_query_counts
159166
})
160167

161-
return TemplateResponse(request, "admin/analytics.html", {'stats': stats, 'article_sentiment': article_sentiment})
168+
return TemplateResponse(request, "admin/analytics.html",
169+
{'stats': stats, 'article_sentiment': article_sentiment})

0 commit comments

Comments
 (0)