1+ from __future__ import unicode_literals
2+
13import struct
24from random import choice
35from os import path , makedirs
@@ -28,17 +30,22 @@ class QuickDrawData():
2830 anvil = qd.get_drawing("anvil")
2931 anvil.image.save("my_anvil.gif")
3032
33+ :param bool recognized:
34+ If ``True`` only recognized drawings will be loaded, if ``False``
35+ only unrecognized drawings will be loaded, if ``None`` (the default)
36+ both recognized and unrecognized drawings will be loaded.
37+
3138 :param int max_drawings:
3239 The maximum number of drawings to be loaded into memory,
3340 defaults to 1000.
3441
3542 :param bool refresh_data:
36- If `True` forces data to be downloaded even if it has been
37- downloaded before, defaults to `False`.
43+ If `` True` ` forces data to be downloaded even if it has been
44+ downloaded before, defaults to `` False` `.
3845
3946 :param bool jit_loading:
40- If `True` (the default) only downloads and loads data into
41- memory when it is required (jit = just in time). If `False`
47+ If `` True` ` (the default) only downloads and loads data into
48+ memory when it is required (jit = just in time). If `` False` `
4249 all drawings will be downloaded and loaded into memory.
4350
4451 :param bool print_messages:
@@ -49,7 +56,16 @@ class QuickDrawData():
4956 Specify a cache directory to use when downloading data files,
5057 defaults to `./.quickdrawcache`.
5158 """
52- def __init__ (self , max_drawings = 1000 , refresh_data = False , jit_loading = True , print_messages = True , cache_dir = CACHE_DIR ):
59+ def __init__ (
60+ self ,
61+ recognized = None ,
62+ max_drawings = 1000 ,
63+ refresh_data = False ,
64+ jit_loading = True ,
65+ print_messages = True ,
66+ cache_dir = CACHE_DIR ):
67+
68+ self ._recognized = recognized
5369 self ._print_messages = print_messages
5470 self ._refresh_data = refresh_data
5571 self ._max_drawings = max_drawings
@@ -74,7 +90,7 @@ def get_drawing(self, name, index=None):
7490 :param int index:
7591 The index of the drawing to get.
7692
77- If `None` (the default) a random drawing will be returned.
93+ If `` None` ` (the default) a random drawing will be returned.
7894 """
7995 return self .get_drawing_group (name ).get_drawing (index )
8096
@@ -91,6 +107,7 @@ def get_drawing_group(self, name):
91107 if name not in self ._drawing_groups .keys ():
92108 drawings = QuickDrawDataGroup (
93109 name ,
110+ recognized = self ._recognized ,
94111 max_drawings = self ._max_drawings ,
95112 refresh_data = self ._refresh_data ,
96113 print_messages = self ._print_messages ,
@@ -99,11 +116,58 @@ def get_drawing_group(self, name):
99116
100117 return self ._drawing_groups [name ]
101118
119+ def search_drawings (self , name , key_id = None , recognized = None , countrycode = None , timestamp = None ):
120+ """
121+ Search the drawings.
122+
123+ Returns an list of :class:`QuickDrawing` instances representing the
124+ matched drawings.
125+
126+ Note - search criteria are a compound.
127+
128+ Search for all the drawings with the ``countrycode`` "PL" ::
129+
130+ from quickdraw import QuickDrawDataGroup
131+
132+ anvils = QuickDrawDataGroup("anvil")
133+ results = anvils.search_drawings(countrycode="PL")
134+
135+ :param string name:
136+ The name of the drawings (anvil, ant, aircraft, etc)
137+ to search.
138+
139+ :param int key_id:
140+ The ``key_id`` to such for. If ``None`` (the default) the
141+ ``key_id`` is not used.
142+
143+ :param bool recognized:
144+ To search for drawings which were ``recognized``. If ``None``
145+ (the default) ``recognized`` is not used.
146+
147+ :param str countrycode:
148+ To search for drawings which with the ``countrycode``. If
149+ ``None`` (the default) ``countrycode`` is not used.
150+
151+ :param int countrycode:
152+ To search for drawings which with the ``timestamp``. If ``None``
153+ (the default) ``timestamp`` is not used.
154+ """
155+ return self .get_drawing_group (name ).search_drawings (key_id , recognized , countrycode , timestamp )
156+
102157 def load_all_drawings (self ):
103158 """
104159 Loads (and downloads if required) all drawings into memory.
105160 """
106- for drawing_group in QUICK_DRAWING_NAMES :
161+ self .load_drawings (self .drawing_names )
162+
163+ def load_drawings (self , list_of_drawings ):
164+ """
165+ Loads (and downloads if required) all drawings into memory.
166+
167+ :param list list_of_drawings:
168+ A list of the drawings to be loaded (anvil, ant, aircraft, etc).
169+ """
170+ for drawing_group in list_of_drawings :
107171 self .get_drawing_group (drawing_group )
108172
109173 @property
@@ -113,6 +177,13 @@ def drawing_names(self):
113177 """
114178 return QUICK_DRAWING_NAMES
115179
180+ @property
181+ def loaded_drawings (self ):
182+ """
183+ Returns a list of drawing which have been loaded into memory.
184+ """
185+ return list (self ._drawing_groups .keys ())
186+
116187
117188class QuickDrawDataGroup ():
118189 """
@@ -130,12 +201,17 @@ class QuickDrawDataGroup():
130201 :param string name:
131202 The name of the drawings to be loaded (anvil, ant, aircraft, etc).
132203
204+ :param bool recognized:
205+ If ``True`` only recognized drawings will be loaded, if ``False``
206+ only unrecognized drawings will be loaded, if ``None`` (the default)
207+ both recognized and unrecognized drawings will be loaded.
208+
133209 :param int max_drawings:
134210 The maximum number of drawings to be loaded into memory,
135211 defaults to 1000.
136212
137213 :param bool refresh_data:
138- If `True` forces data to be downloaded even if it has been
214+ If `` True` ` forces data to be downloaded even if it has been
139215 downloaded before, defaults to `False`.
140216
141217 :param bool print_messages:
@@ -144,9 +220,16 @@ class QuickDrawDataGroup():
144220
145221 :param string cache_dir:
146222 Specify a cache directory to use when downloading data files,
147- defaults to `./.quickdrawcache`.
223+ defaults to `` ./.quickdrawcache` `.
148224 """
149- def __init__ (self , name , max_drawings = 1000 , refresh_data = False , print_messages = True , cache_dir = CACHE_DIR ):
225+ def __init__ (
226+ self ,
227+ name ,
228+ recognized = None ,
229+ max_drawings = 1000 ,
230+ refresh_data = False ,
231+ print_messages = True ,
232+ cache_dir = CACHE_DIR ):
150233
151234 if name not in QUICK_DRAWING_NAMES :
152235 raise ValueError ("{} is not a valid google quick drawing" .format (name ))
@@ -155,6 +238,7 @@ def __init__(self, name, max_drawings=1000, refresh_data=False, print_messages=T
155238 self ._print_messages = print_messages
156239 self ._max_drawings = max_drawings
157240 self ._cache_dir = cache_dir
241+ self ._recognized = recognized
158242
159243 self ._drawings = []
160244
@@ -227,21 +311,27 @@ def _load_drawings(self, filename):
227311 y = struct .unpack (fmt , binary_file .read (n_points ))
228312 image .append ((x , y ))
229313
230- self ._drawings .append ({
231- 'key_id' : key_id ,
232- 'countrycode' : countrycode ,
233- 'recognized' : recognized ,
234- 'timestamp' : timestamp ,
235- 'n_strokes' : n_strokes ,
236- 'image' : image
237- })
314+ append_drawing = True
315+ if self ._recognized is not None :
316+ if bool (recognized ) != self ._recognized :
317+ append_drawing = False
318+
319+ if append_drawing :
320+ self ._drawings .append ({
321+ 'key_id' : key_id ,
322+ 'countrycode' : countrycode ,
323+ 'recognized' : recognized ,
324+ 'timestamp' : timestamp ,
325+ 'n_strokes' : n_strokes ,
326+ 'image' : image
327+ })
328+
329+ self ._drawing_count += 1
238330
239331 # nothing left to read
240332 except struct .error :
241333 break
242334
243- self ._drawing_count += 1
244-
245335 self ._print_message ("load complete" )
246336
247337 def _print_message (self , message ):
@@ -270,7 +360,7 @@ def drawings(self):
270360 """
271361 while True :
272362 self ._current_drawing += 1
273- if self ._current_drawing == self ._drawing_count - 1 :
363+ if self ._current_drawing > self ._drawing_count - 1 :
274364 # reached the end to the drawings
275365 self ._current_drawing = 0
276366 raise StopIteration ()
@@ -295,16 +385,72 @@ def get_drawing(self, index=None):
295385 :param int index:
296386 The index of the drawing to get.
297387
298- If `None` (the default) a random drawing will be returned.
388+ If `` None` ` (the default) a random drawing will be returned.
299389 """
300390 if index is None :
301391 return QuickDrawing (self ._name , choice (self ._drawings ))
302392 else :
303- if index < self .drawing_count - 1 :
393+ if index < self .drawing_count :
304394 return QuickDrawing (self ._name , self ._drawings [index ])
305395 else :
306396 raise IndexError ("index {} out of range, there are {} drawings" .format (index , self .drawing_count ))
307397
398+ def search_drawings (self , key_id = None , recognized = None , countrycode = None , timestamp = None ):
399+ """
400+ Searches the drawings in this group.
401+
402+ Returns an list of :class:`QuickDrawing` instances representing the
403+ matched drawings.
404+
405+ Note - search criteria are a compound.
406+
407+ Search for all the drawings with the ``countrycode`` "PL" ::
408+
409+ from quickdraw import QuickDrawDataGroup
410+
411+ anvils = QuickDrawDataGroup("anvil")
412+ results = anvils.search_drawings(countrycode="PL")
413+
414+ :param int key_id:
415+ The ``key_id`` to such for. If ``None`` (the default) the
416+ ``key_id`` is not used.
417+
418+ :param bool recognized:
419+ To search for drawings which were ``recognized``. If ``None``
420+ (the default) ``recognized`` is not used.
421+
422+ :param str countrycode:
423+ To search for drawings which with the ``countrycode``. If
424+ ``None`` (the default) ``countrycode`` is not used.
425+
426+ :param int countrycode:
427+ To search for drawings which with the ``timestamp``. If ``None``
428+ (the default) ``timestamp`` is not used.
429+ """
430+ results = []
431+
432+ for drawing in self .drawings :
433+ match = True
434+ if key_id is not None :
435+ if key_id != drawing .key_id :
436+ match = False
437+
438+ if recognized is not None :
439+ if recognized != drawing .recognized :
440+ match = False
441+
442+ if countrycode is not None :
443+ if countrycode != drawing .countrycode :
444+ match = False
445+
446+ if timestamp is not None :
447+ if timestamp != drawing .timestamp :
448+ match = False
449+
450+ if match :
451+ results .append (drawing )
452+
453+ return results
308454
309455class QuickDrawing ():
310456 """
@@ -335,7 +481,7 @@ def countrycode(self):
335481 """
336482 Returns the country code for the drawing.
337483 """
338- return self ._drawing_data ["countrycode" ]
484+ return self ._drawing_data ["countrycode" ]. decode ( "utf-8" )
339485
340486 @property
341487 def recognized (self ):
0 commit comments