def save_input(self, mark_last_run=False, mark_as_completed=False): cur_test = self.check.tests[self.check.test_index] cur_test.category_input = self.w_form.type_combo.get_model()[ self.w_form.type_combo.get_active()][1] cur_test.is_uncertain = self.w_form.uncertain_checkbox.get_active() cur_test.context_padding = int( self.w_form.context_pad_spinner.get_adjustment().get_value()) cur_test.syllables_w_context = int( self.w_form.syllables_spinner.get_adjustment().get_value()) cur_test.seg.user_adj_start = float( self.w_form.user_start_entry.get_text()) cur_test.seg.user_adj_end = float( self.w_form.user_end_entry.get_text()) cur_test.syllables_wo_context = None if self.wo_context_checkbox.get_active(): cur_test.syllables_wo_context = int( self.wo_form.syllables_spinner.get_adjustment().get_value()) db = BLLDatabase() cur_test.db_update_user_inputs(db) self.check.db_update_test_index(db) if mark_last_run: self.check.mark_last_run(db) if mark_as_completed: self.check.mark_as_completed(db) db.close()
def __init__(self, db, batch_num, participant_num): self.bll_db = BLLDatabase() self.props = PitchStudyProps.db_select(self.bll_db)[0] self.bll_db.close() self.batch_num = batch_num self.participant_num = participant_num self.order_num = 1 self.filename = None self.window = gtk.Window(gtk.WindowType.TOPLEVEL) self.window.set_title('Batch %d' % (batch_num)) #self.window.set_resizable(False) #self.window.connect('delete-event', lambda x, y: True) self.window.connect('destroy', lambda w: self.window.destroy()) self.window.set_border_width(10) self.window.set_size_request(800, 600) vbox = gtk.VBox() self.test_grid = self._get_test_grid(db) self._update_step(db) vbox.pack_start(self.test_grid, True, True, 0) self.test_grid.hide() self.pause_grid = self._get_pause_grid(db) vbox.pack_start(self.pause_grid, True, False, 0) self.pause_grid.show_all() self.window.add(vbox) vbox.show() self.window.show()
def _build_list_store(self): list_store = gtk.ListStore( gobject.TYPE_STRING, #name gobject.TYPE_STRING, #description gobject.TYPE_STRING, #created timestamp gobject.TYPE_STRING, #output names gobject.TYPE_PYOBJECT, #hidden object ) db = BLLDatabase() configs = OutputConfig.db_select(db) for cur_config in configs: output_names = self._get_output_names_str(cur_config.outputs) created_str = UIUtils.get_db_timestamp_str( cur_config.created) if cur_config.created else '-' list_store.append([ cur_config.name, cur_config.desc, created_str, output_names, cur_config, ]) db.close() return list_store
def _create_config(self): if self._validate(): #extract the output objects from the treeview model outputs = [] model = self.outputs_treeview.get_model() row = 0 while row < len(model): outputs.append(model[row][4]) row += 1 name = self.name_entry.get_text() desc = self.desc_entry.get_text() overview = self.output_overview.get_active() db = BLLDatabase() created = None #if editing, delete previous config from DB if self.edit_config: created = self.edit_config.created self.edit_config.db_delete( db ) #this will also delete any associated outputs and entries in output_configs_to_outputs self.edit_config = None config = OutputConfig(name, desc, outputs, created, overview) config.db_insert(db) db.close() self.window.destroy() self.action_callback(config) else: UIUtils.show_message_dialog( 'Please make sure that all of the fields have been filled out.', gtk.MessageType.WARNING)
def _build_treeview(self): list_store = gtk.ListStore( gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, ) db = BLLDatabase() check2s_list = Check2.db_select(db) for check2 in check2s_list: created = UIUtils.get_db_timestamp_str(check2.created) modified = '-' #don't display modification date if it is the same as creation date if check2.modified != None and check2.modified != check2.created: modified = UIUtils.get_db_timestamp_str(check2.modified) completed = '-' if check2.completed != None: completed = UIUtils.get_db_timestamp_str(check2.completed) list_store.append([ check2.db_id, check2.csv_filename, check2.wav_foldername, completed, created, modified, ]) db.close() treeview = gtk.TreeView(list_store) #create the hidden id column col = gtk.TreeViewColumn('ID', gtk.CellRendererText(), text=0) col.set_visible(False) treeview.append_column(col) #create the rest of the columns column_names = [ 'CSV File', 'WAV Folder', 'Completed', 'Created', 'Modified' ] for i in range(len(column_names)): col = gtk.TreeViewColumn(column_names[i], gtk.CellRendererText(), text=(i + 1)) col.set_resizable(True) col.set_min_width( UIUtils.calc_treeview_col_min_width(column_names[i])) treeview.append_column(col) return treeview
def _load(self, treeview): (model, it) = treeview.get_selection().get_selected() db_id = model.get_value(it, 0) if it else None if db_id != None: db = BLLDatabase() check = Check.db_select(db, [db_id])[0] db.close() self.window.destroy() TestWindow(check) else: UIUtils.show_no_sel_dialog()
def _delete_config(self, treeview): model, it = treeview.get_selection().get_selected() if it: if UIUtils.show_confirm_dialog( 'Are you sure you want to delete this configuration?'): config = model.get(it, 4)[0] model.remove(it) if config.db_id != None: db = BLLDatabase() config.db_delete(db) db.close() else: UIUtils.show_no_sel_dialog()
def load_check(self, treeview): model, sel_paths = treeview.get_selection().get_selected_rows() if sel_paths: it = model.get_iter(sel_paths[0]) check2_id = model.get_value(it, 0) db = BLLDatabase() check2 = Check2.db_select(db, ids=[check2_id])[0] db.close() TestWindow(check2) self.window.destroy() else: UIUtils.show_no_sel_dialog()
def _process(self, src, dest): in_files = None out_files = None if src and os.path.exists(src): src = src.replace('\\', '/') if self.filter_type == FilterWindow.FILTER_TYPES.FILE: if not src.endswith('.csv'): src += '.csv' elif self.filter_type == FilterWindow.FILTER_TYPES.FOLDER: if src.endswith('/'): src = src[:-1] if os.path.isdir(src): in_files = map(lambda name: name.replace('\\', '/'), glob.glob('%s/*.csv' % (src))) else: in_files = [src] else: UIUtils.show_message_dialog('Source path does not exist!') return if dest and os.path.exists(dest): dest = dest.replace('\\', '/') if dest.endswith('/'): dest = dest[:-1] out_files = map(lambda name: '%s/%s-noNaps.csv' % (dest, os.path.basename(name)[:-4]), in_files) else: UIUtils.show_message_dialog('Destination path does not exist!') return self.window.destroy() prog_diag = ProgressDialog( title='Processing...', phases=['Please Wait'] ) prog_diag.show() db = BLLDatabase() for i in range(len(in_files)): Naptime.filter_file(db, in_files[i], out_files[i]) prog_diag.set_fraction(float(i + 1) / float(len(in_files))) db.close() prog_diag.ensure_finish()
def _build_list_store(self): list_store = gtk.ListStore( gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, ) db = BLLDatabase() checks_list = Check.db_select(db) for check in checks_list: created = UIUtils.get_db_timestamp_str(str( check.created)) if check.created != None else '-' last_run = UIUtils.get_db_timestamp_str(str( check.last_run)) if check.last_run != None else '-' completed = UIUtils.get_db_timestamp_str(str( check.completed)) if check.completed != None else '-' filters_str = '' if not check.filters: filters_str = '-' else: for i in range(len(check.filters)): filters_str += check.filters[i].get_filter_desc_str() if i < len(check.filters) - 1: filters_str += ',\n' list_store.append([ check.db_id, check.name, created, completed, last_run, check.input_filename, check.wav_filename, check.default_context_padding, str(check.pick_randomly), filters_str, ]) db.close() return list_store
def parse(self): db = BLLDatabase() self.parse_dict = {} lines = list(self.reader) if lines: #Note: the "Elapsed_Time" column does not reset here because we are using 5 minute blocks start = float(lines[0]['Elapsed_Time']) acts_dict = {} for row in lines: env = row['environment'].strip() act = row['Activity'].strip() if not env in self.parse_dict: self.parse_dict[env] = {} if not act in self.parse_dict[env]: self.parse_dict[env][act] = { 'used': [], 'unused': [], } spreadsheet_timestamp = Reliability2Parser.get_row_timestamp( row, start) child_code = Reliability2Parser.get_child_code(row) #note: no need to check wav_file here, since that is derived from child_code result_set = db.select( 'tests2', ['count(id)'], 'spreadsheet_timestamp=? AND child_code=?', [spreadsheet_timestamp, child_code]) if int(result_set[0][0]) > 0: self.parse_dict[env][act]['used'].append(row) else: self.parse_dict[env][act]['unused'].append(row) if not act in acts_dict: acts_dict[act] = True self.acts = acts_dict.keys() self.envs = self.parse_dict.keys() db.close()
def __init__(self, db_path): self.bll_db = BLLDatabase() self.props = PitchStudyProps.db_select(self.bll_db)[0] self.bll_db.close() self.window = gtk.Window(gtk.WindowType.TOPLEVEL) self.window.set_title('Select Batch Number') self.window.connect('destroy', lambda w: self.window.destroy()) self.window.set_border_width(10) self.window.set_default_size(210, 100) db = Database(db_path) vbox = gtk.VBox() next_batch_num, next_part_num = self._get_next_nums(db) label = gtk.Label('Select the batch number to run: ') batch_spin_adj = gtk.Adjustment(value=1, lower=1, upper=self._get_total_batches(db) + 1, step_increment=1, page_increment=1, page_size=1) self.batch_spin = gtk.SpinButton() self.batch_spin.set_adjustment(batch_spin_adj) self.batch_spin.set_snap_to_ticks(True) self.batch_spin.set_value(next_batch_num) hbox = gtk.HBox() hbox.pack_start(label, True, True, 0) hbox.pack_start(self.batch_spin, True, True, 0) vbox.pack_start(hbox, True, True, 0) label = gtk.Label('Select the participant number to use: ') part_spin_adj = gtk.Adjustment(value=1, lower=1, upper=self.props.max_parts_per_batch + 1, step_increment=1, page_increment=1, page_size=1) self.part_spin = gtk.SpinButton() self.part_spin.set_adjustment(part_spin_adj) self.part_spin.set_snap_to_ticks(True) self.part_spin.set_value(next_part_num) hbox = gtk.HBox() hbox.pack_start(label, True, True, 0) hbox.pack_start(self.part_spin, True, True, 0) vbox.pack_start(hbox, True, True, 0) button_box = self._build_button_box(db) vbox.pack_start(button_box, True, True, 0) self.window.add(vbox) self.window.show_all()
def __init__(self): self.bll_db = BLLDatabase() self.props = PitchStudyProps.db_select(self.bll_db)[0] self.window = gtk.Window(gtk.WindowType.TOPLEVEL) self.window.set_title('Options') self.window.connect('destroy', lambda w: self.window.destroy()) self.window.set_border_width(10) self.window.set_default_size(210, 100) vbox = gtk.VBox() grid = self._build_options_grid() bbox = self._build_button_box() vbox.pack_start(grid, False, False, 0) vbox.pack_start(bbox, False, False, 0) self.window.add(vbox) self.window.show_all()
def _fill_entry(combo, entry): opt_id = combo.get_model()[combo.get_active()][1] db = BLLDatabase() # Ideally, the regex info should come out of an enum in the DBConstants class (such as DBConstants.COMMON_REGEXS). # However, we only have the combobox option id of the selected option, and this isn't enough to figure out which enum value we need. # To solve this problem, I've reverted to a database query here, but this should really be fixed in the future...we need something other # than the option id to identify the selected combo option. rows = db.select('common_regexs', 'regex'.split(), 'combo_option_id=?', [opt_id]) if rows and rows[0]: regex = rows[0][0] highlight_start = regex.find('\<') highlight_end = regex.find('\>') entry.set_text(regex.replace('\<', '<').replace('\>', '>')) entry.grab_focus() if highlight_start > -1 and highlight_end > -1: entry.select_region(highlight_start, highlight_end) db.close()
def delete_check(self, treeview): model, sel_paths = treeview.get_selection().get_selected_rows() if sel_paths: if UIUtils.show_confirm_dialog( 'Are you sure you want to delete this row?'): it = model.get_iter(sel_paths[0]) check2_id = model.get_value(it, 0) db = BLLDatabase() #this is a little awkward, but it works for now... check2 = Check2.db_select(db, ids=[check2_id])[0] if check2.db_delete(db) > 0: model.remove(it) else: UIUtils.show_message_dialog( 'An error has prevented this row from being deleted. Please check the log files for details.', gtk.MESSAGE_ERROR) db.close() else: UIUtils.show_no_sel_dialog()
def update_db(self, path): prog_diag = ProgressDialog(title='Processing...', phases=['Please Wait']) prog_diag.show() db = BLLDatabase() error_filenames = Naptime.update_naptime_data(db, path, prog_diag=prog_diag) db.close() prog_diag.ensure_finish() if error_filenames: UIUtils.show_message_dialog( 'Unable to process the following files - see the log file for details:\n' + '\n'.join(map(os.path.basename, error_filenames)), dialog_type=gtk.MessageType.ERROR) else: UIUtils.show_message_dialog( 'Naptime database table updated successfully.') self.window.destroy()
def save(self, completed, progress_dialog=None): self._save_to_cur_test2() db = BLLDatabase() for i in range(len(self.check2.test2s)): test2 = self.check2.test2s[i] if test2.db_id != None: test2.db_delete(db) test2.db_insert(db) if progress_dialog: progress_dialog.set_fraction( float(i + 1) / float(len(self.check2.test2s))) self.check2.update_test2_index(db) #update modification timestamp self.check2.update_modified(db) #only update completed timestamp the first time the check2 is completed if completed and self.check2.completed == None: self.check2.update_completed(db) db.close()
def _confirm_delete(self, treeview): (model, it) = treeview.get_selection().get_selected() db_id = model.get_value(it, 0) if it else None if db_id != None: response = UIUtils.show_confirm_dialog( 'Are you sure you want to delete the selected check?') if response: db = BLLDatabase() rows_deleted = Check.db_select(db, [db_id])[0].db_delete(db) db.close() if rows_deleted > 0: model.remove(it) else: UIUtils.show_message_dialog( 'An error occurred and the check could not be deleted.' ) else: UIUtils.show_no_sel_dialog()
def create_check(self): error_msg = self.validate_form() if error_msg: UIUtils.show_message_dialog(error_msg) else: filters = self.filters_frame.get_filters() check = Check( self.form.name_entry.get_text(), self.form.input_file_entry.get_text(), self.form.wav_file_entry.get_text(), self.form.num_segs_spinner.get_value_as_int(), self.form.context_pad_spinner.get_value_as_int(), [], 0, filters=filters, pick_randomly=self.form.rand_checkbox.get_active(), ) parser = None progress_dialog = ProgressDialog( title='Loading File', phases=['Parsing file...', 'Setting up...']) segs = [] #TRS files if check.input_filename.lower().endswith('.trs'): parser = TRSParser(check.input_filename) progress_dialog.show() segs = parser.parse( progress_update_fcn=progress_dialog.set_fraction, progress_next_phase_fcn=progress_dialog.next_phase, validate=False, seg_filters=check.filters) #CSV files else: parser = CSVParser(check.input_filename) progress_dialog.show() segs = parser.parse( progress_update_fcn=progress_dialog.set_fraction, seg_filters=check.filters) progress_dialog.next_phase() if check.pick_randomly: #segs = ParserTools.pick_rand_segs(check.num_segs, segs) segs = ParserTools.hacked_pick_rand_segs( check.num_segs, segs, os.path.basename(check.input_filename)) else: segs = ParserTools.pick_contiguous_segs(check.num_segs, segs) progress_dialog.set_fraction(1.0) if len(segs) < check.num_segs: progress_dialog.ensure_finish( ) #close the progress bar (even though there's still one phase left) UIUtils.show_message_dialog( 'The input file does not contain enough segments of the specified types.', dialog_type=gtk.MessageType.ERROR) else: db = BLLDatabase() check.db_insert(db) for i in range(len(segs)): if segs[i].db_id == None: segs[i].db_insert(db) test = Test( check.db_id, None, None, None, segs[i], None, check.default_context_padding, ) test.db_insert(db) check.tests.append(test) progress_dialog.set_fraction( float(i + 1) / float(check.num_segs)) db.close() progress_dialog.ensure_finish() self.window.destroy() TestWindow(check)
def export(self): success = True #whether write succeeded or not try: #write some basic info about the check csv_file = open(self.filename, 'wb') csv_writer = csv.writer(csv_file) csv_writer.writerow(['Check name: "%s"' % (self.check.name)]) csv_writer.writerow([ 'Last run on %s' % (UIUtils.get_db_timestamp_str(str(self.check.last_run))) ]) csv_writer.writerow([ 'Created on %s' % (UIUtils.get_db_timestamp_str(str(self.check.created))) ]) csv_writer.writerow( ['TRS / CSV file: %s' % (self.check.input_filename)]) csv_writer.writerow(['WAV file: %s' % (self.check.wav_filename)]) csv_writer.writerow(['Number of Segs: %s' % (self.check.num_segs)]) csv_writer.writerow([ 'Default context padding (sec): %s' % (self.check.default_context_padding) ]) csv_writer.writerow([ 'Randomly Pick Segments: %s' % (str(self.check.pick_randomly)) ]) #write filter descriptions if self.check.filters: csv_writer.writerow(['Filters:']) for cur_filter in self.check.filters: csv_writer.writerow([cur_filter.get_filter_desc_str()]) else: csv_writer.writerow(['Filters: None']) #write the actual data from the tests csv_writer.writerow([]) headers = [ 'Test Number', 'LENA Start Time (w/o padding)', 'LENA End Time (w/o padding)', 'Context Padding', 'User-Adjusted Start Time', 'User-Adjusted End Time', 'Uncertain/Other', 'Syllables (with context)', 'Syllables (w/o context)', 'Actual Codes', 'Category Selection', 'Category Correct' ] csv_writer.writerow(headers) #write out the column headings #run through all of the tests, writing their data to the file and keeping track of how many times the user's selection was correct correct_count = 0 db = BLLDatabase() for i in range(self.check.num_segs): cur_test = self.check.tests[i] row = [] row.append(str(i + 1)) row.append('%0.3f' % (cur_test.seg.start)) row.append('%0.3f' % (cur_test.seg.end)) row.append(str(cur_test.context_padding)) row.append('%0.3f' % (cur_test.seg.user_adj_start)) row.append('%0.3f' % (cur_test.seg.user_adj_end)) row.append(str(bool(cur_test.is_uncertain))) row.append(str(cur_test.syllables_w_context)) row.append( str(cur_test.syllables_wo_context ) if cur_test.syllables_wo_context != None else '') actual_codes = self._get_actual_speaker_codes(cur_test, db) codes_str = '' for cur_codeinfo in actual_codes: codes_str += cur_codeinfo.code + ' ' if codes_str.endswith(' '): codes_str = codes_str[:-1] row.append(codes_str) cat_sel = self._get_cat_sel(cur_test) row.append(cat_sel.disp_desc) cat_correct = self._get_cat_correct(cur_test, actual_codes, cat_sel) correct_count += int(cat_correct) row.append(str(bool(cat_correct))) csv_writer.writerow(row) db.close() csv_writer.writerow([]) csv_writer.writerow([ 'Ratio correct: %0.2f' % (float(correct_count) / float(self.check.num_segs)) ]) csv_file.close() success = True except Exception as err: self.logger.error('Error exporting check: %s' % (err)) return success
def run(self): csv_path = self.csv_entry.get_text() wav_path = self.wav_entry.get_text() blocks_per_activity = self.blocks_spinner.get_value_as_int() activities = [] if self.acts_treeview and self.acts_treeview.get_selection(): model, sel_paths = self.acts_treeview.get_selection( ).get_selected_rows() for path in sel_paths: it = model.get_iter(path) activities.append(model.get_value(it, 0)) environments = [] if self.envs_treeview and self.envs_treeview.get_selection(): model, sel_paths = self.envs_treeview.get_selection( ).get_selected_rows() for path in sel_paths: it = model.get_iter(path) environments.append(model.get_value(it, 0)) is_valid = csv_path and wav_path and blocks_per_activity and len( activities) and len(environments) if is_valid: check2 = Check2( csv_path, wav_path, activities, environments, blocks_per_activity, ) sel_test2s = None enough_blocks, counts_str = self.parser.have_enough_blocks( check2, False) if enough_blocks: print counts_str sel_test2s = self.parser.pick_rows( check2, lambda filename: UIUtils.open_file( 'Please locate %s' % (filename), filters=[UIUtils.WAV_FILE_FILTER], save_last_location=True, cur_location=wav_path), False) else: enough_blocks, counts_str = self.parser.have_enough_blocks( check2, True) if enough_blocks: print counts_str if UIUtils.show_confirm_dialog( 'There are not enough unused rows left for some activities (see command window for row counts). If you proceed, the same row will be selected twice. Ok to continue?' ): sel_test2s = self.parser.pick_rows( check2, lambda filename: UIUtils.open_file( 'Please locate %s' % (filename), filters=[UIUtils.WAV_FILE_FILTER], save_last_location=True, cur_location=wav_path), True) else: print counts_str UIUtils.show_message_dialog( 'The input file does not contain enough blocks of the specified types. Please refer to the command window for a printout of the activity counts.' ) if sel_test2s: progress_dialog = ProgressDialog(title='Setting up...', phases=['']) progress_dialog.show() db = BLLDatabase() check2.db_insert(db) check2.test2s = sel_test2s for i in range(len(check2.test2s)): test2 = check2.test2s[i] test2.check2_id = check2.db_id test2.db_insert(db) progress_dialog.set_fraction( float(i + 1) / float(len(check2.test2s))) db.close() progress_dialog.ensure_finish() TestWindow(check2) if self.parser: self.parser.close() self.window.destroy() else: UIUtils.show_empty_form_dialog()