MDB/mdb.py

218 lines
8.0 KiB
Python

import PySimpleGUI as sg
import json as js
import ui
class Helper:
def __init__(self):
self.song_file = "G:\\Working\\MDB\\song.txt"
self.dance_file = "G:\\Working\\MDB\\dance.txt"
self.song_file_json = "G:\\Working\\MDB\\songs.json"
def get_songs_dict(self, *args):
'''
Retrieves all Songs Containing the Input as a dictionary.
Parameters:
*args (str): Parameters to search for.
Returns:
list: List of song dicts containing all specified substrings.
'''
result_list = []
try:
with open(self.song_file_json, 'r') as file:
for line in file:
try:
song = js.loads(line)
except ValueError:
print(f"skipping{line}")
# Convert values to strings for substring search
if all(any(arg in str(value) for value in song.values()) for arg in args):
song["dance"] = song["dance"][0].split(":")
result_list.append(song)
except FileNotFoundError:
sg.popup_error('Datei wurde nicht gefunden.')
return 0
except IsADirectoryError:
sg.popup_error('The given Filepath is a directory')
return 0
except PermissionError:
sg.popup_error('The program has no permission to acces file')
return 0
return result_list
def get_songs_dict_beautified(self, dance_length, format, *args):
ugly_songs = self.get_songs_dict(*args)
beautiful_songs = []
beautiful_lists = []
if not ugly_songs:
return []
for song in ugly_songs:
dance_list = song["dance"]
match dance_length:
case "long":
song["dance"] = str(dance_list[1]) # Keep the second element for "long"
beautiful_songs.append(song)
case "short":
song["dance"] = str(dance_list[0]) # Keep the first element for "short"
beautiful_songs.append(song)
match format:
case "list":
for song in beautiful_songs:
beautiful_lists.append(list(song.values()))
print(beautiful_lists)
return beautiful_lists
def write_song_json(self, song, artist, album, duration, dance, comment):
"""
Writes multiple values as a single line to the song file: "{Song}{Artist}{Album}{Duration}{Dance}{comment}"
"""
#sets default duration to "00:00:00"
if duration == "":
duration = "00:00:00"
#validate the data
validation_result = self.validate_song(song, artist, album, duration, dance)
match validation_result:
case 0:
return validation_result
case 1:
return validation_result
case 2:
return validation_result
case 3:
return validation_result
#convert the data to a json object
dance_tuple = self.get_dance(dance)
song_dict = {"song":song,"artist":artist,"album":album,"duration":duration,"dance":dance_tuple,"comment":comment}
try:
with open(self.song_file_json, "a") as f:
f.write(f"{js.dumps(song_dict)}\n")
return None
except FileNotFoundError:
sg.popup_error('Datei wurde nicht gefunden.')
return 0
except IsADirectoryError:
sg.popup_error('The given Filepath is a directory')
return 0
except PermissionError:
sg.popup_error('The program has no permission to acces file')
return 0
def get_dance(self, input):
"""
Retrieves All Dances containing the Input
Parameters:
input (str): Substring to search for in the dance file.
Returns:
list: List of tuples containing matching short and long dances.
Empty list if no matches found.
"""
result_list = []
try:
with open(self.dance_file, 'r') as f:
for line in f:
short, long = line.strip().split(':')
if input == short or input == long:
result_list.append(f"{short}:{long}") # Append "short:long"
return result_list
except FileNotFoundError:
sg.popup_error('Datei wurde nicht gefunden.')
return 0
except IsADirectoryError:
sg.popup_error('The given Filepath is a directory')
return 0
except PermissionError:
sg.popup_error('The program has no permission to acces file')
return 0
def add_dance(self, short, long):
"""
Appends a new line to the dance file in the following format: "short:long"
Parameters:
short (str): Short name of the dance.
long (str): Full name of the dance.
"""
try:
with open(self.dance_file, "a") as f:
f.write(f"{short}:{long}\n")
except FileNotFoundError:
sg.popup_error('Datei wurde nicht gefunden.')
return 0
except IsADirectoryError:
sg.popup_error('The given Filepath is a directory')
return 0
except PermissionError:
sg.popup_error('The program has no permission to acces file')
return 0
def validate_time_format(self, string, delimiter=":"):
"""
Checks if string is in "hh:mm:ss" Format or in "mm:ss" format
Parameters:
string (str): the string to be checked.
delimiter (str): the delimiter between the numbers.
Returns:
bool: True, wenn der String gültig ist, False sonst.
"""
parts = string.split(delimiter)
if len(parts) == 2:
minute, second = parts
hour = "00"
elif len(parts) == 3:
hour, minute, second = parts
else:
return False
if not hour.isdigit() and minute.isdigit() and second.isdigit():
return False
hour = int(hour)
minute = int(minute)
second = int(second)
if not (0 <= hour < 24) or not (0 <= minute < 60) or not (0 <= second < 60):
return False
return True
def validate_song(self, song, artist, album, duration, dance):
"""
Validates a song based on its attributes.
Parameters:
song (str): The title of the song.
artist (str): The artist of the song.
album (str): The album of the song.
duration (int): The duration of the song.
dance (str): The dance style of the song.
Returns:
1: if song already is in the database
2: if the duration is invalid
3: if the dance is invalid
"""
# Check if the song already exists in the database
exists = self.get_songs_dict(song, artist, album, duration, dance)
dance_entry = self.get_dance(dance)
if exists and exists != 0:
sg.popup_error('This Song already exists')
return 1
if not self.validate_time_format(duration):
sg.popup_error('The Time Format is not Valid. Please use "00:00:00"')
return 2
# Check if the dance style is invalid
if dance_entry == 0:
return
if not dance_entry:
sg.popup_error('The Dance is not valid')
return 3
# Otherwise, return the dance style found in the database
return dance_entry
class Settings:
def __init__(self) -> None:
pass
if __name__ == "__main__":
app = ui.Main()
app.run()