Baby Language Lab Scripts
A collection of data processing tools.
 All Classes Namespaces Files Functions Variables Pages
check.py
Go to the documentation of this file.
1 ## @package data_structs.check
2 
3 from data_structs.base_objects import DBObject
4 from data_structs.seg_filters import *
5 from db.bll_database import DBConstants
6 from datetime import datetime
7 from data_structs.test import Test
8 
9 ## A saved collection of settings that can be used to generate stats from a TRS file (for the Reliability App).
10 class Check(DBObject):
11  ## Constructor
12  # @param self
13  # @param name (string) user-defined name for this check
14  # @input_filename (string) absolute path to the trs/csv file that this check will be run on
15  # @wav_filename (string) absolute path to the wav file that this check will use
16  # @num_segs (int) integer representing the upper limit on the number of segs that can be picked (takes precidence over previous param when limit is exceeded). WIll be set to 0 if no limit is to be enforced.
17  # @param default_context_padding (int) number of seconds to pad sound clip, on each side, when context is being used
18  # @param completed (string=None) timestamp string representing the date/time of this check's first run. In general, code should not set this. It's set from db_select(). Will be None if this check has not yet been run.
19  # @param db_id (int=None) Primary key value of this check in the Checks database table. In general, code should not set this. It's set from db_select(), and upon db_insert(). Will be None if object is not yet in the DB.
20  # @param filters (list=[]) List of SegFilter objects to filter the segments from the trs file before picking the clips to test on.
21  # @param pick_randomly (boolean=False) Set to True if user elected to randomly pick segments, False if they want continuous segments to be used.
22  # @param last_run (string=None) String timestamp representing the last time this check was run. Set to None if it has never been run before.
23  def __init__(self,
24  name,
25  input_filename,
26  wav_filename,
27  num_segs,
28  default_context_padding,
29  tests,
30  test_index,
31  completed=None,
32  created=None,
33  db_id=None,
34  filters=[],
35  pick_randomly=False,
36  last_run=None):
37 
38  super(Check, self).__init__()
39 
40  self.name = name
41  self.created = created
42  self.input_filename = input_filename
43  self.wav_filename = wav_filename
44  self.num_segs = num_segs
45  self.default_context_padding = default_context_padding
46  self.tests = tests
47  self.test_index = test_index
48  self.completed = completed
49  self.db_id = db_id
50  self.filters = filters
51  self.pick_randomly = pick_randomly
52  self.last_run = last_run
53 
54  ## See superclass description.
55  def db_insert(self, db):
56  super(Check, self).db_insert(db)
57 
58  cols = 'name input_filename wav_filename num_segs default_context_padding test_index completed pick_randomly'.split()
59  row = [self.name, self.input_filename, self.wav_filename, self.num_segs, self.default_context_padding, self.test_index, self.completed, self.pick_randomly]
60 
61  #grab the last inserted id and use it to assign this object's db_id
62  last_ids = db.insert('checks', cols, [row])
63  self.db_id = last_ids[0]
64 
65  #insert this object's filters, if they haven't already been inserted
66  for cur_filter in self.filters:
67  if cur_filter.db_id == None:
68  cur_filter.db_insert(db)
69 
70  #always insert a row in this relational table, to link this check to its filters
71  db.insert('checks_to_seg_filters', 'seg_filter_id check_id'.split(), [[cur_filter.db_id, self.db_id]])
72 
73  #this will also update the corresponding attribute in self
74  self._update_timestamp('last_run', db)
75 
76  #we allow the DB to set the created timestamp - we do an additional select here to retrieve it right after the row was inserted
77  #Note 1: The DB stores all timestamps in GMT format. When selecting, we must convert back to local time zone (datetime function does this)
78  #Note 2: for some reason, sqlite complains if id param is not a string
79  checks_rows = db.select('checks', ["datetime(created,'localtime')"], 'id=?', [str(self.db_id)])
80  self.created = datetime.strptime(checks_rows[0][0], DBConstants.DB_DATETIME_FMT)
81 
82  for cur_test in self.tests:
83  if cur_test.db_id == None:
84  cur_test.db_insert(db)
85 
86  ## See superclass description.
87  # @returns (int) the number of rows that were soft deleted.
88  def db_delete(self, db):
89  super(Check, self).db_delete(db)
90 
91  #this will cascade and delete from checks_to_seg_filters table
92  for cur_filter in self.filters:
93  cur_filter.db_delete(db)
94 
95  for cur_test in self.tests:
96  cur_test.db_delete(db)
97 
98  #this will cascade and delete from tests table
99  rows = db.delete('checks', 'id=?', [self.db_id])
100 
101  self.db_id = None
102 
103  return rows
104 
105  ## See superclass description.
106  # @returns (list) list of Check objects
107  @staticmethod
108  def db_select(db, ids=[]):
109  DBObject.db_select(db, ids)
110 
111  #build the SQL where clause using the ids passed in
112  where_cond = None
113  if ids:
114  where_cond = DBObject._build_where_cond_from_ids(ids)
115 
116  #perform the select and create Check objects for each row
117  rows = db.select('checks', 'name input_filename wav_filename num_segs default_context_padding test_index datetime(completed,\'localtime\') datetime(created,\'localtime\') id pick_randomly datetime(last_run,\'localtime\')'.split(), where_cond)
118  checks = []
119  for cur_row in rows:
120  check_id = cur_row[8]
121  #select the corresponding filters via a relation table
122  filters = SegFilter.db_select_by_ref(db, 'checks_to_seg_filters', 'seg_filter_id', 'check_id', check_id)
123 
124  tests = Test.db_select_by_check(db, cur_row[8])
125 
126  checks.append( Check(cur_row[0],
127  cur_row[1],
128  cur_row[2],
129  cur_row[3],
130  cur_row[4],
131  tests,
132  cur_row[5],
133  datetime.strptime(cur_row[6], DBConstants.DB_DATETIME_FMT) if cur_row[6] != None else None,
134  datetime.strptime(cur_row[7], DBConstants.DB_DATETIME_FMT) if cur_row[7] != None else None,
135  cur_row[8],
136  pick_randomly=bool(int(cur_row[9])),
137  last_run=datetime.strptime(cur_row[10], DBConstants.DB_DATETIME_FMT) if cur_row[10] != None else None,
138  filters=filters) )
139 
140  return checks
141 
142  ## Updates a timestamp column in the DB, and in this object instance. If the instance is not in the database, an exception is raised.
143  # @param self
144  # @param attr_name (string) name of the instance attribute we will be updating - this name must match the name of the column in the DB checks table.
145  # @param db (BLLDatabase) a database instance
146  def _update_timestamp(self, attr_name, db): #attr name must match db col name
147  if self.db_id != None:
148  #allow the DB to insert the timestamp
149  db.update_timestamp_col('checks', attr_name, 'id=?', [self.db_id])
150 
151  #select the timestamp and convert it to localtime
152  rows = db.select('checks', ["datetime(%s,'localtime')" % (attr_name)], 'id=?', [self.db_id])
153  #convert it to a more readable format for display in the UI
154  setattr(self, attr_name, datetime.strptime(rows[0][0], DBConstants.DB_DATETIME_FMT))
155  else:
156  raise Exception('Cannot update timestamp because Check object is not in the database.')
157 
158  ## Sets the 'completed' attribute (a timestamp in string form) of this Check to the current date/time
159  # @param self
160  # @param db (BLLDatabase) the DB handle object to use for the update operation
161  def mark_as_completed(self, db):
162  self._update_timestamp('completed', db)
163 
164  ## Updates the "last run" attribute/database column value.
165  # @param self
166  # @param db (BLLDatabase) the DB handle object to use for the update operation
167  def mark_last_run(self, db):
168  self._update_timestamp('last_run', db)
169 
170  ## Updates the test_index property/database column value. This allows us to restore a saved check to the position where the user left off. If the instance is not in the database, an exception is raised.
171  # @param self
172  # @param db (BLLDatabase) the DB handle object to use for the update operation
173  def db_update_test_index(self, db):
174  if self.db_id != None:
175  db.update('checks', ['test_index'], 'id=?', [self.test_index, self.db_id])
176  else:
177  raise Exception('Cannot update test_index because Check instance is not in the database.')