Skip to content

Instantly share code, notes, and snippets.

@matkoenig
Last active July 13, 2022 23:49
Show Gist options
  • Save matkoenig/342be770ef469422d8bae17b1631111a to your computer and use it in GitHub Desktop.
Save matkoenig/342be770ef469422d8bae17b1631111a to your computer and use it in GitHub Desktop.
Scriptable iOS widget that shows title, broadcast time and investigation team of next new Tatort episode
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-blue; icon-glyph: magic;
// Tatort Erstausstrahlung 1.3 | Matthias Konig | 11.06.2021
/*----------------------------------------------------------------------------------------------------------------------
Main
----------------------------------------------------------------------------------------------------------------------*/
var url = "https://www.daserste.de/unterhaltung/krimi/tatort/tatort-filter-naechste-erstausstrahlung-102.html"
var widget = await buildWidget()
widget.url = url
widget.backgroundColor = new Color("#232A7A")
if (!config.runsInWidget) widget.presentSmall()
Script.setWidget(widget)
Script.complete()
/*----------------------------------------------------------------------------------------------------------------------
build widget
------------------------------------------------------------------------------------------------------------------------
+------------------------------+
stackHeader | |
+------------------------------+
stackTitle | |
+------------------------------+
| |
Spacer | |
| |
+------------------------------+
stackTeam | |
+------------------------------+
stackDate | |
+------------------------------+
----------------------------------------------------------------------------------------------------------------------*/
async function buildWidget() {
// get data of next episode
var data = await getNextEpisode()
//var data = {date: "So., 01.11.20 | 20:15 Uhr", title: "Der Welten Lohn", team: "Lannert und Bootz"}
console.log(data);
// create widget
var widget = new ListWidget()
widget.setPadding(10, 5, 14, 5)
// background image
widget.backgroundImage = await getLogo()
// stacks
var stackHeader = widget.addStack()
widget.addSpacer(5)
var stackTitle = widget.addStack()
widget.addSpacer()
var stackTeam = widget.addStack()
widget.addSpacer(5)
var stackDate = widget.addStack()
// header
stackHeader.addSpacer()
var stackHeaderCenter = stackHeader.addStack()
stackHeader.addSpacer()
var txtHeader = stackHeaderCenter.addText("nächste Erstausstrahlung ")
txtHeader.font = Font.systemFont(10)
txtHeader.textColor = Color.white()
// title
stackTitle.addSpacer()
var stackTitleCenter = stackTitle.addStack()
stackTitle.addSpacer()
var txtTitle = stackTitleCenter.addText(data.title)
txtTitle.font = Font.boldSystemFont(14)
txtTitle.textColor = Color.white()
txtTitle.lineLimit = 1
txtTitle.minimumScaleFactor = 0.8
// team
stackTeam.addSpacer()
var stackTeamCenter = stackTeam.addStack()
stackTeam.addSpacer()
var txtTeam = stackTeamCenter.addText(data.team)
txtTeam.font = Font.systemFont(12)
txtTeam.textColor = Color.white()
txtTeam.lineLimit = 1
txtTeam.minimumScaleFactor = 0.8
// date
stackDate.addSpacer()
var stackDateCenter = stackDate.addStack()
stackDate.addSpacer()
if (data.date != "") {
var m = data.date.match(/.*(\d\d.\d\d.)\d\d\s\|\s(\d\d:\d\d).*/)
var txtDate = stackDateCenter.addText(m[1] + " um " + m[2])
} else {
var txtDate = stackDateCenter.addText("Aktuell nichts geplant.")
}
txtDate.font = Font.systemFont(10)
txtDate.textColor = Color.white()
// return widget
return widget
}
/*----------------------------------------------------------------------------------------------------------------------
get data of next episode
----------------------------------------------------------------------------------------------------------------------*/
async function getNextEpisode() {
var json = ""
var fm = FileManager.local()
var dir = fm.documentsDirectory()
var path = fm.joinPath(dir, "scriptable-tatort.png")
try {
var req = new Request(url)
var html = await req.loadString()
var webview = new WebView()
await webview.loadHTML(html)
var js =
"var date = '', title = '', team = '', a, i;" +
"if (document.getElementsByClassName('infoBroadcastDateInline')[0]) {" +
" date = document.getElementsByClassName('infoBroadcastDateInline')[0].innerText;" +
" title = document.getElementsByTagName('H1')[0].innerText;" +
" a = document.getElementsByTagName('H3');" +
" for (i = 0; i < a.length; i++) {" +
" if (a[i].innerText.toUpperCase().substr(4, 9) == 'ERMITTLER') {" +
" team = a[i].parentNode.getElementsByTagName('H4')[0].innerText;" +
" break;" +
" }" +
" }" +
"}" +
"JSON.stringify({date: date, title: title, team: team});"
var json = await webview.evaluateJavaScript(js)
fm.writeString(path, json)
widget.refreshAfterDate = new Date(Date.now() + 360 * 60 * 1000)
} catch (err) {
json = fm.readString(path)
}
return JSON.parse(json)
}
/*----------------------------------------------------------------------------------------------------------------------
get logo
----------------------------------------------------------------------------------------------------------------------*/
async function getLogo(url) {
var fm = FileManager.local()
var dir = fm.documentsDirectory()
var path = fm.joinPath(dir, "scriptable-tatort-logo.png")
if (fm.fileExists(path)) {
return await fm.readImage(path)
}
var image = await loadImage("https://img.ardmediathek.de/standard/00/69/46/20/42/198737788/1x1/448?mandant=ard")
var context = new DrawContext()
context.size = new Size(150, 150)
context.opaque = false
context.respectScreenScale = true
context.setFillColor(new Color("#232A7A", 1.0))
context.fill(new Rect(0, 0, 150, 150))
context.drawImageInRect(image, new Rect(33, 33, 84, 84))
var img = context.getImage()
fm.writeImage(path, img)
return img
}
/*----------------------------------------------------------------------------------------------------------------------
load image
----------------------------------------------------------------------------------------------------------------------*/
async function loadImage(url) {
var req = new Request(url)
var image = await req.loadImage()
return image
}
@l3w0
Copy link

l3w0 commented Nov 4, 2020

Sehr coole Idee! Leider kommt bei mir nur ne Fehlermeldung. Irgendetwas scheint da bei mir schief zu laufen.
IMG_F0EFFA81C0BF-1

@matkoenig
Copy link
Author

Hallo I3w(), ich habe meinen obigen Code nochmals getestet. Scheint alles okay zu sein. Die Fehlermeldung deutet stark darauf hin, dass der Code nicht korrekt eingefügt wurde. Am besten oben den Button "Raw" drücken, dann den Code komplett kopieren und in Scriptable einfügen. Dann sollte es funktionieren. LG Matthias

@matkoenig
Copy link
Author

matkoenig commented Nov 5, 2020 via email

@l3w0
Copy link

l3w0 commented Nov 5, 2020

Dankeschön! War wirklich mein Fehler. Jetzt funktioniert es einwandfrei! Vielen Dank und coole Idee!:)

@simon0711
Copy link

simon0711 commented Jun 9, 2021

Ich wollte mir auch gerade mal dieses coole Widget einrichten, allerdings bekomme ich immer die Fehlermeldung. Habe es schon mehrfach neu kopiert. Kannst du mir sagen was der Fehler ist?
Viele Grüße Simon
3D1E5628-7274-47C1-8AAC-87E14EE9DAD9

@matkoenig
Copy link
Author

Hallo Simon, ich habe den Code getestet. Er funktioniert bei mir ohne Probleme. Es muss beim Kopieren irgendwas nicht korrekt übernommen worden sein. Hast Du eine Email für mich, dann schicke ich Dir den Code gerne zu.

@matkoenig
Copy link
Author

Die Fehlermeldung könnte auch bedeuten, dass die Daten nicht gelesen wurden. Kann die App „Kurzbefehle“ auf das Internet zugreifen? Evtl. sind mobile Daten deaktiviert.

@simon0711
Copy link

Hallo Matthias, du bist ja schnell! Ja klar, liebig.simon@googlemail.com
WLAN und mobile Daten sind an. Die anderen Widgets funktionieren auch.
Vielen Dank!

@matkoenig
Copy link
Author

Fehler gefunden. Aktuell hat die ARD keine neue Erstaustrahlung geplant - Wofür zahlen wir eigentlich GEZ Gebühren ;-)
In Version 1.3 wird diese Situation nun abgefangen.

grafik

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