Created
July 13, 2021 14:37
-
-
Save simonbs/e994761a2dd9111cac7ad02382abb6f2 to your computer and use it in GitHub Desktop.
Scriptable script showing a profile of the current Tour de France stage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: yellow; icon-glyph: bicycle; | |
let stages = await loadStages() | |
let stage = findStage(stages) | |
if (stage == null) { | |
let widget = createTournamentOverWidget() | |
await widget.presentMedium() | |
} else { | |
let stageDetails = await loadStageDetails(stage.id) | |
let progress = getProgress(stageDetails) | |
let profileOverlayImage = await getProfileOverlayImage(stageDetails) | |
let profileImage = drawProfileImage(progress, profileOverlayImage) | |
let widget = createWidget(profileImage) | |
await widget.presentMedium() | |
} | |
function createWidget(stageProfileImage) { | |
let widget = new ListWidget() | |
widget.setPadding(0, 0, 0, 0) | |
widget.backgroundColor = Color.white() | |
let vstack = widget.addStack() | |
vstack.addImage(stageProfileImage) | |
return widget | |
} | |
function createTournamentOverWidget() { | |
let widget = new ListWidget() | |
widget.backgroundColor = new Color("#FFC915") | |
let wtext = widget.addText("Tour de France is over for this year.") | |
wtext.textColor = Color.black() | |
wtext.centerAlignText() | |
return widget | |
} | |
function drawProfileImage(progress, profileOverlayImage) { | |
let size = profileOverlayImage.size | |
let progressWidth = Math.round(size.width * progress) | |
let profileColor = new Color("#AAAAAA") | |
let progressColor = new Color("#FFC915") | |
let rect = new Rect(0, 0, size.width, size.height) | |
let progressFillRect = new Rect(0, 0, progressWidth, size.height) | |
let context = new DrawContext() | |
context.size = size | |
context.setFillColor(profileColor) | |
context.fillRect(rect) | |
context.setFillColor(progressColor) | |
context.fillRect(progressFillRect) | |
context.drawImageInRect(profileOverlayImage, rect) | |
return context.getImage() | |
} | |
function getProgress(stage) { | |
let totalDistance = stage.distance | |
let distanceToGo = stage.intermediateGroups.distanceToGo | |
let distanceTraveled = totalDistance - distanceToGo | |
return distanceTraveled / totalDistance | |
} | |
async function getProfileOverlayImage(stage) { | |
let profileOverlayImageURL = findRouteGraphicURL("route_full", stage.routeGraphics) | |
return await loadImage(profileOverlayImageURL) | |
} | |
function findRouteGraphicURL(name, graphics) { | |
for (graphic of graphics) { | |
if (graphic.name == name) { | |
return graphic.value | |
} | |
} | |
return null | |
} | |
function findStage(stages) { | |
stages.sort((a, b) => { | |
return a.startDate > b.startDate | |
}) | |
for (stage of stages) { | |
let startDate = new Date(stage.startDate) | |
let isInFuture = startDate > new Date() | |
if (isToday(startDate) || isInFuture) { | |
return stage | |
} | |
} | |
return null | |
} | |
async function loadStageDetails(id) { | |
let url = "https://appservicesport.tv2api.dk/cycling/stages/2294133/events/" + id | |
return await loadJSON(url) | |
} | |
async function loadStages() { | |
let url = "https://appservicesport.tv2api.dk/cycling/stages/2294133/events/" | |
return await loadJSON(url) | |
} | |
async function loadJSON(url) { | |
let req = new Request(url) | |
return await req.loadJSON() | |
} | |
async function loadImage(url) { | |
let req = new Request(url) | |
return await req.loadImage() | |
} | |
function isToday(date) { | |
let today = new Date() | |
return date.getDate() == today.getDate() && | |
date.getMonth() == today.getMonth() && | |
date.getFullYear() == today.getFullYear() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment