spiderfw 0.6.23 → 0.6.24

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.
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