Skip to content

SBCAT 2026 - Scripture Burrito import#217

Open
ratatozk wants to merge 46 commits intosillsdev:developfrom
ratatozk:develop
Open

SBCAT 2026 - Scripture Burrito import#217
ratatozk wants to merge 46 commits intosillsdev:developfrom
ratatozk:develop

Conversation

@ratatozk
Copy link
Copy Markdown

@ratatozk ratatozk commented Mar 6, 2026

LightSys Code-a-thon APM 2026 — Project Summary

What the Project Was About

This project added support in Audio Project Manager (APM) for reading Scripture Burrito wrappers and converting them into PTF (Project Transfer Format) files.

The system:

  • Reads the Burrito folder structure and metadata
  • Rebuilds the book-level project structure in TypeScript
  • Generates valid PTF projects
  • Exports each book as its own PTF file (packaged as a renamed .zip)

The converter assumes the Burrito was exported from APM. It is not designed to be a universal Burrito-to-PTF solution.


General Notes

  • Only books present in the audio Burrito are processed, per sponsor direction.
  • Each book becomes its own PTF file.
  • The GUI supports filtering by chapter and Burrito, but the backend filters only by book.
  • Supporting deeper filtering would require modifying or recreating APM project data, which was outside scope.
  • Validation is intentionally minimal because inputs are assumed to be APM-generated.
  • Burrito structure interfaces were moved into shared TypeScript files to reduce duplication and improve maintainability.

Overall Results

  • Burrito wrapper parsing was successfully integrated into APM.
  • Book-level project structures are reconstructed from metadata.
  • Valid per-book PTF files are generated and packaged within the APM workflow.

Testing revealed apparent errors in the provided Scripture Burritos, preventing full validation of the upload process.


Future Work

Potential improvements include:

  • Backend support for chapter- and Burrito-level filtering
  • Support for non-APM Burritos
  • Stronger validation and error handling
  • Multi-book bundled PTF exports
  • Expanded automated testing for Burrito imports
  • Defaulting to all books and data selected
  • Investigation into why exported PTFs are different to exported burritos transformed into PTFs
    • The provided Luke only PTF APM data is twice as large when exported into burrito format and is missing 10 media files

src/renderer/src/utils/parseBurritoMetadata.ts

Overview

This module reads a Scripture Burrito wrapper directory and builds a simplified structure used by the application. It extracts:

  • The wrapper label
  • A list of books from audio Burrito metadata

All file reads are performed through IPC.


Data Structures

WrapperStructure

Represents the overall wrapper.

{
  label: string;
  books: BookStructure[];
}
  • label — The localized wrapper display name
  • books — The list of discovered books

BookStructure

Represents a single book inside the wrapper.

{
  id: string;
  label: string;
  chapters: string[];
  burritos: string[];
}
  • id — Book ID (e.g., RUT)
  • label — Localized book name
  • chapters — Currently unused
  • burritos — Currently unused

The chapters and burritos fields exist to support future fine-grained filtering. Supporting that level of filtering would require deeper audio analysis and generation/editing of apmdata, which is outside the scope of this implementation.


Public Functions

readJson<T>(filePath: string): Promise<T>

Reads a JSON file via IPC and parses it into a typed object.

Parameters

  • filePath — Absolute path to a JSON file

Returns

  • Promise<T> — Parsed JSON object typed as T

extractLabel(labels: LocalizedString, lang: string): string

Resolves a localized label from a language-to-string mapping.

Behavior:

  • Attempts to use the requested language
  • Falls back to the first available translation
  • Throws an error if no label is found
  • Removes the suffix "Burrito Wrapper" if present

Parameters

  • labels — Object mapping language codes to strings
  • lang — Preferred language code (e.g., "en")

Returns

  • string — Cleaned localized label

buildStructure(burritoWrapperPath: string, lang: string): Promise<WrapperStructure>

Reads wrapper metadata and audio Burrito metadata to construct a simplified structure.

  • Book IDs are derived from ingredient scopes in audio Burrito metadata
  • Book labels are resolved using localized names

