def create_subtitles(pj: dict, selected_observations: list, parameters: dict,
                     export_dir: str) -> tuple:
    """
    create subtitles for selected observations, subjects and behaviors

    Args:
        pj (dict): project
        selected_observations (list): list of observations
        parameters (dict):
        export_dir (str): directory to save subtitles

    Returns:
        bool: True if OK else False
        str: error message
    """
    def subject_color(subject):
        """
        subject color

        Args:
            subject (str): subject name

        Returns:
            str: HTML tag for color font (beginning)
            str: HTML tag for color font (closing)
        """
        if subject == NO_FOCAL_SUBJECT:
            return "", ""
        else:
            return (
                """<font color="{}">""".format(
                    subtitlesColors[parameters["selected subjects"].index(
                        row["subject"]) % len(subtitlesColors)]),
                "</font>",
            )

    try:
        ok, msg, db_connector = db_functions.load_aggregated_events_in_db(
            pj, parameters["selected subjects"], selected_observations,
            parameters["selected behaviors"])
        if not ok:
            return False, msg

        cursor = db_connector.cursor()
        flag_ok = True
        msg = ""
        for obsId in selected_observations:
            if pj[OBSERVATIONS][obsId][TYPE] in [LIVE]:
                out = ""
                cursor.execute(
                    ("SELECT subject, behavior, start, stop, type, modifiers FROM aggregated_events "
                     "WHERE observation = ? AND subject in ({}) "
                     "AND behavior in ({}) "
                     "ORDER BY start").format(
                         ",".join(["?"] *
                                  len(parameters["selected subjects"])),
                         ",".join(["?"] *
                                  len(parameters["selected behaviors"]))),
                    [obsId] + parameters["selected subjects"] +
                    parameters["selected behaviors"],
                )

                for idx, row in enumerate(cursor.fetchall()):
                    col1, col2 = subject_color(row["subject"])
                    if parameters["include modifiers"]:
                        modifiers_str = "\n{}".format(row["modifiers"].replace(
                            "|", ", "))
                    else:
                        modifiers_str = ""
                    out += ("{idx}\n"
                            "{start} --> {stop}\n"
                            "{col1}{subject}: {behavior}"
                            "{modifiers}"
                            "{col2}\n\n").format(
                                idx=idx + 1,
                                start=utilities.seconds2time(
                                    row["start"]).replace(".", ","),
                                stop=utilities.seconds2time(
                                    row["stop"] if row["type"] ==
                                    STATE else row["stop"] +
                                    POINT_EVENT_ST_DURATION).replace(".", ","),
                                col1=col1,
                                col2=col2,
                                subject=row["subject"],
                                behavior=row["behavior"],
                                modifiers=modifiers_str,
                            )
                '''
                file_name = str(pathlib.Path(pathlib.Path(export_dir) / utilities.safeFileName(obsId)).with suffix(".srt"))
                '''
                file_name = f"{pathlib.Path(export_dir) / utilities.safeFileName(obsId)}.srt"
                try:
                    with open(file_name, "w") as f:
                        f.write(out)
                except Exception:
                    flag_ok = False
                    msg += "observation: {}\ngave the following error:\n{}\n".format(
                        obsId, str(sys.exc_info()[1]))

            elif pj[OBSERVATIONS][obsId][TYPE] in [MEDIA]:

                for nplayer in ALL_PLAYERS:
                    if not pj[OBSERVATIONS][obsId][FILE][nplayer]:
                        continue
                    init = 0
                    for mediaFile in pj[OBSERVATIONS][obsId][FILE][nplayer]:
                        try:
                            end = init + pj[OBSERVATIONS][obsId][MEDIA_INFO][
                                LENGTH][mediaFile]
                        except KeyError:
                            return False, f"The length for media file {mediaFile} is not available"
                        out = ""

                        cursor.execute(
                            ("SELECT subject, behavior, type, start, stop, modifiers FROM aggregated_events "
                             "WHERE observation = ? AND start BETWEEN ? and ? "
                             "AND subject in ({}) "
                             "AND behavior in ({}) "
                             "ORDER BY start").format(
                                 ",".join(
                                     ["?"] *
                                     len(parameters["selected subjects"])),
                                 ",".join(
                                     ["?"] *
                                     len(parameters["selected behaviors"])),
                             ),
                            [obsId, init, end] +
                            parameters["selected subjects"] +
                            parameters["selected behaviors"],
                        )

                        for idx, row in enumerate(cursor.fetchall()):
                            col1, col2 = subject_color(row["subject"])
                            if parameters["include modifiers"]:
                                modifiers_str = "\n{}".format(
                                    row["modifiers"].replace("|", ", "))
                            else:
                                modifiers_str = ""

                            out += (
                                "{idx}\n"
                                "{start} --> {stop}\n"
                                "{col1}{subject}: {behavior}"
                                "{modifiers}"
                                "{col2}\n\n").format(
                                    idx=idx + 1,
                                    start=utilities.seconds2time(row["start"] -
                                                                 init).replace(
                                                                     ".", ","),
                                    stop=utilities.seconds2time(
                                        (row["stop"] if row["type"] ==
                                         STATE else row["stop"] +
                                         POINT_EVENT_ST_DURATION) -
                                        init).replace(".", ","),
                                    col1=col1,
                                    col2=col2,
                                    subject=row["subject"],
                                    behavior=row["behavior"],
                                    modifiers=modifiers_str,
                                )
                        '''
                        file_name = str(pathlib.Path(pathlib.Path(export_dir) / pathlib.Path(mediaFile).name).with suffix(".srt"))
                        '''
                        file_name = f"{pathlib.Path(export_dir) / pathlib.Path(mediaFile).name}.srt"
                        try:
                            with open(file_name, "w") as f:
                                f.write(out)
                        except Exception:
                            flag_ok = False
                            msg += f"observation: {obsId}\ngave the following error:\n{sys.exc_info()[1]}\n"

                        init = end

        return flag_ok, msg
    except Exception:
        return False, str(sys.exc_info()[1])
