Skip to content

Commit 4d0bc64

Browse files
committed
api: refactor sort and order, remove "all entries" route
1 parent e9dead7 commit 4d0bc64

File tree

1 file changed

+34
-83
lines changed

1 file changed

+34
-83
lines changed

hhub/views.py

Lines changed: 34 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22

3-
from django.core.exceptions import FieldError
43
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
54
from django.db.models import F, Q
65
from django.http import JsonResponse
@@ -28,7 +27,7 @@ def entry_manifest(request, pk):
2827

2928
# Manifests need to stay on disk (and not serialized/deserialized from db)
3029
# because that way they can be versioned and modified through PRs
31-
data = open(f"db-sources/{entry.basepath}/{pk}/game.json").read()
30+
data = open(f"db-sources/{entry.basepath}/entries/{pk}/game.json").read()
3231
json_data = json.loads(data)
3332

3433
# Enrich the manifest with some values available only in the (postgres) database
@@ -38,51 +37,6 @@ def entry_manifest(request, pk):
3837
return JsonResponse(json_data)
3938

4039

41-
def entries_all(request):
42-
sort_by_param = request.GET.get("sort", "")
43-
order_by_param = request.GET.get("order_by", "")
44-
num_elements = request.GET.get("results", 10)
45-
46-
entries = Entry.objects.all()
47-
48-
# sort and order
49-
try:
50-
entries = sort_and_order(entries, order_by_param, sort_by_param)
51-
except FieldError as e:
52-
return JsonResponse({"error": str(e)}, status=400)
53-
54-
paginator = Paginator(entries, num_elements)
55-
page = request.GET.get("page", 1)
56-
57-
results = len(entries)
58-
try:
59-
entries = paginator.page(page)
60-
except PageNotAnInteger:
61-
entries = paginator.page(1)
62-
page = 1
63-
except EmptyPage:
64-
entries = paginator.page(paginator.num_pages)
65-
page = paginator.num_pages
66-
67-
serializer = EntrySerializer(entries, many=True)
68-
69-
json_entries = []
70-
for entry in entries:
71-
data = open(f"db-sources/{entry.basepath}/{entry.slug}/game.json").read()
72-
json_entries.append(json.loads(data))
73-
return JsonResponse(
74-
{
75-
"results": results,
76-
"page_total": paginator.num_pages,
77-
"page_current": page,
78-
"page_elements": len(serializer.data),
79-
"entries": json_entries,
80-
},
81-
safe=False,
82-
)
83-
return JsonResponse(serializer.data, safe=False)
84-
85-
8640
def search_entries(request):
8741
"""
8842
Returns every entry matching the conditions given in the query
@@ -108,8 +62,12 @@ def search_entries(request):
10862
num_elements = request.GET.get("results", 10)
10963

11064
# Order and sort
111-
order_by_param = request.GET.get("order_by", "")
112-
sort_by_param = request.GET.get("sort", "")
65+
66+
# Ordering key
67+
# by default, sort by date of addition to the database
68+
sort_key = request.GET.get("sort", "firstadded_date")
69+
# Direction of desired ordering (ascending or descending)
70+
order = request.GET.get("order", "desc")
11371

11472
# Start by selecting everything
11573
entries = Entry.objects.all()
@@ -123,10 +81,6 @@ def search_entries(request):
12381
if thirdparty:
12482
entries = entries.filter(thirdparty__contains=[thirdparty])
12583

126-
# sort and order
127-
if sort_by_param:
128-
entries = sort_and_order(entries, order_by_param, sort_by_param)
129-
13084
if developer:
13185
entries = entries.filter(developer=developer)
13286

@@ -151,6 +105,8 @@ def search_entries(request):
151105

152106
if random_query:
153107
entries = entries.order_by("?")
108+
else:
109+
entries = sort_entries(entries, sort_key, order)
154110

155111
# Prepare paginators and number of results
156112
paginator = Paginator(entries, num_elements)
@@ -170,11 +126,16 @@ def search_entries(request):
170126
# Read from disks the manifests of the result entries
171127
json_entries = []
172128
for entry in entries:
173-
data = open(f"db-sources/{entry.basepath}/{entry.slug}/game.json").read()
129+
data = open(
130+
f"db-sources/{entry.basepath}/entries/{entry.slug}/game.json"
131+
).read()
174132
json_data = json.loads(data)
175133
# Enrich the manifest with some values available only in the (postgres) database
176-
json_data["basepath"] = entry.basepath
177-
json_entries.append(json_data)
134+
additional_json_data = {
135+
"basebath": entry.basepath,
136+
"firstadded_date": entry.firstadded_date,
137+
}
138+
json_entries.append({**json_data, **additional_json_data})
178139

179140
# Prepare final JSON response
180141
return JsonResponse(
@@ -187,6 +148,8 @@ def search_entries(request):
187148
"page_current": int(page),
188149
# number of elements in this page
189150
"page_elements": len(serializer.data),
151+
"sort": sort_key,
152+
"order": order,
190153
# array of entries manifests
191154
"entries": json_entries,
192155
},
@@ -229,33 +192,21 @@ def stats(request):
229192

230193

231194
# Utils
232-
def sort_and_order(entries, col_name, sort_by_param):
195+
def sort_entries(entries, sort_key, direction="asc"):
233196
# regardless what user has submitted, we lowercase the input
234-
col_name = col_name.lower().strip()
235-
sort_by_param = sort_by_param.lower().strip()
236-
237-
# If no column name has been passed, sort the results by most recent
238-
if col_name == "":
239-
col_name = "published_date"
240-
sort_by_param = "desc"
241-
242-
# if col_name has been specified and it is in allowed list of fields,
243-
# check if sort has been specified
244-
if col_name in ["slug", "title", "published_date"]:
245-
if sort_by_param in ["", "asc", "desc"]:
246-
if sort_by_param == "asc" or not sort_by_param:
247-
return entries.order_by(F(col_name).asc(nulls_last=True))
248-
elif sort_by_param == "desc":
249-
return entries.order_by(F(col_name).desc(nulls_last=True))
250-
else:
251-
return entries.order_by(col_name)
252-
elif sort_by_param in ["", "asc", "desc"]:
253-
# default sorting: slug, asc order
254-
if sort_by_param == "asc" or not sort_by_param:
255-
return entries.order_by("slug")
256-
elif sort_by_param == "desc":
257-
# minus here means "desc" order, according to
258-
# https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
259-
return entries.order_by("-slug")
197+
sort_key = sort_key.lower().strip()
198+
direction = direction.lower().strip()
199+
200+
allowed_keys = ["slug", "title", "published_date", "firstadded_date"]
201+
202+
if sort_key not in allowed_keys:
203+
sort_key = "firstadded_date"
204+
if direction not in ["asc", "desc"]:
205+
direction = "asc"
206+
207+
if direction == "asc":
208+
return entries.order_by(F(sort_key).asc(nulls_last=True))
209+
else:
210+
return entries.order_by(F(sort_key).desc(nulls_last=True))
260211

261212
return entries

0 commit comments

Comments
 (0)