Llevo tiempo utilizando Newsboat como cliente de feeds local desde la terminal.
Newsboat tienen una opción para importar archivos OPML y convertirlos en su formato para poder cargar los feeds, pero no me gusta la forma o la falta de organización por categorías, así que escribí un pequeño script para convertir el OPML con categorías en el formato para Newsboat.
package.json
{
"type": "module",
"dependencies": {
"fast-xml-parser": "^4.0.8",
"lodash-es": "^4.17.21"
}
}
index.js
import { readFile, writeFile } from "fs/promises";
import { XMLParser } from "fast-xml-parser";
import { isObject } from "lodash-es";
const parser = new XMLParser({ ignoreAttributes: false });
let urls = `"query:★ Unread:unread = \\"yes\\""\n`;
try {
// Load file
const opml = await readFile("./20221109.xml", "utf8");
try {
const json = parser.parse(opml);
json?.opml?.body?.outline?.map((category) => {
if (Array.isArray(category.outline) && category.outline?.length > 0) {
// Category
urls += `\n\n# ${category["@_title"] || category["@_text"]}\n`;
urls += `"query:${category["@_title"] || category["@_text"]}:tags # \\"${
category["@_title"] || category["@_text"]
}\\""\n`;
category.outline.map((item) => {
urls += `${item["@_xmlUrl"]} ! "~${item["@_title"]}" ${category["@_title"] || category["@_text"]}\n`;
});
} else if (isObject(category.outline)) {
// Single feed category
const item = category.outline;
urls += `\n\n# ${category["@_title"] || category["@_text"]}\n`;
urls += `"query:${category["@_title"] || category["@_text"]}:tags # \\"${
category["@_title"] || category["@_text"]
}\\""\n`;
urls += `${item["@_xmlUrl"]} ! "~${item["@_title"]}" ${category["@_title"] || category["@_text"]}\n`;
} else if (category["@_xmlUrl"]) {
// Feeds without category
urls += `\n${category["@_xmlUrl"]} "~${category["@_title"] || category["@_text"]}"`;
}
});
try {
// Copy this file to ~/.newsboat
writeFile("./urls", urls);
console.log("> ./urls");
} catch (err) {
console.log(err);
}
} catch (err) {
console.log(err);
}
} catch (err) {
console.log(err);
}
Para empezar se agrega la linea "query:★ Unread:unread = \"yes\""
para crear una categoría con todas los artículos sin leer, luego se crean las categorías con los feeds ocultos (!
) para que solo se puedan visualizar al entrar a la categoría y todo eso se guarda en el archivo urls
en el formato para Newsboat.
El resultado es algo así:
urls
"query:★ Unread:unread = \"yes\""
https://feed.abeestrada.com/all "~Abe Estrada"
https://rpilocator.com/feed.rss "~RPi Locator"
# Android
"query:Android:tags # \"Android\""
https://blog.google/products/android/rss/ ! "~Android" Android
http://feeds.feedburner.com/blogspot/hsDu ! "~Android Developers Blog" Android
# Tech
"query:Tech:tags # \"Tech\""
http://www.engadget.com/rss.xml ! "~Engadget" Tech
http://www.theverge.com/rss/index.xml ! "~The Verge" Tech
http://feeds.arstechnica.com/arstechnica/technology-lab ! "~Ars Technica" Tech
Cada categoría es definida con un query
y donde cada url consiste de cuatro partes:
url ! "~Titulo" Categoría
Screenshots