def check_state_events_obs(obsId: str,
                           ethogram: dict,
                           observation: dict,
                           time_format: str = HHMMSS) -> tuple:
    """
    check state events for the observation obsId
    check if behaviors in observation are defined in ethogram
    check if number is odd

    Args:
        obsId (str): id of observation to check
        ethogram (dict): ethogram of project
        observation (dict): observation to be checked
        time_format (str): time format

    Returns:
        tuple (bool, str): if OK True else False , message
    """

    out = ""

    # check if behaviors are defined as "state event"
    event_types = {ethogram[idx]["type"] for idx in ethogram}

    if not event_types or event_types == {"Point event"}:
        return (True, "No behavior is defined as `State event`")

    flagStateEvent = False
    subjects = [
        event[EVENT_SUBJECT_FIELD_IDX] for event in observation[EVENTS]
    ]
    ethogram_behaviors = {ethogram[idx][BEHAVIOR_CODE] for idx in ethogram}

    for subject in sorted(set(subjects)):

        behaviors = [
            event[EVENT_BEHAVIOR_FIELD_IDX] for event in observation[EVENTS]
            if event[EVENT_SUBJECT_FIELD_IDX] == subject
        ]

        for behavior in sorted(set(behaviors)):
            if behavior not in ethogram_behaviors:
                # return (False, "The behaviour <b>{}</b> is not defined in the ethogram.<br>".format(behavior))
                continue
            else:
                if STATE in event_type(behavior, ethogram).upper():
                    flagStateEvent = True
                    lst, memTime = [], {}
                    for event in [
                            event for event in observation[EVENTS]
                            if event[EVENT_BEHAVIOR_FIELD_IDX] == behavior
                            and event[EVENT_SUBJECT_FIELD_IDX] == subject
                    ]:

                        behav_modif = [
                            event[EVENT_BEHAVIOR_FIELD_IDX],
                            event[EVENT_MODIFIER_FIELD_IDX]
                        ]

                        if behav_modif in lst:
                            lst.remove(behav_modif)
                            del memTime[str(behav_modif)]
                        else:
                            lst.append(behav_modif)
                            memTime[str(
                                behav_modif)] = event[EVENT_TIME_FIELD_IDX]

                    for event in lst:
                        out += (
                            'The behavior <b>{behavior}</b> {modifier} is not PAIRED for subject'
                            ' "<b>{subject}</b>" at <b>{time}</b><br>').format(
                                behavior=behavior,
                                modifier=("(modifier " + event[1] +
                                          ") ") if event[1] else "",
                                subject=subject
                                if subject else NO_FOCAL_SUBJECT,
                                time=memTime[str(event)]
                                if time_format == S else
                                utilities.seconds2time(memTime[str(event)]),
                            )

    return (False, out) if out else (True, "No problem detected")
示例#3
0
 def test_gt_86400(self):
     assert utilities.seconds2time(Decimal(86400.999)) == "24:00:00.999"
示例#4
0
 def test_10(self):
     assert utilities.seconds2time(Decimal(10.0)) == "00:00:10.000"
示例#5
0
 def test_negative(self):
     assert utilities.seconds2time(Decimal(-2.123)) == "-00:00:02.123"