11import json
22
3- from django .core .exceptions import FieldError
43from django .core .paginator import EmptyPage , PageNotAnInteger , Paginator
54from django .db .models import F , Q
65from 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-
8640def 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