card 1.20.4 → 1.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +9 -9
  4. data/db/migrate_core_cards/20170515101262_add_advanced_edit_cards.rb +20 -0
  5. data/db/migrate_core_cards/20170608083819_add_full_width_layout_card.rb +23 -0
  6. data/db/migrate_core_cards/20170608200649_add_input_options_codename.rb +8 -0
  7. data/db/seed/new/card_actions.yml +783 -791
  8. data/db/seed/new/card_acts.yml +65 -47
  9. data/db/seed/new/card_changes.yml +3198 -3177
  10. data/db/seed/new/card_references.yml +604 -534
  11. data/db/seed/new/cards.yml +2355 -2256
  12. data/db/seed/test/fixtures/card_actions.yml +1795 -1803
  13. data/db/seed/test/fixtures/card_acts.yml +264 -246
  14. data/db/seed/test/fixtures/card_changes.yml +6275 -6184
  15. data/db/seed/test/fixtures/card_references.yml +1305 -1263
  16. data/db/seed/test/fixtures/cards.yml +3393 -3298
  17. data/db/seed/test/seed.rb +2 -2
  18. data/db/version_core_cards.txt +1 -1
  19. data/lib/card.rb +4 -0
  20. data/lib/card/act_manager/subdirector_array.rb +1 -0
  21. data/lib/card/auth/current.rb +7 -3
  22. data/lib/card/env.rb +5 -0
  23. data/lib/card/env/success.rb +1 -1
  24. data/lib/card/format/names.rb +3 -13
  25. data/lib/card/model/save_helper.rb +4 -6
  26. data/lib/card/query.rb +2 -1
  27. data/lib/card/query/attributes.rb +34 -14
  28. data/lib/card/query/value.rb +3 -4
  29. data/lib/card/set/format.rb +29 -4
  30. data/lib/card/set/format/haml_views.rb +25 -13
  31. data/lib/card/set/trait.rb +1 -0
  32. data/lib/card/set_pattern.rb +17 -1
  33. data/lib/card/subcards.rb +3 -2
  34. data/lib/generators/card/format/format_generator.rb +2 -0
  35. data/lib/generators/card/set/set_generator.rb +2 -0
  36. data/lib/generators/card/template/USAGE +10 -0
  37. data/lib/generators/card/template/template_generator.rb +46 -0
  38. data/lib/generators/card/template/templates/haml_template.erb +1 -0
  39. data/mod/Modfile +1 -1
  40. data/mod/account/set/all/account.rb +9 -5
  41. data/mod/account/set/right/account.rb +17 -5
  42. data/mod/account/set/self/account_links.rb +1 -2
  43. data/mod/account/set/type/signup.rb +4 -5
  44. data/mod/account/set/type/user.rb +1 -1
  45. data/mod/account/spec/set/all/account_spec.rb +2 -2
  46. data/mod/account/spec/set/right/account_spec.rb +2 -2
  47. data/mod/account/spec/set/right/email_spec.rb +1 -1
  48. data/mod/account/spec/set/right/password_spec.rb +1 -1
  49. data/mod/account/spec/set/self/signin_spec.rb +2 -2
  50. data/mod/account/spec/set/type/signup_spec.rb +4 -0
  51. data/mod/ace_editor/set/abstract/ace_editor.rb +6 -3
  52. data/mod/ace_editor/set/self/script_ace.rb +1 -0
  53. data/mod/admin/set/self/admin.rb +1 -1
  54. data/mod/admin/set/self/version.rb +1 -0
  55. data/mod/basic_formats/format/css_format.rb +1 -0
  56. data/mod/basic_formats/format/csv_format.rb +1 -0
  57. data/mod/basic_formats/format/file_format.rb +1 -0
  58. data/mod/basic_formats/format/js_format.rb +1 -0
  59. data/mod/basic_formats/format/json_format.rb +1 -0
  60. data/mod/basic_formats/format/rss_format.rb +1 -0
  61. data/mod/basic_formats/format/xml_format.rb +1 -0
  62. data/mod/basic_formats/set/all/all_csv.rb +1 -1
  63. data/mod/basic_formats/set/all/base.rb +11 -3
  64. data/mod/basic_formats/set/all/json.rb +50 -8
  65. data/mod/basic_formats/set/all/rss.rb +21 -7
  66. data/mod/basic_formats/set/self/01_head/javascript.rb +1 -1
  67. data/mod/basic_formats/set/self/head.rb +1 -1
  68. data/mod/basic_formats/spec/set/all/base_spec.rb +13 -0
  69. data/mod/basic_types/set/type/html.rb +6 -2
  70. data/mod/basic_types/set/type/plain_text.rb +2 -3
  71. data/mod/bootstrap/lib/bootstrap.rb +2 -2
  72. data/mod/bootstrap/lib/bootstrap/basic_tags.rb +1 -1
  73. data/mod/bootstrap/lib/bootstrap/component.rb +2 -3
  74. data/mod/bootstrap/lib/bootstrap/component/form.rb +6 -5
  75. data/mod/bootstrap/lib/bootstrap/component/horizontal_form.rb +1 -1
  76. data/mod/bootstrap/lib/bootstrap/component/layout.rb +3 -3
  77. data/mod/bootstrap/lib/bootstrap/component_loader.rb +0 -2
  78. data/mod/bootstrap/lib/bootstrap/delegate.rb +2 -2
  79. data/mod/bootstrap/lib/bootstrapper.rb +1 -1
  80. data/mod/bootstrap/set/all/bootstrap/accordion.rb +1 -1
  81. data/mod/bootstrap/set/all/bootstrap/form.rb +2 -2
  82. data/mod/bootstrap/set/all/bootstrap/helper.rb +1 -0
  83. data/mod/bootstrap/set/all/bootstrap/wrapper.rb +1 -1
  84. data/mod/bootstrap/set/self/bootstrap_js.rb +1 -1
  85. data/mod/bootstrap/set/self/bootswatch_shared.rb +6 -6
  86. data/mod/bootstrap/set/self/script_mods.rb +1 -1
  87. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_builder_spec.rb +7 -6
  88. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_spec.rb +2 -1
  89. data/mod/bootstrap/spec/set/all/bootstrap/form_spec.rb +6 -3
  90. data/mod/bootstrap/spec/set/all/bootstrap/layout_spec.rb +3 -2
  91. data/mod/carrierwave/set/abstract/attachment.rb +1 -3
  92. data/mod/carrierwave/set/abstract/attachment/paths.rb +1 -1
  93. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +11 -1
  94. data/mod/carrierwave/set/type/file.rb +3 -3
  95. data/mod/carrierwave/spec/lib/carrier_wave/file_card_uploader_spec.rb +3 -0
  96. data/mod/carrierwave/spec/set/type/file_spec.rb +24 -6
  97. data/mod/carrierwave/spec/set/type/image_spec.rb +3 -0
  98. data/mod/core/chunk/link.rb +1 -1
  99. data/mod/core/chunk/nest.rb +2 -1
  100. data/mod/core/chunk/query_reference.rb +1 -1
  101. data/mod/core/chunk/reference.rb +1 -0
  102. data/mod/core/chunk/uri.rb +4 -3
  103. data/mod/core/set/abstract/lock.rb +26 -0
  104. data/mod/core/set/all/assign_attributes.rb +8 -4
  105. data/mod/core/set/all/collection.rb +16 -7
  106. data/mod/core/set/all/content.rb +6 -0
  107. data/mod/core/set/all/event.rb +1 -1
  108. data/mod/core/set/all/fetch.rb +2 -2
  109. data/mod/core/set/all/haml.rb +5 -15
  110. data/mod/core/set/all/initialize.rb +2 -2
  111. data/mod/core/set/all/name.rb +1 -1
  112. data/mod/core/set/all/permissions.rb +28 -16
  113. data/mod/core/set/all/rules.rb +1 -2
  114. data/mod/core/set/all/subcards.rb +3 -3
  115. data/mod/core/set/all/templating.rb +5 -1
  116. data/mod/core/set/all/trash.rb +1 -1
  117. data/mod/core/set/all/utils.rb +1 -1
  118. data/mod/core/spec/set/all/actify_spec.rb +1 -1
  119. data/mod/core/spec/set/all/assign_attributes_spec.rb +2 -2
  120. data/mod/core/spec/set/all/collection_spec.rb +6 -3
  121. data/mod/core/spec/set/all/export_spec.rb +40 -112
  122. data/mod/core/spec/set/all/name_spec.rb +1 -1
  123. data/mod/core/spec/set/all/permissions_spec.rb +7 -7
  124. data/mod/core/spec/set/all/rules2_spec.rb +25 -25
  125. data/mod/core/spec/set/all/rules_spec.rb +2 -7
  126. data/mod/developer/set/all/event_viz.rb +1 -1
  127. data/mod/developer/set/right/debug.rb +1 -1
  128. data/mod/history/lib/card/act.rb +1 -0
  129. data/mod/history/lib/card/act/act_renderer.rb +23 -20
  130. data/mod/history/lib/card/act/act_renderer/absolute_act_renderer.rb +0 -1
  131. data/mod/history/lib/card/act/act_renderer/relative_act_renderer.rb +1 -0
  132. data/mod/history/lib/card/action.rb +1 -1
  133. data/mod/history/lib/card/action/action_renderer.rb +2 -2
  134. data/mod/history/lib/card/change.rb +2 -1
  135. data/mod/history/set/all/action_view.rb +1 -1
  136. data/mod/history/set/all/content_history.rb +7 -4
  137. data/mod/history/set/all/history.rb +6 -6
  138. data/mod/machines/file/all_script_machine_output/file.js +50 -34
  139. data/mod/machines/file/all_style_machine_output/file.css +1 -1
  140. data/mod/machines/lib/javascript/wagn.js.coffee +29 -18
  141. data/mod/machines/lib/javascript/wagn_layout.js.coffee +7 -3
  142. data/mod/machines/lib/stylesheets/style_cards.scss +10 -10
  143. data/mod/machines/set/abstract/machine.rb +5 -28
  144. data/mod/machines/set/abstract/script.rb +7 -4
  145. data/mod/machines/set/all/reset_machines.rb +1 -1
  146. data/mod/machines/set/self/script_jquery_helper.rb +2 -2
  147. data/mod/machines/set/self/script_slot.rb +1 -1
  148. data/mod/machines/set/type/coffee_script.rb +3 -2
  149. data/mod/machines/set/type/css.rb +7 -3
  150. data/mod/machines/set/type/scss.rb +7 -1
  151. data/mod/machines/spec/set/type/coffeescript_spec.rb +1 -1
  152. data/mod/machines/spec/set/type/javascript_spec.rb +1 -1
  153. data/mod/machines/spec/set/type/scss_spec.rb +3 -2
  154. data/mod/machines/spec/set/type/skin_spec.rb +1 -1
  155. data/mod/machines/spec/shared_examples/machine.rb +5 -3
  156. data/mod/machines/spec/shared_examples/machine_input.rb +1 -0
  157. data/mod/notifications/format/email_html_format.rb +1 -0
  158. data/mod/notifications/set/all/follow.rb +1 -1
  159. data/mod/notifications/set/all/observer.rb +1 -1
  160. data/mod/notifications/set/all/send_notifications.rb +2 -2
  161. data/mod/notifications/set/self/follow_defaults.rb +3 -8
  162. data/mod/notifications/set/type/email_template/email_config.rb +2 -2
  163. data/mod/notifications/set/type_plus_right/user/follow.rb +2 -2
  164. data/mod/notifications/spec/set/all/follow_spec.rb +7 -0
  165. data/mod/notifications/spec/set/all/notify_spec.rb +3 -0
  166. data/mod/notifications/spec/set/all/observer_spec.rb +1 -1
  167. data/mod/notifications/spec/set/right/followers_spec.rb +1 -0
  168. data/mod/pointer/set/abstract/00_paging_params.rb +11 -0
  169. data/mod/pointer/set/abstract/{00_paging.rb → 01_paging.rb} +10 -6
  170. data/mod/pointer/set/abstract/{00_paging → 01_paging}/paging_links.rb +0 -0
  171. data/mod/pointer/set/abstract/{01_pointer.rb → 02_pointer.rb} +26 -5
  172. data/mod/pointer/set/abstract/{01_pointer → 02_pointer}/edit.rb +3 -5
  173. data/mod/pointer/set/self/input_options.rb +12 -0
  174. data/mod/pointer/spec/set/self/input_options_spec.rb +8 -0
  175. data/mod/pointer/spec/set/type/pointer_spec.rb +3 -2
  176. data/mod/prosemirror_editor/set/abstract/prosemirror_editor.rb +1 -1
  177. data/mod/prosemirror_editor/set/self/script_prosemirror.rb +1 -0
  178. data/mod/settings/lib/card/setting.rb +1 -2
  179. data/mod/settings/set/abstract/permission.rb +1 -1
  180. data/mod/settings/set/self/add_help.rb +1 -1
  181. data/mod/settings/set/self/autoname.rb +1 -1
  182. data/mod/settings/set/self/csv_structure.rb +2 -0
  183. data/mod/settings/set/self/help.rb +1 -1
  184. data/mod/settings/set/self/input.rb +1 -2
  185. data/mod/settings/set/self/options.rb +2 -2
  186. data/mod/settings/set/self/options_label.rb +2 -2
  187. data/mod/settings/set/type/setting.rb +1 -1
  188. data/mod/settings/spec/set/right/script_spec.rb +1 -1
  189. data/mod/settings/spec/set/right/style_spec.rb +1 -1
  190. data/mod/solid_cache/set/abstract/solid_cache.rb +5 -3
  191. data/mod/solid_cache/spec/set/abstract/solid_cache_spec.rb +4 -3
  192. data/mod/standard/set/abstract/01_search_params.rb +4 -3
  193. data/mod/standard/set/abstract/search.rb +2 -1
  194. data/mod/standard/set/abstract/toolbar_split_button.rb +22 -0
  195. data/mod/standard/set/all/links.rb +3 -3
  196. data/mod/standard/set/all/rich_html/classy.rb +37 -0
  197. data/mod/standard/set/all/rich_html/editing.rb +6 -2
  198. data/mod/standard/set/all/rich_html/editor.rb +50 -0
  199. data/mod/standard/set/all/rich_html/form.rb +19 -12
  200. data/mod/standard/set/all/rich_html/form_elements.rb +2 -2
  201. data/mod/standard/set/all/rich_html/formgroup.rb +2 -1
  202. data/mod/standard/set/all/rich_html/header.rb +2 -27
  203. data/mod/standard/set/all/rich_html/menu.rb +1 -1
  204. data/mod/standard/set/all/rich_html/new.rb +5 -1
  205. data/mod/standard/set/all/rich_html/toolbar.rb +15 -60
  206. data/mod/standard/set/all/rich_html/wrapper.rb +6 -3
  207. data/mod/standard/set/right/when_created.rb +2 -2
  208. data/mod/standard/set/rstar/rules_editor.rb +10 -7
  209. data/mod/standard/set/self/activity_toolbar_button.rb +14 -0
  210. data/mod/standard/set/self/recent.rb +7 -2
  211. data/mod/standard/set/self/rules_toolbar_button.rb +42 -0
  212. data/mod/standard/set/self/search.rb +19 -6
  213. data/mod/standard/set/type/basic.rb +6 -6
  214. data/mod/standard/set/type/cardtype.rb +7 -3
  215. data/mod/standard/set/type/date.rb +2 -4
  216. data/mod/standard/set/type/layout_type.rb +1 -0
  217. data/mod/standard/set/type/list.rb +1 -1
  218. data/mod/standard/set/type/listed_by.rb +1 -2
  219. data/mod/standard/set/type/number.rb +4 -2
  220. data/mod/standard/set/type/phrase.rb +4 -2
  221. data/mod/standard/set/type/search_type.rb +11 -3
  222. data/mod/standard/set/type/set.rb +8 -8
  223. data/mod/standard/set/type/toggle.rb +1 -3
  224. data/mod/standard/set/type/uri.rb +6 -2
  225. data/mod/standard/spec/chunk/include_spec.rb +3 -2
  226. data/mod/standard/spec/chunk/query_reference_spec.rb +2 -2
  227. data/mod/standard/spec/set/all/history_spec.rb +1 -0
  228. data/mod/standard/spec/set/all/links_spec.rb +1 -0
  229. data/mod/standard/spec/set/all/rich_html/toolbar_spec.rb +2 -0
  230. data/mod/standard/spec/set/self/activity_toolbar_button_spec.rb +22 -0
  231. data/mod/standard/spec/set/type/email_template/email_config_spec.rb +10 -8
  232. data/mod/standard/spec/set/type/email_template_spec.rb +1 -0
  233. data/mod/standard/spec/set/type/list_spec.rb +2 -0
  234. data/mod/standard/spec/set/type/listed_by_spec.rb +5 -0
  235. data/mod/standard/spec/set/type/search_type_spec.rb +1 -1
  236. data/mod/standard/spec/set/type/toggle_spec.rb +1 -2
  237. data/mod/standard/spec/set/type/uri_spec.rb +0 -1
  238. data/mod/tinymce_editor/db/migrate_cards/20160804112560_add_tinymce_cards.rb +3 -1
  239. data/mod/tinymce_editor/set/abstract/tinymce_editor.rb +1 -1
  240. data/mod/tinymce_editor/set/self/script_tinymce.rb +1 -0
  241. data/mod/twitter/db/migrate_cards/20170305112346_add_twitter_cards.rb +1 -1
  242. data/mod/twitter/set/type/twitter_template.rb +1 -1
  243. data/spec/lib/card/format_spec.rb +26 -7
  244. data/spec/lib/card/loader_spec.rb +96 -35
  245. data/spec/lib/card/query_spec.rb +0 -1
  246. data/spec/support/card_spec_loader.rb +1 -0
  247. data/spec/support/helper/card_helper.rb +0 -36
  248. data/spec/support/helper/set_helper.rb +80 -0
  249. data/spec/support/matchers.rb +74 -0
  250. data/tmpsets/set/mod001-core/all/actify.rb +5 -6
  251. data/tmpsets/set/mod001-core/all/fetch.rb +14 -12
  252. data/tmpsets/set/mod001-core/all/name.rb +1 -1
  253. data/tmpsets/set/mod001-core/all/permissions.rb +12 -22
  254. data/tmpsets/set/mod001-core/all/tracked_attributes.rb +76 -0
  255. data/tmpsets/set/mod001-core/all/utils.rb +40 -3
  256. data/tmpsets/set/mod002-history/all/history.rb +1 -2
  257. data/tmpsets/set/mod008-solid_cache/abstract/solid_cache.rb +1 -1
  258. data/tmpsets/set/mod013-carrierwave/abstract/attachment.rb +282 -0
  259. data/tmpsets/set/mod013-carrierwave/type/file.rb +155 -0
  260. data/tmpsets/set/mod013-carrierwave/type/image.rb +96 -0
  261. data/tmpsets/set/mod014-admin/self/admin.rb +113 -0
  262. data/tmpsets/set/mod014-admin/self/admin_info.rb +110 -0
  263. data/tmpsets/set/mod014-admin/self/version.rb +15 -0
  264. data/tmpsets/set/mod015-developer/all/event_viz.rb +59 -0
  265. data/tmpsets/set/mod015-developer/all/view_viz.rb +30 -0
  266. data/tmpsets/set/mod015-developer/right/debug.rb +96 -0
  267. metadata +52 -22
