2024-07-17 16:13:54 +02:00
|
|
|
|
#!/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 { version, description }= s.cat("package.json").xargs(JSON.parse);
|
2024-08-29 20:02:13 +02:00
|
|
|
|
const today= [ 6, 0, 1, 2, 3, 4, 5 ][new Date().getDay()];
|
2024-07-17 16:13:54 +02:00
|
|
|
|
|
|
|
|
|
$.api()
|
|
|
|
|
.version(version)
|
|
|
|
|
.describe(description)
|
|
|
|
|
.command("pull", "Update article list")
|
|
|
|
|
.option("--git", "Update git repository")
|
2024-08-29 20:02:13 +02:00
|
|
|
|
.option("--dry-run", "Dry run")
|
|
|
|
|
.action(async function pull({ git: is_git= false, ["dry-run"]: dryRun= false, ..._ }= {}){
|
|
|
|
|
if(dryRun) is_git= false;
|
2024-07-17 16:13:54 +02:00
|
|
|
|
if(is_git) s.run`git pull --rebase`;
|
|
|
|
|
|
|
|
|
|
const menicka= await Promise.allSettled([ menickoCukrovarka(), menickoGlobus(), menickoMamafoodbistro() ])
|
2024-11-28 10:02:46 +01:00
|
|
|
|
.then(results=> results.filter(p=> p.status!=="rejected" ? true : (echo(p), false)).map(p=> p.value));
|
2024-07-17 16:51:51 +02:00
|
|
|
|
const days= [ "pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota", "neděle" ];
|
2024-08-29 20:02:13 +02:00
|
|
|
|
const out_head= description+"\n\n" + days.map((v)=> `[${v}](#${v})`).join(" · "); // anchors for days
|
|
|
|
|
let out= "";
|
|
|
|
|
for(let i= today; i < days.length; i++){ // menicka
|
|
|
|
|
const day= days[i];
|
2024-07-17 16:13:54 +02:00
|
|
|
|
out+= `\n\n## ${day}\n`;
|
|
|
|
|
out+= menicka.map(dayToMd(day)).join("\n");
|
|
|
|
|
}
|
|
|
|
|
const gen= [ "<!-- generated -->", "<!-- /generated -->" ];
|
2024-07-17 17:01:02 +02:00
|
|
|
|
const target= "README.md";
|
|
|
|
|
const readme= s.cat(target);
|
2024-08-29 20:02:13 +02:00
|
|
|
|
const readme_before= readme.indexOf(gen[0])-1;
|
|
|
|
|
const readme_today= today===0 ? -1 : readme.indexOf(`## ${days[today]}`, readme_before)-2;
|
2024-07-17 16:13:54 +02:00
|
|
|
|
out= [
|
2024-08-29 20:02:13 +02:00
|
|
|
|
readme.slice(0, readme_before),
|
|
|
|
|
readme_today < 0 ? gen[0]+out_head : readme.slice(readme_before+1, readme_today),
|
|
|
|
|
out.replace(/(\*)/g, "\\$1"),
|
|
|
|
|
gen[1], readme.slice(readme.indexOf("\n", readme.indexOf(gen[1]))+1)
|
2024-07-17 16:13:54 +02:00
|
|
|
|
].join("\n");
|
2024-08-29 20:02:13 +02:00
|
|
|
|
if(dryRun) echo(out);
|
|
|
|
|
else s.echo(out).to(target);
|
2024-07-17 16:13:54 +02:00
|
|
|
|
|
2024-07-17 17:01:02 +02:00
|
|
|
|
if(is_git) gitCommit([ target ], "pull");
|
2024-07-17 16:13:54 +02:00
|
|
|
|
$.exit(0);
|
|
|
|
|
})
|
|
|
|
|
.parse();
|
|
|
|
|
|
|
|
|
|
function dayToMd(day){
|
|
|
|
|
return function({ symbol, name, url, dny }){
|
|
|
|
|
let has= Reflect.has(dny, day);
|
|
|
|
|
if(!has && (day==="sobota" || day==="neděle") && Reflect.has(dny, "víkend")){
|
|
|
|
|
has= true;
|
|
|
|
|
day= "víkend";
|
|
|
|
|
}
|
|
|
|
|
const section= `[${symbol} ${name}](${url})`;
|
|
|
|
|
if(!has) return `- ${section}: —`;
|
|
|
|
|
|
|
|
|
|
let out= `- ${section}:`;
|
|
|
|
|
const { polevky, hlavni }= dny[day];
|
|
|
|
|
const food= f=> out+= `\n - ${f}`;
|
|
|
|
|
polevky.forEach(food);
|
|
|
|
|
hlavni.forEach(food);
|
|
|
|
|
return out;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
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`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
|
|
|
async function fetchHTML(url){
|
|
|
|
|
const res= await fetch(url);
|
|
|
|
|
if(res.status !== 200) throw new Error(`Fetch failed with status ${res.status}`);
|
|
|
|
|
let text;
|
|
|
|
|
if(res.headers.get("Content-Type").includes("charset=windows-1250"))
|
|
|
|
|
text= await res.arrayBuffer().then(buff=> new TextDecoder('windows-1250').decode(buff));
|
|
|
|
|
else
|
|
|
|
|
text= await res.text();
|
|
|
|
|
|
|
|
|
|
const virtualConsole = new VirtualConsole();
|
|
|
|
|
virtualConsole.on("error", () => {
|
|
|
|
|
// No-op to skip console errors.
|
|
|
|
|
});
|
|
|
|
|
return (new JSDOM(text, { virtualConsole })).window;
|
|
|
|
|
}
|
|
|
|
|
async function menickoMamafoodbistro(){
|
|
|
|
|
const url= "https://www.mamafoodbistro.cz/#poledne";
|
|
|
|
|
const { document }= await fetchHTML(url);
|
|
|
|
|
const menicko= document.querySelectorAll("section")[2].getElementsByClassName("sqs-html-content")[1];
|
|
|
|
|
const dny= {};
|
|
|
|
|
for(const den of menicko.getElementsByTagName("h4")){
|
|
|
|
|
const polevka= den.nextElementSibling;
|
2024-11-27 10:33:57 +01:00
|
|
|
|
if(!polevka) break;
|
2024-10-22 10:49:36 +02:00
|
|
|
|
let hi= polevka;
|
2024-11-27 10:33:57 +01:00
|
|
|
|
const hlavni= [];
|
2024-07-22 15:56:29 +02:00
|
|
|
|
while(( hi= hi.nextElementSibling ) && hi.tagName !== "H4")
|
|
|
|
|
hlavni.push(hi);
|
2024-07-17 16:13:54 +02:00
|
|
|
|
Reflect.set(dny, den.textContent.trim().toLowerCase(), {
|
|
|
|
|
polevky: [ polevka.textContent ],
|
2024-07-22 15:56:29 +02:00
|
|
|
|
hlavni: hlavni.map(el=> el.textContent),
|
2024-07-17 16:13:54 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { name: "MAMAFOOD", symbol: "🍎", url, dny };
|
|
|
|
|
}
|
|
|
|
|
async function menickoCukrovarka(){
|
|
|
|
|
const url= "https://www.menicka.cz/api/iframe/?id=8542&continuous=true";
|
|
|
|
|
const { document }= await fetchHTML(url);
|
2024-11-28 10:02:46 +01:00
|
|
|
|
const food= el=> !el ? "—" : el.getElementsByClassName("food")[0].textContent;
|
2024-07-17 16:13:54 +02:00
|
|
|
|
const dny= {};
|
|
|
|
|
for(const den of document.getElementsByClassName("content")){
|
|
|
|
|
let name= den.getElementsByTagName("h2")[0].textContent.trim();
|
|
|
|
|
name= name.slice(0, name.indexOf(" ")).toLowerCase();
|
|
|
|
|
const [ polevka ]= den.getElementsByClassName("soup");
|
|
|
|
|
const hlavni= den.getElementsByClassName("main");
|
|
|
|
|
Reflect.set(dny, name, {
|
|
|
|
|
polevky: [ food(polevka) ],
|
|
|
|
|
hlavni: [ ...hlavni ].map(food),
|
|
|
|
|
});
|
|
|
|
|
if(name==="neděle") break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { name: "Jídelna Čakovice", symbol: "🏭", url, dny };
|
|
|
|
|
}
|
|
|
|
|
async function menickoGlobus(){
|
|
|
|
|
const url= "https://www.globus.cz/praha-cakovice/sluzby-a-produkty/restaurace#klasicke-menu";
|
|
|
|
|
const { document }= await fetchHTML(url);
|
|
|
|
|
const menicko= document.getElementById("klasicke-menu");
|
|
|
|
|
const dny= {};
|
|
|
|
|
for(const den of menicko.getElementsByTagName("li")){
|
|
|
|
|
const name= den.getElementsByTagName("h3")[0].textContent.trim();
|
|
|
|
|
const vse= [ ...den.getElementsByTagName("tr") ].map(el=> el.getElementsByTagName("td")[1].textContent.trim());
|
|
|
|
|
Reflect.set(dny, name, {
|
|
|
|
|
polevky: vse.slice(0, 2),
|
|
|
|
|
hlavni: vse.slice(2),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { name: "Globus", symbol: "🏪", url, dny };
|
|
|
|
|
}
|