Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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()
Example #4
0
    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()
Example #5
0
    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
Example #6
0
    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()
Example #7
0
    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()
Example #8
0
    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()
Example #9
0
    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()        
Example #10
0
    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
Example #11
0
    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()
Example #12
0
    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()
Example #13
0
    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()
Example #14
0
    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()
Example #15
0
    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()
Example #16
0
    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()
Example #17
0
    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()
Example #18
0
    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()
Example #19
0
    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)
Example #20
0
class BatchSelectionWindow():
    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 _get_next_nums(self, db):
        batch_num = 1
        part_num = 1
        
        total_batches = self._get_total_batches(db)
        
        rows = db.select(
            'clips c join ratings r on c.id = r.clip_id',
            ['max(c.Batch_Num)'],
            where_cond = 'r.Participant_Num is not null'
        )
        if rows and rows[0][0] is not None:
            cur_batch_num = rows[0][0]
            rows = db.select(
                'clips c join ratings r on c.id = r.clip_id',
                ['max(r.Participant_Num)'],
                where_cond = 'c.Batch_Num = ?',
                params = [cur_batch_num]
            )
            if rows and rows[0][0] is not None:
                cur_part_num = rows[0][0]

                if cur_part_num < self.props.max_parts_per_batch:
                    part_num = cur_part_num + 1
                    batch_num = cur_batch_num
                elif cur_batch_num < total_batches:
                    batch_num = cur_batch_num + 1
                    #part_num = 1

        return batch_num, part_num

    def _get_total_batches(self, db):
        rows = db.select(
            'clips',
            ['max(Batch_Num)']
        )
        return rows[0][0]
        
    def _check_if_used(self, db, batch_num, participant_num):
        rows = db.select(
            'clips c join ratings r on c.id = r.clip_id',
            ['count(c.id)'],
            where_cond = 'c.Batch_Num = ? and r.Participant_Num = ?',
            params = [batch_num, participant_num]
        )
        return rows[0][0] > 0

    def _build_button_box(self, db):
        button_box = gtk.HButtonBox()
        button_box.set_layout(gtk.ButtonBoxStyle.EDGE)

        cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL, label='Cancel')
        cancel_button.connect('clicked', lambda w: self.window.destroy())
        button_box.add(cancel_button)
        
        ok_button = gtk.Button(stock=gtk.STOCK_OK, label='Run')
        ok_button.connect('clicked', lambda w: self.check_input(db))
        button_box.add(ok_button)

        return button_box

    def check_input(self, db):
        batch_num = self.batch_spin.get_value_as_int()
        participant_num = self.part_spin.get_value_as_int()
        if self._check_if_used(db, batch_num, participant_num):
            response = UIUtils.show_confirm_dialog('Participant %d has recorded responses for Batch %d.\nContinuing will overwrite the existing data for this participant (in this batch).\nDo you want continue?' % (participant_num, batch_num))
            if response:
                db.delete(
                    'ratings',
                    where_cond = 'clip_id in (select id from clips where Batch_Num = ?) and Participant_Num = ?',
                    params = [batch_num, participant_num]
                )
                self._start_testing(db, batch_num, participant_num)

        else:
            self._start_testing(db, batch_num, participant_num)

        #db.close()
        
    def _start_testing(self, db, batch_num, participant_num):
        self.window.destroy()
        TestingWindow(db, batch_num, participant_num)