@@ -11,18 +11,20 @@ module ClassMethods
11
11
  # * database
12
12
  # * virtual cards
13
13
  #
14
- # @param args [Integer, String, Card::Name, Symbol]
15
- # one or more of the three unique identifiers
16
- # 1. a numeric id (Integer)
17
- # 2. a name/key (String or Card::Name)
18
- # 3. a codename (Symbol)
19
- # If you pass more then one mark they get joined with a '+'.
20
- # The final argument can be a hash to set the following options
21
- # :skip_virtual Real cards only
22
- # :skip_modules Don't load Set modules
23
- # :look_in_trash Return trashed card objects
24
- # :local_only Use only local cache for lookup and storing
25
- # new: { opts for Card#new } Return a new card when not found
14
+ # @param mark [Integer, String, Card::Name, Symbol, Array]
15
+ # one of three unique identifiers
16
+ # 1. a numeric id (Integer)
17
+ # 2. a name/key (String or Card::Name)
18
+ # 3. a codename (Symbol)
19
+ # or any combination of those. If you pass more then one mark they get
20
+ # joined with a '+'
21
+ # @param options [Hash]
22
+ # Options:
23
+ # :skip_virtual Real cards only
24
+ # :skip_modules Don't load Set modules
25
+ # :look_in_trash Return trashed card objects
26
+ # :local_only Use only local cache for lookup and storing
27
+ # new: { opts for Card#new } Return a new card when not found
26
28
  #
27
29
  # @return [Card]
28
30
  def fetch *args
@@ -56,11 +56,11 @@ def update_subcard_names cardname
56
56
  # and self is a subcard as well that changed from +B to A+B then
57
57
  # +C should change to A+B+C. #replace_part doesn't work in this case
58
58
  # because the old name +B is not a part of +C
59
+ # name_to_replace =
59
60
  name_to_replace =
60
61
  if subcard.cardname.junction? &&
61
62
  subcard.cardname.parts.first.empty? &&
62
63
  cardname.parts.first.present?
63
- # replace the empty part
64
64
  "".to_name
65
65
  else
66
66
  name
@@ -187,38 +187,28 @@ event :set_field_read_rules,
187
187
  end
188
188
  end
189
189
 
190
- # currently doing a brute force search for every card that may be impacted.
191
- # may want to optimize(?)
192
- def update_field_read_rules
190
+ def update_read_rule
191
+ Card.record_timestamps = false
192
+ reset_patterns # why is this needed?
193
+ rcard_id, rclass = permission_rule_id_and_class :read
194
+ # these two are just to make sure vals are correct on current object
195
+ self.read_rule_id = rcard_id
196
+ self.read_rule_class = rclass
197
+ Card.where(id: id).update_all read_rule_id: rcard_id, read_rule_class: rclass
198
+ expire_hard
199
+
200
+ # currently doing a brute force search for every card that may be impacted.
201
+ # may want to optimize(?)
193
202
  Auth.as_bot do
