+15
-2
@@ -45,10 +45,21 @@ def metadata(path: pathlib.Path, root: pathlib.Path) -> dict:
|
||||
raise ValueError('presentation requires a generated Pico title image; regenerate assets')
|
||||
if not isinstance(staff['name'], str):
|
||||
raise ValueError('staff name must be a string')
|
||||
solos_enabled = meta.get('solos_enabled', True)
|
||||
if type(solos_enabled) is not bool:
|
||||
raise ValueError('solos_enabled must be a boolean')
|
||||
relative = path.relative_to(root)
|
||||
return dict(id=path.stem, title=meta['title'], composer=meta['composer'], key_signature=key,
|
||||
source_path=relative.as_posix(), source_json=text,
|
||||
measure_count=len(staff['measures']), total_pages=len(presentation['pages']), title_image=title_image, part=staff['name'])
|
||||
measure_count=len(staff['measures']), total_pages=len(presentation['pages']), title_image=title_image, part=staff['name'], solos_enabled=int(solos_enabled))
|
||||
|
||||
VARIANT_ERRORS = """
|
||||
SELECT json_extract(source_json, '$.music.metadata.song_id'), part FROM songs
|
||||
WHERE json_extract(source_json, '$.music.staves[0].arranged') = 1
|
||||
GROUP BY json_extract(source_json, '$.music.metadata.song_id'), part
|
||||
HAVING (part IN ('Acoustic', 'Electric') AND (count(*) != 2 OR sum(solos_enabled) != 1))
|
||||
OR (part = 'Vocal' AND (count(*) != 1 OR sum(solos_enabled) != 1))
|
||||
"""
|
||||
|
||||
def populate(connection: sqlite3.Connection, root: pathlib.Path, audio_assets=None) -> None:
|
||||
if not root.is_dir():
|
||||
@@ -70,7 +81,7 @@ def populate(connection: sqlite3.Connection, root: pathlib.Path, audio_assets=No
|
||||
with connection:
|
||||
connection.execute('BEGIN')
|
||||
connection.execute(f'PRAGMA application_id = {APPLICATION_ID}')
|
||||
connection.execute(f'CREATE TABLE songs ({SONG_COLUMNS}, part TEXT NOT NULL) STRICT')
|
||||
connection.execute(f'CREATE TABLE songs ({SONG_COLUMNS}, part TEXT NOT NULL, solos_enabled INTEGER NOT NULL CHECK(solos_enabled IN (0, 1))) STRICT')
|
||||
connection.execute('CREATE INDEX songs_menu ON songs(title, composer, part, id)')
|
||||
connection.execute('CREATE TABLE resources (id TEXT PRIMARY KEY, value TEXT NOT NULL CHECK(json_valid(value))) STRICT')
|
||||
connection.execute('INSERT INTO resources VALUES (?, ?)', ('audio', json.dumps(audio_assets)))
|
||||
@@ -82,6 +93,8 @@ def populate(connection: sqlite3.Connection, root: pathlib.Path, audio_assets=No
|
||||
connection.execute(f'INSERT INTO songs ({", ".join(row)}) VALUES ({", ".join("?" for _ in row)})', tuple(row.values()))
|
||||
except (ValueError, KeyError, TypeError, sqlite3.Error) as error:
|
||||
raise ValueError(f'{path}: {error}') from error
|
||||
if connection.execute(VARIANT_ERRORS).fetchall():
|
||||
raise ValueError('missing or duplicate solo variants; regenerate score assets')
|
||||
if connection.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:
|
||||
raise ValueError('catalog integrity check failed')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user