spiderfw 0.6.23 → 0.6.24
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +10 -1
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/apps/config_editor/_init.rb +1 -2
- data/apps/config_editor/controllers/config_editor_controller.rb +1 -7
- data/apps/core/admin/controllers/admin_controller.rb +1 -1
- data/apps/core/admin/public/css/sass/admin.css +35 -31
- data/apps/core/admin/public/sass/admin.scss +6 -1
- data/apps/core/components/widgets/crud/crud.shtml +2 -2
- data/apps/core/components/widgets/table/table.rb +5 -5
- data/apps/core/forms/tags/element_row.erb +15 -10
- data/apps/core/forms/widgets/form/form.rb +35 -22
- data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +2 -2
- data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +2 -2
- data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +2 -2
- data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
- data/apps/core/forms/widgets/inputs/input/input.shtml +2 -2
- data/apps/core/forms/widgets/inputs/password/password.shtml +2 -2
- data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +1 -1
- data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
- data/apps/core/forms/widgets/inputs/text/text.shtml +2 -2
- data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +2 -2
- data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +1 -1
- data/blueprints/home/config.ru +8 -0
- data/lib/spiderfw/app.rb +416 -224
- data/lib/spiderfw/cmd/commands/app.rb +243 -239
- data/lib/spiderfw/cmd/commands/cert.rb +421 -417
- data/lib/spiderfw/cmd/commands/config.rb +85 -82
- data/lib/spiderfw/cmd/commands/console.rb +64 -40
- data/lib/spiderfw/cmd/commands/content.rb +29 -25
- data/lib/spiderfw/cmd/commands/create.rb +58 -54
- data/lib/spiderfw/cmd/commands/model.rb +118 -114
- data/lib/spiderfw/cmd/commands/setup.rb +55 -51
- data/lib/spiderfw/cmd/commands/test.rb +63 -59
- data/lib/spiderfw/cmd/commands/webserver.rb +56 -51
- data/lib/spiderfw/config/options/spider.rb +4 -3
- data/lib/spiderfw/controller/controller.rb +2 -0
- data/lib/spiderfw/controller/http_controller.rb +1 -2
- data/lib/spiderfw/controller/mixins/static_content.rb +3 -3
- data/lib/spiderfw/controller/mixins/visual.rb +30 -15
- data/lib/spiderfw/controller/response.rb +84 -0
- data/lib/spiderfw/controller/session/file_session.rb +2 -2
- data/lib/spiderfw/http/adapters/rack.rb +12 -13
- data/lib/spiderfw/http/server.rb +80 -46
- data/lib/spiderfw/i18n/cldr.rb +6 -9
- data/lib/spiderfw/model/base_model.rb +103 -23
- data/lib/spiderfw/model/condition.rb +110 -25
- data/lib/spiderfw/model/mappers/db_mapper.rb +14 -6
- data/lib/spiderfw/model/mappers/mapper.rb +440 -197
- data/lib/spiderfw/model/model.rb +105 -21
- data/lib/spiderfw/model/model_hash.rb +9 -1
- data/lib/spiderfw/model/query.rb +50 -9
- data/lib/spiderfw/model/query_set.rb +211 -44
- data/lib/spiderfw/model/request.rb +28 -21
- data/lib/spiderfw/model/storage/base_storage.rb +125 -10
- data/lib/spiderfw/model/storage/db/db_storage.rb +7 -4
- data/lib/spiderfw/model/storage.rb +8 -1
- data/lib/spiderfw/setup/spider_setup_wizard.rb +9 -7
- data/lib/spiderfw/spider.rb +270 -43
- data/lib/spiderfw/templates/layout.rb +9 -4
- data/lib/spiderfw/templates/resources/sass.rb +3 -2
- data/lib/spiderfw/templates/template.rb +1 -0
- data/lib/spiderfw/utils/annotations.rb +3 -1
- data/lib/spiderfw/utils/logger.rb +1 -1
- data/lib/spiderfw/utils/monkey/symbol.rb +4 -2
- data/lib/spiderfw/utils/shared_store/file_shared_store.rb +2 -2
- data/lib/spiderfw/utils/thread_out.rb +3 -1
- data/public/css/error_page.css +83 -0
- data/public/js/error_page.js +5 -0
- data/spider.gemspec +4 -1
- data/templates/email/error.erb +9 -0
- metadata +28 -12
- data/apps/config_editor/widgets/edit_bool/edit_bool.rb +0 -8
- data/apps/config_editor/widgets/edit_bool/edit_bool.shtml +0 -5
data/lib/spiderfw/spider.rb
CHANGED
@@ -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
|
-
#
|
50
|
-
#
|
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
|
-
#
|
143
|
-
#
|
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
|
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].
|
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
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
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
|
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
|
604
|
-
#
|
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
|
-
#
|
631
|
-
#
|
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
|
-
|
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
|
-
|
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
|