194
203
  fields.each do |field|
195
204
  field.update_read_rule if field.rule(:read) == "_left"
196
205
  end
197
206
  end
198
- end
199
207
 
200
- def without_timestamps
201
- Card.record_timestamps = false
202
- yield
203
208
  ensure
204
209
  Card.record_timestamps = true
205
210
  end
206
211
 
207
- event :update_read_rule do
208
- without_timestamps do
209
- reset_patterns # why is this needed?
210
- rcard_id, rclass = permission_rule_id_and_class :read
211
- # these two are just to make sure vals are correct on current object
212
- self.read_rule_id = rcard_id
213
- self.read_rule_class = rclass
214
- Card.where(id: id).update_all read_rule_id: rcard_id,
215
- read_rule_class: rclass
216
- expire_hard
217
-
218
- update_field_read_rules
219
- end
220
- end
221
-
222
212
  def add_to_read_rule_update_queue updates
223
213
  @read_rule_update_queue = Array.wrap(@read_rule_update_queue).concat updates
224
214
  end
@@ -73,6 +73,82 @@ event :set_content, :store, on: :save do
73
73
  reset_patterns_if_rule true
74
74
  end
75
75
 
76
+ # FIXME: the following don't really belong here, but they have to come after
77
+ # the reference stuff. we need to organize a bit!
78
+
79
+ event :update_ruled_cards, :finalize do
80
+ if is_rule?
81
+ # warn "updating ruled cards for #{name}"
82
+ self.class.clear_rule_cache
83
+ set = rule_set
84
+
85
+ if right_id == Card::ReadID && (name_changed? || trash_changed?)
86
+ update_read_ruled_cards set
87
+ end
88
+ end
89
+ end
90
+
91
+ def update_read_rules_of_set_members_not_governed_by_narrower_rules set
92
+ return {} if trash || !set || !(set_class = set.tag) ||
93
+ !(class_id = set_class.id)
94
+ in_set = {}
95
+ rule_class_ids = set_patterns.map(&:pattern_id)
96
+ Auth.as_bot do
97
+ cur_index = rule_class_ids.index Card[read_rule_class].id
98
+ if (rule_class_index = rule_class_ids.index(class_id))
99
+ set.item_cards(limit: 0).each do |item_card|
100
+ in_set[item_card.key] = true
101
+ next if cur_index < rule_class_index
102
+ item_card.update_read_rule if cur_index >= rule_class_index
103
+ end
104
+ else
105
+ warn "No current rule index #{class_id}, #{rule_class_ids.inspect}"
106
+ end
107
+ end
108
+ in_set
109
+ end
110
+
111
+ def update_read_ruled_cards set
112
+ self.class.clear_read_rule_cache
113
+ Card.cache.reset # maybe be more surgical, just Auth.user related
114
+ expire # probably shouldn't be necessary,
115
+ # but was sometimes getting cached version when card should be in the
116
+ # trash. could be related to other bugs?
117
+
118
+ updated = update_read_rules_of_set_members_not_governed_by_narrower_rules set
119
+
120
+ # then find all cards with me as read_rule_id that were not just updated
121
+ # and regenerate their read_rules
122
+ return if new_card?
123
+ Card.search(read_rule_id: id) do |card|
124
+ card.update_read_rule unless updated[card.key]
125
+ end
126
+ end
127
+
128
+ event :process_read_rule_update_queue, :finalize do
129
+ Array.wrap(@read_rule_update_queue).each(&:update_read_rule)
130
+ @read_rule_update_queue = []
131
+ end
132
+
133
+ event :expire_related, :finalize do
134
+ subcards.keys.each do |key|
135
+ Card.cache.soft.delete key
136
+ end
137
+ expire # FIXME: where do we put this. Here it deletes @stage
138
+ reset_patterns
139
+ if is_structure?
140
+ structuree_names.each do |name|
141
+ Card.expire name
142
+ end
143
+ end
144
+ end
145
+
146
+ event :expire_related_names, before: :expire_related, changed: :name do
147
+ # FIXME: look for opportunities to avoid instantiating the following
148
+ descendants.each(&:expire)
149
+ name_referers.each(&:expire)
150
+ end
151
+
76
152
 
