Пример #1
0
def prepare_overlay_test(values, data, config=None):
    if config is None:
        config = {}

    values = {
        "images": {
            "testbild": {
                "type": "pillow",
                "path": "Test_Bild_1.png",
                "overlay": [values]
            }
        },
        "presets": {
            "test_preset": {
                "color": "black",
                "font_size": 20,
                "font": "Test_Font.ttf"
            },
        }
    }

    step_data = StepData(config, "0", 0, values.get("presets", None))
    step_data.insert_data("_req", {"_test": data}, {})
    step_data.data["_pipe_id"] = "100"
    generate_all_images(values, step_data)

    return values["images"]["testbild"]
def pillow(values: dict, step_data: StepData, prev_paths: dict):
    """
    Erstellt ein Bild mit Hilfe der Python-Bibliothek Pillow.
    Dazu wird ein neues Bild geöffnet oder ein bisher erstelltes Bild weiter bearbeitet.
    In der JSON können beliebige viele Overlays angegeben werden, welche diese Methode alle
    ausführt und auf das Bild setzt.

    :param values: Image-Bauplan des zu erstellenden Bildes
    :param step_data: Daten aus der API
    :param prev_paths: alle Image-Baupläne und somit auch alle Pfade zu den bisher erstellten Bildern
    :return: Pfad zum erstellten Bild
    :rtype: str
    """
    if values.get("path", None) is None:
        image_name = step_data.format(values["image_name"])
        source_img = Image.open(
            resources.get_resource_path(prev_paths[image_name]))
    else:
        path = step_data.format(values["path"])
        source_img = Image.open(resources.get_image_path(path))
    img1 = Image.new("RGBA", source_img.size)
    draw = ImageDraw.Draw(source_img)

    for overlay in values["overlay"]:
        over_func = get_type_func(overlay, OVERLAY_TYPES)
        over_func(overlay, step_data, source_img, prev_paths, draw)

    file = resources.new_temp_resource_path(step_data.data["_pipe_id"], "png")
    Image.composite(img1, source_img, img1).save(file)
    return file
Пример #3
0
def date_weekday(values: dict, data: StepData):
    """Wandelt das angegebene Datum in den jeweiligen Wochentag um.

    Wandelt das angegebene Datum, im unter `"given_format"` angegebenen Format, in den jeweiligen Wochentag um.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    day_weekday = {
        0: "Montag",
        1: "Dienstag",
        2: "Mittwoch",
        3: "Donnerstag",
        4: "Freitag",
        5: "Samstag",
        6: "Sonntag"
    }
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(values["keys"][idx], values)
        given_format = data.format(values["given_format"], values)
        date = datetime.strptime(value, given_format).date()
        new_key = get_new_keys(values, idx)

        new_value = day_weekday[date.weekday()]
        data.insert_data(new_key, new_value, values)
Пример #4
0
def custom(values: dict, step_data: StepData, out_images, out_audios,
           out_audio_l):
    """Generierung des Output-Videos aus ausgewählten Bild- und Audiodateien.

    Generiert das Output-Video. In values (in der JSON) muss angegeben sein in welcher Reihenfolge und wie lange jedes Bild
    und die passenden Audiodatei aneinandergereiht werden sollen.

    :param values: Werte aus der JSON-Datei
    :param step_data: Daten aus der API
    :return: Pfad zum Output-Video
    :rtype: str
    """
    for s in values["sequence"]["pattern"]:
        out_images.append(values["images"][step_data.format(s["image"])])
        if s.get("audio_l", None) is None:
            out_audio_l.append(
                step_data.get_data(s.get("time_diff", 0), None,
                                   numbers.Number))
        else:
            out_audios.append(values["audio"]["audios"][step_data.format(
                s["audio_l"])])
            out_audio_l.append(
                step_data.get_data(s.get("time_diff", 0), None, numbers.Number)
                + MP3(values["audio"]["audios"][step_data.format(
                    s["audio_l"])]).info.length)
Пример #5
0
def normalize_words(values: dict, data: StepData):
    """Wörter, die öfter vorkommen und unterschiedliche cases besitzen, werden normalisiert.

    Eine Liste wird durchlaufen und jedes Wort welches bei zweiten Vorkommen anders geschrieben wurde als das erste
    vorgekommene wird dann so ersetzt, dass es so geschrieben wird wie das zuerst vorgekommene. Z.B. Bundesliga und
    bundesliga. Aus bundesliga wird Bundesliga.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)
        already_there = []
        new_value = []
        for each in value:
            if each.upper() in already_there:
                new_value.append(each.upper())
            elif each.lower() in already_there:
                new_value.append(each.lower())
            elif each.capitalize() in already_there:
                new_value.append(each.capitalize())
            else:
                already_there.append(each)
                new_value.append(each)

        data.insert_data(new_key, new_value, values)
