Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
z1glr committed Apr 25, 2024
2 parents 137ce32 + 4646153 commit fb2f27d
Show file tree
Hide file tree
Showing 80 changed files with 2,930 additions and 1,408 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ client
license-generator.ts
license-reporter.config.ts
build-scripts/*.js
pandoc
14 changes: 10 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
node_modules
node_modules_windows
node_modules_linux
server_log.log
logs
miktex
out
dist
pandoc/*

casparcg/Templates/JohnCG/*.js
build-scripts/build.js
build-scripts/3rdpartylicenses.json
out
dist
*.map
*.map
install-tl.log

!pandoc/install.py
!pandoc/texlive.profile
2 changes: 1 addition & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"bracketSpacing": true,
"quoteProps": "as-needed",
"vueIndentScriptAndStyle": true,
"endOfLine": "auto"
"endOfLine": "lf"
}
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\src\\server\\main.ts",
"program": "${workspaceFolder}/src/server/main.ts",
// "preLaunchTask": "tsc: build - server",
"preLaunchTask": "type-check and esbuild-server-sourcemap",
"outFiles": [
Expand Down
4 changes: 2 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"tasks": [
{
"type": "npm",
"script": "build-release",
"script": "build",
"group": "build",
"problemMatcher": [],
"label": "build release"
"label": "build"
},
{
"type": "npm",
Expand Down
42 changes: 22 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
# johnCG - character-generator for lyrics
Generate lyric-graphics and play them out through CasparCG.
# JohnCG - character-generator for song-lyrics and other church-service-elements
Generate graphics with song-lyrics or for other church-service-elements and play them out through CasparCG.

## Requirements
- CasparCG
- CasparCG-capable hardware
- SongBeamer for creation of song-files
- Linux: `pandoc` and `LaTeX`-packages (basic, langgerman, latex, latexrecommended, latexextra, fontsextra, fontsrecommended)

## Installation
(WiP)
## Getting started
1. Download CasparCG and set it up according to its [GitHub-site](https://github.com/CasparCG/server).
2. Download the latest JohnCG-version from [releases](https://github.com/johannesbuehl/johncg/releases) and unzip it.
3. Move the content of `casparcg/Templates` and `casparcg/Media` inside of CasparCGs Template and Media directories.
4. Edit `config.json` if necessary
5. Start CasparCG
6. Start JohnCG through `JohnCG_[VERSION]_linux.bat` or `JohnCG_[VERSION]_linux.sh`
7. Open [`127.0.0.1:8888`](127.0.0.1:8888) (or the port you specified in `settings.json`)
8. Optionally: create a shortcut to `chrome --app=http://127.0.0.1:8888` to open the client like a standalone app

## roadmap
- implement other playlist-items than song (Missing: Diashow / Multi-Image, Text, Custom AMCP-command)
- client: information about connection (active / reconnecting / ...)
- implement more playlist-items: Text
- companion integration (buttons for song parts -> send name to casparcg)
- check client -> server slide_number out of range
- client: check response-texts, if they are still correct
- write installation instruction (including Bahnschrift-Font installation)
- client communication with osc over websocket?
- add support for NodeCG
- implement all countdown modes
- countdown: save in server wether it is finished
- client-messages: create message-log, group same
- fix "Buffer() is deprecated"
- catch casparcg not running
- create playlist-summarys or lyrics-sheets through pandoc
- load files from disc always at item selection to stay up to date
- create server-items at selection, delete after deselection to always stay up to date, but prevent multiple reloads (alternative: optional argument for accessing functions wether a reload should be done)
- save file through interface instead of download
- on item-update refresh render and client
- change default-item-colors
- use playlist-caption
- render PDF with same size as casparcg
- make keyboard-navigation better
- tabindex for all elements
- keyboard-shortcuts
- update-item: reload changed media (somehow handle video / audio - or just don't care (maybe detect wether it actually changed))
- change font-color of countdown
- create library src-folder
- create library src-folder
- create documentation (including: Template-update-objects, psalm-file-definitions, config-file, companion-setup)
- modify client to avoid props-down-chaining (instead ts-file like `config.ts` or `logger.ts`)
- create example-files for songs and psalm
- move template-jump()-function into update() to prevent error messages in casparcg-log
- parse chords in songfile in preparation for chord-view
- casparcg: if no connection on startup possible: try periodically to reconnect
47 changes: 30 additions & 17 deletions build-scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const release_dir = path.join("dist", build_name);
fs.rmSync(build_dir, { recursive: true, force: true });
fs.rmSync(release_dir, { recursive: true, force: true });
fs.mkdirSync(build_dir, { recursive: true });
fs.mkdirSync(path.join("dist", build_name), { recursive: true });
fs.mkdirSync(release_dir, { recursive: true });

const copy_build_file = (file: string, dest?: string) => fs.copyFileSync(file, path.join(build_dir, dest ?? path.basename(file)));
// const copy_build_dir = (dir: string, dest?: string, args?: fs.CopySyncOptions) => fs.cpSync(dir, path.join(build_dir, dest ?? path.basename(dir)), { recursive: true, ...args });
Expand All @@ -44,6 +44,7 @@ const copy_release_dir = (dir: string, dest?: string, args?: fs.CopySyncOptions)
execSync("npm run server-build");
execSync("npm run client-build");
execSync("npm run templates-build");
execSync("npm run pandoc-build");

// temporary method until there is a solution for packaging sharp
// // create sea-prep.blob
Expand All @@ -61,40 +62,38 @@ copy_build_file(process.execPath, exec_name);
// load the config-file, censor the file-paths and store it for the relase
const config_file = JSON.parse(fs.readFileSync("config.json", "utf-8")) as ConfigJSON;
config_file.path = {
song: "C:/path/to/song/directory",
pdf: "D:/path/to/pdf/directory",
psalm: "E:/path/to/psalm/directory",
playlist: "F:/path/to/playlist/directory",
bible: "Bibles/Luther-Bibel.json"
song: "Song/",
pdf: "PDF/",
psalm: "Psalm/",
playlist: "Playlist/",
bible: "Bible/Luther-Bibel.json"
};
config_file.casparcg.templates = "e:/path/to/the/casparcg/templates/directory";
config_file.companion.address = "172.0.0.1";
config_file.log_level = "INFO";

fs.writeFileSync(path.join(release_dir, "config.json"), JSON.stringify(config_file, undefined, "\t"));

// copy the file to the output
copy_release_file(path.join(build_dir, exec_name));
copy_release_file(path.join(build_dir, "main.js"));
copy_release_dir("Bibles");
fs.readdirSync("files").forEach((dir) => copy_release_dir(path.join("files", dir)));
copy_release_dir(path.join(build_dir, "client"));
const copy_module = (name: string) => {
copy_release_dir(`node_modules/${name}`, `node_modules/${name}/`);

};
copy_release_dir(path.join(build_dir, "Templates"));
copy_release_dir("casparcg/Media");
copy_release_dir(path.join(build_dir, "pandoc"));
copy_release_file("pandoc/texlive.profile", "pandoc/texlive.profile");
copy_module("@img");
copy_module("canvas");
copy_module("pdfjs-dist");

// temporary method until there is a solution for packaging sharp
// create a script-file, that start node with the main.js
switch (process.platform) {
case "win32":
fs.writeFileSync(path.join(release_dir, build_name + ".bat"), `${exec_name} main.js\npause`);
break;
case "linux":
fs.writeFileSync(path.join(release_dir, build_name + ".sh"), `./${exec_name} main.js\nread -n1 -r -p "Press any key to continue..." key`);
break;
}
create_launch_script("main.js", build_name);
create_launch_script("pandoc-installer.js", "pandoc/install");

// create and copy the licenses
// void lr.cli(["--config=build-scripts/license-reporter.config.ts"]);
Expand Down Expand Up @@ -132,4 +131,18 @@ copy_release_file("LICENSE", "LICENSE.txt");
copy_release_dir(path.join(build_dir, "licenses"));

// pack the files in a .tar.gz-file
void tar.c({ gzip: true, file: release_dir + ".tar.gz", cwd: "dist" }, [path.relative("dist", release_dir)]);
void tar.c({ gzip: true, file: release_dir + ".tar.br", cwd: "dist" }, [path.relative("dist", release_dir)]);

function create_launch_script(pth: string, destination: string) {
const relative_path_prefix = "../".repeat((destination.match(/\//g) ?? []).length);

switch (process.platform) {
case "win32": {
fs.writeFileSync(path.join(release_dir, destination + ".bat"), `@echo off\ncd /D "%~dp0"\n${relative_path_prefix.replaceAll("/", "\\")}${exec_name} ${pth}\npause\n`);
}
break;
case "linux":
fs.writeFileSync(path.join(release_dir, destination + ".sh"), `${relative_path_prefix}./${exec_name} ${pth}\nread -n1 -r -p "Press any key to continue..." key`);
break;
}
}
4 changes: 4 additions & 0 deletions build-scripts/license-reporter.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export const configuration: Partial<IReporterConfiguration> = {
},
{
name: "undici-types"
},
{
name: "canvas",
licenseText: "(The MIT License)\n\nCopyright (c) 2010 LearnBoost, and contributors <[email protected]>\n\nCopyright (c) 2014 Automattic, Inc and contributors <[email protected]>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
}
]
};
10 changes: 10 additions & 0 deletions build-scripts/pandoc-build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const esbuild = require("esbuild");

esbuild.build({
entryPoints: ["./build-scripts/pandoc-installer.ts"],
outfile: "./dist/build/pandoc/pandoc-installer.js",
tsconfig: "./build-scripts/tsconfig.json",
platform: "node",
minify: true,
bundle: true
});
74 changes: 74 additions & 0 deletions build-scripts/pandoc-installer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import tmp from "tmp";
import fs from "fs";
import path from "path";
import StreamZip from "node-stream-zip";
import child_process from "child_process";
import readline from "node:readline/promises";
import { stdin, stdout } from "process";

void (async () => {
let license_message: string;

if (process.platform === "win32") {
license_message = "You are about to download eisvogel, pandoc and texlive, which licenses differ from the one of JohnCG. Their respetive licenses can be found at https://raw.githubusercontent.com/Wandmalfarbe/pandoc-latex-template/master/LICENSE, https://raw.githubusercontent.com/jgm/pandoc/main/COPYRIGHT and https://www.tug.org/texlive/LICENSE.TL . By proceeding you acknowledge those.";
} else {
license_message = "You are about to download eisvogel which license differs from the one of JohnCG. It can be found at https://raw.githubusercontent.com/Wandmalfarbe/pandoc-latex-template/master/LICENSE . By proceeding you acknowledge it.";
}

const rl = readline.createInterface({ input: stdin, output: stdout });

const response = rl.question(license_message + " Proceed? (y/[n]) ");

if ((await response).toLowerCase() !== "y") {
process.exit(0);
}

const urls: Record<string, Record<string, string>> = {
win32: {
pandoc: "https://github.com/jgm/pandoc/releases/download/3.1.13/pandoc-3.1.13-windows-x86_64.zip",
texlive: "https://de.mirrors.cicku.me/ctan/systems/texlive/tlnet/install-tl.zip",
eisvogel: "https://github.com/Wandmalfarbe/pandoc-latex-template/releases/latest/download/Eisvogel.zip"
},
linux: {
eisvogel: "https://github.com/Wandmalfarbe/pandoc-latex-template/releases/latest/download/Eisvogel.zip"
}
};

if (!Object.keys(urls).includes(process.platform)) {
return;
}

const download_dir = tmp.dirSync();

// download the files
await Promise.all(Object.values(urls[process.platform]).map(async (url) => {
const response = await fetch(url);

const data = await response.arrayBuffer();

const zip_file = path.join(download_dir.name, path.basename(url));

fs.writeFileSync(zip_file, Buffer.from(data));

const zip = new StreamZip.async({ file: zip_file });
const unpacked_files_dir = zip_file.match(/(.*)\.zip$/)[1];
fs.mkdirSync(unpacked_files_dir);

await zip.extract(null, unpacked_files_dir);

await zip.close();
}));

fs.copyFileSync(path.join(download_dir.name, "Eisvogel", "eisvogel.latex"), "eisvogel.latex");

if (process.platform === "win32") {
fs.copyFileSync(path.join(download_dir.name, path.basename(urls.win32.pandoc).match(/(.*)\.zip$/)[1], "pandoc-3.1.13", "pandoc.exe"), "pandoc.exe");

// get the path with its changed filename
const dir = fs.readdirSync(path.join(download_dir.name, "install-tl")).filter((ele) => ele.match(/^install-tl-\d{8}$/))[0];

child_process.execSync(`${path.join(download_dir.name, "install-tl", dir, "install-tl-windows.bat")} -portable -no-gui --profile texlive.profile`, { stdio: "inherit" });
}

fs.rmSync(download_dir.name, { recursive: true, force: true });
})();
2 changes: 1 addition & 1 deletion build-scripts/templates-watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ async function watch() {
});

await ctx.watch();
console.log("watching...");
console.log("watching ...");
}

watch();
Binary file added casparcg/Media/Green Plants.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion casparcg/Templates/JohnCG/Bible.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

overflow: hidden;

font-family: Ebrima;
font-family: Bahnschrift;
}

body {
Expand Down
2 changes: 0 additions & 2 deletions casparcg/Templates/JohnCG/Countdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@

font-size: 1em;

color: white;

text-wrap: nowrap;
}

Expand Down
3 changes: 1 addition & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
"song": "G:/Meine Ablage/Streaming/80_Songs/Lieder",
"psalm": "G:/Meine Ablage/Streaming/80_Songs/Psalme",
"pdf": "g:/Meine Ablage/Streaming/60_PDF/",
"bible": "Bibles/Luther-Bibel.json"
"bible": "files/Bible/Luther-Bibel.json"
},
"casparcg": {
"templates": "g:/Meine Ablage/Streaming/51_CasparCG-Templates/",
"transition_length": "12.5",
"connections": [
{
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions files/Psalm/Example.psm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"metadata": {
"indent": true,
"caption": "Example Psalm",
"id": "Book ID",
"book": "Book of Examples"
},
"text": [
[
[
"First line of the first part",
"Another line"
],
[
"First line of the seond part which is indented,",
"which can be toggled in the metada-field of the file"
],
[
"and another one"
]
],[
[
"Second page",
"indentation on the second page just continues"
]
]
]
}
Loading

0 comments on commit fb2f27d

Please sign in to comment.