def dataset_write(dataset, file_name, output_format): """ write a tablib dataset to file in specified format Args: dataset (tablib.dataset): dataset to write file_name (str): file name output_format (str): format of output Returns: bool: result. True if OK else False str: error message """ logging.debug("function: dataset_write") try: if output_format == "tsv": with open(file_name, "wb") as f: f.write(str.encode(dataset.tsv)) return True, "" if output_format == "csv": with open(file_name, "wb") as f: f.write(str.encode(dataset.csv)) return True, "" if output_format == "ods": with open(file_name, "wb") as f: f.write(dataset.ods) return True, "" dataset.title = utilities.safe_xl_worksheet_title( dataset.title, output_format) ''' if output_format in ["xls", "xlsx"]: # check worksheet title for forbidden_char in EXCEL_FORBIDDEN_CHARACTERS: dataset.title = dataset.title.replace(forbidden_char, " ") ''' if output_format == "xlsx": with open(file_name, "wb") as f: f.write(dataset.xlsx) return True, "" if output_format == "xls": if len(dataset.title) > 31: dataset.title = dataset.title[:31] with open(file_name, "wb") as f: f.write(dataset.xls) return True, "" if output_format == "html": with open(file_name, "wb") as f: f.write(str.encode(dataset.html)) return True, "" return False, f"Format {output_format} not found" except Exception: return False, str(sys.exc_info()[1])
def save_results(self): """ save results """ extended_file_formats = ["Tab Separated Values (*.tsv)", "Comma Separated Values (*.csv)", "Open Document Spreadsheet ODS (*.ods)", "Microsoft Excel Spreadsheet XLSX (*.xlsx)", "Legacy Microsoft Excel Spreadsheet XLS (*.xls)", "HTML (*.html)"] file_formats = ["tsv", "csv", "ods", "xlsx", "xls", "html"] file_name, filter_ = QFileDialog().getSaveFileName(None, "Save results", "", ";;".join(extended_file_formats)) if not file_name: return output_format = file_formats[extended_file_formats.index(filter_)] if pathlib.Path(file_name).suffix != "." + output_format: file_name = str(pathlib.Path(file_name)) + "." + output_format # check if file with new extension already exists if pathlib.Path(file_name).is_file(): if dialog.MessageDialog(programName, f"The file {file_name} already exists.", [CANCEL, OVERWRITE]) == CANCEL: return if self.rb_details.isChecked(): tablib_dataset = tablib.Dataset(headers=self.details_header) if self.rb_summary.isChecked(): tablib_dataset = tablib.Dataset(headers=self.summary_header) tablib_dataset.title = utilities.safe_xl_worksheet_title(self.logic.text(), output_format) [tablib_dataset.append(x) for x in self.out] try: if output_format in ["csv", "tsv", "html"]: with open(file_name, "wb") as f: f.write(str.encode(tablib_dataset.export(output_format))) if output_format in ["ods", "xlsx", "xls"]: with open(file_name, "wb") as f: f.write(tablib_dataset.export(output_format)) except Exception: QMessageBox.critical(self, programName, f"The file {file_name} can not be saved")
def export_events(parameters, obsId, observation, ethogram, file_name, output_format): """ export events Args: parameters (dict): subjects, behaviors obsId (str): observation id observation (dict): observation ethogram (dict): ethogram of project file_name (str): file name for exporting events output_format (str): output for exporting events Returns: bool: result: True if OK else False str: error message """ total_length = f"{project_functions.observation_total_length(observation):.3f}" eventsWithStatus = project_functions.events_start_stop( ethogram, observation[EVENTS]) # check max number of modifiers max_modifiers = 0 for event in eventsWithStatus: for c in pj_events_fields: if c == "modifier" and event[pj_obs_fields[c]]: max_modifiers = max(max_modifiers, len(event[pj_obs_fields[c]].split("|"))) # media file number mediaNb = 0 if observation["type"] == MEDIA: for player in observation[FILE]: mediaNb += len(observation[FILE][player]) rows = [] # observation id rows.append(["Observation id", obsId]) rows.append([""]) # media file name if observation["type"] in [MEDIA]: rows.append(["Media file(s)"]) elif observation["type"] in [LIVE]: rows.append(["Live observation"]) else: rows.append(["?"]) rows.append([""]) if observation[TYPE] in [MEDIA]: for player in sorted(list(observation[FILE].keys())): for media in observation[FILE][player]: rows.append([f"Player #{player}", media]) rows.append([""]) # date if "date" in observation: rows.append( ["Observation date", observation["date"].replace("T", " ")]) rows.append([""]) # description if "description" in observation: rows.append( ["Description", utilities.eol2space(observation["description"])]) rows.append([""]) # time offset if "time offset" in observation: rows.append(["Time offset (s)", observation["time offset"]]) rows.append([""]) # independent variables if INDEPENDENT_VARIABLES in observation: rows.extend([["independent variables"], ["variable", "value"]]) for variable in observation[INDEPENDENT_VARIABLES]: rows.append( [variable, observation[INDEPENDENT_VARIABLES][variable]]) rows.append([""]) # write table header col = 0 header = ["Time"] header.extend(["Media file path", "Total length", "FPS"]) header.extend(["Subject", "Behavior", "Behavioral category"]) behavioral_category = project_functions.behavior_category(ethogram) for x in range(1, max_modifiers + 1): header.append(f"Modifier {x}") header.extend(["Comment", "Status"]) rows.append(header) duration1 = [] # in seconds if observation["type"] in [MEDIA]: try: for mediaFile in observation[FILE][PLAYER1]: duration1.append(observation[MEDIA_INFO]["length"][mediaFile]) except KeyError: pass for event in eventsWithStatus: if (((event[SUBJECT_EVENT_FIELD] in parameters["selected subjects"]) or (event[SUBJECT_EVENT_FIELD] == "" and NO_FOCAL_SUBJECT in parameters["selected subjects"])) and (event[BEHAVIOR_EVENT_FIELD] in parameters["selected behaviors"])): fields = [] fields.append( utilities.intfloatstr(str(event[EVENT_TIME_FIELD_IDX]))) if observation["type"] in [MEDIA]: time_ = event[EVENT_TIME_FIELD_IDX] - observation[TIME_OFFSET] if time_ < 0: time_ = 0 if duration1: mediaFileIdx = [ idx1 for idx1, x in enumerate(duration1) if time_ >= sum(duration1[0:idx1]) ][-1] fields.append(observation[FILE][PLAYER1][mediaFileIdx]) fields.append(total_length) # FPS try: fields.append(observation[MEDIA_INFO]["fps"][ observation[FILE][PLAYER1][mediaFileIdx]]) # fps except KeyError: fields.append("NA") else: fields.append("NA") # media file fields.append("NA") # FPS if observation["type"] in [LIVE]: fields.append(LIVE) # media fields.append(total_length) # total length fields.append("NA") # FPS fields.append(event[EVENT_SUBJECT_FIELD_IDX]) fields.append(event[EVENT_BEHAVIOR_FIELD_IDX]) # behavioral category try: behav_category = behavioral_category[ event[EVENT_BEHAVIOR_FIELD_IDX]] except Exception: behav_category = "" fields.append(behav_category) # modifiers if max_modifiers: modifiers = event[EVENT_MODIFIER_FIELD_IDX].split("|") while len(modifiers) < max_modifiers: modifiers.append("") for m in modifiers: fields.append(m) # comment fields.append(event[EVENT_COMMENT_FIELD_IDX].replace( os.linesep, " ")) # status fields.append(event[-1]) rows.append(fields) maxLen = max([len(r) for r in rows]) data = tablib.Dataset() data.title = utilities.safe_xl_worksheet_title(obsId, output_format) ''' if output_format in ["xls", "xlsx"]: for forbidden_char in EXCEL_FORBIDDEN_CHARACTERS: data.title = data.title.replace(forbidden_char, " ") if output_format in ["xls"]: if len(data.title) > 31: data.title = data.title[0:31] ''' for row in rows: data.append(utilities.complete(row, maxLen)) r, msg = dataset_write(data, file_name, output_format) return r, msg
def test_title_with_forbidden_chars_xlsx(self): # \/*[]:? assert utilities.safe_xl_worksheet_title(r"000\000/000*000[000]000:000?000 000", "xls") == "000 000 000 000 000 000 000 000"
def test_long_title_tsv(self): assert utilities.safe_xl_worksheet_title("0123456789012345678901234567890123456789", "tsv") == "0123456789012345678901234567890123456789"