spiderfw 0.6.26 → 0.6.27

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 (44) hide show
  1. data/CHANGELOG +4 -0
  2. data/VERSION +1 -1
  3. data/apps/core/forms/_init.rb +1 -0
  4. data/apps/core/forms/public/date_time.js +0 -1
  5. data/apps/core/forms/public/html_area.js +1 -1
  6. data/apps/core/forms/public/text_area.js +2 -2
  7. data/apps/core/forms/widgets/form/form.rb +40 -38
  8. data/apps/core/forms/widgets/inputs/checkbox_list/checkbox_list.rb +71 -0
  9. data/apps/core/forms/widgets/inputs/checkbox_list/checkbox_list.shtml +5 -0
  10. data/apps/core/forms/widgets/inputs/date_time/date_time.rb +1 -1
  11. data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +2 -2
  12. data/apps/messenger/backends/sms/mobyt.rb +72 -0
  13. data/apps/messenger/config/options.rb +6 -1
  14. data/apps/messenger/controllers/mixins/messenger_helper.rb +6 -4
  15. data/apps/messenger/lib/backends/mobyt.rb +43 -4
  16. data/apps/messenger/test/features/mobyt.feature +29 -0
  17. data/apps/messenger/test/features/step_definitions/mobyt_steps.rb +59 -0
  18. data/lib/spiderfw/app.rb +0 -2
  19. data/lib/spiderfw/cmd/commands/model.rb +10 -6
  20. data/lib/spiderfw/config/configuration.rb +1 -4
  21. data/lib/spiderfw/config/options/spider.rb +4 -3
  22. data/lib/spiderfw/controller/http_controller.rb +5 -1
  23. data/lib/spiderfw/http/adapters/rack.rb +5 -1
  24. data/lib/spiderfw/model/base_model.rb +5 -5
  25. data/lib/spiderfw/model/identity_mapper.rb +4 -2
  26. data/lib/spiderfw/model/mappers/db_mapper.rb +5 -2
  27. data/lib/spiderfw/model/mappers/mapper.rb +15 -8
  28. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +48 -44
  29. data/lib/spiderfw/model/storage/db/connectors/mysql.rb +16 -0
  30. data/lib/spiderfw/model/storage/db/connectors/mysql2.rb +9 -0
  31. data/lib/spiderfw/setup/app_manager.rb +0 -5
  32. data/lib/spiderfw/spider.rb +34 -5
  33. data/lib/spiderfw/templates/layout.rb +6 -6
  34. data/lib/spiderfw/templates/resources/sass.rb +1 -2
  35. data/lib/spiderfw/templates/template.rb +5 -1
  36. metadata +161 -248
  37. data/apps/core/components/public/js/jquery/plugins/jquery.ui.nestedSortable.js +0 -356
  38. data/apps/messenger/test/features/sms_mobyt.feature +0 -24
  39. data/apps/messenger/test/features/step_definitions/sms_mobyt.rb +0 -21
  40. data/blueprints/.DS_Store +0 -0
  41. data/blueprints/home/.DS_Store +0 -0
  42. data/blueprints/install/.DS_Store +0 -0
  43. data/data/keys/spider.rsa +0 -27
  44. data/data/keys/spider.rsa.pub +0 -1
@@ -441,14 +441,14 @@ module Spider; module Model
441
441
  element = self.class.elements[name]
442
442
  raise "Internal error! Element method #{name} exists, but element not found" unless element
443
443
  return element.attributes[:fixed] if element.attributes[:fixed]
444
- if (element.integrated?)
444
+ if element.integrated?
445
445
  integrated = get(element.integrated_from.name)
446
446
  return integrated.send(element.integrated_from_element) if integrated
447
447
  return nil
448
448
  end
449
449
  if element_has_value?(name) || element_loaded?(name)
450
450
  val = instance_variable_get(ivar)
451
- val.set_parent(self, name) if val && element.model? && !val._parent # FIXME!!!
451
+ val.set_parent(self, name) if val && element.model?
452
452
  return val
453
453
  end
454
454
 
@@ -472,7 +472,7 @@ module Spider; module Model
472
472
  end
473
473
  val = element.model.new(val) if element.model? && !val.is_a?(BaseModel)
474
474
  end
475
- val.set_parent(self, name) if element.model? && val && val.respond_to?(:parent) && !val._parent # FIXME!!!
475
+ val.set_parent(self, name) if element.model? && val && val.respond_to?(:parent)
476
476
  return val
477
477
  end
478
478
 
@@ -1621,7 +1621,7 @@ module Spider; module Model
1621
1621
  when 'String'
1622
1622
  when 'Spider::DataTypes::Text'
1623
1623
  value = value.to_s
1624
- when 'Fixnum'
1624
+ when 'Fixnum', 'Spider::DataTypes::PK'
1625
1625
  value = value.to_i
1626
1626
  end
1627
1627
  end
@@ -1968,7 +1968,7 @@ module Spider; module Model
1968
1968
 
1969
1969
  # Returns true if no element has a value
1970
1970
  def empty?
1971
- return @_has_values
1971
+ return !@_has_values
1972
1972
  end
1973
1973
 
1974
1974
  # Sets all values of obj on the current object
@@ -95,8 +95,10 @@ module Spider; module Model
95
95
  pks.extend(HashComparison)
96
96
  @objects[obj.class] ||= {}
97
97
  if (check && (existent = @objects[obj.class][pks]) && existent.object_id != obj.object_id)
98
- #debugger if fail_if_exists
99
- raise IdentityMapperException, "A different instance of the same object #{obj.inspect} already exists in the identity mapper" if fail_if_exists
98
+ if fail_if_exists
99
+ #debugger
100
+ raise IdentityMapperException, "A different instance of the same object #{obj.class}(#{obj.primary_keys.inspect}) already exists in the identity mapper"
101
+ end
100
102
  existent.merge!(obj)
101
103
  return existent
102
104
  else
@@ -464,7 +464,7 @@ module Spider; module Model; module Mappers
464
464
  has_join = false
465
465
  cur.each do |cur_join|
466
466
  if (cur_join[:keys] == join[:keys] && cur_join[:conditions] == join[:conditions])
467
- cur_join[:type] = :left if join[:type] == :left
467
+ cur_join[:type] = :left if join[:type] == :left && !join[:order]
468
468
  has_join = true
469
469
  break
470
470
  end
@@ -880,6 +880,9 @@ module Spider; module Model; module Mappers
880
880
  fields << [field, direction]
881
881
  else
882
882
  el_joins, el_model, el = get_deep_join(order_element, :left)
883
+ el_joins.each do |el_j|
884
+ el_j[:order] = true
885
+ end
883
886
  if el.model?
884
887
  if el_model.mapper.have_references?(el) || el.model.storage != storage
885
888
  el.model.primary_keys.each do |pk|
@@ -1195,7 +1198,7 @@ module Spider; module Model; module Mappers
1195
1198
  column_type = element.attributes[:db_column_type] || storage_column_type(key_storage_type, key_attributes)
1196
1199
  unless column
1197
1200
  column_name = element.attributes[:db_column_name] || @storage.column_name("#{element.name}_#{key.name}")
1198
- column_attributes = @storage.column_attributes(key_type, key_attributes)
1201
+ column_attributes = @storage.column_attributes(base_type(key_type), key_attributes)
1199
1202
  column = Field.new(schema.table, column_name, column_type, column_attributes)
1200
1203
  end
1201
1204
  column.type ||= column_type
@@ -168,10 +168,10 @@ module Spider; module Model
168
168
  obj.set(el, set_data)
169
169
  end
170
170
  end
171
- if (!el.integrated? && el.required? && (mode == :insert || obj.element_modified?(el)) && !obj.element_has_value?(el))
172
- raise RequiredError.new(el)
171
+ if !el.integrated? && el.required? && (mode == :insert || obj.element_modified?(el)) && !obj.element_has_value?(el)
172
+ raise RequiredError.new(el)
173
173
  end
174
- if (el.unique? && !el.integrated? && obj.element_modified?(el) && curr_val = obj.get(el))
174
+ if el.unique? && !el.integrated? && obj.element_modified?(el) && curr_val = obj.get(el)
175
175
  existent = @model.where(el.name => curr_val)
176
176
  if (mode == :insert && existent.length > 0) || (mode == :update && existent.length > 1)
177
177
  raise NotUniqueError.new(el)
@@ -252,7 +252,6 @@ module Spider; module Model
252
252
  def after_save(obj, mode)
253
253
  obj.reset_modified_elements
254
254
  save_associations(obj, mode)
255
-
256
255
  end
257
256
 
258
257
  # Hook called after a succesful save, when the object is not in save mode (see {BaseModel#save_mode}) anymore.
@@ -338,7 +337,7 @@ module Spider; module Model
338
337
  # @return [void]
339
338
  def save_associations(obj, mode)
340
339
  association_elements.select{ |el| obj.element_has_value?(el) }.each do |el|
341
- save_element_associations(obj, el, mode)
340
+ save_element_associations(obj, el, mode) # if obj.element_modified?(el)
342
341
  end
343
342
  end
344
343
 
@@ -729,7 +728,14 @@ module Spider; module Model
729
728
  seen[obj] = true
730
729
  end
731
730
  res = path.empty? ? obj : obj.all_children(path)
732
- raise RuntimeError, "Broken object path" if (obj && !path.empty? && res.length < 1)
731
+ if obj && !path.empty? && res.length < 1
732
+ if Spider.runmode == 'production'
733
+ Spider.logger.error("Internal error: broken object path")
734
+ res = [orig_obj]
735
+ else
736
+ raise RuntimeError, "Internal error: broken object path"
737
+ end
738
+ end
733
739
  res = QuerySet.new(@model, res) unless res.is_a?(QuerySet)
734
740
  res = res.select{ |obj| obj.primary_keys_set? }
735
741
  return res
@@ -1335,7 +1341,7 @@ module Spider; module Model
1335
1341
  # Makes the objects' mapper run the task
1336
1342
  # @return [void]
1337
1343
  def execute
1338
- debug_str = "Executing #{@action} on #{@object.inspect}"
1344
+ debug_str = "Executing #{@action} on #{@object.class}(#{@object.primary_keys.inspect})"
1339
1345
  debug_str += " (#{@params.inspect})" unless @params.empty?
1340
1346
  Spider::Logger.debug debug_str
1341
1347
  @object.mapper.execute_action(@action, @object, @params)
@@ -1415,7 +1421,8 @@ module Spider; module Model
1415
1421
  end
1416
1422
  def message
1417
1423
  Spider::GetText.in_domain('spider') do
1418
- _(self.class.msg) % @element.label
1424
+ element = @element.is_a?(Element) ? @element.label : @element
1425
+ _(self.class.msg) % element
1419
1426
  end
1420
1427
  end
1421
1428
  def to_s
@@ -74,7 +74,7 @@ module Spider; module Model; module Storage; module Db
74
74
  class << self; attr_reader :reserved_kewords, :type_synonyms, :safe_conversions, :field_types, :field_flags end
75
75
 
76
76
  def self.new_connection(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
77
- conn = ::Mysql.new(host, user, passwd, db, port, sock, flag)
77
+ conn = ::Mysql.new(host, user, passwd, db, port.to_i, sock, flag)
78
78
  conn.autocommit(true)
79
79
  conn.query("SET NAMES 'utf8'")
80
80
  return conn
@@ -222,56 +222,60 @@ module Spider; module Model; module Storage; module Db
222
222
  query_finished
223
223
  release if curr[:conn] && !in_transaction?
224
224
  end
225
- end
225
+ end
226
226
 
227
- def prepare(sql)
228
- debug("mysql preparing: #{sql}")
229
- return curr[:stmt] = connection.prepare(sql)
230
- end
227
+ def prepare(sql)
228
+ debug("mysql preparing: #{sql}")
229
+ return curr[:stmt] = connection.prepare(sql)
230
+ end
231
231
 
232
- def execute_statement(stmt, *bind_vars)
233
- stmt.execute(*bind_vars)
234
- end
232
+ def execute_statement(stmt, *bind_vars)
233
+ stmt.execute(*bind_vars)
234
+ end
235
235
 
236
- def total_rows
237
- return curr[:total_rows]
238
- end
236
+ def total_rows
237
+ return curr[:total_rows]
238
+ end
239
239
 
240
- def prepare_value(type, value)
241
- value = super(type, value)
242
- return value unless value
243
- case type.name
244
- when 'String'
245
- return value.to_s
246
- when 'Date'
247
- return value.strftime("%Y-%m-%d")
248
- when 'DateTime'
249
- return value.strftime("%Y-%m-%dT%H:%M:%S")
250
- when 'Time'
251
- return value.strftime("%H:%M:%S")
252
- when 'Fixnum'
253
- return value.to_i
254
- end
255
- return value
240
+ def prepare_value(type, value)
241
+ value = super(type, value)
242
+ return value unless value
243
+ case type.name
244
+ when 'String'
245
+ return value.to_s
246
+ when 'Date'
247
+ return value.strftime("%Y-%m-%d")
248
+ when 'DateTime'
249
+ return value.strftime("%Y-%m-%dT%H:%M:%S")
250
+ when 'Time'
251
+ return value.strftime("%H:%M:%S")
252
+ when 'Fixnum'
253
+ return value.to_i
254
+ end
255
+ return value
256
256
  end
257
257
 
258
- def value_to_mapper(type, value)
259
- return unless value
260
- case type.name
261
- when 'DateTime'
262
- @@time_offset ||= DateTime.now.offset
263
- return type.civil(value.year, value.month, value.day, value.hour, value.minute, value.second, @@time_offset)
264
- when 'Date'
265
- return type.civil(value.year, value.month, value.day)
266
- when 'Time'
267
- return type.local(2000, 1, 1, value.hour, value.minute, value.second)
268
- end
269
- return super(type, value)
270
- end
258
+ def value_to_mapper(type, value)
259
+ return unless value
260
+ begin
261
+ case type.name
262
+ when 'DateTime'
263
+ @@time_offset ||= DateTime.now.offset
264
+ return type.civil(value.year, value.month, value.day, value.hour, value.minute, value.second, @@time_offset)
265
+ when 'Date'
266
+ return type.civil(value.year, value.month, value.day)
267
+ when 'Time'
268
+ return type.local(2000, 1, 1, value.hour, value.minute, value.second)
269
+ end
270
+ return super(type, value)
271
+ rescue
272
+ return nil
273
+ end
274
+ end
271
275
 
272
- def last_insert_id
273
- curr[:last_insert_id]
274
- end
276
+ def last_insert_id
277
+ curr[:last_insert_id]
278
+ end
275
279
 
276
280
  ##############################################################
277
281
  # SQL methods #
@@ -0,0 +1,16 @@
1
+ require 'mysql'
2
+
3
+ module Spider; module Model; module Storage; module Db; module Connectors
4
+
5
+ module Mysql
6
+
7
+ def self.new_connection(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
8
+ conn = ::Mysql2::Client.new(
9
+ :host => host, :username => user, :password => passwd, :database => db, :port => port, :socket => sock
10
+ )
11
+ return conn
12
+ end
13
+
14
+ end
15
+
16
+ end; end; end; end; end
@@ -0,0 +1,9 @@
1
+ require 'mysql2'
2
+
3
+ module Spider; module Model; module Storage; module Db; module Connectors
4
+
5
+ module Mysql2
6
+
7
+ end
8
+
9
+ end; end; end; end; end
@@ -496,11 +496,6 @@ module Spider
496
496
 
497
497
  private
498
498
 
499
- def git_command(command)
500
- #`GIT_SSH='ssh -i #{File.join(Spider.paths[:data], 'keys', 'spider.rsa')}' git #{command}`
501
- `git #{command}`
502
- end
503
-
504
499
  def reset_git_env
505
500
  ENV['GIT_WORK_TREE'] = nil
506
501
  ENV["GIT_INDEX_FILE"] = nil
@@ -191,6 +191,7 @@ module Spider
191
191
  if Spider.conf.get('template.cache.reload_on_restart')
192
192
  FileUtils.touch("#{Spider.paths[:tmp]}/templates_reload.txt")
193
193
  end
194
+ check_clear_caches
194
195
  unless Spider.runmode == 'test'
195
196
  if domain = Spider.conf.get('site.domain')
196
197
  ssl_port = Spider.conf.get('site.ssl') ? Spider.conf.get('site.ssl_port') : nil
@@ -223,7 +224,6 @@ module Spider
223
224
  monitor.path(Spider.paths[:tmp], 'restart.txt') do
224
225
  create { |base, relative| Process.kill 'HUP', $$ }
225
226
  update { |base, relative| Process.kill 'HUP', $$ }
226
-
227
227
  end
228
228
 
229
229
  if Spider.conf.get('template.cache.use_fssm')
@@ -373,13 +373,38 @@ module Spider
373
373
  def current
374
374
  Spider::Request.current
375
375
  end
376
+
377
+
378
+ def check_clear_caches
379
+ if File.exists?(Spider.paths[:clear_file])
380
+ stat = File.stat(Spider.paths[:clear_file])
381
+ last_reset_file = File.join(Spider.paths[:var], 'cache_cleared')
382
+ last_stat = File.exists?(last_reset_file) ? File.stat(last_reset_file) : nil
383
+ if !last_stat || stat.mtime > last_stat.mtime
384
+ Spider.clear_caches!
385
+ end
386
+ end
387
+ end
388
+
389
+ def clear_caches!
390
+ Spider.logger.info("Clearing caches")
391
+ FileUtils.touch(File.join(Spider.paths[:var], 'cache_cleared'))
392
+ Dir.new(Spider::Layout.compiled_folder_path).each do |entry|
393
+ next if ['.', '..'].include?(entry)
394
+ ::FileUtils.rm_rf(File.join(Spider::Layout.compiled_folder_path, entry))
395
+ end
396
+ FileUtils.rm_rf(Spider::Template.cache_path)
397
+ end
398
+
399
+ def multithread?
400
+ return false if $SPIDER_SINGLE_THREADED || Spider.current[:multithread] == false
401
+ return true
402
+ end
376
403
 
377
404
  # Called when a new request is started.
378
405
  # @return [void]
379
406
  def request_started
380
407
  @request_mutex.lock if (@request_mutex)
381
- if File.file?(Spider.paths[:reset_file])
382
- end
383
408
  Spider::Request.current = {
384
409
  :_start => Time.now
385
410
  }
@@ -461,7 +486,7 @@ module Spider
461
486
  @paths[:data] = File.join(root, 'data')
462
487
  @paths[:log] = File.join(@paths[:var], 'log')
463
488
  @paths[:restart_file] = File.join(@paths[:tmp], 'restart.txt')
464
- @paths[:reset_file] = File.join(@paths[:tmp], 'reset.txt')
489
+ @paths[:clear_file] = File.join(@paths[:tmp], 'clear.txt')
465
490
  @paths.each do |k, path|
466
491
  @paths[k] = File.expand_path(File.readlink(path)) if File.symlink?(path)
467
492
  end
@@ -1084,9 +1109,13 @@ module Spider
1084
1109
  # so use cached locale if Locale.current fails
1085
1110
  l = @current_locale
1086
1111
  l ||= Locale::Tag.parse(Spider.conf.get('locale')) if Spider.conf.get('locale')
1087
- l ||= Locale::Tag.parse('en')
1112
+ l ||= Locale::Tag.parse(Spider.conf.get('i18n.default_locale'))
1088
1113
  end
1089
1114
  end
1115
+
1116
+ def locale=(val)
1117
+ Locale.current = Locale::Tag.parse(val)
1118
+ end
1090
1119
 
1091
1120
  # @param [Locale::Tag]
1092
1121
  # @return [Spider::I18n::Provider] A provider for the given locale
@@ -15,7 +15,7 @@ module Spider
15
15
  end
16
16
 
17
17
  def render(*args)
18
- $PUB_URL = Spider::HomeController.pub_url
18
+ $PUB_URL = Spider.home.controller.pub_url
19
19
  prepare_assets unless @assets_prepared
20
20
  super
21
21
  end
@@ -67,7 +67,7 @@ module Spider
67
67
  assets[:js].each do |ass|
68
68
  if ass[:cpr]
69
69
  compressed = compress_javascript(ass)
70
- @template_assets[:js] << Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+compressed
70
+ @template_assets[:js] << Spider.home.controller.pub_url+'/'+COMPILED_FOLDER+'/'+compressed
71
71
  else
72
72
  ass[:src] = ass[:cdn] if ass[:cdn] && use_cdn
73
73
  @template_assets[:js] << ass[:src]
@@ -76,7 +76,7 @@ module Spider
76
76
  assets[:css].each do |ass|
77
77
  if ass[:cpr]
78
78
  compressed = compress_css(ass)
79
- @template_assets[:css] << Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+compressed
79
+ @template_assets[:css] << Spider.home.controller.pub_url+'/'+COMPILED_FOLDER+'/'+compressed
80
80
  else
81
81
  ass[:src] = ass[:cdn] if ass[:cdn] && use_cdn
82
82
  is_dyn = ass[:if_ie_lte] || ass[:media] || ass[:rel]
@@ -151,7 +151,7 @@ module Spider
151
151
  end
152
152
  src = name
153
153
  end
154
- ass[:src] = Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+src
154
+ ass[:src] = Spider.home.controller.pub_url+'/'+COMPILED_FOLDER+'/'+src
155
155
  assets[type] << ass
156
156
  else # needs compression
157
157
  name = ass[:compress] || @cname
@@ -196,7 +196,7 @@ module Spider
196
196
 
197
197
  def all_assets
198
198
  tpl_assets = @template.is_a?(Layout) ? @template.all_assets : @template.assets
199
- assets = tpl_assets + self.assets
199
+ assets = self.assets + tpl_assets
200
200
  if @only_asset_profiles
201
201
  assets = assets.select{ |ass| ass[:profiles] && !(ass[:profiles] & @only_asset_profiles).empty? }
202
202
  end
@@ -209,7 +209,7 @@ module Spider
209
209
  COMPILED_FOLDER = '_c'
210
210
 
211
211
  def self.compiled_folder_path
212
- File.join(Spider::HomeController.pub_path, COMPILED_FOLDER)
212
+ File.join(Spider.home.controller.pub_path, COMPILED_FOLDER)
213
213
  end
214
214
 
215
215
  def asset_gettext_messages_file(path)
@@ -90,8 +90,7 @@ module Spider
90
90
  config = Compass::Configuration::Data.new(:spider, options)
91
91
  Compass.add_project_configuration(config)
92
92
  compiler = Compass::Compiler.new(work_dir, File.dirname(src), File.dirname(dest), options)
93
-
94
- compiler.compile(src, dest) if compiler.out_of_date?
93
+ compiler.run
95
94
  else
96
95
  engine = Sass::Engine.for_file(src, {})
97
96
  output = engine.render
@@ -45,9 +45,12 @@ module Spider
45
45
 
46
46
  class << self
47
47
 
48
+ def cache_path
49
+ File.join(Spider.paths[:var], 'cache', 'templates')
50
+ end
48
51
  # Returns the class TemplateCache instance
49
52
  def cache
50
- @@cache ||= TemplateCache.new(File.join(Spider.paths[:var], 'cache', 'templates'))
53
+ @@cache ||= TemplateCache.new(self.cache_path)
51
54
  end
52
55
 
53
56
  # Sets allowed blocks
@@ -408,6 +411,7 @@ module Spider
408
411
  raise "Asset type not given for #{src}" unless type
409
412
  search_classes = [asset_owner]
410
413
  search_classes << @definer_class if @definer_class
414
+ search_classes << Spider.home
411
415
  dfnr = @definer_class.superclass if @definer_class && @definer_class.respond_to?(:superclass)
412
416
  while dfnr && dfnr < Spider::Widget
413
417
  search_classes << dfnr