diff --git a/.gitignore b/.gitignore index 254c49b..7852cfe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.pyc public/ audios/ +songs.dat diff --git a/Makefile b/Makefile index 1a4efd0..b113299 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ public/index.html: $(ALL_TEMPLATES) $(PY_SRC) --latex latex/cancionero.tex \ --audios audios \ --other-latex latex/canciones/ \ + --use-cache \ --title "$(NAME)" \ --author "$(AUTHOR)" \ --links "$(SLO_LINKS)" @@ -44,3 +45,4 @@ public/%: res/static/% clean: rm -rf public + rm -f songs.dat diff --git a/src/latex_scanner.py b/src/latex_scanner.py index 4f2bbea..2e34475 100644 --- a/src/latex_scanner.py +++ b/src/latex_scanner.py @@ -1,6 +1,7 @@ import argparse import os import re +import pickle from django.conf import settings from django.template import Engine, Context @@ -45,7 +46,7 @@ def extra_put(extra: list, index: int, the_type: str, data: dict|None = None): class SongLoader: '''Parses LaTeX files to build a collection of song objects.''' - def __init__(self, latex_file: str, audio_dir: str | None = None): + def __init__(self, latex_file: str | None = None, audio_dir: str | None = None): '''Initializes and populates a LaTeX reader.''' self.index: int = 1 self.category: str | None = None @@ -53,7 +54,16 @@ class SongLoader: self.songs: list[Song] = [] if audio_dir: self.audio_dir = audio_dir - self.scan(latex_file) + if latex_file: + self.scan(latex_file) + + def populate_with_songs(self, songs): + for s in songs: + self.songs.append(s) + if s.category not in self.categories: + self.categories.append(s.category) + if s.number < self.index: + self.index = s.number def scan(self, latex_file: str) -> None: '''Reads through an index file and scans each song, with the same numbers. @@ -345,14 +355,35 @@ def create_argparser(): parser.add_argument("--title", required=True, nargs=1, help="The title of the webpage") parser.add_argument("--author", required=True, nargs=1, help="The author for the footer") parser.add_argument("--links", required=False, nargs=1, default=["false"]) + parser.add_argument("--use-cache", required=False, action="store_true", + help="Whether to use a cache file if available (to use if songs haven't changed)") return parser +def cache_or_parse(args): + loader = None + if args.use_cache: + try: + with open("songs.dat", "rb") as f: + loader = SongLoader() + loader.populate_with_songs(pickle.load(f)) + except OSError: + pass + if not loader: + loader = SongLoader(args.latex[0], args.audios[0]) + if args.other_latex: + loader.scan_others(args.other_latex[0], args.other_index[0]) + try: + with open("songs.dat", "wb") as f: + pickle.dump(loader.songs, f) + except OSError: + pass + return loader + + if __name__ == '__main__': args = create_argparser().parse_args() - loader = SongLoader(args.latex[0], args.audios[0]) - if args.other_latex: - loader.scan_others(args.other_latex[0], int(args.other_index[0])) + loader = cache_or_parse(args) settings.configure(USE_TZ=False, USE_I18N=False) e = Engine(dirs=["res/templates/"]) loader.generate_html(args.output_dir[0], e, {