' ********** Copyright 2020 Roku Corp. All Rights Reserved. **********
' invoked by UILogic/ContentTaskLogic
' which is called by MainScene.xml
'
' Note that we need to import this file in MainLoaderTask.xml using relative path.
sub Init()
print "MainScene.brs:Init"
' set the name of the function in the Task node component to be executed when the state field changes to RUN
' in our case this method executed after the following cmd: m.contentTask.control = "run"(see Init method in MainScene)
m.top.functionName = "GetContent"
end sub
sub GetContent()
result=GetContentJson("https://media.abcc.org/roku/feeds/primary-feed.json")
' or
' result= getContentXML("https://media.abcc.org/roku/feeds/primary_feed.rss")
sleep(1000)
m.top.mediaIndex=bundle.index
''? "m.top.mediaIndex= "; m.top.mediaIndex
m.global.addField("mediaIndex", "assocarray", false)
m.global.mediaIndex = result.index
m.top.content = result.contentArray
end sub
sub GetContentJson(url)
' request the content feed from the API
xfer = CreateObject("roURLTransfer")
xfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
xfer.SetURL(url)
rsp = xfer.GetToString()
rootChildren = []
rows = {}
' parse the feed and build a tree of ContentNodes to populate the GridView
json = ParseJson(rsp)
Print "Json:"
Print json
mediaindex={}
if json <> invalid
for each item in json.items()
' Print "Category"
' Print category
category = mid(item.key,3)
value = item.value ' json.Lookup(category)
if Type(value) = "roArray" ' if parsed key value having other objects in it
if category <> "series" ' ignore series for this phase
row = {}
row.title = category
row.children = []
for each item in value ' parse items and push them to row
itemData = GetItemData(item)
row.children.Push(itemData)
' for deeplink
mediaindex[item.id] = item
''? "mediaindex= "; mediaindex
end for
rootChildren.Push(row)
' Print "adding Cat"
' Print rootChildren
end if
' Stop
end if
end for
' set up a root ContentNode to represent rowList on the GridScreen
contentNode = CreateObject("roSGNode", "ContentNode")
contentNode.Update({
children: rootChildren
}, true)
' populate content field with root content node.
' Observer(see OnMainContentLoaded in MainScene.brs) is invoked at that moment
end if
return {contentarray:contentNode:index:mediaindex} 'Returns the array
end sub
sub GetContent()
' request the content feed from the API
xfer = CreateObject("roURLTransfer")
xfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
' xfer.SetURL("https://jonathanbduval.com/roku/feeds/roku-developers-feed-v1.json")
xfer.SetURL("https://media.abcc.org/roku/feeds/primary-feed.json")
rsp = xfer.GetToString()
rootChildren = []
rows = {}
' parse the feed and build a tree of ContentNodes to populate the GridView
json = ParseJson(rsp)
Print "Json:"
Print json
mediaindex={}
if json <> invalid
for each item in json.items()
' Print "Category"
' Print category
category = mid(item.key,3)
value = item.value ' json.Lookup(category)
if Type(value) = "roArray" ' if parsed key value having other objects in it
if category <> "series" ' ignore series for this phase
row = {}
row.title = category
row.children = []
for each item in value ' parse items and push them to row
itemData = GetItemData(item)
row.children.Push(itemData)
' for deeplink
mediaindex[item.id] = item
''? "mediaindex= "; mediaindex
end for
rootChildren.Push(row)
' Print "adding Cat"
' Print rootChildren
end if
' Stop
end if
end for
' set up a root ContentNode to represent rowList on the GridScreen
contentNode = CreateObject("roSGNode", "ContentNode")
contentNode.Update({
children: rootChildren
}, true)
' populate content field with root content node.
' Observer(see OnMainContentLoaded in MainScene.brs) is invoked at that moment
end if
print "MainLoaderTask completed."
print mediaindex
m.global.addField("mediaIndex", "assocarray", false)
m.global.mediaIndex = mediaindex
m.top.content = contentNode
end sub
function GetItemData(video as Object) as Object
item = {}
' populate some standard content metadata fields to be displayed on the GridScreen
' https://developer.roku.com/docs/developer-program/getting-started/architecture/content-metadata.md
if video.longDescription <> invalid
item.description = video.longDescription
else
item.description = video.shortDescription
end if
item.hdPosterURL = video.thumbnail
item.title = video.title
item.releaseDate = video.releaseDate
item.id = video.id
if video.content <> invalid
' populate length of content to be displayed on the GridScreen
item.length = video.content.duration
' populate meta-data for playback
item.url = video.content.videos[0].url
item.streamFormat = video.content.videos[0].videoType
end if
return item
end function
'
' ---------------------------------
' ------------------------------------
sub GetContentXML(url)
' request the content feed from the API
xfer = CreateObject("roURLTransfer")
xfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
xfer.SetURL(url)
rsp = xfer.GetToString()
rootChildren = []
rows = {}
' parse the feed and build a tree of ContentNodes to populate the GridView
json = ParseJson(rsp)
Print "Json:"
Print json
mediaindex={}
if json <> invalid
for each item in json.items()
' Print "Category"
' Print category
category = mid(item.key,3)
value = item.value ' json.Lookup(category)
if Type(value) = "roArray" ' if parsed key value having other objects in it
if category <> "series" ' ignore series for this phase
row = {}
row.title = category
row.children = []
for each item in value ' parse items and push them to row
itemData = GetItemData(item)
row.children.Push(itemData)
' for deeplink
mediaindex[item.id] = item
''? "mediaindex= "; mediaindex
end for
rootChildren.Push(row)
' Print "adding Cat"
' Print rootChildren
end if
' Stop
end if
end for
' set up a root ContentNode to represent rowList on the GridScreen
contentNode = CreateObject("roSGNode", "ContentNode")
contentNode.Update({
children: rootChildren
}, true)
' populate content field with root content node.
' Observer(see OnMainContentLoaded in MainScene.brs) is invoked at that moment
end if
print "MainLoaderTask completed."
print mediaindex
m.global.addField("mediaIndex", "assocarray", false)
m.global.mediaIndex = mediaindex
m.top.content = contentNode
end sub
Sub loadContent()
bundle=GetContentFeed()
m.top.content = ParseXMLContent(bundle.contentArray)
sleep(1000)
m.top.mediaIndex=bundle.index
''? "m.top.mediaIndex= "; m.top.mediaIndex
return
end Sub
Function GetContentFeed(feedUrl) 'This function retrieves and parses the feed and stores the content item in a ContentNode
url = CreateObject("roUrlTransfer") 'component used to transfer data to/from remote servers
url.SetUrl(feedUrl)
url.SetCertificatesFile("common:/certs/ca-bundle.crt")
rsp = url.GetToString() 'convert response into a string
responseXML = ParseXML(rsp) 'Roku includes its own XML parsing method
if responseXML <> invalid then 'Fall back in case Roku's built in XML parse method fails
responseXML = responseXML.GetChildElements() 'Access content inside Feed
groupArray = responseXML.GetChildElements()
End if
'manually parse feed if ParseXML() is invalid
mediaindex={}
'stop
groups=[]
for each groupXml in groupArray
print groupXml
if groupXml.getName() = "group"
result = [] 'Store all results inside an array. Each element respresents a row inside our RowList stored as an Associative Array (line 63)
print "title"
print groupXml.getAttributes().title
title =groupXml.getAttributes().title
'stop
itemsArray=groupXml.getChildElements()
for each xmlItem in itemsArray 'For loop to grab contents inside each item in XML feed
if xmlItem.getName() = "item" 'Each individual channel content is stored inside the XML header named -
itemAA = xmlItem.getChildElements() 'Get the child elements of item
if itemAA <> invalid 'Fall bak in case invalid is returned
item = {} 'Creates an associative array for each row
for each xmlItem in itemAA ' Goes thru all contents of itemAA
item[xmlItem.getName()] = xmlItem.getText()
if xmlItem.getName() = "media:content" 'Checks to find header
item.stream = {url: xmlItem.url} ' Assigns all content inside to the item AA
item.url = xmlItem.getAttributes().url
item.streamFormat = "mp4"
mediaContent = xmlItem.GetChildElements()
for each mediaContentItem in mediaContent 'Looks through meiaContent to find poster image for each piece of content
if mediaContentItem.getName() = "media:thumbnail"
item.HDPosterURL = mediaContentItem.getattributes().url 'Assign image to item AA
item.HDBackgroundImageUrl = mediaContentItem.getattributes().url
end if
end for
else if xmlitem.getname()="guid"
item.guid=xmlitem.getText()
end if
end for
result.push(item) 'Pushes each AA into the Array
mediaindex[item.guid] = item
''? "mediaindex= "; mediaindex
end if
end if
end for
' end of group
groups.push({Title:title,ContentList:result})
end if
end for
print groups
'stop
return {contentarray:groups:index:mediaindex} 'Returns the array
End Function
Function ParseXML(str As String) As dynamic 'Takes in the content feed as a string
if str = invalid return invalid 'if the response is invalid, return invalid
xml = CreateObject("roXMLElement") '
if not xml.Parse(str) return invalid 'if the string cannot be parse, return invalid
return xml 'returns parsed XML if not invalid
End Function
Function ParseXMLContent(list As Object) 'Formats content into content nodes so they can be passed into the RowList
RowItems = createObject("RoSGNode","ContentNode")
'Content node format for RowList: ContentNode(RowList content) ---> ContentNodes for each row ---> ContentNodes for each item in the row)
for each rowAA in list
row = createObject("RoSGNode","ContentNode")
row.Title = rowAA.Title
for each itemAA in rowAA.ContentList
item = createObject("RoSGNode","ContentNode")
'Don't do item.SetFields(itemAA), as it doesn't cast streamFormat to proper value
'for each key in itemAA
' ?"key = ", key, itemAA[key]
'item[key] = itemAA[key]
'end for
item.setFields(itemAA)
row.appendChild(item)
end for
RowItems.appendChild(row)
end for
return RowItems
End Function