Last active
October 9, 2024 14:00
-
-
Save saiteja09/8cde7be5b80ec63de2d58e3fbdfffc21 to your computer and use it in GitHub Desktop.
Widget for Cricket Scores iOS - Scriptable
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
let teamsListURL = "https://gist.github.com/saiteja09/71f47ed2714a4cad479f409b2f7d7bc2/raw/49ec450f7a2ad8d662a01863f6b5f7279bd06f3a/teams.json"; | |
let teamInfoURL = "https://hs-consumer-api.espncricinfo.com/v1/pages/team/home?lang=en&teamId="; | |
let matchInfoURL = "https://hs-consumer-api.espncricinfo.com/v1/pages/match/home?lang=en&seriesId=<sid>&matchId=<mid>"; | |
// WIDGET MAIN | |
mainWidget = await createWidget(); | |
if (config.runsInWidget) { | |
Script.setWidget(mainWidget); | |
} else { | |
mainWidget.presentMedium(); | |
} | |
Script.complete(); | |
async function createWidget() { | |
teamInfo = await getTeamInformation(); | |
latestMatchInfo = await getLatestMatch(teamInfo); | |
matchInfo = null; | |
// Read Individual Data points from API | |
seriesName = latestMatchInfo.series.name; | |
matchTitle = latestMatchInfo.title; | |
matchFormat = latestMatchInfo.format; | |
matchStatusText = latestMatchInfo.statusText; | |
stage = latestMatchInfo.stage; | |
matchStadium = latestMatchInfo.ground.name; | |
matchStadiumTown = latestMatchInfo.ground.town.name; | |
matchStadiumCountry = latestMatchInfo.ground.country.name; | |
team1ImgURL = "https://espncricinfo.com" + latestMatchInfo.teams[0].team.image.url; | |
team2ImgURL = "https://espncricinfo.com" + latestMatchInfo.teams[1].team.image.url; | |
team1Name = latestMatchInfo.teams[0].team.name; | |
team2Name = latestMatchInfo.teams[1].team.name; | |
team1Id = latestMatchInfo.teams[0].team.objectId; | |
team2Id = latestMatchInfo.teams[1].team.objectId; | |
matchStartTime = new Date(latestMatchInfo.startTime).toLocaleString('en-us', { | |
weekday: "long", | |
year: "numeric", | |
month: "short", | |
day: "numeric", | |
hour: "numeric", | |
minute: "numeric" | |
}) | |
// Get Score Information | |
scoreCard = await getScores(team1Id, team2Id, stage) | |
//Widget Create | |
widget = new ListWidget() | |
widget.backgroundColor = new Color("#F4F6FA") | |
widget.setPadding(10, 0, 10, 0) | |
// Header - Series Name | |
firstStack = widget.addStack(); | |
firstStack.setPadding(0, 20, 3, 20) | |
seriesNameTxt = firstStack.addText(seriesName.toUpperCase()); | |
seriesNameTxt.textColor = Color.black(); | |
seriesNameTxt.font = Font.boldMonospacedSystemFont(10) | |
firstStack.addSpacer() | |
// Header - State of Match - Scheduled/Live/Finished | |
if (stage == "RUNNING") { | |
stage = "LIVE" | |
} | |
stWidth = getStatusWidth(stage) | |
matchStageImg = firstStack.addImage(createRectangle(stWidth, stage)) | |
matchStageImg.imageSize = new Size(stWidth, 12) | |
matchStageImg.centerAlignImage() | |
matchStageImg.cornerRadius = 2 | |
// Second Line - Match Information - Type, Stadium and Place | |
secondStack = widget.addStack(); | |
secondStack.setPadding(0, 20, 0, 20) | |
matchInfoTxt = secondStack.addText(matchTitle.toUpperCase() + ", " + matchFormat.toUpperCase() + ", " + matchStadium.toUpperCase() + ", " + matchStadiumTown.toUpperCase()) | |
matchInfoTxt.textColor = Color.black() | |
matchInfoTxt.font = Font.lightMonospacedSystemFont(10) | |
matchInfoTxt.minimumScaleFactor = 0.5; | |
matchInfoTxt.lineLimit = 1; | |
widget.addSpacer() | |
// Third Line - Team 1 Flag, Name and Score | |
fourthStack = widget.addStack(); | |
fourthStack.setPadding(0, 20, 0, 20) | |
fourthStack.centerAlignContent() | |
team1Img = fourthStack.addImage(await getImageFromURL(team1ImgURL)); | |
team1Img.cornerRadius = 2 | |
team1Img.imageSize = new Size(40, 40); | |
team1NameText = fourthStack.addText(" " + team1Name.toUpperCase()) | |
team1NameText.textColor = Color.black() | |
team1NameText.font = Font.boldMonospacedSystemFont(10) | |
fourthStack.addSpacer() | |
team1ScoreTxt = fourthStack.addText(scoreCard.team1ScoreSummary) | |
team1ScoreTxt.textColor = Color.black() | |
team1ScoreTxt.font = Font.boldMonospacedSystemFont(10) | |
widget.addSpacer() | |
// Fourth Line - Team 2 Flag, Name and Score | |
fifthStack = widget.addStack() | |
fifthStack.setPadding(0, 20, 0, 20) | |
fifthStack.centerAlignContent() | |
team2Img = fifthStack.addImage(await getImageFromURL(team2ImgURL)); | |
team2Img.cornerRadius = 2 | |
team2Img.imageSize = new Size(40, 40); | |
team2NameText = fifthStack.addText(" " + team2Name.toUpperCase()) | |
team2NameText.textColor = Color.black() | |
team2NameText.font = Font.boldMonospacedSystemFont(10) | |
fifthStack.addSpacer() | |
team2ScoreTxt = fifthStack.addText(scoreCard.team2ScoreSummary) | |
team2ScoreTxt.textColor = Color.black() | |
team2ScoreTxt.font = Font.boldMonospacedSystemFont(10) | |
widget.addSpacer() | |
if (stage == "SCHEDULED") { | |
matchStatusText = "Match starts on " + matchStartTime | |
} else { | |
matchStatusText = scoreCard.statusText; | |
} | |
//Fifth Line - Match Status Info | |
seventhStack = widget.addStack() | |
seventhStack.addSpacer() | |
matchStatusTxt = seventhStack.addText(matchStatusText.toUpperCase()) | |
matchStatusTxt.textColor = Color.black() | |
matchStatusTxt.font = Font.boldMonospacedSystemFont(9) | |
matchStatusTxt.minimumScaleFactor = 0.5 | |
matchStatusTxt.lineLimit = 1 | |
seventhStack.addSpacer() | |
return widget | |
} | |
// Get Input Team Information | |
async function getTeamInformation() { | |
// READ INPUT PARAMETERS | |
teamName = null | |
if (args.widgetParameter == null) { | |
teamName = "India"; | |
} else { | |
teamName = args.widgetParameter; | |
} | |
// GET TEAM ID FOR THE SUPPLIER TEAMNANE | |
teamsList = await readFromAPI(teamsListURL) | |
teamId = -1; | |
for (index = 0; index < teamsList.length; index++) { | |
if (teamsList[index].name.toUpperCase() == teamName.toUpperCase()) { | |
teamId = teamsList[index].id; | |
break; | |
} | |
} | |
// GET TEAM INFORMATION AND SCHEDULE | |
teamInfoURL = teamInfoURL + teamId | |
return await readFromAPI(teamInfoURL) | |
} | |
// Get Latest Match of Team provided as Input | |
async function getLatestMatch(teamInfo) { | |
// GET Latest Match, If there's a match running, return that | |
nextMatch = teamInfo.content.recentFixtures[0]; | |
if (nextMatch.stage == "RUNNING") { | |
return nextMatch; | |
} | |
// Get Last Match Info | |
lastMatch = teamInfo.content.recentResults[0]; | |
// GET NEXT MATCH START DATE AND LAST MATCH END DATE | |
nextMatchStartDate = new Date(nextMatch.startTime); | |
lastMatchEndDate = new Date(lastMatch.startTime); | |
currentdate = new Date(); | |
// CALCULATE TIMEDIFF FROM CURRENT TO LAST AND NEXT MATCH | |
nextMatchDiff = Math.abs(currentdate.getTime() - nextMatchStartDate.getTime()) | |
lastMatchDiff = Math.abs(currentdate.getTime() - lastMatchEndDate.getTime()) | |
// RETURN NEXT MATCH, IF ITS MORE THAN 24 HOURS FROM LAST MATCH COMPLETION ELSE RETURN LASTMATCH | |
if (lastMatchDiff > 86400000) { | |
return nextMatch; | |
} else { | |
return lastMatch; | |
} | |
} | |
// Get Scores - Based on the State of the Match - SCHEDULED/RUNNING/FINISHED | |
async function getScores(team1Id, team2Id, stage) { | |
seriesId = latestMatchInfo.series.objectId; | |
matchId = latestMatchInfo.objectId; | |
matchInfoURL = matchInfoURL.replace("<sid>", seriesId); | |
matchInfoURL = matchInfoURL.replace("<mid>", matchId); | |
matchInfo = await readFromAPI(matchInfoURL) | |
if (stage == "FINISHED") { | |
score = {}; | |
score.team1Id = team1Id; | |
score.team2Id = team2Id; | |
innings1Info = matchInfo.content.scorecardSummary.innings[0]; | |
if (innings1Info.team.objectId == team1Id) { | |
score.team1Score = innings1Info.runs; | |
score.team1Wickets = innings1Info.wickets; | |
score.team1Overs = innings1Info.overs; | |
score.team1ScoreSummary = score.team1Score + "/" + score.team1Wickets + " (" + score.team1Overs + ")" | |
} else { | |
score.team2Score = innings1Info.runs; | |
score.team2Wickets = innings1Info.wickets; | |
score.team2Overs = innings1Info.overs; | |
score.team2ScoreSummary = score.team2Score + "/" + score.team2Wickets + " (" + score.team2Overs + ")" | |
} | |
innings2Info = matchInfo.content.scorecardSummary.innings[1]; | |
if (innings2Info.team.objectId == team1Id) { | |
score.team1Score = innings2Info.runs; | |
score.team1Wickets = innings2Info.wickets; | |
score.team1Overs = innings2Info.overs; | |
score.team1ScoreSummary = score.team1Score + "/" + score.team1Wickets + " (" + score.team1Overs + ")" | |
} else { | |
score.team2Score = innings2Info.runs; | |
score.team2Wickets = innings2Info.wickets; | |
score.team2Overs = innings2Info.overs; | |
score.team2ScoreSummary = score.team2Score + "/" + score.team2Wickets + " (" + score.team2Overs + ")" | |
} | |
score.statusText = matchInfo.match.statusText; | |
return score; | |
} else if (stage == "SCHEDULED") { | |
score = {} | |
score.team1ScoreSummary = "" | |
score.team2ScoreSummary = "" | |
return score | |
} else if (stage == "RUNNING") { | |
score = {} | |
team1Info = matchInfo.match.teams[0] | |
team2Info = matchInfo.match.teams[1] | |
statusText = matchInfo.match.statusText; | |
console.log(statusText) | |
if (team1Info.team.objectId == team1Id) { | |
score.team1ScoreSummary = team1Info.score; | |
if (team1Info.scoreInfo != null) | |
{ | |
score.team1ScoreSummary = score.team1ScoreSummary + " (" + team1Info.scoreInfo + ")"; | |
} | |
} else { | |
score.team2ScoreSummary = team1Info.score + " (" + team1Info.scoreInfo + ")"; | |
if (team1Info.scoreInfo != null) | |
{ | |
score.team2ScoreSummary = score.team2ScoreSummary + " (" + team1Info.scoreInfo + ")"; | |
} | |
} | |
if (team2Info.team.objectId == team1Id) { | |
score.team1ScoreSummary = team2Info.score; | |
if (team2Info.scoreInfo != null) | |
{ | |
score.team1ScoreSummary = score.team1ScoreSummary + " (" + team2Info.scoreInfo + ")"; | |
} | |
} else { | |
score.team2ScoreSummary = team2Info.score ; | |
if (team2Info.scoreInfo != null) | |
{ | |
score.team2ScoreSummary = score.team2ScoreSummary + " (" + team2Info.scoreInfo + ")"; | |
} | |
} | |
console.log(score.team1ScoreSummary) | |
console.log(score.team2ScoreSummary) | |
if(score.team1ScoreSummary == null) | |
{ | |
score.team1ScoreSummary ="" | |
} | |
if(score.team2ScoreSummary == null) | |
{ | |
score.team2ScoreSummary = "" | |
} | |
if (score.team1ScoreSummary.includes("null")) { | |
score.team1ScoreSummary = "YET TO BAT" | |
} | |
if (score.team2ScoreSummary.includes("null")) { | |
score.team2ScoreSummary = "YET TO BAT" | |
} | |
score.statusText = statusText; | |
return score; | |
} | |
} | |
// Create Line Seperator (Not Used) | |
function lineSep() { | |
const context = new DrawContext() | |
let width = 250, | |
h = 1 | |
context.size = new Size(width, h) | |
context.opaque = false | |
context.respectScreenScale = true | |
path = new Path() | |
path.move(new Point(0, h)) | |
path.addLine(new Point(width, h)) | |
context.addPath(path) | |
context.setStrokeColor(Color.gray()) | |
context.setLineWidth(1) | |
context.strokePath() | |
return context.getImage() | |
} | |
// Get Rectangle Width for various states of Match | |
function getStatusWidth(matchStatus) { | |
if (matchStatus.toUpperCase() == "SCHEDULED") { | |
return 64 | |
} else if (matchStatus.toUpperCase() == "FINISHED") { | |
return 56 | |
} else if (matchStatus.toUpperCase() == "LIVE") { | |
return 40 | |
} else { | |
return 55 | |
} | |
} | |
// Get Status Colors for various states of Match | |
function getStatusColor(matchStatus) { | |
if (matchStatus.toUpperCase() == "SCHEDULED") { | |
return Color.blue() | |
} else if (matchStatus.toUpperCase() == "FINISHED") { | |
return Color.green() | |
} else if (matchStatus.toUpperCase() == "LIVE") { | |
return Color.red() | |
} else { | |
return Color.lightGray() | |
} | |
} | |
// Create Rectangle for displaying state of Match | |
function createRectangle(width, stage) { | |
const context = new DrawContext(); | |
context.size = new Size(width, 12) | |
context.opaque = false; | |
context.respectScreenScale = true; | |
rect = new Rect(0, 0, width, 12) | |
context.setFillColor(getStatusColor(stage)) | |
context.setStrokeColor(getStatusColor(stage)) | |
context.strokeRect(rect) | |
context.fillRect(rect) | |
context.setFont(Font.boldMonospacedSystemFont(10)) | |
context.setTextColor(Color.white()) | |
context.setTextAlignedCenter() | |
context.drawTextInRect(stage.toUpperCase(), rect) | |
return context.getImage() | |
} | |
// Get Image from URL | |
async function getImageFromURL(url) { | |
let img = await new Request(url).loadImage(); | |
return img; | |
} | |
// Make REST API Calls | |
async function readFromAPI(url) { | |
req = new Request(url); | |
return await req.loadJSON(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
great script. Would be good to have the match status showing too. Example:
`
let teamsListURL = "https://gist.github.com/saiteja09/71f47ed2714a4cad479f409b2f7d7bc2/raw/49ec450f7a2ad8d662a01863f6b5f7279bd06f3a/teams.json";
let teamInfoURL = "https://hs-consumer-api.espncricinfo.com/v1/pages/team/home?lang=en&teamId=";
let matchInfoURL = "https://hs-consumer-api.espncricinfo.com/v1/pages/match/home?lang=en&seriesId=&matchId=";
// WIDGET MAIN
mainWidget = await createWidget();
if (config.runsInWidget) {
Script.setWidget(mainWidget);
} else {
mainWidget.presentMedium();
}
Script.complete();
async function createWidget() {
}
// Get Input Team Information
async function getTeamInformation() {
}
// Get Latest Match of Team provided as Input
async function getLatestMatch(teamInfo) {
// GET Latest Match, If there's a match running, return that
nextMatch = teamInfo.content.recentFixtures[0];
if (nextMatch.stage == "RUNNING") {
return nextMatch;
}
}
// Get Scores - Based on the State of the Match - SCHEDULED/RUNNING/FINISHED
async function getScores(team1Id, team2Id, stage) {
console.log(score.team1ScoreSummary)
console.log(score.team2ScoreSummary)
if(score.team1ScoreSummary == null)
{
score.team1ScoreSummary =""
}
if(score.team2ScoreSummary == null)
{
score.team2ScoreSummary = ""
}
}
// Create Line Seperator (Not Used)
function lineSep() {
const context = new DrawContext()
let width = 250,
h = 1
context.size = new Size(width, h)
context.opaque = false
context.respectScreenScale = true
}
// Get Rectangle Width for various states of Match
function getStatusWidth(matchStatus) {
if (matchStatus.toUpperCase() == "SCHEDULED") {
return 64
} else if (matchStatus.toUpperCase() == "FINISHED") {
return 56
} else if (matchStatus.toUpperCase() == "LIVE") {
return 40
} else {
return 55
}
}
// Get Status Colors for various states of Match
function getStatusColor(matchStatus) {
if (matchStatus.toUpperCase() == "SCHEDULED") {
return Color.blue()
} else if (matchStatus.toUpperCase() == "FINISHED") {
return Color.green()
} else if (matchStatus.toUpperCase() == "LIVE") {
return Color.red()
} else {
return Color.lightGray()
}
}
// Create Rectangle for displaying state of Match
function createRectangle(width, stage) {
const context = new DrawContext();
context.size = new Size(width, 12)
context.opaque = false;
context.respectScreenScale = true;
}
// Get Image from URL
async function getImageFromURL(url) {
let img = await new Request(url).loadImage();
return img;
}
// Make REST API Calls
async function readFromAPI(url) {
req = new Request(url);
return await req.loadJSON();
}`
For England today, it is delayed start due to rain, so can see that at a glance then. (Might need new line etc).