syndicate 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in syndicate.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Brooke McKim
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ Syndicate
2
+ =========
3
+
4
+ Generate MRSS feeds from any directory on your computer.
5
+
6
+ ## Applications
7
+
8
+ Example applications to consume the MRSS feeds are available in the examples directory.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'syndicate'
4
+
5
+ Syndicate::App.run!
@@ -0,0 +1,23 @@
1
+ #########################################################################
2
+ # Simple makefile for packaging Roku Video Player example
3
+ #
4
+ # Makefile Usage:
5
+ # > make
6
+ # > make install
7
+ # > make remove
8
+ #
9
+ # Important Notes:
10
+ # To use the "install" and "remove" targets to install your
11
+ # application directly from the shell, you must do the following:
12
+ #
13
+ # 1) Make sure that you have the curl command line executable in your path
14
+ # 2) Set the variable ROKU_DEV_TARGET in your environment to the IP
15
+ # address of your Roku box. (e.g. export ROKU_DEV_TARGET=192.168.1.1.
16
+ # Set in your this variable in your shell startup (e.g. .bashrc)
17
+ ##########################################################################
18
+ APPNAME = syndicate
19
+ VERSION = 1.0
20
+
21
+ ZIP_EXCLUDE= -x *.git/* -x .gitignore -x .DS_Store -x README.md -x zips/* -x zips/
22
+
23
+ include ./app.mk
@@ -0,0 +1,24 @@
1
+ # Roku Application which can be powered by MRSS feeds.
2
+
3
+ ## Setup
4
+
5
+ 1. Change url variable in appMain.brs to point to your Syndicate server.
6
+ 1. Edit manifest and change Title and Subtitle accordingly.
7
+ 1. Edit Makefile and change Appname accordingly.
8
+
9
+ ## Graphics
10
+
11
+ All graphics are in /images
12
+
13
+ * banner - The banner at the top of the application
14
+ * banner-logo - The logo overlaid on top of the banner. Position is controlled in theme.brs
15
+ * logo - The logo used on the channel screen of the Roku. These can be used when submitting application to Roku as well.
16
+
17
+ ## Install to Roku
18
+
19
+ Roku must first be set to development mode.
20
+
21
+ ```bash
22
+ export ROKU_DEV_TARGET=<ip_address_of_roku>
23
+ make install
24
+ ```
@@ -0,0 +1,89 @@
1
+ #########################################################################
2
+ # common include file for application Makefiles
3
+ #
4
+ # Makefile Usage:
5
+ # > make
6
+ # > make install
7
+ # > make remove
8
+ #
9
+ # to exclude certain files from being added to the zipfile during packaging
10
+ # include a line like this:ZIP_EXCLUDE= -x keys\*
11
+ # that will exclude any file who's name begins with 'keys'
12
+ # to exclude using more than one pattern use additional '-x <pattern>' arguments
13
+ # ZIP_EXCLUDE= -x \*.pkg -x storeassets\*
14
+ #
15
+ # Important Notes:
16
+ # To use the "install" and "remove" targets to install your
17
+ # application directly from the shell, you must do the following:
18
+ #
19
+ # 1) Make sure that you have the curl command line executable in your path
20
+ # 2) Set the variable ROKU_DEV_TARGET in your environment to the IP
21
+ # address of your Roku box. (e.g. export ROKU_DEV_TARGET=192.168.1.1.
22
+ # Set in your this variable in your shell startup (e.g. .bashrc)
23
+ ##########################################################################
24
+ PKGREL = ./packages
25
+ ZIPREL = ./zips
26
+ SOURCEREL = ./source
27
+
28
+ .PHONY: all $(APPNAME)
29
+
30
+ $(APPNAME):
31
+ @echo "*** Creating $(APPNAME).zip ***"
32
+
33
+ @echo " >> removing old application zip $(ZIPREL)/$(APPNAME).zip"
34
+ @if [ -e "$(ZIPREL)/$(APPNAME).zip" ]; \
35
+ then \
36
+ rm $(ZIPREL)/$(APPNAME).zip; \
37
+ fi
38
+
39
+ @echo " >> creating destination directory $(ZIPREL)"
40
+ @if [ ! -d $(ZIPREL) ]; \
41
+ then \
42
+ mkdir -p $(ZIPREL); \
43
+ fi
44
+
45
+ @echo " >> setting directory permissions for $(ZIPREL)"
46
+ @if [ ! -w $(ZIPREL) ]; \
47
+ then \
48
+ chmod 755 $(ZIPREL); \
49
+ fi
50
+
51
+ # zip .png files without compression
52
+ # do not zip up Makefiles, or any files ending with '~'
53
+ @echo " >> creating application zip $(ZIPREL)/$(APPNAME).zip"
54
+ @if [ -d $(SOURCEREL)/ ]; \
55
+ then \
56
+ (zip -0 -r "$(ZIPREL)/$(APPNAME).zip" . -i \*.png $(ZIP_EXCLUDE)); \
57
+ (zip -9 -r "$(ZIPREL)/$(APPNAME).zip" . -x \*~ -x \*.png -x Makefile $(ZIP_EXCLUDE)); \
58
+ else \
59
+ echo "Source for $(APPNAME) not found at $(SOURCEREL)/"; \
60
+ fi
61
+
62
+ @echo "*** developer zip $(APPNAME) complete ***"
63
+
64
+ install: $(APPNAME)
65
+ @echo "Installing $(APPNAME) to host $(ROKU_DEV_TARGET)"
66
+ @curl -s -S -F "mysubmit=Install" -F "archive=@$(ZIPREL)/$(APPNAME).zip" -F "passwd=" http://$(ROKU_DEV_TARGET)/plugin_install | grep "<font color" | sed "s/<font color=\"red\">//"
67
+
68
+ pkg: install
69
+ @echo "*** Creating Package ***"
70
+
71
+ @echo " >> creating destination directory $(PKGREL)"
72
+ @if [ ! -d $(PKGREL) ]; \
73
+ then \
74
+ mkdir -p $(PKGREL); \
75
+ fi
76
+
77
+ @echo " >> setting directory permissions for $(PKGREL)"
78
+ @if [ ! -w $(PKGREL) ]; \
79
+ then \
80
+ chmod 755 $(PKGREL); \
81
+ fi
82
+
83
+ @echo "Packaging $(APPNAME) on host $(ROKU_DEV_TARGET)"
84
+ @read -p "Password: " REPLY ; echo $$REPLY | xargs -i curl -s -S -Fmysubmit=Package -Fapp_name=$(APPNAME)/$(VERSION) -Fpasswd={} -Fpkg_time=`expr \`date +%s\` \* 1000` "http://$(ROKU_DEV_TARGET)/plugin_package" | grep '^<font face=' | sed 's/.*href=\"\([^\"]*\)\".*/\1/' | sed 's#pkgs/##' | xargs -i curl -s -S -o $(PKGREL)/$(APPNAME)_{} http://$(ROKU_DEV_TARGET)/pkgs/{}
85
+
86
+ @echo "*** Package $(APPNAME) complete ***"
87
+ remove:
88
+ @echo "Removing $(APPNAME) from host $(ROKU_DEV_TARGET)"
89
+ @curl -s -S -F "mysubmit=Delete" -F "archive=" -F "passwd=" http://$(ROKU_DEV_TARGET)/plugin_install | grep "<font color" | sed "s/<font color=\"red\">//"
@@ -0,0 +1,9 @@
1
+ title=Syndicate
2
+ subtitle=
3
+ mm_icon_focus_hd=pkg:/images/logo-hd.jpg
4
+ mm_icon_side_hd=pkg:/images/logo-hd.jpg
5
+ mm_icon_focus_sd=pkg:/images/logo-sd.jpg
6
+ mm_icon_side_sd=pkg:/images/logo-sd.jpg
7
+ major_version=1
8
+ minor_version=0
9
+ build_version=00001
@@ -0,0 +1,13 @@
1
+ Sub Main()
2
+
3
+ 'initialize theme attributes like titles, logos and overhang color
4
+ initTheme()
5
+
6
+ 'So the app launches right away instead of waiting to parse xml
7
+ screenFacade = CreateObject("roPosterScreen")
8
+ screenFacade.show()
9
+
10
+ 'prepare the screen for display and get ready to begin
11
+ url = "http://10.0.1.5:3000/d/Users/bmckim/Desktop/"
12
+ showPosterScreen(prePosterScreen("", ""), url)
13
+ End Sub
@@ -0,0 +1,150 @@
1
+ '**********************************************************
2
+ '** Video Player Example Application - General Dialogs
3
+ '** November 2009
4
+ '** Copyright (c) 2009 Roku Inc. All Rights Reserved.
5
+ '**********************************************************
6
+
7
+ '******************************************************
8
+ 'Show basic message dialog without buttons
9
+ 'Dialog remains up until caller releases the returned object
10
+ '******************************************************
11
+
12
+ Function ShowPleaseWait(title As dynamic, text As dynamic) As Object
13
+ if not isstr(title) title = ""
14
+ if not isstr(text) text = ""
15
+
16
+ port = CreateObject("roMessagePort")
17
+ dialog = invalid
18
+
19
+ 'the OneLineDialog renders a single line of text better
20
+ 'than the MessageDialog.
21
+ if text = ""
22
+ dialog = CreateObject("roOneLineDialog")
23
+ else
24
+ dialog = CreateObject("roMessageDialog")
25
+ dialog.SetText(text)
26
+ endif
27
+
28
+ dialog.SetMessagePort(port)
29
+
30
+ dialog.SetTitle(title)
31
+ dialog.ShowBusyAnimation()
32
+ dialog.Show()
33
+ return dialog
34
+ End Function
35
+
36
+ '******************************************************
37
+ 'Retrieve text for connection failed
38
+ '******************************************************
39
+
40
+ Function GetConnectionFailedText() as String
41
+ return "We were unable to connect to the service. Please try again in a few minutes."
42
+ End Function
43
+
44
+ '******************************************************
45
+ 'Show connection error dialog
46
+ '
47
+ 'Parameter: retry t/f - offer retry option
48
+ 'Return 0 = retry, 1 = back
49
+ '******************************************************
50
+
51
+ Function ShowConnectionFailedRetry() as dynamic
52
+ Dbg("Connection Failed Retry")
53
+ title = "Can't connect to video service"
54
+ text = GetConnectionFailedText()
55
+ return ShowDialog2Buttons(title, text, "try again", "back")
56
+ End Function
57
+
58
+ '******************************************************
59
+ 'Show Amzon connection error dialog with only an OK button
60
+ '******************************************************
61
+
62
+ Sub ShowConnectionFailed()
63
+ Dbg("Connection Failed")
64
+ title = "Can't connect to video service"
65
+ text = GetConnectionFailedText()
66
+ ShowErrorDialog(text, title)
67
+ End Sub
68
+
69
+ '******************************************************
70
+ 'Show error dialog with OK button
71
+ '******************************************************
72
+
73
+ Sub ShowErrorDialog(text As dynamic, title=invalid as dynamic)
74
+ if not isstr(text) text = "Unspecified error"
75
+ if not isstr(title) title = ""
76
+ ShowDialog1Button(title, text, "Done")
77
+ End Sub
78
+
79
+ '******************************************************
80
+ 'Show 1 button dialog
81
+ 'Return: nothing
82
+ '******************************************************
83
+
84
+ Sub ShowDialog1Button(title As dynamic, text As dynamic, but1 As String)
85
+ if not isstr(title) title = ""
86
+ if not isstr(text) text = ""
87
+
88
+ Dbg("DIALOG1: ", title + " - " + text)
89
+
90
+ port = CreateObject("roMessagePort")
91
+ dialog = CreateObject("roMessageDialog")
92
+ dialog.SetMessagePort(port)
93
+
94
+ dialog.SetTitle(title)
95
+ dialog.SetText(text)
96
+ dialog.AddButton(0, but1)
97
+ dialog.Show()
98
+
99
+ while true
100
+ dlgMsg = wait(0, dialog.GetMessagePort())
101
+
102
+ if type(dlgMsg) = "roMessageDialogEvent"
103
+ if dlgMsg.isScreenClosed()
104
+ print "Screen closed"
105
+ return
106
+ else if dlgMsg.isButtonPressed()
107
+ print "Button pressed: "; dlgMsg.GetIndex(); " " dlgMsg.GetData()
108
+ return
109
+ endif
110
+ endif
111
+ end while
112
+ End Sub
113
+
114
+ '******************************************************
115
+ 'Show 2 button dialog
116
+ 'Return: 0=first button or screen closed, 1=second button
117
+ '******************************************************
118
+
119
+ Function ShowDialog2Buttons(title As dynamic, text As dynamic, but1 As String, but2 As String) As Integer
120
+ if not isstr(title) title = ""
121
+ if not isstr(text) text = ""
122
+
123
+ Dbg("DIALOG2: ", title + " - " + text)
124
+
125
+ port = CreateObject("roMessagePort")
126
+ dialog = CreateObject("roMessageDialog")
127
+ dialog.SetMessagePort(port)
128
+
129
+ dialog.SetTitle(title)
130
+ dialog.SetText(text)
131
+ dialog.AddButton(0, but1)
132
+ dialog.AddButton(1, but2)
133
+ dialog.Show()
134
+
135
+ while true
136
+ dlgMsg = wait(0, dialog.GetMessagePort())
137
+
138
+ if type(dlgMsg) = "roMessageDialogEvent"
139
+ if dlgMsg.isScreenClosed()
140
+ print "Screen closed"
141
+ dialog = invalid
142
+ return 0
143
+ else if dlgMsg.isButtonPressed()
144
+ print "Button pressed: "; dlgMsg.GetIndex(); " " dlgMsg.GetData()
145
+ dialog = invalid
146
+ return dlgMsg.GetIndex()
147
+ endif
148
+ endif
149
+ end while
150
+ End Function
@@ -0,0 +1,681 @@
1
+ '**********************************************************
2
+ '** Video Player Example Application - General Utilities
3
+ '** November 2009
4
+ '** Copyright (c) 2009 Roku Inc. All Rights Reserved.
5
+ '**********************************************************
6
+
7
+ '******************************************************
8
+ 'Registry Helper Functions
9
+ '******************************************************
10
+ Function RegRead(key, section=invalid)
11
+ if section = invalid then section = "Default"
12
+ sec = CreateObject("roRegistrySection", section)
13
+ if sec.Exists(key) then return sec.Read(key)
14
+ return invalid
15
+ End Function
16
+
17
+ Function RegWrite(key, val, section=invalid)
18
+ if section = invalid then section = "Default"
19
+ sec = CreateObject("roRegistrySection", section)
20
+ sec.Write(key, val)
21
+ sec.Flush() 'commit it
22
+ End Function
23
+
24
+ Function RegDelete(key, section=invalid)
25
+ if section = invalid then section = "Default"
26
+ sec = CreateObject("roRegistrySection", section)
27
+ sec.Delete(key)
28
+ sec.Flush()
29
+ End Function
30
+
31
+
32
+ '******************************************************
33
+ 'Insertion Sort
34
+ 'Will sort an array directly, or use a key function
35
+ '******************************************************
36
+ Sub Sort(A as Object, key=invalid as dynamic)
37
+
38
+ if type(A)<>"roArray" then return
39
+
40
+ if (key=invalid) then
41
+ for i = 1 to A.Count()-1
42
+ value = A[i]
43
+ j = i-1
44
+ while j>= 0 and A[j] > value
45
+ A[j + 1] = A[j]
46
+ j = j-1
47
+ end while
48
+ A[j+1] = value
49
+ next
50
+
51
+ else
52
+ if type(key)<>"Function" then return
53
+ for i = 1 to A.Count()-1
54
+ valuekey = key(A[i])
55
+ value = A[i]
56
+ j = i-1
57
+ while j>= 0 and key(A[j]) > valuekey
58
+ A[j + 1] = A[j]
59
+ j = j-1
60
+ end while
61
+ A[j+1] = value
62
+ next
63
+
64
+ end if
65
+
66
+ End Sub
67
+
68
+
69
+ '******************************************************
70
+ 'Convert anything to a string
71
+ '
72
+ 'Always returns a string
73
+ '******************************************************
74
+ Function tostr(any)
75
+ ret = AnyToString(any)
76
+ if ret = invalid ret = type(any)
77
+ if ret = invalid ret = "unknown" 'failsafe
78
+ return ret
79
+ End Function
80
+
81
+
82
+ '******************************************************
83
+ 'Get a " char as a string
84
+ '******************************************************
85
+ Function Quote()
86
+ q$ = Chr(34)
87
+ return q$
88
+ End Function
89
+
90
+
91
+ '******************************************************
92
+ 'isxmlelement
93
+ '
94
+ 'Determine if the given object supports the ifXMLElement interface
95
+ '******************************************************
96
+ Function isxmlelement(obj as dynamic) As Boolean
97
+ if obj = invalid return false
98
+ if GetInterface(obj, "ifXMLElement") = invalid return false
99
+ return true
100
+ End Function
101
+
102
+
103
+ '******************************************************
104
+ 'islist
105
+ '
106
+ 'Determine if the given object supports the ifList interface
107
+ '******************************************************
108
+ Function islist(obj as dynamic) As Boolean
109
+ if obj = invalid return false
110
+ if GetInterface(obj, "ifArray") = invalid return false
111
+ return true
112
+ End Function
113
+
114
+
115
+ '******************************************************
116
+ 'isint
117
+ '
118
+ 'Determine if the given object supports the ifInt interface
119
+ '******************************************************
120
+ Function isint(obj as dynamic) As Boolean
121
+ if obj = invalid return false
122
+ if GetInterface(obj, "ifInt") = invalid return false
123
+ return true
124
+ End Function
125
+
126
+ '******************************************************
127
+ ' validstr
128
+ '
129
+ ' always return a valid string. if the argument is
130
+ ' invalid or not a string, return an empty string
131
+ '******************************************************
132
+ Function validstr(obj As Dynamic) As String
133
+ if isnonemptystr(obj) return obj
134
+ return ""
135
+ End Function
136
+
137
+
138
+ '******************************************************
139
+ 'isstr
140
+ '
141
+ 'Determine if the given object supports the ifString interface
142
+ '******************************************************
143
+ Function isstr(obj as dynamic) As Boolean
144
+ if obj = invalid return false
145
+ if GetInterface(obj, "ifString") = invalid return false
146
+ return true
147
+ End Function
148
+
149
+
150
+ '******************************************************
151
+ 'isnonemptystr
152
+ '
153
+ 'Determine if the given object supports the ifString interface
154
+ 'and returns a string of non zero length
155
+ '******************************************************
156
+ Function isnonemptystr(obj)
157
+ if isnullorempty(obj) return false
158
+ return true
159
+ End Function
160
+
161
+
162
+ '******************************************************
163
+ 'isnullorempty
164
+ '
165
+ 'Determine if the given object is invalid or supports
166
+ 'the ifString interface and returns a string of non zero length
167
+ '******************************************************
168
+ Function isnullorempty(obj)
169
+ if obj = invalid return true
170
+ if not isstr(obj) return true
171
+ if Len(obj) = 0 return true
172
+ return false
173
+ End Function
174
+
175
+
176
+ '******************************************************
177
+ 'isbool
178
+ '
179
+ 'Determine if the given object supports the ifBoolean interface
180
+ '******************************************************
181
+ Function isbool(obj as dynamic) As Boolean
182
+ if obj = invalid return false
183
+ if GetInterface(obj, "ifBoolean") = invalid return false
184
+ return true
185
+ End Function
186
+
187
+
188
+ '******************************************************
189
+ 'isfloat
190
+ '
191
+ 'Determine if the given object supports the ifFloat interface
192
+ '******************************************************
193
+ Function isfloat(obj as dynamic) As Boolean
194
+ if obj = invalid return false
195
+ if GetInterface(obj, "ifFloat") = invalid return false
196
+ return true
197
+ End Function
198
+
199
+
200
+ '******************************************************
201
+ 'strtobool
202
+ '
203
+ 'Convert string to boolean safely. Don't crash
204
+ 'Looks for certain string values
205
+ '******************************************************
206
+ Function strtobool(obj As dynamic) As Boolean
207
+ if obj = invalid return false
208
+ if type(obj) <> "roString" return false
209
+ o = strTrim(obj)
210
+ o = Lcase(o)
211
+ if o = "true" return true
212
+ if o = "t" return true
213
+ if o = "y" return true
214
+ if o = "1" return true
215
+ return false
216
+ End Function
217
+
218
+
219
+ '******************************************************
220
+ 'itostr
221
+ '
222
+ 'Convert int to string. This is necessary because
223
+ 'the builtin Stri(x) prepends whitespace
224
+ '******************************************************
225
+ Function itostr(i As Integer) As String
226
+ str = Stri(i)
227
+ return strTrim(str)
228
+ End Function
229
+
230
+
231
+ '******************************************************
232
+ 'Get remaining hours from a total seconds
233
+ '******************************************************
234
+ Function hoursLeft(seconds As Integer) As Integer
235
+ hours% = seconds / 3600
236
+ return hours%
237
+ End Function
238
+
239
+
240
+ '******************************************************
241
+ 'Get remaining minutes from a total seconds
242
+ '******************************************************
243
+ Function minutesLeft(seconds As Integer) As Integer
244
+ hours% = seconds / 3600
245
+ mins% = seconds - (hours% * 3600)
246
+ mins% = mins% / 60
247
+ return mins%
248
+ End Function
249
+
250
+
251
+ '******************************************************
252
+ 'Pluralize simple strings like "1 minute" or "2 minutes"
253
+ '******************************************************
254
+ Function Pluralize(val As Integer, str As String) As String
255
+ ret = itostr(val) + " " + str
256
+ if val <> 1 ret = ret + "s"
257
+ return ret
258
+ End Function
259
+
260
+
261
+ '******************************************************
262
+ 'Trim a string
263
+ '******************************************************
264
+ Function strTrim(str As String) As String
265
+ st=CreateObject("roString")
266
+ st.SetString(str)
267
+ return st.Trim()
268
+ End Function
269
+
270
+
271
+ '******************************************************
272
+ 'Tokenize a string. Return roList of strings
273
+ '******************************************************
274
+ Function strTokenize(str As String, delim As String) As Object
275
+ st=CreateObject("roString")
276
+ st.SetString(str)
277
+ return st.Tokenize(delim)
278
+ End Function
279
+
280
+
281
+ '******************************************************
282
+ 'Replace substrings in a string. Return new string
283
+ '******************************************************
284
+ Function strReplace(basestr As String, oldsub As String, newsub As String) As String
285
+ newstr = ""
286
+
287
+ i = 1
288
+ while i <= Len(basestr)
289
+ x = Instr(i, basestr, oldsub)
290
+ if x = 0 then
291
+ newstr = newstr + Mid(basestr, i)
292
+ exit while
293
+ endif
294
+
295
+ if x > i then
296
+ newstr = newstr + Mid(basestr, i, x-i)
297
+ i = x
298
+ endif
299
+
300
+ newstr = newstr + newsub
301
+ i = i + Len(oldsub)
302
+ end while
303
+
304
+ return newstr
305
+ End Function
306
+
307
+
308
+ '******************************************************
309
+ 'Get all XML subelements by name
310
+ '
311
+ 'return list of 0 or more elements
312
+ '******************************************************
313
+ Function GetXMLElementsByName(xml As Object, name As String) As Object
314
+ list = CreateObject("roArray", 100, true)
315
+ if islist(xml.GetBody()) = false return list
316
+
317
+ for each e in xml.GetBody()
318
+ if e.GetName() = name then
319
+ list.Push(e)
320
+ endif
321
+ next
322
+
323
+ return list
324
+ End Function
325
+
326
+
327
+ '******************************************************
328
+ 'Get all XML subelement's string bodies by name
329
+ '
330
+ 'return list of 0 or more strings
331
+ '******************************************************
332
+ Function GetXMLElementBodiesByName(xml As Object, name As String) As Object
333
+ list = CreateObject("roArray", 100, true)
334
+ if islist(xml.GetBody()) = false return list
335
+
336
+ for each e in xml.GetBody()
337
+ if e.GetName() = name then
338
+ b = e.GetBody()
339
+ if type(b) = "roString" list.Push(b)
340
+ endif
341
+ next
342
+
343
+ return list
344
+ End Function
345
+
346
+
347
+ '******************************************************
348
+ 'Get first XML subelement by name
349
+ '
350
+ 'return invalid if not found, else the element
351
+ '******************************************************
352
+ Function GetFirstXMLElementByName(xml As Object, name As String) As dynamic
353
+ if islist(xml.GetBody()) = false return invalid
354
+
355
+ for each e in xml.GetBody()
356
+ if e.GetName() = name return e
357
+ next
358
+
359
+ return invalid
360
+ End Function
361
+
362
+
363
+ '******************************************************
364
+ 'Get first XML subelement's string body by name
365
+ '
366
+ 'return invalid if not found, else the subelement's body string
367
+ '******************************************************
368
+ Function GetFirstXMLElementBodyStringByName(xml As Object, name As String) As dynamic
369
+ e = GetFirstXMLElementByName(xml, name)
370
+ if e = invalid return invalid
371
+ if type(e.GetBody()) <> "roString" return invalid
372
+ return e.GetBody()
373
+ End Function
374
+
375
+
376
+ '******************************************************
377
+ 'Get the xml element as an integer
378
+ '
379
+ 'return invalid if body not a string, else the integer as converted by strtoi
380
+ '******************************************************
381
+ Function GetXMLBodyAsInteger(xml As Object) As dynamic
382
+ if type(xml.GetBody()) <> "roString" return invalid
383
+ return strtoi(xml.GetBody())
384
+ End Function
385
+
386
+
387
+ '******************************************************
388
+ 'Parse a string into a roXMLElement
389
+ '
390
+ 'return invalid on error, else the xml object
391
+ '******************************************************
392
+ Function ParseXML(str As String) As dynamic
393
+ if str = invalid return invalid
394
+ xml=CreateObject("roXMLElement")
395
+ if not xml.Parse(str) return invalid
396
+ return xml
397
+ End Function
398
+
399
+
400
+ '******************************************************
401
+ 'Get XML sub elements whose bodies are strings into an associative array.
402
+ 'subelements that are themselves parents are skipped
403
+ 'namespace :'s are replaced with _'s
404
+ '
405
+ 'So an XML element like...
406
+ '
407
+ '<blah>
408
+ ' <This>abcdefg</This>
409
+ ' <Sucks>xyz</Sucks>
410
+ ' <sub>
411
+ ' <sub2>
412
+ ' ....
413
+ ' </sub2>
414
+ ' </sub>
415
+ ' <ns:doh>homer</ns:doh>
416
+ '</blah>
417
+ '
418
+ 'returns an AA with:
419
+ '
420
+ 'aa.This = "abcdefg"
421
+ 'aa.Sucks = "xyz"
422
+ 'aa.ns_doh = "homer"
423
+ '
424
+ 'return an empty AA if nothing found
425
+ '******************************************************
426
+ Sub GetXMLintoAA(xml As Object, aa As Object)
427
+ for each e in xml.GetBody()
428
+ body = e.GetBody()
429
+ if type(body) = "roString" then
430
+ name = e.GetName()
431
+ name = strReplace(name, ":", "_")
432
+ aa.AddReplace(name, body)
433
+ endif
434
+ next
435
+ End Sub
436
+
437
+
438
+ '******************************************************
439
+ 'Walk an AA and print it
440
+ '******************************************************
441
+ Sub PrintAA(aa as Object)
442
+ print "---- AA ----"
443
+ if aa = invalid
444
+ print "invalid"
445
+ return
446
+ else
447
+ cnt = 0
448
+ for each e in aa
449
+ x = aa[e]
450
+ PrintAny(0, e + ": ", aa[e])
451
+ cnt = cnt + 1
452
+ next
453
+ if cnt = 0
454
+ PrintAny(0, "Nothing from for each. Looks like :", aa)
455
+ endif
456
+ endif
457
+ print "------------"
458
+ End Sub
459
+
460
+
461
+ '******************************************************
462
+ 'Walk a list and print it
463
+ '******************************************************
464
+ Sub PrintList(list as Object)
465
+ print "---- list ----"
466
+ PrintAnyList(0, list)
467
+ print "--------------"
468
+ End Sub
469
+
470
+
471
+ '******************************************************
472
+ 'Print an associativearray
473
+ '******************************************************
474
+ Sub PrintAnyAA(depth As Integer, aa as Object)
475
+ for each e in aa
476
+ x = aa[e]
477
+ PrintAny(depth, e + ": ", aa[e])
478
+ next
479
+ End Sub
480
+
481
+
482
+ '******************************************************
483
+ 'Print a list with indent depth
484
+ '******************************************************
485
+ Sub PrintAnyList(depth As Integer, list as Object)
486
+ i = 0
487
+ for each e in list
488
+ PrintAny(depth, "List(" + itostr(i) + ")= ", e)
489
+ i = i + 1
490
+ next
491
+ End Sub
492
+
493
+
494
+ '******************************************************
495
+ 'Print anything
496
+ '******************************************************
497
+ Sub PrintAny(depth As Integer, prefix As String, any As Dynamic)
498
+ if depth >= 10
499
+ print "**** TOO DEEP " + itostr(5)
500
+ return
501
+ endif
502
+ prefix = string(depth*2," ") + prefix
503
+ depth = depth + 1
504
+ str = AnyToString(any)
505
+ if str <> invalid
506
+ print prefix + str
507
+ return
508
+ endif
509
+ if type(any) = "roAssociativeArray"
510
+ print prefix + "(assocarr)..."
511
+ PrintAnyAA(depth, any)
512
+ return
513
+ endif
514
+ if islist(any) = true
515
+ print prefix + "(list of " + itostr(any.Count()) + ")..."
516
+ PrintAnyList(depth, any)
517
+ return
518
+ endif
519
+
520
+ print prefix + "?" + type(any) + "?"
521
+ End Sub
522
+
523
+
524
+ '******************************************************
525
+ 'Print an object as a string for debugging. If it is
526
+ 'very long print the first 500 chars.
527
+ '******************************************************
528
+ Sub Dbg(pre As Dynamic, o=invalid As Dynamic)
529
+ p = AnyToString(pre)
530
+ if p = invalid p = ""
531
+ if o = invalid o = ""
532
+ s = AnyToString(o)
533
+ if s = invalid s = "???: " + type(o)
534
+ if Len(s) > 4000
535
+ s = Left(s, 4000)
536
+ endif
537
+ print p + s
538
+ End Sub
539
+
540
+
541
+ '******************************************************
542
+ 'Try to convert anything to a string. Only works on simple items.
543
+ '
544
+ 'Test with this script...
545
+ '
546
+ ' s$ = "yo1"
547
+ ' ss = "yo2"
548
+ ' i% = 111
549
+ ' ii = 222
550
+ ' f! = 333.333
551
+ ' ff = 444.444
552
+ ' d# = 555.555
553
+ ' dd = 555.555
554
+ ' bb = true
555
+ '
556
+ ' so = CreateObject("roString")
557
+ ' so.SetString("strobj")
558
+ ' io = CreateObject("roInt")
559
+ ' io.SetInt(666)
560
+ ' tm = CreateObject("roTimespan")
561
+ '
562
+ ' Dbg("", s$ ) 'call the Dbg() function which calls AnyToString()
563
+ ' Dbg("", ss )
564
+ ' Dbg("", "yo3")
565
+ ' Dbg("", i% )
566
+ ' Dbg("", ii )
567
+ ' Dbg("", 2222 )
568
+ ' Dbg("", f! )
569
+ ' Dbg("", ff )
570
+ ' Dbg("", 3333.3333 )
571
+ ' Dbg("", d# )
572
+ ' Dbg("", dd )
573
+ ' Dbg("", so )
574
+ ' Dbg("", io )
575
+ ' Dbg("", bb )
576
+ ' Dbg("", true )
577
+ ' Dbg("", tm )
578
+ '
579
+ 'try to convert an object to a string. return invalid if can't
580
+ '******************************************************
581
+ Function AnyToString(any As Dynamic) As dynamic
582
+ if any = invalid return "invalid"
583
+ if isstr(any) return any
584
+ if isint(any) return itostr(any)
585
+ if isbool(any)
586
+ if any = true return "true"
587
+ return "false"
588
+ endif
589
+ if isfloat(any) return Str(any)
590
+ if type(any) = "roTimespan" return itostr(any.TotalMilliseconds()) + "ms"
591
+ return invalid
592
+ End Function
593
+
594
+
595
+ '******************************************************
596
+ 'Walk an XML tree and print it
597
+ '******************************************************
598
+ Sub PrintXML(element As Object, depth As Integer)
599
+ print tab(depth*3);"Name: [" + element.GetName() + "]"
600
+ if invalid <> element.GetAttributes() then
601
+ print tab(depth*3);"Attributes: ";
602
+ for each a in element.GetAttributes()
603
+ print a;"=";left(element.GetAttributes()[a], 4000);
604
+ if element.GetAttributes().IsNext() then print ", ";
605
+ next
606
+ print
607
+ endif
608
+
609
+ if element.GetBody()=invalid then
610
+ ' print tab(depth*3);"No Body"
611
+ else if type(element.GetBody())="roString" then
612
+ print tab(depth*3);"Contains string: [" + left(element.GetBody(), 4000) + "]"
613
+ else
614
+ print tab(depth*3);"Contains list:"
615
+ for each e in element.GetBody()
616
+ PrintXML(e, depth+1)
617
+ next
618
+ endif
619
+ print
620
+ end sub
621
+
622
+
623
+ '******************************************************
624
+ 'Dump the bytes of a string
625
+ '******************************************************
626
+ Sub DumpString(str As String)
627
+ print "DUMP STRING"
628
+ print "---------------------------"
629
+ print str
630
+ print "---------------------------"
631
+ l = Len(str)-1
632
+ i = 0
633
+ for i = 0 to l
634
+ c = Mid(str, i)
635
+ val = Asc(c)
636
+ print itostr(val)
637
+ next
638
+ print "---------------------------"
639
+ End Sub
640
+
641
+
642
+ '******************************************************
643
+ 'Validate parameter is the correct type
644
+ '******************************************************
645
+ Function validateParam(param As Object, paramType As String,functionName As String, allowInvalid = false) As Boolean
646
+ if type(param) = paramType then
647
+ return true
648
+ endif
649
+
650
+ if allowInvalid = true then
651
+ if type(param) = invalid then
652
+ return true
653
+ endif
654
+ endif
655
+
656
+ print "invalid parameter of type "; type(param); " for "; paramType; " in function "; functionName
657
+ return false
658
+ End Function
659
+
660
+ '**********************************************************
661
+ '** Video Player Example Application - DeviceInfo
662
+ '** November 2009
663
+ '** Copyright (c) 2009 Roku Inc. All Rights Reserved.
664
+ '**********************************************************
665
+
666
+ '******************************************************
667
+ 'Get our device version
668
+ '******************************************************
669
+
670
+ Function GetDeviceVersion()
671
+ return CreateObject("roDeviceInfo").GetVersion()
672
+ End Function
673
+
674
+ '******************************************************
675
+ 'Get our serial number
676
+ '******************************************************
677
+
678
+ Function GetDeviceESN()
679
+ return CreateObject("roDeviceInfo").GetDeviceUniqueId()
680
+ End Function
681
+