Hilfe bei einem Script

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Xork2
User
Beiträge: 11
Registriert: Samstag 23. November 2019, 20:50

Hallo liebes Forum,

wir haben ein Webradio und da läuft folgende Regelung:
- Es gibt zwei Ordner, aus denen sich das Script (playlist.py) die Songs zieht. Einmal von 10-0 und einmal von 0 - 10. Nun wollen wir aber folgende Struktur:

0 – 6 > NightRotation
6 – 12 > MiddayRotation
12 – 18 > DayRotation
18 – 24 > AbendRotation

Leider sind wir was Python angeht völlige Noobs, und unser PRogrammierer ist aufgrund von Studium zeitlich nicht mehr in der Lage, mitzumachen. Daher würde ich mich freuen, wenn ihr uns dieses Problem löst :-)


Code: Alles auswählen

#!/usr/bin/env python

heavyRotationPercentage = 1.0 / 2.0

import os
import random
import pickle
import datetime

directory = os.path.dirname(os.path.abspath(__file__))
heavyRotationDir = os.path.join(directory, "HeavyRotation")
normalRotationDir = os.path.join(directory, "NormalRotation")
oldRotationDir = os.path.join(directory, "OldRotation")
jinglesDir = os.path.join(directory, "Jingles")
statusFile = os.path.join(directory, "status.txt")
currentHour = datetime.datetime.now().hour

status = [('','')]*8

if os.path.isfile(statusFile):
    with open(statusFile, "rb") as f:
        status = pickle.load(f)
lastFiles = [i[0] for i in status]

fileListFilter = lambda fileList: [fileName for fileName in fileList if
                                   fileName not in lastFiles and fileName[-4:] == ".mp3"]

choosenFileDir = False
choosenFileList = False


if status[-1][1]!=jinglesDir:
    #Letzte Track war kein Jingle
    choosenFileDir = jinglesDir
    choosenFileList = fileListFilter(os.listdir(jinglesDir))


if currentHour >= 10 and choosenFileDir == False:
    #Von 10:00 bis 24:00 aus der normalen / Heavy Rotation waehlen
    filesInHeavyRotation = fileListFilter(os.listdir(heavyRotationDir))
    filesInNormalRotation = fileListFilter(os.listdir(normalRotationDir))
    if random.random() <= heavyRotationPercentage and len(filesInHeavyRotation) > 0:
        choosenFileDir = heavyRotationDir
        choosenFileList = filesInHeavyRotation
    elif len(filesInNormalRotation) > 0:
        choosenFileDir = normalRotationDir
        choosenFileList = filesInNormalRotation

if choosenFileDir == False:
    # Von 00:00 bis 10:00 (oder wenn nichts anderes gefunden wurde) aus der alten Rotation waehlen
    choosenFileDir = oldRotationDir
    choosenFileList = fileListFilter(os.listdir(oldRotationDir))


choosenFile = random.choice(choosenFileList)

with open(statusFile, "wb") as f:
    status.append((choosenFile, choosenFileDir))
    pickle.dump(status[1:],f)

print os.path.join(choosenFileDir, choosenFile)

Vielen lieben dank :)
Benutzeravatar
__blackjack__
User
Beiträge: 14030
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Xork2: Die Beschreibung stimmt nicht so ganz mit dem Programm überein, denn da gibt es *drei* Ordner für Musik (und einen für Jingles).

Lernt doch selbst Python, dann seid Ihr nicht auf andere angewiesen.

Das sollte man sowieso komplett neu schreiben. Zuerst einmal weil es noch in Python 2 ist, was nur noch etwas mehr als einen Monat von den Entwicklern unterstützt wird. Und dann ist das kein wirklich guter Code. Viel zu viel Code in einem grossen Batzen der zudem auch noch auf Modulebene statt in Funktionen steht. Die Namensschreibweise entspricht nicht den Konventionen. Es gibt Namen die für verschiedene Typen verwendet werden, weshalb man nicht einfach die ansonsten unnötigen vergleiche mit literalen `True`/`False` weglassen kann. ``lambda`` wird falsch verwendet. Worfür es verwendet wird ist eigentlich ein Job für das `glob()`-Modul bzw. wenn man modernes Python schreiben will für die `glob()`-Methode von einem `pathlib.Path`-Objekt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Xork2: Habe das vorhandene mal auf Python 3 portiert und modernisiert. Ausserdem auf Funktionen aufgeteilt um die Code-Wiederholungen einzudämmen und die Struktur einfacher zu machen. Das Speicherformat ist nun auch einfacher: eine JSON-Datei mit den letzten Pfadnamen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import datetime
import json
import random
from pathlib import Path

MAX_RECENTLY_PLAYED = 8
HEAVY_ROTATION_PERCENTAGE = 0.5

BASE_PATH = Path(__file__).absolute().parent
HEAVY_ROTATION_PATH = BASE_PATH / "HeavyRotation"
NORMAL_ROTATION_PATH = BASE_PATH / "NormalRotation"
OLD_ROTATION_PATH = BASE_PATH / "OldRotation"
JINGLES_PATH = BASE_PATH / "Jingles"
STATUS_FILE_PATH = BASE_PATH / "status.json"


def is_jingle(file_path):
    return file_path.parent == JINGLES_PATH


def get_fresh_file_paths(recently_played_file_paths, folder_path):
    return [
        path
        for path in folder_path.glob("*.mp3")
        if path not in recently_played_file_paths
    ]


def choose_rotation(recently_played_file_paths):
    if recently_played_file_paths and not is_jingle(
        recently_played_file_paths[-1]
    ):
        return get_fresh_file_paths(recently_played_file_paths, JINGLES_PATH)

    #
    # Von 10:00 bis 24:00 aus der normalen / Heavy Rotation wählen.
    #
    if datetime.datetime.now().hour >= 10:
        heavy_rotation_filenames = get_fresh_file_paths(
            recently_played_file_paths, HEAVY_ROTATION_PATH
        )
        if (
            heavy_rotation_filenames
            and random.random() <= HEAVY_ROTATION_PERCENTAGE
        ):
            return heavy_rotation_filenames

        normal_rotation_filenames = get_fresh_file_paths(
            recently_played_file_paths, NORMAL_ROTATION_PATH
        )
        if normal_rotation_filenames:
            return normal_rotation_filenames

    #
    # Von 00:00 bis 10:00 (oder wenn nichts anderes gefunden wurde) aus der
    # alten Rotation wählen.
    #
    return get_fresh_file_paths(recently_played_file_paths, OLD_ROTATION_PATH)


def main():
    try:
        with STATUS_FILE_PATH.open(encoding="utf-8") as file:
            recently_played_file_paths = list(map(Path, json.load(file)))
    except FileNotFoundError:
        recently_played_file_paths = []

    chosen_file_path = random.choice(
        choose_rotation(recently_played_file_paths)
    )
    recently_played_file_paths.append(chosen_file_path)
    
    with STATUS_FILE_PATH.open(encoding="utf-8") as file:
        json.dump(
            list(map(str, recently_played_file_paths[-MAX_RECENTLY_PLAYED:])),
            file,
        )

    print(chosen_file_path)


if __name__ == "__main__":
    main()
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Xork2
User
Beiträge: 11
Registriert: Samstag 23. November 2019, 20:50

__blackjack__ hat geschrieben: Sonntag 24. November 2019, 02:48 @Xork2: Habe das vorhandene mal auf Python 3 portiert und modernisiert. Ausserdem auf Funktionen aufgeteilt um die Code-Wiederholungen einzudämmen und die Struktur einfacher zu machen. Das Speicherformat ist nun auch einfacher: eine JSON-Datei mit den letzten Pfadnamen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import datetime
import json
import random
from pathlib import Path

MAX_RECENTLY_PLAYED = 8
HEAVY_ROTATION_PERCENTAGE = 0.5

BASE_PATH = Path(__file__).absolute().parent
HEAVY_ROTATION_PATH = BASE_PATH / "HeavyRotation"
NORMAL_ROTATION_PATH = BASE_PATH / "NormalRotation"
OLD_ROTATION_PATH = BASE_PATH / "OldRotation"
JINGLES_PATH = BASE_PATH / "Jingles"
STATUS_FILE_PATH = BASE_PATH / "status.json"


