Exemplo n.º 1
0
def append(values: dict, data: StepData):
    """Speichert den Wert unter `"key"` in einem Array.

    :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 = values["new_keys"][idx]
        new_key_format = data.format(values.get("append_type", "list"))

        try:
            result = data.get_data(new_key, values)
        except StepKeyError:
            if new_key_format == "string":
                data.insert_data(new_key, "", values)
            else:
                data.insert_data(new_key, [], values)

            result = data.get_data(new_key, values)

        if new_key_format == "string":
            result = result + data.format(values.get("delimiter", " ")) + value
            data.insert_data(new_key, result, values)
        else:
            result.append(value)
Exemplo n.º 2
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
Exemplo n.º 3
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
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
Exemplo n.º 5
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)
Exemplo n.º 6
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
Exemplo n.º 7
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)
Exemplo n.º 8
0
def storing(values: dict, data: StepData):
    """Schreibt die API-Daten nach Ausführung der `transform`-Typen in eine JSON-Datei.

    Als Dateiname wird der Jobname sowie das heutige Datum verwendet.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    if values.get("storing", None):
        for value in values["storing"]:
            new_data = _remove_keys(value, data,
                                    data.get_data(value["key"], values))
            name = data.format(value["name"])
            if value.get("safe_only_on_change", True):
                try:
                    with resources.open_specific_memory_resource(
                            data.get_config("job_name"), name, False) as fp:
                        old_data = json.loads(fp.read())
                    if old_data == new_data:
                        continue
                except (FileNotFoundError, IndexError):
                    pass
            with open(
                    resources.new_memory_resource_path(
                        data.get_config("job_name"), name), 'w') as fp:
                json.dump(new_data, fp)
            delete_memory_files(
                data.get_config("job_name"), value["name"],
                data.get_data(value.get("count", 10), values, int))
Exemplo n.º 9
0
def regex(values: dict, data: StepData):
    """Führt `"re.sub"` für die angegebenen Felder aus.
    regex (suche nach dieser Expression, replace_by (ersetze Expression durch), value (String in dem ersetzt werden soll)

    Geht nur für regex ohne backslash \

    :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)

        regex = data.format(values["regex"], values)
        find = fr"{regex}"
        replace_by = data.format(values["replace_by"], values)
        new_value = re.sub(find, replace_by, value)
        data.insert_data(new_key, new_value, values)
Exemplo n.º 10
0
def date_now(values: dict, data: StepData):
    """Generiert das heutige Datum und gibt es im gewünschten Format aus.

    Generiert das heutige Datum und gibt es im unter `"format"` angegebenen Format aus.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    new_key = values["new_key"]
    value = datetime.now()
    zeropaded_off = data.get_data(values.get("zeropaded_off", False), values,
                                  bool)
    if zeropaded_off:
        new_value = value.strftime(data.format(values["format"],
                                               values)).lstrip("0").replace(
                                                   " 0", " ")
    else:
        new_value = value.strftime(data.format(values["format"], values))
    data.insert_data(new_key, new_value, values)
Exemplo n.º 11
0
def _remove_keys(value, data: StepData, export_data):
    if value.get("exclude", None) is not None:
        export_data = copy.deepcopy(export_data)
        for key in value["exclude"]:
            key = data.format(key)
            try:
                data_remove_pattern(key, export_data)
            except StepKeyError:
                pass
    return export_data
Exemplo n.º 12
0
def text(overlay: dict, step_data: StepData, source_img, prev_paths, draw):
    """
    Methode, um Text auf ein gegebenes Bild zu schreiben mit dem Bauplan, der in overlay vorgegeben ist.

    :param overlay: Bauplan des zu schreibenden Overlays
    :param step_data: Daten aus der API
    :param source_img: Bild, auf welches geschrieben werden soll
    :param prev_paths: Alle Image-Baupläne und somit auch alle Pfade zu den bisher erstellen Bildern
    :param draw: Draw-Objekt
    """
    content = step_data.format(overlay["pattern"])
    draw_func = get_type_func(overlay, DRAW_TYPES, "anchor_point")

    draw_func(draw,
              (step_data.get_data(overlay["pos_x"], None, numbers.Number),
               step_data.get_data(overlay["pos_y"], None, numbers.Number)),
              content,
              step_data.get_data(overlay["font_size"], None, numbers.Number),
              step_data.format(overlay["color"]),
              step_data.format(overlay["font"]), overlay.get("width", None))
