5
5
import collections
6
6
import sys
7
7
import os
8
+ import re
8
9
from datetime import datetime
9
10
import json
10
11
import sqlite3
21
22
22
23
BROWSE_TEMPLATE = 'browse.html'
23
24
24
- #pylint: disable=abstract-method
25
+ _TAG_PREFIX_RE = re .compile (
26
+ r"""^v[0-9]+(?:\.[0-9]+){0,2} # vMAJOR[.MINOR[.PATCH]]
27
+ (?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)? # optional -prerelease
28
+ (?:\+[0-9A-Za-z.-]+)? # optional +build
29
+ """ ,
30
+ re .IGNORECASE | re .VERBOSE ,
31
+ )
25
32
33
+ #pylint: disable=abstract-method
26
34
class BrowseDataRetrievalHandler (tornado .web .RequestHandler ):
27
35
""" Ajax data retrieval handler """
28
36
@@ -185,6 +193,27 @@ def get_columns_from_tuple(db_tuple, counter, all_overview_imgs):
185
193
flight_modes
186
194
], search_only_columns )
187
195
196
+ def is_hashish (q : str ) -> bool :
197
+ """ return true if the string looks like a hash """
198
+ if len (q ) < 4 :
199
+ return False
200
+ hex_chars = set ('0123456789abcdef' )
201
+ return all (c in hex_chars for c in q )
202
+
203
+ def is_tagish (q : str ) -> bool :
204
+ """ return true if the string looks like a tag """
205
+ if not q or q [0 ] not in ('v' , 'V' ):
206
+ return False
207
+ return bool (_TAG_PREFIX_RE .match (q ))
208
+
209
+ def _flatten_strings (maybe_list ):
210
+ """ flatten a list of strings or a single string into a single string list """
211
+ if not maybe_list :
212
+ return []
213
+ if isinstance (maybe_list , (list , tuple )):
214
+ return [str (x ) for x in maybe_list ]
215
+ return [str (maybe_list )]
216
+
188
217
# need to fetch all here, because we will do more SQL calls while
189
218
# iterating (having multiple cursor's does not seem to work)
190
219
db_tuples = cur .fetchall ()
@@ -209,20 +238,37 @@ def get_columns_from_tuple(db_tuple, counter, all_overview_imgs):
209
238
filtered_counter = len (db_tuples )
210
239
else :
211
240
counter = 1
241
+ hash_mode = is_hashish (search_str )
242
+ tag_mode = is_tagish (search_str )
243
+
212
244
for db_tuple in db_tuples :
213
245
counter += 1
214
246
215
247
columns = get_columns_from_tuple (db_tuple , counter , all_overview_imgs )
248
+
216
249
if columns is None :
217
250
continue
218
251
219
- if any (search_str in str (column ).lower () for column in \
220
- (columns .columns , columns .search_only_columns )):
252
+ visible = _flatten_strings (columns .columns )
253
+ hidden = _flatten_strings (columns .search_only_columns )
254
+
255
+ prefix_hit = False
256
+ if tag_mode or hash_mode :
257
+ for col in hidden :
258
+ if col .lower ().startswith (search_str ):
259
+ prefix_hit = True
260
+ break
261
+
262
+ substring_hit = False
263
+ if not prefix_hit :
264
+ haystack = [s .lower () for s in (visible + hidden )]
265
+ substring_hit = any (search_str in s for s in haystack )
266
+
267
+ if prefix_hit or substring_hit :
221
268
if data_start <= filtered_counter < data_start + data_length :
222
269
json_output ['data' ].append (columns .columns )
223
270
filtered_counter += 1
224
271
225
-
226
272
cur .close ()
227
273
con .close ()
228
274
0 commit comments