answers-core 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +6 -0
  3. data/answers-core.gemspec +30 -0
  4. data/app/assets/fonts/answers/League_Gothic-webfont.eot +0 -0
  5. data/app/assets/fonts/answers/League_Gothic-webfont.svg +230 -0
  6. data/app/assets/fonts/answers/League_Gothic-webfont.ttf +0 -0
  7. data/app/assets/fonts/answers/League_Gothic-webfont.woff +0 -0
  8. data/app/assets/images/OaklandCityTree.png +0 -0
  9. data/app/assets/images/background_image.jpg +0 -0
  10. data/app/assets/images/background_pattern.png +0 -0
  11. data/app/assets/images/beta.png +0 -0
  12. data/app/assets/images/bg_transparent.png +0 -0
  13. data/app/assets/images/border.png +0 -0
  14. data/app/assets/images/brigade.png +0 -0
  15. data/app/assets/images/cfa.png +0 -0
  16. data/app/assets/images/cfa_logo.png +0 -0
  17. data/app/assets/images/cfa_logo_footer.png +0 -0
  18. data/app/assets/images/favicon.ico +0 -0
  19. data/app/assets/images/forest.jpeg +0 -0
  20. data/app/assets/images/getting_started_btn.png +0 -0
  21. data/app/assets/images/govuk.png +0 -0
  22. data/app/assets/images/openoaklandlogo.png +0 -0
  23. data/app/assets/images/quick_answers_icon.png +0 -0
  24. data/app/assets/images/quick_answers_icon_small.png +0 -0
  25. data/app/assets/images/searchIcon.png +0 -0
  26. data/app/assets/images/wmd-buttons.png +0 -0
  27. data/app/assets/images/yellow_bg.png +0 -0
  28. data/app/assets/javascripts/answers.js +19 -0
  29. data/app/assets/javascripts/answers/Markdown.Extra.js +304 -0
  30. data/app/assets/javascripts/answers/active_admin.js +62 -0
  31. data/app/assets/javascripts/answers/pagedown/LICENSE.txt +32 -0
  32. data/app/assets/javascripts/answers/pagedown/Markdown.Converter.js +1332 -0
  33. data/app/assets/javascripts/answers/pagedown/Markdown.Editor.js +2212 -0
  34. data/app/assets/javascripts/answers/pagedown/Markdown.Sanitizer.js +108 -0
  35. data/app/assets/javascripts/answers/pagedown/README.txt +0 -0
  36. data/app/assets/javascripts/answers/pagedown/demo/browser/demo.css +120 -0
  37. data/app/assets/javascripts/answers/pagedown/demo/browser/demo.html +83 -0
  38. data/app/assets/javascripts/answers/pagedown/demo/node/demo.js +44 -0
  39. data/app/assets/javascripts/answers/pagedown/local/Markdown.local.fr.js +43 -0
  40. data/app/assets/javascripts/answers/pagedown/node-pagedown.js +2 -0
  41. data/app/assets/javascripts/answers/pagedown/package.json +12 -0
  42. data/app/assets/javascripts/answers/pagedown/resources/wmd-buttons.psd +0 -0
  43. data/app/assets/javascripts/answers/pagedown/wmd-buttons.png +0 -0
  44. data/app/assets/javascripts/answers/skip_nav.js +8 -0
  45. data/app/assets/stylesheets/answers/active_admin.css.scss +17 -0
  46. data/app/assets/stylesheets/answers/active_admin_custom.css.scss +35 -0
  47. data/app/assets/stylesheets/answers/formatting.css +82 -0
  48. data/app/assets/stylesheets/answers/mobile.css +149 -0
  49. data/app/assets/stylesheets/answers/tags.css.scss +3 -0
  50. data/app/assets/stylesheets/answers/theme.css +916 -0
  51. data/app/controllers/answers/answers_controller.rb +26 -0
  52. data/app/controllers/answers/api/v1/answers_controller.rb +38 -0
  53. data/app/controllers/answers/api/v1/api_controller.rb +13 -0
  54. data/app/controllers/answers/api/v1/questions_controller.rb +39 -0
  55. data/app/controllers/answers/api/v1/taggings_controller.rb +46 -0
  56. data/app/controllers/answers/api/v1/tags_controller.rb +38 -0
  57. data/app/controllers/answers/application_controller.rb +27 -0
  58. data/app/controllers/answers/home_controller.rb +17 -0
  59. data/app/controllers/answers/questions_controller.rb +33 -0
  60. data/app/controllers/answers/search_controller.rb +22 -0
  61. data/app/controllers/answers/tags_controller.rb +36 -0
  62. data/app/helpers/answers/tags_helper.rb +7 -0
  63. data/app/models/.gitkeep +0 -0
  64. data/app/models/answers/ability.rb +28 -0
  65. data/app/models/answers/administrator.rb +5 -0
  66. data/app/models/answers/answer.rb +6 -0
  67. data/app/models/answers/api/v1/api_user.rb +5 -0
  68. data/app/models/answers/question.rb +31 -0
  69. data/app/models/answers/user.rb +30 -0
  70. data/app/views/answers/admin/contacts/_article.html.erb +0 -0
  71. data/app/views/answers/admin/dashboard/_dashboard.html.erb +5 -0
  72. data/app/views/answers/admin/guide_steps/_form.html.erb +17 -0
  73. data/app/views/answers/api/v1/answers/_answer.json.jbuilder +2 -0
  74. data/app/views/answers/api/v1/answers/index.json.jbuilder +1 -0
  75. data/app/views/answers/api/v1/answers/show.json.jbuilder +1 -0
  76. data/app/views/answers/api/v1/questions/_question.json.jbuilder +2 -0
  77. data/app/views/answers/api/v1/questions/index.json.jbuilder +1 -0
  78. data/app/views/answers/api/v1/questions/show.json.jbuilder +1 -0
  79. data/app/views/answers/api/v1/taggings/_tagging.json.jbuilder +3 -0
  80. data/app/views/answers/api/v1/taggings/index.json.jbuilder +1 -0
  81. data/app/views/answers/api/v1/taggings/show.json.jbuilder +1 -0
  82. data/app/views/answers/api/v1/tags/_tag.json.jbuilder +2 -0
  83. data/app/views/answers/api/v1/tags/index.json.jbuilder +1 -0
  84. data/app/views/answers/api/v1/tags/show.json.jbuilder +1 -0
  85. data/app/views/answers/devise/confirmations/new.html.erb +12 -0
  86. data/app/views/answers/devise/mailer/confirmation_instructions.html.erb +5 -0
  87. data/app/views/answers/devise/mailer/reset_password_instructions.html.erb +8 -0
  88. data/app/views/answers/devise/mailer/unlock_instructions.html.erb +7 -0
  89. data/app/views/answers/devise/passwords/edit.html.erb +24 -0
  90. data/app/views/answers/devise/passwords/new.html.erb +20 -0
  91. data/app/views/answers/devise/registrations/edit.html.erb +25 -0
  92. data/app/views/answers/devise/registrations/new.html.erb +18 -0
  93. data/app/views/answers/devise/sessions/new.html.erb +25 -0
  94. data/app/views/answers/devise/shared/_links.erb +25 -0
  95. data/app/views/answers/devise/unlocks/new.html.erb +12 -0
  96. data/app/views/answers/home/_article.html.erb +3 -0
  97. data/app/views/answers/home/_category.html.erb +8 -0
  98. data/app/views/answers/home/about.html.erb +72 -0
  99. data/app/views/answers/home/index.html.erb +44 -0
  100. data/app/views/answers/questions/index.html.erb +21 -0
  101. data/app/views/answers/questions/show.html.erb +31 -0
  102. data/app/views/answers/search/index.html.erb +32 -0
  103. data/app/views/answers/shared/_articles_sidebar.html.erb +22 -0
  104. data/app/views/answers/shared/_autocomplete.html.erb +8 -0
  105. data/app/views/answers/shared/_categories_sidebar.html.erb +12 -0
  106. data/app/views/answers/shared/_search_form.html.erb +4 -0
  107. data/app/views/answers/shared/admin/_administration.html.erb +38 -0
  108. data/app/views/answers/shared/admin/_article_actions.html.erb +86 -0
  109. data/app/views/answers/shared/admin/_article_content.html.erb +27 -0
  110. data/app/views/answers/shared/admin/_article_details.html.erb +11 -0
  111. data/app/views/answers/shared/admin/_article_form.html.erb +20 -0
  112. data/app/views/answers/shared/admin/_author_pic.html.erb +0 -0
  113. data/app/views/answers/tags/index.html.erb +34 -0
  114. data/app/views/answers/tags/show.html.erb +31 -0
  115. data/app/views/layouts/answers/application.html.erb +97 -0
  116. data/config.ru +5 -0
  117. data/config/initializers/active_admin.rb +245 -0
  118. data/config/initializers/devise.rb +228 -0
  119. data/config/locales/devise.en.yml +57 -0
  120. data/config/locales/en.yml +129 -0
  121. data/config/routes.rb +22 -0
  122. data/config/secrets.yml +68 -0
  123. data/db/migrate/20140911060606_answers_up.rb +79 -0
  124. data/lib/answers-core.rb +1 -0
  125. data/lib/answers.rb +175 -0
  126. data/lib/answers/admin/answer.rb +29 -0
  127. data/lib/answers/admin/dashboard.rb +75 -0
  128. data/lib/answers/admin/question.rb +57 -0
  129. data/lib/answers/admin/tag.rb +12 -0
  130. data/lib/answers/admin/users.rb +65 -0
  131. data/lib/answers/core.rb +25 -0
  132. data/lib/answers/core/configuration.rb +90 -0
  133. data/lib/answers/core/engine.rb +116 -0
  134. data/lib/answers/engine.rb +62 -0
  135. data/lib/answers/errors.rb +13 -0
  136. data/lib/answers/plugin.rb +75 -0
  137. data/lib/answers/plugins.rb +73 -0
  138. data/lib/answers/version.rb +16 -0
  139. data/lib/api_client.rb +20 -0
  140. data/lib/assets/.gitkeep +0 -0
  141. data/lib/assets/eng_stop.csv +1 -0
  142. data/lib/generators/answers/clash_keywords.yml +3 -0
  143. data/lib/generators/answers/cms/cms_generator.rb +314 -0
  144. data/lib/generators/answers/cms/templates/.gitignore +91 -0
  145. data/lib/generators/answers/cms/templates/app/decorators/controllers/answers/.keep +0 -0
  146. data/lib/generators/answers/cms/templates/app/decorators/models/answers/.keep +0 -0
  147. data/lib/generators/answers/cms/templates/app/views/sitemap/index.xml.builder +15 -0
  148. data/lib/generators/answers/cms/templates/config/database.yml.mysql +20 -0
  149. data/lib/generators/answers/cms/templates/config/database.yml.postgresql +58 -0
  150. data/lib/generators/answers/cms/templates/config/database.yml.sqlite3 +18 -0
  151. data/lib/generators/answers/core/core_generator.rb +10 -0
  152. data/lib/generators/answers/core/templates/config/initializers/answers/core.rb.erb +35 -0
  153. data/lib/generators/answers/dummy/dummy_generator.rb +86 -0
  154. data/lib/generators/answers/dummy/templates/rails/Rakefile +7 -0
  155. data/lib/generators/answers/dummy/templates/rails/application.js +3 -0
  156. data/lib/generators/answers/dummy/templates/rails/application.rb.erb +12 -0
  157. data/lib/generators/answers/dummy/templates/rails/boot.rb.erb +6 -0
  158. data/lib/generators/answers/dummy/templates/rails/database.yml +34 -0
  159. data/lib/generators/answers/dummy/templates/rails/routes.rb +3 -0
  160. data/lib/generators/answers/engine/USAGE +24 -0
  161. data/lib/generators/answers/engine/engine_generator.rb +44 -0
  162. data/lib/generators/answers/engine/templates/.gitignore +2 -0
  163. data/lib/generators/answers/engine/templates/Gemfile +42 -0
  164. data/lib/generators/answers/engine/templates/Rakefile +19 -0
  165. data/lib/generators/answers/engine/templates/answers-extension_plural_name.gemspec +19 -0
  166. data/lib/generators/answers/engine/templates/app/controllers/answers/namespace/admin/plural_name_controller.rb.erb +14 -0
  167. data/lib/generators/answers/engine/templates/app/controllers/answers/namespace/plural_name_controller.rb.erb +34 -0
  168. data/lib/generators/answers/engine/templates/app/models/answers/namespace/singular_name.rb.erb +37 -0
  169. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_actions.html.erb +25 -0
  170. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_form.html.erb +65 -0
  171. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_plural_name.html.erb +2 -0
  172. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_records.html.erb +16 -0
  173. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_singular_name.html.erb +33 -0
  174. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_sortable_list.html.erb +5 -0
  175. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/edit.html.erb +1 -0
  176. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/index.html.erb +7 -0
  177. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/new.html.erb +1 -0
  178. data/lib/generators/answers/engine/templates/app/views/answers/namespace/plural_name/index.html.erb +11 -0
  179. data/lib/generators/answers/engine/templates/app/views/answers/namespace/plural_name/show.html.erb +39 -0
  180. data/lib/generators/answers/engine/templates/config/locales/cs.yml +28 -0
  181. data/lib/generators/answers/engine/templates/config/locales/en.yml +28 -0
  182. data/lib/generators/answers/engine/templates/config/locales/es.yml +29 -0
  183. data/lib/generators/answers/engine/templates/config/locales/fr.yml +28 -0
  184. data/lib/generators/answers/engine/templates/config/locales/it.yml +28 -0
  185. data/lib/generators/answers/engine/templates/config/locales/nb.yml +28 -0
  186. data/lib/generators/answers/engine/templates/config/locales/nl.yml +28 -0
  187. data/lib/generators/answers/engine/templates/config/locales/sk.yml +28 -0
  188. data/lib/generators/answers/engine/templates/config/locales/tr.yml +28 -0
  189. data/lib/generators/answers/engine/templates/config/locales/zh-CN.yml +30 -0
  190. data/lib/generators/answers/engine/templates/config/routes.rb.erb +19 -0
  191. data/lib/generators/answers/engine/templates/db/migrate/1_create_namespace_plural_name.rb.erb +39 -0
  192. data/lib/generators/answers/engine/templates/db/seeds.rb.erb +21 -0
  193. data/lib/generators/answers/engine/templates/lib/answers-extension_plural_name.rb.erb +1 -0
  194. data/lib/generators/answers/engine/templates/lib/answers/plural_name.rb.erb +21 -0
  195. data/lib/generators/answers/engine/templates/lib/answers/plural_name/engine.rb.erb +23 -0
  196. data/lib/generators/answers/engine/templates/lib/generators/answers/extension_plural_name_generator.rb.erb +19 -0
  197. data/lib/generators/answers/engine/templates/lib/tasks/answers/extension_plural_name.rake +13 -0
  198. data/lib/generators/answers/engine/templates/readme.md +10 -0
  199. data/lib/generators/answers/engine/templates/script/rails +10 -0
  200. data/lib/generators/answers/engine/templates/spec/features/answers/namespace/admin/plural_name_spec.rb.erb +200 -0
  201. data/lib/generators/answers/engine/templates/spec/models/answers/namespace/singular_name_spec.rb.erb +20 -0
  202. data/lib/generators/answers/engine/templates/spec/spec_helper.rb +31 -0
  203. data/lib/generators/answers/engine/templates/spec/support/factories/answers/plural_name.rb.erb +7 -0
  204. data/lib/generators/answers/engine/templates/tasks/rspec.rake +6 -0
  205. data/lib/generators/answers/engine/templates/tasks/testing.rake +8 -0
  206. data/lib/generators/answers/generator.rb +292 -0
  207. data/lib/markdownifier.rb +11 -0
  208. data/log/.gitkeep +0 -0
  209. data/log/development.log +12870 -0
  210. data/log/newrelic_agent.log +1339 -0
  211. data/log/test.log +233181 -0
  212. data/public/404.html +25 -0
  213. data/public/422.html +25 -0
  214. data/public/500.html +24 -0
  215. data/public/favicon.ico +0 -0
  216. data/public/robots.txt +5 -0
  217. data/script/delayed_job +5 -0
  218. data/spec/controllers/answers_controller_spec.rb +55 -0
  219. data/spec/controllers/api/v1/answers_controller_spec.rb +144 -0
  220. data/spec/controllers/api/v1/questions_controller_spec.rb +144 -0
  221. data/spec/controllers/api/v1/taggings_controller_spec.rb +126 -0
  222. data/spec/controllers/api/v1/tags_controller_spec.rb +126 -0
  223. data/spec/controllers/home_controller_spec.rb +60 -0
  224. data/spec/controllers/questions_controller_spec.rb +55 -0
  225. data/spec/controllers/tags_controller_spec.rb +42 -0
  226. data/spec/factories/answers.rb +10 -0
  227. data/spec/factories/questions.rb +8 -0
  228. data/spec/factories/tags.rb +8 -0
  229. data/spec/factories/user.rb +32 -0
  230. data/spec/features/admin_dashboard_spec.rb +53 -0
  231. data/spec/features/admin_user_spec.rb +61 -0
  232. data/spec/features/searches_spec.rb +101 -0
  233. data/spec/fixtures/Article/_before_validation/sets_access_count_if_nil.yml +223 -0
  234. data/spec/fixtures/Article/_delete_orphaned_keywords/updating_an_article/destroys_orphaned_keywords_associated.yml +223 -0
  235. data/spec/fixtures/Article/_delete_orphaned_keywords/when_deleting_an_article/destroys_all_keywords_associated.yml +223 -0
  236. data/spec/fixtures/Article/_find_by_friendly_id/when_an_article_does_not_exist/does_not_raise_an_exception.yml +223 -0
  237. data/spec/fixtures/Article/_find_by_friendly_id/when_an_article_exists/returns_the_corresponding_article.yml +223 -0
  238. data/spec/fixtures/Article/_find_by_type/excludes_articles_not_matching_specified_type.yml +223 -0
  239. data/spec/fixtures/Article/_find_by_type/returns_articles_matching_type.yml +223 -0
  240. data/spec/fixtures/Article/_hits/before_an_article_has_been_viewed/has_zero_hits.yml +223 -0
  241. data/spec/fixtures/Article/_hits/returns_number_of_views/has_seven_views.yml +223 -0
  242. data/spec/fixtures/Article/_indexable_/returns_false_if_article_is_not_published.yml +223 -0
  243. data/spec/fixtures/Article/_indexable_/returns_true_if_article_is_published.yml +223 -0
  244. data/spec/fixtures/Article/_legacy_/returns_true_if_render_markdown_is_false.yml +223 -0
  245. data/spec/fixtures/Article/_qm_after_create/creates_wordcounts_for_relevant_keywords.yml +223 -0
  246. data/spec/fixtures/Article/_record_hit/viewing_an_article/increases_hit_by_one.yml +223 -0
  247. data/spec/fixtures/Article/_related/has_no_related_articles/.yml +223 -0
  248. data/spec/fixtures/Article/_related/has_related_articles/.yml +223 -0
  249. data/spec/fixtures/Article/_remove_stop_words/removes_common_english_words_from_the_string.yml +223 -0
  250. data/spec/fixtures/Article/_search/_search_titles/query_is_present_in_the_title/.yml +223 -0
  251. data/spec/fixtures/Article/_search/_search_titles/returns_an_empty_array_when_the_search_term_is_present_in_an_article_but_not_the_title.yml +223 -0
  252. data/spec/fixtures/Article/_search/matches_articles_in_the_database.yml +223 -0
  253. data/spec/fixtures/Article/_search/query_does_not_match_anything_in_the_database/returns_an_empty_array.yml +223 -0
  254. data/spec/fixtures/Article/_search/query_is_a_single_space/.yml +223 -0
  255. data/spec/fixtures/Article/_search/query_is_an_empty_string/.yml +223 -0
  256. data/spec/fixtures/Article/_to_s/when_an_article_has_a_category/returns_a_string_containing_title_id_and_category.yml +223 -0
  257. data/spec/fixtures/Article/can_be_published/an_unpublished_article/is_published.yml +223 -0
  258. data/spec/fixtures/Article/can_be_published/an_unpublished_article/returns_status_Published.yml +223 -0
  259. data/spec/fixtures/Article/has_a_friendly_url.yml +223 -0
  260. data/spec/fixtures/Article/is_valid_with_a_title.yml +223 -0
  261. data/spec/fixtures/Searches/search_results/1_result_found/.yml +22047 -0
  262. data/spec/fixtures/Searches/search_results/no_results_found/.yml +393 -0
  263. data/spec/fixtures/Searches/search_results/several_results_found/should_contain_the_title_and_preview_of_both_articles.yml +223 -0
  264. data/spec/fixtures/Searches/search_results/several_results_found/show_the_query.yml +277 -0
  265. data/spec/fixtures/articles.yml +428 -0
  266. data/spec/fixtures/categories.yml +17 -0
  267. data/spec/fixtures/contacts.yml +11 -0
  268. data/spec/fixtures/dragon_keyword_cassette.yml +77 -0
  269. data/spec/fixtures/oakland_answers.yml +2379 -0
  270. data/spec/helpers/tags_helper_spec.rb +15 -0
  271. data/spec/lib/markdownifier_spec.rb +12 -0
  272. data/spec/models/ability_spec.rb +36 -0
  273. data/spec/models/answer_spec.rb +5 -0
  274. data/spec/models/question_spec.rb +70 -0
  275. data/spec/models/user_spec.rb +55 -0
  276. data/spec/routing/answers_routing_spec.rb +19 -0
  277. data/spec/routing/questions_routing_spec.rb +19 -0
  278. data/spec/routing/routes_spec.rb +13 -0
  279. data/spec/security/brakeman_spec.rb +37 -0
  280. data/spec/spec_helper.rb +61 -0
  281. data/spec/support/login_helpers.rb +10 -0
  282. data/spec/support/wait_for_ajax_helper.rb +7 -0
  283. data/spec/support/wait_for_dom_helper.rb +12 -0
  284. data/spec/views/questions/index.html.erb_spec.rb +16 -0
  285. data/spec/views/questions/show.html.erb_spec.rb +14 -0
  286. data/spec/views/tags/index.html.erb_spec.rb +5 -0
  287. data/spec/views/tags/show.html.erb_spec.rb +5 -0
  288. data/vendor/assets/javascripts/.gitkeep +0 -0
  289. data/vendor/assets/stylesheets/.gitkeep +0 -0
  290. data/vendor/assets/stylesheets/bootstrap.css +3990 -0
  291. data/vendor/crudgen/lib/generators/crudgen/install_generator.rb +23 -0
  292. data/vendor/plugins/.gitkeep +0 -0
  293. metadata +484 -0