Exemplo n.º 13
0
def _create_query(values: dict, data: StepData):
    req = {}
    api_key_name = values.get("api_key_name", None)

    # Get/Format method and headers
    req["method"] = data.format(values.get("method", "get"))
    req["headers"] = data.deep_format(values.get("headers", None),
                                      api_key_name, values)

    # Get/Format body data
    req["body_type"] = data.format(values.get("body_type", "json"), values)

    if req["body_type"].__eq__("json"):
        req["json"] = data.deep_format(values.get("body", None), api_key_name,
                                       values)
    else:
        req["other"] = data.format(
            values["body"]) if "body" in values else None

        if values.get("body_encoding", None) is not None:
            req[req["body_type"]] = req[req["body_type"]].encode(
                values["body_encoding"])

    # Get/Format url
    req["url"] = data.format_api(values["url_pattern"], api_key_name, values)

    # Get/Format params
    req["params"] = data.deep_format(values.get("params", None), api_key_name,
                                     values)
    if values.get("params_array", None) is not None:
        _build_params_array(values, data, api_key_name, req)

    # Get/Format response, format
    req["res_format"] = data.format(values.get("response_format", "json"))
    # TODO use Format
    req["xml_config"] = data.deep_format(values.get("xml_config", {}),
                                         values=values)
    req["include_headers"] = data.get_data(
        values.get("include_headers", False), values, bool)

    return req
Exemplo n.º 14
0
def wind_direction(values: dict, data: StepData):
    """Wandelt einen String von Windrichtungen um.

    Funktion nur mit den wind_cdir_full-Werten aus der Weatherbit-API ausführbar.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    value = data.get_data(values["key"], values)
    new_key = get_new_key(values)
    delimiter = data.format(values["delimiter"], values)
    if value.find(delimiter) != -1:
        wind = value.split(delimiter)
        wind_1 = wind[0]
        wind_2 = wind[1]
        wind_dir_1 = data.format(values["dict"][wind_1]["0"], values)
        wind_dir_2 = data.format(values["dict"][wind_2]["0"], values)
        new_value = f"{wind_dir_1}-{wind_dir_2}"
    else:
        new_value = data.format(values["dict"][value]["1"], values)
    data.insert_data(new_key, new_value, values)
Exemplo n.º 15
0
def image(overlay: dict, step_data: StepData, source_img, prev_paths, draw):
    """
    Methode, um ein Bild in das `source_img` einzufügen, mit dem Bauplan, der in overlay vorgegeben ist.

    :param overlay: Bauplan des zu schreibenden Overlays
    :param step_data: Daten aus der API
    :param source_img: Bild, auf welches das Bild eingefügt werden soll
    :param prev_paths: Alle Image-Baupläne und somit auch alle Pfade zu den bisher erstellen Bildern
    :param draw: Draw-Objekt
    """
    if overlay.get("path", None) is None:
        image_name = step_data.format(overlay["image_name"])
        path = resources.get_resource_path(prev_paths[image_name])
    else:
        path = resources.get_image_path(step_data.format(overlay["path"]))
    icon = Image.open(path).convert("RGBA")
    if overlay.get("color_transparency", None) is not None:
        _color_to_transparent(icon,
                              step_data.format(overlay["color_transparency"]))
    if step_data.format(overlay.get("color", "RGBA")) != "RGBA":
        icon = icon.convert(step_data.format(overlay["color"]))
    if overlay.get("size_x", None) is not None and overlay.get(
            "size_y", None) is not None:
        icon = icon.resize([
            step_data.get_data(overlay["size_x"], None, numbers.Number),
            step_data.get_data(overlay["size_y"], None, numbers.Number)
        ], Image.LANCZOS)
    if overlay.get("pos_x", None) is not None and overlay.get(
            "pos_y", None) is not None:
        pos_x = step_data.get_data(overlay["pos_x"], None, numbers.Number)
        pos_y = step_data.get_data(overlay["pos_y"], None, numbers.Number)
    else:
        width_b, height_b = source_img.size
        width_i, height_i = icon.size
        pos_x = int(round((width_b - width_i) / 2))
        pos_y = int(round((height_b - height_i) / 2))
    if step_data.get_data(overlay.get("transparency", False), None, bool):
        source_img.alpha_composite(icon, (pos_x, pos_y))
    else:
        source_img.paste(icon, (pos_x, pos_y), icon)
Exemplo n.º 16
0
def translate(values: dict, data: StepData):
    """Setzt den Wert eines Keys zu einem neuen Key als Wert für die JSON.

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

        new_value = data.format(translation[value], values)
        data.insert_data(new_key, new_value, values)
Exemplo n.º 17
0
def timestamp(values: dict, data: StepData):
    """Wandelt einen UNIX-Zeitstempel in ein anderes Format um.

    Wandelt einen UNIX-Zeitstempel in ein anderes Format um, welches unter `"format"` angegeben wird. Ist zeropaded_off
    true, so wird aus z.B. 05 eine 5.

    :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)
        date = datetime.fromtimestamp(value)
        new_key = get_new_keys(values, idx)
        zeropaded_off = data.get_data(values.get("zeropaded_off", False),
                                      values, bool)
        if zeropaded_off:
            new_value = date.strftime(data.format(values["format"],
                                                  values)).lstrip("0").replace(
                                                      " 0", " ")
        else:
            new_value = date.strftime(data.format(values["format"], values))
        data.insert_data(new_key, new_value, values)
Exemplo n.º 18
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)
Exemplo n.º 19
0
def date_format(values: dict, data: StepData):
    """Ändert das Format des Datums und der Uhrzeit.

    Ändert das Format des Datums und der Uhrzeit, welches unter `"given_format"` angegeben wird, in ein gewünschtes
    anderes Format, welches unter `"format"` angegeben wird.

    :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)
        given_format = data.format(values["given_format"], values)
        date = datetime.strptime(value, given_format).date()
        new_key = get_new_keys(values, idx)
        zeropaded_off = data.get_data(values.get("zeropaded_off", False),
                                      values, bool)
        if zeropaded_off:
            new_value = date.strftime(data.format(values["format"],
                                                  values)).lstrip("0").replace(
                                                      " 0", " ")
        else:
            new_value = date.strftime(data.format(values["format"], values))
        data.insert_data(new_key, new_value, values)
Exemplo n.º 20
0
def alias(values: dict, data: StepData):
    """Erstzt einen Key durch einen neuen Key.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    for key, new_key in zip(values["keys"], values["new_keys"]):
        value = data.get_data(key, values)
        new_key = data.format(new_key, values)

        data.insert_data(new_key, value, values)

        if not data.get_data(values.get("keep_old", False), {}, bool):
            data.remove_data(key, values)
Exemplo n.º 21
0
def add_symbol(values: dict, data: StepData):
    """Fügt ein Zeichen, Symbol, Wort oder einen Satz zu einem Wert hinzu.

    Fügt ein Zeichen, Symbol, Wort oder einen Satz zu einem Wert hinzu. Dieses kann sowohl vor als auch hinter dem Wert
    stehen, der mit `"{_key}"` eingefügt wird. Außerdem kann man so einen Wert kopieren und einem neuen Key zuweisen, wenn
    man in unter `"pattern"` nur `"{_key}"` einsetzt.

    :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_values = data.format(values['pattern'], values)
        data.insert_data(new_key, new_values, values)
Exemplo n.º 22
0
def replace(values: dict, data: StepData):
    """Ersetzt ein Zeichen, Symbol, Wort, einen Satz oder eine ganzen Text in einem String.

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

        new_value = value.replace(
            data.format(values["old_value"], values),
            data.format(values["new_value"], values),
            data.get_data(values.get("count", -1), values, int))
        data.insert_data(new_key, new_value, values)
Exemplo n.º 23
0
def join(values: dict, data: StepData):
    """Fügt Elemente einer Liste zu einem String zusammen mit jeweils einem Delimiter dazwischen.

    :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)
        delimiter = data.format(values.get("delimiter", ""), values)

        new_value = delimiter.join(value)

        data.insert_data(new_key, new_value, values)
