mirror of
https://gitlab.com/parroquia-san-leandro/cancionero-web.git
synced 2024-12-22 08:43:33 +01:00
documentacion y pistas de tipo en metodos
This commit is contained in:
parent
03522304fa
commit
bc4e7ed51d
4 changed files with 67 additions and 28 deletions
|
@ -1,8 +1,8 @@
|
||||||
|
import re
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import isfile, join
|
from os.path import isfile, join
|
||||||
from model import Audio
|
|
||||||
import re
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from model import Audio
|
||||||
|
|
||||||
|
|
||||||
def find_audios(index, audio_dir):
|
def find_audios(index, audio_dir):
|
||||||
|
|
|
@ -6,6 +6,7 @@ import pickle
|
||||||
|
|
||||||
|
|
||||||
def generate_songbook(songs, song_numbers, out_file, dj_engine):
|
def generate_songbook(songs, song_numbers, out_file, dj_engine):
|
||||||
|
'''Generate an HTML file with a sequence of songs.'''
|
||||||
# Build the list of songs
|
# Build the list of songs
|
||||||
song_list = []
|
song_list = []
|
||||||
for n in song_numbers:
|
for n in song_numbers:
|
||||||
|
@ -24,6 +25,7 @@ def generate_songbook(songs, song_numbers, out_file, dj_engine):
|
||||||
|
|
||||||
|
|
||||||
def create_argparser():
|
def create_argparser():
|
||||||
|
'''Parse main's arguments.'''
|
||||||
parser = latex_scanner.create_argparser()
|
parser = latex_scanner.create_argparser()
|
||||||
parser.add_argument("--songs", required=True, nargs='+', type=int, help="A list of song numbers to include.")
|
parser.add_argument("--songs", required=True, nargs='+', type=int, help="A list of song numbers to include.")
|
||||||
parser.add_argument("--output-file", required=False, nargs=1, default=["misa.html"],
|
parser.add_argument("--output-file", required=False, nargs=1, default=["misa.html"],
|
||||||
|
|
|
@ -11,7 +11,7 @@ from audio_scanner import find_audios
|
||||||
from model import Chord, Line, Song, Verse
|
from model import Chord, Line, Song, Verse
|
||||||
|
|
||||||
|
|
||||||
def mkdir(path):
|
def mkdir(path: str) -> None:
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
|
|
||||||
|
@ -19,33 +19,40 @@ def mkdir(path):
|
||||||
# Note that re.match prepends ^ to the pattern, whereas re.search doesn't
|
# Note that re.match prepends ^ to the pattern, whereas re.search doesn't
|
||||||
|
|
||||||
|
|
||||||
def read_property(text, key):
|
def read_property(text: str, key: str) -> str | None:
|
||||||
|
'''A parser for \\beginsong attributes.'''
|
||||||
if text is None:
|
if text is None:
|
||||||
return None
|
return None
|
||||||
match = re.search(key + "={(.*?)}", text)
|
match = re.search(key + "={(.*?)}", text)
|
||||||
return match.group(1) if match else None
|
return match.group(1) if match else None
|
||||||
|
|
||||||
|
|
||||||
def extra_put(extra, index, the_type, data=None):
|
def extra_put(extra: list, index: int, the_type: str, data: dict|None = None):
|
||||||
|
'''Adds the given data (if any) to the extra list, \
|
||||||
|
at the given index, and tagged with the given the_type.'''
|
||||||
payload = {'type': the_type, 'data': data} if data else {'type': the_type}
|
payload = {'type': the_type, 'data': data} if data else {'type': the_type}
|
||||||
if index not in extra:
|
if index not in extra:
|
||||||
extra[index] = []
|
extra[index] = []
|
||||||
extra[index].append(payload)
|
extra[index].append(payload)
|
||||||
|
|
||||||
|
|
||||||
class SongLoader:
|
class SongLoader:
|
||||||
def __init__(self, latex_file, audio_dir=None):
|
'''Parses LaTeX files to build a collection of song objects.'''
|
||||||
self.index = 1
|
|
||||||
self.category = None
|
def __init__(self, latex_file: str, audio_dir: str | None = None):
|
||||||
self.categories = []
|
'''Initializes and populates a LaTeX reader.'''
|
||||||
self.songs = []
|
self.index: int = 1
|
||||||
|
self.category: str | None = None
|
||||||
|
self.categories: list[str] = []
|
||||||
|
self.songs: list[Song] = []
|
||||||
if audio_dir:
|
if audio_dir:
|
||||||
self.audio_dir = audio_dir
|
self.audio_dir = audio_dir
|
||||||
self.scan(latex_file)
|
self.scan(latex_file)
|
||||||
|
|
||||||
def scan(self, latex_file):
|
def scan(self, latex_file: str) -> None:
|
||||||
|
'''Reads through an index file and scans each song, with the same numbers.
|
||||||
|
:param latex_file: The main latex file, which includes songs via \\input.'''
|
||||||
main_file = open(latex_file, 'r')
|
main_file = open(latex_file, 'r')
|
||||||
canciones_dir = join(str(Path(latex_file).parent), "canciones")
|
|
||||||
for line in main_file.readlines():
|
for line in main_file.readlines():
|
||||||
# Remove newline
|
# Remove newline
|
||||||
if line[-1] == '\n':
|
if line[-1] == '\n':
|
||||||
|
@ -61,14 +68,18 @@ class SongLoader:
|
||||||
self.category = re_chapter_match.group(1)
|
self.category = re_chapter_match.group(1)
|
||||||
self.categories.append(self.category)
|
self.categories.append(self.category)
|
||||||
# Traverse into \input commands if path starts w/ 'canciones/'
|
# Traverse into \input commands if path starts w/ 'canciones/'
|
||||||
re_input_match = re.search(r"\\input{canciones/(.*?)}", line)
|
re_input_match = re.search(r"\\input{(.*?)}", line)
|
||||||
if re_input_match is not None:
|
if re_input_match is not None:
|
||||||
input_file = join(canciones_dir, re_input_match.group(1))
|
input_file = join(str(Path(latex_file).parent), re_input_match.group(1))
|
||||||
if not input_file.endswith(".tex"):
|
if not input_file.endswith(".tex"):
|
||||||
input_file += ".tex"
|
input_file += ".tex"
|
||||||
self.scan_song_file(input_file)
|
self.scan_song_file(input_file)
|
||||||
|
|
||||||
def scan_others(self, folder, start_index):
|
def scan_others(self, folder: str, start_index: int) -> None:
|
||||||
|
'''Looks for songs not found during self.scan(...).
|
||||||
|
:param folder: A folder to scan through, looking for .tex files.
|
||||||
|
:param start_index: When numbering new songs, the first index to use.
|
||||||
|
'''
|
||||||
self.index = start_index
|
self.index = start_index
|
||||||
self.category = "Nuevas"
|
self.category = "Nuevas"
|
||||||
self.categories.append(self.category)
|
self.categories.append(self.category)
|
||||||
|
@ -81,22 +92,46 @@ class SongLoader:
|
||||||
print("Scanning extra file", f)
|
print("Scanning extra file", f)
|
||||||
self.scan_song_file(f)
|
self.scan_song_file(f)
|
||||||
|
|
||||||
def scan_song_file(self, song_file):
|
def scan_song_file(self, song_file: str) -> None:
|
||||||
|
'''Scan a single song file and store any songs found.'''
|
||||||
# Variables
|
# Variables
|
||||||
ignore = False
|
ignore: bool = False
|
||||||
current_song = None
|
current_song: Song | None = None
|
||||||
current_verse = None
|
current_verse: Verse | None = None
|
||||||
memory = None
|
memory: str | None = None
|
||||||
memorizing = False
|
memorizing: bool = False
|
||||||
replay_index = 0
|
replay_index: int = 0
|
||||||
transpose = 0
|
transpose: int = 0
|
||||||
trfmt = "normal"
|
trfmt: str = "normal"
|
||||||
|
|
||||||
|
# General behaviour: read the file and scan line-by-line
|
||||||
|
# In each line, read char-by-char, searching for common LaTeX commands
|
||||||
|
# Apply the effects of these commands, and add each verse (line inside
|
||||||
|
# song after removing all commands) to build up each song.
|
||||||
|
# Commands include:
|
||||||
|
### Comments: % Something something -> Ignored
|
||||||
|
### Line break locations: \brk -> Ignored
|
||||||
|
### Transpose: \transpose{SEMITONES}
|
||||||
|
### Begin song: \beginsong{NAME}[METADATA]
|
||||||
|
### End song: \endsong
|
||||||
|
### Verse begin/end: \beginverse, \endverse
|
||||||
|
### Chorus begin/end: \beginchorus, \endchorus
|
||||||
|
### Capo: \capo{FRET}
|
||||||
|
### Chord-excl. txt.: \ifchorded, \else, \fi
|
||||||
|
### (the contents between \else and \fi are discarded)
|
||||||
|
### Echoes: \echo{TEXT}
|
||||||
|
### Chord: \[CHORD]
|
||||||
|
### Chord repetition: \^
|
||||||
|
### Music repetition: \lrep, \rrep
|
||||||
|
### Lyric repetition: \rep{TIMES}
|
||||||
|
### Chord memory: \memorize, \replay
|
||||||
|
### Transpose format: \renewcommand{\trchordformat}[2]{.*}
|
||||||
|
### Other unrecognized commands: \NAME([ARG]|{ARG})*
|
||||||
for line in open(song_file, "r").readlines():
|
for line in open(song_file, "r").readlines():
|
||||||
# Remove newline
|
# Remove newline
|
||||||
if line[-1] == '\n':
|
if line[-1] == '\n':
|
||||||
line = line[:-1]
|
line = line[:-1]
|
||||||
# Remove commends and \brk commands
|
# Remove comments and \brk commands
|
||||||
text = re.sub(r"%.*$", "", line)
|
text = re.sub(r"%.*$", "", line)
|
||||||
text = re.sub(r"\\brk({})?", '', text)
|
text = re.sub(r"\\brk({})?", '', text)
|
||||||
text = re.sub(r"``", u"\u201C", text)
|
text = re.sub(r"``", u"\u201C", text)
|
||||||
|
@ -245,7 +280,8 @@ class SongLoader:
|
||||||
continue
|
continue
|
||||||
current_verse.add_line(Line(text, extras))
|
current_verse.add_line(Line(text, extras))
|
||||||
|
|
||||||
def sort_categories(self):
|
def sort_categories(self) -> dict[str, list[Song]]:
|
||||||
|
'''Returns a dictionary of categories to lists of songs (sorted by number).'''
|
||||||
result = {}
|
result = {}
|
||||||
for c in self.categories:
|
for c in self.categories:
|
||||||
result[c] = sorted([s for s in self.songs if s.category == c],
|
result[c] = sorted([s for s in self.songs if s.category == c],
|
||||||
|
|
|
@ -4,7 +4,8 @@ from datetime import datetime
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
|
|
||||||
def join_list(the_list, separator="\n"):
|
def join_list(the_list: list, separator: str = "\n") -> str:
|
||||||
|
'''Join a list of objects in a string, with a separator.'''
|
||||||
return ft.reduce(lambda x, y: x + (separator if x else "") + str(y), the_list, "")
|
return ft.reduce(lambda x, y: x + (separator if x else "") + str(y), the_list, "")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue