| Index: appengine/swarming/server/bot_management.py | 
| diff --git a/appengine/swarming/server/bot_management.py b/appengine/swarming/server/bot_management.py | 
| index feff1773397b570f2ff84e94429fc4195d6db657..6a01af7ae72f41ba6f391e19d4072b35099d7d51 100644 | 
| --- a/appengine/swarming/server/bot_management.py | 
| +++ b/appengine/swarming/server/bot_management.py | 
| @@ -28,6 +28,7 @@ | 
| entities which are generated from data provided by the bot itself. | 
| """ | 
|  | 
| +import datetime | 
| import hashlib | 
|  | 
| from google.appengine.ext import ndb | 
| @@ -267,6 +268,30 @@ def get_settings_key(bot_id): | 
| return ndb.Key(BotSettings, 'settings', parent=get_root_key(bot_id)) | 
|  | 
|  | 
| +def filter_dimensions(q, dimensions): | 
| +  """Filters a ndb.Query for BotInfo based on dimensions in the request.""" | 
| +  for d in dimensions: | 
| +    parts = d.split(':', 1) | 
| +    if len(parts) != 2 or any(i.strip() != i or not i for i in parts): | 
| +      raise ValueError('Invalid dimensions') | 
| +    q = q.filter(BotInfo.dimensions_flat == d) | 
| +  return q | 
| + | 
| + | 
| +def filter_availability(q, quarantined, is_dead, now): | 
| +  """Filters a ndb.Query for BotInfo based on quarantined/is_dead.""" | 
| +  if quarantined is not None: | 
| +    q = q.filter(BotInfo.quarantined == quarantined) | 
| + | 
| +  dt = datetime.timedelta(seconds=config.settings().bot_death_timeout_secs) | 
| +  timeout = now - dt | 
| +  if is_dead: | 
| +    q = q.filter(BotInfo.last_seen_ts < timeout) | 
| +  elif is_dead is not None: | 
| +    q = q.filter(BotInfo.last_seen_ts > timeout) | 
| +  return q | 
| + | 
| + | 
| def bot_event( | 
| event_type, bot_id, external_ip, authenticated_as, dimensions, state, | 
| version, quarantined, task_id, task_name, **kwargs): | 
|  |