Exemplo n.º 24
0
def random_value(values: dict, data: StepData):
    """Wählt random einen Wert aus einem Array oder einem Dictionary (zu einem bestimmten Key) aus.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    """
    if "array" in values:
        for key in values["new_keys"]:
            array = data.get_data(values["array"], values, list)
            length = len(array)

            rand = randint(0, length - 1)
            new_value = data.format(array[rand], values)
            data.insert_data(key, new_value, values)
    elif "dict" in values:
        for idx, key in data.loop_key(values["keys"], values):
            new_key = get_new_keys(values, idx)
            new_values = data.get_data(values.get("dict", None), values, dict)
            value = str(data.get_data(key, values))
            length = len(new_values[value])

            rand = randint(0, length - 1)
            new_value = data.format(new_values[value][rand], values)
            data.insert_data(new_key, new_value, values)
Exemplo n.º 25
0
def split_string(values: dict, data: StepData):
    """Teilt einen String am angegebenen Trennzeichen.

    Das Trennzeichen können auch mehrere Zeichen sein. Soll die Groß- und Kleinschreibung des Trennzeichens (delimiter) ignoriert werden, setzte `ignore_case` auf `true`.

    :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)
        delimiter = data.format(values.get("delimiter", " "), values)
        new_key = get_new_keys(values, idx)

        if data.get_data(values.get("ignore_case", False), values, bool):
            new_value = re.split(delimiter, value, flags=re.IGNORECASE)
        else:
            new_value = re.split(delimiter, value)
        data.insert_data(new_key, new_value, values)
Exemplo n.º 26
0
def custom(values: dict, data: StepData, config: dict):
    """Generiert eine Audiodatei mithilfe einer bestimmten TTS-API und Konfigurationen dafür.

    :param values: Werte aus der JSON-Datei
    :param data: Daten aus der API
    :param config: Daten aus der Konfigurationsdatei
    :return:
    """
    logger.info("Generate audio with custom audio config")

    _prepare_custom(config.get("prepare", None), data, config)

    for key in values:
        text = part.audio_parts(values[key]["parts"], data)

        if text[1]:

            data.data["_audio"]["text"] = text[0]
            generate = config["generate"]
            generate["include_headers"] = True
            api_request(generate, data, "audio", "_audio|gen", True)

            values[key] = _save_audio(data.get_data("_audio|gen", values),
                                      data, config)

        else:
            audio_list = []
            for item in values[key]["parts"]:
                if item["type"] == "text":
                    data.data["_audio"]["text"] = data.format(
                        item["pattern"], values)
                    generate = config["generate"]
                    generate["include_headers"] = True
                    api_request(generate, data, "audio", "_audio|gen", True)
                    audio_list.append(
                        _save_audio(data.get_data("_audio|gen", values), data,
                                    config))
                if item["type"] == "file":
                    audio_list.append(resources.get_audio_path(item["path"]))

            values[key] = _audios_to_audio(audio_list, data)
Exemplo n.º 27
0
def generate_diagram(values: dict, step_data: StepData, prev_paths):
    """
    Alte Implementierung der Diagramme für alte Job-Konfigurationen
    """
    data = step_data.format(values["data"])
    data = data[1:len(data) - 1].split(", ")
    data = list(map(float, data))
    days = []
    labels = None
    if values.get("bar_label", None) is not None:
        labels = step_data.format(values["bar_label"])
        labels = labels[1:len(labels) - 1].split(", ")
        labels = list(map(str, labels))
    if step_data.format(values.get("label_use_date", False)):
        now = datetime.now()
        for hop_value in range(len(data)):
            day = now - timedelta(days=hop_value)
            days.insert(0, day.strftime('%d.%m'))
    else:
        days = step_data.format(values["label"])
        days = days.replace("'", "")
        days = days[1:len(days) - 1].split(", ")
        days = list(map(str, days))
        if values.get("label_append", None) is not None:
            replace_cities = values["label_append"]
            for idx, city in enumerate(days):
                for replace_city in replace_cities:
                    if city == replace_city:
                        label_append_value = str(values["label_append_value"])
                        label_append_value = label_append_value.replace(
                            "_idx", str(idx))
                        days[idx] = city + " " + step_data.format(
                            label_append_value)
    plt.rcParams.update(
        {'font.size': step_data.format(values.get("label_size", 18))})
    fig = plt.figure(figsize=[
        step_data.format(values.get("plot_size_x", 20)),
        step_data.format(values.get("plot_size_y", 10))
    ])
    ax = fig.add_subplot(111)

    if step_data.format(values.get("sorted", False)):
        if labels is None:
            days, data = zip(*sorted(zip(days, data)))
        else:
            days, data, labels = zip(*sorted(zip(days, data, labels)))

    for axis in ['top', 'bottom', 'left', 'right']:
        ax.spines[axis].set_linewidth(
            step_data.format(values.get("axis_depth", 1)))

    if values.get("grid_axis", None) is not None:
        ax.grid(axis=step_data.format(values["grid_axis"]),
                color=step_data.format(values.get("grid_color", "grey")))
    if step_data.format(values["plot_type"]) == "bar_chart":
        ax.set_yticks(np.arange(len(days)))
        ax.set_yticklabels(days)
        if step_data.get_config("marked_city", None) is not None:
            for l in ax.get_yticklabels():
                if l.get_text() == step_data.format(
                        step_data.get_config("marked_city", "")):
                    l.set_fontweight(550)
        ax.invert_yaxis()  # labels von oben nach unten

        bar_list = plt.barh(
            np.arange(len(days)),
            data,
            color=(step_data.format(values["label_color"].get("r", 0)),
                   step_data.format(values["label_color"].get("g", 0)),
                   step_data.format(values["label_color"].get("b", 0)),
                   step_data.format(values["label_color"].get("t", 1))))

    elif step_data.format(values["plot_type"]) == "column_chart":
        bar_list = plt.bar(
            days,
            data,
            color=(step_data.format(values["label_color"].get("r", 0)),
                   step_data.format(values["label_color"].get("g", 0)),
                   step_data.format(values["label_color"].get("b", 0)),
                   step_data.format(values["label_color"].get("t", 1))))
    else:
        raise
    if step_data.format(values.get("use_extended_labels", False)):
        current_value = 0
        x_label_list = [current_value]
        max_value = max(data)
        hop_value = 10
        hop_values = values.get("extended_labels_map", None)
        if hop_values is not None:
            for entry in hop_values:
                if entry["value"] < max_value:
                    hop_value = entry["step"]
        while current_value < max_value:
            current_value = current_value + hop_value
            x_label_list.append(current_value)
        counter = 0
        counters = values.get("extended_labels_append", None)
        if counters is not None:
            for entry in counters:
                if entry["value"] < max_value:
                    counter = entry["amount"]
        while counter != 0:
            current_value = current_value + hop_value
            x_label_list.append(current_value)
            counter = counter - 1
        ax.set_xticks(x_label_list)

    for idx, b in enumerate(bar_list):
        color_not_set = True
        for entry in values["bar_colors"]["list"]:
            if data[idx] > step_data.format(entry["number"]):
                b.set_color(step_data.format(entry["color"]))
                color_not_set = False
            if color_not_set:
                b.set_color(step_data.format(values["bar_colors"]["default"]))

    plt.xticks(rotation=step_data.format(values.get("label_rotation", 0)))
    plt.tight_layout()

    if values.get("bar_label", None) is not None:
        rects = ax.patches
        for rect, label, data, days in zip(rects, labels, data, days):
            if step_data.format(values.get("show_bar_label_sign", False)):
                if label[0] != '-' and float(label) != 0.0:
                    label = "+" + label
                if float(label) == 0.0:
                    label = "\u00B10"
            label = str(data) + " / " + label
            if step_data.get_config("marked_city", None) is not None:
                if days == step_data.format(
                        step_data.get_config("marked_city", "")):
                    ax.text(rect.get_width() + 0.4,
                            (rect.get_y() + rect.get_height() / 2) + 0.2,
                            label,
                            fontsize=step_data.format(
                                values["label_fontsize"]),
                            fontweight=550)
                else:
                    ax.text(rect.get_width() + 0.4,
                            (rect.get_y() + rect.get_height() / 2) + 0.2,
                            label,
                            fontsize=step_data.format(
                                values["label_fontsize"]))
    file = resources.new_temp_resource_path(step_data.data["_pipe_id"], "png")
    plt.savefig(file, transparent=True)
    return file