card 1.19.6 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (298) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +8 -7
  4. data/config/initializers/01_core_extensions/array.rb +4 -0
  5. data/config/initializers/01_core_extensions/persistent_identifiers.rb +12 -0
  6. data/config/initializers/02_patches/better_errors.rb +56 -0
  7. data/config/initializers/core_extensions.rb +13 -18
  8. data/config/initializers/patches.rb +8 -0
  9. data/config/locales/de.yml +0 -2
  10. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +22 -12
  11. data/db/migrate_core_cards/20161102202156_tweak_recaptcha_setting_cards.rb +17 -0
  12. data/db/migrate_core_cards/20161103154836_update_keys.rb +46 -0
  13. data/lib/card.rb +1 -8
  14. data/lib/card/act_manager.rb +4 -0
  15. data/lib/card/auth/permissions.rb +5 -3
  16. data/lib/card/cache.rb +1 -20
  17. data/lib/card/cache/persistent.rb +6 -0
  18. data/lib/card/content/chunk.rb +4 -3
  19. data/lib/card/content/diff.rb +2 -2
  20. data/lib/card/content/diff/result.rb +11 -0
  21. data/lib/card/env/success.rb +4 -0
  22. data/lib/card/error.rb +2 -0
  23. data/lib/card/format.rb +14 -17
  24. data/lib/card/format/content.rb +16 -8
  25. data/lib/card/format/error.rb +3 -5
  26. data/lib/card/format/names.rb +22 -16
  27. data/lib/card/format/nest.rb +67 -61
  28. data/lib/card/format/nest/fetch.rb +40 -33
  29. data/lib/card/format/nest/main.rb +39 -19
  30. data/lib/card/format/nest/subformat.rb +3 -16
  31. data/lib/card/format/nest/view.rb +23 -32
  32. data/lib/card/format/permission.rb +49 -34
  33. data/lib/card/format/registration.rb +12 -6
  34. data/lib/card/format/render.rb +62 -73
  35. data/lib/card/migration.rb +14 -10
  36. data/lib/card/migration/import.rb +20 -19
  37. data/lib/card/migration/import/import_data.rb +50 -59
  38. data/lib/card/migration/import/import_data/card_attributes.rb +56 -0
  39. data/lib/card/migration/import/import_data/card_content.rb +33 -0
  40. data/lib/card/migration/import/merger.rb +47 -0
  41. data/lib/card/mod/loader.rb +4 -4
  42. data/lib/card/model/save_helper.rb +49 -10
  43. data/lib/card/name.rb +16 -52
  44. data/lib/card/name/fields_and_traits.rb +67 -0
  45. data/lib/card/name/variants.rb +17 -0
  46. data/lib/card/query.rb +6 -2
  47. data/lib/card/query/attributes.rb +1 -1
  48. data/lib/card/query/interpretation.rb +3 -3
  49. data/lib/card/set/event.rb +2 -1
  50. data/lib/card/set/format.rb +18 -7
  51. data/lib/card/set_pattern.rb +17 -13
  52. data/lib/card/tasks/card.rake +1 -1
  53. data/lib/card/view.rb +55 -0
  54. data/lib/card/view/cache.rb +90 -0
  55. data/lib/card/view/fetch.rb +109 -0
  56. data/lib/card/view/options.rb +164 -0
  57. data/lib/card/view/stub.rb +30 -0
  58. data/lib/card/view/visibility.rb +95 -0
  59. data/lib/cardio.rb +3 -2
  60. data/lib/cardio/schema.rb +21 -8
  61. data/lib/generators/card.rb +16 -2
  62. data/lib/generators/card/format/format_generator.rb +10 -9
  63. data/lib/generators/card/migration/migration_generator.rb +10 -5
  64. data/lib/generators/card/set/USAGE +1 -1
  65. data/lib/generators/card/set/set_generator.rb +11 -9
  66. data/mod/account/set/right/account.rb +38 -40
  67. data/mod/account/set/right/token.rb +2 -1
  68. data/mod/account/set/self/account_links.rb +34 -54
  69. data/mod/account/set/self/signin.rb +107 -93
  70. data/mod/account/set/type/signup.rb +33 -32
  71. data/mod/account/set/type/user.rb +28 -21
  72. data/mod/account/spec/set/all/account_spec.rb +9 -9
  73. data/mod/account/spec/set/right/account_spec.rb +23 -14
  74. data/mod/account/spec/set/right/email_spec.rb +6 -6
  75. data/mod/account/spec/set/right/password_spec.rb +4 -4
  76. data/mod/account/spec/set/right/token_spec.rb +3 -3
  77. data/mod/account/spec/set/self/account_links_spec.rb +3 -3
  78. data/mod/account/spec/set/self/signin_spec.rb +2 -2
  79. data/mod/account/spec/set/type/signup_spec.rb +7 -8
  80. data/mod/ace_editor/set/abstract/ace_editor.rb +1 -4
  81. data/mod/admin/set/self/admin.rb +2 -2
  82. data/mod/admin/set/self/admin_info.rb +1 -1
  83. data/mod/admin/set/self/recaptcha_private_key.rb +3 -0
  84. data/mod/admin/set/self/recaptcha_proxy.rb +3 -0
  85. data/mod/admin/set/self/recaptcha_public_key.rb +3 -0
  86. data/mod/admin/set/self/trash.rb +4 -4
  87. data/mod/admin/spec/set/self/admin_spec.rb +4 -4
  88. data/mod/admin/spec/set/self/version_spec.rb +1 -1
  89. data/mod/basic_formats/set/all/all_css.rb +3 -3
  90. data/mod/basic_formats/set/all/all_csv.rb +6 -6
  91. data/mod/basic_formats/set/all/all_js.rb +4 -0
  92. data/mod/basic_formats/set/all/base.rb +40 -62
  93. data/mod/basic_formats/set/all/json.rb +34 -39
  94. data/mod/basic_formats/set/all/rss.rb +6 -6
  95. data/mod/basic_formats/set/all/text.rb +3 -2
  96. data/mod/basic_formats/set/self/01_head/javascript.rb +2 -2
  97. data/mod/basic_formats/set/self/head.rb +6 -10
  98. data/mod/basic_formats/spec/set/all/all_css_spec.rb +1 -1
  99. data/mod/basic_formats/spec/set/all/all_csv_spec.rb +1 -1
  100. data/mod/basic_formats/spec/set/all/base_spec.rb +8 -5
  101. data/mod/basic_formats/spec/set/all/json_spec.rb +2 -2
  102. data/mod/basic_formats/spec/set/all/rss_spec.rb +4 -4
  103. data/mod/basic_types/set/type/plain_text.rb +3 -5
  104. data/mod/basic_types/spec/set/type/plain_text_spec.rb +2 -2
  105. data/mod/bootstrap/lib/bootstrap.rb +16 -0
  106. data/mod/bootstrap/lib/bootstrap/basic_tags.rb +26 -0
  107. data/mod/bootstrap/lib/bootstrap/component.rb +133 -0
  108. data/mod/bootstrap/lib/bootstrap/component/form.rb +31 -0
  109. data/mod/bootstrap/lib/bootstrap/component/horizontal_form.rb +38 -0
  110. data/mod/bootstrap/lib/bootstrap/component/layout.rb +83 -0
  111. data/mod/bootstrap/lib/bootstrap/component/panel.rb +9 -0
  112. data/mod/bootstrap/lib/bootstrap/component_loader.rb +30 -0
  113. data/mod/bootstrap/lib/bootstrap/delegate.rb +16 -0
  114. data/mod/bootstrap/lib/bootstrapper.rb +16 -0
  115. data/mod/bootstrap/lib/stylesheets/bootstrap/_tables.scss +55 -52
  116. data/mod/bootstrap/lib/stylesheets/bootstrap/mixins/_table-row.scss +12 -12
  117. data/mod/bootstrap/lib/stylesheets/bootstrap_cards.scss +12 -0
  118. data/mod/bootstrap/set/all/bootstrap/accordion.rb +63 -0
  119. data/mod/bootstrap/set/all/bootstrap/helper.rb +7 -140
  120. data/mod/bootstrap/set/all/bootstrap/navbar.rb +74 -0
  121. data/mod/bootstrap/set/all/bootstrap/table.rb +76 -46
  122. data/mod/bootstrap/set/all/bootstrap/tabs.rb +58 -23
  123. data/mod/bootstrap/set/all/bootstrap/wrapper.rb +14 -8
  124. data/mod/bootstrap/set/all/rich_bootstrap.rb +5 -3
  125. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_builder_spec.rb +31 -0
  126. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_spec.rb +20 -0
  127. data/mod/bootstrap/spec/set/all/bootstrap/form_spec.rb +59 -1
  128. data/mod/bootstrap/spec/set/all/bootstrap/layout_spec.rb +104 -15
  129. data/mod/carrierwave/set/abstract/attachment.rb +4 -3
  130. data/mod/carrierwave/set/abstract/attachment/paths.rb +1 -1
  131. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +5 -11
  132. data/mod/carrierwave/set/type/file.rb +39 -32
  133. data/mod/carrierwave/set/type/image.rb +59 -34
  134. data/mod/carrierwave/spec/set/type/image_spec.rb +3 -3
  135. data/mod/core/chunk/link.rb +5 -0
  136. data/mod/core/chunk/{include.rb → nest.rb} +8 -29
  137. data/mod/core/chunk/reference.rb +5 -6
  138. data/mod/core/chunk/view_stub.rb +42 -0
  139. data/mod/core/format/html_format.rb +23 -26
  140. data/mod/core/set/abstract/code_file.rb +1 -1
  141. data/mod/core/set/all/actify.rb +1 -1
  142. data/mod/core/set/all/active_card.rb +0 -1
  143. data/mod/core/set/all/{tracked_attributes.rb → assign_attributes.rb} +55 -24
  144. data/mod/core/set/all/collection.rb +136 -122
  145. data/mod/core/set/all/content.rb +8 -0
  146. data/mod/core/set/all/event.rb +5 -2
  147. data/mod/core/set/all/export.rb +7 -7
  148. data/mod/core/set/all/fetch.rb +90 -26
  149. data/mod/core/set/all/initialize.rb +17 -6
  150. data/mod/core/set/all/name.rb +2 -3
  151. data/mod/core/set/all/permissions.rb +19 -11
  152. data/mod/core/set/all/states.rb +12 -2
  153. data/mod/core/set/all/trash.rb +1 -1
  154. data/mod/core/set/all/type.rb +2 -0
  155. data/mod/core/set/all/utils.rb +4 -3
  156. data/mod/core/spec/chunk/literal_spec.rb +2 -2
  157. data/mod/core/spec/chunk/uri_spec.rb +17 -17
  158. data/mod/core/spec/format/html_format_spec.rb +11 -13
  159. data/mod/core/spec/set/all/attribute_tracking_spec.rb +2 -2
  160. data/mod/core/spec/set/all/collection_spec.rb +21 -24
  161. data/mod/core/spec/set/all/content_spec.rb +1 -1
  162. data/mod/core/spec/set/all/export_spec.rb +3 -3
  163. data/mod/core/spec/set/all/fetch_spec.rb +5 -5
  164. data/mod/core/spec/set/all/initialize_spec.rb +4 -4
  165. data/mod/core/spec/set/all/name_spec.rb +6 -6
  166. data/mod/core/spec/set/all/permissions_spec.rb +10 -10
  167. data/mod/core/spec/set/all/references_spec.rb +1 -1
  168. data/mod/core/spec/set/all/rules2_spec.rb +24 -24
  169. data/mod/core/spec/set/all/rules_spec.rb +1 -1
  170. data/mod/core/spec/set/all/templating_spec.rb +8 -8
  171. data/mod/core/spec/set/all/tracked_attributes_spec.rb +6 -6
  172. data/mod/core/spec/set/all/type_spec.rb +5 -5
  173. data/mod/developer/spec/set/all/event_viz_spec.rb +1 -1
  174. data/mod/developer/spec/set/right/debug_spec.rb +1 -1
  175. data/mod/email/set/all/email_html.rb +2 -2
  176. data/mod/email/set/all/notify.rb +8 -3
  177. data/mod/email/set/right/bcc.rb +3 -3
  178. data/mod/email/set/right/follow.rb +5 -5
  179. data/mod/email/set/right/following.rb +1 -1
  180. data/mod/email/set/self/follow_defaults.rb +27 -16
  181. data/mod/email/set/type/email_template.rb +1 -1
  182. data/mod/email/set/type_plus_right/user/follow.rb +10 -9
  183. data/mod/history/lib/card/act.rb +4 -0
  184. data/mod/history/lib/card/act/act_renderer.rb +194 -0
  185. data/mod/history/lib/card/act/act_renderer/absolute_act_renderer.rb +25 -0
  186. data/mod/history/lib/card/act/act_renderer/relative_act_renderer.rb +41 -0
  187. data/mod/history/lib/card/action.rb +1 -0
  188. data/mod/history/lib/card/action/action_renderer.rb +92 -0
  189. data/mod/history/lib/card/action/differ.rb +6 -1
  190. data/mod/history/set/all/act_view.rb +64 -0
  191. data/mod/history/set/all/action_view.rb +65 -0
  192. data/mod/history/set/all/content_history.rb +44 -37
  193. data/mod/history/set/all/history.rb +49 -263
  194. data/mod/machines/lib/stylesheets/style_cards.scss +30 -115
  195. data/mod/machines/set/abstract/script.rb +42 -7
  196. data/mod/machines/set/right/machine_input.rb +4 -0
  197. data/mod/machines/set/type/coffee_script.rb +8 -22
  198. data/mod/machines/set/type/css.rb +2 -2
  199. data/mod/machines/set/type/java_script.rb +4 -24
  200. data/mod/machines/set/type/scss.rb +1 -1
  201. data/mod/machines/spec/set/type/css_spec.rb +1 -1
  202. data/mod/machines/spec/set/type/scss_spec.rb +3 -3
  203. data/mod/machines/spec/set/type/skin_spec.rb +7 -7
  204. data/mod/pointer/set/abstract/01_pointer.rb +44 -46
  205. data/mod/pointer/set/abstract/01_pointer/edit.rb +13 -13
  206. data/mod/pointer/set/right/options.rb +4 -0
  207. data/mod/pointer/spec/set/type/pointer_spec.rb +7 -7
  208. data/mod/prosemirror_editor/set/abstract/prosemirror_editor.rb +3 -3
  209. data/mod/settings/set/abstract/permission.rb +25 -18
  210. data/mod/settings/set/right/add_help.rb +3 -3
  211. data/mod/settings/set/right/structure.rb +10 -16
  212. data/mod/settings/spec/set/right/comment_spec.rb +3 -3
  213. data/mod/settings/spec/set/right/create_spec.rb +1 -1
  214. data/mod/settings/spec/set/right/style_spec.rb +1 -1
  215. data/mod/settings/spec/set/type/setting_spec.rb +1 -1
  216. data/mod/solid_cache/set/abstract/solid_cache.rb +4 -4
  217. data/mod/solid_cache/set/right/solid_cache.rb +9 -10
  218. data/mod/standard/set/abstract/01_search_params.rb +41 -0
  219. data/mod/standard/set/abstract/search.rb +132 -0
  220. data/mod/standard/set/abstract/search/paging.rb +81 -0
  221. data/mod/standard/set/abstract/search/paging/paging_links.rb +90 -0
  222. data/mod/standard/set/abstract/wql_search.rb +67 -0
  223. data/mod/standard/set/all/error.rb +89 -82
  224. data/mod/standard/set/all/links.rb +1 -1
  225. data/mod/standard/set/all/rich_html/content.rb +125 -141
  226. data/mod/standard/set/all/rich_html/editing.rb +115 -178
  227. data/mod/standard/set/all/rich_html/form.rb +111 -131
  228. data/mod/standard/set/all/rich_html/header.rb +57 -39
  229. data/mod/standard/set/all/rich_html/menu.rb +94 -94
  230. data/mod/standard/set/all/rich_html/modal.rb +5 -10
  231. data/mod/standard/set/all/rich_html/new.rb +103 -0
  232. data/mod/standard/set/all/rich_html/toolbar.rb +54 -74
  233. data/mod/standard/set/all/rich_html/wrapper.rb +111 -138
  234. data/mod/standard/set/rstar/rules.rb +27 -38
  235. data/mod/standard/set/rstar/rules_editor.rb +298 -277
  236. data/mod/standard/set/self/navbox.rb +20 -15
  237. data/mod/standard/set/self/recent.rb +25 -17
  238. data/mod/standard/set/self/search.rb +25 -4
  239. data/mod/standard/set/type/cardtype.rb +11 -9
  240. data/mod/standard/set/type/date.rb +1 -1
  241. data/mod/standard/set/type/number.rb +1 -1
  242. data/mod/standard/set/type/phrase.rb +1 -1
  243. data/mod/standard/set/type/search_type.rb +17 -282
  244. data/mod/standard/set/type/session.rb +1 -1
  245. data/mod/standard/set/type/set.rb +155 -131
  246. data/mod/standard/set/type/toggle.rb +1 -1
  247. data/mod/standard/set/type/uri.rb +4 -4
  248. data/mod/standard/spec/chunk/include_spec.rb +13 -31
  249. data/mod/standard/spec/chunk/link_spec.rb +1 -1
  250. data/mod/standard/spec/set/all/error_spec.rb +1 -1
  251. data/mod/standard/spec/set/all/history_spec.rb +2 -2
  252. data/mod/standard/spec/set/all/rich_html/form_spec.rb +4 -4
  253. data/mod/standard/spec/set/all/rich_html/toolbar_spec.rb +22 -0
  254. data/mod/standard/spec/set/all/rich_html/wrapper_spec.rb +3 -2
  255. data/mod/standard/spec/set/right/when_created_spec.rb +1 -1
  256. data/mod/standard/spec/set/right/when_last_edited_spec.rb +1 -1
  257. data/mod/standard/spec/set/rstar/rules_spec.rb +2 -3
  258. data/mod/standard/spec/set/self/head_spec.rb +2 -2
  259. data/mod/standard/spec/set/self/navbox_spec.rb +1 -1
  260. data/mod/standard/spec/set/self/now_spec.rb +1 -1
  261. data/mod/standard/spec/set/type/date_spec.rb +1 -1
  262. data/mod/standard/spec/set/type/email_template_spec.rb +1 -1
  263. data/mod/standard/spec/set/type/layout_type_spec.rb +1 -1
  264. data/mod/standard/spec/set/type/number_spec.rb +1 -1
  265. data/mod/standard/spec/set/type/phrase_spec.rb +1 -1
  266. data/mod/standard/spec/set/type/search_type_spec.rb +2 -2
  267. data/mod/standard/spec/set/type/set_spec.rb +2 -2
  268. data/mod/standard/spec/set/type/toggle_spec.rb +2 -2
  269. data/mod/standard/spec/set/type/uri_spec.rb +3 -1
  270. data/mod/tinymce_editor/set/abstract/tinymce_editor.rb +1 -1
  271. data/spec/config/initializers/core_extensions_spec.rb +40 -10
  272. data/spec/lib/card/auth_spec.rb +8 -8
  273. data/spec/lib/card/cache_spec.rb +3 -3
  274. data/spec/lib/card/chunk_spec.rb +4 -4
  275. data/spec/lib/card/codename_spec.rb +2 -2
  276. data/spec/lib/card/content_spec.rb +23 -23
  277. data/spec/lib/card/diff_spec.rb +1 -1
  278. data/spec/lib/card/format_spec.rb +19 -24
  279. data/spec/lib/card/loader_spec.rb +4 -4
  280. data/spec/lib/card/name_spec.rb +16 -16
  281. data/spec/lib/card/query_spec.rb +80 -80
  282. data/spec/lib/card/reference_spec.rb +5 -5
  283. data/spec/lib/card/set_spec.rb +6 -6
  284. data/spec/lib/card/subcards_spec.rb +14 -0
  285. data/spec/lib/card/view_cache_spec.rb +5 -5
  286. data/spec/models/card/cardtype_spec.rb +15 -15
  287. data/spec/models/card/create_spec.rb +2 -2
  288. data/spec/models/card/trash_spec.rb +24 -24
  289. data/spec/models/card/type_transition_spec.rb +8 -8
  290. data/spec/models/card/validation_spec.rb +5 -5
  291. data/spec/models/card_spec.rb +14 -14
  292. data/spec/spec_helper.rb +6 -2
  293. data/spec/support/card_spec_helper.rb +21 -11
  294. data/spec/support/helper/card_helper.rb +11 -4
  295. metadata +73 -15
  296. data/lib/card/cache/view_cache.rb +0 -103
  297. data/mod/bootstrap/set/all/bootstrap/layout.rb +0 -58
  298. data/mod/core/set/all/view_cache.rb +0 -9
@@ -39,15 +39,10 @@ class Card::Migration < ActiveRecord::Migration
39
39
  end
40
40
 
41
41
  def schema_mode mig_type=type
42
- new_suffix = schema_suffix mig_type
43
- original_suffix = ActiveRecord::Base.table_name_suffix
44
-
45
- ActiveRecord::Base.table_name_suffix = new_suffix
46
- ActiveRecord::SchemaMigration.reset_table_name
47
- paths = Cardio.migration_paths(type)
48
- yield(paths)
49
- ActiveRecord::Base.table_name_suffix = original_suffix
50
- ActiveRecord::SchemaMigration.reset_table_name
42
+ Cardio.with_suffix mig_type do
43
+ paths = Cardio.migration_paths(type)
44
+ yield(paths)
45
+ end
51
46
  end
52
47
 
53
48
  def assume_migrated_upto_version
@@ -99,10 +94,19 @@ class Card::Migration < ActiveRecord::Migration
99
94
  Card.merge_list full_data, merge_opts
100
95
  end
101
96
 
97
+ # uses the data in cards.yml and the card content in db/migrate_cards/data/cards
98
+ # to update or create the cards given by name or key in names_or_keys
99
+ def merge_cards names_or_keys
100
+ names_or_keys = Array(names_or_keys)
101
+ Card::Mailer.perform_deliveries = false
102
+
103
+ Card::Migration::Import.merge only: names_or_keys
104
+ end
105
+
102
106
  def read_json filename
103
107
  raw_json = File.read data_path(filename)
104
108
  json = JSON.parse raw_json
105
- json["card"]["value"]
109
+ json.is_a?(Hash) ? json["card"]["value"] : json
106
110
  end
107
111
 
108
112
  def data_path filename=nil
@@ -1,4 +1,5 @@
1
1
  require "import_data"
2
+ require "merger"
2
3
 
3
4
  class Card
4
5
  class Migration
@@ -14,25 +15,16 @@ class Card
14
15
  # To update other attributes change them in the yml file and either remove
15
16
  # the 'merged' value or touch the corresponding content file
16
17
  class Import
17
- OUTPUT_FILE = Card::Migration.data_path "unmerged"
18
18
  class << self
19
- # Merge the import data into the cards table
20
- # If 'all' is true all import data is merged.
21
- # Otherwise only the data that was changed or added since the last merge
22
- def merge all=false
23
- merge_data = all ? ImportData.all_cards : ImportData.changed_cards
24
- puts("nothing to merge") && return if merge_data.empty?
25
-
26
- Card::Mailer.perform_deliveries = false
27
- Card::Auth.as_bot do
28
- Card.merge_list merge_data, output_file: OUTPUT_FILE
29
- end
30
- update_time = Time.zone.now.to_s
31
- ImportData.update do |import_data|
32
- merge_data.each do |card_data|
33
- import_data.merged card_data, update_time
34
- end
35
- end
19
+ # Merge the import data into the cards table.
20
+ # Bu default it merges only the data that was changed or added
21
+ # since the last merge.
22
+ # @param [Hash] opts choose which cards to merge
23
+ # @option opts [Boolean] :all merge all available import data
24
+ # @option opts [Array] :only a key/name or list of keys/names to
25
+ # be merged
26
+ def merge opts={}
27
+ Merger.new(opts).merge
36
28
  end
37
29
 
38
30
  # Get import data from a deck
@@ -91,7 +83,7 @@ class Card
91
83
  json_url = "#{url}/#{name}.json"
92
84
  json_url += "?view=#{view}" if view
93
85
  json = open(json_url).read
94
- JSON.parse(json).deep_symbolize_keys
86
+ parse_and_symbolize json
95
87
  end
96
88
 
97
89
  def fetch_local_data name, view
@@ -99,6 +91,15 @@ class Card
99
91
  Card[name].format(format: :json).render(view || :content)
100
92
  end
101
93
  end
94
+
95
+ def parse_and_symbolize json
96
+ parsed = JSON.parse(json)
97
+ case parsed
98
+ when Hash then parsed.deep_symbolize_keys
99
+ when Array then parsed.map(&:deep_symbolize_keys)
100
+ else parsed
101
+ end
102
+ end
102
103
  end
103
104
  end
104
105
  end
@@ -4,13 +4,18 @@ class Card
4
4
  # Handles the card attributes and remotes for the import
5
5
  class ImportData
6
6
  DEFAULT_PATH = Card::Migration.data_path("cards.yml").freeze
7
- CARD_CONTENT_DIR = Card::Migration.data_path("cards").freeze
7
+
8
+ include CardContent
9
+ include CardAttributes
8
10
 
9
11
  class << self
12
+ # Takes a block to update import data
13
+ # use #add_card and #add_remote in the block to make
14
+ # changes
10
15
  def update
11
16
  data = ImportData.new
12
17
  yield(data)
13
- data.write
18
+ data.write_attributes
14
19
  end
15
20
 
16
21
  def all_cards
@@ -20,18 +25,28 @@ class Card
20
25
  def changed_cards
21
26
  ImportData.new.changed_cards
22
27
  end
28
+
29
+ def select_cards names_or_keys
30
+ ImportData.new.select_cards Array(names_or_keys)
31
+ end
23
32
  end
24
33
 
25
34
  def initialize path=nil
26
35
  @path = path || DEFAULT_PATH
27
- ensure_path
28
- @data = read
36
+ @data = read_attributes
29
37
  end
30
38
 
31
39
  def all_cards
32
40
  cards.map { |data| prepare_for_import data }
33
41
  end
34
42
 
43
+ def select_cards names_or_keys
44
+ cards.map do |attributes|
45
+ next unless name_or_key_match attributes, names_or_keys
46
+ prepare_for_import attributes
47
+ end.compact
48
+ end
49
+
35
50
  def changed_cards
36
51
  cards.map do |data|
37
52
  next unless changed?(data)
@@ -44,48 +59,45 @@ class Card
44
59
  update_attribute data["name"], :merged, time
