writefully 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c578de39737faf4bcb838175f4ac604262b874e7
4
+ data.tar.gz: d6ddeb25fcf43d553f1b992ed6b43aa93c2499a7
5
+ SHA512:
6
+ metadata.gz: 6ed18f2b874486eb6c055b430a2bfd5489be4ce36a7bc567382616840bb3fe4dea85bba93214c00cb26990f89997b2dbbfbecbe536601ec78376e570f5be6a90
7
+ data.tar.gz: 8b28483bbc1141ec538af5e9196b66844a70bde65a3015fe8f1c3ac4dd817482f24ea71f29f15a967dde120808bf6dd04a6ceb7661a7896492b4346611bdd76e
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Writefully
2
+
3
+ [![Build Status](https://travis-ci.org/codemy/writefully.svg?branch=master)](https://travis-ci.org/codemy/writefully) [![Coverage Status](https://coveralls.io/repos/codemy/writefully/badge.png?branch=master)](https://coveralls.io/r/codemy/writefully?branch=master) [![Code Climate](https://codeclimate.com/github/codemy/writefully.png)](https://codeclimate.com/github/codemy/writefully)
4
+
5
+ Allows developers who love to write to publish easily
6
+
7
+ ## Manifesto
8
+
9
+ + Writefully Core
10
+ + Separate lightweight process that manages all the work
11
+ + Main rails process should be able to communicate with Writefully via Redis queue
12
+ + When a site is created it sets up a repository / hooks with sample content
13
+ + Manages content taxonomy via Tags / Taggings
14
+ + Easily Extendable from main rails app
15
+ + Content Localization
16
+ + Backend Interface for managing sites
17
+ + Receive WebHook from github and updates site
18
+ + Turns repository collaborators into authors
19
+ + Converts local based images into content provider URL
20
+ + S3 / Cloudfront
21
+ + Akamai
22
+ + Cloudfiles
23
+ + etc...
24
+
25
+ + Writefully Desktop App
26
+ + Probably going to use [node-webkit](https://github.com/rogerwang/node-webkit)
27
+ + More details to com
28
+
29
+ + Writefully mobile app
30
+ + Probably going to use [Framework7](http://www.idangero.us/framework7/)
31
+ + More details to come
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9
+
10
+ load 'rails/tasks/engine.rake'
11
+
12
+ Bundler::GemHelper.install_tasks
13
+
14
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
15
+
16
+ require 'rspec/core'
17
+ require 'rspec/core/rake_task'
18
+
19
+ desc "Run all specs in spec directory (excluding plugin specs)"
20
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
21
+
22
+ task :default => :spec
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,6 @@
1
+ # this file will boot up your transponder app
2
+
3
+ # presenters
4
+
5
+
6
+ # services
@@ -0,0 +1,28 @@
1
+ Application.services_manifest = ->
2
+ # fill in your manifest here
3
+ # example:
4
+ # if you want to trigger a service on your entire app
5
+ # $('body').trigger 'application:services:service_name'
6
+ #
7
+ # If you want a more fine grained control for
8
+ # different pages you can add a class to your body
9
+ # in your views/layouts/application.html.erb
10
+ # on your body tag you can do something like this
11
+ #
12
+ # <body class="[controller_name] [action_name]">
13
+ #
14
+ # You now have a more fine grained control in
15
+ # your manifest file
16
+ # $('body.posts.show').trigger 'application:services:service_name'
17
+ #
18
+ # if you need to trigger the same services on multiple pages
19
+ # $('body.posts.show,
20
+ # body.dashboard.show,
21
+ # body.photos.index').trigger 'application:services:service_name'
22
+ #
23
+
24
+ Application.run_ready = ->
25
+ Application.services_manifest()
26
+
27
+ $(document).ready Application.run_ready
28
+ $(document).on 'page:load', Application.run_ready
@@ -0,0 +1,4 @@
1
+ window.Application =
2
+ Helpers: {}
3
+ Services: {}
4
+ Presenters: {}
@@ -0,0 +1,6 @@
1
+ #= require ./initializers/setup
2
+ #= require_tree ./services
3
+ #= require_tree ./helpers
4
+ #= require_tree ./presenters
5
+ #= require ./initializers/boot
6
+ #= require ./initializers/manifest
@@ -0,0 +1,8 @@
1
+ # this is where you require all the files
2
+ #= require jquery
3
+ #= require jquery_ujs
4
+ #= require turbolinks
5
+ #= require transponder
6
+
7
+ # this part boots up the transponder module
8
+ #= require writefully/writefully/loader
@@ -0,0 +1,23 @@
1
+ .status-warning
2
+ color: $brand-warning
3
+
4
+ .status-success
5
+ color: $brand-success
6
+
7
+ .status-danger
8
+ color: $brand-danger
9
+
10
+ a
11
+ color: #999
12
+
13
+ a:hover
14
+ text-decoration: none
15
+ color: #333
16
+
17
+ div.container
18
+ > h1, > h2, > h3, > h4, > h5, > h6
19
+ margin-bottom: 20px
20
+
21
+ .panel
22
+ h1, h2, h3, h4, h5, h6
23
+ margin: 0px !important
@@ -0,0 +1,9 @@
1
+ body.writefully.sessions.new
2
+ div#new-session
3
+ margin-top: 30px
4
+ h1
5
+ font-weight: 100
6
+ text-align: center
7
+
8
+ p.setup-help
9
+ padding: 10px
@@ -0,0 +1,33 @@
1
+ body.writefully.sites, body.writefully.posts.index
2
+ h1, h2, h3, h4, h5, h6
3
+ font-weight: 100
4
+
5
+ div.post.media
6
+ border-top: 1px solid #eee
7
+ padding-top: 15px
8
+
9
+ &:first-child
10
+ border-top: 0px
11
+ padding-top: 0px
12
+
13
+ ul.nav-tabs
14
+ margin-bottom: 20px
15
+
16
+ form#new_site
17
+ margin-top: 40px
18
+ p.form-info
19
+ padding: 10px
20
+
21
+
22
+ div.site.media
23
+ border-top: 1px solid #eee
24
+ padding-top: 15px
25
+ &:first-child
26
+ border-top: 0px
27
+ padding-top: 0px
28
+ div.status
29
+ margin-top: 5px
30
+ vertical-align: middle
31
+ font-size: 16px
32
+ h2
33
+ font-weight: 200
@@ -0,0 +1,4 @@
1
+ @import "bootstrap"
2
+ @import "base"
3
+ @import "sites"
4
+ @import "sessions"
@@ -0,0 +1,28 @@
1
+ module Writefully
2
+ class ApplicationController < ActionController::Base
3
+
4
+ def authenticate_wf_authorship!
5
+ redirect_to signin_path unless wf_authorship_signed_in?
6
+ end
7
+
8
+ def wf_authorship_signed_in?
9
+ current_wf_authorship.present?
10
+ end
11
+
12
+ def set_flash(type, object: nil)
13
+ flash[:namespace] = 'writefully'
14
+ flash[:from] = action_name
15
+ flash[:type] = type
16
+ flash[:object_type] = object.class.name
17
+ flash[:object_id] = object.id
18
+ end
19
+
20
+ private
21
+
22
+ helper_method :current_wf_authorship
23
+
24
+ def current_wf_authorship
25
+ @current_wf_authorship ||= Authorship.where(id: session[:wf_authorship_id]).first if session[:wf_authorship_id]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class AuthorshipsController < ApplicationController
5
+ before_filter :authenticate_wf_owner!
6
+
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class HooksController < ApplicationController
5
+ respond_to :json
6
+ before_filter :check_signature
7
+
8
+ HMAC_DIGEST = OpenSSL::Digest::Digest.new('sha1')
9
+
10
+ class InvalidSignature < StandardError; end
11
+
12
+ def create
13
+ self.__send__ request.headers["X-Github-Event"].to_sym
14
+ head :ok
15
+ end
16
+
17
+ def push
18
+ Writefully.add_job :handyman, { task: :synchronize,
19
+ site_slug: body.repository.name } if branch_match?
20
+ end
21
+
22
+ def member
23
+ authorship = Authorship.find_by_uid(body.member.id)
24
+ unless authorship
25
+ Authorship.create_from_data(body.member)
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def branch_match?
32
+ Site.where(slug: body.repository.name).first.branch == body.ref.split('/').last
33
+ end
34
+
35
+ def body
36
+ @_body ||= Hashie::Mash.new(JSON.parse(request.body.read))
37
+ end
38
+
39
+ def check_signature
40
+ unless signature == request.headers["X-Hub-Signature"]
41
+ raise InvalidSignature, "Invalid signature"
42
+ end
43
+ end
44
+
45
+ def signature
46
+ 'sha1=' + OpenSSL::HMAC.hexdigest(HMAC_DIGEST,
47
+ Writefully.options[:hook_secret],
48
+ request.body.read)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class PostsController < ApplicationController
5
+ def index
6
+ @site = get_site
7
+ @posts = @site.posts
8
+ end
9
+
10
+ def show
11
+ @site = get_site
12
+ @post = @site.posts.friendly.find(params[:id])
13
+ end
14
+
15
+ protected
16
+
17
+ def get_site
18
+ current_wf_authorship.owned_sites.friendly.find(params[:site_id])
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class SessionsController < ApplicationController
5
+ def new
6
+ @github_app = Writefully.github_app
7
+ end
8
+
9
+ def create
10
+ @auth = Writefully.github_app.get_token(params[:code])
11
+ @github = Github.new oauth_token: @auth.token
12
+ @github_user = @github.users.get
13
+ @owner = find_or_create_owner
14
+
15
+ refresh_token
16
+ session[:wf_authorship_id] = @owner.id
17
+ redirect_to root_path, notice: 'signed_in'
18
+ end
19
+
20
+ def destroy
21
+ session[:wf_authorship_id] = nil
22
+ redirect_to root_path, notice: 'signed_out'
23
+ end
24
+
25
+ protected
26
+
27
+ def refresh_token
28
+ @owner.update_attributes(data: @owner.data.merge({ auth_token: @auth.token }))
29
+ end
30
+
31
+ def find_or_create_owner
32
+ find_owner || create_owner
33
+ end
34
+
35
+ def find_owner
36
+ Authorship.find_by_uid(@github_user.id)
37
+ end
38
+
39
+ def create_owner
40
+ if Authorship.count == 0
41
+ Authorship.create_from_data(@github_user)
42
+ else
43
+ return redirect_to root_path, notice: 'owner_exists'
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class SitesController < ApplicationController
5
+ before_filter :authenticate_wf_authorship!
6
+
7
+ VALID_TABS = %w(processing errors)
8
+
9
+ def index
10
+ @sites = current_wf_authorship.owned_sites
11
+ redirect_to new_site_path if @sites.empty?
12
+ end
13
+
14
+ def show
15
+ @site = get_site
16
+ if params[:tab].nil? or not tab_valid?
17
+ redirect_to site_posts_path(@site)
18
+ end
19
+ end
20
+
21
+ def new
22
+ @site = current_wf_authorship.owned_sites.build
23
+ end
24
+
25
+ def edit
26
+ @site = get_site
27
+ end
28
+
29
+ def create
30
+ @site = current_wf_authorship.owned_sites.build(site_params)
31
+ if @site.save
32
+ set_flash :success, object: @site
33
+ redirect_to sites_path
34
+ end
35
+ end
36
+
37
+ protected
38
+
39
+ def tab_valid?
40
+ VALID_TABS.include?(params[:tab])
41
+ end
42
+
43
+ def get_site
44
+ current_wf_authorship.owned_sites.friendly.find(params[:id])
45
+ end
46
+
47
+ def site_params
48
+ params.require(:site).permit(:name, :domain)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ module Writefully
2
+ module ApplicationHelper
3
+ def path_active?(path)
4
+ request.path == path ? 'active' : nil
5
+ end
6
+
7
+ def link_icon(icon)
8
+ content_tag :span, nil,class: "glyphicon glyphicon-#{icon}" if icon
9
+ end
10
+
11
+ def activeable_link_to(type, name, path, options = {})
12
+ render 'activeable_link_to', type: type, name: name, path: path, options: options
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ module Writefully
2
+ module FlashHelper
3
+ def render_flash
4
+ render 'flash' if can_flash?
5
+ end
6
+
7
+ def can_flash?
8
+ flash.keys.sort == [:from, :object_id, :object_type, :type] and \
9
+ flash.to_hash.values.compact.count == flash_values_count
10
+ end
11
+
12
+ def flash_values_count
13
+ action_name == "create" ? 3 : flash.keys.count
14
+ end
15
+
16
+ def flash_object
17
+ flash[:object_type].classify.constantize.where(id: flash[:object_id]).first
18
+ end
19
+
20
+ def flash_path
21
+ File.join((flash[:namespace] || nil), controller_name, 'flash', flash[:from].to_s, flash[:type].to_s)
22
+ end
23
+
24
+ def flash_color
25
+ { success: 'alert-success',
26
+ error: 'alert-danger',
27
+ notice: 'alert-info',
28
+ warn: 'alert-warning' }[flash[:type]]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ module Writefully
2
+ module PostsHelper
3
+ def publish_tag post
4
+ partial = post.published_at.present? ? 'published' : 'not_published'
5
+ 'writefully/posts/' + partial
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ module Writefully
2
+ module SitesHelper
3
+
4
+ STATE_PARTIAL = {
5
+ true => 'yes',
6
+ false => 'no'
7
+ }
8
+
9
+ def processing_partial site
10
+ 'writefully/sites/processing/' + STATE_PARTIAL[site.processing]
11
+ end
12
+
13
+ def healthy_partial site
14
+ 'writefully/sites/healthy/' + STATE_PARTIAL[site.healthy]
15
+ end
16
+
17
+ def site_tab(tab)
18
+ tab.present? ? tab : 'posts'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module Writefully
2
+ class Authorship < ActiveRecord::Base
3
+ belongs_to :user
4
+
5
+ has_many :posts
6
+ has_many :owned_sites, class_name: "Writefully::Site", foreign_key: :owner_id
7
+
8
+ store_accessor :data, :name, :email, :uid, :user_name, :auth_token
9
+
10
+ def to_s
11
+ data["name"] || data["login"] || data["email"] || data["uid"]
12
+ end
13
+
14
+ def self.find_by_uid(uid)
15
+ where("data -> 'uid' = ?", uid.to_s).first
16
+ end
17
+
18
+ def select_role
19
+ Authorship.count == 0 ? "super_admin" : "collaborator"
20
+ end
21
+
22
+ def self.create_from_data(auth_user)
23
+ create! do |authorship|
24
+ authorship.data = { email: auth_user.email,
25
+ uid: auth_user.id,
26
+ user_name: auth_user.login,
27
+ name: auth_user.name,
28
+ avatar: auth_user.avatar_url }.select { |k,v| v.present? }
29
+
30
+ authorship.role = authorship.select_role
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ module Writefully
2
+ class Post < ActiveRecord::Base
3
+ extend FriendlyId
4
+ include Writefully::Postable
5
+
6
+ friendly_id :title, use: :slugged
7
+
8
+ has_many :taggings
9
+ wf_taxonomize :tags, -> { where(type: nil) }, through: :taggings
10
+
11
+ belongs_to :authorship
12
+ belongs_to :translation_source, class_name: "Writefully::Post"
13
+ belongs_to :site
14
+
15
+ has_many :translations, class_name: "Writefully::Post", foreign_key: :translation_source_id
16
+
17
+ scope :by_site, -> (site_id) { where(site_id: site_id) }
18
+
19
+ def details
20
+ Hashie::Mash.new(read_attribute(:details))
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ module Writefully
2
+ class Site < ActiveRecord::Base
3
+ extend FriendlyId
4
+
5
+ HOOK_EVENTS = %w(push collaborator)
6
+
7
+ friendly_id :name, use: :slugged
8
+
9
+ after_save :setup_repository, if: -> { repository.nil? }
10
+ after_save :clear_errors, if: -> { healthy_changed? and healthy? }
11
+
12
+ belongs_to :owner, class_name: "Writefully::Authorship"
13
+
14
+ has_many :posts, -> { order(:position) }
15
+
16
+ def setup_repository
17
+ Writefully.add_job :handyman, { task: :build, auth_token: owner.data["auth_token"],
18
+ user_name: owner.data["user_name"],
19
+ site_id: id, site_slug: slug }
20
+ end
21
+
22
+ def processing_errors
23
+ Writefully.redis.with { |c| c.smembers "site:#{self.id}:errors" }
24
+ end
25
+
26
+ def clear_errors
27
+ Writefully.redis.with { |c| c.del("site:#{self.id}:errors") }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ module Writefully
2
+ class Tag < ActiveRecord::Base
3
+ has_many :taggings
4
+ has_many :posts, through: :taggings
5
+
6
+ class << self
7
+ def ids_from_tokens tokens
8
+ taxon = Taxon.new(tokens, pluck(:name), name)
9
+
10
+ import taxon.non_existing
11
+ where(slug: tokens.map { |t| t.parameterize }).ids
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Writefully
2
+ class Tagging < ActiveRecord::Base
3
+ belongs_to :tag, class_name: "Writefully::Tag"
4
+ belongs_to :post, class_name: "Writefully::Post"
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for(:title).present? ? (content_for(:title) + " - Writefully Admin") : "Writefully Admin" %></title>
5
+ <%= stylesheet_link_tag "writefully/writefully", media: "all" %>
6
+ <%= javascript_include_tag "writefully/writefully" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body class='writefully <%= controller_name %> <%= action_name %>'>
10
+ <%= render 'navigation' %>
11
+ <div class='container'>
12
+ <%= yield %>
13
+ </div>
14
+
15
+ </body>
16
+ </html>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Owner Setup</title>
5
+ <%= stylesheet_link_tag "writefully/writefully", media: "all" %>
6
+ <%= javascript_include_tag "writefully/writefully" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body class='writefully <%= controller_name %> <%= action_name %>'>
10
+
11
+ <div class='container'>
12
+ <%= yield %>
13
+ </div>
14
+
15
+ </body>
16
+ </html>