Skip to content

Instantly share code, notes, and snippets.

@leo848
Last active November 26, 2021 07:40
Show Gist options
  • Save leo848/7919e0ea059815ab1c30fb6e7e63d98d to your computer and use it in GitHub Desktop.
Save leo848/7919e0ea059815ab1c30fb6e7e63d98d to your computer and use it in GitHub Desktop.
An extra large widget (for the iPad) displaying a random Wikipedia article as well as an image, a short summary and related links.
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: light-gray; icon-glyph: user-graduate;
const lang = args.widgetParameter || args.queryParameters.lang || "de"
let res, img, links, related = [];
let qParams = args.queryParameters;
// qParams.title = qParams.title || "4529281"
//if (config.runsInApp) sendNotification("qParams", qParams);
qParams?.title ?
await initializeGlobalsWithTitle(qParams.title) :
await initializeGlobals();
console.log(links);
Array.prototype.last = function(){
return this[this.length - 1];
};
Array.prototype.randomChoice = function(){
return this[Math.floor(Math.random() * this.length)]
}
let widget = createWidget({
title: res?.title,
desc: res?.description,
body: res?.extract,
img: img,
imgUrl: res?.originalimage?.source, url: res?.content_urls?.mobile.page
})
if (config.runsInWidget) {
// create and show widget
Script.setWidget(widget)
Script.complete()
}
else {
widget.presentExtraLarge();
}
async function initializeGlobals(){
let articleNotAvailable = true;
for (let mxctr = 0;
mxctr < 10 && articleNotAvailable;
mxctr++){
try {
res = await loadRandomArticle(lang);
img = await loadThumbnail(res);
links = await loadLinks(res);
articleNotAvailable = false;
} catch (e) {
console.log(e)
}
}
}
async function initializeGlobalsWithTitle(title) {
let ttitle = Number(qParams.title);
if (isNaN(ttitle)) throw "Not a Number, but " + title
res = await loadArticleByPageID(lang, ttitle)
log("init by number")
//sendNotification(title, qParams);
img = await loadThumbnail(res);
links = await loadLinks(res);
}
async function loadRandomArticle(lang){
const url = `https://${lang}.wikipedia.org/api/rest_v1/page/random/summary`;
const req = new Request(url);
return await req.loadJSON();
}
async function loadArticleByTitle(lang,title){
const url = `https://${lang}.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(title.replace(" ", "_"))}`
const req = new Request(url);
return await req.loadJSON();
}
async function loadArticleByPageID(lang,id){ const url = `https://${lang}.wikipedia.org/w/api.php?action=query&pageids=${id}&format=json`;
const req = new Request(url);
const title = (await req.loadJSON())?.query.pages[id].title.replace(" ", "_");
console.log("lABPID title: " + title);
return (await loadArticleByTitle(lang,title));
}
async function loadThumbnail(res){
if (!res?.thumbnail?.source) return;
return await new Request(res.thumbnail.source).loadImage();
}
async function loadLinks(res){
const canon = (res.content_urls?.desktop?.page??"/")
.split("/")
.slice(-1)[0];
console.log("canon: " + canon);
const url = `https://${lang}.wikipedia.org/w/api.php?action=query&titles=${canon}&prop=links&pllimit=max&format=json`;
const request = new Request(url)
const json = await request.loadJSON();
const links = json?.query?.pages[res.pageid]?.links ?? [];
const retArr = [];
for (let i = 0, sfctr = 0; i < 3 && sfctr < 100; i++, sfctr++){
let elt = links[
Math.floor(Math.random()*links.length)
].title;
let id = (await loadArticleByTitle(lang, elt)).pageid
//log("name: " + elt);
console.log("pageid: " + id);
if (!retArr.includes(id)) {retArr.push(id);related.push(elt)}
else i--;
}
return retArr
}
function createWidget(obj){//title, desc, body, img, imgUrl, widgeturl) {
console.log("Title: "+obj.title)
console.log("Desc: " +obj.imgDesc)
let w = new ListWidget()
w.backgroundGradient = createGradient();
let stack = w.addStack()
stack.layoutHorizontally()
if (obj.img){
let imageStack = stack.addStack();
imageStack.layoutVertically();
imageStack.size = new Size(220, 0);
imageStack.centerAlignContent()
let image = imageStack.addImage(obj.img);
image.centerAlignImage()
image.applyFittingContentMode()
image.url = obj.imgUrl;
image.cornerRadius = 15;
stack.addSpacer(20);
}
let innerTextStack = stack.addStack();
innerTextStack.setPadding(2, 5, 2, 5);
innerTextStack.cornerRadius = 15;
//innerTextStack.borderWidth = 5;
innerTextStack.layoutVertically();
let titleTxt = innerTextStack.addText(obj.title ?? "No title (wait what)")
titleTxt.textColor = Color.white()
titleTxt.font = Font.boldSystemFont(30);
titleTxt.url = obj.url;
let descText = innerTextStack.addText(obj.desc ?? "No description");
descText.textColor = Color.gray()
descText.font = Font.italicSystemFont(18);
innerTextStack.addSpacer(3)
let bodyText = innerTextStack.addText(obj.body ?? "No body (?)");
bodyText.textColor = Color.white()
bodyText.font = getAppropiateFontSize(obj.desc?.length ?? 0, obj.body.length);
innerTextStack.addSpacer()
let actionStack = innerTextStack.addStack();
actionStack.layoutHorizontally();
let refreshText = actionStack.addText("Neu laden")
refreshText.textColor = Color.blue()
refreshText.font = Font.systemFont(14)
refreshText.url = "scriptable:///run/Random%20Wikipedia";
for (let i = 0; i < links.length; i++){
actionStack.addSpacer() ;
let lURL = actionStack.addText((related[i]??"").toString());
lURL.textColor = Color.blue()
lURL.font = Font.systemFont(12)
lURL.url = `scriptable:///run?scriptName=Random%20Wikipedia&title=${links[i]}&lang=${lang}`;
lURL.centerAlignText()
}
actionStack.addSpacer()
stack.setPadding(0,0,0,0)
w.url = obj.url
return w
}
function alert(title, body){
let alert = new Alert();
alert.title = title.toString();
alert.message = body.toString();
alert.addAction("Close")
alert.presentAlert()
}
function sendNotification(title, body) { let notif = new Notification()
notif.title = JSON.stringify(title);
notif.body = JSON.stringify(body);
notif.schedule()
}
/*function encode(str) {
console.log("trying to decode str: " + str);
return str? btoa(unescape(encodeURIComponent(str))) :
str;
}
function decode(str) {
console.log("trying to decode str: " + str);
return str? decodeURIComponent(escape(atob(str))): str;
}*/
function getAppropiateFontSize(descLength, bodyLength){
let size, totalLength = descLength + bodyLength;
console.log(totalLength)
if (totalLength < 50) size = 28;
else if (totalLength < 125) size = 24;
else if (totalLength < 200) size = 20;
else if (totalLength < 250) size = 18;
else if (totalLength < 400) size = 16;
else if (totalLength < 600) size = 14;
else if (totalLength < 800) size = 13;
else if (totalLength < 1000) size = 12;
else size = 10;
return Font.systemFont(size);
}
function createGradient(color1, color2) {
let gradient = new LinearGradient()
gradient.locations = [0,1]
gradient.startPoint = new Point(0,0);
gradient.endPoint = new Point(0.4,1);
gradient.colors = [new Color(color1 ?? "#535353"), new Color(color2 ?? "#000000")]
return gradient;
}
function randomColor(){
const colors = "0123456789ABCDEF"
let string = ""
for (let i = 0; i < 6; i++){
string += colors[randint(colors.length)]
}
return new Color(string);
}
function randint(limit){
return Math.floor(Math.random() * limit);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment