File size: 1,906 Bytes
b6f5bc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
"""The bank the app serves: the math content file plus the lessons published in the database (add-subjects-and-worksheets).

The file's bank is kept as `app.state.base_bank`. `rebuild` reads the subjects and the published lessons and swaps a new merged
bank into `app.state.bank` in one step, at start-up and after every publish, unpublish or reorder, so a change reaches students
without a restart; a request already running keeps the bank it started with. When the database cannot be read (the subjects
migration not applied yet, or the database down at start-up) the file's lessons are served alone and the reason is kept in
`app.state.content_error` for the content screens. If building a new bank fails, the bank already served stays.
"""
from __future__ import annotations

import logging

from .bank import Bank, merge

log = logging.getLogger("mathly2.content")


def _raw(store):
    return getattr(store, "_store", store)                  # past the short cache: a change must show at once


def rebuild(app) -> Bank:
    """Build and serve the merged bank. Returns the bank now served. Raises only if building fails while the database answered."""
    base = app.state.base_bank
    try:
        store = _raw(app.state.store)
        subjects, lessons = store.subjects(), store.published_lessons()
    except Exception as exc:                                 # missing tables or no database: the file's lessons, math only
        log.warning("subjects and lessons could not be read, serving the content file only: %s", exc)
        app.state.content_error = str(exc) or type(exc).__name__
        if not hasattr(app.state, "bank") or app.state.bank is base:
            app.state.bank = Bank(merge(base.data, [], []))
        return app.state.bank
    bank = Bank(merge(base.data, subjects, lessons, log=log.warning))
    app.state.bank = bank
    app.state.content_error = None
    return bank