Last active
November 26, 2020 20:22
-
-
Save joeybaumgartner/d659ced958ccc194c449f634fcbabb08 to your computer and use it in GitHub Desktop.
CBC Scriptable Widget
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
/* | |
You can override the default CBC feed by specifying the RSS | |
feed you would prefer to use through the parameters field in | |
the widget. Available CBC RSS feed are available here: | |
https://www.cbc.ca/rss/ | |
*/ | |
function unescapeHTML(str) {//modified from underscore.string and string.js | |
return str.replace(/\&([^;]+);/g, function(entity, entityCode) { | |
var escapeChars = { lt: '<', gt: '>', quot: '"', apos: "'", amp: '&' }; | |
var match; | |
if ( entityCode in escapeChars) { | |
return escapeChars[entityCode]; | |
} else if ( match = entityCode.match(/^#x([\da-fA-F]+)$/)) { | |
return String.fromCharCode(parseInt(match[1], 16)); | |
} else if ( match = entityCode.match(/^#(\d+)$/)) { | |
return String.fromCharCode(~~match[1]); | |
} else { | |
return entity; | |
} | |
}); | |
} | |
let params = args.widgetParameter; | |
var url = "https://rss.cbc.ca/lineup/canada.xml"; | |
if(params != null) { | |
url = params; | |
} | |
let items = []; | |
let request = new Request(url); | |
let s = await request.loadString(request); | |
let xmlParser = new XMLParser(s); | |
let elementName = ""; | |
let currentValue = null; | |
let currentItem = null; | |
let currentAttributes = null; | |
xmlParser.didStartElement = (name, attributes) => { | |
currentValue = ""; | |
if(name == "item") { | |
currentItem = {}; | |
} | |
} | |
xmlParser.didEndElement = name => { | |
const hasItem = currentItem != null; | |
if(hasItem) { | |
switch(name) { | |
case "title": | |
currentItem["title"] = currentValue; | |
break; | |
case "description": | |
currentItem["description"] = currentValue; | |
break; | |
case "link": | |
currentItem["link"] = currentValue; | |
break; | |
case "pubDate": | |
currentItem["date"] = new Date(currentValue); | |
break; | |
case "author": | |
currentItem["author"] = currentValue; | |
break; | |
default: | |
break; | |
} | |
} | |
if(name == "item") { | |
items.push(currentItem); | |
currentItem = {}; | |
} | |
} | |
xmlParser.foundCharacters = (string) => { | |
currentValue += string; | |
} | |
xmlParser.parseErrorOccurred = (string) => { | |
console.log("failed on: " + string); | |
} | |
xmlParser.parse(); | |
let widget = await createWidget(items); | |
if(!config.runsInWidget) | |
{ | |
await widget.presentMedium(); | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
async function createWidget(items) | |
{ | |
let info = items[0]; | |
let imageURL = extractImageURL(info.description); | |
let df = new DateFormatter(); | |
df.dateFormat = "MMMM dd, yyyy h:mm a"; | |
let publishDate = df.string(info.date); | |
let w = new ListWidget(); | |
w.url = info.link; | |
let title = w.addText(info.title); | |
title.font = Font.boldSystemFont(16); | |
w.addSpacer(1); | |
let storyDate = "@ " + w.addText(publishDate); | |
storyDate.font = Font.caption1(); | |
let g = new LinearGradient(); | |
g.locations = [0, 1]; | |
g.colors = [ | |
new Color("#ff0000af"), | |
new Color("#0000007f") | |
] | |
let imageRequest = new Request(imageURL); | |
let image = await imageRequest.loadImage(); | |
if(image != null) | |
{ | |
w.backgroundImage = image; | |
} | |
w.backgroundColor = Color.red(); | |
w.backgroundGradient = g; | |
w.addSpacer(8); | |
var story = w.addText(extractStoryText(info.description)); | |
story.font = Font.mediumSystemFont(12); | |
return w; | |
} | |
function extractImageURL(item) | |
{ | |
let regex = /<img src='(.*)' alt='/; | |
let matches = item.match(regex); | |
if (matches && matches.length >= 2) { | |
return matches[1]; | |
} | |
else | |
{ | |
return null; | |
} | |
} | |
function extractStoryText(item) | |
{ | |
let regex = /<p>(.*)<\/p>/; | |
let matches = item.match(regex); | |
if(matches && matches.length >= 2) { | |
return matches[1]; | |
} | |
else | |
{ | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added
unescapeHTML
function that was missing from original file.