diff --git a/Makefile b/Makefile index 3ab350d..e63cb59 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ ALL_CSS := $(patsubst res/%.less,public/%.css,$(wildcard res/*.less)) ALL_JS := $(patsubst res/%.js,public/%.js,$(wildcard res/*.js)) ALL_SVG := $(patsubst res/%.svg,public/%.svg,$(wildcard res/*.svg)) +ALL_TEMPLATES := $(wildcard res/html/*.html) all: public/index.html @@ -17,9 +18,7 @@ svg: $(ALL_SVG) public: mkdir public -public/index.html: static public public/audios \ - res/index.html res/page.html \ - res/song.html res/song_li.html res/song_redir.html +public/index.html: static public public/audios $(ALL_TEMPLATES) python3 src/latex_scanner.py --latex latex/cancionero.tex --audios audios public/audios: audios public diff --git a/res/html/footer.html b/res/html/footer.html new file mode 100644 index 0000000..3c5a1d8 --- /dev/null +++ b/res/html/footer.html @@ -0,0 +1,6 @@ + diff --git a/res/html/head.html b/res/html/head.html new file mode 100644 index 0000000..1873632 --- /dev/null +++ b/res/html/head.html @@ -0,0 +1,7 @@ + +Cancionero - Parroquia San Leandro + + +{% if specific_css %} + +{% endif %} \ No newline at end of file diff --git a/res/html/header.html b/res/html/header.html new file mode 100644 index 0000000..4be012e --- /dev/null +++ b/res/html/header.html @@ -0,0 +1,10 @@ +
+

Cancionero San Leandro

+ +
diff --git a/res/html/index.html b/res/html/index.html new file mode 100644 index 0000000..7915f53 --- /dev/null +++ b/res/html/index.html @@ -0,0 +1,25 @@ + + + + {% include "head.html" with path="." only %} + + + + {% include "header.html" with path="." %} +

Índice

+ Las canciones sin acordes están marcadas en rojo. +
    + {% for song in songs %} + +
  1. + {{ song.number }}. + {{ song.name }} + {% if song.author %} por {{ song.author }} {% endif %} + {% if song.origin %} basado en {{ song.origin }} {% endif %} +
  2. +
    + {% endfor %} +
+ {% include "footer.html" %} + + \ No newline at end of file diff --git a/res/html/song.html b/res/html/song.html new file mode 100644 index 0000000..6ad94fc --- /dev/null +++ b/res/html/song.html @@ -0,0 +1,110 @@ + + + + {% include "head.html" with path=".." only %} + + + + + + {% include "header.html" with path=".." %} +
+

{{ song.name}}

+ {% if song.author %} +
Autor: {{ song.author }}
+ {% endif %} + {% if song.origin %} +
Basada en: {{ song.origin }}
+ {% endif %} +

Ajustes

+
+ + + + +
+ {% if song.chorded %} +
+ + + + + + + +
+ {% endif %} + {% if song.capo != 0 %} +
+ Tono original: Cejilla {{ song.capo }} + +
+ {% endif %} +

Canción

+
+ {% for verse in song.verses %} +
+ {% for line in verse.lines %} + {% spaceless %} + {% for chord, lyric in line.zipped_arr %} + + + + + + + +
+ {% if chord.class %} + + {% endif %} + {% for c in chord.chord.items %} + {% if c.chord %} + {{ c.text|safe }} + {% else %} + {{ c.text|safe }} + {% endif %} + {% endfor %} +
+ {% if 'rowspan' not in chord %} + {{ lyric|safe }} + {% endif %} +
+ {% endfor %} + {% if not forloop.last %}
{% endif %} + {% endspaceless %} + {% endfor %} +
+ {% endfor %} +
+ {% for audio in audios %} + {% if forloop.first %} +

Audios

+ {% endif %} +
+ Audio del {{ audio.date_text }} Descargar + +
+ {% endfor %} + Ver archivo original (LaTeX) + Índice +
+ {% include "footer.html" %} + + \ No newline at end of file diff --git a/res/html/song_redir.html b/res/html/song_redir.html new file mode 100644 index 0000000..1024dce --- /dev/null +++ b/res/html/song_redir.html @@ -0,0 +1,12 @@ + + + + {% include "head.html" with path=".." only %} + + + + {% include "header.html" with path=".." %} + Redirigiendo a la canción, haz click aquí si no sucede de forma automática. + {% include "footer.html" %} + + diff --git a/res/index.html b/res/index.html deleted file mode 100644 index 69b337d..0000000 --- a/res/index.html +++ /dev/null @@ -1,5 +0,0 @@ -

Índice

-
    - Las canciones sin acordes están marcadas en rojo. - {list_content} -
diff --git a/res/index.less b/res/index.less index 583d24f..97775dc 100644 --- a/res/index.less +++ b/res/index.less @@ -20,7 +20,7 @@ background-color: @secondary-hover; transition-duration: @transition; } - &.hasChords { + &.noChords { background-color: @nochordscolor; &:hover { color: @text-hover; @@ -30,7 +30,7 @@ } } } -span.hasChords { +span.noChords { background-color: @nochordscolor; padding: 0.3em 0.4em; border-radius: @border-radius; diff --git a/res/main.less b/res/main.less index c3d064a..2544c35 100644 --- a/res/main.less +++ b/res/main.less @@ -6,6 +6,9 @@ h1 { width: max-content; max-width: 100%; text-align: center; + > a, > a:hover, > a:active, > a:visited { + color: @title; + } } h2, h3 { diff --git a/res/page.html b/res/page.html deleted file mode 100644 index c985dbb..0000000 --- a/res/page.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Cancionero - Parroquia San Leandro - - {css} - - -
-

Cancionero San Leandro

- -
-
- {main} -
- - - diff --git a/res/song.html b/res/song.html deleted file mode 100644 index 4015d07..0000000 --- a/res/song.html +++ /dev/null @@ -1,48 +0,0 @@ -
- - -

{name}

- {author} - {origin} -

Ajustes

-
- - - - -
-
- - - - - - - -
- {capo_settings} -

Canción

-
- {song_html} -
-
- {audios_header} - {audios_html} -
- Ver archivo original (LaTeX) - Atrás -
diff --git a/res/song_li.html b/res/song_li.html deleted file mode 100644 index 7fe2e0e..0000000 --- a/res/song_li.html +++ /dev/null @@ -1,6 +0,0 @@ - -
  • - {number}. - {name}{author}{origin} -
  • -
    \ No newline at end of file diff --git a/res/song_redir.html b/res/song_redir.html deleted file mode 100644 index ccebfd0..0000000 --- a/res/song_redir.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Redirigiendo a la canción, haz click aquí si no sucede de forma automática. - - diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/audio_scanner.py b/src/audio_scanner.py index ba7fdb6..5b98f7b 100644 --- a/src/audio_scanner.py +++ b/src/audio_scanner.py @@ -1,6 +1,6 @@ from os import listdir from os.path import isfile, join -from song_types import Audio +from model import Audio import re from datetime import datetime diff --git a/src/latex_scanner.py b/src/latex_scanner.py index 440497e..506198d 100644 --- a/src/latex_scanner.py +++ b/src/latex_scanner.py @@ -1,14 +1,15 @@ -from song_types import Chord, Line, Song, Verse -from song_types import readfile, join_list -from audio_scanner import find_audios -from os.path import join -from pathlib import Path -import shutil import argparse -import urllib.parse import os import re +import shutil +from django.conf import settings +from django.template import Engine, Context +from os.path import join +from pathlib import Path + +from audio_scanner import find_audios +from model import Chord, Line, Song, Verse def mkdir(path): if not os.path.exists(path): @@ -31,14 +32,6 @@ def extra_put(extra, index, the_type, data=None): extra[index].append(payload) -page_template = readfile("res/page.html") -index_template = readfile("res/index.html") -index_per_song_template = readfile("res/song_li.html") -song_redir_template = readfile("res/song_redir.html") -index_css = '\n\t' -song_css = '\n\t' - - class SongLoader: def __init__(self, latex_file, audio_dir): self.index = 1 @@ -235,35 +228,28 @@ class SongLoader: continue current_verse.add_line(Line(text, extras)) - def print_index(self, index_file="index.html"): - self.songs = sorted(self.songs, key=lambda s: s.number) - song_list = join_list([index_per_song_template.format( - url=s.get_url(), - li_class=' class="hasChords"' if not s.chorded() else '', - number=s.number, - name=s.name, - author=" por %s " % s.author if s.author else "", - origin=" basado en %s " % s.origin if s.origin else "") - for s in self.songs]) - body = index_template.format(list_content=song_list) + def print_index(self, index_file, dj_engine): + songs = sorted(self.songs, key=lambda s: s.number) + html = dj_engine.get_template("index.html").render(Context({'songs': songs})) with open(index_file, 'w') as f: - f.write(page_template.format(css=index_css, main=body)) + f.write(html) - def print_songs(self, directory="."): - for song in self.songs: - num_dir = join(directory, "%03d" % (song.number)) - mkdir(num_dir) - with open(join(num_dir, "index.html"), 'w') as f: - f.write(song_redir_template.format(url=urllib.parse.quote("../" + song.get_url()))) - song_dir = join(directory, song.get_url()) - mkdir(song_dir) - with open(join(song_dir, "index.html"), 'w') as f: - f.write(page_template.format(css=song_css, main=str(song))) + def print_song(self, song, directory, dj_engine): + context = Context({'song': song}) + num_dir = join(directory, "%03d" % (song.number)) + mkdir(num_dir) + with open(join(num_dir, "index.html"), 'w') as f: + f.write(dj_engine.get_template("song_redir.html").render(context)) + song_dir = join(directory, song.url()) + mkdir(song_dir) + with open(join(song_dir, "index.html"), 'w') as f: + f.write(dj_engine.get_template("song.html").render(context)) - def generate_html(self, output_dir): + def generate_html(self, output_dir, dj_engine): mkdir(output_dir) - self.print_songs(output_dir) - self.print_index(join(output_dir, "index.html")) + for song in self.songs: + self.print_song(song, output_dir, dj_engine) + self.print_index(join(output_dir, "index.html"), dj_engine) def parse_args(): @@ -277,4 +263,6 @@ def parse_args(): if __name__ == '__main__': args = parse_args() loader = SongLoader(args.latex[0], args.audios[0]) - loader.generate_html(args.output_dir[0]) + settings.configure(USE_TZ=False, USE_I18N=False) + e = Engine(dirs=["res/html/"]) + loader.generate_html(args.output_dir[0], e) diff --git a/src/song_types.py b/src/model.py similarity index 70% rename from src/song_types.py rename to src/model.py index 217ce54..3e2175a 100644 --- a/src/song_types.py +++ b/src/model.py @@ -8,13 +8,7 @@ def join_list(the_list, separator="\n"): return ft.reduce(lambda x, y: x + (separator if x else "") + str(y), the_list, "") -def readfile(file): - with open(file, 'r') as f: - return join_list(f.readlines(), '') - - locale.setlocale(locale.LC_ALL, "es_ES.UTF-8") -song_template = readfile("res/song.html") class Song: @@ -32,17 +26,7 @@ class Song: self.category = category def __str__(self): - return song_template.format( - name=self.name, - author="
    Autor: %s
    " % self.author if self.author else "", - origin="
    Basada en: %s
    " % self.origin if self.origin else "", - capo_settings="""
    Tono original: Cejilla {s.capo} -
    """ - .format(s=self) if self.capo != 0 else "", - song_html=join_list(self.verses), - audios_header="

    Audios

    " if len(self.audios) > 0 else "", - audios_html=join_list(self.audios), - latex_file=self.latex_file) + return self.name def set_capo(self, capo): self.capo = capo @@ -55,7 +39,7 @@ class Song: assert isinstance(verse, Verse) self.verses.append(verse) - def get_url(self): + def url(self): return "%03d %s" % (self.number, self.name.replace("¿", "").replace("?", "")) def chorded(self): @@ -69,13 +53,10 @@ class Verse: def __init__(self, is_chorus=False): self.is_chorus = is_chorus self.lines = [] + self.kind = "chorus" if is_chorus else "verse" def __str__(self): - return """ -
    - %s -
    - """ % ("chorus" if self.is_chorus else "verse", join_list([str(l) for l in self.lines], "\n
    \n")) + return join_list(self.lines, " ") def add_line(self, line): assert isinstance(line, Line) @@ -99,15 +80,11 @@ class Line: self.lyric_arr = [] self.build() self.remove_brackets() + assert len(self.chord_arr) == len(self.lyric_arr) + self.zipped_arr = zip(self.chord_arr, self.lyric_arr) def __str__(self): - assert len(self.chord_arr) == len(self.lyric_arr) - return join_list(["""%s
    %s%s
    """ - % (self.chord_arr[i]["rowspan"] if "rowspan" in self.chord_arr[i] else 1, - '' % self.chord_arr[i]["class"] if "class" in self.chord_arr[i] else "", - self.chord_arr[i]["chord"] if "chord" in self.chord_arr[i] else "", - '%s' % self.lyric_arr[i] if "rowspan" not in self.chord_arr[i] else '' - ) for i in range(len(self.chord_arr))], separator='') + return self.text def add_chord(self, index, chord): self.add_item(index, "chord", chord) @@ -172,8 +149,7 @@ class Line: self.lyric_arr.append(Line.ECHO_BEGIN if inside_echo else '') mid = True self.lyric_arr[-1] += self.text[i] - for i in range(len(self.lyric_arr)): - self.lyric_arr[i] = re.sub(r"(^ | $)", " ", self.lyric_arr[i]) + self.lyric_arr = [re.sub(r"(^ | $)", " ", l) for l in self.lyric_arr] def remove_brackets(self): self.lyric_arr = [l.replace('}', '').replace('{', '') for l in self.lyric_arr] @@ -186,6 +162,10 @@ class Line: return False +def chord_eng2lat(text): + return Chord.CHORDS_LAT[Chord.ENG_INDEX[text]] + + class Chord: N_CHORDS = 12 CHORDS_LAT = ['Do', 'Do#', 'Re', 'Re#', 'Mi', 'Fa', 'Fa#', 'Sol', 'Sol#', 'La', 'Sib', 'Si'] @@ -194,7 +174,7 @@ class Chord: def __init__(self, text, base_transpose=0): self.text = text - self.chords = [] + self.items = [] self.base_transpose = base_transpose ignore = False for i, char in enumerate(text): @@ -203,21 +183,15 @@ class Chord: continue if "A" <= char <= "G": if len(text) > i + 1 and (text[i + 1] == "#" or text[i + 1] == "&"): - self.chords.append({'text': char + text[i + 1], 'chord': True}) + self.items.append({'text': chord_eng2lat(char + text[i + 1]), 'chord': True}) ignore = True else: - self.chords.append({'text': char, 'chord': True}) + self.items.append({'text': chord_eng2lat(char), 'chord': True}) else: - self.chords.append({'text': char, 'chord': False}) + self.items.append({'text': char, 'chord': False}) def __str__(self): - res = "" - for c in self.chords: - if c['chord']: - res += "%s" % Chord.CHORDS_LAT[Chord.ENG_INDEX[c['text']]] - else: - res += c['text'] - return res + return self.text class Audio: @@ -228,11 +202,4 @@ class Audio: self.audio_file = audio_file def __str__(self): - return """ -
    - Audio del %s Descargar - -
    - """ % (self.date_text, self.audio_file, self.audio_file) + return self.audio_file