card 1.16.4 → 1.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150429090551_search_card_context.rb +34 -0
  4. data/db/migrate_core_cards/20150824135418_update_file_history.rb +10 -5
  5. data/db/migrate_core_cards/20150910085603_remove_performance_log_card.rb +10 -0
  6. data/db/seed/new/card_actions.yml +358 -366
  7. data/db/seed/new/card_acts.yml +1 -1
  8. data/db/seed/new/card_changes.yml +1379 -1399
  9. data/db/seed/new/card_references.yml +1109 -710
  10. data/db/seed/new/cards.yml +1436 -1454
  11. data/db/seed/test/fixtures/card_actions.yml +1031 -1039
  12. data/db/seed/test/fixtures/card_acts.yml +155 -155
  13. data/db/seed/test/fixtures/card_changes.yml +4148 -4168
  14. data/db/seed/test/fixtures/card_references.yml +1577 -1178
  15. data/db/seed/test/fixtures/cards.yml +2259 -2277
  16. data/db/version_core_cards.txt +1 -1
  17. data/lib/card.rb +3 -2
  18. data/lib/card/env.rb +66 -0
  19. data/lib/card/format.rb +3 -38
  20. data/lib/card/loader.rb +0 -4
  21. data/lib/card/location.rb +38 -0
  22. data/lib/card/set.rb +1 -3
  23. data/lib/card/success.rb +2 -3
  24. data/mod/01_core/format/html_format.rb +0 -48
  25. data/mod/01_core/set/all/collection.rb +9 -7
  26. data/mod/01_core/set/all/initialize.rb +5 -0
  27. data/mod/01_core/set/all/location_history.rb +10 -0
  28. data/mod/01_core/set/all/phases.rb +2 -1
  29. data/mod/01_core/set/all/rules.rb +0 -2
  30. data/mod/01_core/set/all/trash.rb +3 -2
  31. data/mod/01_core/set/all/utils.rb +12 -0
  32. data/mod/01_core/spec/set/all/permissions_spec.rb +8 -8
  33. data/mod/01_core/spec/set/all/type_spec.rb +14 -14
  34. data/mod/01_history/set/all/content_history.rb +7 -3
  35. data/mod/01_history/set/all/history.rb +3 -3
  36. data/mod/02_basic_types/set/type/pointer.rb +8 -1
  37. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +39 -0
  38. data/mod/03_machines/lib/stylesheets/style_cards.scss +12 -2
  39. data/mod/03_machines/set/right/machine_output.rb +4 -0
  40. data/mod/03_machines/set/type/css.rb +1 -1
  41. data/mod/04_settings/spec/set/right/structure_spec.rb +1 -1
  42. data/mod/05_email/set/all/observer.rb +5 -5
  43. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  44. data/mod/05_standard/file/favicon/image-icon.png +0 -0
  45. data/mod/05_standard/file/favicon/image-large.png +0 -0
  46. data/mod/05_standard/file/favicon/image-medium.png +0 -0
  47. data/mod/05_standard/file/favicon/image-original.png +0 -0
  48. data/mod/05_standard/file/favicon/image-small.png +0 -0
  49. data/mod/05_standard/lib/carrier_wave/cardmount.rb +8 -2
  50. data/mod/05_standard/lib/file_uploader.rb +47 -35
  51. data/mod/05_standard/set/abstract/attachment.rb +87 -35
  52. data/mod/05_standard/set/all/error.rb +1 -1
  53. data/mod/05_standard/set/all/links.rb +1 -0
  54. data/mod/05_standard/set/self/signin.rb +1 -1
  55. data/mod/05_standard/set/type/file.rb +16 -1
  56. data/mod/05_standard/set/type/image.rb +2 -0
  57. data/mod/05_standard/set/type/search_type.rb +2 -2
  58. data/mod/05_standard/spec/chunk/link_spec.rb +42 -32
  59. data/mod/05_standard/spec/set/all/links_spec.rb +15 -0
  60. data/mod/05_standard/spec/set/self/head_spec.rb +3 -3
  61. data/mod/05_standard/spec/set/type/email_template_spec.rb +39 -39
  62. data/mod/05_standard/spec/set/type/file_spec.rb +0 -12
  63. data/mod/05_standard/spec/set/type/image_spec.rb +26 -2
  64. data/spec/lib/card/content_spec.rb +169 -154
  65. data/spec/lib/card/format_spec.rb +7 -7
  66. data/spec/lib/card/success_spec.rb +1 -1
  67. metadata +7 -6
  68. data/lib/card/log.rb +0 -545
  69. data/mod/05_standard/set/self/performance_log.rb +0 -92
  70. data/spec/lib/card/log_spec.rb +0 -270
@@ -347,7 +347,7 @@ describe Card::Set::All::Permissions do
347
347
  assert_hidden_from( @u1, @c2 )
348
348
  assert_hidden_from( @u3, @c2 )
349
349
  end
350
-
350
+
351
351
  context "create permissions" do
352
352
  before do
353
353
  Card::Auth.as_bot do
@@ -355,17 +355,17 @@ describe Card::Set::All::Permissions do
355
355
  Card.create! :name=>'*self+*right+*create', :type=>'Pointer', :content=>'[[Anyone Signed In]]'
356
356
  end
357
357
  end
358
-
358
+
359
359
  it "should inherit" do
360
360
  Card::Auth.as(:anyone_signed_in) do
361
361
  expect(Card.fetch( 'A+*self' ).ok?(:create)).to be_truthy #explicitly granted above
362
- expect(Card.fetch( 'A+*right').ok?(:create)).to be_falsey #by default restricted
363
-
362
+ expect(Card.fetch( 'A+*right').ok?(:create)).to be_falsey #by default restricted
363
+
364
364
  expect(Card.fetch( 'A+*self+*structure', :new=>{} ).ok?(:create)).to be_truthy # +*structure granted;
365
365
  expect(Card.fetch( 'A+*right+*structure', :new=>{} ).ok?(:create)).to be_falsey # can't create A+B, therefore can't create A+B+C
366
366
  end
367
367
  end
368
-
368
+
369
369
  end
370
370
 
371
371
 
@@ -493,9 +493,9 @@ describe Card::Set::All::Permissions do
493
493
  end
494
494
  end
495
495
  end
496
-
497
-
498
-
496
+
497
+
498
+
499
499
  end
500
500
 
501
501
 
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  describe Card::Set::All::Type do
4
-
4
+
5
5
  describe 'get_type_id (#new)' do
6
6
  it "should accept cardtype name and casespace variant as type" do
7
7
  expect(Card.new( :type=>'Phrase' ).type_id).to eq(Card::PhraseID)
@@ -9,17 +9,17 @@ describe Card::Set::All::Type do
9
9
  expect(Card.new( :type=>'phrase' ).type_id).to eq(Card::PhraseID)
10
10
  expect(Card.new( :type=>'phrase??' ).type_id).to eq(Card::PhraseID)
11
11
  end
12
-
12
+
13
13
  it 'should accept type_code' do
14
14
  expect(Card.new( :type_code=>'phrase' ).type_id).to eq(Card::PhraseID)
15
15
  expect(Card.new( :type_code=>:phrase ).type_id).to eq(Card::PhraseID)
16
16
  end
17
-
17
+
18
18
  it 'should accept type_id' do
19
19
  expect(Card.new( :type_id=>Card::PhraseID ).type_code).to eq(:phrase)
20
20
  end
21
21
  end
22
-
22
+
23
23
  describe 'card with wagneered type' do
24
24
  before do
25
25
  Card::Auth.as_bot do
@@ -27,26 +27,26 @@ describe Card::Set::All::Type do
27
27
  end
28
28
  @hat = Card.new :type=>'Hat'
29
29
  end
30
-
30
+
31
31
  it 'should have a type_name' do
32
32
  expect(@hat.type_name).to eq('Hat')
33
33
  end
34
-
34
+
35
35
  it 'should not have a type_code' do
36
36
  expect(@hat.type_code).to eq(nil)
37
37
  end
38
-
38
+
39
39
  it 'should have a type_id' do
40
40
  expect(@hat.type_id).to eq(@type.id)
41
41
  end
42
-
42
+
43
43
  it 'should have a type_card' do
44
44
  expect(@hat.type_card).to eq(@type)
45
45
  end
46
46
 
47
47
  end
48
-
49
-
48
+
49
+
50
50
  describe 'card with structured type' do
51
51
  before do
52
52
  Card::Auth.as_bot do
@@ -55,11 +55,11 @@ describe Card::Set::All::Type do
55
55
  Card.create! :name=>'Topic+results+*type plus right+*structure', :type=>'Search', :content=>'{}'
56
56
  end
57
57
  end
58
-
59
- it "should clear cache of structured included card after saving" do
58
+
59
+ it "should clear cache of structured nested card after saving" do
60
60
  Card::Auth.as_bot do
61
61
  expect(Card.fetch('t1+results', :new=>{}).type_name).to eq('Basic')
62
-
62
+
63
63
  topic1 = Card.new :type=>'Topic', :name=>'t1'
64
64
  topic1.format._render_new
65
65
  topic1.save!
@@ -67,5 +67,5 @@ describe Card::Set::All::Type do
67
67
  end
68
68
  end
69
69
  end
70
-
70
+
71
71
  end
@@ -70,9 +70,13 @@ def with_selected_action_id action_id
70
70
  end
71
71
 
72
72
  def selected_content_action_id
73
- @selected_action_id ||
74
- (@current_action && (new_card? || @current_action.new_content? || db_content_changed?) && @current_action.id) ||
75
- last_content_action_id
73
+ @selected_action_id || new_content_action_id || last_content_action_id
74
+ end
75
+
76
+ def new_content_action_id
77
+ if @current_action && (new_card? || @current_action.new_content? || db_content_changed?)
78
+ @current_action.id
79
+ end
76
80
  end
77
81
 
78
82
  def last_action_id
@@ -5,7 +5,7 @@ def history?
5
5
  end
6
6
 
7
7
  # must be called on all actions and before :set_name, :process_subcards and :validate_delete_children
8
- event :assign_act, :before=>:prepare, :when=>proc {|c| c.history?} do
8
+ event :assign_act, :before=>:prepare, :when=>proc {|c| c.history? || c.respond_to?(:attachment) } do
9
9
  @current_act = (@supercard && @supercard.current_act) || Card::Act.create(:ip_address=>Env.ip)
10
10
  end
11
11
 
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  # stores changes in the changes table and assigns them to the current action
21
21
  # removes the action if there are no changes
22
- event :finalize_action, :after =>:stored, :when=>proc {|c| c.history? && c.current_action} do
22
+ event :finalize_action, :after =>:stored, :when=>proc {|c| (c.history? || c.respond_to?(:attachment)) && c.current_action} do
23
23
  @changed_fields = Card::TRACKED_FIELDS.select{ |f| changed_attributes.member? f }
24
24
  if @changed_fields.present?
25
25
  @changed_fields.each{ |f| Card::Change.create :field => f, :value => self[f], :card_action_id=>@current_action.id }
