commit e7c870cf962cc5a5d81e0aa82dda60d1ff84c367
parent 20f2333605be1a355087ffd9b39c9e4f14d0e6cf
Author: Sivaldo <gxixtx@xsxixvxaxlxdxoxdxaxvxix.xcxoxm>
Date: Mon, 10 Aug 2026 15:20:45 -0300
feat(culto): adicionar categorias de músicas e ajustar cabeçalhos
Diffstat:
| M | .local/bin/culto | | | 92 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 70 insertions(+), 22 deletions(-)
diff --git a/.local/bin/culto b/.local/bin/culto
@@ -127,14 +127,15 @@ def slides_read(rows, ref_label, no_cover, resp):
if resp:
for i, row in enumerate(rows):
label = "DIRIGENTE" if i % 2 == 0 else "IGREJA"
- out += [f"{label}\n{row['verse']}. {row['text']}", ""]
+ header = f"{row['book']} {row['chapter']} ({label})"
+ out += [f"{header}\n{row['verse']}. {row['text']}", ""]
else:
full_text = " ".join(f"{r['verse']}. {r['text']}" for r in rows)
chunks = _chunks(full_text, SLIDE_WIDTH)
for i, chunk in enumerate(chunks):
pre = "... " if i > 0 else ""
pos = " ..." if i < len(chunks) - 1 else ""
- out += [f"{pre}{chunk}{pos}", ""]
+ out += [f"{ref_label}\n{pre}{chunk}{pos}", ""]
return "\n".join(out)
def terminal_read(rows, ref_label):
@@ -215,14 +216,15 @@ clear_sent() {
_ensure_musicas() {
if [ ! -f "$MUSICAS_FILE" ]; then
- echo "{}" > "$MUSICAS_FILE" # Cria vazio se não existir
+ # Cria vazio, já com as categorias, se não existir
+ printf '{\n "Hinos": {},\n "Salmos": {},\n "Cânticos Espirituais": {}\n}\n' > "$MUSICAS_FILE"
fi
}
_render_json_song() {
local title="$1"
MUSICAS_FILE="$MUSICAS_FILE" python3 - "$title" <<'PYEOF'
-import sys, json, os, signal
+import sys, json, os, re, signal
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
@@ -230,12 +232,25 @@ musicas_file = os.environ["MUSICAS_FILE"]
target_title = sys.argv[1]
with open(musicas_file, encoding='utf-8') as f:
- songs = json.load(f)
-
-if target_title in songs:
- print(target_title)
- print("\n\n")
- for stanza in songs[target_title]:
+ categorias = json.load(f)
+
+# Procura o título em qualquer categoria (Hinos / Salmos / Cânticos Espirituais)
+stanzas = None
+for cat_songs in categorias.values():
+ if target_title in cat_songs:
+ stanzas = cat_songs[target_title]
+ break
+
+if stanzas is not None:
+ m = re.match(r'^(\d+(?:-[A-Za-z])?)\s*-\s*.+$', target_title)
+ if m:
+ print(f"HINO {m.group(1)}")
+ print("\n\n")
+ elif re.search(r'salmo', target_title, re.IGNORECASE):
+ print(target_title)
+ print("\n\n")
+
+ for stanza in stanzas:
print(stanza)
print("\n")
else:
@@ -248,9 +263,13 @@ pick_song() {
_ensure_musicas || return 1
local chosen
- # Adicionado o signal import e handler aqui também no one-liner
- chosen=$(python3 -c "import json, signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL); data=json.load(open('$MUSICAS_FILE')); print('\n'.join(sorted(data.keys())))" \
- | fzf --reverse --prompt="Música: ")
+ chosen=$(python3 -c "
+import json, signal
+signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+data = json.load(open('$MUSICAS_FILE'))
+titulos = sorted(t for cat_songs in data.values() for t in cat_songs)
+print('\n'.join(titulos))
+" | fzf --reverse --prompt="Música: ")
[ -z "$chosen" ] && return 0
@@ -274,6 +293,8 @@ action = sys.argv[1]
title = sys.argv[2]
tmp_md = sys.argv[3]
+CATEGORIAS = ["Hinos", "Salmos", "Cânticos Espirituais"]
+
if os.path.exists(musicas_file):
with open(musicas_file, 'r', encoding='utf-8') as f:
try:
@@ -283,26 +304,48 @@ if os.path.exists(musicas_file):
else:
songs = {}
+# Garante que as categorias existam
+for c in CATEGORIAS:
+ songs.setdefault(c, {})
+
+def find_category(title):
+ """Procura em qual categoria o título já existe. None se for novo."""
+ for cat in CATEGORIAS:
+ if title in songs.get(cat, {}):
+ return cat
+ return None
+
+def infer_category(title):
+ """Para músicas novas: decide a categoria pelo padrão do título."""
+ if re.match(r'^\d+(?:-[A-Za-z])?\s*-\s*.+$', title):
+ return "Hinos"
+ if re.search(r'salmo', title, re.IGNORECASE):
+ return "Salmos"
+ return "Cânticos Espirituais"
+
if action == "extract":
- text = "\n\n".join(songs.get(title, []))
+ cat = find_category(title)
+ text = "\n\n".join(songs.get(cat, {}).get(title, [])) if cat else ""
with open(tmp_md, 'w', encoding='utf-8') as f:
f.write(f"# {title}\n\n{text}\n")
-
+
elif action == "save":
with open(tmp_md, 'r', encoding='utf-8') as f:
content = f.read()
-
+
# Remove o título em markdown (ex: # Nome da música)
content = re.sub(r'^#.*\n?', '', content, flags=re.MULTILINE)
-
+
# Separa os blocos (estrofes) por linhas em branco
stanzas = [b.strip() for b in re.split(r'\n{2,}', content) if b.strip()]
-
+
if stanzas:
- songs[title] = stanzas
+ # Se já existe em alguma categoria, atualiza lá; senão, infere a categoria
+ cat = find_category(title) or infer_category(title)
+ songs[cat][title] = stanzas
with open(musicas_file, 'w', encoding='utf-8') as f:
json.dump(songs, f, ensure_ascii=False, indent=2)
- print(f"✅ Música salva com sucesso no JSON!")
+ print(f"✅ Música salva com sucesso em '{cat}'!")
else:
print("⚠️ Nenhuma estrofe encontrada. Alteração descartada.")
PYEOF
@@ -329,8 +372,13 @@ edit_song() {
_ensure_musicas || return 1
local chosen
- chosen=$(python3 -c "import json, signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL); data=json.load(open('$MUSICAS_FILE')); print('\n'.join(sorted(data.keys())))" \
- | fzf --reverse --prompt="Editar Música: ")
+ chosen=$(python3 -c "
+import json, signal
+signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+data = json.load(open('$MUSICAS_FILE'))
+titulos = sorted(t for cat_songs in data.values() for t in cat_songs)
+print('\n'.join(titulos))
+" | fzf --reverse --prompt="Editar Música: ")
[ -z "$chosen" ] && return 0