410 lines
14 KiB
Python
Executable File
410 lines
14 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
import sqlite3
|
||
import json
|
||
import os
|
||
|
||
DB_PATH = 'songs.db'
|
||
SETTINGS_PATH = 'settings.json'
|
||
EXPORT_PATH = 'pesmi_export.txt'
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# PREDHODNE NASTAVITVE IN POVEZAVA NA BAZO
|
||
# ---------------------------------------------------------------------------
|
||
|
||
if not os.path.exists(SETTINGS_PATH):
|
||
print("Nastavitve manjkajo! Zaženi 'nastavitve.bat' najprej.")
|
||
exit()
|
||
|
||
with open(SETTINGS_PATH, "r", encoding="utf-8") as f:
|
||
settings = json.load(f)
|
||
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
|
||
cursor.execute('''CREATE TABLE IF NOT EXISTS songs (
|
||
id INTEGER PRIMARY KEY,
|
||
title TEXT,
|
||
lyrics TEXT
|
||
)''')
|
||
conn.commit()
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# POMOŽNE FUNKCIJE
|
||
# ---------------------------------------------------------------------------
|
||
|
||
def get_next_free_id(start: int = 792) -> int:
|
||
"""Vrne prvo prosto številko pesmi, ki je ≥ start (privzeto 792)."""
|
||
next_id = start
|
||
while True:
|
||
cursor.execute("SELECT 1 FROM songs WHERE id = ?", (next_id,))
|
||
if cursor.fetchone() is None:
|
||
return next_id
|
||
next_id += 1
|
||
|
||
def slovenski_kljuc(naslov: str) -> str:
|
||
nadom = {'č': 'cz', 'Č': 'Cz', 'š': 'sz', 'Š': 'Sz', 'ž': 'zz', 'Ž': 'Zz'}
|
||
return ''.join(nadom.get(z, z) for z in naslov).lower()
|
||
|
||
def prikazi_meni():
|
||
print("\nIzberi možnost:")
|
||
print("1. Dodaj pesem")
|
||
print("2. Uredi pesem")
|
||
print("3. Prestavi pesem")
|
||
print("4. Izbriši pesem")
|
||
print("5. Izvozi bazo v TXT")
|
||
print("6. Uvozi bazo iz TXT")
|
||
print("7. Izpiši kazalo")
|
||
print("9. Zapri program")
|
||
|
||
def uredi_vnos(lines):
|
||
processed, prazne = [], 0
|
||
for line in lines:
|
||
if line.strip() == "":
|
||
prazne += 1
|
||
continue
|
||
if prazne:
|
||
processed.extend([""] * prazne)
|
||
prazne = 0
|
||
if line.strip().startswith("- "):
|
||
line = line.replace("- ", "• ", 1)
|
||
processed.append(line)
|
||
if prazne:
|
||
processed.extend([""] * prazne)
|
||
return "\n".join(processed)
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# FUNKCIJE POSAMEZNIH MENIJSKIH OPCIJ
|
||
# ---------------------------------------------------------------------------
|
||
|
||
def dodaj_pesem():
|
||
# -- izbira št. pesmi ----------------------------------------------------
|
||
while True:
|
||
try:
|
||
song_id = int(input("Vnesi številko pesmi: "))
|
||
break
|
||
except ValueError:
|
||
print("Vnesi veljavno celo število!")
|
||
|
||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||
row = cursor.fetchone()
|
||
if row:
|
||
print(f"Želiš prepisati obstoječo pesem {song_id} – {row[0]}?")
|
||
predlagana = get_next_free_id()
|
||
print(f"Prva prosta številka nad 791 je {predlagana}.")
|
||
izbira = input("D = prepiši, N ali Enter = uporabi predlagano, "
|
||
"ali vnesi drugo številko: ").strip()
|
||
|
||
if izbira.lower() == "d":
|
||
pass
|
||
elif izbira.lower() == "n" or izbira == "":
|
||
song_id = predlagana
|
||
else:
|
||
try:
|
||
song_id = int(izbira)
|
||
except ValueError:
|
||
print("Neveljaven vnos – uporabljam predlagano številko.")
|
||
song_id = predlagana
|
||
|
||
# -- vnos besedila -------------------------------------------------------
|
||
title = input("Vnesi naslov pesmi: ")
|
||
print("Vnesi besedilo (prazna vrstica = presledek, dve prazni = nova kitica).\n"
|
||
"Ko končaš, vpiši 'konec'.")
|
||
|
||
lines = []
|
||
while True:
|
||
line = input()
|
||
if line.strip().lower() == "konec":
|
||
break
|
||
if line.strip().startswith("- "):
|
||
line = line.replace("- ", "• ", 1)
|
||
lines.append(line)
|
||
|
||
full_lyrics = uredi_vnos(lines)
|
||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||
(song_id, title, full_lyrics))
|
||
conn.commit()
|
||
print("Pesem uspešno shranjena!")
|
||
|
||
def uredi_pesem():
|
||
try:
|
||
song_id = int(input("Vnesi številko pesmi za urejanje: "))
|
||
except ValueError:
|
||
print("Uporabi celo število!")
|
||
return
|
||
|
||
cursor.execute("SELECT title, lyrics FROM songs WHERE id = ?", (song_id,))
|
||
result = cursor.fetchone()
|
||
if not result:
|
||
print("Pesem s to številko ne obstaja.")
|
||
return
|
||
|
||
print(f"Trenutni naslov: {result[0]}")
|
||
print(f"Trenutno besedilo:\n{result[1]}")
|
||
|
||
new_title = input("Nov naslov (pusti prazno za obdržanje): ")
|
||
print("Novo besedilo (vpiši 'konec' za zaključek, pusti prazno za obdržanje):")
|
||
|
||
lines = []
|
||
while True:
|
||
line = input()
|
||
if line.strip().lower() == "konec":
|
||
break
|
||
if line.strip().startswith("- "):
|
||
line = line.replace("- ", "• ", 1)
|
||
lines.append(line)
|
||
|
||
if new_title.strip() == "":
|
||
new_title = result[0]
|
||
new_lyrics = result[1] if len(lines) == 0 else uredi_vnos(lines)
|
||
|
||
cursor.execute("UPDATE songs SET title = ?, lyrics = ? WHERE id = ?",
|
||
(new_title, new_lyrics, song_id))
|
||
conn.commit()
|
||
print("Pesem uspešno posodobljena!")
|
||
|
||
def prestavi_pesem():
|
||
try:
|
||
old_id = int(input("Vnesi številko pesmi, ki jo želiš prestaviti: "))
|
||
new_id = int(input("Vnesi novo številko pesmi: "))
|
||
except ValueError:
|
||
print("Uporabi cela števila!")
|
||
return
|
||
|
||
cursor.execute("SELECT title, lyrics FROM songs WHERE id = ?", (old_id,))
|
||
vir = cursor.fetchone()
|
||
if vir is None:
|
||
print("Pesem s to številko ne obstaja.")
|
||
return
|
||
|
||
cursor.execute("SELECT title FROM songs WHERE id = ?", (new_id,))
|
||
cilj = cursor.fetchone()
|
||
if cilj:
|
||
print(f"Želiš prepisati obstoječo pesem {new_id} – {cilj[0]}?")
|
||
predlagana = get_next_free_id()
|
||
print(f"Prva prosta številka nad 791 je {predlagana}.")
|
||
izbira = input("D = prepiši, N ali Enter = predlagana, ali vnesi drugo številko: ").strip()
|
||
if izbira.lower() == "d":
|
||
pass
|
||
elif izbira.lower() == "n" or izbira == "":
|
||
new_id = predlagana
|
||
else:
|
||
try:
|
||
new_id = int(izbira)
|
||
except ValueError:
|
||
print("Neveljaven vnos – uporabljam predlagano številko.")
|
||
new_id = predlagana
|
||
|
||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||
(new_id, vir[0], vir[1]))
|
||
cursor.execute("DELETE FROM songs WHERE id = ?", (old_id,))
|
||
conn.commit()
|
||
print("Pesem uspešno prestavljena!")
|
||
|
||
def izbrisi_pesem():
|
||
try:
|
||
song_id = int(input("Vnesi številko pesmi za izbris: "))
|
||
except ValueError:
|
||
print("Uporabi celo število!")
|
||
return
|
||
|
||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||
row = cursor.fetchone()
|
||
if row is None:
|
||
print("Pesem s to številko ne obstaja.")
|
||
return
|
||
|
||
potrdi = input(f"Želiš res izbrisati pesem {song_id} – {row[0]}? (D/N): ").strip().lower()
|
||
if potrdi == "d":
|
||
cursor.execute("DELETE FROM songs WHERE id = ?", (song_id,))
|
||
conn.commit()
|
||
print("Pesem uspešno izbrisana!")
|
||
else:
|
||
print("Brisanje preklicano.")
|
||
|
||
def izvozi_bazo():
|
||
cursor.execute("SELECT id, title, lyrics FROM songs ORDER BY id")
|
||
pesmi = cursor.fetchall()
|
||
with open(EXPORT_PATH, "w", encoding="utf-8") as f:
|
||
for pesem in pesmi:
|
||
f.write("===\n")
|
||
f.write(f"{pesem[0]}\n{pesem[1]}\n{pesem[2]}\n")
|
||
print(f"Baza je bila izvožena v '{EXPORT_PATH}'.")
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 6. UVOZ BAZE Z NAPREDNO KONTROLO PODVOJENIH PESMI
|
||
# ---------------------------------------------------------------------------
|
||
|
||
def uvozi_bazo():
|
||
if not os.path.exists(EXPORT_PATH):
|
||
print(f"Datoteka '{EXPORT_PATH}' ne obstaja.")
|
||
return
|
||
|
||
with open(EXPORT_PATH, "r", encoding="utf-8") as f:
|
||
vsebina = f.read().replace('\r\n', '\n').replace('\r', '\n')
|
||
|
||
pesmi_raw = [p for p in vsebina.strip().split("===\n") if p.strip()]
|
||
|
||
duplicate_mode = None # 'd', 'n', 'p' ==> vedno prepiši / preskoči / nova ID
|
||
|
||
for pesem_raw in pesmi_raw:
|
||
vrstice = pesem_raw.strip().split("\n")
|
||
if len(vrstice) < 3:
|
||
print("Preskočena nepopolna pesem.")
|
||
continue
|
||
|
||
try:
|
||
song_id = int(vrstice[0])
|
||
except ValueError:
|
||
print("Neveljaven ID – preskočeno.")
|
||
continue
|
||
|
||
title = vrstice[1]
|
||
raw_lyrics_lines = vrstice[2:]
|
||
|
||
# -- predobdelava besedila ------------------------------------------
|
||
processed_lines, prazne = [], 0
|
||
for line in raw_lyrics_lines:
|
||
if line.strip().startswith("- "):
|
||
line = line.replace("- ", "• ", 1)
|
||
if line.strip() == "":
|
||
prazne += 1
|
||
continue
|
||
if prazne:
|
||
processed_lines.extend([""] * prazne)
|
||
prazne = 0
|
||
processed_lines.append(line)
|
||
if prazne:
|
||
processed_lines.extend([""] * prazne)
|
||
|
||
lyrics = "\n".join(processed_lines)
|
||
|
||
# -- obravnava podvojene številke -----------------------------------
|
||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||
exists = cursor.fetchone()
|
||
|
||
if exists:
|
||
# Če imamo globalni način, ga upoštevamo
|
||
if duplicate_mode is not None:
|
||
choice = duplicate_mode
|
||
else:
|
||
print(f"\nPozor: pesem št. {song_id} – \"{exists[0]}\" že obstaja.")
|
||
print("Izberi dejanje:")
|
||
print(" d … prepiši")
|
||
print(" n … preskoči")
|
||
print(" p … shrani pod prvo prosto številko ≥ 792")
|
||
print(" da … prepiši to in vse naslednje podvojene pesmi")
|
||
print(" na … preskoči to in vse naslednje podvojene pesmi")
|
||
print(" pa … shrani to in vse naslednje podvojene pesmi pod novo ID")
|
||
izbira = input("Tvoja izbira: ").strip().lower()
|
||
|
||
if izbira in {"da", "na", "pa"}:
|
||
duplicate_mode = izbira[0] # 'd', 'n', 'p'
|
||
choice = duplicate_mode
|
||
elif izbira in {"d", "n", "p"}:
|
||
choice = izbira
|
||
else:
|
||
print("Neznana izbira – pesem preskočena.")
|
||
continue
|
||
|
||
# izvajanje po izbrani logiki
|
||
if choice == "n":
|
||
print("Pesem preskočena.")
|
||
continue
|
||
elif choice == "p":
|
||
song_id = get_next_free_id()
|
||
print(f"Shranjujem pod novo številko {song_id}.")
|
||
# choice == 'd' -> prepis
|
||
|
||
# -- shranjevanje pesmi ---------------------------------------------
|
||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||
(song_id, title, lyrics))
|
||
|
||
conn.commit()
|
||
print("\nUvoz pesmi uspešen!")
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# DODATNE FUNKCIJE (kazalo, projekcija) – nespremenjene
|
||
# ---------------------------------------------------------------------------
|
||
|
||
def izpisi_kazalo():
|
||
poglavja = [
|
||
(13, " -- SLAVIMO GOSPODA -- "),
|
||
(13, "ADVENTNE"),
|
||
(27, "BOŽIČNA DEVETDNEVNICA"),
|
||
(39, "BOŽIČNE"),
|
||
(65, "POSTNE"),
|
||
(119, "VELIKONOČNE"),
|
||
(142, "ČAS MED LETOM"),
|
||
(160, "MARIJINE"),
|
||
(240, "SVETNIŠKE"),
|
||
(263, "ZAKRAMENTI"),
|
||
(383, "MAŠNE"),
|
||
(406, "DAROVANJSKE"),
|
||
(419, "OBHAJILNE"),
|
||
(470, "BLAGOSLOVNE"),
|
||
(497, "ZAKRAMENT SPRAVE"),
|
||
(505, "MAŠNIŠKO POSVEČENJE"),
|
||
(539, "POGREB"),
|
||
(696, "LITANIJE"),
|
||
(773, "KRIŽEV POT"),
|
||
(777, "ROŽNI VENEC"),
|
||
(786, "MISIJONSKE"),
|
||
(788, "ZAHVALNE"),
|
||
(790, "JUBILATE DEO in ON ŽIVI"),
|
||
(1273,"DRUGE PESMI"),
|
||
]
|
||
|
||
cursor.execute("SELECT id, title FROM songs ORDER BY id")
|
||
zaporedno = cursor.fetchall()
|
||
|
||
cursor.execute("SELECT id, title FROM songs")
|
||
abecedno = cursor.fetchall()
|
||
abecedno.sort(key=lambda x: slovenski_kljuc(x[1]))
|
||
|
||
with open("kazalo.txt", "w", encoding="utf-8") as f:
|
||
f.write("ZAPOREDNO KAZALO\n")
|
||
trenutno_poglavje, indeks = None, 0
|
||
|
||
for pesem in zaporedno:
|
||
while indeks < len(poglavja) and pesem[0] >= poglavja[indeks][0]:
|
||
trenutno_poglavje = poglavja[indeks][1]
|
||
f.write(f"\n--- {trenutno_poglavje} ---\n")
|
||
indeks += 1
|
||
f.write(f"{pesem[0]}\t{pesem[1]}\n")
|
||
|
||
f.write("\n\nABECEDNO KAZALO\n")
|
||
for pesem in abecedno:
|
||
f.write(f"{pesem[0]}\t{pesem[1]}\n")
|
||
|
||
print("Kazalo izpisano v 'kazalo.txt'.")
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# G L A V N I Z A G O N
|
||
# ---------------------------------------------------------------------------
|
||
|
||
def main():
|
||
while True:
|
||
prikazi_meni()
|
||
izbira = input("Vnesi številko možnosti: ").strip()
|
||
os.system('cls' if os.name == 'nt' else 'clear')
|
||
|
||
if izbira == "1": dodaj_pesem()
|
||
elif izbira == "2": uredi_pesem()
|
||
elif izbira == "3": prestavi_pesem()
|
||
elif izbira == "4": izbrisi_pesem()
|
||
elif izbira == "5": izvozi_bazo()
|
||
elif izbira == "6": uvozi_bazo()
|
||
elif izbira == "7": izpisi_kazalo()
|
||
elif izbira == "9":
|
||
print("Program se zapira …")
|
||
break
|
||
else:
|
||
print("Napačna izbira, poskusi znova.")
|
||
|
||
conn.close()
|
||
|
||
if __name__ == "__main__":
|
||
main()
|