@@ -30,7 +30,7 @@ event :finalize_action, :after =>:stored, :when=>proc {|c| c.history? && c.curre
30
30
  end
31
31
  end
32
32
 
33
- event :finalize_act, :after=>:finalize_action, :when=>proc {|c| c.history? && !c.supercard } do
33
+ event :finalize_act, :after=>:finalize_action, :when=>proc {|c| !c.supercard } do
34
34
  if @current_act.actions(true).empty?
35
35
  @current_act.delete
36
36
  @current_act = nil
@@ -179,13 +179,19 @@ end
179
179
 
180
180
 
181
181
  format :css do
182
+
183
+ #generalize to all collections?
184
+ def default_item_view
185
+ params[:item] || :content
186
+ end
187
+
182
188
  view :titled do |args|
183
189
  %(#{major_comment "STYLE GROUP: \"#{card.name}\"", '='}#{ _render_core })
184
190
  end
185
191
 
186
192
  view :core do |args|
187
193
  card.item_cards.map do |item|
188
- nest item, :view=>(args[:item] || :content)
194
+ nest item, :view=>item_view(args)
189
195
  end.join "\n\n"
190
196
  end
191
197
 
@@ -195,6 +201,7 @@ end
195
201
 
196
202
 
197
203
  format :js do
204
+
198
205
  view :core do |args|
199
206
  card.item_cards.map do |item|
200
207
  nest item, :view=>( args[:item] || :core)
@@ -333,6 +333,44 @@ $(window).ready ->
333
333
  if val != ''
334
334
  window.location = wagn.rootPath + escape( val )
335
335
 
336
+ # performance log mod
337
+ $('body').on 'click', '.open-slow-items', ->
338
+
339
+ panel = $(this).closest('.panel-group')
340
+ panel.find('.open-slow-items').removeClass('open-slow-items').addClass('close-slow-items')
341
+ panel.find('.toggle-fast-items').text("show < 100ms")
342
+ panel.find('.duration-ok').hide()
343
+ panel.find('.panel-danger > .panel-collapse').collapse('show').find('a > span').addClass('show-fast-items')
344
+
345
+ $('body').on 'click', '.close-slow-items', ->
346
+ panel = $(this).closest('.panel-group')
347
+ panel.find('.close-slow-items').removeClass('close-slow-items').addClass('open-slow-items')
348
+ panel.find('.toggle-fast-items').text("hide < 100ms")
349
+ panel.find('.panel-danger > .panel-collapse').collapse('hide').removeClass('show-fast-items')
350
+ panel.find('.duration-ok').show()
351
+
352
+ $('body').on 'click', '.toggle-fast-items', ->
353
+ panel = $(this).closest('.panel-group')
354
+ if $(this).text() == 'hide < 100ms'
355
+ panel.find('.duration-ok').hide()
356
+ $(this).text("show < 100ms")
357
+ else
358
+ panel.find('.duration-ok').show()
359
+ $(this).text("hide < 100ms")
360
+
361
+ $('body').on 'click', '.show-fast-items', (event) ->
362
+ $(this).removeClass('show-fast-items')
363
+ panel = $(this).closest('.panel-group')
364
+ panel.find('.duration-ok').show()
365
+ panel.find('.show-fast-items').removeClass('show-fast-items')
366
+ panel.find('.panel-collapse').collapse('show')
367
+ event.stopPropagation()
368
+
369
+
370
+
371
+
372
+
373
+
336
374
 
337
375
  toggleShade = (shadeSlot) ->
338
376
  shadeSlot.find('.shade-content').slideToggle 1000
@@ -408,3 +446,4 @@ navbox_select = (event, ui) ->
408
446
 
409
447
 
410
448
 
449
+
@@ -924,7 +924,17 @@ html>body .open-view {
924
924
  font-size: .85em;
925
925
  }
926
926
 
927
- .SELF-Xperformance_log.open-view .panel-group {
928
- margin-bottom: 0;
927
+ .RIGHT-Xperformance_log.open-view {
928
+ font-size: 12px;
929
+ .panel-group {
930
+ margin-bottom: 0;
931
+ }
932
+ .panel-body {
933
+ padding: 0px 0px 0px 15px;
934
+ }
935
+ .panel-title {
936
+ font-size: 14px;
937
+ }
929
938
  }
930
939
 
940
+
@@ -2,6 +2,10 @@ def followable?
2
2
  false
3
3
  end
4
4
 
5
+ def history?
6
+ false
7
+ end
8
+
5
9
  format do
6
10
  view :not_found do |args|
7
11
  if update_machine_output_live?
@@ -38,7 +38,7 @@ format :html do
38
38
  view :core do |args|
39
39
  # FIXME: scan must happen before process for inclusion interactions to work, but this will likely cause
40
40
  # problems with including other css?
41
- process_content ::CodeRay.scan( _render_raw, :css ).div, :size=>:icon
41
+ process_content ::CodeRay.scan( _render_raw, :css ).div, :content_opts=>{:size=>:icon}
42
42
  end
43
43
 
44
44
  view :content_changes, :mod=>CoffeeScript::HtmlFormat
@@ -17,6 +17,6 @@ describe Card::Set::Right::Structure do
17
17
 
18
18
  it 'renders core as raw' do
19
19
  trs = Card.fetch('*type+*right+*structure').format.render_core
20
- expect(trs).to eq '{"type":"_self"}'
20
+ expect(trs).to eq '{"type":"_left"}'
21
21
  end
22
22
  end
@@ -1,12 +1,12 @@
1
- def send_action_mails args
2
- setting = "on_#{args[:on]}".to_sym
1
+ def send_action_mails args
2
+ setting = "on_#{args[:on]}".to_sym
3
3
  email_templates_for( setting ) do |mailcard|
4
4
  mailcard.deliver( context: self )
5
5
  end
6
6
  end
7
7
 
8
8
  def email_templates_for setting
9
-
9
+
10
10
  if email_templates = @email_template_cache ||
11
11
  ( event_card = self.rule_card(setting) and event_card.extended_item_cards )
12
12
  email_templates.each do |mailcard|
@@ -16,12 +16,12 @@ def email_templates_for setting
16
16
  end
17
17
 
18
18
  [:create, :update, :delete].each do |action|
19
- event "observer_#{action}".to_sym, :after=>:extend, :on=>action do
19
+ event "observer_#{action}".to_sym, :after=>:extend, :on=>action do
20
20
  self.send_action_mails :on=>action
21
21
  end
22
22
  end
23
23
 
24
- event :cache_delete_email_templates, :after=>:approve, :on=>:delete do
24
+ event :cache_delete_email_templates, :after=>:approve, :on=>:delete do
25
25
  event_card = self.rule_card(:on_delete)
26
26
  @email_template_cache = event_card && event_card.extended_item_cards
27
27
  end
@@ -160,7 +160,7 @@ format :html do
160
160
  view :errors, :perms=>:none do |args|
161
161
  if card.errors.any?
162
162
  if card.errors.find { |attrib,msg| attrib == :permission_denied }
163
- save_interrupted_action(request.env['REQUEST_URI'])
163
+ Env.save_interrupted_action(request.env['REQUEST_URI'])
164
164
  title = "Problems with #{card.name}"
165
165
  frame args.merge(:panel_class=>"panel panel-warning", :title=>title, :hide=>'menu' ) do
166
166
  "Please #{ link_to 'sign in', card_url(':signin') }" #" #{to_task}"
@@ -22,15 +22,19 @@ module CarrierWave
22
22
  store_#{column}!
23
23
  end
24
24
 
25
- event :remove_#{column}_event, :on =>:delete, :after=>:stored do
25
+ # remove files only if card has no history
26
+ event :remove_#{column}_event, :on =>:delete, :after=>:stored, :when => proc { |c| !c.history? } do
26
27
  remove_#{column}!
27
28
  end
28
29
  event :mark_remove_#{column}_false_event, :on => :update, :after=>:stored do
29
30
  mark_remove_#{column}_false
30
31
  end
31
- event :store_previous_model_for_#{column}_event, :on=>:update, :before =>:store do
32
+ event :store_previous_model_for_#{column}_event, :on=>:update, :before =>:store, :when => proc { |c| !c.history? } do
32
33
  store_previous_model_for_#{column}
33
34
  end
35
+ event :remove_previously_stored_#{column}_event, :on=>:update, :after => :store, :when => proc { |c| !c.history?} do
36
+ remove_previously_stored_#{column}
37
+ end
34
38
 
35
39
  def attachment
36
40
  #{column}
@@ -47,9 +51,11 @@ module CarrierWave
47
51
  def read_uploader *args
48
52
  read_attribute *args
49
53
  end
54
+
50
55
  def write_uploader *args
51
56
  write_attribute *args
52
57
  end
58
+
53
59
  def #{column}=(new_file)
54
60
  send(:"#{column}_will_change!")
55
61
  db_column = _mounter(:#{column}).serialization_column
@@ -1,22 +1,20 @@
1
1
  =begin
2
2
 
3
- DATABASE_CONTENT
3
+ *DATABASE_CONTENT*
4
4
  if in mod:
5
5
  :codename/modname.ext
6
6
  else
7
7
  ~card_id/action_id.ext
8
8
 
9
-
10
- FILE SYSTEM
9
+ *FILE SYSTEM*
11
10
  if in mod
12
11
  (mod_dir)/files/codename/type_code-variant.ext (no colon on codename!)
13
12
  else
14
13
  (files_dir)/id/action_id-variant.ext (no tilde on id!)
15
14
 
16
- variant = icon|small|medium|large|original
17
-
15
+ variant = icon|small|medium|large|original (only for images)
18
16
 
19
- URLS
17
+ *URLS*
20
18
  mark.ext
21
19
  mark/revision.ext
22
20
  mark/revision-variant.ext
@@ -44,7 +42,7 @@ end
44
42
 
45
43
  class FileUploader < CarrierWave::Uploader::Base
46
44
  attr_accessor :mod
47
- include Card::Format::Location
45
+ include Card::Location
48
46
 
49
47
  storage :file
50
48
 
@@ -57,33 +55,36 @@ class FileUploader < CarrierWave::Uploader::Base
57
55
  end
58
56
 
59
57
  def extension
60
- if file && file.extension.present?
61
- ".#{file.extension}"
62
- elsif original_filename
63
- File.extname(original_filename)
64
- else model.content
65
- File.extname(model.content)
58
+ case
59
+ when file && file.extension.present? ; ".#{file.extension}"
60
+ when card_content = model.content ; File.extname(card_content)
61
+ when orig = original_filename ; File.extname(orig)
62
+ else ''
66
63
  end.downcase
67
64
  end
68
65
 
69
66
  # generate identifier that gets stored in the card's db_content field
70
67
  def db_content opts={}
71
- @mod = opts[:mod] || model.load_from_mod # don't use mod_file? here
72
- # mod_file? looks at the identifier in the db
73
- # to figure out whether it's a mod file
74
- # so it wouldn't be possible to turn a mod file card into a regular file card
68
+ if opts[:mod] && !model.load_from_mod
69
+ model.load_from_mod = opts[:mod]
70
+ end
71
+ "%s/%s" % [file_dir, url_filename(opts)]
72
+ end
75
73
 
76
- basename =
77
- if @mod
78
- "#{@mod}#{extension}"
79
- else
80
- "#{action_id}#{extension}"
81
- end
82
- "%s/%s" % [file_dir, basename]
74
+ def url_filename opts={}
75
+ if opts[:mod] && !model.load_from_mod
76
+ model.load_from_mod = opts[:mod]
77
+ end
78
+
79
+ basename = if (mod = mod_file?)
80
+ "#{mod}#{extension}"
81
+ else
82
+ "#{action_id}#{extension}"
83
+ end
83
84
  end
84
85
 
85
- def url(options = {})
86
- "%s/%s/%s" % [card_path(Card.config.files_web_path), file_dir, full_filename(filename)]
86
+ def url opts = {}
87
+ "%s/%s/%s" % [card_path(Card.config.files_web_path), file_dir, full_filename(url_filename(opts))]
87
88
  end
88
89
 
89
90
  def file_dir
@@ -100,20 +101,27 @@ class FileUploader < CarrierWave::Uploader::Base
100
101
  Cardio.paths['files'].existent.first + '/cache'
101
102
  end
102
103
 
103
- # Carrierwave usually stores the filename as identifier in the database
104
- # and retrieve_from_store! calls store_path with the identifier from the db
104
+ # Carrierwave calls store_path without argument when it stores the file
105
+ # and with the identifier from the db when it retrieves the file
105
106
  # In our case the first part of our identifier is not part of the path
106
107
  # but we can construct the filename from db data. So we don't need the identifier.
107
- # We can just call store_path always with the filename
108
- def store_path(for_file=filename) #
109
- super(filename)
108
+ def store_path(for_file=nil) #
109
+ if for_file
110
+ retrieve_path
111
+ else
112
+ File.join([store_dir, full_filename(filename)].compact)
113
+ end
114
+ end
115
+
116
+ def retrieve_path
117
+ File.join([retrieve_dir, full_filename(filename)].compact)
110
118
  end
111
119
 
112
120
  def tmp_path
113
- if !Dir.exists? model.tmp_store_dir
114
- Dir.mkdir model.tmp_store_dir
121
+ if !Dir.exists? model.tmp_upload_dir
122
+ Dir.mkdir model.tmp_upload_dir
115
123
  end
116
- File.join model.tmp_store_dir, filename
124
+ File.join model.tmp_upload_dir, filename
117
125
  end
118
126
 
119
127
  def create_versions? new_file
@@ -126,13 +134,17 @@ class FileUploader < CarrierWave::Uploader::Base
126
134
  end
127
135
 
128
136
  def original_filename
129
- @original_filename || (model.selected_action && model.selected_action.comment)
137
+ @original_filename ||= (model.selected_action && model.selected_action.comment)
130
138
  end
131
139
 
132
140
  def store_dir
133
141
  model.store_dir
134
142
  end
135
143
 
144
+ def retrieve_dir
145
+ model.retrieve_dir
146
+ end
147
+
136
148
  def mod_file?
137
149
  @mod ||= model.mod_file?
138
150
  end