Parameters

  • burritoWrapperPath — Absolute path to the wrapper directory containing metadata.json
  • lang — Preferred language code for resolving labels

Returns

  • Promise<WrapperStructure> — Object containing the localized wrapper label and an array of discovered books

src/renderer/src/utils/burritoConversion.ts

Overview

This module converts a Scripture Burrito wrapper directory into one or more PTF files.

For each selected book:

  1. Wrapper metadata is read
  2. Book-specific media and APM data are gathered
  3. The required folder structure is built
  4. The contents are compressed into a .ptf archive

All filesystem operations are performed through IPC.


Public Functions

convertWrapperToPTFs(filter: WrapperStructure, dirPath: string): Promise<string[]>

Converts selected books from a Burrito wrapper directory into individual PTF files.

  • Media files are gathered from wrapper-contained Burritos (excluding apmdata)
  • APM data is read from the apmdata directory
  • One PTF archive is generated per selected book

Parameters

  • filter — Structure describing which books should be converted
  • dirPath — Absolute path to the Burrito wrapper directory

Returns

  • Promise<string[]> — Array of generated .ptf file paths

convertBookToPTF(bookName: string, mediaList: PathObject[], dataList: PathObject[]): Promise<string>

Creates a single PTF file for a given book.

Process:

  • Builds required directory structure
  • Copies media and data files
  • Generates required metadata files
  • Compresses the folder into a .ptf archive

Parameters

  • bookName — Standardized book identifier (e.g., "08RUT")
  • mediaList — Parsed file paths for media files
  • dataList — Parsed file paths for APM data files

Returns

  • Promise<string> — File path of the generated .ptf archive

Resulting PTF Structure

Each generated archive contains:

media/
data/
SILTranscriber
Version

One archive is produced per selected book.


src/renderer/src/components/FilterContent.tsx

Overview

This component renders a dialog page allowing users to select which books to convert from an uploaded Scripture Burrito.

  • Selection method: checkbox tree
  • Selections are finalized when the user presses the Upload button
  • The tree is built using the output of buildStructure from parseBurritoMetadata.ts

Filtering Functionality

  • Accepts any data formatted as WrapperStructure (except when books is empty)

  • Supports filtering by:

    • Book
    • Chapter
    • Burrito
  • Returns filtered data in the same WrapperStructure format

Note: Backend conversion currently only supports book-level filtering.


UI/UX Images

  • Figure 1 — Initial dialog view
  • Figure 2 — “All Books” checkbox selected
  • Figure 3 — Single book selected with cursor hovering over “Upload”

Additions to src/main/ipcMethods.ts

These handlers extend the Electron main process to support zipping and file/directory selection dialogs.


zipFolder(sourceDir, outFile)

Creates a zip archive from a directory.

  • Compresses entire contents of sourceDir
  • Writes resulting archive to outFile
  • Archive is constructed in memory before writing to disk
  • Very large directories may impact memory usage and performance

Parameters

  • sourceDir — Absolute path to directory to be zipped
  • outFile — Absolute output file path (including filename)

Returns

  • void — Writes archive to disk
  • Throws an error if source directory does not exist

openDirectoryDialog()

Opens a system dialog restricted to directory selection.

Returns

  • string[] | undefined

    • Array of selected directory paths
    • undefined if canceled

importOpen(filters)

Opens a system file selection dialog with configurable file type filters.

Modified to support importing file types beyond .ptf.

Parameters

  • filters — Array of Electron file filter objects (e.g., by extension)

Returns

  • string[] | undefined

    • Array of selected file paths
    • undefined if canceled

NathanielCavallaro and others added 30 commits March 3, 2026 10:02
The tree uses stuff from mui/x-tree-view. All other changes are to shortcut to get to FilterContent.tsx
also made it so all decendents toggle status is determined by changing it's parent's toggle status
Should have data that is returned without breaking anything
@ratatozk ratatozk marked this pull request as ready for review March 9, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants