spiderfw 0.6.23 → 0.6.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGELOG +10 -1
  2. data/README.rdoc +1 -1
  3. data/VERSION +1 -1
  4. data/apps/config_editor/_init.rb +1 -2
  5. data/apps/config_editor/controllers/config_editor_controller.rb +1 -7
  6. data/apps/core/admin/controllers/admin_controller.rb +1 -1
  7. data/apps/core/admin/public/css/sass/admin.css +35 -31
  8. data/apps/core/admin/public/sass/admin.scss +6 -1
  9. data/apps/core/components/widgets/crud/crud.shtml +2 -2
  10. data/apps/core/components/widgets/table/table.rb +5 -5
  11. data/apps/core/forms/tags/element_row.erb +15 -10
  12. data/apps/core/forms/widgets/form/form.rb +35 -22
  13. data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +2 -2
  14. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +2 -2
  15. data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +2 -2
  16. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  17. data/apps/core/forms/widgets/inputs/input/input.shtml +2 -2
  18. data/apps/core/forms/widgets/inputs/password/password.shtml +2 -2
  19. data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +1 -1
  20. data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
  21. data/apps/core/forms/widgets/inputs/text/text.shtml +2 -2
  22. data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +2 -2
  23. data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +1 -1
  24. data/blueprints/home/config.ru +8 -0
  25. data/lib/spiderfw/app.rb +416 -224
  26. data/lib/spiderfw/cmd/commands/app.rb +243 -239
  27. data/lib/spiderfw/cmd/commands/cert.rb +421 -417
  28. data/lib/spiderfw/cmd/commands/config.rb +85 -82
  29. data/lib/spiderfw/cmd/commands/console.rb +64 -40
  30. data/lib/spiderfw/cmd/commands/content.rb +29 -25
  31. data/lib/spiderfw/cmd/commands/create.rb +58 -54
  32. data/lib/spiderfw/cmd/commands/model.rb +118 -114
  33. data/lib/spiderfw/cmd/commands/setup.rb +55 -51
  34. data/lib/spiderfw/cmd/commands/test.rb +63 -59
  35. data/lib/spiderfw/cmd/commands/webserver.rb +56 -51
  36. data/lib/spiderfw/config/options/spider.rb +4 -3
  37. data/lib/spiderfw/controller/controller.rb +2 -0
  38. data/lib/spiderfw/controller/http_controller.rb +1 -2
  39. data/lib/spiderfw/controller/mixins/static_content.rb +3 -3
  40. data/lib/spiderfw/controller/mixins/visual.rb +30 -15
  41. data/lib/spiderfw/controller/response.rb +84 -0
  42. data/lib/spiderfw/controller/session/file_session.rb +2 -2
  43. data/lib/spiderfw/http/adapters/rack.rb +12 -13
  44. data/lib/spiderfw/http/server.rb +80 -46
  45. data/lib/spiderfw/i18n/cldr.rb +6 -9
  46. data/lib/spiderfw/model/base_model.rb +103 -23
  47. data/lib/spiderfw/model/condition.rb +110 -25
  48. data/lib/spiderfw/model/mappers/db_mapper.rb +14 -6
  49. data/lib/spiderfw/model/mappers/mapper.rb +440 -197
  50. data/lib/spiderfw/model/model.rb +105 -21
  51. data/lib/spiderfw/model/model_hash.rb +9 -1
  52. data/lib/spiderfw/model/query.rb +50 -9
  53. data/lib/spiderfw/model/query_set.rb +211 -44
  54. data/lib/spiderfw/model/request.rb +28 -21
  55. data/lib/spiderfw/model/storage/base_storage.rb +125 -10
  56. data/lib/spiderfw/model/storage/db/db_storage.rb +7 -4
  57. data/lib/spiderfw/model/storage.rb +8 -1
  58. data/lib/spiderfw/setup/spider_setup_wizard.rb +9 -7
  59. data/lib/spiderfw/spider.rb +270 -43
  60. data/lib/spiderfw/templates/layout.rb +9 -4
  61. data/lib/spiderfw/templates/resources/sass.rb +3 -2
  62. data/lib/spiderfw/templates/template.rb +1 -0
  63. data/lib/spiderfw/utils/annotations.rb +3 -1
  64. data/lib/spiderfw/utils/logger.rb +1 -1
  65. data/lib/spiderfw/utils/monkey/symbol.rb +4 -2
  66. data/lib/spiderfw/utils/shared_store/file_shared_store.rb +2 -2
  67. data/lib/spiderfw/utils/thread_out.rb +3 -1
  68. data/public/css/error_page.css +83 -0
  69. data/public/js/error_page.js +5 -0
  70. data/spider.gemspec +4 -1
  71. data/templates/email/error.erb +9 -0
  72. metadata +28 -12
  73. data/apps/config_editor/widgets/edit_bool/edit_bool.rb +0 -8
  74. data/apps/config_editor/widgets/edit_bool/edit_bool.shtml +0 -5
@@ -1,6 +1,7 @@
1
1
  require 'spiderfw/env'
2
2
 
3
3
  require 'rubygems'
4
+ require 'etc'
4
5
  require 'backports'
5
6
  require 'find'
6
7
  require 'fileutils'
@@ -17,6 +18,10 @@ rescue LoadError
17
18
  end
18
19
 
19
20
 
21
+ # The main Spider module.
22
+ #
23
+ # It contains methods to manage the environment and the lifecycle of
24
+ # the application.
20
25
  module Spider
21
26
 
22
27
  @apps = {}; @apps_by_path = {}; @apps_by_short_name = {}; @loaded_apps = {}
@@ -28,14 +33,19 @@ module Spider
28
33
  # Everything here must be thread safe!!!
29
34
 
30
35
  # An instance of the shared logger.
36
+ # @return [Spider::Logger]
31
37
  attr_reader :logger
32
38
  # An hash of registered Spider::App, indexed by name.
39
+ # @return [Array]
33
40
  attr_reader :apps
34
41
  # An hash of registred Spider::App modules, indexed by path.
42
+ # @return [Hash]
35
43
  attr_reader :apps_by_path
36
44
  # An hash of registred Spider::App modules, indexed by short name (name without namespace).
45
+ # @return [Hash]
37
46
  attr_reader :apps_by_short_name
38
47
  # The current runmode (test, devel or production).
48
+ # @return [String]
39
49
  attr_reader :runmode
40
50
  # An hash of runtime paths.
41
51
  # :root:: The base runtime path.
@@ -46,19 +56,26 @@ module Spider
46
56
  # :var:: Var folder. Must be writable. Contains cache, logs, and other files written by the server.
47
57
  # :data:: Data folder. Holds static and dynamic files. Some subdirs may have to be writable.
48
58
  # :certs:: Certificates folder.
49
- # ::tmp:: Temp folder. Must be writable.
50
- # ::log:: Log location.
59
+ # :tmp:: Temp folder. Must be writable.
60
+ # :log:: Log location.
61
+ # @return [Hash]
51
62
  attr_reader :paths
52
63
  # Current Home
64
+ # @return [Spider::Home]
53
65
  attr_reader :home
54
66
  # Registered resource types
67
+ # @return [Array]
55
68
  attr_reader :resource_types
56
69
  # Main site
70
+ # @return [Site]
57
71
  attr_accessor :site
72
+
58
73
  attr_accessor :spawner
59
74
 
60
75
  # Initializes the runtime environment. This method is called when spider is required. Apps may implement
61
76
  # an app_init method, that will be called after Spider::init is done.
77
+ # @param [force=false] Force init, even if it is already done.
78
+ # @returns [true]
62
79
  def init(force=false)
63
80
  return if @init_done && !force
64
81
 
@@ -86,6 +103,8 @@ module Spider
86
103
  @init_done=true
87
104
  end
88
105
 
106
+ # Sets up GetText for each app, and runs app_init on them, if the app implement it.
107
+ # @returns [nil]
89
108
  def init_apps
90
109
  @apps.each do |name, mod|
91
110
  repos = []
@@ -106,10 +125,15 @@ module Spider
106
125
  end
107
126
  end
108
127
 
128
+ # @return [TrueClass|FalseClass] True if init has already been done
109
129
  def init_done?
110
130
  @init_done
111
131
  end
112
132
 
133
+ # Loads configuration, sets up Locale and GetText, sets paths and the default Logger.
134
+ # The runmode is also set at this phase, if it is defined as $SPIDER_RUNMODE or in configuration.
135
+ # @param [force=false] Force init_base, even if it is already done.
136
+ # @returns [true]
113
137
  def init_base(force=false)
114
138
  return if @init_base_done && !force
115
139
  l = Spider.locale.to_s
@@ -129,22 +153,22 @@ module Spider
129
153
  end
130
154
  @runmode = nil
131
155
  self.runmode = $SPIDER_RUNMODE if $SPIDER_RUNMODE
132
-
133
156
  load_configuration File.join($SPIDER_PATH, 'config')
157
+ user_rc = File.join(Etc.getpwuid.dir, '.spider.conf.yml')
158
+ if File.file?(user_rc)
159
+ load_configuration_file(user_rc)
160
+ end
134
161
  load_configuration File.join(@root, 'config')
162
+ self.runmode ||= $SPIDER_RUNMODE if $SPIDER_RUNMODE
135
163
  Locale.default = Spider.conf.get('i18n.default_locale')
136
164
  setup_env
137
165
  @logger = Spider::Logger
138
166
  @init_base_done = true
139
167
  end
140
168
 
141
- #
142
- # def stop
143
- # @apps.each do |name, mod|
144
- # mod.app_stop if mod.respond_to?(:app_stop)
145
- # end
146
- # end
147
-
169
+
170
+ # Creates runtime folders: 'tmp', 'var', 'var/memory' and 'var/data'
171
+ # @return [void]
148
172
  def setup_env
149
173
  unless File.exists?(File.join(Spider.paths[:root], 'init.rb'))
150
174
  raise "This command must be run from the root directory"
@@ -158,6 +182,7 @@ module Spider
158
182
 
159
183
 
160
184
  # Invoked before a long running service started. Apps may implement the app_startup method, that will be called.
185
+ # @return [void]
161
186
  def startup
162
187
  init
163
188
  setup_env
@@ -184,6 +209,13 @@ module Spider
184
209
  end
185
210
  end
186
211
 
212
+ # Called before the main process starts up.
213
+ #
214
+ # This happens, for example, when Spider server is started from command line; the main process can then
215
+ # spawn other processes, as supporting listeners or workers.
216
+ #
217
+ # Note that in some environments (e.g. Phusion Passenger) there will not be a main process, so
218
+ # this method will not be called.
187
219
  def main_process_startup
188
220
  if defined?(FSSM)
189
221
  monitor = FSSM::Monitor.new
@@ -229,21 +261,27 @@ module Spider
229
261
 
230
262
  end
231
263
 
264
+ # @param [Proc] proc A block that will be called when #main_process_startup is run
265
+ # @return [Proc] The passed proc
232
266
  def on_main_process_startup(&proc)
233
267
  @main_process_startup_blocks ||= []
234
268
  @main_process_startup_blocks << proc
235
269
  end
236
270
 
271
+ # @return [true] True if startup has been done
237
272
  def startup_done?
238
273
  @startup_done
239
274
  end
240
275
 
276
+ # @param [Proc] proc A block that will be called when #shutdown is run
277
+ # @return [Proc] The passed proc
241
278
  def on_shutdown(&block)
242
279
  @shutdown_blocks ||= []
243
280
  @shutdown_blocks << block
244
281
  end
245
282
 
246
283
  # Invoked when a server is shutdown. Apps may implement the app_shutdown method, that will be called.
284
+ # @return [void]
247
285
  def shutdown(force=false)
248
286
  unless force
249
287
  #return unless Thread.current == Thread.main
@@ -277,10 +315,16 @@ module Spider
277
315
  end
278
316
  end
279
317
 
318
+ # Force shutdown, even if it has been done already
319
+ # @return [void]
280
320
  def shutdown!
281
321
  shutdown(true)
282
322
  end
283
323
 
324
+ # Adds a running thread to the application. The app will wait for running threads
325
+ # when shutting down.
326
+ # @param [Thread] thread to add
327
+ # @return [void]
284
328
  def add_thread(thr)
285
329
  @running_threads ||= []
286
330
  @threads_mutex ||= Mutex.new
@@ -289,12 +333,17 @@ module Spider
289
333
  end
290
334
  end
291
335
 
336
+ # Removes a running thread. See {add_thread}.
337
+ # @param [Thread] The thread to remove
338
+ # @return [void]
292
339
  def remove_thread(thr)
293
340
  @threads_mutex.synchronize do
294
341
  @running_threads.delete(thr)
295
342
  end
296
343
  end
297
344
 
345
+ # Called when the main process is shut down. See also {main_process_startup}.
346
+ # @return [void]
298
347
  def main_process_shutdown
299
348
  if startup_done?
300
349
  shutdown!
@@ -304,20 +353,29 @@ module Spider
304
353
  end
305
354
  end
306
355
 
356
+ # @param [Proc] proc A block that will be called when {main_process_shutdown} is run
357
+ # @return [Proc] The passed proc
307
358
  def on_main_process_shutdown(&block)
308
359
  @main_process_shutdown_blocks ||= []
309
360
  @main_process_shutdown_blocks << block
310
361
  end
311
362
 
312
-
363
+ # Restarts the application.
364
+ #
365
+ # Note that this actually touches the restart file (tmp/restart.txt by default), so the same
366
+ # effect can by achieved by manually touching the file
367
+ # @return [void]
313
368
  def restart!
314
369
  FileUtils.touch(@paths[:restart_file])
315
370
  end
316
371
 
372
+ # @return [Hash] An Hash of data local to the current request.
317
373
  def current
318
374
  Spider::Request.current
319
375
  end
320
376
 
377
+ # Called when a new request is started.
378
+ # @return [void]
321
379
  def request_started
322
380
  @request_mutex.lock if (@request_mutex)
323
381
  Spider::Request.current = {
@@ -325,26 +383,37 @@ module Spider
325
383
  }
326
384
  end
327
385
 
386
+ # Called when a new request is finished.
387
+ # @return [void]
328
388
  def request_finished
329
389
  # Spider.logger.info("Done in #{(Time.now - Spider::Request.current[:_start])*1000}ms")
330
390
  Spider::Request.reset_current
331
391
  @request_mutex.unlock if (@request_mutex)
332
392
  end
333
393
 
394
+ # Run a lock around requests, ensuring only one request is run at a time.
395
+ # This is usually not needed, except for testing and special situations.
396
+ # @return [void]
334
397
  def mutex_requests!
335
398
  @request_mutex = Mutex.new
336
399
  end
337
400
 
401
+ # @return [Mutex] The current Request Mutex, if set
338
402
  def request_mutex
339
403
  @request_mutex
340
404
  end
341
405
 
406
+ # Sets the current Request Mutex
407
+ # @param [Mutex]
408
+ # @return [Mutex]
342
409
  def request_mutex=(val)
343
410
  @request_mutex = val
344
411
  end
345
412
 
346
413
 
347
414
  # Closes any open loggers, and opens new ones based on configured settings.
415
+ # @param [bool] force to start loggers even if already started.
416
+ # @return [true]
348
417
  def start_loggers(force=false)
349
418
  init_base
350
419
  return if @logger_started && !force
@@ -375,11 +444,9 @@ module Spider
375
444
  @logger_started = true
376
445
  end
377
446
 
378
- def start_loggers!
379
- start_loggers(false)
380
- end
381
447
 
382
- # Sets the default paths (see #paths).
448
+ # Sets the default paths (see {paths}).
449
+ # @return [Hash] The paths Hash
383
450
  def setup_paths(root)
384
451
  @paths[:root] = root
385
452
  @paths[:apps] = File.join(root, 'apps')
@@ -395,15 +462,18 @@ module Spider
395
462
  @paths.each do |k, path|
396
463
  @paths[k] = File.expand_path(File.readlink(path)) if File.symlink?(path)
397
464
  end
465
+ @paths
398
466
  end
399
467
 
468
+ # @return [Array] paths to look for apps
400
469
  def app_paths
401
470
  paths = [$SPIDER_PATHS[:core_apps]]
402
471
  paths.unshift(@paths[:apps]) if @paths[:apps]
403
472
  paths
404
473
  end
405
474
 
406
- # Finds an app by name, looking in paths[:apps] and paths[:core_apps]. Returns the found path.
475
+ # Finds an app by name, looking in paths[:apps] and paths[:core_apps].
476
+ # @return [String|nil] The path of the found app, or nil if it was not found.
407
477
  def find_app(name)
408
478
  path = nil
409
479
  app_paths.each do |base|
@@ -416,6 +486,9 @@ module Spider
416
486
  return path
417
487
  end
418
488
 
489
+ # Finds sub-apps (apps inside another one)
490
+ # @param [String] name
491
+ # @return [Array] An Array of apps found at path name
419
492
  def find_apps(name)
420
493
  app_paths.each do |base|
421
494
  test = File.join(base, name)
@@ -425,6 +498,9 @@ module Spider
425
498
  end
426
499
  end
427
500
 
501
+ # Loads the given app
502
+ # @param [String] name
503
+ # @return [void]
428
504
  def load_app(name)
429
505
  paths = find_apps(name)
430
506
  paths.each do |path|
@@ -432,6 +508,9 @@ module Spider
432
508
  end
433
509
  end
434
510
 
511
+ # Loads the app inside the give folder
512
+ # @param [String] path
513
+ # @return [void]
435
514
  def load_app_at_path(path)
436
515
  return if @loaded_apps[path]
437
516
  relative_path = path
@@ -446,7 +525,9 @@ module Spider
446
525
  app_files.each{ |f| require File.join(relative_path, f) if File.exist?(File.join(path, f)) }
447
526
  end
448
527
 
449
-
528
+ # Loads a list of apps
529
+ # @param [*apps]
530
+ # @return [void]
450
531
  def load_apps(*l)
451
532
  if l.empty?
452
533
  l = Spider.conf.get('apps')
@@ -456,12 +537,16 @@ module Spider
456
537
  end
457
538
  end
458
539
 
540
+ # Loads all apps inside the defined app paths (see {app_paths})
541
+ # @return [void]
459
542
  def load_all_apps
460
543
  find_all_apps.each do |path|
461
544
  load_app_at_path(path)
462
545
  end
463
546
  end
464
547
 
548
+ # @param [Array] An Array of paths to look into. Will use {app_paths} if nil.
549
+ # @return [Array] An Array of paths for all found apps
465
550
  def find_all_apps(paths=nil)
466
551
  paths ||= self.app_paths
467
552
 
@@ -478,6 +563,8 @@ module Spider
478
563
  return app_paths
479
564
  end
480
565
 
566
+ # @param [String] path
567
+ # @return [Array] An array of all apps found inside path
481
568
  def find_apps_in_folder(path)
482
569
  return unless File.directory?(path)
483
570
  return [path] if File.exist?(File.join(path, '_init.rb'))
@@ -494,18 +581,30 @@ module Spider
494
581
  return found
495
582
  end
496
583
 
584
+ # Registers an App with Spider
585
+ # @param [Spider::App] mod The App module
586
+ # @return [void]
497
587
  def add_app(mod)
498
588
  @apps[mod.name] = mod
499
589
  @apps_by_path[mod.relative_path] = mod
500
590
  @apps_by_short_name[mod.short_name] = mod
501
591
  end
502
592
 
593
+ # @param [String] path_or_name
594
+ # @return [bool] True if there is an app at given path or with given name, False otherwise
503
595
  def app?(path_or_name)
504
596
  return true if @apps_by_path[path_or_name]
505
597
  return true if @apps_by_short_name[path_or_name]
506
598
  return false
507
599
  end
508
600
 
601
+ # Returns the dependencies for given apps, based on the apps' spec.
602
+ #
603
+ # Options accepts:
604
+ # * :optional whether to include optional apps in the dependencies
605
+ # @param [Arrray] An Array of App names
606
+ # @param [Hash] options
607
+ # @return [Array] The dependencies for the given apps
509
608
  def get_app_deps(apps, options={})
510
609
  new_apps = apps.clone
511
610
  specs = {}
@@ -520,6 +619,8 @@ module Spider
520
619
  specs.keys
521
620
  end
522
621
 
622
+ # Used by configuration editor
623
+ #-- TODO
523
624
  def activate_apps(apps, specs=nil)
524
625
  require 'spiderfw/config/configuration_editor'
525
626
  init_base
@@ -539,6 +640,9 @@ module Spider
539
640
  editor.save
540
641
  end
541
642
 
643
+ # @param [Array] apps The apps to order
644
+ # @param [Hash] specs A Hash of the apps' {AppSpec}s, indexed by app short name
645
+ # @return [Array] the order in which to load apps, based on their specs.
542
646
  def apps_load_order(apps, specs)
543
647
  # TODO
544
648
  require 'spiderfw/app'
@@ -549,6 +653,10 @@ module Spider
549
653
  sort.tsort.reject{ |a| a.nil? }
550
654
  end
551
655
 
656
+
657
+ # Loads configuration YAML files found inside path
658
+ # @param [String] path
659
+ # @return [void]
552
660
  def load_configuration(path)
553
661
  return unless File.directory?(path)
554
662
  opts = File.join(path, 'options.rb')
@@ -559,27 +667,37 @@ module Spider
559
667
  when /^\./
560
668
  next
561
669
  when /\.(yaml|yml)$/
562
- begin
563
- @configuration.load_yaml(File.join(path, f))
564
- rescue ConfigurationException => exc
565
- if exc.type == :yaml
566
- err = "Configuration file #{path+f} is not valid YAML"
567
- Spider.output(err, :ERROR)
568
- else
569
- raise
570
- end
571
- end
670
+ load_configuration_file(File.join(path, f))
671
+ end
672
+ end
673
+ end
674
+
675
+ # Loads a YAML configuration file
676
+ # @param [String] path to the file
677
+ # @return [void]
678
+ def load_configuration_file(file)
679
+ begin
680
+ @configuration.load_yaml(file)
681
+ rescue ConfigurationException => exc
682
+ if exc.type == :yaml
683
+ err = "Configuration file #{path+f} is not valid YAML"
684
+ Spider.output(err, :ERROR)
685
+ else
686
+ raise
572
687
  end
573
688
  end
574
689
  end
575
690
 
576
- # Returns the default controller.
691
+ # Returns the default controller Class ({SpiderController}).
692
+ # @return [Class]
577
693
  def controller
578
694
  require 'spiderfw/controller/spider_controller'
579
695
  SpiderController
580
696
  end
581
697
 
582
- # Sets routes on the #controller for the given apps.
698
+ # Sets routes on the controller for the given apps.
699
+ # @param [Array] An array of app names to route.
700
+ # @return [void]
583
701
  def route_apps(*apps)
584
702
  options = {}
585
703
  if apps[-1].is_a?(Hash)
@@ -599,11 +717,18 @@ module Spider
599
717
 
600
718
  # Adds a resource type
601
719
  # name must be a symbol, extensions an array of extensions (strings, without the dot) for this resource.
720
+ #
721
+ # Resources can be searched with {find_resource}. They will be searched first inside the home, then
722
+ # inside the app's folder. This way, home can override app resources. See also {find_resource}.
723
+ #
602
724
  # Options may be:
603
- # :extensions an array of possible extensions. If given, find_resource will try appending the extensions
604
- # when looking for the file.
605
- # :path the path of the resource relative to resource root; if not given, name will be used.
725
+ # * :extensions an Array of possible extensions. If given, find_resource will try appending the extensions
726
+ # when looking for the file.
727
+ # * :path the path of the resource relative to resource root; if not given, name will be used.
606
728
  #
729
+ # @param [Symbol] name
730
+ # @param [Hash] options
731
+ # @return [void]
607
732
  def register_resource_type(name, options={})
608
733
  @resource_types[name] = {
609
734
  :extensions => options[:extensions],
@@ -613,25 +738,46 @@ module Spider
613
738
 
614
739
  Spider.register_resource_type(:views, :extensions => ['shtml'])
615
740
 
741
+ # @return [String] $SPIDER_PATH
616
742
  def path
617
743
  $SPIDER_PATH
618
744
  end
619
745
 
746
+ # @return [String] '/spider'
620
747
  def relative_path
621
748
  '/spider'
622
749
  end
623
750
 
624
751
  # Returns the full path of a resource.
625
- # resource_type may be :views, or any other type registered with #register_resource_type
626
- # path is the path of the resource, relative to the resource folder
627
- # cur_path, if provided, is the current working path
628
- # owner_class, if provided, must respond to *app*
629
752
  #
630
- # Will look for the resource in the runtime root first, than in the
631
- # app's :"#{resource_type}_path", and finally in the spider folder.
753
+ # Spider provides the following resources:
754
+ # * :views (:filetypes => ['.shtml'])
755
+ # * :js and :css (:path => 'public')
756
+ #
757
+ # Apps can define their own resource types (see {register_resource_type}).
758
+ #
759
+ # This method will look for the resource in the runtime root first, than in the
760
+ # app's :"#{resource_type}_path", and finally in the spider's gem folder.
761
+ #
762
+ # For example:
763
+ #
764
+ # find_resource(:views, 'abc/my_view', nil, [MyApp]) will look into:
765
+ # * /home/views/my_app/abc/my_view.shtml
766
+ # * /home/views/apps/my_app/views/abc/my_view.shtml
767
+ # * /lib/spider/views/abc/my_view.shtml
768
+ #
769
+ #
770
+ # @param [Symbol] resource_type
771
+ # @param [String] path
772
+ # @param [String] cur_path Current path: if set, will be used to resolve relative paths
773
+ # @param [Array] owner_classes An Array of Classes, which must respond to .app (i.e., they must belong to an App).
774
+ # If set, will be used to determine the apps to look into.
775
+ # @param [Array] search_paths An Array of additional paths to look inside
776
+ # @return [Resource]
777
+
632
778
  def find_resource(resource_type, path, cur_path=nil, owner_classes=nil, search_paths=[])
633
779
  owner_classes = [owner_classes] unless owner_classes.is_a?(Enumerable)
634
- # FIXME: security check for allowed paths?
780
+
635
781
  def first_found(extensions, path)
636
782
  extensions.each do |ext|
637
783
  full = path
@@ -700,6 +846,9 @@ module Spider
700
846
  return Resource.new(path)
701
847
  end
702
848
 
849
+ # @param [Symbol] resource_type
850
+ # @param [Spider::App] the App who owns the resource
851
+ # @return [Array] An array of places to look for resources of type resource_type belonging to app
703
852
  def resource_search_locations(resource_type, app=nil)
704
853
  resource_config = @resource_types[resource_type]
705
854
  resource_rel_path = resource_config[:path]
@@ -727,6 +876,12 @@ module Spider
727
876
  search_locations
728
877
  end
729
878
 
879
+ # Returns an Array of all resources of a certain type
880
+ # @param [Symbol] resource_type
881
+ # @param [owner_class] the owner of the resource (must respond to .app)
882
+ # @param [String] start A subfolder to start looking from
883
+ # @params [Array] An array of additional places to search
884
+ # @return [Array] An array of resources
730
885
  def list_resources(resource_type, owner_class=nil, start=nil, search_paths = [])
731
886
  app = nil
732
887
  if owner_class <= Spider::App
@@ -756,6 +911,14 @@ module Spider
756
911
 
757
912
  end
758
913
 
914
+ # See also {find_resource}
915
+ # @param [Symbol] resource_type
916
+ # @param [String] path
917
+ # @param [String] cur_path Current path: if set, will be used to resolve relative paths
918
+ # @param [Array] owner_classes An Array of Classes, which must respond to .app (i.e., they must be inside an app).
919
+ # If set, will be used to determine the apps to look into.
920
+ # @param [Array] search_paths An Array of additional paths to look inside
921
+ # @return [String|nil] the path of the found Resource, or nil if not found
759
922
  def find_resource_path(resource_type, path, cur_path=nil, owner_classes=nil, search_paths=[])
760
923
  res = find_resource(resource_type, path, cur_path, owner_classes, search_paths)
761
924
  return res ? res.path : nil
@@ -764,6 +927,12 @@ module Spider
764
927
 
765
928
  # Source file management
766
929
 
930
+
931
+ # @private
932
+ # Lists all sources inside a path.
933
+ # @param [String] path
934
+ # @return [void]
935
+ #-- TODO: fix or remove
767
936
  def sources_in_dir(path)
768
937
  loaded = []
769
938
  $".each do |file|
@@ -783,12 +952,22 @@ module Spider
783
952
  return loaded
784
953
  end
785
954
 
786
- def reload_sources_in_dir(dir)
955
+
956
+ # @private
957
+ # Reloads all application inside a folder.
958
+ # @return [void]
959
+ #-- TODO: fix or remove
960
+ def relo
961
+ ad_sources_in_dir(dir)
787
962
  self.sources_in_dir(dir).each do |file|
788
963
  load(file)
789
964
  end
790
965
  end
791
966
 
967
+ # @private
968
+ # Reloads all application sources.
969
+ # @return [void]
970
+ #-- TODO: fix or remove
792
971
  def reload_sources
793
972
  logger.debug("Reloading sources")
794
973
  crit = Thread.critical
@@ -803,7 +982,9 @@ module Spider
803
982
  end
804
983
  Thread.critical = crit
805
984
  end
806
-
985
+
986
+ # Terminates the current process and starts a new one
987
+ # @return [void]
807
988
  def respawn!
808
989
  require 'rbconfig'
809
990
  Spider.logger.info("Restarting")
@@ -825,24 +1006,62 @@ module Spider
825
1006
  end
826
1007
  end
827
1008
 
1009
+ # Sets the current runmode.
1010
+ #
1011
+ # Note: the runmode can't be changed when set; the method will raise an error if trying to
1012
+ # set a runmode when one is already set.
1013
+ # @param [String] mode
1014
+ # @return [void]
828
1015
  def runmode=(mode)
829
1016
  raise "Can't change runmode" if @runmode
830
1017
  @runmode = mode
831
1018
  @configuration.include_set(mode)
832
1019
  if Spider.conf.get('debugger.start') || File.exists?(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
833
1020
  init_debug
1021
+ debug_txt = File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt')
1022
+ if File.exists?(debug_txt)
1023
+ File.delete(debug_txt)
1024
+ end
834
1025
  end
835
1026
  Spider.paths[:var] = File.join(Spider.paths[:var], mode) if mode != 'production'
836
1027
  Bundler.require(:default, @runmode.to_sym) if defined?(Bundler)
837
1028
  end
838
-
1029
+
1030
+ # Starts the debugger (ruby-debug, or Pry if debugger.pry configuration is true)
839
1031
  def init_debug
1032
+ if Spider.conf.get('debugger.pry')
1033
+ begin
1034
+ init_pry_debug
1035
+ rescue Exception
1036
+ init_ruby_debug
1037
+ end
1038
+ else
1039
+ init_ruby_debug
1040
+ end
1041
+ end
1042
+
1043
+ # @private
1044
+ # Inits the pry debugger
1045
+ # @return [void]
1046
+ def init_pry_debug
1047
+ require 'pry'
1048
+ require 'pry-nav'
1049
+ require 'pry-stack_explorer'
1050
+ if File.exists?(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
1051
+ require 'pry-remote'
1052
+ end
1053
+ Pry::Commands.alias_command "l=", "whereami"
1054
+ end
1055
+
1056
+ # @private
1057
+ # Inits ruby-debug
1058
+ # @return [void]
1059
+ def init_ruby_debug
840
1060
  begin
841
1061
  require 'ruby-debug'
842
1062
  if File.exists?(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
843
1063
  Debugger.wait_connection = true
844
1064
  Debugger.start_remote
845
- File.delete(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
846
1065
  else
847
1066
  Debugger.start
848
1067
  end
@@ -853,6 +1072,7 @@ module Spider
853
1072
  end
854
1073
  end
855
1074
 
1075
+ # @return [Locale::Tag] The current locale
856
1076
  def locale
857
1077
  begin
858
1078
  @current_locale = Locale.current[0]
@@ -865,6 +1085,8 @@ module Spider
865
1085
  end
866
1086
  end
867
1087
 
1088
+ # @param [Locale::Tag]
1089
+ # @return [Spider::I18n::Provider] A provider for the given locale
868
1090
  def i18n(l = self.locale)
869
1091
  Spider::I18n.provider(l)
870
1092
  end
@@ -887,10 +1109,15 @@ module Spider
887
1109
  end
888
1110
  end
889
1111
 
1112
+ # @return [bool] True if spider is running in interactive mode (i.e. run from the command line), false otherwise
890
1113
  def interactive?
891
1114
  !!$SPIDER_INTERACTIVE
892
1115
  end
893
1116
 
1117
+ # Outputs a string, to the console or to log
1118
+ # @param [String] str String to output
1119
+ # @param [Symbol] level Log level
1120
+ # @return [void]
894
1121
  def output(str, level=:INFO)
895
1122
  use_log = !Spider.interactive? && @logger_started
896
1123
  if use_log