writefully 0.4.10 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/writefully/loading-bubbles.svg +14 -0
  3. data/app/assets/javascripts/writefully/writefully/initializers/manifest.coffee +5 -5
  4. data/app/assets/javascripts/writefully/writefully/initializers/setup.coffee +1 -1
  5. data/app/assets/javascripts/writefully/writefully/services/autosave.coffee +8 -0
  6. data/app/assets/stylesheets/writefully/base.sass +16 -1
  7. data/app/assets/stylesheets/writefully/profiles.sass +3 -0
  8. data/app/assets/stylesheets/writefully/sites.sass +0 -4
  9. data/app/assets/stylesheets/writefully/writefully.sass +2 -0
  10. data/app/controllers/writefully/profiles_controller.rb +12 -0
  11. data/app/models/writefully/authorship.rb +1 -1
  12. data/app/models/writefully/post.rb +1 -1
  13. data/app/views/writefully/application/_navigation.html.erb +2 -5
  14. data/app/views/writefully/application/_super_admin.html.erb +4 -0
  15. data/app/views/writefully/profiles/_form.html.erb +17 -0
  16. data/app/views/writefully/profiles/edit.html.erb +11 -0
  17. data/app/views/writefully/sites/new.html.erb +1 -1
  18. data/config/routes.rb +2 -1
  19. data/db/migrate/20140501094825_add_trashed_to_posts.rb +5 -0
  20. data/lib/writefully/cli.rb +1 -1
  21. data/lib/writefully/loader.rb +7 -2
  22. data/lib/writefully/postable.rb +22 -0
  23. data/lib/writefully/process.rb +9 -3
  24. data/lib/writefully/taxon.rb +52 -1
  25. data/lib/writefully/tools/dispatcher.rb +1 -1
  26. data/lib/writefully/tools/eraser.rb +16 -0
  27. data/lib/writefully/tools/pencil.rb +4 -34
  28. data/lib/writefully/tools/stationery.rb +42 -0
  29. data/lib/writefully/tools.rb +1 -0
  30. data/lib/writefully/version.rb +1 -1
  31. data/lib/writefully/workers/journalist.rb +2 -0
  32. data/spec/controllers/writefully/authorships_controller_spec.rb +7 -0
  33. data/spec/controllers/writefully/profiles_controller_spec.rb +7 -0
  34. data/spec/dummy/content/codemy-net/posts/1-hash-selector-pattern/meta.yml +0 -1
  35. data/spec/dummy/content/codemy-net/posts/2-rails-flash-partials/meta.yml +0 -1
  36. data/spec/dummy/db/schema.rb +2 -1
  37. data/spec/dummy/log/development.log +70 -0
  38. data/spec/dummy/log/test.log +2316 -0
  39. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_alerts.scssc +0 -0
  40. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_background-variant.scssc +0 -0
  41. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_border-radius.scssc +0 -0
  42. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_buttons.scssc +0 -0
  43. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_center-block.scssc +0 -0
  44. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_clearfix.scssc +0 -0
  45. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_forms.scssc +0 -0
  46. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_gradients.scssc +0 -0
  47. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_grid-framework.scssc +0 -0
  48. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_grid.scssc +0 -0
  49. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_hide-text.scssc +0 -0
  50. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_image.scssc +0 -0
  51. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_labels.scssc +0 -0
  52. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_list-group.scssc +0 -0
  53. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_nav-divider.scssc +0 -0
  54. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_nav-vertical-align.scssc +0 -0
  55. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_opacity.scssc +0 -0
  56. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_pagination.scssc +0 -0
  57. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_panels.scssc +0 -0
  58. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_progress-bar.scssc +0 -0
  59. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_reset-filter.scssc +0 -0
  60. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_resize.scssc +0 -0
  61. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_responsive-visibility.scssc +0 -0
  62. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_size.scssc +0 -0
  63. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_tab-focus.scssc +0 -0
  64. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_table-row.scssc +0 -0
  65. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_text-emphasis.scssc +0 -0
  66. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_text-overflow.scssc +0 -0
  67. data/spec/dummy/tmp/cache/assets/test/sass/2214915388977a1da0d5bf83510616733a1df75d/_vendor-prefixes.scssc +0 -0
  68. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_alerts.scssc +0 -0
  69. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_badges.scssc +0 -0
  70. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_breadcrumbs.scssc +0 -0
  71. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_button-groups.scssc +0 -0
  72. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_buttons.scssc +0 -0
  73. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_carousel.scssc +0 -0
  74. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_close.scssc +0 -0
  75. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_code.scssc +0 -0
  76. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_component-animations.scssc +0 -0
  77. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_dropdowns.scssc +0 -0
  78. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_forms.scssc +0 -0
  79. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_glyphicons.scssc +0 -0
  80. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_grid.scssc +0 -0
  81. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_input-groups.scssc +0 -0
  82. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_jumbotron.scssc +0 -0
  83. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_labels.scssc +0 -0
  84. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_list-group.scssc +0 -0
  85. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_media.scssc +0 -0
  86. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_mixins.scssc +0 -0
  87. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_modals.scssc +0 -0
  88. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_navbar.scssc +0 -0
  89. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_navs.scssc +0 -0
  90. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_normalize.scssc +0 -0
  91. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_pager.scssc +0 -0
  92. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_pagination.scssc +0 -0
  93. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_panels.scssc +0 -0
  94. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_popovers.scssc +0 -0
  95. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_print.scssc +0 -0
  96. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_progress-bars.scssc +0 -0
  97. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_responsive-embed.scssc +0 -0
  98. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_responsive-utilities.scssc +0 -0
  99. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_scaffolding.scssc +0 -0
  100. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_tables.scssc +0 -0
  101. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_thumbnails.scssc +0 -0
  102. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_tooltip.scssc +0 -0
  103. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_type.scssc +0 -0
  104. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_utilities.scssc +0 -0
  105. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_variables.scssc +0 -0
  106. data/spec/dummy/tmp/cache/assets/test/sass/4e0ec03be757f8083cd0b7f1d18721d9c08da7d6/_wells.scssc +0 -0
  107. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/base.sassc +0 -0
  108. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/profiles.sassc +0 -0
  109. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/sessions.sassc +0 -0
  110. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/sites.sassc +0 -0
  111. data/spec/dummy/tmp/cache/assets/test/sass/77bc3b7f842c905df4dddb7e3ac7b7cf15d9035b/writefully.sassc +0 -0
  112. data/spec/dummy/tmp/cache/assets/test/sass/af039d23726606ef9c96e50dbc4f6a7893b20f53/bootstrap.scssc +0 -0
  113. data/spec/dummy/tmp/cache/assets/test/sprockets/064b3076e29f54ea572ca43d6c5950cc +0 -0
  114. data/spec/dummy/tmp/cache/assets/test/sprockets/3063f229c5edc0e8a3d82d7bf78024de +0 -0
  115. data/spec/dummy/tmp/cache/assets/test/sprockets/31c84f37a0c92c38be6459f19997c981 +0 -0
  116. data/spec/dummy/tmp/cache/assets/test/sprockets/4684201e9a7b66017ea250f0d7fd06e2 +0 -0
  117. data/spec/dummy/tmp/cache/assets/test/sprockets/81e4a723953d063ec006596c9f2fb1ef +0 -0
  118. data/spec/dummy/tmp/cache/assets/test/sprockets/82b92bb7c88523dc617b3c0c877aeade +0 -0
  119. data/spec/dummy/tmp/cache/assets/test/sprockets/8d225befd9f2c5c3ef1ff73591bea154 +0 -0
  120. data/spec/dummy/tmp/cache/assets/test/sprockets/98223bde155ccb586e710444611aabb4 +0 -0
  121. data/spec/dummy/tmp/cache/assets/test/sprockets/9b9ee2a899dd8b3bfa592fba44ebf8d2 +0 -0
  122. data/spec/dummy/tmp/cache/assets/test/sprockets/a8b93e1f061f64547b92633c5bde6b13 +0 -0
  123. data/spec/dummy/tmp/cache/assets/test/sprockets/abf4fd7235880434a75a35635e4fb67a +0 -0
  124. data/spec/dummy/tmp/cache/assets/test/sprockets/adae8faa21b116471ec4285998d3f3cf +0 -0
  125. data/spec/dummy/tmp/cache/assets/test/sprockets/b83537e814e13cf03642ccc3d90fda13 +0 -0
  126. data/spec/dummy/tmp/cache/assets/test/sprockets/c1208bf8d0e9714161d8e6ae61781efc +0 -0
  127. data/spec/dummy/tmp/cache/assets/test/sprockets/d10e06dee94ddaa562f7df319407bf18 +0 -0
  128. data/spec/dummy/tmp/cache/assets/test/sprockets/d1238ae38ca7b9522d86d67ee367223e +0 -0
  129. data/spec/dummy/tmp/cache/assets/test/sprockets/d2c2fff5893ce8979ca48bab1c6f1c3a +0 -0
  130. data/spec/dummy/tmp/cache/assets/test/sprockets/d70cdda3055dc0a1d8b8e40baa559146 +0 -0
  131. data/spec/dummy/tmp/cache/assets/test/sprockets/d9930581c13e892e69359a33854d7af4 +0 -0
  132. data/spec/dummy/tmp/cache/assets/test/sprockets/e784991cbb1dab2f65db11cc0381b11d +0 -0
  133. data/spec/lib/writefully/content_spec.rb +0 -1
  134. data/spec/lib/writefully/tools/pencil_spec.rb +2 -2
  135. metadata +171 -3
  136. data/lib/writefully/workers_helpers.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea727086bde7ed0d78dd3e7958a1fb03e97a81d2
4
- data.tar.gz: a918d1b2a13efcebd964644d9c7cd6026815d5f2
3
+ metadata.gz: f90afad3ac8a344ab63f1b9d301f27feaa0b4b4e
4
+ data.tar.gz: f4729685c69d37d11d244f8eafcaf96fbf67d8b7
5
5
  SHA512:
6
- metadata.gz: e320662c11c6f99e2daafd18095130c6bfc3979b5c0e4612b6a09d1b117bd70583c5c281b1b73d66eb3e132ee2598ff9703972ed33d07debf7cabe8924ac944d
7
- data.tar.gz: 96c3d3cac5e7eb62d7b28cee033ff1c53b9f12e217bead0f7e9fb18e9f08c10f90dfaf05ff48c5699b9bd4a6a029bef5affa5fd390a45fadbab2dd515999f4b8
6
+ metadata.gz: 9328f4d1e289b665ddc26ef2caaf29b43c555f0da2ee203aa1124de44923a5f27a28b9ae67d5f383453e6790b6785bf2827f63aa2a582a5b38bce5d59b8e08b1
7
+ data.tar.gz: 64c333720e0aba0799289765427724065676410bc607393cef7a209dab8a358bc33d9f0e3b2daf412eaf88e659f2cf94198d55aa5cea0f6ba8d99f77c6e837a4
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="#ccc">
2
+ <circle transform="translate(8 0)" cx="0" cy="16" r="0">
3
+ <animate attributeName="r" values="0; 4; 0; 0" dur="1.2s" repeatCount="indefinite" begin="0"
4
+ keytimes="0;0.2;0.7;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
5
+ </circle>
6
+ <circle transform="translate(16 0)" cx="0" cy="16" r="0">
7
+ <animate attributeName="r" values="0; 4; 0; 0" dur="1.2s" repeatCount="indefinite" begin="0.3"
8
+ keytimes="0;0.2;0.7;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
9
+ </circle>
10
+ <circle transform="translate(24 0)" cx="0" cy="16" r="0">
11
+ <animate attributeName="r" values="0; 4; 0; 0" dur="1.2s" repeatCount="indefinite" begin="0.6"
12
+ keytimes="0;0.2;0.7;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
13
+ </circle>
14
+ </svg>
@@ -1,4 +1,4 @@
1
- Application.services_manifest = ->
1
+ Writefully.services_manifest = ->
2
2
  # fill in your manifest here
3
3
  # example:
4
4
  # if you want to trigger a service on your entire app
@@ -21,8 +21,8 @@ Application.services_manifest = ->
21
21
  # body.photos.index').trigger 'application:services:service_name'
22
22
  #
23
23
 
24
- Application.run_ready = ->
25
- Application.services_manifest()
24
+ Writefully.run_ready = ->
25
+ Writefully.services_manifest()
26
26
 
27
- $(document).ready Application.run_ready
28
- $(document).on 'page:load', Application.run_ready
27
+ $(document).ready Writefully.run_ready
28
+ $(document).on 'page:load', Writefully.run_ready
@@ -1,4 +1,4 @@
1
- window.Application =
1
+ window.Writefully =
2
2
  Helpers: {}
3
3
  Services: {}
4
4
  Presenters: {}
@@ -0,0 +1,8 @@
1
+ class Writefully.Services.Notepad extends Transponder.Service
2
+ serviceName: 'autosave'
3
+ module: 'writefully'
4
+
5
+ init: ->
6
+
7
+ serve: ->
8
+ @init()
@@ -20,4 +20,19 @@ div.container
20
20
 
21
21
  .panel
22
22
  h1, h2, h3, h4, h5, h6
23
- margin: 0px !important
23
+ margin: 0px !important
24
+
25
+ form.form-horizontal
26
+ margin-top: 40px
27
+ p.form-info
28
+ padding: 10px
29
+
30
+ .form-control
31
+ border: none
32
+ @include box-shadow(none)
33
+ border-radius: 0px
34
+ background: #f8f8f8
35
+ border: 1px solid #e7e7e7
36
+
37
+ &:focus
38
+ @include box-shadow(0px 0px 5px #ddd)
@@ -0,0 +1,3 @@
1
+ body.writefully.profiles
2
+ h1
3
+ font-weight: 100
@@ -13,10 +13,6 @@ body.writefully.sites, body.writefully.posts.index
13
13
  ul.nav-tabs
14
14
  margin-bottom: 20px
15
15
 
16
- form#new_site
17
- margin-top: 40px
18
- p.form-info
19
- padding: 10px
20
16
 
21
17
 
22
18
  div.site.media
@@ -1,4 +1,6 @@
1
1
  @import "bootstrap"
2
+ @import "bootstrap/mixins"
2
3
  @import "base"
3
4
  @import "sites"
5
+ @import "profiles"
4
6
  @import "sessions"
@@ -0,0 +1,12 @@
1
+ require_dependency "writefully/application_controller"
2
+
3
+ module Writefully
4
+ class ProfilesController < ApplicationController
5
+ before_filter :authenticate_wf_authorship!
6
+
7
+
8
+ def edit
9
+ @authorship = current_wf_authorship
10
+ end
11
+ end
12
+ end
@@ -7,7 +7,7 @@ module Writefully
7
7
  has_many :posts
8
8
  has_many :owned_sites, class_name: "Writefully::Site", foreign_key: :owner_id
9
9
 
10
- store_accessor :data, :name, :email, :uid, :user_name, :auth_token
10
+ store_accessor :data, :name, :email, :uid, :user_name, :auth_token, :bio
11
11
 
12
12
  def to_s
13
13
  data["name"] || data["login"] || data["email"] || data["uid"]
@@ -8,7 +8,7 @@ module Writefully
8
8
  friendly_id :title, use: :slugged
9
9
 
10
10
  has_many :taggings, dependent: :destroy
11
- wf_taxonomize :tags, -> { where(type: nil) }, through: :taggings
11
+ wf_taxonomize :tags, through: :taggings
12
12
 
13
13
  belongs_to :authorship
14
14
  belongs_to :translation_source, class_name: "Writefully::Post"
@@ -10,12 +10,9 @@
10
10
  <%= link_to "Writefully", root_path, class: 'navbar-brand' %>
11
11
  </div>
12
12
  <div class="collapse navbar-collapse">
13
- <ul class='nav navbar-nav'>
14
- <%= activeable_link_to :li, "Dashboard", root_path, icon: 'home' %>
15
- <%= activeable_link_to :li, "New Site", new_site_path, icon: 'plus' %>
16
- </ul>
13
+ <%= render 'super_admin' if current_wf_authorship.role == 'super_admin' %>
17
14
  <ul class="nav navbar-nav navbar-right">
18
- <li><p class='navbar-text'><%= current_wf_authorship %></p></li>
15
+ <li><%= link_to current_wf_authorship, edit_profile_path %></li>
19
16
  <li><%= link_to "Sign Out", signout_path %></li>
20
17
  </ul>
21
18
  </div>
@@ -0,0 +1,4 @@
1
+ <ul class='nav navbar-nav'>
2
+ <%= activeable_link_to :li, "Dashboard", root_path, icon: 'home' %>
3
+ <%= activeable_link_to :li, "New Site", new_site_path, icon: 'plus' %>
4
+ </ul>
@@ -0,0 +1,17 @@
1
+ <%= form_for @authorship, html: { class: 'form-horizontal', role: 'form' } do |f| %>
2
+ <div class='form-group'>
3
+ <div class='col-sm-12'>
4
+ <%= f.text_field :name, class: 'form-control input-lg', placeholder: 'Name' %>
5
+ </div>
6
+ </div>
7
+ <div class='form-group'>
8
+ <div class='col-sm-12'>
9
+ <%= f.text_field :email, class: 'form-control input-lg', placeholder: 'Email' %>
10
+ </div>
11
+ </div>
12
+ <div class='form-group'>
13
+ <div class='col-sm-12'>
14
+ <%= f.text_area :bio, class: 'form-control input-lg', placeholder: 'A bit about yourself' %>
15
+ </div>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= content_for(:title, "Edit Author Profile") %>
2
+ <div class='row'>
3
+ <div class='col-md-4 col-md-offset-4'>
4
+ <h1 class='text-center'><%= current_wf_authorship %></h1>
5
+ <%= render 'form' %>
6
+ <p class='text-center loader hide'>
7
+ <%= image_tag 'writefully/loading-bubbles.svg', alt: 'loading icon', width: '128', height: '128' %>
8
+ </p>
9
+ </div>
10
+ </div>
11
+
@@ -1,4 +1,4 @@
1
- <%#= content_for(:title, "Site Setup") %>
1
+ <%= content_for(:title, "Site Setup") %>
2
2
  <div class='row'>
3
3
  <div class='col-md-4 col-md-offset-4'>
4
4
  <h1 class='text-center'>Site Setup</h1>
data/config/routes.rb CHANGED
@@ -5,7 +5,8 @@ Writefully::Engine.routes.draw do
5
5
  resources :posts, only: [:index, :show]
6
6
  end
7
7
 
8
- resources :authorships
8
+ resource :profile, only: [:edit]
9
+ resource :authorship, only: [:update]
9
10
  resource :hook, only: [:create]
10
11
 
11
12
  get '/signin', to: 'sessions#new'
@@ -0,0 +1,5 @@
1
+ class AddTrashedToPosts < ActiveRecord::Migration
2
+ def change
3
+ add_column :writefully_posts, :trashed, :boolean, default: false
4
+ end
5
+ end
@@ -45,7 +45,7 @@ module Writefully
45
45
 
46
46
  no_tasks do
47
47
  def listen(config)
48
- Writefully::Process.new(config).listen
48
+ Writefully::Process.instance.listen(config)
49
49
  end
50
50
 
51
51
  def setup_logger(logfile)
@@ -5,6 +5,10 @@ module Writefully
5
5
  SCOPES = %w(repo public_repo user write:repo_hook)
6
6
 
7
7
  class << self
8
+ QUEUE = {
9
+ top: -> (c, job) { c.lpush "jobs", job },
10
+ bottom: -> (c, job) { c.rpush "jobs", job }
11
+ }
8
12
 
9
13
  def options=(config)
10
14
  @_options = config
@@ -21,8 +25,9 @@ module Writefully
21
25
  end
22
26
  end
23
27
 
24
- def add_job worker, message
25
- Writefully.redis.with { |c| c.sadd "jobs", convert_job(worker, message) }
28
+ def add_job worker, message, position = nil
29
+ position_selector = position || :bottom
30
+ Writefully.redis.with { |c| QUEUE[position_selector].call(c, convert_job(worker, message)) }
26
31
  end
27
32
 
28
33
  def convert_job worker, message
@@ -9,6 +9,8 @@ module Writefully
9
9
  after_initialize :check_content_field_existence
10
10
  attr_accessor :publish
11
11
 
12
+ scope :with_taxonomies, -> (*types) { select(Taxon::EagerLoader.new(self).build(*types)) }
13
+
12
14
  before_save :publish_resource, if: -> { respond_to?(:published_at) }
13
15
  end
14
16
 
@@ -41,17 +43,37 @@ module Writefully
41
43
  class_eval do
42
44
  has_many :"#{type}", *args
43
45
 
46
+ define_method("all_#{type}") do
47
+ read_attribute(:"all_#{type}").map { |taxon| Hashie::Mash.new(taxon) }
48
+ end
49
+
44
50
  define_method("#{type}=") do |tokens|
45
51
  self.taxonomize_with(tokens, type)
46
52
  end
47
53
  end
48
54
  end
49
55
 
56
+ def filter_with(filters)
57
+ if filters.present?
58
+ filters.keys.inject(self) do |klass, type|
59
+ klass.where(id: by_taxonomies(filters[type].split(/,/), type))
60
+ end
61
+ else all end
62
+ end
63
+
64
+ def by_taxonomies(taxonomies, type)
65
+ joins(type.to_sym)
66
+ .where(writefully_tags: { slug: taxonomies,
67
+ type: (type == "tags" ? nil : type.classify) })
68
+ .uniq
69
+ end
70
+
50
71
  def wf_content(field_name)
51
72
  class_eval do
52
73
  alias_attribute :content, :"#{field_name}" unless field_name == :content
53
74
  end
54
75
  end
76
+
55
77
  end
56
78
  end
57
79
  end
@@ -14,15 +14,21 @@ require 'writefully/loader'
14
14
  require 'writefully/tools'
15
15
  require 'writefully/workers'
16
16
  require 'writefully/news_agency'
17
+ require 'singleton'
17
18
 
18
19
  %w(tag post site tagging authorship).each do |model|
19
20
  require File.dirname(__FILE__) + "/../../app/models/writefully/#{model}"
20
21
  end
21
22
 
22
23
  module Writefully
23
- Process = Struct.new(:config) do
24
+ class Process
25
+ include Singleton
26
+
27
+ attr_reader :config
28
+
29
+ def listen config
30
+ @config = config
24
31
 
25
- def listen
26
32
  set_title
27
33
  set_options
28
34
  log_start
@@ -88,7 +94,7 @@ module Writefully
88
94
 
89
95
  JOBS = {
90
96
  write: -> (index) { Writefully.add_job :journalists, index.merge({task: :publish}) },
91
- remove: -> (index) { Wrotefully.add_job :journalists, index.merge({task: :remove}) }
97
+ remove: -> (index) { Writefully.add_job :journalists, index.merge({task: :remove}), :top }
92
98
  }
93
99
 
94
100
  def queue_jobs indices, action
@@ -1,5 +1,13 @@
1
1
  module Writefully
2
- Taxon = Struct.new(:incoming, :existing, :type) do
2
+ class Taxon
3
+ attr_reader :incoming, :existing, :type
4
+
5
+ def initialize(incoming, existing, type)
6
+ @incoming = incoming
7
+ @existing = existing
8
+ @type = type
9
+ end
10
+
3
11
  def non_existing
4
12
  get_difference.map { |token| Tag.new(build_attributes(token)) }
5
13
  end
@@ -24,5 +32,48 @@ module Writefully
24
32
  def parameterized items
25
33
  items.map { |t| t.parameterize }
26
34
  end
35
+
36
+ class EagerLoader
37
+ attr_reader :tags, :taggings, :resource
38
+
39
+ def initialize(klass)
40
+ @tags = Tag.arel_table
41
+ @taggings = Tagging.arel_table
42
+ @resource = klass.arel_table
43
+ end
44
+
45
+ def build *types
46
+ [resource[Arel.star]] << types.map { |type| array_of_taxonomy_hstores_for(type) }
47
+ end
48
+
49
+ private
50
+
51
+ def array_of_taxonomy_hstores_for type
52
+ Arel::Nodes::NamedFunction.new('ARRAY', [hstore_for_taxon(type)]).as("all_#{type}")
53
+ end
54
+
55
+ def hstore_for_taxon type
56
+ tags.project(Arel.sql('hstore(taxon)')).from(taxons_for_resource(type))
57
+ end
58
+
59
+ def taxons_for_resource type
60
+ Tag.joins(:taggings).arel.where(tags_by_type(type))
61
+ .where(taggings_by_resource).as('taxon')
62
+ end
63
+
64
+ def tags_by_type type
65
+ tags[:type].eq(calculate_type(type))
66
+ end
67
+
68
+ def taggings_by_resource
69
+ # we use post_id for now but we should
70
+ # make it a polymorphic association later
71
+ taggings[:post_id].eq(resource[:id])
72
+ end
73
+
74
+ def calculate_type type
75
+ type == :tags ? nil : type.to_s.classify
76
+ end
77
+ end
27
78
  end
28
79
  end
@@ -12,7 +12,7 @@ module Writefully
12
12
  end
13
13
 
14
14
  def get_job_data
15
- Writefully.redis.with { |c| c.spop 'jobs' }
15
+ Writefully.redis.with { |c| c.lpop 'jobs' }
16
16
  end
17
17
 
18
18
  def heartbeat
@@ -0,0 +1,16 @@
1
+ module Writefully
2
+ module Tools
3
+ class Eraser < Stationery
4
+
5
+ def use
6
+ destroy
7
+ end
8
+
9
+ def destroy
10
+ compute_type.by_site(site_id)
11
+ .where(slug: content.slug)
12
+ .first.update_attributes(trashed: true)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,21 +1,8 @@
1
1
  module Writefully
2
2
  module Tools
3
- class Pencil
4
- include Celluloid
3
+ class Pencil < Stationery
5
4
 
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
5
+ def use
19
6
  assets_uploaded = upload_assets.map(&:value).compact
20
7
  written_to_db = future.write if can_update_db?(assets_uploaded)
21
8
  terminate if written_to_db.value
@@ -24,7 +11,8 @@ module Writefully
24
11
  def computed_attributes
25
12
  content.meta.merge({
26
13
  "content" => asset.convert_for(content.body),
27
- "details" => asset.convert_for(content.details)
14
+ "details" => asset.convert_for(content.details),
15
+ "trashed" => false
28
16
  })
29
17
  end
30
18
 
@@ -32,8 +20,6 @@ module Writefully
32
20
  compute_type.by_site(site_id).where(slug: content.slug)
33
21
  .first_or_initialize
34
22
  .update_attributes(computed_attributes)
35
- ensure
36
- ::ActiveRecord::Base.clear_active_connections! if defined?(::ActiveRecord)
37
23
  end
38
24
 
39
25
  def upload_assets
@@ -49,22 +35,6 @@ module Writefully
49
35
  raise SomeAssetsNotUploaded, "Some assets was not uploaded"
50
36
  end
51
37
  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
38
 
69
39
  end
70
40
  end
@@ -0,0 +1,42 @@
1
+ module Writefully
2
+ module Tools
3
+ class Stationery
4
+ include Celluloid
5
+
6
+ attr_reader :content, :asset, :index, :site_id
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
+ use
20
+ ensure
21
+ ::ActiveRecord::Base.clear_active_connections! if defined?(::ActiveRecord)
22
+ end
23
+
24
+ private
25
+
26
+ def compute_type
27
+ index[:resource].classify.constantize
28
+ rescue NameError
29
+ fallback_type
30
+ end
31
+
32
+ def fallback_type
33
+ if index[:resource] == "posts"
34
+ "Writefully::Post".constantize
35
+ else
36
+ raise ContentModelNotFound, "Model #{index[:resource].classify} was not found"
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -4,6 +4,7 @@ module Writefully
4
4
  end
5
5
  end
6
6
 
7
+ require 'writefully/tools/stationery'
7
8
  require 'writefully/tools/eraser'
8
9
  require 'writefully/tools/pencil'
9
10
  require 'writefully/tools/pigeon'
@@ -1,3 +1,3 @@
1
1
  module Writefully
2
- VERSION = "0.4.10"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -9,6 +9,8 @@ module Writefully
9
9
 
10
10
  def remove
11
11
  Writefully.logger.info "Removing #{message[:resource]} #{message[:slug]}"
12
+ eraser = Tools::Eraser.new_link(message)
13
+ eraser.perform
12
14
  end
13
15
 
14
16
  def message_with_tries
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module Writefully
4
+ describe AuthorshipsController do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module Writefully
4
+ describe ProfilesController do
5
+
6
+ end
7
+ end
@@ -1,5 +1,4 @@
1
1
  title: "Ruby Hash Selector Pattern"
2
- slug: "ruby-hash-selector-pattern"
3
2
  tags: ["Ruby"]
4
3
  playlists: ["A Shot of Ruby"]
5
4
  details:
@@ -1,5 +1,4 @@
1
1
  title: "Rails Flash Partials"
2
- slug: "rails-flash-partials"
3
2
  tags: ["Rails"]
4
3
  playlists: ["A Shot of Ruby"]
5
4
  details:
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20140403181629) do
14
+ ActiveRecord::Schema.define(version: 20140501094825) do
15
15
 
16
16
  # These are extensions that must be enabled in order to support this database
17
17
  enable_extension "plpgsql"
@@ -41,6 +41,7 @@ ActiveRecord::Schema.define(version: 20140403181629) do
41
41
  t.integer "authorship_id"
42
42
  t.datetime "created_at"
43
43
  t.datetime "updated_at"
44
+ t.boolean "trashed", default: false
44
45
  end
45
46
 
46
47
  add_index "writefully_posts", ["authorship_id"], name: "index_writefully_posts_on_authorship_id", using: :btree