card 1.16.3 → 1.16.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/card.gemspec +1 -1
- data/db/migrate_core_cards/20150724123438_update_file_and_image_cards.rb +1 -1
- data/db/migrate_core_cards/20150824135418_update_file_history.rb +20 -0
- data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +13 -0
- data/db/seed/new/card_actions.yml +16 -0
- data/db/seed/new/card_acts.yml +1 -1
- data/db/seed/new/card_changes.yml +56 -80
- data/db/seed/new/card_references.yml +282 -58
- data/db/seed/new/cards.yml +1348 -1312
- data/db/seed/test/fixtures/card_actions.yml +884 -868
- data/db/seed/test/fixtures/card_acts.yml +250 -250
- data/db/seed/test/fixtures/card_changes.yml +1935 -1959
- data/db/seed/test/fixtures/card_references.yml +1024 -800
- data/db/seed/test/fixtures/cards.yml +2402 -2366
- data/db/version_core_cards.txt +1 -1
- data/lib/card.rb +3 -1
- data/lib/card/cache.rb +5 -5
- data/lib/card/chunk.rb +2 -0
- data/lib/card/env.rb +1 -1
- data/lib/card/query/card_clause.rb +59 -58
- data/lib/card/set.rb +7 -0
- data/lib/card/success.rb +143 -0
- data/mod/01_core/chunk/query_reference.rb +16 -7
- data/mod/01_core/chunk/reference.rb +3 -3
- data/mod/01_core/set/all/collection.rb +1 -1
- data/mod/01_core/set/all/name.rb +2 -1
- data/mod/01_core/set/all/phases.rb +12 -2
- data/mod/01_core/set/all/type.rb +5 -5
- data/mod/01_history/set/all/actions.rb +6 -2
- data/mod/01_history/set/all/content_history.rb +17 -2
- data/mod/01_history/set/all/history.rb +1 -1
- data/mod/02_basic_types/set/all/file.rb +0 -31
- data/mod/03_machines/lib/javascript/jquery.fileupload.js +539 -182
- data/mod/03_machines/lib/javascript/wagn.js.coffee +3 -0
- data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +20 -18
- data/mod/03_machines/lib/stylesheets/style_cards.scss +28 -1
- data/mod/05_email/set/all/notify.rb +1 -1
- data/mod/05_standard/file/favicon/image-icon.png +0 -0
- data/mod/05_standard/file/favicon/image-large.png +0 -0
- data/mod/05_standard/file/favicon/image-medium.png +0 -0
- data/mod/05_standard/file/favicon/image-original.png +0 -0
- data/mod/05_standard/file/favicon/image-small.png +0 -0
- data/mod/05_standard/lib/carrier_wave/cardmount.rb +25 -6
- data/mod/05_standard/lib/file_uploader.rb +27 -11
- data/mod/05_standard/lib/image_uploader.rb +7 -4
- data/mod/05_standard/set/abstract/attachment.rb +132 -14
- data/mod/05_standard/set/right/account.rb +2 -2
- data/mod/05_standard/set/self/signin.rb +0 -1
- data/mod/05_standard/set/type/file.rb +48 -19
- data/mod/05_standard/set/type/image.rb +9 -12
- data/mod/05_standard/spec/chunk/include_spec.rb +13 -12
- data/mod/05_standard/spec/chunk/query_reference_spec.rb +50 -0
- data/mod/05_standard/spec/set/right/account_spec.rb +24 -25
- data/mod/05_standard/spec/set/type/file_spec.rb +1 -1
- data/spec/lib/card/reference_spec.rb +14 -0
- data/spec/lib/card/success_spec.rb +142 -0
- data/tmpsets/set/mod001-01_core/all/collection.rb +1 -1
- data/tmpsets/set/mod001-01_core/all/name.rb +2 -1
- data/tmpsets/set/mod001-01_core/all/phases.rb +12 -2
- data/tmpsets/set/mod001-01_core/all/type.rb +5 -5
- data/tmpsets/set/mod002-01_history/all/actions.rb +6 -2
- data/tmpsets/set/mod002-01_history/all/content_history.rb +17 -2
- data/tmpsets/set/mod002-01_history/all/history.rb +1 -1
- data/tmpsets/set/mod003-02_basic_types/all/file.rb +0 -24
- data/tmpsets/set/mod003-02_basic_types/all/rss.rb +8 -5
- data/tmpsets/set/mod003-02_basic_types/type/pointer.rb +2 -2
- data/tmpsets/set/mod005-04_settings/right/structure.rb +7 -2
- data/tmpsets/set/mod006-05_email/all/notify.rb +1 -1
- data/tmpsets/set/mod007-05_standard/abstract/attachment.rb +132 -14
- data/tmpsets/set/mod007-05_standard/all/links.rb +8 -0
- data/tmpsets/set/mod007-05_standard/all/rich_html/header.rb +5 -7
- data/tmpsets/set/mod007-05_standard/right/account.rb +2 -2
- data/tmpsets/set/mod007-05_standard/self/signin.rb +0 -1
- data/tmpsets/set/mod007-05_standard/type/file.rb +49 -20
- data/tmpsets/set/mod007-05_standard/type/image.rb +9 -12
- data/tmpsets/set/mod007-05_standard/type/search_type.rb +40 -22
- data/tmpsets/set/mod008-06_bootstrap/self/bootswatch_shared.rb +1 -1
- metadata +10 -4
@@ -0,0 +1,142 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
describe Card::Success do
|
4
|
+
let(:context) { Card['A'].cardname }
|
5
|
+
let(:previous) { '/B' }
|
6
|
+
let(:home) { Card['Home'] }
|
7
|
+
def success_params params
|
8
|
+
@success = Card::Success.new(context, params)
|
9
|
+
@success.stub(:previous_location) { previous }
|
10
|
+
end
|
11
|
+
describe '#target' do
|
12
|
+
subject { @success.target }
|
13
|
+
|
14
|
+
context 'initialized with nil' do
|
15
|
+
before do
|
16
|
+
success_params nil
|
17
|
+
end
|
18
|
+
it { is_expected.to eq Card['A'] }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'initialized with hash' do
|
22
|
+
before do
|
23
|
+
success_params :id=>home.id, :view=>'closed'
|
24
|
+
end
|
25
|
+
it { is_expected.to eq home}
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'initialized with REDIRECT string' do
|
29
|
+
before do
|
30
|
+
success_params 'REDIRECT: Home'
|
31
|
+
end
|
32
|
+
it { is_expected.to eq home}
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'initialized with TEXT string' do
|
36
|
+
before do
|
37
|
+
success_params 'TEXT: Hi'
|
38
|
+
end
|
39
|
+
it { is_expected.to eq 'Hi'}
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'initialized with card object' do
|
43
|
+
before do
|
44
|
+
success_params home
|
45
|
+
end
|
46
|
+
it { is_expected.to eq home}
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'initialized with url' do
|
50
|
+
before do
|
51
|
+
success_params 'http://wagn.org'
|
52
|
+
end
|
53
|
+
it { is_expected.to eq 'http://wagn.org'}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#to_url' do
|
58
|
+
subject { @success.to_url}
|
59
|
+
context 'with params' do
|
60
|
+
context 'using initilization' do
|
61
|
+
before do
|
62
|
+
success_params :id=>home.id, :view=>'closed', :layout=>'my_layout'
|
63
|
+
end
|
64
|
+
it { is_expected.to eq '/Home?layout=my_layout&view=closed' }
|
65
|
+
end
|
66
|
+
context 'using array assignment' do
|
67
|
+
before do
|
68
|
+
success_params nil
|
69
|
+
@success[:view] = 'closed'
|
70
|
+
end
|
71
|
+
it { is_expected.to eq '/A?view=closed' }
|
72
|
+
end
|
73
|
+
context 'using assignment' do
|
74
|
+
before do
|
75
|
+
success_params nil
|
76
|
+
@success.view = 'closed'
|
77
|
+
end
|
78
|
+
it { is_expected.to eq '/A?view=closed' }
|
79
|
+
end
|
80
|
+
context 'using <<' do
|
81
|
+
before do
|
82
|
+
success_params nil
|
83
|
+
@success << { :card=>home, :view=>'closed'}
|
84
|
+
end
|
85
|
+
it { is_expected.to eq '/Home?view=closed' }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
context 'redirect string' do
|
89
|
+
before do
|
90
|
+
success_params 'REDIRECT: *previous'
|
91
|
+
end
|
92
|
+
it { is_expected.to eq previous}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#soft_redirect?' do
|
97
|
+
it 'returns true if soft_redirect parameter is true' do
|
98
|
+
success_params :soft_redirect=>true
|
99
|
+
expect(@success.soft_redirect?).to be_truthy
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#hard_redirect?' do
|
104
|
+
it 'true for "REDIRECT: anywhere"' do
|
105
|
+
success_params "REDIRECT: anywhere"
|
106
|
+
expect(@success.hard_redirect?).to be_truthy
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#mark=' do
|
111
|
+
subject { @success.target }
|
112
|
+
before do
|
113
|
+
success_params nil
|
114
|
+
end
|
115
|
+
it 'works with id' do
|
116
|
+
@success.mark = home.id
|
117
|
+
is_expected.to eq home
|
118
|
+
end
|
119
|
+
it 'works with name' do
|
120
|
+
@success.mark = home.name
|
121
|
+
is_expected.to eq home
|
122
|
+
end
|
123
|
+
it 'works with card object' do
|
124
|
+
@success.mark = home
|
125
|
+
is_expected.to eq home
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'params' do
|
130
|
+
it 'returns params hash' do
|
131
|
+
success_params :name=>'Home', :view=>'View'
|
132
|
+
@success.layout = 'Layout'
|
133
|
+
@success.apply :script => 'Script'
|
134
|
+
@success << {:structure => 'Structure'}
|
135
|
+
expect(@success.params.keys.sort).to eq [:layout, :script, :structure, :view]
|
136
|
+
end
|
137
|
+
it 'ignores "id", "name", "mark", "card"", target", and "redirect"' do
|
138
|
+
success_params :id=>5, :name=>'Home', :card=>Card['Home'], :mark=>'Home', :target=>'Home', :redirect=>false, :view=>'View'
|
139
|
+
expect(@success.params.keys).to eq [:view]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -235,7 +235,7 @@ end
|
|
235
235
|
|
236
236
|
|
237
237
|
event :cascade_name_changes, :after=>:store, :on=>:update, :changed=>:name do
|
238
|
-
Rails.logger.
|
238
|
+
#Rails.logger.info "------------------- #{name_was} CASCADE #{self.name} -------------------------------------"
|
239
239
|
|
240
240
|
self.update_referencers = false if self.update_referencers == 'false' #handle strings from cgi
|
241
241
|
Card::Reference.update_on_rename self, name, self.update_referencers
|
@@ -247,6 +247,7 @@ event :cascade_name_changes, :after=>:store, :on=>:update, :changed=>:name do
|
|
247
247
|
|
248
248
|
deps.each do |dep|
|
249
249
|
# here we specifically want NOT to invoke recursive cascades on these cards, have to go this low level to avoid callbacks.
|
250
|
+
Rails.logger.info "cascading name: #{dep.name}"
|
250
251
|
Card.expire dep.name #old name
|
251
252
|
newname = dep.cardname.replace_part name_was, name
|
252
253
|
Card.where( :id=> dep.id ).update_all :name => newname.to_s, :key => newname.key
|
@@ -13,7 +13,7 @@ def abort status, msg='action canceled'
|
|
13
13
|
if status == :failure && errors.empty?
|
14
14
|
errors.add :abort, msg
|
15
15
|
elsif Hash === status and status[:success]
|
16
|
-
|
16
|
+
success << status[:success]
|
17
17
|
status = :success
|
18
18
|
end
|
19
19
|
raise Card::Abort.new( status, msg)
|
@@ -51,11 +51,18 @@ end
|
|
51
51
|
# perhaps above should be in separate module?
|
52
52
|
#~~~~~~
|
53
53
|
|
54
|
-
def
|
54
|
+
def prepare
|
55
55
|
@action = identify_action
|
56
56
|
# the following should really happen when type, name etc are changed
|
57
57
|
reset_patterns
|
58
58
|
include_set_modules
|
59
|
+
run_callbacks :prepare
|
60
|
+
rescue =>e
|
61
|
+
rescue_event e
|
62
|
+
end
|
63
|
+
|
64
|
+
def approve
|
65
|
+
@action ||= identify_action
|
59
66
|
run_callbacks :approve
|
60
67
|
expire_pieces if errors.any?
|
61
68
|
errors.empty?
|
@@ -180,6 +187,9 @@ event :store_subcards, :after=>:store do
|
|
180
187
|
end
|
181
188
|
end
|
182
189
|
|
190
|
+
def success
|
191
|
+
Env[:success] ||= Card::Success.new(cardname)
|
192
|
+
end
|
183
193
|
|
184
194
|
|
185
195
|
|
@@ -30,7 +30,7 @@ end
|
|
30
30
|
|
31
31
|
def get_type_id args={}
|
32
32
|
return if args[:type_id] # type_id was set explicitly. no need to set again.
|
33
|
-
|
33
|
+
|
34
34
|
type_id = case
|
35
35
|
when args[:type_code]
|
36
36
|
if code=args[:type_code]
|
@@ -62,11 +62,11 @@ event :validate_type_change, :before=>:approve, :on=>:update, :changed=>:type_id
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
event :validate_type, :before=>:approve, :changed=>:type_id do
|
65
|
+
event :validate_type, :before=>:approve, :changed=>:type_id do
|
66
66
|
if !type_name
|
67
67
|
errors.add :type, "No such type"
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
if rt = structure and rt.assigns_type? and type_id!=rt.type_id
|
71
71
|
errors.add :type, "can't be changed because #{name} is hard templated to #{rt.type_name}"
|
72
72
|
end
|
@@ -74,7 +74,7 @@ end
|
|
74
74
|
|
75
75
|
event :reset_type_specific_fields, :after=>:store do
|
76
76
|
Auth.as_bot do
|
77
|
-
Card.search :left=>{ :
|
77
|
+
Card.search :left=>{ :left_id=>type_id }, :right=>{:codename=>'type_plus_right'} do |set_card|
|
78
78
|
set_card.reset_set_patterns
|
79
79
|
end
|
80
80
|
end
|
@@ -84,7 +84,7 @@ end
|
|
84
84
|
# Card["#{lef}"]
|
85
85
|
# set_card.reset_set_patterns
|
86
86
|
# end
|
87
|
-
|
87
|
+
|
88
88
|
|
89
89
|
|
90
90
|
# ~~~~~~~~~~~ below autogenerated; above pulled from /Users/ethan/dev/wagn/gem/card/mod/01_core/set/all/type.rb ~~~~~~~~~~~
|
@@ -3,13 +3,17 @@ class Card; module Set; module All; module Actions; extend Card::Set # ~~~~~~~~~
|
|
3
3
|
# -*- encoding : utf-8 -*-
|
4
4
|
|
5
5
|
def select_action_by_params params
|
6
|
-
action = find_action_by_params(params)
|
6
|
+
if (action = find_action_by_params(params))
|
7
|
+
run_callbacks :select_action do
|
8
|
+
self.selected_action_id = action.id
|
9
|
+
end
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
def find_action_by_params args
|
10
14
|
if args[:rev]
|
11
15
|
nth_action args[:rev]
|
12
|
-
elsif args[:rev_id] =~ /^\d+$/
|
16
|
+
elsif Integer === args[:rev_id] || args[:rev_id] =~ /^\d+$/
|
13
17
|
if action = Action.fetch(args[:rev_id]) and action.card_id == id
|
14
18
|
action
|
15
19
|
end
|
@@ -6,7 +6,7 @@ class Card; module Set; module All; module ContentHistory; extend Card::Set # ~~
|
|
6
6
|
def content
|
7
7
|
if @selected_action_id
|
8
8
|
@selected_content ||= begin
|
9
|
-
(change = last_change_on( :db_content, :not_after=> @selected_action_id ) and change.value) || db_content
|
9
|
+
(change = last_change_on( :db_content, :not_after=> @selected_action_id, :including_drafts=>true ) and change.value) || db_content
|
10
10
|
end
|
11
11
|
else
|
12
12
|
super
|
@@ -26,7 +26,10 @@ def save_content_draft content
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def last_change_on(field, opts={})
|
29
|
-
where_sql = 'card_actions.card_id = :card_id AND field = :field
|
29
|
+
where_sql = 'card_actions.card_id = :card_id AND field = :field '
|
30
|
+
if !opts[:including_drafts]
|
31
|
+
where_sql += 'AND (draft is not true) '
|
32
|
+
end
|
30
33
|
where_sql += if opts[:before]
|
31
34
|
'AND card_action_id < :action_id'
|
32
35
|
elsif opts[:not_after]
|
@@ -56,6 +59,18 @@ def selected_action
|
|
56
59
|
selected_action_id and Action.fetch(selected_action_id)
|
57
60
|
end
|
58
61
|
|
62
|
+
def with_selected_action_id action_id
|
63
|
+
current_action_id = @selected_action_id
|
64
|
+
run_callbacks :select_action do
|
65
|
+
self.selected_action_id = action_id
|
66
|
+
end
|
67
|
+
result = yield
|
68
|
+
run_callbacks :select_action do
|
69
|
+
self.selected_action_id = current_action_id
|
70
|
+
end
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
59
74
|
def selected_content_action_id
|
60
75
|
@selected_action_id ||
|
61
76
|
(@current_action && (new_card? || @current_action.new_content? || db_content_changed?) && @current_action.id) ||
|
@@ -7,7 +7,7 @@ def history?
|
|
7
7
|
end
|
8
8
|
|
9
9
|
# must be called on all actions and before :set_name, :process_subcards and :validate_delete_children
|
10
|
-
event :assign_act, :before=>:
|
10
|
+
event :assign_act, :before=>:prepare, :when=>proc {|c| c.history?} do
|
11
11
|
@current_act = (@supercard && @supercard.current_act) || Card::Act.create(:ip_address=>Env.ip)
|
12
12
|
end
|
13
13
|
|
@@ -1,29 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class Card; module Set; module All; module File; extend Card::Set # ~~~~~~~~~~~ above autogenerated; below pulled from /Users/ethan/dev/wagn/gem/card/mod/02_basic_types/set/all/file.rb ~~~~~~~~~~~
|
3
|
-
# FIXME: these methods should move to type/file.rb but some machine stuff is failing if it's not in a "all" set
|
4
|
-
def store_dir
|
5
|
-
if (mod = mod_file?)
|
6
|
-
"#{ Cardio.gem_root}/mod/#{mod}/file/#{codename}"
|
7
|
-
elsif id
|
8
|
-
"#{ Card.paths['files'].existent.first }/#{id}"
|
9
|
-
else
|
10
|
-
tmp_store_dir
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def tmp_store_dir
|
15
|
-
"#{ Card.paths['files'].existent.first }/#{key}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def mod_file?
|
19
|
-
# when db_content was changed assume that it's no longer a mod file
|
20
|
-
if !db_content_changed? && content.present? && content =~ /^:[^\/]+\/([^.]+)/
|
21
|
-
$1
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
3
|
format :file do
|
28
4
|
|
29
5
|
view :core do |args|
|
@@ -8,11 +8,10 @@ format :rss do
|
|
8
8
|
|
9
9
|
def initialize card, args
|
10
10
|
super
|
11
|
-
@xml = @parent.xml
|
11
|
+
@xml = @parent ? @parent.xml : ::Builder::XmlMarkup.new
|
12
12
|
end
|
13
13
|
|
14
14
|
def show view, args
|
15
|
-
@xml = ::Builder::XmlMarkup.new
|
16
15
|
view ||= :feed
|
17
16
|
render view, args
|
18
17
|
end
|
@@ -26,7 +25,7 @@ format :rss do
|
|
26
25
|
@xml.title render_feed_title
|
27
26
|
@xml.description render_feed_description
|
28
27
|
@xml.link render_url
|
29
|
-
|
28
|
+
render_feed_body
|
30
29
|
end
|
31
30
|
end
|
32
31
|
rescue =>e
|
@@ -34,12 +33,16 @@ format :rss do
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
|
-
def raw_feed_items
|
36
|
+
def raw_feed_items args
|
38
37
|
[card]
|
39
38
|
end
|
40
39
|
|
40
|
+
view :feed_body do |args|
|
41
|
+
render_feed_item_list
|
42
|
+
end
|
43
|
+
|
41
44
|
view :feed_item_list do |args|
|
42
|
-
raw_feed_items.each do |item|
|
45
|
+
raw_feed_items(args).each do |item|
|
43
46
|
@xml.item do
|
44
47
|
subformat(item).render_feed_item :view_changes=>(card.id==RecentID) #FIXME! yuck.
|
45
48
|
end
|
@@ -187,7 +187,7 @@ format :css do
|
|
187
187
|
|
188
188
|
view :core do |args|
|
189
189
|
card.item_cards.map do |item|
|
190
|
-
nest item, :view=>(
|
190
|
+
nest item, :view=>(args[:item] || :content)
|
191
191
|
end.join "\n\n"
|
192
192
|
end
|
193
193
|
|
@@ -199,7 +199,7 @@ end
|
|
199
199
|
format :js do
|
200
200
|
view :core do |args|
|
201
201
|
card.item_cards.map do |item|
|
202
|
-
nest item, :view=>(
|
202
|
+
nest item, :view=>( args[:item] || :core)
|
203
203
|
end.join "\n\n"
|
204
204
|
end
|
205
205
|
end
|
@@ -2,13 +2,18 @@
|
|
2
2
|
class Card; module Set; module Right; module Structure; extend Card::Set # ~~~~~~~~~~~ above autogenerated; below pulled from /Users/ethan/dev/wagn/gem/card/mod/04_settings/set/right/structure.rb ~~~~~~~~~~~
|
3
3
|
|
4
4
|
format :rss do
|
5
|
-
def raw_feed_items
|
5
|
+
def raw_feed_items args
|
6
6
|
[card]
|
7
|
-
end
|
7
|
+
end
|
8
8
|
end
|
9
9
|
|
10
10
|
format :html do
|
11
11
|
include AddHelp::HtmlFormat
|
12
|
+
|
13
|
+
view :core do |args|
|
14
|
+
render_raw args
|
15
|
+
end
|
16
|
+
|
12
17
|
end
|
13
18
|
|
14
19
|
|
@@ -65,7 +65,7 @@ def followable?
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def notable_change?
|
68
|
-
!supercard && current_act && Card::Auth.current_id != WagnBotID && followable?
|
68
|
+
!silent_change && !supercard && current_act && Card::Auth.current_id != WagnBotID && followable?
|
69
69
|
end
|
70
70
|
|
71
71
|
event :notify_followers_after_save, :after=>:subsequent, :on=>:save, :when=>proc{ |ca| ca.notable_change? } do
|
@@ -1,34 +1,87 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class Card; module Set; module Abstract; module Attachment; extend Card::Set # ~~~~~~~~~~~ above autogenerated; below pulled from /Users/ethan/dev/wagn/gem/card/mod/05_standard/set/abstract/attachment.rb ~~~~~~~~~~~
|
3
3
|
require 'carrier_wave/cardmount'
|
4
|
+
|
4
5
|
def self.included host_class
|
5
6
|
host_class.extend CarrierWave::CardMount
|
6
7
|
end
|
7
8
|
|
9
|
+
event :select_file_revision, :after=>:select_action do
|
10
|
+
attachment.retrieve_from_store!(attachment.identifier)
|
11
|
+
end
|
8
12
|
|
9
|
-
event :
|
10
|
-
|
13
|
+
event :determine_store_place, :before=>:prepare, :on=>:update do
|
14
|
+
@store_place = load_from_mod || :deck
|
11
15
|
end
|
12
16
|
|
13
|
-
event :
|
14
|
-
|
15
|
-
|
17
|
+
event :upload_attachment, :before=>:validate_name, :on=>:save, :when=>proc { |c| c.preliminary_upload? } do
|
18
|
+
save_original_filename # save original filename as comment in action
|
19
|
+
write_identifier # set db_content (needs original filename to determine extension)
|
20
|
+
store_attachment!
|
21
|
+
finalize_action # create Card::Change entry for db_content
|
22
|
+
@current_action.update_attributes! :draft => true, :card_id => (new_card? ? upload_cache_card.id : id)
|
23
|
+
|
24
|
+
success << {
|
25
|
+
:target => (new_card? ? upload_cache_card : '_self'),
|
26
|
+
:type=> type_name,
|
27
|
+
:view => 'preview_editor',
|
28
|
+
:rev_id => current_action.id
|
29
|
+
}
|
30
|
+
abort :success
|
31
|
+
end
|
32
|
+
|
33
|
+
event :assign_attachment_on_create, :after=>:prepare, :on=>:create do
|
34
|
+
if save_preliminary_upload? && (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
|
35
|
+
upload_cache_card.selected_action_id = action.id
|
36
|
+
upload_cache_card.select_file_revision
|
37
|
+
assign_attachment upload_cache_card.attachment.file, action.comment
|
38
|
+
action.delete # TODO: delete files too
|
16
39
|
end
|
17
40
|
end
|
18
41
|
|
19
|
-
event :
|
20
|
-
if ::
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
42
|
+
event :assign_attachment_on_update, :after=>:prepare, :on=>:update do
|
43
|
+
if save_preliminary_upload? && (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
|
44
|
+
uploaded_file =
|
45
|
+
with_selected_action_id(action.id) do
|
46
|
+
attachment.file
|
47
|
+
end
|
48
|
+
assign_attachment uploaded_file, action.comment
|
49
|
+
action.delete
|
25
50
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_attachment file, original_filename
|
54
|
+
send "#{attachment_name}=", file
|
55
|
+
write_identifier
|
56
|
+
@current_action.update_attributes! :comment=>original_filename
|
57
|
+
end
|
58
|
+
|
59
|
+
# we need a card id for the path so we have to update db_content when we got an id
|
60
|
+
event :correct_identifier, :after=>:store, :on=>:create do
|
61
|
+
update_column(:db_content,attachment.db_content(:mod=>load_from_mod))
|
62
|
+
expire
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
event :save_original_filename, :after=>:validate_name, :when => proc {|c| !c.preliminary_upload? && !c.save_preliminary_upload? && c.attachment_changed?} do
|
67
|
+
if @current_action
|
68
|
+
@current_action.update_attributes! :comment=>original_filename
|
29
69
|
end
|
30
70
|
end
|
31
71
|
|
72
|
+
event :write_identifier, :after=>:save_original_filename do
|
73
|
+
self.content = attachment.db_content(:mod=>load_from_mod)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def upload_cache_card
|
78
|
+
@upload_cache_card ||= Card["new_#{attachment_name}".to_sym ]
|
79
|
+
end
|
80
|
+
|
81
|
+
def tmp_store_dir action_id=nil
|
82
|
+
"#{ Card.paths['files'].existent.first }/#{upload_cache_card.id}"
|
83
|
+
end
|
84
|
+
|
32
85
|
def item_names(args={}) # needed for flexmail attachments. hacky.
|
33
86
|
[self.cardname]
|
34
87
|
end
|
@@ -37,6 +90,60 @@ def original_filename
|
|
37
90
|
attachment.original_filename
|
38
91
|
end
|
39
92
|
|
93
|
+
def preliminary_upload?
|
94
|
+
Card::Env && Card::Env.params[:attachment_upload]
|
95
|
+
end
|
96
|
+
|
97
|
+
def save_preliminary_upload?
|
98
|
+
Card::Env.params[:cached_upload].present?
|
99
|
+
end
|
100
|
+
|
101
|
+
def attachment_changed?
|
102
|
+
send "#{attachment_name}_changed?"
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_versions?
|
106
|
+
true
|
107
|
+
end
|
108
|
+
|
109
|
+
def store_place
|
110
|
+
@store_place ||= mod_file? || :deck
|
111
|
+
end
|
112
|
+
|
113
|
+
def load_from_mod= value
|
114
|
+
@mod = value
|
115
|
+
end
|
116
|
+
|
117
|
+
def load_from_mod
|
118
|
+
@mod
|
119
|
+
end
|
120
|
+
|
121
|
+
def store_dir
|
122
|
+
if (store_place == :deck)
|
123
|
+
if id
|
124
|
+
"#{ Card.paths['files'].existent.first }/#{id}"
|
125
|
+
else
|
126
|
+
tmp_store_dir
|
127
|
+
end
|
128
|
+
else
|
129
|
+
"#{ Cardio.gem_root}/mod/#{store_place}/file/#{codename}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def mod_file?
|
134
|
+
# when db_content was changed assume that it's no longer a mod file
|
135
|
+
if @store_place != :deck && !db_content_changed? && content.present?
|
136
|
+
case content
|
137
|
+
when /^:[^\/]+\/([^.]+)/ ; $1 # current mod_file format
|
138
|
+
when /^\~/ ; false # current id file format
|
139
|
+
else
|
140
|
+
if lines = content.split("\n") and lines.size == 4 # old format, still used in card_changes.
|
141
|
+
lines.last
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
40
147
|
|
41
148
|
def assign_set_specific_attributes
|
42
149
|
if @set_specific && @set_specific.present?
|
@@ -45,6 +152,17 @@ def assign_set_specific_attributes
|
|
45
152
|
super
|
46
153
|
end
|
47
154
|
|
155
|
+
def clear_upload_tmp_dir
|
156
|
+
Dir.entries(tmp_store_dir).each do |filename|
|
157
|
+
if filename =~/^\d+/
|
158
|
+
path = File.join(tmp_store_dir, filename )
|
159
|
+
older_than_five_days = ( DateTime.now - File.ctime(path) > 432000)
|
160
|
+
if older_than_five_days
|
161
|
+
FileUtils.rm path
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
48
166
|
|
49
167
|
def symlink_to(prior_action_id) # create filesystem links to files from prior action
|
50
168
|
if prior_action_id != last_action_id
|