writefully 0.3.6

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 (328) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +31 -0
  4. data/Rakefile +22 -0
  5. data/app/assets/javascripts/writefully/authorships.js +2 -0
  6. data/app/assets/javascripts/writefully/sessions.js +2 -0
  7. data/app/assets/javascripts/writefully/writefully/initializers/boot.coffee +6 -0
  8. data/app/assets/javascripts/writefully/writefully/initializers/manifest.coffee +28 -0
  9. data/app/assets/javascripts/writefully/writefully/initializers/setup.coffee +4 -0
  10. data/app/assets/javascripts/writefully/writefully/loader.coffee +6 -0
  11. data/app/assets/javascripts/writefully/writefully.coffee +8 -0
  12. data/app/assets/stylesheets/writefully/base.sass +23 -0
  13. data/app/assets/stylesheets/writefully/sessions.sass +9 -0
  14. data/app/assets/stylesheets/writefully/sites.sass +33 -0
  15. data/app/assets/stylesheets/writefully/writefully.sass +4 -0
  16. data/app/controllers/writefully/application_controller.rb +28 -0
  17. data/app/controllers/writefully/authorships_controller.rb +8 -0
  18. data/app/controllers/writefully/hooks_controller.rb +51 -0
  19. data/app/controllers/writefully/posts_controller.rb +21 -0
  20. data/app/controllers/writefully/sessions_controller.rb +47 -0
  21. data/app/controllers/writefully/sites_controller.rb +51 -0
  22. data/app/helpers/writefully/application_helper.rb +15 -0
  23. data/app/helpers/writefully/flash_helper.rb +31 -0
  24. data/app/helpers/writefully/posts_helper.rb +8 -0
  25. data/app/helpers/writefully/sites_helper.rb +21 -0
  26. data/app/models/writefully/authorship.rb +34 -0
  27. data/app/models/writefully/post.rb +23 -0
  28. data/app/models/writefully/site.rb +30 -0
  29. data/app/models/writefully/tag.rb +15 -0
  30. data/app/models/writefully/tagging.rb +6 -0
  31. data/app/views/layouts/writefully/application.html.erb +16 -0
  32. data/app/views/layouts/writefully/sessions.html.erb +16 -0
  33. data/app/views/writefully/application/_activeable_link_to.html.erb +5 -0
  34. data/app/views/writefully/application/_flash.html.erb +5 -0
  35. data/app/views/writefully/application/_navigation.html.erb +23 -0
  36. data/app/views/writefully/application/flash/_owner_exists.html.erb +0 -0
  37. data/app/views/writefully/application/flash/_signed_in.html.erb +0 -0
  38. data/app/views/writefully/application/flash/_signed_out.html.erb +0 -0
  39. data/app/views/writefully/posts/_not_published.html.erb +1 -0
  40. data/app/views/writefully/posts/_post.html.erb +14 -0
  41. data/app/views/writefully/posts/_published.html.erb +1 -0
  42. data/app/views/writefully/posts/index.html.erb +7 -0
  43. data/app/views/writefully/posts/show.html.erb +0 -0
  44. data/app/views/writefully/sessions/new.html.erb +7 -0
  45. data/app/views/writefully/sites/_empty.html.erb +0 -0
  46. data/app/views/writefully/sites/_form.html.erb +15 -0
  47. data/app/views/writefully/sites/_site.html.erb +16 -0
  48. data/app/views/writefully/sites/edit.html.erb +0 -0
  49. data/app/views/writefully/sites/flash/create/_error.html.erb +0 -0
  50. data/app/views/writefully/sites/flash/create/_success.html.erb +2 -0
  51. data/app/views/writefully/sites/healthy/_no.html.erb +3 -0
  52. data/app/views/writefully/sites/healthy/_yes.html.erb +3 -0
  53. data/app/views/writefully/sites/index.html.erb +14 -0
  54. data/app/views/writefully/sites/new.html.erb +7 -0
  55. data/app/views/writefully/sites/processing/_no.html.erb +3 -0
  56. data/app/views/writefully/sites/processing/_yes.html.erb +3 -0
  57. data/app/views/writefully/sites/show/_errors.html.erb +0 -0
  58. data/app/views/writefully/sites/show/_heading.html.erb +6 -0
  59. data/app/views/writefully/sites/show/_processing.html.erb +0 -0
  60. data/app/views/writefully/sites/show/_tabs.html.erb +5 -0
  61. data/app/views/writefully/sites/show.html.erb +3 -0
  62. data/bin/rails +12 -0
  63. data/bin/writefully +7 -0
  64. data/config/routes.rb +16 -0
  65. data/db/migrate/20140402091204_create_writefully_posts.rb +22 -0
  66. data/db/migrate/20140402091244_create_writefully_tags.rb +14 -0
  67. data/db/migrate/20140402091415_create_writefully_taggings.rb +10 -0
  68. data/db/migrate/20140402200330_create_writefully_authorships.rb +12 -0
  69. data/db/migrate/20140403181629_create_writefully_sites.rb +20 -0
  70. data/lib/sample/README.md +26 -0
  71. data/lib/sample/meta.yml +7 -0
  72. data/lib/sample/writefully.png +0 -0
  73. data/lib/tasks/writefully_tasks.rake +9 -0
  74. data/lib/writefully/asset.rb +33 -0
  75. data/lib/writefully/cli.rb +57 -0
  76. data/lib/writefully/content.rb +31 -0
  77. data/lib/writefully/engine.rb +25 -0
  78. data/lib/writefully/indices.rb +21 -0
  79. data/lib/writefully/news_agency.rb +8 -0
  80. data/lib/writefully/postable.rb +57 -0
  81. data/lib/writefully/process.rb +84 -0
  82. data/lib/writefully/source.rb +52 -0
  83. data/lib/writefully/storage.rb +33 -0
  84. data/lib/writefully/taxon.rb +28 -0
  85. data/lib/writefully/tools/dispatcher.rb +59 -0
  86. data/lib/writefully/tools/eraser.rb +0 -0
  87. data/lib/writefully/tools/hammer.rb +41 -0
  88. data/lib/writefully/tools/initializer.rb +38 -0
  89. data/lib/writefully/tools/pencil.rb +71 -0
  90. data/lib/writefully/tools/pigeon.rb +19 -0
  91. data/lib/writefully/tools/synchronizer.rb +24 -0
  92. data/lib/writefully/tools.rb +13 -0
  93. data/lib/writefully/version.rb +3 -0
  94. data/lib/writefully/workers/base_worker.rb +25 -0
  95. data/lib/writefully/workers/handyman.rb +44 -0
  96. data/lib/writefully/workers/helpers/handyman/builder.rb +17 -0
  97. data/lib/writefully/workers/helpers.rb +8 -0
  98. data/lib/writefully/workers/journalist.rb +23 -0
  99. data/lib/writefully/workers.rb +9 -0
  100. data/lib/writefully/workers_helpers.rb +7 -0
  101. data/lib/writefully.rb +77 -0
  102. data/scripts/initialize.sh +30 -0
  103. data/scripts/sync.sh +17 -0
  104. data/spec/controllers/writefully/hooks_controller_spec.rb +35 -0
  105. data/spec/controllers/writefully/posts_controller_spec.rb +46 -0
  106. data/spec/controllers/writefully/sites_controller_spec.rb +91 -0
  107. data/spec/dummy/Rakefile +8 -0
  108. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  109. data/spec/dummy/app/models/playlist.rb +3 -0
  110. data/spec/dummy/app/models/post.rb +3 -0
  111. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  112. data/spec/dummy/bin/bundle +3 -0
  113. data/spec/dummy/bin/rails +4 -0
  114. data/spec/dummy/bin/rake +4 -0
  115. data/spec/dummy/config/application.rb +22 -0
  116. data/spec/dummy/config/boot.rb +5 -0
  117. data/spec/dummy/config/database.yml +25 -0
  118. data/spec/dummy/config/environment.rb +5 -0
  119. data/spec/dummy/config/environments/development.rb +29 -0
  120. data/spec/dummy/config/environments/production.rb +80 -0
  121. data/spec/dummy/config/environments/test.rb +36 -0
  122. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  123. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  124. data/spec/dummy/config/initializers/inflections.rb +16 -0
  125. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  126. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  127. data/spec/dummy/config/initializers/session_store.rb +3 -0
  128. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  129. data/spec/dummy/config/locales/en.yml +23 -0
  130. data/spec/dummy/config/routes.rb +3 -0
  131. data/spec/dummy/config/writefully.yml +9 -0
  132. data/spec/dummy/config.ru +4 -0
  133. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/README.md +119 -0
  134. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/assets/hash-selector-cover.png +0 -0
  135. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/assets/hash-selector-icon.png +0 -0
  136. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/benchmark/selector.rb +77 -0
  137. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/meta.yml +7 -0
  138. data/spec/dummy/content/codemy-net/posts/2-rails-flash-partials/README.md +171 -0
  139. data/spec/dummy/content/codemy-net/posts/2-rails-flash-partials/assets/cover.png +0 -0
  140. data/spec/dummy/content/codemy-net/posts/2-rails-flash-partials/meta.yml +7 -0
  141. data/spec/dummy/db/schema.rb +89 -0
  142. data/spec/dummy/log/development.log +13946 -0
  143. data/spec/dummy/log/test.log +100164 -0
  144. data/spec/dummy/tmp/cache/assets/development/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/application.sassc +0 -0
  145. data/spec/dummy/tmp/cache/assets/development/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/bootstrap.cssc +0 -0
  146. data/spec/dummy/tmp/cache/assets/development/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/setups.sassc +0 -0
  147. data/spec/dummy/tmp/cache/assets/development/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/writefully.sassc +0 -0
  148. data/spec/dummy/tmp/cache/assets/development/sprockets/04641fdb653c0ff3c557033d87eb6a16 +0 -0
  149. data/spec/dummy/tmp/cache/assets/development/sprockets/064b3076e29f54ea572ca43d6c5950cc +0 -0
  150. data/spec/dummy/tmp/cache/assets/development/sprockets/0d2e79f7f8c9026d7d8a7f6dc63fb4a8 +0 -0
  151. data/spec/dummy/tmp/cache/assets/development/sprockets/0f1c342384786865a6200cc3ed6234a3 +0 -0
  152. data/spec/dummy/tmp/cache/assets/development/sprockets/13c3568b2854b103512b2658e6507d4b +0 -0
  153. data/spec/dummy/tmp/cache/assets/development/sprockets/18eb9f12c7e8971e0e2fad29c85a8b8e +0 -0
  154. data/spec/dummy/tmp/cache/assets/development/sprockets/18f8d9596e0fba3397539181f63befe1 +0 -0
  155. data/spec/dummy/tmp/cache/assets/development/sprockets/1977498f5af78beca26942a7c812b294 +0 -0
  156. data/spec/dummy/tmp/cache/assets/development/sprockets/1ae121eed970dfdb5f4f09953ade4de2 +0 -0
  157. data/spec/dummy/tmp/cache/assets/development/sprockets/1b5404b64386f619af12582a1a634574 +0 -0
  158. data/spec/dummy/tmp/cache/assets/development/sprockets/22b701cb6ffd8eac83ec1bfc563b54cb +0 -0
  159. data/spec/dummy/tmp/cache/assets/development/sprockets/2d27da60cfa2f1952c3aadd169ea2570 +0 -0
  160. data/spec/dummy/tmp/cache/assets/development/sprockets/2e33b23d27ad5b8771d09ed8a1435cf6 +0 -0
  161. data/spec/dummy/tmp/cache/assets/development/sprockets/3063f229c5edc0e8a3d82d7bf78024de +0 -0
  162. data/spec/dummy/tmp/cache/assets/development/sprockets/31c84f37a0c92c38be6459f19997c981 +0 -0
  163. data/spec/dummy/tmp/cache/assets/development/sprockets/320d61138ae0221b11c7e4ea0f3d53d3 +0 -0
  164. data/spec/dummy/tmp/cache/assets/development/sprockets/3355368d663ec5236287158290d6c297 +0 -0
  165. data/spec/dummy/tmp/cache/assets/development/sprockets/3df2d5c2f4f6b6d502c017346b915051 +0 -0
  166. data/spec/dummy/tmp/cache/assets/development/sprockets/4596b288fc67fdb9037e06897d416879 +0 -0
  167. data/spec/dummy/tmp/cache/assets/development/sprockets/47381977da0f1b2165bdbb09480ccff3 +0 -0
  168. data/spec/dummy/tmp/cache/assets/development/sprockets/4aab863b927c65a4b9e70c43e4e6d482 +0 -0
  169. data/spec/dummy/tmp/cache/assets/development/sprockets/4c0271d24537b8a24979e07bbd75956c +0 -0
  170. data/spec/dummy/tmp/cache/assets/development/sprockets/4c16c5c88ae074d893e1de2ad787b031 +0 -0
  171. data/spec/dummy/tmp/cache/assets/development/sprockets/51610d35f263eb68b1cf73737045113d +0 -0
  172. data/spec/dummy/tmp/cache/assets/development/sprockets/5af65427549750bdf60b3f06ce273b41 +0 -0
  173. data/spec/dummy/tmp/cache/assets/development/sprockets/63958de32a7352bcfb139639ba2d4209 +0 -0
  174. data/spec/dummy/tmp/cache/assets/development/sprockets/63f349e6a646ae0252d46e1816064e0c +0 -0
  175. data/spec/dummy/tmp/cache/assets/development/sprockets/67ae1c504593279ebd6da7b6fdbe99b7 +0 -0
  176. data/spec/dummy/tmp/cache/assets/development/sprockets/68e61e8d5ac667de89a4bf1e732cde0a +0 -0
  177. data/spec/dummy/tmp/cache/assets/development/sprockets/69dfb59cc80e2c111bfbfc108371b27b +0 -0
  178. data/spec/dummy/tmp/cache/assets/development/sprockets/6d0103100e416966beba1039661e234e +0 -0
  179. data/spec/dummy/tmp/cache/assets/development/sprockets/71ea75f9945cdb543e0dc44527fcd926 +0 -0
  180. data/spec/dummy/tmp/cache/assets/development/sprockets/7556620a4f8405144dca74330e54608c +0 -0
  181. data/spec/dummy/tmp/cache/assets/development/sprockets/76598a5aebf24a1b763f5b10ae223c15 +0 -0
  182. data/spec/dummy/tmp/cache/assets/development/sprockets/7af8770b019b471931e4f6cb86027307 +0 -0
  183. data/spec/dummy/tmp/cache/assets/development/sprockets/7b696db3b421aeaa1afd210b07db8aae +0 -0
  184. data/spec/dummy/tmp/cache/assets/development/sprockets/7ff072db2442371da6ee49c9b279efdc +0 -0
  185. data/spec/dummy/tmp/cache/assets/development/sprockets/82b92bb7c88523dc617b3c0c877aeade +0 -0
  186. data/spec/dummy/tmp/cache/assets/development/sprockets/8c388cf0035e064a06ae30a03d96b51b +0 -0
  187. data/spec/dummy/tmp/cache/assets/development/sprockets/95703f30550e80a229dd0ec4a6ddc85c +0 -0
  188. data/spec/dummy/tmp/cache/assets/development/sprockets/98ccb36ebbfc6f6ac684a05ad8543c01 +0 -0
  189. data/spec/dummy/tmp/cache/assets/development/sprockets/9ad5688a6dad8d54658f492eb1fa07d6 +0 -0
  190. data/spec/dummy/tmp/cache/assets/development/sprockets/9b9ee2a899dd8b3bfa592fba44ebf8d2 +0 -0
  191. data/spec/dummy/tmp/cache/assets/development/sprockets/9c48c31b831040e919db903d9edef2ab +0 -0
  192. data/spec/dummy/tmp/cache/assets/development/sprockets/9f9f72b9edf89242aada0d52dbc57635 +0 -0
  193. data/spec/dummy/tmp/cache/assets/development/sprockets/a0e14dd5894f94a561a349d40037db07 +0 -0
  194. data/spec/dummy/tmp/cache/assets/development/sprockets/a125c2261ecc9d800e450373950ea433 +0 -0
  195. data/spec/dummy/tmp/cache/assets/development/sprockets/a3999d8baf1b9ed61d91ea6bd5e42951 +0 -0
  196. data/spec/dummy/tmp/cache/assets/development/sprockets/a8b93e1f061f64547b92633c5bde6b13 +0 -0
  197. data/spec/dummy/tmp/cache/assets/development/sprockets/ad8f1428d5543a9fc4ed7a9e9526e40a +0 -0
  198. data/spec/dummy/tmp/cache/assets/development/sprockets/adae8faa21b116471ec4285998d3f3cf +0 -0
  199. data/spec/dummy/tmp/cache/assets/development/sprockets/aea01e6a7f75a01b9f61f7e0430bd61b +0 -0
  200. data/spec/dummy/tmp/cache/assets/development/sprockets/b690c630e4500da8d405b10c5d827ac9 +0 -0
  201. data/spec/dummy/tmp/cache/assets/development/sprockets/b83537e814e13cf03642ccc3d90fda13 +0 -0
  202. data/spec/dummy/tmp/cache/assets/development/sprockets/ba4f054949cb1c1bea0fd796890fcb11 +0 -0
  203. data/spec/dummy/tmp/cache/assets/development/sprockets/bccc085acd77705bf4cd104dbd5dbec3 +0 -0
  204. data/spec/dummy/tmp/cache/assets/development/sprockets/c0c44ab8b0b90fb0287ca1400731f920 +0 -0
  205. data/spec/dummy/tmp/cache/assets/development/sprockets/c1208bf8d0e9714161d8e6ae61781efc +0 -0
  206. data/spec/dummy/tmp/cache/assets/development/sprockets/c6dae51db325ad18ac445895075e66b5 +0 -0
  207. data/spec/dummy/tmp/cache/assets/development/sprockets/ca8c11b2ed33b38e8b65858a2ba66d6f +0 -0
  208. data/spec/dummy/tmp/cache/assets/development/sprockets/ce5a98586efc888dc74dff9380760c33 +0 -0
  209. data/spec/dummy/tmp/cache/assets/development/sprockets/d0e440792b09f3cc258704d7850f0652 +0 -0
  210. data/spec/dummy/tmp/cache/assets/development/sprockets/d0e6d527077e64dc87dfa25abccd4dd3 +0 -0
  211. data/spec/dummy/tmp/cache/assets/development/sprockets/d10e06dee94ddaa562f7df319407bf18 +0 -0
  212. data/spec/dummy/tmp/cache/assets/development/sprockets/d1238ae38ca7b9522d86d67ee367223e +0 -0
  213. data/spec/dummy/tmp/cache/assets/development/sprockets/d2c2fff5893ce8979ca48bab1c6f1c3a +0 -0
  214. data/spec/dummy/tmp/cache/assets/development/sprockets/e1a679a58449aa2ee72eb4341d85b5d6 +0 -0
  215. data/spec/dummy/tmp/cache/assets/development/sprockets/e8fafe37de58ddbf16ebaf5cdc988320 +0 -0
  216. data/spec/dummy/tmp/cache/assets/development/sprockets/f15276b8745ef08f03a61f6fabe0001f +0 -0
  217. data/spec/dummy/tmp/cache/assets/development/sprockets/f79e04c0583c4be5f17610f948bc7436 +0 -0
  218. data/spec/dummy/tmp/cache/assets/development/sprockets/f966462e6d5e859d5be8f52161d2f53b +0 -0
  219. data/spec/dummy/tmp/cache/assets/development/sprockets/f977be4be94ab364314f054e18c53742 +0 -0
  220. data/spec/dummy/tmp/cache/assets/test/sass/23cfae14a65dc753e1ade92b6095067a45aad26f/bootstrap.scssc +0 -0
  221. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_alerts.scssc +0 -0
  222. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_badges.scssc +0 -0
  223. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_breadcrumbs.scssc +0 -0
  224. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_button-groups.scssc +0 -0
  225. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_buttons.scssc +0 -0
  226. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_carousel.scssc +0 -0
  227. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_close.scssc +0 -0
  228. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_code.scssc +0 -0
  229. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_component-animations.scssc +0 -0
  230. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_dropdowns.scssc +0 -0
  231. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_forms.scssc +0 -0
  232. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_glyphicons.scssc +0 -0
  233. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_grid.scssc +0 -0
  234. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_input-groups.scssc +0 -0
  235. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_jumbotron.scssc +0 -0
  236. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_labels.scssc +0 -0
  237. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_list-group.scssc +0 -0
  238. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_media.scssc +0 -0
  239. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_mixins.scssc +0 -0
  240. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_modals.scssc +0 -0
  241. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_navbar.scssc +0 -0
  242. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_navs.scssc +0 -0
  243. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_normalize.scssc +0 -0
  244. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_pager.scssc +0 -0
  245. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_pagination.scssc +0 -0
  246. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_panels.scssc +0 -0
  247. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_popovers.scssc +0 -0
  248. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_print.scssc +0 -0
  249. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_progress-bars.scssc +0 -0
  250. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_responsive-utilities.scssc +0 -0
  251. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_scaffolding.scssc +0 -0
  252. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_tables.scssc +0 -0
  253. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_thumbnails.scssc +0 -0
  254. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_tooltip.scssc +0 -0
  255. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_type.scssc +0 -0
  256. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_utilities.scssc +0 -0
  257. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_variables.scssc +0 -0
  258. data/spec/dummy/tmp/cache/assets/test/sass/6cd443894d18a18028b11ff7afc2188b8e6a0c6d/_wells.scssc +0 -0
  259. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/base.sassc +0 -0
  260. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/sessions.sassc +0 -0
  261. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/sites.sassc +0 -0
  262. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/writefully.sassc +0 -0
  263. data/spec/dummy/tmp/cache/assets/test/sprockets/064b3076e29f54ea572ca43d6c5950cc +0 -0
  264. data/spec/dummy/tmp/cache/assets/test/sprockets/0d2e79f7f8c9026d7d8a7f6dc63fb4a8 +0 -0
  265. data/spec/dummy/tmp/cache/assets/test/sprockets/18eb9f12c7e8971e0e2fad29c85a8b8e +0 -0
  266. data/spec/dummy/tmp/cache/assets/test/sprockets/1977498f5af78beca26942a7c812b294 +0 -0
  267. data/spec/dummy/tmp/cache/assets/test/sprockets/2d27da60cfa2f1952c3aadd169ea2570 +0 -0
  268. data/spec/dummy/tmp/cache/assets/test/sprockets/2e33b23d27ad5b8771d09ed8a1435cf6 +0 -0
  269. data/spec/dummy/tmp/cache/assets/test/sprockets/3063f229c5edc0e8a3d82d7bf78024de +0 -0
  270. data/spec/dummy/tmp/cache/assets/test/sprockets/31c84f37a0c92c38be6459f19997c981 +0 -0
  271. data/spec/dummy/tmp/cache/assets/test/sprockets/3df2d5c2f4f6b6d502c017346b915051 +0 -0
  272. data/spec/dummy/tmp/cache/assets/test/sprockets/4aab863b927c65a4b9e70c43e4e6d482 +0 -0
  273. data/spec/dummy/tmp/cache/assets/test/sprockets/4c0271d24537b8a24979e07bbd75956c +0 -0
  274. data/spec/dummy/tmp/cache/assets/test/sprockets/4c16c5c88ae074d893e1de2ad787b031 +0 -0
  275. data/spec/dummy/tmp/cache/assets/test/sprockets/63f349e6a646ae0252d46e1816064e0c +0 -0
  276. data/spec/dummy/tmp/cache/assets/test/sprockets/67ae1c504593279ebd6da7b6fdbe99b7 +0 -0
  277. data/spec/dummy/tmp/cache/assets/test/sprockets/68e61e8d5ac667de89a4bf1e732cde0a +0 -0
  278. data/spec/dummy/tmp/cache/assets/test/sprockets/6cf5095a6f2a3e346267010d81431898 +0 -0
  279. data/spec/dummy/tmp/cache/assets/test/sprockets/71ea75f9945cdb543e0dc44527fcd926 +0 -0
  280. data/spec/dummy/tmp/cache/assets/test/sprockets/74d56087624f43b73234c3691a21203b +0 -0
  281. data/spec/dummy/tmp/cache/assets/test/sprockets/76598a5aebf24a1b763f5b10ae223c15 +0 -0
  282. data/spec/dummy/tmp/cache/assets/test/sprockets/7af8770b019b471931e4f6cb86027307 +0 -0
  283. data/spec/dummy/tmp/cache/assets/test/sprockets/7ff072db2442371da6ee49c9b279efdc +0 -0
  284. data/spec/dummy/tmp/cache/assets/test/sprockets/82b92bb7c88523dc617b3c0c877aeade +0 -0
  285. data/spec/dummy/tmp/cache/assets/test/sprockets/8789652d56b500257c05b6b3370096a2 +0 -0
  286. data/spec/dummy/tmp/cache/assets/test/sprockets/95703f30550e80a229dd0ec4a6ddc85c +0 -0
  287. data/spec/dummy/tmp/cache/assets/test/sprockets/98ccb36ebbfc6f6ac684a05ad8543c01 +0 -0
  288. data/spec/dummy/tmp/cache/assets/test/sprockets/9ad5688a6dad8d54658f492eb1fa07d6 +0 -0
  289. data/spec/dummy/tmp/cache/assets/test/sprockets/9b9ee2a899dd8b3bfa592fba44ebf8d2 +0 -0
  290. data/spec/dummy/tmp/cache/assets/test/sprockets/9c48c31b831040e919db903d9edef2ab +0 -0
  291. data/spec/dummy/tmp/cache/assets/test/sprockets/9f9f72b9edf89242aada0d52dbc57635 +0 -0
  292. data/spec/dummy/tmp/cache/assets/test/sprockets/a2398b853766dfb3e66e6709e65e0fe8 +0 -0
  293. data/spec/dummy/tmp/cache/assets/test/sprockets/a8b93e1f061f64547b92633c5bde6b13 +0 -0
  294. data/spec/dummy/tmp/cache/assets/test/sprockets/adae8faa21b116471ec4285998d3f3cf +0 -0
  295. data/spec/dummy/tmp/cache/assets/test/sprockets/b776b64154999147a7219e7ab2ec18c5 +0 -0
  296. data/spec/dummy/tmp/cache/assets/test/sprockets/b83537e814e13cf03642ccc3d90fda13 +0 -0
  297. data/spec/dummy/tmp/cache/assets/test/sprockets/bccc085acd77705bf4cd104dbd5dbec3 +0 -0
  298. data/spec/dummy/tmp/cache/assets/test/sprockets/c1208bf8d0e9714161d8e6ae61781efc +0 -0
  299. data/spec/dummy/tmp/cache/assets/test/sprockets/d0e6d527077e64dc87dfa25abccd4dd3 +0 -0
  300. data/spec/dummy/tmp/cache/assets/test/sprockets/d10e06dee94ddaa562f7df319407bf18 +0 -0
  301. data/spec/dummy/tmp/cache/assets/test/sprockets/d1238ae38ca7b9522d86d67ee367223e +0 -0
  302. data/spec/dummy/tmp/cache/assets/test/sprockets/d2c2fff5893ce8979ca48bab1c6f1c3a +0 -0
  303. data/spec/dummy/tmp/cache/assets/test/sprockets/d743017d31a484ac9254192a452e4619 +0 -0
  304. data/spec/dummy/tmp/cache/assets/test/sprockets/e1c18951e718ae5b0d527ddf0099a3b0 +0 -0
  305. data/spec/dummy/tmp/cache/assets/test/sprockets/e1eb88bc099cda2e70c0a0ebc1e99665 +0 -0
  306. data/spec/dummy/tmp/cache/assets/test/sprockets/e8fafe37de58ddbf16ebaf5cdc988320 +0 -0
  307. data/spec/features/writefully/sites_feature_spec.rb +27 -0
  308. data/spec/fixtures/writefully/authorships.yml +11 -0
  309. data/spec/fixtures/writefully/github_hook_test.json +4 -0
  310. data/spec/fixtures/writefully/github_member_add_hook.json +127 -0
  311. data/spec/fixtures/writefully/github_push_hook.json +94 -0
  312. data/spec/fixtures/writefully/posts.yml +14 -0
  313. data/spec/fixtures/writefully/sites.yml +10 -0
  314. data/spec/lib/writefully/asset_spec.rb +22 -0
  315. data/spec/lib/writefully/content_spec.rb +22 -0
  316. data/spec/lib/writefully/indices_spec.rb +17 -0
  317. data/spec/lib/writefully/postable_spec.rb +27 -0
  318. data/spec/lib/writefully/source_spec.rb +23 -0
  319. data/spec/lib/writefully/taxon_spec.rb +27 -0
  320. data/spec/lib/writefully/tools/dispatcher_spec.rb +75 -0
  321. data/spec/lib/writefully/tools/hammer_spec.rb +78 -0
  322. data/spec/lib/writefully/tools/initializer_spec.rb +18 -0
  323. data/spec/lib/writefully/tools/pencil_spec.rb +72 -0
  324. data/spec/lib/writefully/tools/synchronizer_spec.rb +17 -0
  325. data/spec/lib/writefully/workers/handyman_spec.rb +50 -0
  326. data/spec/lib/writefully/workers/journalist_spec.rb +30 -0
  327. data/spec/spec_helper.rb +56 -0
  328. metadata +903 -0
@@ -0,0 +1,84 @@
1
+ require 'listen'
2
+ require 'logger'
3
+
4
+ require 'celluloid'
5
+
6
+ require 'active_record'
7
+ require 'writefully'
8
+ require 'redis'
9
+ require 'redis-namespace'
10
+
11
+ %w(tag post site tagging authorship).each do |model|
12
+ require File.dirname(__FILE__) + "/../../app/models/writefully/#{model}"
13
+ end
14
+
15
+ Writefully::Source.to_load.each do |model|
16
+ require File.join(Writefully.options[:app_directory], 'app', 'models', model)
17
+ end
18
+
19
+ require 'github_api'
20
+
21
+ require 'writefully/tools'
22
+ require 'writefully/workers'
23
+ require 'writefully/news_agency'
24
+
25
+ module Writefully
26
+ Process = Struct.new(:config) do
27
+
28
+ def listen
29
+ log_start
30
+ connect_to_database!
31
+ start_news_agency!
32
+ start_dispatcher!
33
+ boot_listener!
34
+ end
35
+
36
+ # connect to db
37
+ def connect_to_database!
38
+ ActiveRecord::Base.establish_connection(Writefully.db_config)
39
+ end
40
+
41
+ # Dispatcher monitors job queue and throws job at workers
42
+ def start_dispatcher!
43
+ Tools::Dispatcher.supervise_as :dispatch
44
+ end
45
+
46
+ # Supervises the actors that manage all the work with converting content
47
+ # and sorting it into its place
48
+ def start_news_agency!
49
+ NewsAgency.run!
50
+ end
51
+
52
+ def log_start
53
+ Writefully.logger.info("This is doctor Frasier Crane. I'm listening...")
54
+ end
55
+
56
+ def process_message
57
+ Proc.new do |modified, added, removed|
58
+ queue_jobs(Indices.build_from(modified), :write)
59
+ queue_jobs(Indices.build_from(added), :write)
60
+ queue_jobs(Indices.build_from(removed), :remove)
61
+ end
62
+ end
63
+
64
+ # this listener listens to the specified content folder
65
+ # queues the changes detected into the job queue
66
+ def boot_listener!
67
+ listener = Listen.to config[:content], wait_for_delay: 2, &process_message
68
+ listener.start
69
+ while listener.listen?
70
+ sleep 0.5
71
+ end
72
+ end
73
+
74
+ JOBS = {
75
+ write: -> (index) { Writefully.add_job :journalists, index.merge({task: :publish}) },
76
+ remove: -> (index) { Wrotefully.add_job :journalists, index.merge({task: :remove}) }
77
+ }
78
+
79
+ def queue_jobs indices, action
80
+ indices.uniq.each { |index| JOBS[action].call(index) if Source.valid_resources.include?(index[:resource]) }
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,52 @@
1
+ require 'base64'
2
+
3
+ module Writefully
4
+ module Source
5
+
6
+ class << self
7
+ def content_path
8
+ Writefully.options[:content]
9
+ end
10
+
11
+ def models_path
12
+ File.join(Writefully.options[:app_directory], 'app', 'models')
13
+ end
14
+
15
+ def sample_content file
16
+ open(File.dirname(__FILE__) + "/../sample/#{file}").read
17
+ end
18
+
19
+ def sample_content_paths
20
+ valid_resources.map do |resource|
21
+ ["#{resource}/1-change-me/README.md",
22
+ "#{resource}/1-change-me/meta.yml",
23
+ "#{resource}/1-change-me/assets/writefully.png"]
24
+ end.flatten
25
+ end
26
+
27
+ def sample_content_properties file
28
+ {
29
+ path: file,
30
+ content: sample_content(file),
31
+ message: "added sample #{file}"
32
+ }
33
+ end
34
+
35
+ def valid_resources
36
+ skim_for(::Regexp.new('Writefully::Post')).map { |r| r.pluralize }
37
+ end
38
+
39
+ def to_load
40
+ skim_for ::Regexp.new('Writefully')
41
+ end
42
+
43
+ def skim_for matcher
44
+ Dir.chdir(models_path) do
45
+ Dir.glob('*').select do |file|
46
+ open(File.join(models_path, file)).read.strip.match(matcher) if File.file?(file)
47
+ end.collect { |file| file.split('.')[0] }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,33 @@
1
+ module Writefully
2
+ module Storage
3
+ class << self
4
+ def directory
5
+ @directory ||= connection.directories.get(Writefully.options[:storage_folder])
6
+ end
7
+
8
+ def store_file(path, body)
9
+ directory.files.create({
10
+ key: path,
11
+ body: body,
12
+ public: true
13
+ })
14
+ end
15
+
16
+ def endpoint
17
+ provider_endpoints[Writefully.options[:storage_provider].downcase.to_sym]
18
+ end
19
+
20
+ def provider_endpoints
21
+ { aws: "https://#{Writefully.options[:storage_folder]}.s3.amazonaws.com"}
22
+ end
23
+
24
+ def connection
25
+ @connection ||= Fog::Storage.new({
26
+ provider: Writefully.options[:storage_provider],
27
+ aws_access_key_id: Writefully.options[:storage_key],
28
+ aws_secret_access_key: Writefully.options[:storage_secret]
29
+ })
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module Writefully
2
+ Taxon = Struct.new(:incoming, :existing, :type) do
3
+ def non_existing
4
+ get_difference.map { |token| Tag.new(build_attributes(token)) }
5
+ end
6
+
7
+ def selector
8
+ @selector ||= type.underscore.to_sym
9
+ end
10
+
11
+ def get_difference
12
+ (parameterized(incoming) - parameterized(existing)).map { |t| t.titleize }
13
+ end
14
+
15
+ def type_attribute
16
+ selector == :'writefully/tag' ? { type: nil } : { type: selector.to_s.classify }
17
+ end
18
+
19
+ def build_attributes token
20
+ type_attribute
21
+ .merge({ name: token, slug: token.parameterize })
22
+ end
23
+
24
+ def parameterized items
25
+ items.map { |t| t.parameterize }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ module Writefully
2
+ module Tools
3
+ class Dispatcher
4
+ include Celluloid
5
+
6
+ attr_reader :job
7
+
8
+ def initialize
9
+ every 1.second do
10
+ async.heartbeat
11
+ end
12
+ end
13
+
14
+ def get_job_data
15
+ Writefully.redis.with { |c| c.spop 'jobs' }
16
+ end
17
+
18
+ def heartbeat
19
+ @job = Marshal.load(get_job_data)
20
+ run_job if is_job?
21
+ end
22
+
23
+ def run_job
24
+ if is_retry? and retry_valid? then retry_job
25
+ elsif is_job? and job_valid? then dispatch
26
+ else mark_as_failed end
27
+ end
28
+
29
+ def dispatch
30
+ Celluloid::Actor[job[:worker]].perform(job[:message])
31
+ end
32
+
33
+ def retry_job
34
+ after((job[:tries] * job[:tries]).seconds) { dispatch(job) }
35
+ end
36
+
37
+ def mark_as_failed
38
+ Writefully.redis.with { |c| c.sadd 'failed', Marshal.dump(job) }
39
+ end
40
+
41
+ def is_job?
42
+ job.has_key?(:worker) and job.has_key?(:message)
43
+ end
44
+
45
+ def is_retry?
46
+ is_job? and job.has_key?(:tries)
47
+ end
48
+
49
+ def job_valid?
50
+ job.keys.count == 2
51
+ end
52
+
53
+ def retry_valid?
54
+ job[:tries] <= 5
55
+ end
56
+
57
+ end
58
+ end
59
+ end
File without changes
@@ -0,0 +1,41 @@
1
+ module Writefully
2
+ module Tools
3
+ class Hammer
4
+ include Celluloid
5
+
6
+ attr_reader :api, :message
7
+
8
+ def initialize message
9
+ @message = message
10
+ @api = Github.new oauth_token: message[:auth_token]
11
+ end
12
+
13
+ def hook_config
14
+ { name: 'web',
15
+ events: ["push", "member"],
16
+ active: true,
17
+ config: {
18
+ url: "#{message[:domain]}/writefully/hook",
19
+ content_type: 'json',
20
+ secret: Writefully.options[:hook_secret]
21
+ }
22
+ }
23
+ end
24
+
25
+ def forge
26
+ Writefully.logger.info "Forging #{message[:site_slug]}"
27
+ api.repos.create name: message[:site_slug], auto_init: true
28
+ rescue Exception => e
29
+ raise e
30
+ end
31
+
32
+ def add_hook_for repo_name
33
+ Writefully.logger.info "Adding hook for #{message[:site_slug]}"
34
+ api.repos.hooks.create message[:user_name], repo_name, hook_config
35
+ rescue Exception => e
36
+ raise e
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ module Writefully
2
+ module Tools
3
+ class Initializer
4
+ include Celluloid
5
+
6
+ INITIALIZE_SCRIPT = File.dirname(__FILE__) + "/../../../scripts/initialize.sh"
7
+
8
+ attr_reader :message, :api
9
+
10
+ def initialize message
11
+ @message = message
12
+ @api = Github.new oauth_token: message[:auth_token]
13
+ end
14
+
15
+ def add_sample_content
16
+ Writefully.logger.info "Adding Sample content #{message[:site_slug]}"
17
+ Source.sample_content_paths.map do |path|
18
+ api.repos.contents.create message[:user_name],
19
+ message[:site_slug],
20
+ path, sample_content_for(path.split('/').last)
21
+ end
22
+ end
23
+
24
+ def build_content_folder
25
+ Writefully.logger.info "Creating content folder #{message[:site_slug]}"
26
+ system(content_folder_setup_command)
27
+ end
28
+
29
+ def content_folder_setup_command
30
+ ['bash', INITIALIZE_SCRIPT, Writefully.options[:content], message[:site_slug], message[:ssh_url]].join(' ')
31
+ end
32
+
33
+ def sample_content_for file_name
34
+ Source.sample_content_properties(file_name)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,71 @@
1
+ module Writefully
2
+ module Tools
3
+ class Pencil
4
+ include Celluloid
5
+
6
+ attr_reader :resource, :content, :asset, :index, :site_id, :asset
7
+
8
+ class ContentModelNotFound < StandardError; end
9
+ class SomeAssetsNotUploaded < StandardError; end
10
+
11
+ def initialize(index)
12
+ @site_id = Site.where(slug: index[:site]).first.id
13
+ @index = index
14
+ @content = Content.new(index)
15
+ @asset = Asset.new(index)
16
+ end
17
+
18
+ def perform
19
+ assets_uploaded = upload_assets.map(&:value).compact
20
+ written_to_db = future.write if can_update_db?(assets_uploaded)
21
+ terminate if written_to_db.value
22
+ end
23
+
24
+ def computed_attributes
25
+ content.meta.merge({
26
+ "content" => asset.convert_for(content.body),
27
+ "details" => asset.convert_for(content.details)
28
+ })
29
+ end
30
+
31
+ def write
32
+ compute_type.by_site(site_id).where(slug: content.slug)
33
+ .first_or_initialize
34
+ .update_attributes(computed_attributes)
35
+ ensure
36
+ ::ActiveRecord::Base.clear_active_connections! if defined?(::ActiveRecord)
37
+ end
38
+
39
+ def upload_assets
40
+ asset.names.map do |name|
41
+ Celluloid::Actor[:pigeons].future.upload(asset.endpoint, asset.path, name)
42
+ end
43
+ end
44
+
45
+ def can_update_db? uploaded
46
+ if asset.names.count == uploaded.count
47
+ true
48
+ else
49
+ raise SomeAssetsNotUploaded, "Some assets was not uploaded"
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def compute_type
56
+ index[:resource].classify.constantize
57
+ rescue NameError
58
+ fallback_type
59
+ end
60
+
61
+ def fallback_type
62
+ if index[:resource] == "posts"
63
+ "Writefully::Post".constantize
64
+ else
65
+ raise ContentModelNotFound, "Model #{index[:resource].classify} was not found"
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ module Writefully
2
+ module Tools
3
+ class Pigeon
4
+ include Celluloid
5
+
6
+ def upload endpoint, path, name
7
+ file = File.open(File.join(path, name))
8
+ Writefully::Storage.store_file(File.join(endpoint, name), file)
9
+ true
10
+ rescue Exception => e
11
+ nil
12
+ end
13
+
14
+ def remove endpoint, path, name
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Writefully
2
+ module Tools
3
+ class Synchronizer
4
+ include Celluloid
5
+
6
+ SYNC_SCRIPT = File.dirname(__FILE__) + "/../../../scripts/sync.sh"
7
+
8
+ attr_reader :message
9
+
10
+ def initialize message
11
+ @message = message
12
+ end
13
+
14
+ def sync
15
+ Writefully.logger.info "Synchronizing #{message[:site_slug]}"
16
+ system(sync_command)
17
+ end
18
+
19
+ def sync_command
20
+ ['bash', SYNC_SCRIPT, Writefully.options[:content], message[:site_slug]].join(' ')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ module Writefully
2
+ module Tools
3
+
4
+ end
5
+ end
6
+
7
+ require 'writefully/tools/eraser'
8
+ require 'writefully/tools/pencil'
9
+ require 'writefully/tools/pigeon'
10
+ require 'writefully/tools/hammer'
11
+ require 'writefully/tools/dispatcher'
12
+ require 'writefully/tools/initializer'
13
+ require 'writefully/tools/synchronizer'
@@ -0,0 +1,3 @@
1
+ module Writefully
2
+ VERSION = "0.3.6"
3
+ end
@@ -0,0 +1,25 @@
1
+ module Writefully
2
+ module Workers
3
+ class BaseWorker
4
+ include Celluloid
5
+
6
+ trap_exit :actor_died
7
+
8
+ attr_reader :message
9
+
10
+ def perform(message)
11
+ @message = message
12
+ self.__send__ message[:task]
13
+ end
14
+
15
+ def close_db_connection!
16
+ ::ActiveRecord::Base.clear_active_connections! if defined?(::ActiveRecord)
17
+ end
18
+
19
+ def actor_died(actor, reason)
20
+ Writefully.logger.error "An error occured #{reason.message}"
21
+ on_death(actor, reason) if self.respond_to?(:on_death)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ module Writefully
2
+ module Workers
3
+ class Handyman < BaseWorker
4
+ include Helpers::Handyman::Builder
5
+
6
+ attr_reader :site
7
+
8
+ def build
9
+ @site = Site.where(id: message[:site_id]).first
10
+ @hammer = Tools::Hammer.new_link(message.merge({ domain: site.domain }))
11
+ # create the repository
12
+ repo = @hammer.future.forge
13
+
14
+ # add sample content
15
+ @initializer = Tools::Initializer.new_link(message.merge({ ssh_url: repo.value.ssh_url }))
16
+ initialize_sample_content
17
+
18
+ # add web hook
19
+ hook = @hammer.future.add_hook_for(repo.value.name)
20
+ complete_site_setup(repo.value, hook.value)
21
+ ensure
22
+ @hammer.terminate
23
+ @initializer.terminate
24
+ close_db_connection!
25
+ end
26
+
27
+ def synchronize
28
+ @synchronizer = Tools::Synchronizer.new_link(message)
29
+ synced = @synchronizer.future.sync
30
+ Writefully.logger.info "Synchronized #{message[:site_slug]}" if synced.value
31
+ ensure
32
+ @synchronizer.terminate
33
+ end
34
+
35
+ def on_death actor, reason
36
+ if site
37
+ Writefully.redis.with { |c| s.sadd "site:#{site.id}:errors", reason.message }
38
+ site.update_attributes(processing: false, healty: false)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ module Writefully::Workers::Helpers::Handyman
2
+ module Builder
3
+ extend ActiveSupport::Concern
4
+
5
+ def complete_site_setup repo, hook
6
+ site_repository = { name: repo.name, id: repo.id, hook_id: hook.id }
7
+ site.update_attributes(repository: site_repository, processing: false, healthy: true)
8
+ end
9
+
10
+ def initialize_sample_content
11
+ added_sample_content = @initializer.add_sample_content
12
+ created_directory = @initializer.build_content_folder
13
+
14
+ [added_sample_content, created_directory]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ require 'active_support/concern'
2
+
3
+ module Writefully::Workers
4
+ module Helpers
5
+ end
6
+ end
7
+
8
+ require 'writefully/workers/helpers/handyman/builder'
@@ -0,0 +1,23 @@
1
+ module Writefully
2
+ module Workers
3
+ class Journalist < BaseWorker
4
+ def publish
5
+ Writefully.logger.info "Publishing #{message[:resource]} #{message[:slug]}"
6
+ pencil = Tools::Pencil.new_link(message)
7
+ pencil.perform
8
+ end
9
+
10
+ def remove
11
+ Writefully.logger.info "Removing #{message[:resource]} #{message[:slug]}"
12
+ end
13
+
14
+ def message_with_tries
15
+ message.merge({ tries: (message[:tries] || 1) + 1 })
16
+ end
17
+
18
+ def on_death actor, reason
19
+ Writefully.add_job :journalists, message_with_tries
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ module Writefully
2
+ module Workers
3
+
4
+ end
5
+ end
6
+ require 'writefully/workers/helpers'
7
+ require 'writefully/workers/base_worker'
8
+ require 'writefully/workers/journalist'
9
+ require 'writefully/workers/handyman'
@@ -0,0 +1,7 @@
1
+
2
+ module Writefully
3
+ module Helpers
4
+
5
+ end
6
+ end
7
+