45
60
  end
46
61
 
47
- def add_card new_attr
48
- card_data = {}
49
- [:name, :type, :codename].each do |key|
50
- card_data[key] = new_attr[key] if new_attr[key]
51
- end
52
- card_data[:key] = new_attr[:name].to_name.key
53
- card_entry = find_card card_data[:name]
62
+ # to be used in an update block
63
+ def add_card card_data
64
+ card_attr, card_content = split_attributes_and_content card_data
54
65
 
55
- if card_entry
56
- card_entry.replace card_data
57
- else
58
- cards << card_data
59
- end
60
- write_card_content card_data, new_attr[:content]
61
- card_data
66
+ update_card_attributes card_attr
67
+ write_card_content card_attr, card_content
68
+ card_attr
62
69
  end
63
70
 
71
+ # to be used in an update block
64
72
  def add_remote name, url
65
- @data[:remotes][name] = url
73
+ remotes[name] = url
66
74
  end
67
75
 
68
76
  def url remote_name
69
- @data[:remotes][remote_name.to_sym] ||
77
+ remotes[remote_name.to_sym] ||
70
78
  raise("unknown remote: #{remote_name}")
71
79
  end
72
80
 
73
- def read
74
- return { cards: [], remotes: {} } unless File.exist? @path
75
- YAML.load_file(@path).deep_symbolize_keys
76
- end
81
+ private
77
82
 
78
- def write
79
- File.write @path, @data.to_yaml
83
+ def split_attributes_and_content data
84
+ card_data = {}
85
+ [:name, :type, :codename].each do |key|
86
+ card_data[key] = data[key] if data[key]
87
+ end
88
+ card_data[:key] = data[:name].to_name.key
89
+ [card_data, data[:content]]
80
90
  end
81
91
 
82
- private
92
+ def name_or_key_match attributes, names_or_keys
93
+ names_or_keys.any? do |nk|
94
+ nk == attributes[:name] || nk == attributes[:name].to_name.key ||
95
+ nk == attributes[:key]
96
+ end
97
+ end
83
98
 
84
- def update_attribute name, attr_key, attr_value
85
- card = find_card name
86
- return unless card
87
- card[attr_key] = attr_value
88
- card
99
+ def remotes
100
+ @data[:remotes]
89
101
  end
90
102
 
91
103
  def cards
@@ -93,41 +105,20 @@ class Card
93
105
  end
94
106
 
95
107
  def prepare_for_import data
96
- card_attr = ::Set.new [:name, :type, :codename, :file, :image]
97
- hash = data.select { |k, v| v && card_attr.include?(k) }
98
- hash[:content] = File.read(content_path(data))
108
+ hash = card_attributes(data)
109
+ hash[:content] = card_content(data)
99
110
  [:file, :image].each do |attach|
100
- hash[attach] &&= Card::Migration.data_path "files/#{hash[attach]}"
111
+ hash[attach] &&= card_attachment(attach, data)
101
112
  end
102
113
  hash.with_indifferent_access
103
114
  end
104
115
 
105
116
  def changed? data
106
- !data[:merged] ||
107
- Time.parse(data[:merged]) < File.mtime(content_path(data))
108
- end
109
-
110
- def write_card_content data, content
111
- FileUtils.mkpath CARD_CONTENT_DIR unless Dir.exist? CARD_CONTENT_DIR
112
- File.write content_path(data), content.to_s
113
- end
114
-
115
- def content_path data
116
- filename = data[:key] || data[:name].to_name.key
117
- File.join CARD_CONTENT_DIR, filename
118
- end
119
-
120
- def find_card name
121
- key = name.to_name.key
122
- index = cards.find_index { |attr| attr[:key] == key } ||
123
- cards.find_index { |attr| attr[:name] == name }
124
- return unless index
125
- cards[index]
117
+ !data[:merged] || content_changed?(data)
126
118
  end
127
119
 
128
- def ensure_path
129
- dir = File.dirname(@path)
130
- FileUtils.mkpath dir unless Dir.exist? dir
120
+ def card_attachment attach_type, data
121
+ Card::Migration.data_path "files/#{data[attach_type]}"
131
122
  end
132
123
  end
133
124
  end
@@ -0,0 +1,56 @@
1
+ class Card
2
+ class Migration
3
+ class Import
4
+ class ImportData
5
+ # handles card attributes for import
6
+ module CardAttributes
7
+ def card_attributes data
8
+ card_attr = ::Set.new [:name, :type, :codename, :file, :image]
9
+ data.select { |k, v| v && card_attr.include?(k) }
10
+ end
11
+
12
+ def update_card_attributes card_data
13
+ card_entry = find_card_attributes card_data[:name]
14
+ if card_entry
15
+ card_entry.replace card_data
16
+ else
17
+ cards << card_data
18
+ end
19
+ end
20
+
21
+ def update_attribute name, attr_key, attr_value
22
+ card = find_card_attributes name
23
+ return unless card
24
+ card[attr_key] = attr_value
25
+ card
26
+ end
27
+
28
+ def write_attributes
29
+ File.write @path, @data.to_yaml
30
+ end
31
+
32
+ def read_attributes
33
+ ensure_path
34
+ return { cards: [], remotes: {} } unless File.exist? @path
35
+ YAML.load_file(@path).deep_symbolize_keys
36
+ end
37
+
38
+ def find_card_attributes name
39
+ key = name.to_name.key
40
+ index = cards.find_index { |attr| attr[:key] == key } ||
41
+ cards.find_index { |attr| attr[:name] == name }
42
+ return unless index
43
+ cards[index]
44
+ end
45
+
46
+ private
47
+
48
+ def ensure_path
49
+ dir = File.dirname(@path)
50
+ FileUtils.mkpath dir unless Dir.exist? dir
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,33 @@
1
+ class Card
2
+ class Migration
3
+ class Import
4
+ class ImportData
5
+ # handles card content for import
6
+ module CardContent
7
+ CARD_CONTENT_DIR = Card::Migration.data_path("cards").freeze
8
+
9
+ def card_content data
10
+ File.read(content_path(data))
11
+ end
12
+
13
+ def content_changed? data
14
+ Time.parse(data[:merged]) < File.mtime(content_path(data))
15
+ end
16
+
17
+ private
18
+
19
+ def write_card_content data, content
20
+ FileUtils.mkpath CARD_CONTENT_DIR unless Dir.exist? CARD_CONTENT_DIR
21
+ File.write content_path(data), content.to_s
22
+ end
23
+
24
+ def content_path data
25
+ filename = data[:key] || data[:name].to_name.key
26
+ File.join CARD_CONTENT_DIR, filename
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,47 @@
1
+ class Card
2
+ class Migration
3
+ class Import
4
+ # executes the card import
5
+ class Merger
6
+ OUTPUT_FILE = Card::Migration.data_path "unmerged"
7
+
8
+ def initialize opts={}
9
+ load_data opts
10
+ end
11
+
12
+ def merge
13
+ puts("nothing to merge") && return if @data.empty?
14
+
15
+ Card::Mailer.perform_deliveries = false
16
+ Card::Auth.as_bot do
17
+ Card.merge_list @data, output_file: OUTPUT_FILE
18
+ end
19
+
20
+ update_import_data
21
+ end
22
+
23
+ private
24
+
25
+ def load_data opts
26
+ @data =
27
+ if opts[:all]
28
+ ImportData.all_cards
29
+ elsif opts[:only]
30
+ ImportData.select_cards opts[:only]
31
+ else
32
+ ImportData.changed_cards
33
+ end
34
+ end
35
+
36
+ def update_import_data
37
+ update_time = Time.zone.now.to_s
38
+ ImportData.update do |import_data|
39
+ @data.each do |card_data|
40
+ import_data.merged card_data, update_time
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -155,11 +155,11 @@ class Card
155
155
  end
156
156
 
