HMS

Home Media Server for Roku Players
git clone https://www.brianlane.com/git/HMS
Log | Files | Refs | README | LICENSE

commit 528b680e94f9134eac78e21569454301d21b09db
parent 60bd50edd87cd4a0c9d51a6a7235d709e5b3fbcf
Author: Brian C. Lane <bcl@brianlane.com>
Date:   Sun, 13 Nov 2022 14:30:01 -0800

Add the list of categories to the main screen

This retrieves the category list from the server and uses a LabelList to
display them on the screen.

Diffstat:
MHMS/components/MainLoaderTask.brs | 50++++++++++++++++++++++++++++++++++++++++++++++++++
MHMS/components/MainLoaderTask.xml | 5++++-
MHMS/components/MainScene.brs | 23+++++++++++++++++------
MHMS/components/MainScene.xml | 4++--
MHMS/source/appMediaServer.brs | 51---------------------------------------------------
MHMS/source/getDirectoryListing.brs | 33++++-----------------------------
AHMS/source/keystore.brs | 29+++++++++++++++++++++++++++++
7 files changed, 106 insertions(+), 89 deletions(-)

diff --git a/HMS/components/MainLoaderTask.brs b/HMS/components/MainLoaderTask.brs @@ -13,4 +13,54 @@ sub GetContent() print "MainLoaderTask->GetContent()" print m.top.serverurl + m.top.categories = getSortedCategoryTitles(m.top.serverurl) end sub + +'****************************************************** +' Return a roArray of just the category names +'****************************************************** +Function catTitles(categories As Object) As Object + titles = CreateObject("roArray", categories.Count(), false) + for i = 0 to categories.Count()-1 + titles.Push(getLastElement(categories[i][0])) + end for + return titles +End Function + +'****************************************************** +'** Get a sorted roArray of category titles +'****************************************************** +Function getSortedCategoryTitles(url as String) As Object + ' Build list of Category Names from the top level directories + listing = getDirectoryListing(url) + if listing = invalid then + return invalid + end if + categories = displayFiles(listing, {}, true) + Sort(categories, function(k) + return LCase(k[0]) + end function) + return catTitles(categories) +End Function + +'****************************************************** +'** Return a list of the Videos and directories +'** +'** Videos end in the following extensions +'** .mp4 .m4v .mov .wmv +'****************************************************** +Function displayFiles(files As Object, fileTypes As Object, dirs=false As Boolean) As Object + list = [] + for each f in files + ' This expects the path to have a system volume at the start + p = CreateObject("roPath", "pkg:/" + f) + if p.IsValid() and f.Left(1) <> "." then + fileType = fileTypes[p.Split().extension.mid(1)] + if (dirs and f.Right(1) = "/") or fileType = true then + list.push([f, p.Split()]) + end if + end if + end for + + return list +End Function diff --git a/HMS/components/MainLoaderTask.xml b/HMS/components/MainLoaderTask.xml @@ -1,9 +1,12 @@ <?xml version="1.0" encoding="utf-8" ?> <component name="MainLoaderTask" extends="Task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd"> + <script type="text/brightscript" uri="pkg:/source/generalUtils.brs" /> + <script type="text/brightscript" uri="pkg:/source/urlUtils.brs" /> + <script type="text/brightscript" uri="pkg:/source/getDirectoryListing.brs" /> <script type="text/brightscript" uri="MainLoaderTask.brs" /> <interface> <field id="serverurl" type="uri" /> - <field id="content" type="node" /> + <field id="categories" type="roArray" /> </interface> </component> diff --git a/HMS/components/MainScene.brs b/HMS/components/MainScene.brs @@ -21,16 +21,27 @@ sub RunContentTask() m.contentTask = CreateObject("roSGNode", "MainLoaderTask") m.contentTask.serverurl = m.top.serverurl - m.contentTask.ObserveField("content", "OnMainContentLoaded") + m.contentTask.ObserveField("categories", "OnCategoriesLoaded") m.contentTask.control = "run" end sub -sub OnMainContentLoaded() - print "MainScene->OnMainContentLoaded()" +sub OnCategoriesLoaded() + print "MainScene->OnCategoriesLoaded()" + print m.contentTask.categories + m.categories = m.contentTask.categories -' m.GridScreen.SetFocus(true) -' m.loadingIndicator.visible = false -' m.GridScreen.content = m.contentTask.content + ' Add these to the list on the left side of the screen... how? + m.topmenu = m.top.FindNode("topmenu") + m.topmenu.vertFocusAnimationStyle = "floatingFocus" + + ln = CreateObject("roSGNode", "ContentNode") + for each item in m.categories: + n = CreateObject("roSGNode", "ContentNode") + n.title = item + ln.appendChild(n) + end for + m.topmenu.content = ln + m.topmenu.SetFocus(true) end sub sub RunValidateURLTask(url as string) diff --git a/HMS/components/MainScene.xml b/HMS/components/MainScene.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" ?> <component name="MainScene" extends="Scene" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd"> <script type="text/brightscript" uri="pkg:/source/generalUtils.brs" /> - <script type="text/brightscript" uri="pkg:/source/urlUtils.brs" /> <script type="text/brightscript" uri="MainScene.brs" /> <interface> <field id="serverurl" type="uri" onChange="RunLoaderTask" /> <field id="keystore" type="bool" /> + <field id="categories" type="roArray" /> </interface> <children> - <Label text="Hello World!" /> + <LabelList id="topmenu" /> </children> </component> diff --git a/HMS/source/appMediaServer.brs b/HMS/source/appMediaServer.brs @@ -443,28 +443,6 @@ Function getLastPosition(title As String, url As String, has_keystore As Boolean End Function '****************************************************** -'** Return a list of the Videos and directories -'** -'** Videos end in the following extensions -'** .mp4 .m4v .mov .wmv -'****************************************************** -Function displayFiles( files As Object, fileTypes As Object, dirs=false As Boolean ) As Object - list = [] - for each f in files - ' This expects the path to have a system volume at the start - p = CreateObject("roPath", "pkg:/" + f) - if p.IsValid() and f.Left(1) <> "." then - fileType = fileTypes[p.Split().extension.mid(1)] - if (dirs and f.Right(1) = "/") or fileType = true then - list.push([f, p.Split()]) - end if - end if - end for - - return list -End Function - -'****************************************************** '** Play the video using the data from the movie '** metadata object passed to it '****************************************************** @@ -523,35 +501,6 @@ Function getDescription(url As String) return "" End Function -'****************************************************** -' Return a roArray of just the category names -' include the Setup row as the first entry -'****************************************************** -Function catTitles(categories As Object) As Object - titles = CreateObject("roArray", categories.Count()+1, false) - titles.Push("Jump To") - for i = 0 to categories.Count()-1 - titles.Push(getLastElement(categories[i][0])) - end for - return titles -End Function - -'****************************************************** -'** Get a sorted roArray of category titles -'****************************************************** -Function getSortedCategoryTitles(url as String) As Object - ' Build list of Category Names from the top level directories - listing = getDirectoryListing(url) - if listing = invalid then - return invalid - end if - categories = displayFiles(listing, {}, true) - Sort(categories, function(k) - return LCase(k[0]) - end function) - return catTitles(categories) -End Function - '******************************************************************* ' Return a roArray of roAssociativeArrays for the selected category '******************************************************************* diff --git a/HMS/source/getDirectoryListing.brs b/HMS/source/getDirectoryListing.brs @@ -6,11 +6,10 @@ Function getDirectoryListing(url As String) As Object result = getHTMLWithTimeout(url, 60) if result.error or result.str = invalid then - title = "Directory Listing Error" - text = "There was an error fetching the directory listing." - print text - ShowErrorDialog(text, title) - +' title = "Directory Listing Error" +' text = "There was an error fetching the directory listing." +' print text +' ShowErrorDialog(text, title) return invalid end if @@ -33,27 +32,3 @@ Function getDirectoryListing(url As String) As Object next_href = next_quote + 2 end while End Function - -' *********************************** -' * Get a value for a key -' *********************************** -Function getKeyValue(url As String, key As String) As String - result = getHTMLWithTimeout(url+"/keystore/"+key, 60) - if result.error and result.response <> 404 then - print "Error ";result.response;" getting key ";key;": ";result.reason - return "" - elseif result.error and result.response = 404 then - return "" - end if - return result.str -End Function - -' *********************************** -' * Set a value for a key -' *********************************** -Function setKeyValue(url As String, key As String, value As String) - result = postHTMLWithTimeout(url+"/keystore/"+key, "value="+value, 60) - if result.error then - print "Error ";result.response;" setting key ";key;"=";value;": ";result.reason - end if -End Function diff --git a/HMS/source/keystore.brs b/HMS/source/keystore.brs @@ -0,0 +1,29 @@ +'******************************************************************** +'** Home Media Server Application - keystore functions +'** Copyright (c) 2022 Brian C. Lane All Rights Reserved. +'******************************************************************** + + +' *********************************** +' * Get a value for a key +' *********************************** +Function getKeyValue(url As String, key As String) As String + result = getHTMLWithTimeout(url+"/keystore/"+key, 60) + if result.error and result.response <> 404 then + print "Error ";result.response;" getting key ";key;": ";result.reason + return "" + elseif result.error and result.response = 404 then + return "" + end if + return result.str +End Function + +' *********************************** +' * Set a value for a key +' *********************************** +Function setKeyValue(url As String, key As String, value As String) + result = postHTMLWithTimeout(url+"/keystore/"+key, "value="+value, 60) + if result.error then + print "Error ";result.response;" setting key ";key;"=";value;": ";result.reason + end if +End Function