spiderfw 0.6.21 → 0.6.22

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 (149) hide show
  1. data/CHANGELOG +33 -0
  2. data/Rakefile +0 -1
  3. data/VERSION +1 -1
  4. data/apps/core/admin/_init.rb +4 -0
  5. data/apps/core/admin/admin.rb +20 -4
  6. data/apps/core/admin/controllers/admin_controller.rb +63 -4
  7. data/apps/core/admin/controllers/app_admin_controller.rb +15 -0
  8. data/apps/core/admin/data/locale/it/LC_MESSAGES/admin.mo +0 -0
  9. data/apps/core/admin/po/admin.pot +33 -0
  10. data/apps/core/admin/po/it/admin.po +34 -0
  11. data/apps/core/admin/public/css/admin.css +13 -0
  12. data/apps/core/admin/public/css/login.css +51 -0
  13. data/apps/core/admin/public/css/sass/admin.css +198 -0
  14. data/apps/core/admin/public/css/sass/bootstrap/bootstrap.css +3107 -0
  15. data/apps/core/admin/public/img/css/header_bg.png +0 -0
  16. data/apps/core/admin/public/img/css/noise.png +0 -0
  17. data/apps/core/admin/public/img/css/side_bg.png +0 -0
  18. data/apps/core/admin/public/img/icons/logout.png +0 -0
  19. data/apps/core/admin/public/img/icons-s845a69dd9f.png +0 -0
  20. data/apps/core/admin/public/js/bootstrap-alerts.js +113 -0
  21. data/apps/core/admin/public/js/bootstrap-buttons.js +62 -0
  22. data/apps/core/admin/public/js/bootstrap-dropdown.js +55 -0
  23. data/apps/core/admin/public/js/bootstrap-modal.js +260 -0
  24. data/apps/core/admin/public/js/bootstrap-popover.js +90 -0
  25. data/apps/core/admin/public/js/bootstrap-scrollspy.js +107 -0
  26. data/apps/core/admin/public/js/bootstrap-tabs.js +80 -0
  27. data/apps/core/admin/public/js/bootstrap-twipsy.js +321 -0
  28. data/apps/core/admin/public/sass/admin.scss +167 -0
  29. data/apps/core/admin/public/sass/bootstrap/bootstrap.scss +29 -0
  30. data/apps/core/admin/public/sass/bootstrap/forms.scss +478 -0
  31. data/apps/core/admin/public/sass/bootstrap/mixins.scss +220 -0
  32. data/apps/core/admin/public/sass/bootstrap/patterns.scss +1062 -0
  33. data/apps/core/admin/public/sass/bootstrap/reset.scss +141 -0
  34. data/apps/core/admin/public/sass/bootstrap/scaffolding.scss +136 -0
  35. data/apps/core/admin/public/sass/bootstrap/tables.scss +224 -0
  36. data/apps/core/admin/public/sass/bootstrap/type.scss +187 -0
  37. data/apps/core/admin/public/sass/bootstrap/variables.scss +60 -0
  38. data/apps/core/admin/public/sass/grid.scss +54 -0
  39. data/apps/core/admin/views/_app_info.shtml +5 -0
  40. data/apps/core/admin/views/admin.layout.shtml +35 -0
  41. data/apps/core/admin/views/index.shtml +1 -1
  42. data/apps/core/admin/views/login.layout.shtml +13 -0
  43. data/apps/core/auth/controllers/mixins/auth_helper.rb +1 -1
  44. data/apps/core/auth/models/super_user.rb +6 -0
  45. data/apps/core/auth/models/user.rb +9 -0
  46. data/apps/core/components/assets.rb +5 -1
  47. data/apps/core/components/data/locale/it/LC_MESSAGES/spider_components.mo +0 -0
  48. data/apps/core/components/po/it/spider_components.po +23 -9
  49. data/apps/core/components/po/spider_components.pot +16 -8
  50. data/apps/core/components/public/css/admin.css +0 -12
  51. data/apps/core/components/public/css/crud.css +16 -19
  52. data/apps/core/components/public/css/table.css +11 -5
  53. data/apps/core/components/public/js/less-1.1.3.min.js +16 -0
  54. data/apps/core/components/public/widgets/table.js +1 -1
  55. data/apps/core/components/widgets/admin/admin.rb +10 -0
  56. data/apps/core/components/widgets/admin/admin.shtml +24 -4
  57. data/apps/core/components/widgets/confirm/confirm.rb +2 -2
  58. data/apps/core/components/widgets/confirm/confirm.shtml +5 -2
  59. data/apps/core/components/widgets/crud/crud.rb +10 -1
  60. data/apps/core/components/widgets/crud/crud.shtml +18 -21
  61. data/apps/core/components/widgets/menu/menu.shtml +1 -2
  62. data/apps/core/components/widgets/switcher/switcher.rb +6 -3
  63. data/apps/core/components/widgets/switcher/templates/default.shtml +3 -1
  64. data/apps/core/components/widgets/table/table.rb +3 -2
  65. data/apps/core/components/widgets/table/table.shtml +44 -25
  66. data/apps/core/forms/data/locale/it/LC_MESSAGES/spider_forms.mo +0 -0
  67. data/apps/core/forms/po/it/spider_forms.po +7 -2
  68. data/apps/core/forms/po/spider_forms.pot +5 -1
  69. data/apps/core/forms/public/css/form.css +3 -3
  70. data/apps/core/forms/public/css/html_area.css +0 -1
  71. data/apps/core/forms/public/date_time.js +4 -3
  72. data/apps/core/forms/public/select.js +5 -4
  73. data/apps/core/forms/tags/element_label.erb +1 -1
  74. data/apps/core/forms/tags/row.erb +1 -1
  75. data/apps/core/forms/widgets/form/form.rb +23 -1
  76. data/apps/core/forms/widgets/form/form.shtml +7 -8
  77. data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +3 -3
  78. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +3 -3
  79. data/apps/core/forms/widgets/inputs/file_input/file_input.rb +4 -2
  80. data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +1 -1
  81. data/apps/core/forms/widgets/inputs/hidden/hidden.shtml +1 -1
  82. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  83. data/apps/core/forms/widgets/inputs/password/password.shtml +3 -3
  84. data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +2 -2
  85. data/apps/core/forms/widgets/inputs/select/select.shtml +16 -13
  86. data/apps/core/forms/widgets/inputs/text/text.shtml +3 -3
  87. data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +5 -2
  88. data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +3 -3
  89. data/apps/messenger/_init.rb +10 -2
  90. data/apps/messenger/controllers/messenger_admin_controller.rb +53 -0
  91. data/apps/messenger/controllers/messenger_controller.rb +2 -0
  92. data/apps/messenger/controllers/mixins/messenger_helper.rb +2 -2
  93. data/apps/messenger/models/message.rb +1 -1
  94. data/apps/messenger/public/app_icon.png +0 -0
  95. data/apps/messenger/views/admin/_admin.layout.shtml +26 -0
  96. data/apps/messenger/views/admin/index.shtml +13 -0
  97. data/apps/messenger/views/admin/queue.shtml +28 -0
  98. data/apps/messenger/views/index.shtml +3 -3
  99. data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
  100. data/lib/spiderfw/app.rb +10 -1
  101. data/lib/spiderfw/cache/template_cache.rb +21 -22
  102. data/lib/spiderfw/cmd/commands/app.rb +3 -3
  103. data/lib/spiderfw/cmd/commands/setup.rb +1 -1
  104. data/lib/spiderfw/config/options/spider.rb +18 -2
  105. data/lib/spiderfw/controller/controller.rb +9 -3
  106. data/lib/spiderfw/controller/dispatcher.rb +25 -12
  107. data/lib/spiderfw/controller/home_controller.rb +3 -3
  108. data/lib/spiderfw/controller/http_controller.rb +11 -0
  109. data/lib/spiderfw/controller/mixins/static_content.rb +3 -12
  110. data/lib/spiderfw/controller/mixins/visual.rb +21 -20
  111. data/lib/spiderfw/controller/request.rb +1 -3
  112. data/lib/spiderfw/http/adapters/mongrel.rb +1 -1
  113. data/lib/spiderfw/i18n/gettext.rb +14 -0
  114. data/lib/spiderfw/i18n/shtml_parser.rb +2 -2
  115. data/lib/spiderfw/model/base_model.rb +4 -3
  116. data/lib/spiderfw/model/mappers/db_mapper.rb +137 -79
  117. data/lib/spiderfw/model/mappers/mapper.rb +6 -2
  118. data/lib/spiderfw/model/migrations/drop_element.rb +1 -1
  119. data/lib/spiderfw/model/migrations/previous_model.rb +73 -0
  120. data/lib/spiderfw/model/migrations/rename_element.rb +42 -0
  121. data/lib/spiderfw/model/migrations.rb +14 -1
  122. data/lib/spiderfw/model/mixins/tree.rb +65 -19
  123. data/lib/spiderfw/model/model_hash.rb +9 -5
  124. data/lib/spiderfw/model/query.rb +8 -0
  125. data/lib/spiderfw/model/query_funcs.rb +23 -0
  126. data/lib/spiderfw/model/query_set.rb +1 -1
  127. data/lib/spiderfw/model/request.rb +11 -3
  128. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +28 -1
  129. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +10 -10
  130. data/lib/spiderfw/model/storage/db/db_schema.rb +20 -3
  131. data/lib/spiderfw/model/storage/db/db_storage.rb +39 -17
  132. data/lib/spiderfw/setup/app_manager.rb +69 -31
  133. data/lib/spiderfw/setup/setup_task.rb +76 -8
  134. data/lib/spiderfw/spider.rb +21 -1
  135. data/lib/spiderfw/templates/blocks/text.rb +4 -4
  136. data/lib/spiderfw/templates/blocks/text_domain.rb +25 -0
  137. data/lib/spiderfw/templates/blocks/widget.rb +1 -1
  138. data/lib/spiderfw/templates/layout.rb +160 -92
  139. data/lib/spiderfw/templates/resources/less.rb +10 -2
  140. data/lib/spiderfw/templates/resources/sass.rb +66 -9
  141. data/lib/spiderfw/templates/template.rb +35 -10
  142. data/lib/spiderfw/templates/template_blocks.rb +6 -3
  143. data/lib/spiderfw/utils/logger.rb +20 -0
  144. data/lib/spiderfw/utils/memory.rb +7 -3
  145. data/lib/spiderfw/widget/widget.rb +13 -7
  146. data/lib/spiderfw/widget/widget_attributes.rb +2 -2
  147. data/spider.gemspec +1 -0
  148. metadata +68 -11
  149. data/apps/core/admin/views/spider_admin.layout.shtml +0 -23
@@ -22,6 +22,7 @@ module Spider; module Model; module Storage; module Db
22
22
  :sequences => true,
23
23
  :transactions => true
24
24
  }
25
+ @fixed_length_types = ['TIME', 'DATE', 'DATETIME']
25
26
 
26
27
  class << self
27
28
  # An Array of keywords that can not be used in schema names.
@@ -30,6 +31,8 @@ module Spider; module Model; module Storage; module Db
30
31
  attr_reader :type_synonyms
31
32
  # Type conversions which do not lose data. See also #safe_schema_conversion?
32
33
  attr_reader :safe_conversions
34
+ # Types for which we can safely ignore length in conversions
35
+ attr_reader :fixed_length_types
33
36
 
34
37
 
35
38
  def storage_type
@@ -40,6 +43,7 @@ module Spider; module Model; module Storage; module Db
40
43
  subclass.instance_variable_set("@reserved_keywords", @reserved_keywords)
41
44
  subclass.instance_variable_set("@type_synonyms", @type_synonyms)
42
45
  subclass.instance_variable_set("@safe_conversions", @safe_conversions)
46
+ subclass.instance_variable_set("@fixed_length_types", @fixed_length_types)
43
47
  super
44
48
  end
45
49
 
@@ -249,17 +253,17 @@ module Spider; module Model; module Storage; module Db
249
253
  sql = "SELECT #{sql_keys(query)} FROM #{tables_sql} "
250
254
  bind_vars += tables_values
251
255
  where, vals = sql_condition(query)
252
- bind_vars += vals
256
+ bind_vars += vals if vals
253
257
  sql += "WHERE #{where} " if where && !where.empty?
254
258
  having, having_vals = sql_condition(query, true)
255
- unless having.blank?
256
- group_fields = (
259
+ unless having.blank? && query[:group_by].blank?
260
+ group_fields = query[:group_by] || (
257
261
  query[:keys].select{ |k| !k.is_a?(FieldExpression)
258
262
  } + collect_having_fields(query[:condition])).flatten.uniq
259
263
  group_keys = sql_keys(group_fields)
260
264
  sql += "GROUP BY #{group_keys} "
261
- sql += "HAVING #{having} "
262
- bind_vars += having_vals
265
+ sql += "HAVING #{having} " unless having.blank?
266
+ bind_vars += having_vals if having_vals
263
267
  end
264
268
  order = sql_order(query)
265
269
  sql += "ORDER BY #{order} " if order && !order.empty?
@@ -275,7 +279,7 @@ module Spider; module Model; module Storage; module Db
275
279
  # Returns the SQL for select keys.
276
280
  def sql_keys(query)
277
281
  query = {:keys => query} unless query.is_a?(Hash)
278
- query[:keys].join(',')
282
+ query[:keys].join(', ')
279
283
  end
280
284
 
281
285
  # Returns an array containing the 'FROM' part of an SQL query (including joins),
@@ -427,8 +431,9 @@ module Spider; module Model; module Storage; module Db
427
431
  return query[:order].map{|o|
428
432
  repl = replacements[o[0].to_s]
429
433
  ofield = repl ? repl : o[0]
434
+ ofield = ofield.name if ofield.is_a?(FieldExpression)
430
435
  "#{ofield} #{o[1]}"
431
- }.join(' ,')
436
+ }.join(', ')
432
437
  end
433
438
 
434
439
  # Returns the LIMIT and OFFSET SQL.
@@ -448,7 +453,7 @@ module Spider; module Model; module Storage; module Db
448
453
  end
449
454
 
450
455
  # Returns SQL and values for an update statement.
451
- def sql_update(update)
456
+ def sql_update(update, allow_all=false)
452
457
  curr[:last_query_type] = :update
453
458
  values = []
454
459
  tables = update[:table].to_s
@@ -462,7 +467,8 @@ module Spider; module Model; module Storage; module Db
462
467
  sql += sql_update_values(update)
463
468
  where, bind_vars = sql_condition(update)
464
469
  values += bind_vars
465
- sql += " WHERE #{where}"
470
+ raise "Update without conditions" if where.blank? && !allow_all
471
+ sql += " WHERE #{where}" unless where.blank?
466
472
  return [sql, values]
467
473
  end
468
474
 
@@ -524,8 +530,10 @@ module Spider; module Model; module Storage; module Db
524
530
  sqls += sql_alter_field(table_name, field[:name], field[:type], field[:attributes])
525
531
  end
526
532
  if (alter_attributes[:primary_keys] && !alter_attributes[:primary_keys].empty?)
527
- sqls << sql_drop_primary_key(table_name) if (current[:primary_keys] && !current[:primary_keys].empty? && current[:primary_keys] != alter_attributes[:primary_keys])
528
- sqls << sql_create_primary_key(table_name, alter_attributes[:primary_keys])
533
+ sqls.unshift sql_drop_primary_key(table_name) if (current[:primary_keys] && !current[:primary_keys].empty? && current[:primary_keys] != alter_attributes[:primary_keys])
534
+ # unshift avoids problems with a field being created with primary key before the drop
535
+ sql_pk = sql_create_primary_key(table_name, alter_attributes[:primary_keys])
536
+ sqls << sql_pk if sql_pk
529
537
  end
530
538
  if (alter_attributes[:foreign_key_constraints])
531
539
  cur_fkc = current && current[:foreign_key_constraints] ? current[:foreign_key_constraints] : []
@@ -567,6 +575,12 @@ module Spider; module Model; module Storage; module Db
567
575
  sqls = sql_drop_field(table_name, field_name)
568
576
  sqls.each{ |sql| execute(sql) }
569
577
  end
578
+
579
+ def change_field(table_name, field_name, new_field_name, type, attributes)
580
+ sqls = sql_change_field(table_name, field_name, new_field_name, type, attributes)
581
+ sqls.each{ |sql| execute(sql) }
582
+
583
+ end
570
584
 
571
585
  # Drops a table from the DB.
572
586
  def drop_table(table_name)
@@ -622,6 +636,10 @@ module Spider; module Model; module Storage; module Db
622
636
  def sql_drop_table(table_name)
623
637
  ["DROP TABLE #{table_name}"]
624
638
  end
639
+
640
+ def sql_change_field(table_name, field, new_field, type, attributes)
641
+ ["ALTER TABLE #{table_name} CHANGE #{field} #{sql_table_field(new_field, type, attributes)}"]
642
+ end
625
643
 
626
644
  # Checks if a DB field is equal to a schema field.
627
645
  def schema_field_equal?(current, field)
@@ -630,9 +648,11 @@ module Spider; module Model; module Storage; module Db
630
648
  (self.class.type_synonyms && self.class.type_synonyms[current[:type]] && self.class.type_synonyms[current[:type]].include?(field[:type]))
631
649
  try_method = :"schema_field_#{field[:type].downcase}_equal?"
632
650
  return send(try_method, current, field) if (respond_to?(try_method))
633
- current[:length] ||= 0; attributes[:length] ||= 0; current[:precision] ||= 0; attributes[:precision] ||= 0
634
- return false unless current[:length] == attributes[:length]
635
- return false unless current[:precision] == attributes[:precision]
651
+ unless self.class.fixed_length_types.include?(field[:type])
652
+ current[:length] ||= 0; attributes[:length] ||= 0; current[:precision] ||= 0; attributes[:precision] ||= 0
653
+ return false unless current[:length] == attributes[:length]
654
+ return false unless current[:precision] == attributes[:precision]
655
+ end
636
656
  return true
637
657
  end
638
658
 
@@ -640,7 +660,7 @@ module Spider; module Model; module Storage; module Db
640
660
  # Checks if the conversion from a current DB field to a schema field is safe, i.e. can
641
661
  # be done without loss of data.
642
662
  def safe_schema_conversion?(current, field)
643
- attributes = field[:attributes]
663
+ attributes = field[:attributes].clone
644
664
  safe = self.class.safe_conversions
645
665
  if (current[:type] != field[:type])
646
666
  if safe[current[:type]] && safe[current[:type]].include?(field[:type])
@@ -649,9 +669,11 @@ module Spider; module Model; module Storage; module Db
649
669
  return false
650
670
  end
651
671
  end
652
- return true if ((!current[:length] || current[:length] == 0) \
672
+ cur = current
673
+ return true if self.class.fixed_length_types.include?(current[:type])
674
+ return true if ((!cur[:length] || cur[:length] == 0) \
653
675
  || (attributes[:length] && current[:length] <= attributes[:length])) && \
654
- ((!current[:precision] || current[:precision] == 0) \
676
+ ((!cur[:precision] || cur[:precision] == 0) \
655
677
  || (attributes[:precision] && current[:precision] <= attributes[:precision]))
656
678
  return false
657
679
  end
@@ -5,7 +5,7 @@ module Spider
5
5
 
6
6
  class AppManager
7
7
 
8
- def initialize(options)
8
+ def initialize(options={})
9
9
  @options = options
10
10
  end
11
11
 
@@ -47,6 +47,9 @@ module Spider
47
47
  return res if apps.empty?
48
48
  require 'spiderfw/setup/app_server_client'
49
49
  client = Spider::AppServerClient.new(url)
50
+ if options[:branch]
51
+ apps = apps.map{ |a| "#{a}@#{options[:branch]}"}
52
+ end
50
53
  if options[:no_deps]
51
54
  specs = client.get_specs(apps)
52
55
  else
@@ -215,6 +218,13 @@ module Spider
215
218
  end
216
219
  end
217
220
  end
221
+ if @options[:interactive]
222
+ puts "\n\n"
223
+ @done_tasks.each do |app, tasks|
224
+ next unless tasks
225
+ task.print_release_notes
226
+ end
227
+ end
218
228
  if options[:clear_cache]
219
229
  Spider.output _("Clearing cache...")
220
230
  Spider::Template.cache.clear!
@@ -251,7 +261,10 @@ module Spider
251
261
  Spider.output _("%s already installed, skipping") % spec.id
252
262
  return
253
263
  end
254
- repo = Git.open(@home_path)
264
+ repo = nil
265
+ if ::File.directory?(File.join(@home_path, '.git'))
266
+ repo = Git.open(@home_path)
267
+ end
255
268
  repo_url = spec.git_repo_rw || spec.git_repo
256
269
  Spider.output _("Fetching %s from %s") % [spec.app_id, repo_url]
257
270
 
@@ -260,13 +273,19 @@ module Spider
260
273
  end
261
274
 
262
275
  ENV['GIT_WORK_TREE'] = nil
263
- Dir.chdir(@home_path) do
264
- `git submodule add #{repo_url} apps/#{spec.id}`
265
- `git submodule init`
266
- `git submodule update`
267
- end
268
- repo.add(['.gitmodules', "apps/#{spec.id}"])
269
- repo.commit(_("Added app %s") % spec.id)
276
+ if repo
277
+ Dir.chdir(@home_path) do
278
+ `git submodule add #{repo_url} apps/#{spec.id}`
279
+ `git submodule init`
280
+ `git submodule update`
281
+ repo.add(['.gitmodules', "apps/#{spec.id}"])
282
+ repo.commit(_("Added app %s") % spec.id)
283
+ end
284
+ else
285
+ Dir.chdir(File.join(@home_path, 'apps')) do
286
+ Git.clone(repo_url, spec.id)
287
+ end
288
+ end
270
289
  end
271
290
 
272
291
  def pack_install(spec, options={})
@@ -308,33 +327,45 @@ module Spider
308
327
 
309
328
  def git_update(spec, options={})
310
329
  require 'git'
311
- home_repo = Git.open(@home_path)
330
+ home_repo = nil
331
+ if ::File.directory?(File.join(@home_path, '.git'))
332
+ home_repo = Git.open(@home_path)
333
+ end
312
334
  app_path = File.join(@home_path, "apps", spec.id)
313
335
  app_repo = Git.open(app_path)
314
336
  Spider.output _("Updating %s from %s") % [spec.app_id, spec.git_repo]
315
337
  options[:branch] ||= 'master'
316
338
  Dir.chdir(app_path) do
317
- app_repo.branch(options[:branch]).checkout
318
- end
319
- response = err = nil
320
- Dir.chdir(app_path) do
321
- response = `git --git-dir='#{app_path}/.git' pull origin master`
322
- end
323
- require 'ruby-debug'
324
- if response =~ /Aborting/
325
- Spider.output err, :ERROR
326
- raise "Unable to update"
327
- end
328
- Dir.chdir(app_path) do
329
- app_repo.reset('HEAD', :hard => true)
330
- app_repo.branch(options[:branch]).checkout
339
+ app_repo.fetch
340
+ if app_repo.is_branch?(options[:branch])
341
+ app_repo.checkout(options[:branch])
342
+ else
343
+ app_repo.checkout("origin/#{options[:branch]}", :new_branch => options[:branch])
344
+ end
345
+ app_repo.merge("origin/#{options[:branch]}")
331
346
  end
347
+ # response = err = nil
348
+ # Dir.chdir(app_path) do
349
+ # response = `git --git-dir='#{app_path}/.git' pull origin #{options[:branch]}`
350
+ # end
351
+ # app_repo.branch(options[:branch]).checkout
352
+ # require 'ruby-debug'
353
+ # if response =~ /Aborting/
354
+ # Spider.output err, :ERROR
355
+ # raise "Unable to update"
356
+ # end
357
+ # Dir.chdir(app_path) do
358
+ # app_repo.reset('HEAD', :hard => true)
359
+ # app_repo.branch(options[:branch]).checkout
360
+ # end
332
361
 
333
- home_repo.add("apps/#{spec.id}")
334
- begin
335
- home_repo.commit(_("Updated app %s") % spec.id)
336
- rescue => exc
337
- raise unless exc.message =~ /no changes added to commit/
362
+ if home_repo
363
+ home_repo.add("apps/#{spec.id}")
364
+ begin
365
+ home_repo.commit(_("Updated app %s") % spec.id)
366
+ rescue => exc
367
+ raise unless exc.message =~ /no changes added to commit/
368
+ end
338
369
  end
339
370
  end
340
371
 
@@ -388,7 +419,7 @@ module Spider
388
419
  if version
389
420
  tasks = ["#{@version}.rb"]
390
421
  else
391
- tasks = Dir.entries(path).reject{ |p| p[0].chr == '.'}.sort{ |a, b|
422
+ tasks = Dir.entries(path).reject{ |p| !File.file?(File.join(path, p)) || p[0].chr == '.'}.sort{ |a, b|
392
423
  va = Gem::Version.new(File.basename(a, '.rb'))
393
424
  vb = Gem::Version.new(File.basename(b, '.rb'))
394
425
  va <=> vb
@@ -421,7 +452,14 @@ module Spider
421
452
  Spider.output _("Setup task done")
422
453
  rescue => exc
423
454
  Spider.output exc, :ERROR
424
- done_tasks.reverse.each{ |dt| dt.do_down } # FIXME: rescue and log errors in down
455
+ done_tasks.reverse.each do |dt|
456
+ begin
457
+ dt.do_down
458
+ rescue => exc
459
+ Spider.output("Unable to do down on #{dt}!", :ERROR)
460
+ Spider.output(exc, :ERROR)
461
+ end
462
+ end
425
463
  raise
426
464
  end
427
465
  end
@@ -4,7 +4,7 @@ module Spider
4
4
 
5
5
  class SetupTask
6
6
  attr_reader :path, :version
7
- attr_accessor :before, :up, :down, :cleanup, :sync_models, :app
7
+ attr_accessor :before, :up, :down, :cleanup, :sync_models, :app, :interactive
8
8
 
9
9
  class <<self
10
10
  def tasks
@@ -25,10 +25,12 @@ module Spider
25
25
  obj.down = Setup.down
26
26
  obj.cleanup = Setup.cleanup
27
27
  obj.sync_models = Setup.sync_models
28
+ obj.interactive = Setup.interactive?
28
29
  #obj = @last_class.new(path)
29
30
  # Kernel.send(:remove_const, @last_class.name)
30
31
  #@last_class = nil
31
32
  Thread.critical = crit
33
+ obj.do_before
32
34
  return obj
33
35
  end
34
36
  end
@@ -47,8 +49,21 @@ module Spider
47
49
  @version = Gem::Version.new(version)
48
50
  @desc = desc
49
51
  end
52
+
53
+ def dir
54
+ File.join(::File.dirname(@path), @version.to_s)
55
+ end
56
+
57
+ def do_before
58
+ return unless @before
59
+ Spider::Model::Managed.no_set_dates = true
60
+ instance_eval(&@before)
61
+ #sync_schema unless @no_sync || @sync_done
62
+ Spider::Model::Managed.no_set_dates = false
63
+ end
50
64
 
51
65
  def do_up
66
+ return unless @up
52
67
  Spider::Model::Managed.no_set_dates = true
53
68
  instance_eval(&@up)
54
69
  #sync_schema unless @no_sync || @sync_done
@@ -56,8 +71,9 @@ module Spider
56
71
  end
57
72
 
58
73
  def do_down
74
+ return unless @down
59
75
  Spider::Model::Managed.no_set_dates = true
60
- instance_eval(&@down) if @down
76
+ instance_eval(&@down)
61
77
  Spider::Model::Managed.no_set_dates = false
62
78
  end
63
79
 
@@ -66,12 +82,25 @@ module Spider
66
82
  end
67
83
 
68
84
  def do_sync
69
- return unless @sync_models
85
+ sync_schema
86
+ end
87
+
88
+ def sync_schema(*models)
89
+ had_models = models
90
+ models = @sync_models if models.blank?
91
+ return unless models
92
+ @sync_options = models.pop if models.last.is_a?(Hash)
93
+ models = models.map{ |m|
94
+ m <= Spider::App ? m.models.reject{ |n| n <= Spider::Migrations::PreviousModel } : m
95
+ }.flatten
96
+ @sync_options ||= {}
70
97
  options = {
71
- :no_foreign_key_constraints => true
72
- }
73
- @sync_models.each do |m|
74
- m.mapper.sync_schema(false, options)
98
+ :no_foreign_key_constraints => true,
99
+ :force => false
100
+ }.merge(@sync_options)
101
+ models.each do |m|
102
+ next unless m.mapper.respond_to?(:sync_schema)
103
+ m.mapper.sync_schema(options[:force], options)
75
104
  end
76
105
  end
77
106
 
@@ -89,7 +118,7 @@ module Spider
89
118
  good = false
90
119
 
91
120
  while !good
92
- print "#{msg} #{y}/#{n}]: "
121
+ print "#{msg} [#{y}/#{n}]: "
93
122
  res = $stdin.gets.strip
94
123
 
95
124
  good = true
@@ -109,6 +138,17 @@ module Spider
109
138
 
110
139
 
111
140
  end
141
+
142
+ def warn(msg)
143
+ puts msg
144
+ print "\n"+_("Press any key to continue ")
145
+ $stdin.getch
146
+ print "\n"
147
+ end
148
+
149
+ def interactive?
150
+ @interactive
151
+ end
112
152
 
113
153
  # def no_sync_schema
114
154
  # @no_sync = true
@@ -142,6 +182,32 @@ module Spider
142
182
  # args = models + [options]
143
183
  # sync_schema(*args)
144
184
  # end
185
+
186
+ def setup_previous_templates(templates)
187
+ msg = ""
188
+ templates.each do |t|
189
+ from = File.join(self.dir, t[:prev])
190
+ to = File.join(Spider.paths[:root], 'views', t[:dest])
191
+ unless File.file?(to)
192
+ FileUtils.mkdir_p(File.dirname(to))
193
+ FileUtils.cp(from, to)
194
+ msg += _(t[:msg]) % to
195
+ msg += "\n"
196
+ end
197
+ end
198
+ warn(msg) unless msg.blank?
199
+ end
200
+
201
+ def print_release_notes
202
+ readme = File.join(self.dir, "README.#{Spider.locale.language}")
203
+ unless File.file?(readme)
204
+ readme = File.join(self.dir, "README")
205
+ end
206
+ if File.file?(readme)
207
+ puts File.read(readme)
208
+ end
209
+
210
+ end
145
211
 
146
212
 
147
213
  end
@@ -154,7 +220,9 @@ module Spider
154
220
 
155
221
  # TODO: pass options
156
222
  def self.sync_schema(*models)
223
+ options = models.pop if models.last.is_a?(Hash)
157
224
  @sync_models = models
225
+ @sync_options = options || {}
158
226
  end
159
227
 
160
228
  def self.sync_models
@@ -1,6 +1,7 @@
1
1
  require 'spiderfw/env'
2
2
 
3
3
  require 'rubygems'
4
+ require 'backports'
4
5
  require 'find'
5
6
  require 'fileutils'
6
7
  require 'pathname'
@@ -151,6 +152,7 @@ module Spider
151
152
  FileUtils.mkdir_p(Spider.paths[:tmp])
152
153
  FileUtils.mkdir_p(Spider.paths[:var])
153
154
  FileUtils.mkdir_p(File.join(Spider.paths[:var], 'memory'))
155
+ FileUtils.mkdir_p(File.join(Spider.paths[:var], 'data'))
154
156
 
155
157
  end
156
158
 
@@ -183,7 +185,7 @@ module Spider
183
185
  end
184
186
 
185
187
  def main_process_startup
186
- if Object.const_defined?(:FSSM)
188
+ if defined?(FSSM)
187
189
  monitor = FSSM::Monitor.new
188
190
 
189
191
  monitor.path(Spider.paths[:tmp], 'restart.txt') do
@@ -192,12 +194,30 @@ module Spider
192
194
 
193
195
  end
194
196
 
197
+ if Spider.conf.get('template.cache.use_fssm')
198
+ monitor.path(Spider.paths[:root]) do
199
+ glob '**/*.shtml'
200
+ create { |base, relative| FileUtils.rm_rf(File.join(Spider.paths[:var], 'cache', 'templates')) }
201
+ update { |base, relative| FileUtils.rm_rf(File.join(Spider.paths[:var], 'cache', 'templates')) }
202
+ end
203
+ monitor.path($SPIDER_PATH) do
204
+ glob '**/*.shtml'
205
+ create { |base, relative| FileUtils.rm_rf(File.join(Spider.paths[:var], 'cache', 'templates')) }
206
+ update { |base, relative| FileUtils.rm_rf(File.join(Spider.paths[:var], 'cache', 'templates')) }
207
+ end
208
+ FileUtils.rm_rf(File.join(Spider.paths[:var], 'cache', 'templates'))
209
+ end
210
+
195
211
  @fssm_thread = Thread.new do
196
212
  monitor.run
197
213
  end
198
214
  Spider.output("Monitoring restart.txt")
215
+
199
216
  else
200
217
  Spider.output("FSSM not installed, unable to monitor restart.txt")
218
+ if Spider.conf.get('template.cache.use_fssm')
219
+ raise "Unable to use FSSM for monitoring templates; use template.cache.disable instead"
220
+ end
201
221
  end
202
222
  trap('TERM'){ Spider.main_process_shutdown; exit }
203
223
  trap('INT'){ Spider.main_process_shutdown; exit }
@@ -3,7 +3,7 @@ require 'strscan'
3
3
 
4
4
  module Spider; module TemplateBlocks
5
5
  ExpressionOutputRegexp = /\{?\{\s([^\s].*?)\s\}\}?/
6
- GettextRegexp = /_\(([^\)]+)?\)(\s%\s([^\s,]+(?:,\s*\S+\s*)?))?/
6
+ GettextRegexp = /([snp][snp]?)?_\(([^\)]+)?\)(\s%\s([^\s,]+(?:,\s*\S+\s*)?))?/
7
7
  ERBRegexp = /(<%(.+)?%>)/
8
8
 
9
9
  class Text < Block
@@ -21,9 +21,9 @@ module Spider; module TemplateBlocks
21
21
  when :expr
22
22
  c += "$out << #{vars_to_scene(val)}\n"
23
23
  when :gettext
24
- c += "$out << _('#{escape_text(val[0])}')"
25
- if val[1]
26
- c += " % [#{vars_to_scene(val[1])}]"
24
+ c += "$out << #{val[:func]}_('#{escape_text(val[:val])}')"
25
+ if val[:vars]
26
+ c += " % [#{vars_to_scene(val[:vars])}]"
27
27
  end
28
28
  c += "\n"
29
29
  when :erb
@@ -0,0 +1,25 @@
1
+ require 'spiderfw/templates/template_blocks'
2
+
3
+ module Spider; module TemplateBlocks
4
+
5
+ class TextDomain < Block
6
+
7
+ def compile(options={})
8
+ init = ""
9
+ td = @el.get_attribute('tpl:text-domain')
10
+ c = "Spider::GetText.in_domain('#{td}') do\n"
11
+ @el.remove_attribute('tpl:text-domain')
12
+ content = Spider::TemplateBlocks.parse_element(@el, @allowed_blocks, @template).compile(options)
13
+ init += content.init_code
14
+ content.run_code.each_line do |line|
15
+ c += ' '+line
16
+ end
17
+ c += "end\n"
18
+ return CompiledBlock.new(init, c)
19
+ end
20
+
21
+
22
+ end
23
+
24
+
25
+ end; end
@@ -37,7 +37,6 @@ module Spider; module TemplateBlocks
37
37
  @el.each_child do |ch|
38
38
  html += ch.to_html
39
39
  end
40
- html = "<sp:widget-content>#{html}</sp:widget-content>" unless html.empty?
41
40
  runtime_content, overrides = klass.parse_content_xml(html)
42
41
 
43
42
  template = nil
@@ -73,6 +72,7 @@ module Spider; module TemplateBlocks
73
72
  html.gsub!("'", "\\\\'")
74
73
 
75
74
  init_params = self.class.attributes_to_init_params(@el.attributes.to_hash)
75
+ runtime_content.gsub!("'", "\\\\'") if runtime_content
76
76
 
77
77
  init += "add_widget('#{id}', #{klass}.new(@request, @response), {#{init_params.join(', ')}}, '#{runtime_content}', #{t_param})\n"
78
78
  c = "yield :\"#{id}\"\n"