// Menu: Currency Converter using google// Author: Jakub Olek// Twitter: @JakubOlek/** @type {import("@johnlindquist/kit")} */const from = await arg("from", ["pln", "usd", "eur"]);const to = await arg("to", ["usd", "pln", "eur"]);const query = await arg("amount");const value = await scrapeSelector(`https://google.com/search?q=${encodeURIComponent(query + " " + from + " " + to)}`,"span[data-value]");div(query + " " + from + " = " + value + " " + to, "p-4");
// Menu: RCKIK mobile// Description: Show filtered plan of mobile RCKIK busses// Author: Jakub Olek// Twitter: @JakubOlek/** @type {import("@johnlindquist/kit")} */function transform(node) {// Edit that to filter locations that you're interested in// has to be inside transform function - as it's being serialized and passed to browserconst filter = "Poznań";const columns = [...node.querySelectorAll("td")];if (columns[3].innerHTML.startsWith(filter)) {return (columns[0].querySelector("a").innerHTML +" " +columns[3].innerHTML +" " +columns[2].innerHTML);}}const pagination = await scrapeSelector("https://www.rckik.poznan.pl/najblizsze-wyjazdy?page=1",".pagination li");const numberOfPages = pagination.length;let t = [];for (let i = 1; i <= numberOfPages; i += 1) {const result = await scrapeSelector(`https://www.rckik.poznan.pl/najblizsze-wyjazdy?page=${i}`,"#calendarTable tr:not(.header):not(.canceled)",transform);t = t.concat(result);}div(`<ul>${t.filter(Boolean).map((date) => `<li>${date}</li>`).join("")}</ul>`,"p-4");
// Menu: Weather by yr.no// Author: Jakub Olek// Twitter: @JakubOlek/** @type {import("@johnlindquist/kit")} *//*** 1. Open https://www.yr.no/* 2. Find your location* 3. Copy what comes AFTER https://www.yr.no/en/forecast/daily-table/ to location const*/const location = "5-1233000/Poland/Poznan";div(`<iframe src="https://www.yr.no/en/print/forecast/${location}#toolbar=0" height=800 width=600/>`,"p-2");
// Menu: Record Screen// Description: Start QuickTime player and open screen recorder// Author: Jakub Olek// Twitter: @JakubOlekawait run("app-launcher", "QuickTime Player");await keystroke("command control n");
// Menu: Ping// Description: Ping destination and show line graph of latest values// Author: Jakub Olek// Twitter: @JakubOlekconst jsdom = await npm("jsdom");await npm("canvas");const Chart = await npm("chart.js");const { JSDOM } = jsdom;// Edit the list to suit your needsconst destination = await arg("ping", ["8.8.8.8", "google.com"]);// How many entries should the chart showconst entries = 20;const command = `ping ${destination}`;const child = exec(command, { async: true });const dom = new JSDOM(`<!DOCTYPE html><canvas id="bar-chart" width="800" height="450"></canvas>`);global.window = dom.window;Chart.defaults.color = "white";Chart.defaults.font = { size: 24, weight: "bold" };const labels = new Array(entries).fill().map((_, i) => i).reverse();let output = [];const chartData = {labels: labels,datasets: [{label: `${command}: - ms`,backgroundColor: "rgb(255, 99, 132)",borderColor: "rgb(255, 99, 132)",data: output,},],};const chart = new Chart(dom.window.document.getElementById("bar-chart"), {type: "line",data: chartData,options: {animation: false,tooltips: { enabled: false },hover: { mode: null },},});let firstLine = true;child.stdout.on("data", function (data) {if (!firstLine) {const value = +data.replace(/.*time=(.*)ms/, "$1");output.push(value);if (output.length > entries) {output = output.slice(1);}chartData.datasets[0].label = `${command}: ${value}ms`;chartData.datasets[0].data = output;chart.update();div(`<img src="${chart.toBase64Image("image/jpeg", 1)}"/>`, "p-4");} else {firstLine = false;}});
// Menu: Open Jira ticket in browser// Description: Parses a valid ticket number from selection and opens it in browser// Author: Jakub Olek// Twitter: @JakubOlekconst jiraDomain = await env("JIRA_DOMAIN");const text = await getSelectedText();const jiraTicket = text.match(/([A-Z]{2,5}-[0-9]+)/);if (jiraTicket) {focusTab(`${jiraDomain}/browse/${jiraTicket[0]}`);}