spiderfw 0.6.24 → 0.6.25

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.24
1
+ 0.6.25
@@ -689,6 +689,19 @@ jQuery.parseISODate = function(iso){
689
689
  else return null;
690
690
  };
691
691
 
692
+ // Same as toISOString, but without time, and ignoring timezone
693
+ Date.prototype.toISODate = (function(){
694
+ function t(i){return i<10?"0"+i:i;};
695
+ return function(){
696
+ return "".concat(
697
+ this.getFullYear(), "-",
698
+ t(this.getMonth() + 1), "-",
699
+ t(this.getDate())
700
+ );
701
+ };
702
+ })();
703
+
704
+
692
705
  if (!Date.prototype.toISOString){
693
706
  Date.prototype.toISOString = (function(){
694
707
  function t(i){return i<10?"0"+i:i;};
@@ -785,4 +798,4 @@ function basename(path){
785
798
 
786
799
  function dirname(path){
787
800
  return path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '');
788
- }
801
+ }
@@ -148,42 +148,30 @@ module Spider; module Forms
148
148
 
149
149
  def load_widgets(template=@template)
150
150
  super
151
- if @action == :sub
152
- if @sub_element.multiple?
153
- @crud = Spider::Components::Crud.new(@request, @response)
154
- @crud.id = "crud_#{@sub_element.name.to_s}"
155
- @crud.model = @sub_element.model
156
- add_widget(@crud)
157
- @scene.crud = @crud
158
- @obj = load
159
- cond = {}
160
- debugger
161
- if @sub_element.integrated?
162
- @sub_element.integrated_from.model.primary_keys.each do |key|
163
- cond[@sub_element.reverse.to_s+'.'+key.name.to_s] = @obj.get("#{@sub_element.integrated_from.name}.#{key.name}")
164
- end
165
- else
166
- @model.primary_keys.each do |key|
167
- cond[@sub_element.reverse.to_s+'.'+key.name.to_s] = @obj.get(key)
168
- end
151
+ if (@action == :sub)
152
+ @crud = Spider::Components::Crud.new(@request, @response)
153
+ @crud.id = "crud_#{@sub_element.name.to_s}"
154
+ @crud.model = @sub_element.model
155
+ add_widget(@crud)
156
+ @scene.crud = @crud
157
+ @obj = load
158
+ cond = {}
159
+ if @sub_element.integrated?
160
+ @sub_element.integrated_from.model.primary_keys.each do |key|
161
+ cond[@sub_element.reverse.to_s+'.'+key.name.to_s] = @obj.get("#{@sub_element.integrated_from.name}.#{key.name}")
169
162
  end
170
- @crud.fixed = cond
171
- sub_elements = []
172
- #sub_elements += @sub_element.model.primary_keys.map{ |k| k.name }
173
- @sub_element.model.elements_array.each do |el|
174
- sub_elements << el.name unless el.integrated? || el.model == @model
163
+ else
164
+ @model.primary_keys.each do |key|
165
+ cond[@sub_element.reverse.to_s+'.'+key.name.to_s] = @obj.get(key)
175
166
  end
176
- @crud.attributes[:table_elements] = sub_elements
177
- # else
178
- # @crud = Spider::Forms::Form.new(@request, @response)
179
- # @form.id = "crud_#{@sub_element.name.to_s}"
180
- # @form.model = @sub_element.model
181
- # add_widget(@crud)
182
- # @scene.crud = @crud
183
- # @obj.load
184
- # debugger
185
- # @form.pk = @obj.get(@sub_element).id
186
167
  end
168
+ @crud.fixed = cond
169
+ sub_elements = []
170
+ #sub_elements += @sub_element.model.primary_keys.map{ |k| k.name }
171
+ @sub_element.model.elements_array.each do |el|
172
+ sub_elements << el.name unless el.integrated? || el.model == @model
173
+ end
174
+ @crud.attributes[:table_elements] = sub_elements
187
175
  else
188
176
  create_inputs
189
177
  end
@@ -263,7 +251,7 @@ module Spider; module Forms
263
251
  if ([:choice, :multiple_choice, :state, :multiple_state].include?(el.association) && !el.extended?)
264
252
  widget_type = el.type.attributes[:estimated_size] && el.type.attributes[:estimated_size] > 30 ?
265
253
  SearchSelect : Select
266
- elsif @attributes[:show_related] && @pk
254
+ elsif @attributes[:show_related] && @pk && el.multiple?
267
255
  @sub_links[el.name] = sub_link(el)
268
256
  end
269
257
  end
data/lib/spiderfw/app.rb CHANGED
@@ -516,6 +516,11 @@ END_OF_EVAL
516
516
  def self.parse_hash(h)
517
517
  spec = self.new
518
518
  h.each do |key, value|
519
+ unless spec.respond_to?(:"#{key}")
520
+ Spider.output("Bad spec key #{key} in:", :ERROR)
521
+ Spider.output(h.inspect, :ERROR)
522
+ next
523
+ end
519
524
  if value.is_a?(Array)
520
525
  spec.send(:"#{key}", *value)
521
526
  else
@@ -544,6 +549,11 @@ END_OF_EVAL
544
549
  self.gems_optional.map{ |g| g.is_a?(Array) ? g.first : g }
545
550
  end
546
551
 
552
+ def branch(val=nil)
553
+ @branch = val if val
554
+ @branch
555
+ end
556
+
547
557
  end
548
558
 
549
559
  # Helper class to sort the runtime dependencies of an app using TSort.
@@ -109,6 +109,7 @@ module Spider::CommandLine
109
109
  install.short_desc = _("Install an app")
110
110
  install.options = CmdParse::OptionParserWrapper.new do |opt|
111
111
  opt.on("--[no-]git", _("Use git for installing apps"), "-g"){ |r| @git = r }
112
+ opt.on("--rw", _("Use read-write git repository"), "-w"){ |rw| @rw = true }
112
113
  opt.on("--no-dependencies", _("Don't install other apps this one depends on"), "-d"){ |d|
113
114
  @no_deps = true
114
115
  }
@@ -130,7 +131,8 @@ module Spider::CommandLine
130
131
  require 'spiderfw/setup/app_manager'
131
132
  options = {
132
133
  :use_git => @git, :all => @all, :no_deps => @no_deps, :optional => @optional,
133
- :no_gems => @no_gems, :no_optional_gems => @no_optional_gems, :no_activate => @no_activate
134
+ :no_gems => @no_gems, :no_optional_gems => @no_optional_gems, :no_activate => @no_activate,
135
+ :rw => @rw
134
136
  }
135
137
  options[:url] = @server_url if @server_url
136
138
  options[:branch] = @branch if @branch
@@ -37,7 +37,7 @@ module Spider::CommandLine
37
37
  if @opts[:irb]
38
38
  ENV['SPIDER_RUNMODE'] = $SPIDER_RUNMODE if ($SPIDER_RUNMODE)
39
39
  ENV['SPIDER_CONFIG_SETS'] = $SPIDER_CONFIG_SETS.join(',') if ($SPIDER_CONFIG_SETS)
40
- exec("#{@opts[:irb]} -I #{$SPIDER_LIB} -r spiderfw")
40
+ exec("#{@opts[:irb]} -I #{$SPIDER_LIB} -r spiderfw/init")
41
41
  elsif @opts[:ripl]
42
42
  require 'ripl/irb'
43
43
  require 'ripl/multi_line'
@@ -68,4 +68,4 @@ module Spider::CommandLine
68
68
 
69
69
  end
70
70
 
71
- end
71
+ end
@@ -121,7 +121,7 @@ module Spider
121
121
  def url(action=nil)
122
122
  u = @default_route || ''
123
123
  u += "/#{action}" if action
124
- if @default_dispatcher
124
+ if @default_dispatcher && @default_dispatcher != self
125
125
  u = @default_dispatcher.url + '/' + u
126
126
  elsif self.app
127
127
  u = self.app.url + '/' + u
@@ -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
@@ -17,9 +17,13 @@ module Spider; module Model
17
17
  Thread.current[:storages][type] ||= {}
18
18
  return Thread.current[:storages][type][url] if Thread.current[:storages][type][url]
19
19
  klass = nil
20
- matches = url.match(/^(.+?):\/\/(.+)/)
21
- adapter = matches[1]
22
- rest = matches[2]
20
+ begin
21
+ matches = url.match(/^(.+?):\/\/(.+)/)
22
+ adapter = matches[1]
23
+ rest = matches[2]
24
+ rescue => exc
25
+ Spider.output _("The connection string %s is not correct") % url, :error
26
+ end
23
27
  if adapter =~ /(.+):(.+)/
24
28
  connector = $1
25
29
  adapter = $2
@@ -125,7 +125,7 @@ module Spider
125
125
  use_git = false
126
126
  if spec.git_repo && !options[:no_git]
127
127
  app_path = File.join(@home_path, "apps/#{spec.app_id}")
128
- use_git = true if File.directory?(File.join(app_path, '.git'))
128
+ use_git = true if File.exists?(File.join(app_path, '.git'))
129
129
  end
130
130
  if use_git && !self.class.git_available?
131
131
  Spider.output _("Can't update app #{spec.id} via git, since git gem is not available") % spec.app_id, :ERROR
@@ -267,7 +267,7 @@ module Spider
267
267
  if ::File.directory?(File.join(@home_path, '.git'))
268
268
  repo = Git.open(@home_path)
269
269
  end
270
- repo_url = spec.git_repo_rw || spec.git_repo
270
+ repo_url = options[:rw] ? spec.git_repo_rw : spec.git_repo
271
271
  Spider.output _("Fetching %s from %s") % [spec.app_id, repo_url]
272
272
 
273
273
  if options[:ssh_user] && repo_url =~ /ssh:\/\/([^@]+@)?(.+)/
@@ -281,21 +281,33 @@ module Spider
281
281
  `git submodule init`
282
282
  `git submodule update`
283
283
  repo.add(['.gitmodules', "apps/#{spec.id}"])
284
- repo.commit(_("Added app %s") % spec.id)
284
+ begin
285
+ repo.commit(_("Added app %s") % spec.id)
286
+ rescue Git::GitExecuteError => exc
287
+ # If no changes added, it means the app was deleted and then reinstalled,
288
+ # no need to raise an exception
289
+ raise unless exc.message =~ /no changes added/
290
+ end
285
291
  end
286
292
  else
287
293
  Dir.chdir(File.join(@home_path, 'apps')) do
288
294
  Git.clone(repo_url, spec.id)
289
295
  end
290
296
  end
297
+ app_path = File.join(@home_path, "apps", spec.id)
298
+ if spec.branch != 'master'
299
+ reset_git_env
300
+ Dir.chdir(app_path) do
301
+ `git checkout #{spec.branch}`
302
+ end
303
+ end
291
304
  end
292
305
 
293
306
  def pack_install(spec, options={})
294
307
  require 'rubygems/package'
295
308
  client = AppServerClient.new(spec.app_server)
296
309
  print _("Fetching %s from server... ") % spec.app_id
297
- options[:branch] ||= 'master'
298
- tmp_path = client.fetch_app(spec.app_id, options[:branch])
310
+ tmp_path = client.fetch_app(spec.app_id, spec.branch)
299
311
  Spider.output _("Fetched.")
300
312
  dest = File.join(@home_path, "apps/#{spec.app_id}")
301
313
  FileUtils.mkdir_p(dest)
@@ -336,9 +348,14 @@ module Spider
336
348
  app_path = File.join(@home_path, "apps", spec.id)
337
349
  app_repo = Git.open(app_path)
338
350
  Spider.output _("Updating %s from %s") % [spec.app_id, spec.git_repo]
339
- options[:branch] ||= 'master'
340
351
  Dir.chdir(app_path) do
341
- app_repo.branch('master').checkout
352
+ response = `git status`
353
+ unless response =~ /working directory clean/
354
+ Spider.output(_("You have local modifications in the #{spec.id} app"), :ERROR)
355
+ Spider.output(_("Commit them or reset repo to update"), :ERROR)
356
+ exit
357
+ end
358
+ `git checkout master`
342
359
  end
343
360
  response = err = nil
344
361
  Dir.chdir(app_path) do
@@ -348,9 +365,10 @@ module Spider
348
365
  Spider.output err, :ERROR
349
366
  raise "Unable to update"
350
367
  end
351
- Dir.chdir(app_path) do
352
- app_repo.reset('HEAD', :hard => true)
353
- app_repo.branch('master').checkout
368
+ if spec.branch != 'master'
369
+ Dir.chdir(app_path) do
370
+ `git checkout #{spec.branch}`
371
+ end
354
372
  end
355
373
  # response = err = nil
356
374
  # Dir.chdir(app_path) do
@@ -476,6 +494,16 @@ module Spider
476
494
  end
477
495
 
478
496
 
497
+ private
498
+
499
+ def reset_git_env
500
+ ENV['GIT_WORK_TREE'] = nil
501
+ ENV["GIT_INDEX_FILE"] = nil
502
+ ENV["GIT_WORK_TREE"] = nil
503
+ ENV["GIT_DIR"] = nil
504
+ end
505
+
506
+
479
507
  end
480
508
 
481
509
  end
@@ -197,7 +197,7 @@ module Spider
197
197
  end
198
198
  ask _("Database type: "), :db_type, :choices => ['sqlite', 'mysql', 'oracle'], \
199
199
  :default => url_db_type
200
- break unless @db_type
200
+ return unless @db_type
201
201
  unless @db_type == 'sqlite'
202
202
  db = wizard_instance(get_db_wizard(@db_type))
203
203
  db.parse_url(conf["url"]) if conf && conf["url"] && @db_type == url_db_type
@@ -33,7 +33,7 @@ module Spider
33
33
  assets = {:css => [], :js => []}
34
34
  compress_assets = {:js => {}, :css => {}}
35
35
  seen = {}
36
- js_messages = []
36
+ js_translations = {}
37
37
  use_cdn = Spider.conf.get('assets.use_cdn')
38
38
  cname = File.basename(@path, '.layout.shtml')
39
39
  cname = File.basename(cname, '.shtml')
@@ -49,7 +49,7 @@ module Spider
49
49
 
50
50
  ass = compile_asset(ass)
51
51
 
52
- res = prepare_asset(ass, compress_assets, js_messages)
52
+ res = prepare_asset(ass, compress_assets, js_translations)
53
53
  assets[:css] += res[:css]
54
54
  assets[:js] += res[:js]
55
55
 
@@ -87,18 +87,16 @@ module Spider
87
87
  @content[:yield_to] = @template
88
88
  @scene.assets = @template_assets
89
89
  @scene.extend(LayoutScene)
90
- if js_messages.empty?
90
+ if js_translations.empty?
91
91
  @scene.js_translations = ""
92
92
  else
93
- translations = {}
94
- js_messages.each{ |msg| translations[msg] = _(msg) }
95
- @scene.js_translations = "var translations = #{translations.to_json}"
93
+ @scene.js_translations = "var translations = #{js_translations.to_json}"
96
94
  end
97
95
 
98
96
  @assets_prepared = true
99
97
  end
100
98
 
101
- def prepare_asset(ass, compress_assets={}, js_messages=[])
99
+ def prepare_asset(ass, compress_assets={}, js_translations={})
102
100
  type = ass[:type].to_sym
103
101
  assets = {:css => [], :js => []}
104
102
  pub_dest = nil
@@ -168,7 +166,13 @@ module Spider
168
166
  if ass[:gettext] && type == :js
169
167
  msg_path = asset_gettext_messages_file(ass[:path])
170
168
  if File.exists?(msg_path)
171
- js_messages += JSON.parse(File.read(msg_path))
169
+ js_messages = JSON.parse(File.read(msg_path))
170
+ Spider::GetText.in_domain(ass[:app].short_name) do
171
+ js_messages.each{ |msg|
172
+ next if js_translations.key?(msg)
173
+ js_translations[msg] = _(msg)
174
+ }
175
+ end
172
176
  else
173
177
  Spider.logger.warn("Javascript Gettext file #{msg_path} not found")
174
178
  end
@@ -29,6 +29,7 @@ module Spider
29
29
  attr_accessor :runtime_overrides
30
30
  attr_reader :overrides, :path, :subtemplates, :widgets, :content
31
31
  attr_accessor :asset_profiles
32
+ attr_accessor :subtemplate_of
32
33
 
33
34
  @@registered = {}
34
35
  @@widget_plugins = {}
@@ -258,7 +259,12 @@ module Spider
258
259
  end
259
260
  end
260
261
  @compiled = self.class.cache.fetch(cache_path) do
261
- compile(:mode => @mode)
262
+ begin
263
+ compile(:mode => @mode)
264
+ rescue Exception
265
+ Spider.logger.error("Failed compilation of template #{@path}:")
266
+ raise
267
+ end
262
268
  end
263
269
  end
264
270
 
@@ -268,7 +274,7 @@ module Spider
268
274
  compiled.source_path = @path
269
275
  doc = open(@path){ |f| Hpricot.XML(f) }
270
276
  root = get_el(doc)
271
- el = process_tags(root)
277
+ process_tags(root)
272
278
  apply_overrides(root)
273
279
  root.search('tpl:placeholder').remove # remove empty placeholders
274
280
  owner_class = @owner ? @owner.class : @owner_class
@@ -288,7 +294,6 @@ module Spider
288
294
  root.search('.to_delete').remove
289
295
  root.search('tpl:assets').each do |ass|
290
296
  if wattr = ass.get_attribute('widgets')
291
- widgets = []
292
297
  wattr.split(/,\s*/).each do |w|
293
298
  w_templates = nil
294
299
  if w =~ /(\.+)\((.+)\)/
@@ -332,6 +337,7 @@ module Spider
332
337
  compiled.block = root_block.compile(options)
333
338
  subtemplates.each do |id, sub|
334
339
  sub.owner_class = @subtemplate_owners[id]
340
+ sub.subtemplate_of = options[:owner_class]
335
341
  compiled.subtemplates[id] = sub.compile(options.merge({:mode => :widget})) # FIXME! :mode => :widget is wrong, it's just a quick kludge
336
342
  @assets += compiled.subtemplates[id].assets
337
343
  end
@@ -510,6 +516,7 @@ module Spider
510
516
  ext_owner = @owner.class
511
517
  ext_app = ext_owner.app
512
518
  end
519
+ @extended_app = ext_app
513
520
  ext_search_paths = nil
514
521
  if ext_owner && ext_owner.respond_to?(:template_paths)
515
522
  ext_search_paths = ext_owner.template_paths
@@ -522,7 +529,6 @@ module Spider
522
529
  assets += root.children_of_type('tpl:assets')
523
530
  end
524
531
  @dependencies << ext
525
- tpl = Template.new(ext)
526
532
  root = get_el(ext)
527
533
  if ext_app.short_name != our_domain
528
534
  root.set_attribute('tpl:text-domain', ext_app.short_name)
@@ -827,6 +833,18 @@ module Spider
827
833
  if override.name == 'tpl:delete'
828
834
  found.remove
829
835
  else
836
+ td = nil
837
+ orig_td = nil
838
+ if @extended_app
839
+ td = @definer_class.respond_to?(:app) ? @definer_class.app.short_name : nil
840
+ orig_td = @extended_app.short_name
841
+ elsif @subtemplate_of
842
+ td = @subtemplate_of.respond_to?(:app) ? @subtemplate_of.app.short_name : nil
843
+ orig_td = @definer_class.respond_to?(:app) ? @definer_class.app.short_name : nil
844
+ end
845
+ if td && orig_td && td != orig_td
846
+ override.innerHTML = '<tpl:pass tpl:text-domain="'+td+'">'+override.innerHTML+'</tpl:pass>'
847
+ end
830
848
  found.each do |f|
831
849
  o_doc = nil
832
850
  if override.name == 'tpl:override-content'
@@ -837,10 +855,16 @@ module Spider
837
855
  if o_search = o.get_attribute('search')
838
856
  o_doc ||= Hpricot("<o>#{overridden}</o>")
839
857
  ovr = o_doc.root.search(o_search).to_html
840
- end
858
+ end
859
+ if orig_td
860
+ ovr = '<tpl:pass tpl:text-domain="'+orig_td+'">'+ovr+'</tpl:pass>'
861
+ end
841
862
  o.swap(ovr)
842
863
  end
843
864
  elsif override.name == 'tpl:override' || override.name == 'tpl:content'
865
+ if orig_td
866
+ f.set_attribute('tpl:text-domain', orig_td)
867
+ end
844
868
  overridden = f.to_html
845
869
  parent = f.parent
846
870
  if f == el
@@ -872,6 +896,7 @@ module Spider
872
896
  elsif override.name == 'tpl:after'
873
897
  f.after(override.innerHTML)
874
898
  end
899
+
875
900
  end
876
901
  end
877
902
  end
@@ -37,6 +37,8 @@ module Spider
37
37
  block = :Run
38
38
  elsif el.name == 'sp:yield'
39
39
  block = :Yield
40
+ elsif !skip_attributes && el.has_attribute?('tpl:text-domain')
41
+ block = :TextDomain
40
42
  elsif el.name == 'sp:pass' || el.name == 'tpl:pass' || el.name == 'sp:template'
41
43
  block = :Pass
42
44
  elsif el.name == 'sp:debugger'
@@ -45,8 +47,6 @@ module Spider
45
47
  block = :ParentContext
46
48
  elsif el.name == 'sp:recurse'
47
49
  block = :Recurse
48
- elsif !skip_attributes && el.has_attribute?('tpl:text-domain')
49
- block = :TextDomain
50
50
  elsif Spider::Template.registered?(el.name)
51
51
  klass = Spider::Template.get_registered_class(el.name)
52
52
  if klass < ::Spider::Widget
@@ -16,7 +16,7 @@ module Spider
16
16
  attr_accessor :active
17
17
 
18
18
  @@common_attributes = {
19
- :id => {}
19
+ :id => {:process => lambda{ |val| val.gsub('-', '_')}}
20
20
  }
21
21
 
22
22
  class << self