Compare commits

...

4 Commits

Author SHA1 Message Date
zvonimir 19f8561862 fix update 2026-04-18 01:43:52 +02:00
zvonimir 7af7b1c1ae add better filtering 2026-04-17 15:52:55 +02:00
zvonimir 99a99dd04a add readme 2026-04-17 15:39:14 +02:00
zvonimir 46c34ba545 add jsdoc 2026-04-17 15:36:11 +02:00
5 changed files with 53 additions and 9 deletions
+10
View File
@@ -0,0 +1,10 @@
# ✝️ holybar
Simple menu bar app to show the daily readings from the Bible. It uses the [United States Conference of Catholic Bishops](https://bible.usccb.org/) as the source and the Roman Calendar ([romcal](https://www.npmjs.com/package/romcal)) package to determine the liturgical color.
## Usage
```bash
# Install dependencies
npm install
# Run the application
npm start
```
+5
View File
@@ -3,6 +3,11 @@ import * as cheerio from "cheerio";
import { error, reading } from "../helpers/html.mjs";
import { log } from "../helpers/logger.mjs";
/**
* Fetches the daily Bible reading from the USCCB website and updates the app's HTML.
*
* @param {Object} app - The application instance to update with the fetched reading.
*/
export default async function refresh(app) {
const key = format(startOfToday(), "MMddyy");
+30 -4
View File
@@ -1,13 +1,26 @@
import { format } from "date-fns";
import { format, getMonth } from "date-fns";
import Handlebars from "handlebars";
import romcal from "romcal";
import { isToday } from "date-fns";
import { isToday, startOfToday, getYear } from "date-fns";
/**
* Generates CSS styles for the HTML content, dynamically adjusting colors based on the current liturgical event.
*
* @returns {string} A string containing the CSS styles.
*/
function css() {
const now = startOfToday();
let color = "#007acc"; // Default color
// Get today's liturgical event from the Roman calendar
const event = romcal
.calendarFor(new Date().getFullYear())
.calendarFor({
year: getYear(now),
country: "croatia",
query: {
month: getMonth(now),
},
})
.find((e) => isToday(new Date(e.moment)));
if (event) {
@@ -81,8 +94,15 @@ const readingTemplate = Handlebars.compile(`
</html>
`);
/**
* Generates the HTML content for the daily Bible reading, including the title, readings, and a link to the source.
*
* @param {string} title - The title of the reading.
* @param {Array} readings - An array of reading objects, each containing a title, content, and URL.
* @returns {string} A string containing the generated HTML content for the reading.
*/
export function reading(title, readings) {
const now = new Date();
const now = startOfToday();
const url = `https://bible.usccb.org/bible/readings/${format(now, "MMddyy")}.cfm`;
const date = format(now, "MMMM d, yyyy");
@@ -94,6 +114,12 @@ export function reading(title, readings) {
});
}
/**
* Generates the HTML content for an error message when fetching the reading fails.
*
* @param {number} status - The HTTP status code of the error.
* @returns {string} A string containing the generated HTML content for the error message.
*/
export function error(status) {
return `
<html>
+5
View File
@@ -1,3 +1,8 @@
/**
* A simple logging utility that prefixes log messages with a timestamp and a tag.
*
* @param {...any} args - The arguments to log, which can be of any type.
*/
export const log = (...args) => {
const timestamp = new Date().toISOString();
console.log(`[holybar] [${timestamp}]`, ...args);
+3 -5
View File
@@ -2,13 +2,12 @@ import { statusItem } from "glimpseui";
import refresh from "./handlers/refresh.mjs";
import { base } from "./helpers/html.mjs";
import { log } from "./helpers/logger.mjs";
import { differenceInDays } from "date-fns";
import { isToday } from "date-fns";
import open from "open";
let lastDate = new Date();
let interval;
// Open a hidden screen
const app = statusItem(base, {
title: "✝️",
width: 800,
@@ -21,10 +20,9 @@ app.on("message", (message) => {
case "ready":
interval = setInterval(() => {
log("Checking for new reading...");
const now = new Date();
if (Math.abs(differenceInDays(now, lastDate)) >= 1) {
if (!isToday(lastDate)) {
refresh(app);
lastDate = now;
lastDate = new Date();
log("Updated reading for date:", lastDate);
}