Compare commits

...

85 Commits

Author SHA1 Message Date
Bot
c8f411f46f Updated by bot – pull 2025-06-23 19:44:01 +00:00
Bot
9c58b975b4 Updated by bot – pull 2025-06-20 19:44:43 +00:00
Bot
548c6b9a62 Updated by bot – pull 2025-06-16 19:43:50 +00:00
Bot
46f4f39603 Updated by bot – pull 2025-06-15 19:43:49 +00:00
Bot
dd6d51fc39 Updated by bot – pull 2025-06-09 19:44:30 +00:00
Bot
631386dcd3 Updated by bot – pull 2025-06-02 19:44:35 +00:00
Bot
64a16c6afd Updated by bot – pull 2025-05-26 19:49:13 +00:00
Bot
33a19b324d Updated by bot – pull 2025-05-19 19:44:05 +00:00
Bot
ccd578cea5 Updated by bot – pull 2025-05-12 19:44:06 +00:00
Bot
d8d2b3cb56 Updated by bot – pull 2025-05-05 19:44:36 +00:00
Bot
11f7bef325 Updated by bot – pull 2025-05-04 19:44:38 +00:00
Bot
6efdd8177a Updated by bot – pull 2025-04-28 19:44:16 +00:00
Bot
c0955cf0a3 Updated by bot – pull 2025-04-27 19:44:17 +00:00
Bot
de7e7fd4f0 Updated by bot – pull 2025-04-21 19:44:13 +00:00
Bot
784444d1fc Updated by bot – pull 2025-04-20 19:44:13 +00:00
Bot
59af72a72c Updated by bot – pull 2025-04-14 19:44:26 +00:00
Bot
41b7ac3688 Updated by bot – pull 2025-04-07 19:43:59 +00:00
Bot
c18aa5d278 Updated by bot – pull 2025-03-31 19:44:45 +00:00
Bot
1747eadc54 Updated by bot – pull 2025-03-24 19:44:09 +00:00
Bot
7d56bb1f59 Updated by bot – pull 2025-03-23 19:44:08 +00:00
Bot
158b96c7c5 Updated by bot – pull 2025-03-17 19:44:35 +00:00
Bot
950868bfb4 Updated by bot – pull 2025-03-10 19:44:36 +00:00
3d1ac373e3 🐛 Adds encoding entities
All checks were successful
Update RSS / update-rss (push) Successful in 5m13s
2025-03-04 09:36:31 +01:00
Bot
b1db05311f Updated by bot – pull 2025-03-03 19:44:08 +00:00
4e8cc1bd94 🐛 Quickfix amp in title
All checks were successful
Update RSS / update-rss (push) Successful in 5m14s
Signed-off-by: Jan Andrle <andrle.jan@centrum.cz>
2025-02-24 22:23:38 +01:00
Bot
8c766b0ac3 Updated by bot – pull 2025-02-24 19:44:10 +00:00
Bot
13441a8788 Updated by bot – pull 2025-02-17 19:44:27 +00:00
Bot
e494ea3ff6 Updated by bot – pull 2025-02-10 19:44:40 +00:00
Bot
b3fed778f3 Updated by bot – pull 2025-02-03 19:44:41 +00:00
Bot
85cdbe7a9e Updated by bot – pull 2025-01-27 19:44:38 +00:00
Bot
c09b247142 Updated by bot – pull 2025-01-20 19:44:06 +00:00
Bot
26b75634d5 Updated by bot – pull 2025-01-19 19:44:05 +00:00
Bot
7d04475878 Updated by bot – pull 2025-01-13 18:44:36 +00:00
Bot
da9a6d9e9d Updated by bot – pull 2025-01-06 18:44:16 +00:00
Bot
44da85f0d0 Updated by bot – pull 2024-12-21 18:44:28 +00:00
Bot
9d55e4ebd9 Updated by bot – pull 2024-12-16 18:45:01 +00:00
0a5326b80f 🐛 Fallback for missing author and pull
All checks were successful
Update RSS / update-rss (push) Successful in 5m44s
2024-12-10 10:09:42 +01:00
Bot
c74512e208 Updated by bot – pull 2024-12-02 18:44:42 +00:00
8f0a06a526 Updates deps
All checks were successful
Update RSS / update-rss (push) Successful in 5m10s
2024-11-28 09:28:17 +01:00
Bot
2f3caba17e Updated by bot – pull 2024-11-25 18:44:27 +00:00
Bot
77ecfa309a Updated by bot – pull 2024-11-19 18:44:25 +00:00
Bot
8568922457 Updated by bot – pull 2024-11-18 18:44:23 +00:00
Bot
39e8ff4b4c Updated by bot – pull 2024-11-11 18:44:24 +00:00
Bot
7abd1571b9 Updated by bot – pull 2024-11-04 18:44:25 +00:00
Bot
898b7d7ea5 Updated by bot – pull 2024-10-28 18:44:26 +00:00
Bot
e33cc9d756 Updated by bot – pull 2024-10-21 17:44:27 +00:00
Bot
9b5084bd63 Updated by bot – pull 2024-10-14 17:44:01 +00:00
Bot
fbf3e60e0d Updated by bot – pull 2024-10-07 17:43:59 +00:00
Bot
81c8d52b00 Updated by bot – pull 2024-10-01 17:43:55 +00:00
Bot
ffd2f41a13 Updated by bot – pull 2024-09-23 17:44:29 +00:00
Bot
1aab450bf7 Updated by bot – pull 2024-09-20 17:44:28 +00:00
Bot
46765180ae Updated by bot – pull 2024-09-16 17:44:29 +00:00
Bot
55e5e9dc7d Updated by bot – pull 2024-09-15 17:44:27 +00:00
Bot
a56d920a67 Updated by bot – pull 2024-09-09 17:44:21 +00:00
000216ae77 updates dependencies
All checks were successful
Update RSS / update-rss (push) Successful in 6m8s
2024-09-09 11:25:31 +02:00
Bot
9e16a8ea95 Updated by bot – pull 2024-09-03 17:44:23 +00:00
Bot
633ca5465b Updated by bot – pull 2024-09-02 17:44:22 +00:00
1ffe1ab293 🐛 updated rss by hand
All checks were successful
Update RSS / update-rss (push) Successful in 5m17s
currently new drop detection not working!!!
2024-08-28 21:14:11 +02:00
Bot
200669791c Updated by bot – pull 2024-08-19 17:45:08 +00:00
Bot
fd723e72e9 Updated by bot – pull 2024-08-12 17:44:34 +00:00
Bot
b146530fe2 Updated by bot – pull 2024-08-05 17:44:35 +00:00
Bot
fe224be1d3 Updated by bot – pull 2024-08-02 17:44:46 +00:00
Bot
97ef8e3fb2 Updated by bot – pull 2024-07-30 17:44:47 +00:00
Bot
f20337c45e Updated by bot – pull 2024-07-26 17:44:49 +00:00
Bot
6fbb45210f Updated by bot – pull 2024-07-23 17:44:50 +00:00
Bot
4404a4b962 Updated by bot – pull 2024-07-15 17:44:50 +00:00
Bot
ded37d1178 Updated by bot – pull 2024-07-14 17:44:49 +00:00
71acab3ce5 🐛 improved to fulfill the validator
All checks were successful
Update RSS / update-rss (push) Successful in 5m14s
see https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fgitea.jaandrle.cz%2Fjaandrle%2Fpagenotfound-cli%2Fraw%2Fbranch%2Fmain%2Frss.xml
2024-07-11 16:01:02 +02:00
Bot
a576caff53 Updated by bot – pull 2024-07-09 17:44:48 +00:00
Bot
e080684fb2 Updated by bot – pull 2024-07-08 17:44:46 +00:00
5d174d2f19 Now cli is able to update the last drop articles
All checks were successful
Update RSS / update-rss (push) Successful in 5m20s
2024-07-08 10:33:33 +02:00
Bot
ce93c7241f Updated by bot – pull 2024-07-07 17:44:50 +00:00
7ebcf6e2d2 🐛 📺 pull --rebase before commit
All checks were successful
Update RSS / update-rss (push) Successful in 5m18s
2024-07-06 20:05:05 +02:00
8f0deba912 🐛 now, pulls first in Gieta Action
All checks were successful
Update RSS / update-rss (push) Successful in 5m18s
because of how it works now receiving
error, see for example:
https://gitea.jaandrle.cz/jaandrle/pagenotfound-cli/actions/runs/8#jobstep-4-8
2024-07-06 12:19:05 +02:00
Bot
1b2f55079c Updated by bot – pull 2024-07-01 17:44:48 +00:00
5a1c52565e 📺 🐛 nodejsscript is now peerDependencie
All checks were successful
Update RSS / update-rss (push) Successful in 5m17s
2024-06-28 14:43:05 +02:00
6c6c269dbd 📺 updates package info 2024-06-28 10:45:13 +02:00
df82405ed8 Updates workflow (more functional and straightforward)
All checks were successful
Update RSS / update-rss (push) Successful in 5m16s
2024-06-27 16:35:15 +02:00
Bot
39bb5ef62d Updated by bot – pull 2024-06-27 16:34:42 +02:00
Bot
4bbd88a563 Updated by bot – pull 2024-06-27 16:32:57 +02:00
0054ceb6f2 cron daily at 19:39 Prague 2024-06-27 11:09:58 +02:00
add7993460 cron daily at 10:47 Prague 2024-06-27 11:03:28 +02:00
db2af48953 🐛 cron at 9:05 GMT 2024-06-27 11:00:30 +02:00
597e21895a 🐛 adds commit, fixes cron
All checks were successful
Update RSS / update-rss (push) Successful in 5m14s
2024-06-27 10:52:51 +02:00
837cea046d 👮 better cron name
Some checks failed
Update RSS / update-rss (push) Failing after 6m16s
2024-06-26 15:56:05 +02:00
6 changed files with 6232 additions and 1154 deletions

View File

@ -2,10 +2,10 @@ name: Update RSS
on:
workflow_dispatch:
schedule:
- cron: '0 3 * * *' # daily at 3am
- cron: '39 19 * * *' # daily at 19:39 Prague
jobs:
Explore-Gitea-Actions:
update-rss:
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
@ -14,4 +14,4 @@ jobs:
node-version: lts/*
cache: 'npm'
- run: npm ci
- run: npx nodejsscript cli.js pull
- run: npx nodejsscript cli.mjs pull --git

134
cli.mjs
View File

@ -1,7 +1,7 @@
#!/usr/bin/env -S npx nodejsscript
/* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */
const url_drops= "https://pagenotfound.cz/drop/";
const { version, description }= s.cat("package.json").xargs(JSON.parse);
const { version, description, homepage }= s.cat("package.json").xargs(JSON.parse);
/**
* @typedef {Object} Article
* @property {string} title
@ -20,76 +20,168 @@ const { version, description }= s.cat("package.json").xargs(JSON.parse);
* @property {Article[]} articles
* @property {Drop[]} drops
* */
/**
* @typedef {Object} State
* @property {Sitemap} json
* @property {string[]} changed Changed files
* */
const pubDate= (function pubDateInner(){ // pubDate must be an RFC-822 date-time
const intl= new Intl.DateTimeFormat("en-gb", {
/* Wed, 02 Oct 2002 */ weekday: "short", day: "2-digit", month: "short", year: "numeric",
/* 08:00:00 */ hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit",
/* EST */ timeZoneName: "longOffset", timeZone: "UTC",
});
/** @param {string} date */
return date=> {
const D= new Date(date);
const d= intl.format(D);
// remove redundant second comma to make it RFC-822
const red_comma_i= d.indexOf(",", d.indexOf(",")+1);
return d.slice(0, red_comma_i) + d.slice(red_comma_i+1);
};
})();
$.api()
.version(version)
.describe(description)
.command("pull", "Update article list")
.action(async function pull(){
const json= await sitemap();
toRSS(json);
.option("--git", "Update git repository")
.action(async function pull({ git: is_git= false }){
if(is_git) s.run`git pull --rebase`;
const { changed }= await sitemap().then(toRSS);
echo("Changed files:", changed.length ? changed.join(", ") : "—");
if(is_git) gitCommit(changed, "pull");
$.exit(0);
})
.command("only-rss", "Update RSS from known sitemap")
.action(async function onlyRSS(){
const { path, json }= knownSitemap();
const status= await toRSS({ json, changed: [ path ] });
echo({ status });
$.exit(0);
})
.parse();
/** @param {Sitemap} json */
async function toRSS(json){
function gitCommit(files, des= "not specified"){
if(!files.length || !s.run`git diff --numstat`.trim())
return echo("Nothig todo");
echo("Diff to save");
s.run`git config user.name "Bot"`;
s.run`git config user.email "${"zc.murtnec@naj.elrdna".split("").reverse().join("")}"`;
s.run`git add ${files}`;
s.run`git commit -m "Updated by bot ${des}"`;
s.run`git push`;
s.run`git config --remove-section user`;
}
/**
* @param {State} state
* @returns {State} state
* */
async function toRSS({ json, changed }){
if(!changed.length) return { json, changed };
const path= "rss.xml";
const host= "https://pagenotfound.cz";
const articles= json.articles.map(function({ title, perex, author, loc, drop }){
return [
"<item>",
...[
`<title>${title}</title>`,
`<title>${encodeToXml(title)}</title>`,
`<link>${host+loc}</link>`,
`<description>${perex}</description>`,
`<author>${author}</author>`,
`<pubDate>${json.drops.find(d=> d.drop === drop).date}</pubDate>`,
`<guid>${host+loc}</guid>`,
`<description>${encodeToXml(perex)}</description>`,
`<dc:creator>${encodeToXml(author)}</dc:creator>`,
`<pubDate>${pubDate(json.drops.find(d=> d.drop === drop).date)}</pubDate>`,
`<category>${drop}</category>`,
].map(l=> "\t"+l),
"</item>"
].map(l=> "\t"+l).join("\n");
});
const description = [
"Page not found jsme založili z touhy po zábavné, kvalitní a inovativní žurnalistice.",
"Chceme vám tu nabízet komplexní long ready, nečekané bonusy, multimediální obsah",
"a hlavně texty, které nám samotným v ostatních médiích chybí. Budujte spolu s námi",
"komunitu Page not found, dejte nám zpětnou vazbu na první drop, přihlaste se",
"k odebírání newsletterů. Společně s vámi budeme moct naše cíle plnit rychleji."
].join(" ");
s.echo([
`<?xml version="1.0" encoding="UTF-8" ?>`,
`<rss version="2.0">`,
`<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">`,
"<channel>",
` <title>Pagenotfound.cz</title>`,
` <link>${host}</link>`,
` <description>${description}</description>`,
` <atom:link href="${homepage}/raw/branch/main/rss.xml" rel="self" type="application/rss+xml" />`,
...articles,
"</channel>",
"</rss>"
].join("\n")).to(path);
return { json, changed: [...changed, path] };
}
import { JSDOM } from "jsdom";
/** @returns {Promise<State>} */
async function sitemap(){
const path= "sitemap.json";
/** @type {Sitemap} */
const json= s.test("-f", path) ? s.cat(path).xargs(JSON.parse) : { drops: [], articles: [] };
const [ article_last= { drop: "" } ]= json.articles;
const { json, path }= knownSitemap();
await syncDrops(json);
const [ { drop: drop_last } ]= json.drops;
if(drop_last === article_last.drop) return json;
const res= await fetch(url_drops+drop_last);
if(res.status !== 200) return;
if(res.status !== 200) return { json, changed: [] };
const drop_articles= dropArticles(drop_last, json);
const dom= new JSDOM(await res.text());
const diff= [];
for(const article of dom.window.document.querySelectorAll("article")){
const loc= article.querySelector("a")?.href;
if(!loc){
echo("Article without link:", article.textContent);
continue;
}
if(drop_articles.has(loc)) continue;
diff.push({
title: article.querySelector("h2").textContent.trim(),
perex: article.querySelector("[class^=ArticleTile_perex]").textContent.trim(),
author: article.querySelector("[class^=ArticleTile_author]").textContent.trim(),
loc: article.querySelector("a").href,
author: (article.querySelector("[class^=ArticleTile_author]")?.textContent || "Redakce").trim(),
loc,
drop: drop_last,
});
}
if(!diff.length) return { json, changed: [] };
json.articles.unshift(...diff);
s.echo(JSON.stringify(json, null, "\t")).to(path);
return json;
return { json, changed: [ path ] };
}
function encodeToXml(str){
if(!str) return str;
return str
.replace(/&/g, "&amp;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
function knownSitemap(){
const path= "sitemap.json";
/** @type {Sitemap} */
const json= s.test("-f", path) ? s.cat(path).xargs(JSON.parse) : { drops: [], articles: [] };
return { json, path };
}
/**
* Assumes that articles are sorted from newest to oldest
* @param {Drop.drop} drop
* @param {Sitemap} json
* @returns {Set<Article.loc>}
* */
function dropArticles(drop, { articles }){
const out= new Set();
for(const article of articles){
if(article.drop !== drop) break;
out.add(article.loc);
}
return out;
}
/** @param {Sitemap} json */
async function syncDrops(json){

2180
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,28 @@
{
"name": "pagenotfound-cli",
"version": "1.0.0",
"description": "Utility primary for generating RSS feed for Pagenotfound",
"bin": "cli.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"jsdom": "~24.1",
"nodejsscript": "~1.0"
},
"engines": {
"node": ">=18.19"
}
"name": "pagenotfound-cli",
"version": "1.2.3",
"description": "Utility primary for generating RSS feed for Pagenotfound",
"bin": "cli.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jan Andrle <andrle.jan@centrum.cz>",
"repository": {
"type": "git",
"url": "https://gitea.jaandrle.cz/jaandrle/pagenotfound-cli.git"
},
"homepage": "https://gitea.jaandrle.cz/jaandrle/pagenotfound-cli",
"bugs": {
"url": "https://gitea.jaandrle.cz/jaandrle/pagenotfound-cli/issues"
},
"license": "MIT",
"dependencies": {
"jsdom": "~25.0"
},
"peerDependencies": {
"nodejsscript": "~1.0"
},
"engines": {
"node": ">=18.19"
}
}

2795
rss.xml

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff