Last active
September 29, 2020 13:20
-
-
Save MiracleXYZ/ec0597a359e22e0bf5c439493b8276e3 to your computer and use it in GitHub Desktop.
An iOS 14 Scriptable Widget to display stats info of Nijisanji streams.
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
// Set groups. If you want all groups, just set groups to []. | |
let groups = ['nijisanjip', 'nijisanjiin', 'nijisanjiid', 'nijisanjikr'] | |
// let groups = [] | |
let data = await loadData(groups) | |
let widget = await createWidget(data) | |
// Check if the script is running in a widget. If not, show a preview of the widget to easier debug it -> open the stats webpage in Safari. | |
if (!config.runsInWidget) { | |
// await widget.presentMedium() | |
await Safari.open('https://hiyoko.sonoj.net/live/') | |
} | |
// Tell the system to show the widget. | |
Script.setWidget(widget) | |
Script.complete() | |
async function createWidget(data) { | |
let items = data | |
// Transform the update time into string. | |
let updatedDate = new Date(Date.now()) | |
let dateFormatter = new DateFormatter() | |
dateFormatter.useShortDateStyle() | |
dateFormatter.useShortTimeStyle() | |
let updatedStr = dateFormatter.string(updatedDate) | |
let item = items[0] | |
let streamer = item.streamer_name | |
let imgURL = item.thumbnail_url | |
let rawDate = item.actual_start_time | |
let date = new Date(rawDate) | |
let strDate = dateFormatter.string(date) | |
let channelType = '' | |
if (item.ch_type == 1) { | |
channelType = 'YT' | |
} else { | |
channelType = item.ch_id.slice(0, 2) | |
} | |
let trendStr = '' | |
if (!(item.trend_rank == null)) { | |
trendStr = ` 路 馃敟${item.trend_rank}浣峘 | |
} | |
// Set gradient colors. Feel free to change if you want a different color. | |
let gradient = new LinearGradient() | |
gradient.locations = [0, 1] | |
gradient.colors = [ | |
new Color("#ef7a03e6"), | |
new Color("#ef7a03b3") | |
] | |
let w = new ListWidget() | |
if (imgURL != null) { | |
let imgReq = new Request(imgURL) | |
let img = await imgReq.loadImage() | |
w.backgroundImage = img | |
} | |
w.backgroundColor = new Color("#ef7a03") | |
w.backgroundGradient = gradient | |
// Add spacer above content to center it vertically. | |
w.addSpacer() | |
// Show title. | |
let titleTxt = w.addText(item.title) | |
titleTxt.font = Font.boldSystemFont(16) | |
titleTxt.textColor = Color.white() | |
// Add spacing below title. | |
w.addSpacer(8) | |
// Show stats info. | |
let statsTxt = w.addText(`${streamer} 路 ${strDate} 路 ${channelType}`) | |
statsTxt.font = Font.mediumSystemFont(12) | |
statsTxt.textColor = Color.white() | |
statsTxt.textOpacity = 0.9 | |
// Add spacing below stats info. | |
w.addSpacer(2) | |
// Show stats info. | |
let statsTxt2 = w.addText(`${item.groups_name} 路 馃敪 ${item.viewers}${trendStr}`) | |
statsTxt2.font = Font.mediumSystemFont(12) | |
statsTxt2.textColor = Color.white() | |
statsTxt2.textOpacity = 0.9 | |
// Add spacing below stats info. | |
w.addSpacer(2) | |
// Show number of ongoing streams. | |
let ongoingTxt = w.addText(`鐝惧湪 ${data.length} 銇儵銈ゃ儢閰嶄俊銇屻亗銈娿伨銇檂) | |
ongoingTxt.font = Font.mediumSystemFont(12) | |
ongoingTxt.textColor = Color.white() | |
ongoingTxt.textOpacity = 0.9 | |
// Add spacing... | |
w.addSpacer(2) | |
// Show footer. | |
let footer = w.addText(`${updatedStr}, VNUMA`) | |
footer.font = Font.mediumSystemFont(12) | |
footer.textColor = Color.white() | |
footer.textOpacity = 0.9 | |
// footer.rightAlignText() | |
// Add spacing below content to center it vertically. | |
w.addSpacer() | |
return w | |
} | |
async function loadData(groups) { | |
// let url = "https://hiyoko.sonoj.net/dy-st/30s/6c6cb639-1d2f-4151-81c7-fd877700cf98.json" | |
let url = "https://hiyoko.sonoj.net/f/avtapi/live/fetch_current_v3" | |
let req = new Request(url) | |
req.method = 'POST' | |
req.headers = { | |
'Connection': 'keep-alive', | |
'Content-Length': '0', | |
'Accept': 'application/json;charset=UTF-8', | |
'Cache-Cotrol': 'public, max-age=300', | |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', | |
'Origin': 'https://hiyoko.sonoj.net', | |
'Sec-Fetch-Site': 'same-origin', | |
'Sec-Fetch-Mode': 'cors', | |
'Sec-Fetch-Dest': 'empty', | |
'Referer': 'https://hiyoko.sonoj.net/live/', | |
'Accept-Language': 'en;q=0.8', | |
} | |
let json = await req.loadJSON() | |
// console.log(json) | |
let jsonSorted = json.current_live.sort((a, b) => (b.viewers - a.viewers)) | |
let jsonFiltered = jsonSorted.filter((entry) => { | |
if (entry.groups == null) { | |
return false | |
} else if (groups.length == 0) { | |
return true | |
} else { | |
let included = false | |
for (const group of groups) { | |
included = included || entry.groups.includes(group) | |
} | |
return included | |
} | |
}) | |
return jsonFiltered | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment