Skip to content

Instantly share code, notes, and snippets.

@marco79cgn
Last active October 1, 2023 18:28
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marco79cgn/bba78cb20e9c0847e9d24414f1a07eb5 to your computer and use it in GitHub Desktop.
Save marco79cgn/bba78cb20e9c0847e9d24414f1a07eb5 to your computer and use it in GitHub Desktop.
A custom widget showing editors picks of the ARD Mediathek for scriptable.app
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-blue; icon-glyph: film;
// name: ard-mediathek.js
// description: A scriptable widget which displays the latest editorial picks of the ARD Mediathek
// author: Marco Dengel
// email: marco79cgn@gmail.com
let mediathekData;
try {
mediathekData = await new Request(
'https://api.ardmediathek.de/page-gateway/widgets/ard/editorials/1FdQ5oz2JK6o2qmyqMsqiI:-5299873058662924535?pageNumber=0&pageSize=10'
).loadJSON();
} catch (e) {
const errorWidget = createErrorWidget();
if (!config.runsInWidget) {
await errorWidget.presentMedium();
} else {
Script.setWidget(errorWidget);
}
Script.complete();
}
const widget = await createWidget();
if (!config.runsInWidget) {
await widget.presentMedium();
} else {
Script.setWidget(widget);
}
Script.complete();
async function createWidget() {
let listWidget = new ListWidget();
listWidget.setPadding(10,10,10,10);
listWidget.backgroundImage = await loadImage(
'https://www.designtagebuch.de/wp-content/uploads/mediathek//2015/03/daserste-corporate-background.jpg'
);
listWidget = await createHeaderImage(listWidget);
listWidget.addSpacer(14);
// Get two different random items
let itemNumber = getRandomNumber(1, mediathekData.teasers.length) - 1
let itemNumber2
do {
itemNumber2 = getRandomNumber(1, mediathekData.teasers.length) - 1
} while (itemNumber2 === itemNumber)
listWidget = await createArticle(listWidget, mediathekData.teasers[itemNumber]);
listWidget.addSpacer(10)
listWidget = await createArticle(listWidget,mediathekData.teasers[itemNumber2])
return listWidget;
}
async function createArticle(listWidget, data) {
const { shortTitle } = data;
let date;
if (data.broadcastedOn) {
date = new Date(data.broadcastedOn);
}
const image = data.images.aspect16x9.src.replace('{width}', 200);
let ressort
if(data.publicationService) {
ressort = data.publicationService.name
} else {
ressort = 'Sonstiges'
}
const article = listWidget.addStack();
const articleImage = article.addImage(await loadImage(image));
articleImage.cornerRadius = 5;
articleImage.imageSize = new Size(85,48)
let mediaUrl = await getMediaUrl(data)
article.url = mediaUrl
article.addSpacer(6);
const articleInfo = article.addStack();
articleInfo.layoutVertically();
const articleRessort = articleInfo.addText(ressort);
articleRessort.textColor = Color.yellow();
articleRessort.font = Font.boldMonospacedSystemFont(11);
articleInfo.addSpacer(2)
const articleTitle = articleInfo.addText(shortTitle.trim());
articleTitle.textColor = Color.white();
articleTitle.font = Font.semiboldMonospacedSystemFont(13)
articleTitle.lineLimit = 1
articleTitle.minimumScaleFactor = 0.7;
articleInfo.addSpacer(2)
if (date) {
const articleDate = articleInfo.addText(formatDate(date));
articleDate.font = Font.semiboldMonospacedSystemFont(11);
articleDate.textOpacity = 0.7;
articleDate.textColor = Color.white()
}
return listWidget;
}
async function createHeaderImage(listWidget) {
const headerImage = listWidget.addImage(
await getImage('mediathek-logo.png')
);
headerImage.imageSize = new Size(100, 8);
headerImage.tintColor = Color.white();
headerImage.centerAlignImage();
headerImage.applyFillingContentMode();
return listWidget;
}
function createErrorWidget() {
const errorWidget = new ListWidget();
const bgGradient = new LinearGradient();
bgGradient.locations = [0, 1];
bgGradient.colors = [new Color('#2D65AE'), new Color('#19274C')];
errorWidget.backgroundGradient = bgGradient;
const title = errorWidget.addText('ARD Mediathek');
title.font = Font.headline();
title.centerAlignText();
title.textColor = Color.white()
errorWidget.addSpacer(10);
const errorText = errorWidget.addText(
'Es besteht momentan keine Verbindung zum Internet.'
);
errorText.font = Font.semiboldMonospacedSystemFont(16);
errorText.textColor = Color.red();
errorText.centerAlignText()
return errorWidget;
}
async function loadImage(url) {
return await new Request(url).loadImage();
}
function formatDate(dateObject) {
return `${leadingZero(dateObject.getDate())}.${leadingZero(
dateObject.getMonth() + 1
)}.${dateObject.getFullYear()}, ${leadingZero(
dateObject.getHours()
)}:${leadingZero(dateObject.getMinutes())} Uhr`;
}
function leadingZero(input) {
return ('0' + input).slice(-2);
}
// random number, min and max included
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
async function getImage(image) {
let fm = FileManager.local();
let dir = fm.documentsDirectory()
let path = fm.joinPath(dir, image)
if (fm.fileExists(path)) {
return fm.readImage(path)
} else {
// download once
let imageUrl
switch (image) {
case 'mediathek-logo.png':
imageUrl = "https://i.imgur.com/vUfzOhj.png"
break
default:
console.log(`Sorry, couldn't find ${image}.`);
}
let iconImage = await loadImage(imageUrl)
fm.writeImage(path, iconImage)
return iconImage
}
}
async function getMediaUrl(data) {
let targetUrl = data.links.target.href.replace('&embedded=true','').replace('?embedded=true','')
let mediaUrl
if(targetUrl.indexOf('/item/') > 0) {
const mediaResult = await new Request(targetUrl).loadJSON()
mediaUrl = mediaResult.widgets[0].mediaCollection.embedded._mediaArray[0]._mediaStreamArray[0]._stream
if(mediaUrl.startsWith('//')) {
mediaUrl = 'https:' + mediaUrl
}
} else if(targetUrl.indexOf('retro') > 0) {
mediaUrl = 'https://www.ardmediathek.de/ard/retro/'
} else if(data.type.toLowerCase() === 'show') {
mediaUrl = 'https://www.ardmediathek.de/ard/sendung/' + data.links.target.id
}
else {
const nextResult = await new Request(targetUrl).loadJSON()
const mediaResult = await new Request(nextResult.widgets[0].teasers[0].links.target.href.replace('&embedded=true','').replace('?embedded=true','')).loadJSON()
mediaUrl = mediaResult.widgets[0].mediaCollection.embedded._mediaArray[0]._mediaStreamArray[0]._stream
}
return mediaUrl
}
// Ende des Skripts
// Bitte alles markieren!
@marco79cgn
Copy link
Author

marco79cgn commented Nov 4, 2020

Intro

Das Widget zeigt die neuesten Editor's Picks der ARD Mediathek in zufälliger Reihenfolge an. Ein Tap genügt, um das jeweilige Video direkt abzuspielen. Serien und Sammlungen werden im Browser geöffnet.

Anforderungen

Installation

  • Kopiere den Quellcode von oben (klick vorher auf "raw" oben rechts oder hier)
  • Achte darauf, den gesamten Code bis zum Ende zu markieren
  • Öffne die Scriptable app
  • Klick auf das "+" Symbol oben rechts und füge das kopierte Skript aus der Zwischenablage ein
  • Klick auf den Titel des Skripts ganz oben und vergebe einen Namen (z.B. ARD-Mediathek)
  • Speichere das Skript durch Klick auf "Done" oben links
  • Gehe auf deinen iOS Homescreen und drücke irgendwo lang, um in den "Wiggle Modus" zu kommen (mit dem man auch die Apps anordnen kann)
  • Drücke das "+" Symbol oben links, blättere dann nach unten zu "Scriptable" (Liste ist alphabetisch), wähle die erste Widget Größe (small) und drück unten auf "Widget hinzufügen"
  • Drücke auf das Widget, um seine Einstellungen zu bearbeiten (optional lang drücken, wenn der Wiggle Modus schon beendet wurde)
  • Wähle unter "Script" das oben erstellte aus (ARD-Mediathek)

Danke

Großer Dank an @simonbs für großartige Apps wie Scriptable, DataJar oder Jayson.

Disclaimer

Es handelt sich um ein von mir selbst entwickeltes Spaßprojekt, kein offizielles Produkt von Das Erste/ARD.

@marco79cgn
Copy link
Author

Update: 01.10.2023
Fixed api url.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment