HMS

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

commit 81e80e4dd499627820478d1e61601d28605650c3
parent 6be73a42be453bd1fbabede5046c34889bf7796b
Author: Brian C. Lane <bcl@brianlane.com>
Date:   Sun, 24 Oct 2010 17:25:54 -0700

Basic main loop is running

pushes paths onto a stack, pops them off when exited.
Added a top level placeholder screen and new sub-screens
A new screen for each level seems to be the key.
Added breadcrumb of parent directory (or host name at top)

Diffstat:
MHMS/source/appDisplayDirectory.brs | 65++++++++++++++++++++++++++++++++++++++++++++---------------------
MHMS/source/appMain.brs | 42++++++++++++++++++++++++++++++++++++------
DHMS/source/appPosterScreen.brs | 126-------------------------------------------------------------------------------
MHMS/source/getDirectoryListing.brs | 25+++++++++++++++++--------
4 files changed, 97 insertions(+), 161 deletions(-)

diff --git a/HMS/source/appDisplayDirectory.brs b/HMS/source/appDisplayDirectory.brs @@ -6,19 +6,32 @@ '****************************************************** '** Show the contents of url '****************************************************** -Sub displayDirectory( url ) As Void +Function displayDirectory( url As String ) As Object + print "url: ";url + + port=CreateObject("roMessagePort") + screen = CreateObject("roPosterScreen") + screen.SetMessagePort(port) + screen.SetListStyle("flat-category") + screen.SetListDisplayMode("zoom-to-fill") + + ' Get last element of URL to use as a breadcrumb + toks = url.tokenize("/") + bc1 = "" + bc2 = toks[toks.Count()-1] + screen.SetBreadcrumbText(bc1, bc2) + screen.Show() ' Get the directory listing files = getDirectoryListing(url) + print "got listing" if files = invalid then - print "Failed to get directory listing for"; url - return + print "Failed to get directory listing for";url + return invalid end if - 'print files - ' Figure out what kind of directory this is - ' videos(0) - default, photos(1), songs(2), episodes(3) + ' dirs(0) - default, photos(1), songs(2), episodes(3), movies(4) if files.DoesExist("photos") then dirType = 1 displayList = displayFiles(files, { jpg : true }) @@ -41,15 +54,28 @@ Sub displayDirectory( url ) As Void return LCase(k[0]) end function) +' print "dirType: ";dirType ' for each f in displayList ' print f[0] ' print f[1] ' end for + + if displayList.Count() = 0 then + return invalid + end if + if dirType = 0 then - ret = showCategories( displayList ) + ret = showCategories( screen, displayList ) + if ret <> invalid then + return ret[1]["basename"] + else + return invalid + end if + else + return invalid end if -End Sub +End Function '****************************************************** '** Return a list of the Videos and directories @@ -57,7 +83,7 @@ End Sub '** Videos end in the following extensions '** .mp4 .m4v .mov .wmv '****************************************************** -Sub displayFiles( files As Object, fileTypes As Object, dirs=false As Boolean ) As Object +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 @@ -71,18 +97,13 @@ Sub displayFiles( files As Object, fileTypes As Object, dirs=false As Boolean ) end for return list -End Sub +End Function '****************************************************** '** Display a flat-category poster screen of items '** return the one selected by the user or nil? '****************************************************** -Sub showCategories( files As Object ) As Object - screen = CreateObject("roPosterScreen") - screen.SetBreadcrumbText("bc-1", "bc-2") - screen.SetMessagePort(m.port) - screen.SetListStyle("flat-category") - screen.SetListDisplayMode("zoom-to-fill") +Function showCategories( screen As Object, files As Object ) As Object list = CreateObject("roArray", files.Count(), true) for each f in files @@ -99,15 +120,17 @@ Sub showCategories( files As Object ) As Object screen.SetContentList(list) screen.Show() - done = false - while not done - msg = wait(0, m.port) + while true + msg = wait(0, screen.GetMessagePort()) print msg if msg = invalid or msg.isScreenClosed() then - return -1 + ' UP appears to close the screen, so we get here + print "screen closed" + return invalid else if msg.isListItemSelected() then print "msg: ";msg.GetMessage();" idx: ";msg.GetIndex() + return files[msg.GetIndex()] end if end while -End Sub +End Function diff --git a/HMS/source/appMain.brs b/HMS/source/appMain.brs @@ -2,11 +2,7 @@ '** Home Media Server Application - Main '** Copyright (c) 2010 Brian C. Lane All Rights Reserved. '******************************************************************** - Sub Main() - - m.port = CreateObject("roMessagePort") - 'initialize theme attributes like titles, logos and overhang color initTheme() @@ -16,7 +12,30 @@ Sub Main() return endif - displayDirectory("http://"+RegRead("ServerURL") ) + screen = PreShowPosterScreen() + if screen = invalid then + print "Error creating initial poster screen" + return + end if + + path = [] + + done = false + while not done + print path + pathString = joinString(path, "/", true, true) + print pathString + ret = displayDirectory( "http://"+RegRead("ServerURL")+pathString ) + print "main: ";ret + print "depth:";path.Count() + if ret = invalid and path.Count() = 0 then + done = true + else if ret = invalid then + path.Pop() + else + path.Push(ret) + end if + end while End Sub @@ -27,7 +46,6 @@ End Sub '** Theme attributes affect the branding of the application '** and are artwork, colors and offsets specific to the app '************************************************************* - Sub initTheme() app = CreateObject("roAppManager") @@ -47,3 +65,15 @@ Sub initTheme() End Sub +'************************************************************* +'** Setup something as a placeholder while we load +'************************************************************* +Function preShowPosterScreen() As Object + port=CreateObject("roMessagePort") + screen = CreateObject("roPosterScreen") + screen.SetMessagePort(port) + screen.SetListStyle("flat-category") + screen.Show() + return screen +End Function + diff --git a/HMS/source/appPosterScreen.brs b/HMS/source/appPosterScreen.brs @@ -1,126 +0,0 @@ -'****************************************************** -'** Video Player Example Application -- Poster Screen -'** November 2009 -'** Copyright (c) 2009 Roku Inc. All Rights Reserved. -'****************************************************** - -'****************************************************** -'** Perform any startup/initialization stuff prior to -'** initially showing the screen. -'****************************************************** -Function preShowPosterScreen(breadA=invalid, breadB=invalid) As Object - - if validateParam(breadA, "roString", "preShowPosterScreen", true) = false return -1 - if validateParam(breadB, "roString", "preShowPosterScreen", true) = false return -1 - - port=CreateObject("roMessagePort") - screen = CreateObject("roPosterScreen") - screen.SetMessagePort(port) - if breadA<>invalid and breadB<>invalid then - screen.SetBreadcrumbText(breadA, breadB) - end if - - screen.SetListStyle("arced-portrait") - return screen - -End Function - - -'****************************************************** -'** Display the home screen and wait for events from -'** the screen. The screen will show retreiving while -'** we fetch and parse the feeds for the game posters -'****************************************************** -Function showPosterScreen(screen As Object, category As Object) As Integer - - if validateParam(screen, "roPosterScreen", "showPosterScreen") = false return -1 - if validateParam(category, "roAssociativeArray", "showPosterScreen") = false return -1 - - m.curCategory = 0 - m.curShow = 0 - - screen.SetListNames(getCategoryList(category)) - screen.SetContentList(getShowsForCategoryItem(category, m.curCategory)) - screen.Show() - - while true - msg = wait(0, screen.GetMessagePort()) - if type(msg) = "roPosterScreenEvent" then - print "showPosterScreen | msg = "; msg.GetMessage() " | index = "; msg.GetIndex() - if msg.isListFocused() then - m.curCategory = msg.GetIndex() - m.curShow = 0 - screen.SetFocusedListItem(m.curShow) - screen.SetContentList(getShowsForCategoryItem(category, m.curCategory)) - print "list focused | current category = "; m.curCategory - else if msg.isListItemSelected() then - m.curShow = msg.GetIndex() - print "list item selected | current show = "; m.curShow - m.curShow = displayShowDetailScreen(category, m.curShow) - screen.SetFocusedListItem(m.curShow) - print "list item updated | new show = "; m.curShow - else if msg.isScreenClosed() then - return -1 - end if - end If - end while - - -End Function - -'********************************************************** -'** When a poster on the home screen is selected, we call -'** this function passing an associative array with the -'** data for the selected show. This data should be -'** sufficient for the show detail (springboard) to display -'********************************************************** -Function displayShowDetailScreen(category as Object, showIndex as Integer) As Integer - - if validateParam(category, "roAssociativeArray", "displayShowDetailScreen") = false return -1 - - shows = getShowsForCategoryItem(category, m.curCategory) - screen = preShowDetailScreen(category.Title, category.kids[m.curCategory].Title) - showIndex = showDetailScreen(screen, shows, showIndex) - - return showIndex -End Function - - -'************************************************************** -'** Given an roAssociativeArray representing a category node -'** from the category feed tree, return an roArray containing -'** the names of all of the sub categories in the list. -'*************************************************************** -Function getCategoryList(topCategory As Object) As Object - - if validateParam(topCategory, "roAssociativeArray", "getCategoryList") = false return -1 - - if type(topCategory) <> "roAssociativeArray" then - print "incorrect type passed to getCategoryList" - return -1 - endif - - categoryList = CreateObject("roArray", 100, true) - for each subCategory in topCategory.Kids - categoryList.Push(subcategory.Title) - next - return categoryList - -End Function - -'******************************************************************** -'** Return the list of shows corresponding the currently selected -'** category in the filter banner. As the user highlights a -'** category on the top of the poster screen, the list of posters -'** displayed should be refreshed to corrrespond to the highlighted -'** item. This function returns the list of shows for that category -'******************************************************************** -Function getShowsForCategoryItem(category As Object, item As Integer) As Object - - if validateParam(category, "roAssociativeArray", "getCategoryList") = false return invalid - - conn = InitShowFeedConnection(category.kids[item]) - showList = conn.LoadShowFeed(conn) - return showList - -End Function diff --git a/HMS/source/getDirectoryListing.brs b/HMS/source/getDirectoryListing.brs @@ -2,8 +2,9 @@ ' ** Parse an HTML directory listing ' ** Copyright (c) 2010 Brian C. Lane All Rights Reserved. ' ******************************************************************** +Function getDirectoryListing(url As String) As Object + print "dir url: ";url -Sub getDirectoryListing(url as String) As Object http = CreateObject("roUrlTransfer") http.SetUrl(url) dir = http.GetToString() @@ -14,20 +15,28 @@ Sub getDirectoryListing(url as String) As Object end if ' Try parsing the html as if it is XML - rsp=CreateObject("roXMLElement") - if not rsp.Parse(dir) then + xml=CreateObject("roXMLElement") + if not xml.Parse(dir) then print "Cannot parse directory listing as XML" return invalid end if + print "got xml" + ' grab all the <a href /> elements - urls = getUrls({}, rsp) + urls = getUrls({}, xml) + + print urls + return urls -End Sub +End Function -Sub getUrls(array as Object, element as Object) As Object +Function getUrls(array as Object, element as Object) As Object if element.GetName() = "a" and element.HasAttribute("href") then - array.AddReplace(element.GetAttributes()["href"], "") +' array.AddReplace(element.GetAttributes()["href"], "") + href = element.GetAttributes()["href"] + print "href: ";href + array.AddReplace(href, "") end if if element.GetChildElements()<>invalid then for each e in element.GetChildElements() @@ -35,5 +44,5 @@ Sub getUrls(array as Object, element as Object) As Object end for end if return array -End Sub +End Function