spiderfw 0.6.26 → 0.6.27

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