spiderfw 0.6.21 → 0.6.22

Sign up to get free protection for your applications and to get access to all the features.
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"