Пример #6
0
def request_multiple_custom(values: dict,
                            data: StepData,
                            name: str,
                            save_key,
                            ignore_testing=False):
    """Fragt unterschiedliche Daten einer API ab.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :param name: Testdatei, die geladen werden soll.
    :param save_key: Key, unter dem die Daten gespeichert werden.
    :param ignore_testing: Ob der Request durchgeführt werden soll, obwohl testing `true` ist.
    """

    if data.get_config("testing", False) and not ignore_testing:
        return _load_test_data(values, data, name, save_key)

    if values.get("use_loop_as_key", False):
        data.insert_data(save_key, {}, values)

        for idx, key in enumerate(values["steps_value"]):
            api_request(values["requests"][idx], data, name,
                        f"{save_key}|{key}", ignore_testing)
    else:
        data.insert_data(save_key, [None] * len(values["requests"]), values)

        for idx, value in enumerate(values["requests"]):
            api_request(value, data, name, f"{save_key}|{idx}", ignore_testing)
Пример #7
0
def _load_test_data(values: dict, data: StepData, name, save_key):
    logger.info(f"Loading test data from 'exampledata/{name}.json'")
    try:
        with resources.open_resource(f"exampledata/{name}.json") as fp:
            data.insert_data(save_key, json.loads(fp.read()), values)
    except IOError as e:
        raise TestDataError(name) from e
Пример #8
0
def _save_audio(response, data: StepData, config: dict):
    post_generate = config.get("post_generate", {})
    extension = data.format(post_generate["file_extension"]) if post_generate.get("file_extension",
                                                                                  None) is not None else None
    # if multiple requests were used, get only the request with the audio file
    if config["generate"]["type"].startswith("request_multiple"):
        audio_idx = data.format(config["generate"]["audio_idx"])
        response = response[audio_idx]

    content_type = response["headers"]["content-type"]
    audio = response["content"]

    # if content type is JSON, try to decode JSON string with base64
    if content_type.startswith("application/json"):
        # get audio string
        audio = data_get_pattern(data.format(post_generate["audio_key"]), audio)
        # decode Audio Key with base64
        audio = base64.b64decode(audio)
    elif extension is None:
        # check if content type is an audio type
        if not content_type.startswith("audio"):
            raise InvalidContentTypeError(None, content_type, "'audio/*'")

        # get file extention from mime type:
        extension = mimetypes.guess_all_extensions(content_type)[0].replace(".", "")

    audio_path = resources.new_temp_resource_path(data.data["_pipe_id"], extension)

    with open(audio_path, "wb") as fp:
        fp.write(audio)

    return audio_path
Пример #9
0
def init_pipeline(data: StepData,
                  pipeline_id: str,
                  step_name: str,
                  idx=None,
                  config=None,
                  no_tmp_dir=False):
    config["job_name"] = data.get_config("job_name")

    if no_tmp_dir:
        config["attach_mode"] = "combined"
        config["output_path"] = data.get_config("output_path")
    else:
        config["attach_mode"] = "separate"
        config["output_path"] = get_relative_temp_resource_path(
            "", data.data["_pipe_id"])

    if not idx is None:
        config["job_name"] = f"{config['job_name']}_subtask_{idx}"

    config = {**STEPS_BASE_CONFIG, **config}

    # Avoid mutual imports
    from visuanalytics.analytics.control.procedures.pipeline import Pipeline

    return Pipeline(data.data["_job_id"],
                    pipeline_id,
                    step_name,
                    config,
                    attach_mode=True,
                    no_tmp_dir=no_tmp_dir)
Пример #10
0
def default(values: dict, data: StepData, config: dict):
    """Generiert eine Audiodatei mit der Python-Bibliothek gTTS.

    Wenn in der Konfiguration `sub_pairs` angegeben sind, werden diese den bisherigen `sub_pairs` hinzugefügt.
    `sub_pairs` sind bestimmte Wörter, die im Text ersetzt werden sollen.
    Beispiel: "z.B." soll vorgelesen werden als "zum Beispiel".

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :param config: Daten aus der Konfigurationsdatei
    :return:
    """
    for key in values:
        text = part.audio_parts(values[key]["parts"], data)

        sub_pairs = data.deep_format(config.get("sub_pairs", None), values=values)

        if sub_pairs:
            for key in sub_pairs:
                value = data.get_data(key, values)
                gtts.tokenizer.symbols.SUB_PAIRS.append((key, value))

        tts = gTTS(text, lang=data.format(config["lang"]))

        file_path = resources.new_temp_resource_path(data.data["_pipe_id"], data.format(config["format"]))
        tts.save(file_path)

        values[key] = file_path