def is_jingle(file_path):
    return file_path.parent == JINGLES_PATH


def get_fresh_file_paths(recently_played_file_paths, folder_path):
    return [
        path
        for path in folder_path.glob("*.mp3")
        if path not in recently_played_file_paths
    ]


def choose_rotation(recently_played_file_paths):
    if recently_played_file_paths and not is_jingle(
        recently_played_file_paths[-1]
    ):
        return get_fresh_file_paths(recently_played_file_paths, JINGLES_PATH)

    #
    # Von 10:00 bis 24:00 aus der normalen / Heavy Rotation wählen.
    #
    if datetime.datetime.now().hour >= 10:
        heavy_rotation_filenames = get_fresh_file_paths(
            recently_played_file_paths, HEAVY_ROTATION_PATH
        )
        if (
            heavy_rotation_filenames
            and random.random() <= HEAVY_ROTATION_PERCENTAGE
        ):
            return heavy_rotation_filenames

        normal_rotation_filenames = get_fresh_file_paths(
            recently_played_file_paths, NORMAL_ROTATION_PATH
        )
        if normal_rotation_filenames:
            return normal_rotation_filenames

    #
    # Von 00:00 bis 10:00 (oder wenn nichts anderes gefunden wurde) aus der
    # alten Rotation wählen.
    #
    return get_fresh_file_paths(recently_played_file_paths, OLD_ROTATION_PATH)


def main():
    try:
        with STATUS_FILE_PATH.open(encoding="utf-8") as file:
            recently_played_file_paths = list(map(Path, json.load(file)))
    except FileNotFoundError:
        recently_played_file_paths = []

    chosen_file_path = random.choice(
        choose_rotation(recently_played_file_paths)
    )
    recently_played_file_paths.append(chosen_file_path)
    
    with STATUS_FILE_PATH.open(encoding="utf-8") as file:
        json.dump(
            list(map(str, recently_played_file_paths[-MAX_RECENTLY_PLAYED:])),
            file,
        )

    print(chosen_file_path)


if __name__ == "__main__":
    main()

Mega geil, vielen Dank.

Könntest du vielleicht noch:

0 – 6 > NightRotation
6 – 12 > MiddayRotation
12 – 18 > DayRotation
18 – 24 > AbendRotation

Da irgendwie einfügen? :/ Das wäreecht großartig. :)))) Wäre mehr als dankbar
Xork2
User
Beiträge: 11
Registriert: Samstag 23. November 2019, 20:50

__blackjack__ hat geschrieben: Sonntag 24. November 2019, 01:42 @Xork2: Die Beschreibung stimmt nicht so ganz mit dem Programm überein, denn da gibt es *drei* Ordner für Musik (und einen für Jingles).

Lernt doch selbst Python, dann seid Ihr nicht auf andere angewiesen.

Das sollte man sowieso komplett neu schreiben. Zuerst einmal weil es noch in Python 2 ist, was nur noch etwas mehr als einen Monat von den Entwicklern unterstützt wird. Und dann ist das kein wirklich guter Code. Viel zu viel Code in einem grossen Batzen der zudem auch noch auf Modulebene statt in Funktionen steht. Die Namensschreibweise entspricht nicht den Konventionen. Es gibt Namen die für verschiedene Typen verwendet werden, weshalb man nicht einfach die ansonsten unnötigen vergleiche mit literalen `True`/`False` weglassen kann. ``lambda`` wird falsch verwendet. Worfür es verwendet wird ist eigentlich ein Job für das `glob()`-Modul bzw. wenn man modernes Python schreiben will für die `glob()`-Methode von einem `pathlib.Path`-Objekt.
Da hast du ansich Recht, aber bei us laufen nur noch enige Streams auf dieser Basis. Ist sicher kein guter Grund, aber aus zeitlichen Gründen ist e derzeit für mich schwierig, diese Sprache zu erlernen und auf das bereits bestehende anzuwenden, da wir mehrere Bereiche haben, an denen wir gerade schrauben. Sicher werde ich mir da mal im nächsten Jahr ein Buch oder paar Tuts zur Hand nehmen :)
Antworten