157
157
  def rewrite_tmp_files?
158
- if defined?(@@rewrite)
159
- @@rewrite
158
+ if defined?(@rewrite)
159
+ @rewrite
160
160
  else
161
- @@rewrite = !(Rails.env.production? &&
162
- Card.paths["tmp/set"].existent.first)
161
+ @rewrite = !(Rails.env.production? &&
162
+ Card.paths["tmp/set"].existent.first)
163
163
  end
164
164
  end
165
165
 
@@ -16,16 +16,19 @@ class Card
16
16
  end
17
17
 
18
18
  def update_card name, content_or_args
19
- args = standardize_update_args content_or_args
19
+ args = standardize_update_args name, content_or_args
20
20
  resolve_name_conflict args
21
21
  Card[name].update_attributes! args
22
22
  end
23
23
 
24
24
  def create_or_update_card name_or_args, content_or_args=nil
25
- args = standardize_args name_or_args, content_or_args
26
- if Card[args[:name]]
27
- update_card(args.delete(:name), args)
25
+ name = name_from_args name_or_args
26
+
27
+ if Card[name]
28
+ args = standardize_update_args name_or_args, content_or_args
29
+ update_card(name, args)
28
30
  else
31
+ args = standardize_args name_or_args, content_or_args
29
32
  create_card(args)
30
33
  end
31
34
  end
@@ -43,13 +46,16 @@ class Card
43
46
  # create if card doesn't exist
44
47
  # updates existing card only if given attributes are different except the
45
48
  # name
46
- # For example if a card with name "under_score" exists
47
- # then `ensure_card "Under Score"` doesn't change anything
49
+ # @example if a card with name "under_score" exists
50
+ # ensure_card "Under Score" # => no change
51
+ # ensure_card "Under Score", type: :pointer # => changes the type to pointer
52
+ # # but not the name
48
53
  def ensure_card name_or_args, content_or_args=nil
49
54
  args = standardize_args name_or_args, content_or_args
50
55
  name = args.delete(:name)
51
56
  if (card = Card[name])
52
57
  ensure_attributes card, args
58
+ card
53
59
  else
54
60
  Card.create! args.merge(name: name)
55
61
  end
@@ -76,7 +82,7 @@ class Card
76
82
  end
77
83
 
78
84
  def update_card! name, content_or_args
79
- args = standardize_update_args content_or_args
85
+ args = standardize_update_args name, content_or_args
80
86
  update_card name, args.reverse_merge(rename_if_conflict: :new)
81
87
  end
82
88
 
@@ -94,7 +100,8 @@ class Card
94
100
  end
95
101
  end
96
102
 
97
- def standardize_update_args content_or_args
103
+ def standardize_update_args name_or_args, content_or_args
104
+ return name_or_args if name_or_args.is_a?(Hash)
98
105
  if content_or_args.is_a?(String)
99
106
  { content: content_or_args }
100
107
  else
@@ -102,17 +109,21 @@ class Card
102
109
  end
103
110
  end
104
111
 
112
+ def name_from_args name_or_args
113
+ name_or_args.is_a?(Hash) ? name_or_args[:name] : name_or_args
114
+ end
115
+
105
116
  def add_name name, content_or_args
106
117
  if content_or_args.is_a?(String)
107
118
  { content: content_or_args, name: name }
108
119
  else
109
- content_or_args.merge name: name
120
+ content_or_args.reverse_merge name: name
110
121
  end
111
122
  end
112
123
 
113
124
  def resolve_name_conflict args
114
125
  rename = args.delete :rename_if_conflict
115
- return unless rename
126
+ return unless args[:name] && rename
116
127
  args[:name] = Card.uniquify_name args[:name], rename
117
128
  end
118
129
 
@@ -122,6 +133,34 @@ class Card
122
133
  card.update_attributes! update_args
123
134
  end
124
135
 
136
+ def add_style name, opts={}
137
+ name.sub!(/^style\:?\s?/, '') # in case name is given with prefix
138
+ # remove it so that we don't double it
139
+
140
+ add_coderule_item name, "style",
141
+ opts[:type_id] || Card::ScssID,
142
+ opts[:to] || "*all+*style"
143
+ end
144
+
145
+ def add_script name, opts={}
146
+ name.sub!(/^script\:?\s?/, '') # in case name is given with prefix
147
+ # remove it so that we don't double it
148
+
149
+ add_coderule_item name, "script",
150
+ opts[:type_id] || Card::CoffeeScriptID,
151
+ opts[:to] || "*all+*script"
152
+ end
153
+
154
+
155
+ def add_coderule_item name, prefix, type_id, to
156
+ codename = "#{prefix}_#{name.tr(' ', '_').underscore}"
157
+ name = "#{prefix}: #{name}"
158
+
159
+ ensure_card name, type_id: type_id,
160
+ codename: codename
161
+ Card[to].add_item! name
162
+ end
163
+
125
164
  alias_method :create, :create_card
126
165
  alias_method :update, :update_card
127
166
  alias_method :create_or_update, :create_or_update_card