Пример #11
0
def _combine(sequence_out: list, step_data: StepData, values: dict):
    try:
        args = ["ffmpeg", "-loglevel", "8", "-i"]
        concat = "concat:"
        file_temp = []
        output = resources.get_temp_resource_path(f"file.mkv", step_data.data["_pipe_id"])
        for idx, file in enumerate(sequence_out):
            temp_file = resources.get_temp_resource_path(f"temp{idx}.ts", step_data.data["_pipe_id"])
            args2 = ["ffmpeg", "-loglevel", "8", "-i", file, "-c", "copy", "-bsf:v", "h264_mp4toannexb", "-f", "mpegts",
                     temp_file]

            subprocess.run(args2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)

            file_temp.append(temp_file)
        for idx, file in enumerate(file_temp):
            if idx != 0:
                concat += "|"
            concat += file
        args.extend((concat, "-codec", "copy", output))

        subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)

        new_output = resources.get_out_path(values["out_time"], step_data.get_config("output_path", ""),
                                            step_data.get_config("job_name", ""))
        args = ["ffmpeg", "-loglevel", "8", "-i", output, new_output]

        subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)
        values["sequence"] = output
    except subprocess.CalledProcessError as e:
        raise FFmpegError(e.returncode, e.output.decode("utf-8")) from e
Пример #12
0
def transform_dict(values: dict, data: StepData):
    """Führt alle angegebenen `"transform"`-Funktionen für alle Werte eines Dictionaries aus.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for _ in data.loop_dict(data.get_data(values["dict_key"], values), values):
        transform(values, data)
Пример #13
0
def delete(values: dict, data: StepData):
    """
    Löscht die angegebenen Keys aus den daten

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for idx, key in data.loop_key(values["keys"], values):
        data.remove_data(key, values)
Пример #14
0
def copy(values: dict, data: StepData):
    """Kopiert einen Wert zu einem neuen Key.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for idx, key in data.loop_key(values["keys"], values):
        new_key = get_new_keys(values, idx)
        new_value = data.get_data(key, values)
        data.insert_data(new_key, new_value, values)
Пример #15
0
def request_multiple(values: dict,
                     data: StepData,
                     name: str,
                     save_key,
                     ignore_testing=False):
    """Fragt für einen variablen Key, mehrere Male gewünschte Daten einer API ab.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :param name: Testdatei, die geladen werden soll.
    :param save_key: Key, unter dem die Daten gespeichert werden.
    :param ignore_testing: Ob der Request durchgeführt werden soll, obwohl testing `true` ist.
    """

    if data.get_config("testing", False) and not ignore_testing:
        return _load_test_data(values, data, name, save_key)

    if data.get_data(values.get("use_loop_as_key", False), values, bool):
        data.insert_data(save_key, {}, values)
        for _, key in data.loop_array(values["steps_value"], values):
            fetch(values, data, f"{save_key}|{key}")
            waiting_time = data.get_data(
                values.get("timer_between_requests", 0.0), values, float)
            if waiting_time > 0.0:
                time.sleep(waiting_time)
    else:
        data.insert_data(save_key, [None] * len(values["steps_value"]), values)
        for idx, _ in data.loop_array(values["steps_value"], values):
            fetch(
                values,
                data,
                f"{save_key}|{idx}",
            )
Пример #16
0
def add_data(values: dict, data: StepData):
    """Fügt Daten zu einem neuen Key hinzu.

    Fügt die unter `"data"` angegebenen Daten zu einem neuen Key hinzu.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for new_key in values["new_keys"]:
        value = data.deep_format(values["data"], values=values)
        data.insert_data(new_key, value, values)
Пример #17
0
def _get_audio_config(values: dict, data: StepData):
    config = get_config()["audio"]
    custom_config = values["audio"].get("config", {})

    # if config in step-JSON is present, use that config
    config.update(custom_config)

    # init _audio with audio config
    data.insert_data("_audio|_conf", config, {})

    return config
Пример #18
0
def calculate_mode(values: dict, data: StepData):
    """Bestimmt den am häufigsten in einem Array vorkommenden Wert.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)
        new_value = collections.Counter(value).most_common()[0][0]
        data.insert_data(new_key, new_value, values)
Пример #19
0
def select_range(values: dict, data: StepData):
    """Entfernt alle Werte aus `"array_key"`, die nicht in `"range"` sind.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    value_array = data.get_data(values["array_key"], values)
    range_start = data.get_data(values.get("range_start", 0), values, int)
    range_end = data.get_data(values["range_end"], values, int)

    data.insert_data(values["array_key"], value_array[range_start:range_end],
                     values)
