strelka 0.0.1pre4 → 0.0.1.pre129

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/History.rdoc +1 -1
  2. data/IDEAS.rdoc +62 -0
  3. data/Manifest.txt +38 -7
  4. data/README.rdoc +124 -5
  5. data/Rakefile +22 -6
  6. data/bin/leash +102 -157
  7. data/contrib/hoetemplate/.autotest.erb +23 -0
  8. data/contrib/hoetemplate/History.rdoc.erb +4 -0
  9. data/contrib/hoetemplate/Manifest.txt.erb +8 -0
  10. data/contrib/hoetemplate/README.rdoc.erb +17 -0
  11. data/contrib/hoetemplate/Rakefile.erb +24 -0
  12. data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
  13. data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
  14. data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
  15. data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
  16. data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
  17. data/data/strelka/apps/hello-world +30 -0
  18. data/lib/strelka/app/defaultrouter.rb +49 -30
  19. data/lib/strelka/app/errors.rb +121 -0
  20. data/lib/strelka/app/exclusiverouter.rb +40 -0
  21. data/lib/strelka/app/filters.rb +18 -7
  22. data/lib/strelka/app/negotiation.rb +122 -0
  23. data/lib/strelka/app/parameters.rb +171 -14
  24. data/lib/strelka/app/paramvalidator.rb +751 -0
  25. data/lib/strelka/app/plugins.rb +66 -46
  26. data/lib/strelka/app/restresources.rb +499 -0
  27. data/lib/strelka/app/router.rb +73 -0
  28. data/lib/strelka/app/routing.rb +140 -18
  29. data/lib/strelka/app/templating.rb +12 -3
  30. data/lib/strelka/app.rb +174 -24
  31. data/lib/strelka/constants.rb +0 -20
  32. data/lib/strelka/exceptions.rb +29 -0
  33. data/lib/strelka/httprequest/acceptparams.rb +377 -0
  34. data/lib/strelka/httprequest/negotiation.rb +257 -0
  35. data/lib/strelka/httprequest.rb +155 -7
  36. data/lib/strelka/httpresponse/negotiation.rb +579 -0
  37. data/lib/strelka/httpresponse.rb +140 -0
  38. data/lib/strelka/logging.rb +4 -1
  39. data/lib/strelka/mixins.rb +53 -0
  40. data/lib/strelka.rb +22 -1
  41. data/spec/data/error.tmpl +1 -0
  42. data/spec/lib/constants.rb +0 -1
  43. data/spec/lib/helpers.rb +21 -0
  44. data/spec/strelka/app/defaultrouter_spec.rb +41 -35
  45. data/spec/strelka/app/errors_spec.rb +212 -0
  46. data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
  47. data/spec/strelka/app/filters_spec.rb +196 -0
  48. data/spec/strelka/app/negotiation_spec.rb +73 -0
  49. data/spec/strelka/app/parameters_spec.rb +149 -0
  50. data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
  51. data/spec/strelka/app/plugins_spec.rb +26 -19
  52. data/spec/strelka/app/restresources_spec.rb +393 -0
  53. data/spec/strelka/app/router_spec.rb +63 -0
  54. data/spec/strelka/app/routing_spec.rb +183 -9
  55. data/spec/strelka/app/templating_spec.rb +1 -2
  56. data/spec/strelka/app_spec.rb +265 -32
  57. data/spec/strelka/exceptions_spec.rb +53 -0
  58. data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
  59. data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
  60. data/spec/strelka/httprequest_spec.rb +204 -14
  61. data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
  62. data/spec/strelka/httpresponse_spec.rb +114 -0
  63. data/spec/strelka/mixins_spec.rb +99 -0
  64. data.tar.gz.sig +1 -0
  65. metadata +175 -79
  66. metadata.gz.sig +2 -0
  67. data/IDEAS.textile +0 -174
  68. data/data/strelka/apps/strelka-admin +0 -65
  69. data/data/strelka/apps/strelka-setup +0 -26
  70. data/data/strelka/bootstrap-config.rb +0 -34
  71. data/data/strelka/templates/admin/console.tmpl +0 -21
  72. data/data/strelka/templates/layout.tmpl +0 -30
  73. data/lib/strelka/process.rb +0 -19