77
153
  # ~~ below autogenerated; above pulled from /Users/ethan/dev/wagn/gem/card/mod/core/set/all/tracked_attributes.rb ~~
78
154
  end;end;end;end;
@@ -8,6 +8,7 @@ module ClassMethods
8
8
  Card::Action.delete_cardless
9
9
  Card::Reference.unmap_if_referee_missing
10
10
  Card::Reference.delete_if_referer_missing
11
+ Card.delete_tmp_files_of_cached_uploads
11
12
  end
12
13
 
13
14
  # deletes any file not associated with a real card.
@@ -43,6 +44,20 @@ module ClassMethods
43
44
  sql_results.map(&:values).flatten.map(&:to_i)
44
45
  end
45
46
 
47
+ def delete_tmp_files_of_cached_uploads
48
+ actions = Card::Action.find_by_sql "SELECT * FROM card_actions
49
+ INNER JOIN cards ON card_actions.card_id = cards.id
50
+ WHERE cards.type_id IN (#{Card::FileID}, #{Card::ImageID})
51
+ AND card_actions.draft = true"
52
+ actions.each do |action|
53
+ # we don't want to delete uploads in progress
54
+ if older_than_five_days?(action.created_at) && (card = action.card)
55
+ # we don't want to delete uploads in progress
56
+ card.delete_files_for_action action
57
+ end
58
+ end
59
+ end
60
+
46
61
  def merge_list attribs, opts={}
47
62
  unmerged = []
48
63
  attribs.each do |row|
@@ -72,7 +87,7 @@ module ClassMethods
72
87
  end
73
88
 
74
89
  def merge name, attribs={}, opts={}
75
- puts "merging #{name}"
90
+ # puts "merging #{name}"
76
91
  card = fetch name, new: {}
77
92
  [:image, :file].each do |attach|
78
93
  next unless attribs[attach] && attribs[attach].is_a?(String)
@@ -85,11 +100,33 @@ module ClassMethods
85
100
  end
86
101
  end
87
102
 
88
- def seed_test_db
89
- system "env RAILS_ENV=test bundle exec rake db:fixtures:load"
103
+ def older_than_five_days? time
104
+ Time.now - time > 432_000
90
105
  end
91
106
  end
92
107
 
108
+ def debug_type
109
+ "#{type_code || ''}:#{type_id}"
110
+ end
111
+
112
+ def to_s
113
+ "#<#{self.class.name}[#{debug_type}]#{attributes['name']}>"
114
+ end
115
+
116
+ def inspect
117
+ tags = []
118
+ tags << "trash" if trash
119
+ tags << "new" if new_card?
120
+ tags << "frozen" if frozen?
121
+ tags << "readonly" if readonly?
122
+ tags << "virtual" if @virtual
123
+ tags << "set_mods_loaded" if @set_mods_loaded
124
+
125
+ error_messages = errors.any? ? "<E*#{errors.full_messages * ', '}*>" : ""
126
+
127
+ "#<Card##{id}[#{debug_type}](#{name})#{error_messages}{#{tags * ','}}"
128
+ end
129
+
93
130
 
94
131
  # ~~ below autogenerated; above pulled from /Users/ethan/dev/wagn/gem/card/mod/core/set/all/utils.rb ~~
95
132
  end;end;end;end;
@@ -85,8 +85,7 @@ event :rollback_actions, :prepare_to_validate,
85
85
  Env.params["action_ids"] = nil
86
86
  update_attributes! revision
87
87
  rollback_actions.each do |action|
88
- # rollback file and image cards
89
- action.card.try :rollback_to, action
88
+ action.card.try :symlink_to, action.id
90
89
  end
91
90
  clear_drafts
92
91
  abort :success
@@ -31,7 +31,7 @@ module ClassMethods
31
31
  # cards whose solid caches are expired because of the update.
32
32
  # @param set_of_changed_card [set constant] a set of cards that triggers
33
33
  # a cache update
34
- # @param args [Hash]
34
+ # @params args [Hash]
35
35
  # @option args [Symbol, Array of symbols] :on the action(s)
36
36
  # (:create, :update, or :delete) on which the cache update
37
37
  # should be triggered. Default is all actions.
@@ -0,0 +1,282 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Card; module Set; class Abstract; module Attachment; extend Card::Set
3
+ # ~~ above autogenerated; below pulled from /Users/ethan/dev/wagn/gem/card/mod/carrierwave/set/abstract/attachment.rb ~~
4
+ require "carrier_wave/cardmount"
5
+
6
+ def self.included host_class
7
+ host_class.extend CarrierWave::CardMount
8
+ end
9
+
10
+ event :select_file_revision, after: :select_action do
11
+ attachment.retrieve_from_store!(attachment.identifier)
12
+ end
13
+
14
+ event :upload_attachment, :prepare_to_validate,
15
+ on: :save, when: proc { |c| c.preliminary_upload? } do
16
+ save_original_filename # save original filename as comment in action
17
+ write_identifier # set db_content
18
+ # (needs original filename to determine extension)
19
+ store_attachment!
20
+ finalize_action # create Card::Change entry for db_content
21
+
22
+ card_id = new_card? ? upload_cache_card.id : id
23
+ @current_action.update_attributes! draft: true, card_id: card_id
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, :initialize,
34
+ after: :assign_action, on: :create,
35
+ when: proc { |c| c.save_preliminary_upload? } do
36
+ if (action = Card::Action.fetch(@action_id_of_cached_upload))
37
+ upload_cache_card.selected_action_id = action.id
38
+ upload_cache_card.select_file_revision
39
+ assign_attachment upload_cache_card.attachment.file, action.comment
40
+ end
41
+ end
42
+
43
+ event :assign_attachment_on_update, :initialize,
44
+ after: :assign_action, on: :update,
45
+ when: proc { |c| c.save_preliminary_upload? } do
46
+ if (action = Card::Action.fetch(@action_id_of_cached_upload))
47
+ uploaded_file =
48
+ with_selected_action_id(action.id) do
49
+ attachment.file
50
+ end
51
+ assign_attachment uploaded_file, action.comment
52
+ end
53
+ end
54
+
55
+ def assign_attachment file, original_filename
56
+ send "#{attachment_name}=", file
57
+ write_identifier
58
+ @current_action.update_attributes! comment: original_filename
59
+ end
60
+
61
+ # we need a card id for the path so we have to update db_content when we have
62
+ # an id
63
+ event :correct_identifier, :finalize, on: :create do
64
+ update_column(:db_content, attachment.db_content(mod: load_from_mod))
65
+ expire
66
+ end
67
+
68
+ def file_ready_to_save?
69
+ attachment.file.present? &&
70
+ !preliminary_upload? &&
71
+ !save_preliminary_upload? &&
72
+ attachment_changed?
73
+ end
74
+
75
+ event :save_original_filename, :prepare_to_store,
76
+ when: proc { |c| c.file_ready_to_save? } do
77
+ return unless @current_action
78
+ @current_action.update_attributes! comment: original_filename
79
+ end
80
+
81
+ event :delete_cached_upload_file_on_create, :integrate,
82
+ on: :create, when: proc { |c| c.save_preliminary_upload? } do
83
+ if (action = Card::Action.fetch(@action_id_of_cached_upload))
84
+ upload_cache_card.delete_files_for_action action
85
+ action.delete
86
+ end
87
+ clear_upload_cache_dir_for_new_cards
88
+ end
89
+
90
+ event :delete_cached_upload_file_on_update, :integrate,
91
+ on: :update, when: proc { |c| c.save_preliminary_upload? } do
92
+ if (action = Card::Action.fetch(@action_id_of_cached_upload))
93
+ delete_files_for_action action
94
+ action.delete
95
+ end
96
+ end
97
+
98
+ event :validate_file_exist, :validate, on: :create do
99
+ unless attachment.file.present? || empty_ok?
100
+ errors.add attachment_name, "is missing"
101
+ end
102
+ end
103
+
104
+ event :write_identifier, after: :save_original_filename do
105
+ self.content = attachment.db_content(mod: load_from_mod)
106
+ end
107
+
108
+ def item_names _args={} # needed for flexmail attachments. hacky.
109
+ [cardname]
110
+ end
111
+
112
+ def original_filename
113
+ attachment.original_filename
114
+ end
115
+
116
+ def unfilled?
117
+ !attachment.present? && !save_preliminary_upload? && !subcards.present?
118
+ end
119
+
120
+ def preliminary_upload?
121
+ Card::Env && Card::Env.params[:attachment_upload]
122
+ end
123
+
124
+ def save_preliminary_upload?
125
+ @action_id_of_cached_upload.present?
126
+ end
127
+
128
+ def attachment_changed?
129
+ send "#{attachment_name}_changed?"
130
+ end
131
+
132
+ def create_versions?
133
+ true
134
+ end
135
+
136
+ # used for uploads for new cards until the new card is created
137
+ def upload_cache_card
138
+ @upload_cache_card ||= Card["new_#{attachment_name}".to_sym]
139
+ end
140
+
141
+ # action id of the cached upload
142
+ attr_writer :action_id_of_cached_upload
143
+
144
+ attr_reader :action_id_of_cached_upload
145
+
146
+ attr_writer :empty_ok
147
+
148
+ def empty_ok?
149
+ @empty_ok
150
+ end
151
+
152
+ def load_from_mod= value
153
+ @mod = value
154
+ write_identifier
155
+ @store_in_mod = true if value
156
+ end
157
+
158
+ def load_from_mod
159
+ @mod
160
+ end
161
+
162
+ def store_dir
163
+ if @store_in_mod
164
+ mod_dir
165
+ else
166
+ upload_dir
167
+ end
168
+ end
169
+
170
+ def retrieve_dir
171
+ if mod_file?
172
+ mod_dir
173
+ else
174
+ upload_dir
175
+ end
176
+ end
177
+
178
+ # place for files of regular file cards
179
+ def upload_dir
180
+ if id
181
+ "#{Card.paths['files'].existent.first}/#{id}"
182
+ else
183
+ tmp_upload_dir
184
+ end
185
+ end
186
+
187
+ # place for files if card doesn't have an id yet
188
+ def tmp_upload_dir _action_id=nil
189
+ "#{Card.paths['files'].existent.first}/#{upload_cache_card.id}"
190
+ end
191
+
192
+ # place for files of mod file cards
193
+ def mod_dir
194
+ mod = @mod || mod_file?
195
+ Card.paths["mod"].to_a.each do |mod_path|
196
+ dir = File.join(mod_path, mod, "file", codename)
197
+ return dir if Dir.exist? dir
198
+ end
199
+ end
200
+
201
+ def mod_file?
202
+ return @mod if @store_in_mod
203
+ # when db_content was changed assume that it's no longer a mod file
204
+ return if db_content_changed? || !content.present?
205
+ case content
206
+ when %r{^:[^/]+/([^.]+)} then Regexp.last_match(1) # current mod_file format
207
+ when /^\~/ then false # current id file format
208
+ else
209
+ if (lines = content.split("\n")) && (lines.size == 4)
210
+ # old format, still used in card_changes.
211
+ lines.last
212
+ end
213
+ end
214
+ end
215
+
216
+ def assign_set_specific_attributes
217
+ # reset content if we really have something to upload
218
+ if @set_specific.present? && @set_specific[attachment_name.to_s].present?
219
+ self.content = nil
220
+ end
221
+ super
222
+ end
223
+
224
+ def clear_upload_cache_dir_for_new_cards
225
+ Dir.entries(tmp_upload_dir).each do |filename|
226
+ if filename =~ /^\d+/
227
+ path = File.join(tmp_upload_dir, filename)
228
+ FileUtils.rm path if Card.older_than_five_days? File.ctime(path)
229
+ end
230
+ end
231
+ end
232
+
233
+ def delete_files_for_action action
234
+ with_selected_action_id(action.id) do
235
+ FileUtils.rm attachment.file.path
236
+ attachment.versions.each_value do |version|
237
+ FileUtils.rm version.path
238
+ end
239
+ end
240
+ end
241
+
242
+ # create filesystem links to files from prior action
243
+ def symlink_to prior_action_id
244
+ return unless prior_action_id != last_action_id
245
+ save_action_id = selected_action_id
246
+ links = {}
247
+
248
+ self.selected_action_id = prior_action_id
249
+ attachment.versions.each do |name, version|
250
+ links[name] = version.store_path
251
+ end
252
+ original = attachment.store_path
253
+
254
+ self.selected_action_id = last_action_id
255
+ attachment.versions.each do |name, version|
256
+ ::File.symlink links[name], version.store_path
257
+ end
258
+ ::File.symlink original, attachment.store_path
259
+
260
+ self.selected_action_id = save_action_id
261
+ end
262
+
263
+ def attachment_format ext
264
+ if ext.present? && attachment && (original_ext = attachment.extension)
265
+ if ["file", original_ext].member? ext
266
+ original_ext
267
+ elsif (exts = MIME::Types[attachment.content_type])
268
+ if exts.find { |mt| mt.extensions.member? ext }
269
+ ext
270
+ else
271
+ exts[0].extensions[0]
272
+ end
273
+ end
274
+ end
275
+ rescue => e
276
+ Rails.logger.info "attachment_format issue: #{e.message}"
277
+ nil
278
+ end
279
+
280
+
281
+ # ~~ below autogenerated; above pulled from /Users/ethan/dev/wagn/gem/card/mod/carrierwave/set/abstract/attachment.rb ~~
282
+ end;end;end;end;