Example #21
0
class TestingWindow():
    def _update_rating(self, db, rating):
        rows = db.select('clips', ['id'],
                         where_cond='Batch_Num = ? and Batch_Order = ?',
                         params=[self.batch_num, self.order_num])
        clip_id = rows[0][0]

        db.insert('ratings', ['clip_id', 'Participant_Num', 'Question_Rating'],
                  [[clip_id, self.participant_num, rating]])

    def _get_num_clips(self, db):
        row = db.select('clips', ['count(id)'],
                        where_cond='Batch_Num = ?',
                        params=[self.batch_num])
        return row[0][0]

    def _next(self, db, rating):
        num_clips = self._get_num_clips(db)

        if self.order_num == num_clips:
            self._finish()

        else:
            self._update_rating(db, rating)
            self.order_num += 1
            self._update_step(db)

            if (self.order_num - 1) == num_clips or num_clips == 1:
                self._finish()

            elif (self.order_num - 1) % self.props.break_interval == 0:
                self.test_grid.hide()
                self.pause_grid.show_all()

            else:
                self._play_clip(db)

    def _finish(self):
        self.window.destroy()
        UIUtils.show_message_dialog('Testing complete! Thanks for your help.')

    def _update_step(self, db):
        row = db.select('clips', ['Filename', 'Age'],
                        where_cond='Batch_Num = ? and Batch_Order = ?',
                        params=[self.batch_num, self.order_num])
        filename, age = row[0]
        self.filename = '%sbatch%d/%s_%d-%d.wav' % (
            self.props.clips_dir_path, self.batch_num, filename[:-5], age,
            self.order_num)

        num_clips = self._get_num_clips(db)
        #self.label.set_text('Clip %d of %d' % (self.order_num, self._get_num_clips(db)))
        self.progress.set_fraction(self.order_num /
                                   float(self._get_num_clips(db)))

    def _play_clip(self, db):
        map(lambda button: button.set_sensitive(False), self.scale_buttons)
        while gtk.events_pending():
            gtk.main_iteration()

        time.sleep(self.props.inter_clip_sound_del)

        self._toggle_playing_icon(True)

        wav_parser = WavParser(self.filename)
        wav_parser.play_clip(0, wav_parser.get_sound_len())
        wav_parser.close()

        map(lambda button: button.set_sensitive(True), self.scale_buttons)
        self._toggle_playing_icon(False)

    def _continue(self, db):
        self.pause_grid.hide()
        self.test_grid.show_all()

        self._play_clip(db)

    def _get_pause_grid(self, db):
        vbox = gtk.VBox()

        label = gtk.Label(
            'Click the button below when you\'re ready to continue.')
        vbox.pack_start(label, False, False, 0)

        button = gtk.Button('Continue')
        button.connect('clicked', lambda w: self._continue(db))
        hbox = gtk.HBox()
        hbox.pack_start(button, True, False, 0)
        vbox.pack_start(hbox, True, True, 10)

        return vbox

    def _toggle_playing_icon(self, is_on):
        icon = UIUtils.BUTTON_ICONS.VOLUME_OFF
        if is_on:
            icon = UIUtils.BUTTON_ICONS.VOLUME_ON

        icon_path = UIUtils.get_icon_path(icon, UIUtils.BUTTON_ICON_SIZES.PX64)

        self.playing_icon.set_from_file(icon_path)

        while gtk.events_pending():
            gtk.main_iteration()

    def _get_test_grid(self, db):
        grid = gtk.Grid()

        self.progress = gtk.ProgressBar()
        self.progress.set_orientation(gtk.Orientation.HORIZONTAL)
        self.progress.set_fraction(self.order_num +
                                   1 / float(self._get_num_clips(db)))
        #self.progress.set_vexpand(False)
        #self.progress.set_vexpand_set(True)
        grid.attach(self.progress, 0, 0, 5, 1)

        #self.label = gtk.Label('Clip %d of %d' % (self.order_num + 1, self._get_num_clips(db)))
        #UIUtils.set_font_size(self.label, 25, bold=True)
        #self.label.set_hexpand(True)
        #self.label.set_hexpand_set(True)
        #grid.attach(self.label, 0, 0, 5, 1)

        question_label = gtk.Label(
            'How much does this sentence sound like a question?')
        UIUtils.set_font_size(question_label, 30, bold=True)
        grid.attach(question_label, 0, 1, 5, 1)

        self.playing_icon = gtk.Image()
        self.playing_icon.set_vexpand(True)
        self.playing_icon.set_vexpand_set(True)
        self._toggle_playing_icon(False)
        grid.attach(self.playing_icon, 0, 2, 5, 1)

        self.scale_buttons = []
        button_grid = gtk.Grid()
        button_grid.set_column_homogeneous(True)

        label_low = gtk.Label('Not Very Much like a Question')
        label_low.set_alignment(0, 0)
        UIUtils.set_font_size(label_low, 20, bold=True)
        button_grid.attach(label_low, 0, 0, 2, 1)

        label_high = gtk.Label('Very Much like a Question')
        label_high.set_alignment(1, 0)
        UIUtils.set_font_size(label_high, 20, bold=True)
        button_grid.attach(label_high, self.props.num_options - 2, 0, 2, 1)

        for i in range(self.props.num_options):
            button = gtk.Button('\n' + str(i + 1) + '\n')
            UIUtils.set_font_size(button, 15, bold=True)
            button.connect('button-release-event',
                           lambda w, e: self._next(db, int(w.get_label())))
            button.set_vexpand(False)
            button.set_vexpand_set(False)

            self.scale_buttons.append(button)
            button.set_hexpand(True)
            button.set_hexpand_set(True)
            button_grid.attach(button, i, 1, 1, 1)

        grid.attach(button_grid, 0, 3, 5, 1)

        return grid

    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()
Example #22
0
    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()