data/bin/leash CHANGED
@@ -1,14 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'mongrel2'
4
- require 'mongrel2/config'
5
3
  require 'strelka'
6
-
7
- require 'pp'
8
- require 'fileutils'
9
- require 'shellwords'
10
- require 'tnetstring'
11
-
12
4
  require 'trollop'
13
5
  require 'highline'
14
6
 
@@ -26,74 +18,21 @@ class Strelka::LeashCommand
26
18
 
27
19
  # Make a HighLine color scheme
28
20
  COLOR_SCHEME = HighLine::ColorScheme.new do |scheme|
29
- scheme[:header] = [ :bold, :yellow ]
21
+ scheme[:header] = [ :bold, :yellow ]
30
22
  scheme[:subheader] = [ :bold, :white ]
31
- scheme[:key] = [ :white ]
32
- scheme[:value] = [ :bold, :white ]
33
- scheme[:error] = [ :red ]
23
+ scheme[:key] = [ :white ]
24
+ scheme[:value] = [ :bold, :white ]
25
+ scheme[:error] = [ :red ]
34
26
  scheme[:warning] = [ :yellow ]
35
27
  scheme[:message] = [ :reset ]
36
28
  end
37
29
 
38
30
 
39
- # Path to the default history file for 'shell' mode
40
- HISTORY_FILE = Pathname( "~/.leash.history" )
41
-
42
- # Number of items to store in history by default
43
- DEFAULT_HISTORY_SIZE = 100
44
-
45
- # The prompt the 'shell' mode should show
46
- PROMPT = 'leash> '
47
-
48
- # The data directory in the project if that exists, otherwise the gem datadir
49
- DATADIR = if File.directory?( 'data/strelka' )
50
- Pathname( 'data/strelka' )
51
- elsif path = Gem.datadir('strelka')
52
- Pathname( path )
53
- else
54
- raise ScriptError, "can't find the data directory!"
55
- end
56
-
57
-
58
31
  # Class instance variables
59
32
  @command_help = Hash.new {|h,k| h[k] = { :desc => nil, :usage => ''} }
60
33
  @prompt = @option_parser = nil
61
34
 
62
35
 
63
- ### Add a help string for the given +command+.
64
- def self::help( command, helpstring=nil )
65
- if helpstring
66
- @command_help[ command.to_sym ][:desc] = helpstring
67
- end
68
-
69
- return @command_help[ command.to_sym ][:desc]
70
- end
71
-
72
-
73
- ### Add/fetch the +usagestring+ for +command+.
74
- def self::usage( command, usagestring=nil )
75
- if usagestring
76
- prefix = usagestring[ /\A(\s+)/, 1 ]
77
- usagestring.gsub!( /^#{prefix}/m, '' ) if prefix
78
-
79
- @command_help[ command.to_sym ][:usage] = usagestring
80
- end
81
-
82
- return @command_help[ command.to_sym ][:usage]
83
- end
84
-
85
-
86
- ### Return the global Highline prompt object, creating it if necessary.
87
- def self::prompt
88
- unless @prompt
89
- @prompt = HighLine.new
90
- @prompt.wrap_at = @prompt.output_cols - 10
91
- end
92
-
93
- return @prompt
94
- end
95
-
96
-
97
36
  ### Run the utility with the given +args+.
98
37
  def self::run( args )
99
38
  HighLine.color_scheme = COLOR_SCHEME
@@ -147,7 +86,6 @@ class Strelka::LeashCommand
147
86
  def self::make_option_parser
148
87
  unless @option_parser
149
88
  progname = File.basename( $0 )
150
- default_configdb = Mongrel2::DEFAULT_CONFIG_URI
151
89
 
152
90
  # Make a list of the log level names and the available commands
153
91
  loglevels = Strelka::Logging::LOG_LEVELS.
@@ -157,15 +95,14 @@ class Strelka::LeashCommand
157
95
  command_table = self.make_command_table
158
96
 
159
97
  @option_parser = Trollop::Parser.new do
160
- banner "Take your Mongrel(2) for a walk:"
98
+ banner "Manage Strelka apps"
161
99
 
162
100
  text ''
163
101
  command_table.each {|line| text(line) }
164
102
  text ''
165
103
 
166
104
  text 'Global Options'
167
- opt :config, "Specify the configfile to use.",
168
- :default => DEFAULT_CONFIG_URI
105
+ opt :config, "Specify the config file to load."
169
106
  text ''
170
107
 
171
108
  text 'Other Options:'
@@ -179,6 +116,45 @@ class Strelka::LeashCommand
179
116
  end
180
117
 
181
118
 
119
+ ### Add a help string for the given +command+.
120
+ def self::help( command, helpstring=nil )
121
+ if helpstring
122
+ @command_help[ command.to_sym ][:desc] = helpstring
123
+ end
124
+
125
+ return @command_help[ command.to_sym ][:desc]
126
+ end
127
+
128
+
129
+ ### Add/fetch the +usagestring+ for +command+.
130
+ def self::usage( command, usagestring=nil )
131
+ if usagestring
132
+ prefix = usagestring[ /\A(\s+)/, 1 ]
133
+ usagestring.gsub!( /^#{prefix}/m, '' ) if prefix
134
+
135
+ @command_help[ command.to_sym ][:usage] = usagestring
136
+ end
137
+
138
+ return @command_help[ command.to_sym ][:usage]
139
+ end
140
+
141
+
142
+ ### Return the global Highline prompt object, creating it if necessary.
143
+ def self::prompt
144
+ unless @prompt
145
+ @prompt = HighLine.new
146
+
147
+ columns = @prompt.output_cols.nonzero? || 80
148
+ rows = @prompt.output_rows.nonzero? || 1000
149
+
150
+ @prompt.page_at = rows - 5
151
+ @prompt.wrap_at = columns - 2
152
+ end
153
+
154
+ return @prompt
155
+ end
156
+
157
+
182
158
  #################################################################
183
159
  ### I N S T A N C E M E T H O D S
184
160
  #################################################################
@@ -188,7 +164,6 @@ class Strelka::LeashCommand
188
164
  def initialize( options )
189
165
  Strelka.logger.formatter = Strelka::Logging::ColorFormatter.new( Strelka.logger )
190
166
  @options = options
191
- @shellmode = false
192
167
 
193
168
  if @options.debug
194
169
  $DEBUG = true
@@ -198,7 +173,6 @@ class Strelka::LeashCommand
198
173
  Strelka.logger.level = Strelka::Logging::LOG_LEVELS[ @options.loglevel ]
199
174
  end
200
175
 
201
- Mongrel2::Config.configure( :configdb => @options.config )
202
176
  end
203
177
 
204
178
 
@@ -209,9 +183,6 @@ class Strelka::LeashCommand
209
183
  # The Trollop options hash the command will read its configuration from
210
184
  attr_reader :options
211
185
 
212
- # True if running in shell mode
213
- attr_reader :shellmode
214
-
215
186
 
216
187
  # Delegate the instance #prompt method to the class method instead
217
188
  define_method( :prompt, &self.method(:prompt) )
@@ -264,84 +235,77 @@ class Strelka::LeashCommand
264
235
  usage :help, "[COMMAND]"
265
236
 
266
237
 
267
- ### The 'setup' command
268
- def setup_command( *args )
269
- port = args.shift || DEFAULT_ADMIN_PORT
270
- self.setup_bootstrap_config( port )
271
- m2pid = self.start_admin_mongrel2
272
- apppid = self.start_admin_app
238
+ ### The 'discover' command
239
+ def discover_command( *args )
240
+ header "Searching for Strelka applications..."
273
241
 
274
- header "Okay, point a browser at http://localhost:#{port}/"
242
+ paths = Strelka::App.discover_paths
243
+ if paths.empty?
244
+ message "None found."
245
+ else
246
+ paths.each do |gemname, paths|
247
+ message "Found:"
275
248
 
276
- rescue
277
- message "Killing admin mongrel2..."
278
- Process.kill( :TERM, m2pid ) if m2pid
249
+ subheader "#{gemname}:"
250
+ filenames = paths.map {|path| path.basename.to_s }
251
+ list( filenames )
252
+ end
253
+ end
254
+ end
255
+ help :discover, "Show available Strelka applications installed as gems."
279
256
 
280
- message "Killing admin app..."
281
- Process.kill( apppid, :TERM ) if apppid
282
257
 
283
- ensure
284
- results = Process.waitall
285
- message "Done: %p" % [ results ]
258
+ ### The 'setup' command
259
+ def setup_command( *args )
286
260
  end
287
261
  help :setup, "Set up a new Strelka environment and start the admin server."
288
- usage :setup, "[PORT]"
289
262
 
290
263
 
291
- ### Install a bootstrap config database for the admin server, which will run
292
- ### on localhost at the specified +port+.
293
- def setup_bootstrap_config( port )
294
- configfile = DATADIR + 'bootstrap-config.rb'
295
- runspace = Module.new do
296
- extend Mongrel2::Config::DSL, FileUtils::Verbose
297
- end
298
-
299
- header "Loading config from #{configfile}"
300
- source = configfile.read
301
- Mongrel2::Config.init_database!
302
- runspace.module_eval( source, configfile.to_s, 0 )
264
+ ### The 'start' command
265
+ def start_command( *args )
303
266
  end
267
+ help :start, "Start the web adminstration app"
304
268
 
305
269
 
306
- ### Start the Mongrel2 instance that serves as the front end of the admin server.
307
- def start_admin_mongrel2
308
- server = Mongrel2::Config.servers.find {|s| s.name == 'adminserver' } or
309
- raise ScriptError, "Ack! No server named 'adminserver' in #{Mongrel2::Config.pathname}"
310
-
311
- message "Starting mongrel2..."
312
- cmd = [ 'mongrel2', 'mongrel2 (Strelka Admin)' ]
313
- args = [ Mongrel2::Config.pathname.to_s, server.uuid ]
314
-
315
- return spawn( cmd, *args )
270
+ ### The 'version' command
271
+ def version_command( *args )
272
+ message( "<%= color 'Version:', :header %> " + Mongrel2.version_string(true) )
316
273
  end
274
+ help :version, "Prints the Ruby-Mongrel2 version."
317
275
 
318
276
 
319
- ### Start the admin app.
320
- def start_admin_app
321
- message "Starting up control app..."
322
-
323
- pid = fork do
324
- appsdir = DATADIR + 'apps'
325
- templatedir = DATADIR + 'templates'
326
- strelka_admin = appsdir + 'strelka-admin'
277
+ #
278
+ # Command functions
279
+ #
327
280
 
328
- Kernel.load( strelka_admin )
281
+ ### Install a bootstrap config database for the admin server.
282
+ def setup_bootstrap_config
283
+ Mongrel2::Config.init_database
329
284
 
330
- Inversion::Template.configure( :template_paths => [templatedir] )
331
- Strelka::AdminConsole.run( 'admin-console' )
285
+ if Mongrel2::Config::Server.by_uuid( ADMINSERVER_ID ).first
286
+ message "Admin server is already configured"
287
+ if !self.prompt.agree( "Replace the existing config? ", true )
288
+ message "Okay, keeping the existing config."
289
+ return
290
+ end
291
+ end
332
292
 
333
- exit!
293
+ configfile = DATADIR + 'bootstrap-config.rb'
294
+ runspace = Module.new do
295
+ extend Mongrel2::Config::DSL, FileUtils::Verbose
334
296
  end
335
297
 
336
- return pid
298
+ header "Installing admin server config from #{configfile}"
299
+ source = configfile.read
300
+ runspace.module_eval( source, configfile.to_s, 1 )
337
301
  end
338
302
 
339
303
 
340
- ### The 'version' command
341
- def version_command( *args )
342
- message( "<%= color 'Version:', :header %> " + Mongrel2.version_string(true) )
304
+ ### Set up the mongrel2 chroot directory for Strelka's adminserver by copying static
305
+ ### files, and creating the necessary directories. This depends on the configuration
306
+ ### being installed.
307
+ def setup_runtime_directory
343
308
  end
344
- help :version, "Prints the Ruby-Mongrel2 version."
345
309
 
346
310
 
347
311
  #
@@ -360,42 +324,23 @@ class Strelka::LeashCommand
360
324
  end
361
325
 
362
326
 
363
- ### Output the given +text+ highlighted as an error.
364
- def error( text )
365
- message( self.prompt.color(text, :error) )
327
+ ### Output the given +text+ highlighted as a subheader.
328
+ def subheader( text )
329
+ message( self.prompt.color(text, :subheader) )
366
330
  end
367
331
 
368
332
 
369
- ### Read command line history from HISTORY_FILE
370
- def read_history
371
- histfile = HISTORY_FILE.expand_path
372
-
373
- if histfile.exist?
374
- lines = histfile.readlines.collect {|line| line.chomp }
375
- self.log.debug "Read %d saved history commands from %s." % [ lines.length, histfile ]
376
- Readline::HISTORY.push( *lines )
377
- else
378
- self.log.debug "History file '%s' was empty or non-existant." % [ histfile ]
379
- end
333
+ ### Output the given +text+ highlighted as an error.
334
+ def error( text )
335
+ message( self.prompt.color(text, :error) )
380
336
  end
381
337
 
382
338
 
383
- ### Save command line history to HISTORY_FILE
384
- def save_history
385
- histfile = HISTORY_FILE.expand_path
386
-
387
- lines = Readline::HISTORY.to_a.reverse.uniq.reverse
388
- lines = lines[ -DEFAULT_HISTORY_SIZE, DEFAULT_HISTORY_SIZE ] if
389
- lines.length > DEFAULT_HISTORY_SIZE
390
-
391
- self.log.debug "Saving %d history lines to %s." % [ lines.length, histfile ]
392
-
393
- histfile.open( File::WRONLY|File::CREAT|File::TRUNC ) do |ofh|
394
- ofh.puts( *lines )
395
- end
339
+ ### Output the given +items+ as a columnar list.
340
+ def list( *items )
341
+ message( self.prompt.list(items.flatten.compact.map(&:to_s), :columns_down) )
396
342
  end
397
343
 
398
-
399
344
  end # class Strelka::LeashCommand
400
345
 
401
346
 
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
@@ -0,0 +1,4 @@
1
+ ## 0.0.1 [<%= Time.now.strftime("%Y-%m-%d") %>] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Initial release.
4
+
@@ -0,0 +1,8 @@
1
+ History.rdoc
2
+ README.rdoc
3
+ Rakefile
4
+ data/<%= file_name %>/apps/<%= file_name %>_app
5
+ data/<%= file_name %>/templates/layout.tmpl
6
+ data/<%= file_name %>/templates/top.tmpl
7
+ lib/<%= file_name %>.rb
8
+ spec/<%= file_name %>_spec.rb
@@ -0,0 +1,17 @@
1
+ = <%= project %>
2
+
3
+ * <%= XIF %> (url)
4
+
5
+ == Description
6
+
7
+ <%= XIF %> (describe your package)
8
+
9
+ == Installation
10
+
11
+ gem install <%= project %>
12
+
13
+ == License
14
+
15
+ Copyright (c) <%= Time.now.strftime("%Y") %>, <%= XIF %>
16
+ All rights reserved.
17
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'hoe'
5
+ rescue LoadError
6
+ abort "This Rakefile requires 'hoe' (gem install hoe)"
7
+ end
8
+
9
+ # Sign gems
10
+ Hoe.plugin :signing
11
+
12
+ Hoe.spec '<%= project %>' do
13
+ self.readme_file = 'README.rdoc'
14
+ self.history_file = 'History.rdoc'
15
+ self.extra_rdoc_files = FileList[ '*.rdoc' ]
16
+
17
+ self.developer '<%= XIF %>', '<%= XIF %>' # (name, email)
18
+
19
+ self.dependency 'strelka', '~> 0.1'
20
+ self.dependency 'rspec', '~> 2.7', :developer
21
+
22
+ self.require_ruby_version( '~> 1.9' )
23
+ end
24
+
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'strelka'
4
+
5
+
6
+ # The main <%= project %> application
7
+ class <%= klass %>::Application < Strelka::App
8
+
9
+ # Uncomment this if you need an appid other than
10
+ # '<%= klass.gsub(/[^[:alnum:]]+/, '-').downcase %>-application'.
11
+ #ID = '<%= XIF %>' # (set the app id of the main application)
12
+
13
+ # Load some plugins
14
+ plugins :templating, :routing
15
+
16
+ # By default, responses are HTML
17
+ default_type 'text/html'
18
+
19
+ # Templating -- wrap everything in the layout
20
+ layout 'layout.tmpl'
21
+ templates \
22
+ :top => 'top.tmpl'
23
+
24
+
25
+ # GET request handler -- handles all GET requests
26
+ get do |req|
27
+ # Use the 'top' template for the body, wrapped in the 'layout' template
28
+ return :top
29
+ end
30
+
31
+
32
+ end # class <%= klass %>::Application
33
+
34
+
35
+ <%= klass %>::Application.run if __FILE__ == $0
36
+
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ <%= XIF %> (application title)
6
+ </title>
7
+ </head>
8
+ <body>
9
+ <!-- <%= XIF %> (set up the main layout template) -->
10
+ <?attr body ?>
11
+ </body>
12
+ </html>
13
+
@@ -0,0 +1,8 @@
1
+ <!-- <%= XIF %> (set up the main content template) -->
2
+
3
+ <p>Your request looked this:</p>
4
+
5
+ <pre><code>
6
+ <?prettyprint request ?>
7
+ </code></pre>
8
+
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # <%= XIF %> (top-level documentation)
4
+ #
5
+ # == Author/s
6
+ #
7
+ # * Michael Granger <ged@FaerieMUD.org>
8
+ #
9
+ module <%= klass %>
10
+
11
+ # Library version constant
12
+ VERSION = '0.0.1'
13
+
14
+ # Version-control revision constant
15
+ REVISION = %q$Revision: c21afe9776d3 $
16
+
17
+ end # module <%= klass %>
18
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname( __FILE__ ).dirname.parent
6
+ libdir = basedir + 'lib'
7
+
8
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
9
+ }
10
+
11
+ require 'rspec'
12
+ require '<%= file_name %>'
13
+
14
+ describe <%= klass %> do
15
+
16
+ it "is well-tested" do
17
+ fail "it isn't"
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'strelka'
4
+
5
+ # The Strelka admin web console.
6
+ class HelloWorldApp < Strelka::App
7
+
8
+ # The route appid that will configure this app if no appid is specified
9
+ ID = 'hello-world'
10
+
11
+
12
+ # Use Sinatra-like routing
13
+ plugins :routing
14
+
15
+ # Set responses to plaintext if they don't specify differently
16
+ default_type 'text/plain'
17
+
18
+ # Handle all GET requests the same way
19
+ get do |req|
20
+ res = req.response
21
+ res.status = HTTP::OK
22
+ res << 'Hello, world!'
23
+ return res
24
+ end
25
+
26
+ end # class HelloWorldApp
27
+
28
+
29
+ # Run the app
30
+ HelloWorldApp.run if __FILE__ == $0