@@ -0,0 +1,62 @@
1
+ module Answers
2
+ module Engine
3
+ # Specify a block of code to be run after the answers inclusion step. See
4
+ # Answers::Core::Engine#answers_inclusion for details regarding the Answers
5
+ # inclusion process.
6
+ #
7
+ # Example:
8
+ # module Answers
9
+ # module Images
10
+ # class Engine < Rails::Engine
11
+ # extend Answers::Engine
12
+ # engine_name :images
13
+ #
14
+ # after_inclusion do
15
+ # # perform something here
16
+ # end
17
+ # end
18
+ # end
19
+ # end
20
+ def after_inclusion(&block)
21
+ if block && block.respond_to?(:call)
22
+ after_inclusion_procs << block
23
+ else
24
+ raise 'Anything added to be called after_inclusion must be callable (respond to #call).'
25
+ end
26
+ end
27
+
28
+ # Specify a block of code to be run before the answers inclusion step. See
29
+ # Answers::Core::Engine#answers_inclusion for details regarding the Answers
30
+ # inclusion process.
31
+ #
32
+ # Example:
33
+ # module Answers
34
+ # module Images
35
+ # class Engine < Rails::Engine
36
+ # extend Answers::Engine
37
+ # engine_name :images
38
+ #
39
+ # before_inclusion do
40
+ # # perform something here
41
+ # end
42
+ # end
43
+ # end
44
+ # end
45
+ def before_inclusion(&block)
46
+ if block && block.respond_to?(:call)
47
+ before_inclusion_procs << block
48
+ else
49
+ raise 'Anything added to be called before_inclusion must be callable (respond to #call).'
50
+ end
51
+ end
52
+
53
+ private
54
+ def after_inclusion_procs
55
+ @@after_inclusion_procs ||= []
56
+ end
57
+
58
+ def before_inclusion_procs
59
+ @@before_inclusion_procs ||= []
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,13 @@
1
+ module Answers
2
+
3
+ # = Answers Errors
4
+ #
5
+ # Generic Answers exception class
6
+ class AnswersError < StandardError
7
+ end
8
+
9
+ # Raised when an extension has not been properly defined. See the exception message for further
10
+ # details
11
+ class InvalidEngineError < AnswersError
12
+ end
13
+ end
@@ -0,0 +1,75 @@
1
+ module Answers
2
+ class Plugin
3
+
4
+ attr_accessor :name, :class_name, :controller, :directory, :url,
5
+ :dashboard, :always_allow_access, :menu_match,
6
+ :hide_from_menu, :pathname, :plugin_activity
7
+
8
+ def self.register(&block)
9
+ yield(plugin = self.new)
10
+
11
+ raise "A plugin MUST have a name!: #{plugin.inspect}" if plugin.name.blank?
12
+
13
+ # Set defaults.
14
+ plugin.menu_match ||= %r{answers/#{plugin.name}(/.+?)?$}
15
+ plugin.always_allow_access ||= false
16
+ plugin.dashboard ||= false
17
+ plugin.class_name ||= plugin.name.camelize
18
+
19
+ # add the new plugin to the collection of registered plugins
20
+ ::Answers::Plugins.registered << plugin
21
+ end
22
+
23
+ # Returns the internationalized version of the title
24
+ def title
25
+ ::I18n.translate(['answers', 'plugins', name, 'title'].join('.'))
26
+ end
27
+
28
+ # Returns the internationalized version of the description
29
+ def description
30
+ ::I18n.translate(['answers', 'plugins', name, 'description'].join('.'))
31
+ end
32
+
33
+ # Stores information that can be used to retrieve the latest activities of this plugin
34
+ def activity=(activities)
35
+ Answers.deprecate('Answers::Plugin#activity=', when: '3.1')
36
+ end
37
+
38
+ # Used to highlight the current tab in the admin interface
39
+ def highlighted?(params)
40
+ !!(params[:controller].try(:gsub, "admin/", "") =~ menu_match) || (dashboard && params[:action] == 'error_404')
41
+ end
42
+
43
+ def pathname=(value)
44
+ value = Pathname.new(value) if value.is_a? String
45
+ @pathname = value
46
+ end
47
+
48
+ # Returns a hash that can be used to create a url that points to the administration part of the plugin.
49
+ def url
50
+ @url ||= if controller.present?
51
+ { :controller => "answers/admin/#{controller}" }
52
+ elsif directory.present?
53
+ { :controller => "answers/admin/#{directory.split('/').pop}" }
54
+ else
55
+ { :controller => "answers/admin/#{name}" }
56
+ end
57
+
58
+ if @url.is_a?(Hash)
59
+ {:only_path => true}.merge(@url)
60
+ elsif @url.respond_to?(:call)
61
+ @url.call
62
+ else
63
+ @url
64
+ end
65
+ end
66
+
67
+ # Make this protected, so that only Plugin.register can use it.
68
+ protected
69
+ def initialize
70
+ # provide a default pathname to where this plugin is using its lib directory.
71
+ depth = RUBY_VERSION >= "1.9.2" ? 4 : 3
72
+ self.pathname ||= Pathname.new(caller(depth).first.match("(.*)#{File::SEPARATOR}lib")[1])
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,73 @@
1
+ require 'forwardable'
2
+
3
+ module Answers
4
+ class Plugins
5
+ include Enumerable
6
+ extend Forwardable
7
+
8
+ def initialize(*args)
9
+ @plugins = Array.new(*args)
10
+ end
11
+
12
+ def_delegators :@plugins, :<<, :each, :delete_if
13
+
14
+ def find_by_name(name)
15
+ detect { |plugin| plugin.name == name }
16
+ end
17
+ alias :[] :find_by_name
18
+
19
+ def find_by_title(title)
20
+ detect { |plugin| plugin.title == title }
21
+ end
22
+
23
+ def in_menu
24
+ self.class.new(reject(&:hide_from_menu))
25
+ end
26
+
27
+ def names
28
+ map(&:name)
29
+ end
30
+
31
+ def pathnames
32
+ map(&:pathname).compact.uniq
33
+ end
34
+
35
+ def titles
36
+ map(&:title)
37
+ end
38
+
39
+ class << self
40
+ def active
41
+ @active_plugins ||= new
42
+ end
43
+
44
+ def always_allowed
45
+ new registered.select(&:always_allow_access)
46
+ end
47
+
48
+ def registered
49
+ @registered_plugins ||= new
50
+ end
51
+
52
+ def activate(name)
53
+ active << registered[name] if registered[name] && !active[name]
54
+ end
55
+
56
+ def deactivate(name)
57
+ active.delete_if {|p| p.name == name}
58
+ end
59
+
60
+ def set_active(names)
61
+ @active_plugins = new
62
+
63
+ names.each do |name|
64
+ activate(name)
65
+ end
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ attr_reader :plugins
72
+ end
73
+ end
@@ -0,0 +1,16 @@
1
+ module Answers
2
+ class Version
3
+ @major = 0
4
+ @minor = 0
5
+ @tiny = 5
6
+ @build = nil
7
+
8
+ class << self
9
+ attr_reader :major, :minor, :tiny, :build
10
+
11
+ def to_s
12
+ [@major, @minor, @tiny, @build].compact.join('.')
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/api_client.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'weary'
2
+ require 'json'
3
+
4
+ DEVELOPMENT_DOMAIN = "http://localhost:3000"
5
+
6
+ module APIClient
7
+ class Answer < Weary::Client
8
+ domain DEVELOPMENT_DOMAIN if Rails.env.development?
9
+ domain PRODUCTION_DOMAIN if Rails.env.production?
10
+
11
+ get :all, "/answers.json"
12
+ get :find, "/answers/{id}.json"
13
+
14
+ post :create, "/answers.json" do |resource|
15
+ resource.optional :need_to_know
16
+ resource.required :text, :in_language
17
+ end
18
+ end
19
+ end
20
+
File without changes
@@ -0,0 +1 @@
1
+ a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,much,lost
@@ -0,0 +1,3 @@
1
+ - case
2
+ - class
3
+ - switch
@@ -0,0 +1,314 @@
1
+ require 'pathname'
2
+ module Answers
3
+ class CmsGenerator < Rails::Generators::Base
4
+ source_root Pathname.new(File.expand_path('../templates', __FILE__))
5
+
6
+ class_option :update, :type => :boolean, :aliases => nil, :group => :runtime,
7
+ :desc => "Update an existing Answers based application"
8
+ class_option :fresh_installation, :type => :boolean, :aliases => nil, :group => :runtime, :default => false,
9
+ :desc => "Allow Answers to remove default Rails files in a fresh installation"
10
+ class_option :heroku, :type => :string, :default => nil, :group => :runtime, :banner => 'APP_NAME',
11
+ :desc => "Deploy to Heroku after the generator has run."
12
+ class_option :stack, :type => :string, :default => 'cedar', :group => :runtime,
13
+ :desc => "Specify which Heroku stack you want to use. Requires --heroku option to function."
14
+ class_option :skip_db, :type => :boolean, :default => false, :aliases => nil, :group => :runtime,
15
+ :desc => "Skip over any database creation, migration or seeding."
16
+ class_option :skip_migrations, :type => :boolean, :default => false, :aliases => nil, :group => :runtime,
17
+ :desc => "Skip over installing or running migrations."
18
+
19
+ def generate
20
+ start_pretending?
21
+
22
+ manage_roadblocks! unless self.options[:update]
23
+
24
+ ensure_environments_are_sane!
25
+
26
+ stop_pretending?
27
+
28
+ append_gemfile!
29
+
30
+ append_gitignore!
31
+
32
+ append_seeds!
33
+
34
+ append_asset_pipeline!
35
+
36
+ forced_overwriting?
37
+
38
+ copy_files!
39
+
40
+ create_decorators!
41
+
42
+ mount!
43
+
44
+ run_additional_generators! if self.options[:fresh_installation]
45
+
46
+ generate_active_admin_install
47
+
48
+ migrate_database!
49
+
50
+ seed_database!
51
+
52
+ deploy_to_hosting?
53
+ end
54
+
55
+ protected
56
+
57
+ def append_asset_pipeline!
58
+ application_css = 'app/assets/stylesheets/application.css'
59
+ if destination_path.join(application_css).file?
60
+ insert_into_file application_css, %q{*= require answers/formatting
61
+ *= require answers/theme
62
+ }, before: '*= require_self'
63
+ end
64
+
65
+ application_js = 'app/assets/javascripts/application.js'
66
+ if destination_path.join(application_js).file?
67
+ insert_into_file application_js, %q{//= require answers
68
+ }, before: '//= require_tree .'
69
+ end
70
+ end
71
+
72
+ def append_gemfile!
73
+ if destination_path.join('Gemfile').file? &&
74
+ destination_path.join('Gemfile').read !~ %r{group :development, :test do\n.+?gem 'sqlite3'\nend}m
75
+ gsub_file 'Gemfile', %q{gem 'sqlite3'}, %q{group :development, :test do
76
+ gem 'sqlite3'
77
+ end} end
78
+ end
79
+
80
+ def append_gitignore!
81
+ # Ensure .gitignore exists and append our rules to it.
82
+ create_file ".gitignore" unless destination_path.join('.gitignore').file?
83
+ our_ignore_rules = self.class.source_root.join('.gitignore').read
84
+ our_ignore_rules = our_ignore_rules.split('# ANSWERS DEVELOPMENT').first if destination_path != Answers.root
85
+ append_file ".gitignore", our_ignore_rules
86
+ end
87
+
88
+ def append_seeds!
89
+ append_file 'db/seeds.rb', %q{
90
+ puts 'SETTING UP DEFAULT USER LOGIN'
91
+ print "Enter admin email: "
92
+ admin_email = 'admin@answers.gsa.io'
93
+
94
+ user = Answers::User.create! :email => admin_email, :password => 'Mahalo43', :password_confirmation => 'Mahalo43', :is_admin => true, :is_editor => true, :is_writer => true
95
+ puts 'New user created: ' << user.email
96
+ puts "Admin password has been set to: Mahalo43"
97
+ }
98
+ end
99
+
100
+ def append_heroku_gems!
101
+ append_file 'Gemfile', %q{
102
+ # The Heroku gem allows you to interface with Heroku's API
103
+ gem 'heroku'
104
+
105
+ # Fog allows you to use S3 assets (added for Heroku)
106
+ gem 'fog'
107
+ }
108
+ # If postgres is not the database in use, Heroku still needs it.
109
+ if destination_path.join('Gemfile').file? && destination_path.join('Gemfile').read !~ %r{gem ['"]pg['"]}
110
+ append_file 'Gemfile', %q{
111
+ # Postgres support (added for Heroku)
112
+ gem 'pg'
113
+ }
114
+ end
115
+ end
116
+
117
+ def bundle!
118
+ run 'bundle install'
119
+ end
120
+
121
+ def generate_active_admin_install
122
+ run 'rails g active_admin:install --skip-users'
123
+ remove_file 'config/initializers/active_admin.rb', :verbose => true
124
+ end
125
+
126
+ def copy_files!
127
+ # The extension installer only installs database templates.
128
+ Pathname.glob(self.class.source_root.join('**', '*')).reject{|f|
129
+ f.directory? or f.to_s =~ /\/db\//
130
+ }.sort.each do |path|
131
+ copy_file path, path.to_s.gsub(self.class.source_root.to_s, destination_path.to_s)
132
+ end
133
+ end
134
+
135
+ def create_decorators!
136
+ # Create decorator directories
137
+ %w[controllers models].each do |decorator_namespace|
138
+ src_file_path = "app/decorators/#{decorator_namespace}/answers/.keep"
139
+ copy_file self.class.source_root.join(src_file_path), destination_path.join(src_file_path)
140
+ end
141
+ end
142
+
143
+ def deploy_to_hosting?
144
+ if heroku?
145
+ append_heroku_gems!
146
+
147
+ bundle!
148
+
149
+ # Sanity check the heroku application name and save whatever messages are produced.
150
+ message = sanity_check_heroku_application_name!
151
+
152
+ # Supply the deploy process with the previous messages to make them visible.
153
+ deploy_to_hosting_heroku!(message)
154
+ end
155
+ end
156
+
157
+ def deploy_to_hosting_heroku!(message = nil)
158
+ say_status "Initializing and committing to git..", nil
159
+ run "git init && git add . && git commit -am 'Created application using Answers #{Answers.version}'"
160
+
161
+ say_status message, nil, :yellow if message
162
+
163
+ say_status "Creating Heroku app..", nil
164
+ run ["heroku create",
165
+ (options[:heroku] if heroku?),
166
+ "#{"--stack #{options[:stack]}" if options[:stack]}"
167
+ ].compact.join(' ')
168
+
169
+ say_status "Pushing to Heroku (this takes time, be patient)..", nil
170
+ run "git push heroku master"
171
+
172
+ say_status "Setting up the Heroku database..", nil
173
+ run "heroku#{' run' if options[:stack] == 'cedar'} rake db:migrate"
174
+
175
+ say_status "Restarting servers...", nil
176
+ run "heroku restart"
177
+ end
178
+
179
+ # Helper method to quickly convert destination_root to a Pathname for easy file path manipulation
180
+ def destination_path
181
+ @destination_path ||= Pathname.new(self.destination_root)
182
+ end
183
+
184
+ def ensure_environments_are_sane!
185
+ # Massage environment files
186
+ %w(development test production).map{|e| "config/environments/#{e}.rb"}.each do |env|
187
+ next unless destination_path.join(env).file?
188
+
189
+ # Answers does not necessarily expect action_mailer to be available as
190
+ # we may not always require it (currently only the authentication extension).
191
+ # Rails, however, will optimistically place config entries for action_mailer.
192
+ current_mailer_config = File.read(destination_path.join(env)).to_s.
193
+ match(%r{^\s.+?config\.action_mailer\..+([\w\W]*\})?}).
194
+ to_a.flatten.first
195
+
196
+ if current_mailer_config.present?
197
+ new_mailer_config = [
198
+ " if config.respond_to?(:action_mailer)",
199
+ current_mailer_config.gsub(%r{\A\n+?}, ''). # remove extraneous newlines at the start
200
+ gsub(%r{^\ \ }) { |line| " #{line}" }, # add indentation on each line
201
+ " end"
202
+ ].join("\n")
203
+
204
+ gsub_file env, current_mailer_config, new_mailer_config, :verbose => false
205
+ end
206
+
207
+ gsub_file env, "config.assets.compile = false", "config.assets.compile = true", :verbose => false
208
+ end
209
+ end
210
+
211
+ def forced_overwriting?
212
+ force_options = self.options.dup
213
+ force_options[:force] = self.options[:force] || self.options[:update]
214
+ self.options = force_options
215
+ end
216
+
217
+ def heroku?
218
+ options[:heroku].present?
219
+ end
220
+
221
+ def manage_roadblocks!
222
+ %w(public/index.html app/views/layouts/application.html.erb).each do |roadblock|
223
+ if (roadblock_path = destination_path.join(roadblock)).file?
224
+ if self.options[:fresh_installation]
225
+ remove_file roadblock_path, :verbose => true
226
+ else
227
+ say_status :"-- You may need to remove '#{roadblock}' for Answers to function properly --", nil, :yellow
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ def migrate_database!
234
+ unless self.options[:skip_migrations]
235
+ rake 'railties:install:migrations'
236
+ rake 'db:create db:migrate' unless self.options[:skip_db]
237
+ end
238
+ end
239
+
240
+ def mount!
241
+ if (routes_file = destination_path.join('config', 'routes.rb')).file? && (self.behavior == :revoke || (routes_file.read !~ %r{mount\ Answers::Core::Engine}))
242
+ # Append routes
243
+ mount = %Q{
244
+ # This line mounts Answers's routes at the root of your application.
245
+ # This means, any requests to the root URL of your application will go to Answers::PagesController#home.
246
+ # If you would like to change where this extension is mounted, simply change the :at option to something different.
247
+ #
248
+ # We ask that you don't use the :as option here, as Answers relies on it being the default of "answers"
249
+ mount Answers::Core::Engine, at: '/'
250
+ ActiveAdmin.routes(self)
251
+
252
+ }
253
+
254
+ inject_into_file 'config/routes.rb', mount, after: ".routes.draw do"
255
+ end
256
+ end
257
+
258
+ def run_additional_generators!
259
+ generator_args = []
260
+ generator_args << '--quiet' if self.options[:quiet]
261
+ generator_args << '--skip-migrations' if self.options[:skip_migrations]
262
+ Answers::CoreGenerator.start generator_args
263
+ Answers::AuthenticationGenerator.start generator_args if defined?(Answers::AuthenticationGenerator)
264
+ Answers::I18nGenerator.start generator_args if defined?(Answers::I18nGenerator)
265
+ end
266
+
267
+ def sanity_check_heroku_application_name!
268
+ if heroku? && options[:heroku].to_s.include?('_') || options[:heroku].to_s.length > 30
269
+ message = ["\nThe application name '#{options[:heroku]}' that you specified is invalid for Heroku."]
270
+ suggested_name = options[:heroku].dup.to_s
271
+ if suggested_name.include?('_')
272
+ message << "This is because it contains underscores which Heroku does not allow."
273
+ suggested_name.gsub!(/_/, '-')
274
+ end
275
+ if suggested_name.length > 30
276
+ message << "This is#{" also" unless suggested_name.nil?} because it is longer than 30 characters."
277
+ suggested_name = suggested_name[0..29]
278
+ end
279
+
280
+ options[:heroku] = suggested_name
281
+
282
+ message << "We have changed the name to '#{suggested_name}' for you, hope it suits you.\n"
283
+ message.join("\n")
284
+ end
285
+
286
+ options[:heroku] = '' if options[:heroku] == 'heroku'
287
+ end
288
+
289
+ def seed_database!
290
+ rake 'db:seed' unless self.options[:skip_db] || self.options[:skip_migrations]
291
+ end
292
+
293
+ def start_pretending?
294
+ # Only pretend to do the next actions if this is Answers to stay DRY
295
+ if destination_path == Answers.root
296
+ say_status :'-- pretending to make changes that happen in an actual installation --', nil, :yellow
297
+ old_pretend = self.options[:pretend]
298
+ new_options = self.options.dup
299
+ new_options[:pretend] = true
300
+ self.options = new_options
301
+ end
302
+ end
303
+
304
+ def stop_pretending?
305
+ # Stop pretending
306
+ if destination_path == Answers.root
307
+ say_status :'-- finished pretending --', nil, :yellow
308
+ new_options = self.options.dup
309
+ new_options[:pretend] = old_pretend
310
+ self.options = new_options
311
+ end
312
+ end
313
+ end
314
+ end