Пример #20
0
def _copy_and_rename(src_file: str, values: dict, step_data: StepData):
    out_path = resources.path_from_root(step_data.get_config("output_path"))

    values["thumbnail"] = resources.get_out_path(
        values["out_time"],
        step_data.get_config("output_path"),
        step_data.get_config("job_name"),
        format=".png",
        thumbnail=True)
    shutil.copy(src_file, out_path)
    os.rename(os.path.join(out_path, os.path.basename(src_file)),
              values["thumbnail"])
Пример #21
0
def length(values: dict, data: StepData):
    """Gibt die Länge von Arrays (Listen), Strings, Tupeln und Dictionaries aus.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)

        data.insert_data(new_key, len(value), values)
Пример #22
0
def capitalize(values: dict, data: StepData):
    """Der erste Buchstabe jedes Worts in der Liste wird groß geschrieben.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)

        new_value = [each.capitalize() for each in value]
        data.insert_data(new_key, new_value, values)
Пример #23
0
def upper_case(values: dict, data: StepData):
    """Jedes Wort in der Liste wird komplett in Großbuchstaben geschrieben.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)

        new_value = [each.upper() for each in value]
        data.insert_data(new_key, new_value, values)
Пример #24
0
def seperator(values: dict, data: StepData):
    """Fügt Trennzeichen in einen Integer hinzu.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = int(data.get_data(key, values))
        new_key = get_new_keys(values, idx)

        new_value = '{:,}'.format(value).replace(
            ',', data.format(values["seperator"], values))
        data.insert_data(new_key, new_value, values)
Пример #25
0
def to_dict(values: dict, data: StepData):
    """Wandelt eine Liste aus Tupeln oder Arrays in ein Dictionary um.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    for idx, key in data.loop_key(values["keys"], values):
        value = data.get_data(key, values)
        new_key = get_new_keys(values, idx)
        new_value = dict(value)

        data.insert_data(new_key, new_value, values)
Пример #26
0
def convert(values: dict, data: StepData):
    """Konvertiert ein Datentyp in einen anderen Datentyp.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :return:
    """
    new_type = locate(values["to"])
    for idx, key in data.loop_key(values["keys"], values):
        new_key = get_new_keys(values, idx)
        value = new_type(data.get_data(key, values))

        data.insert_data(new_key, value, values)
Пример #27
0
def prepare_test(values: list, data, expected_data: dict, config=None):
    if config is None:
        config = {}

    step_data = StepData(config, "0", 0)
    step_data.insert_data("_req", data, {})
    transform({"transform": values}, step_data)

    # removed Temporary set data
    step_data.data.pop("_conf")
    step_data.data.pop("_pipe_id")
    step_data.data.pop("_job_id")

    return step_data.data, expected_data
Пример #28
0
def _build_params_array(values: dict, data: StepData, api_key_name: str,
                        req: dict):
    if req["params"] is None:
        req["params"] = {}

    for params in values["params_array"]:
        params_array = data.get_data(params["array"], values, list)
        data.deep_format(params_array, api_key_name, values)

        param = "".join([
            f"{data.format(params['pattern'], values)}{data.format(params.get('delimiter', ''), values)}"
            for _ in data.loop_array(params_array, values)
        ])
        req["params"][params["key"]] = param[:-1]
Пример #29
0
def _text_to_audio(data: StepData, values: dict, text: str, config: dict):
    sub_pairs = data.deep_format(config.get("sub_pairs", None), values=values)

    if sub_pairs:
        for key in sub_pairs:
            value = data.get_data(key, values)
            gtts.tokenizer.symbols.SUB_PAIRS.append((key, value))

    tts = gTTS(data.format(text, values), lang=data.format(config["lang"]))

    file_path = resources.new_temp_resource_path(data.data["_pipe_id"],
                                                 data.format(config["format"]))
    tts.save(file_path)
    return file_path
Пример #30
0
def _bi_calculate(values: dict, data: StepData, op):
    keys_right = values.get("keys_right", None)
    value_right = values.get("value_right", None)
    value_left = values.get("value_left", None)
    decimal = values.get("decimal", None)

    # TODO (max) May solve loop two key arrays better to support key, key1
    for idx, key in data.loop_key(values["keys"], values):
        key = data.get_data(key, values)
        new_key = get_new_keys(values, idx)

        if keys_right is not None:
            # If keys_right is present use that key
            right = data.get_data(keys_right[idx], values)
            res = op(key, right)
        elif value_right is not None:
            # If value_right is present use that value
            right = data.get_data(value_right, values, numbers.Number)
            res = op(key, right)
        else:
            # If value_left is present use that value
            left = data.get_data(value_left, values, numbers.Number)
            res = op(left, key)

        if decimal is not None:
            # If decimal is present round
            decimal = data.get_data(decimal, values, numbers.Number)
            res = round(res, decimal)

        data.insert_data(new_key, res, values)