crowdblog 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.autotest +5 -0
  2. data/.gitignore +1 -0
  3. data/app/assets/javascripts/crowdblog/models/post.js.coffee.erb +1 -1
  4. data/app/assets/stylesheets/application.css +3 -0
  5. data/app/controllers/crowdblog/admin/assets_controller.rb +20 -0
  6. data/app/controllers/crowdblog/admin/authors_controller.rb +11 -0
  7. data/app/controllers/crowdblog/admin/base_controller.rb +7 -0
  8. data/app/controllers/crowdblog/admin/posts_controller.rb +71 -0
  9. data/app/controllers/crowdblog/application_controller.rb +8 -7
  10. data/app/controllers/crowdblog/posts_controller.rb +2 -66
  11. data/app/models/crowdblog/post.rb +2 -2
  12. data/app/models/crowdblog/user.rb +18 -26
  13. data/app/views/crowdblog/{authors → admin/authors}/index.html.slim +0 -0
  14. data/app/views/crowdblog/{posts → admin/posts}/_form.html.slim +0 -0
  15. data/app/views/crowdblog/admin/posts/_post.html.slim +13 -0
  16. data/app/views/crowdblog/{posts → admin/posts}/edit.html.slim +2 -2
  17. data/app/views/crowdblog/admin/posts/index.html.slim +24 -0
  18. data/app/views/crowdblog/{posts → admin/posts}/new.html.slim +0 -0
  19. data/app/views/crowdblog/{posts → admin/posts}/update.json.jbuilder +0 -0
  20. data/app/views/crowdblog/application/_navbar.html.slim +4 -6
  21. data/app/views/crowdblog/posts/_post.html.slim +4 -13
  22. data/app/views/crowdblog/posts/index.html.slim +1 -24
  23. data/app/views/layouts/crowdblog/admin/base.html.slim +20 -0
  24. data/app/views/layouts/crowdblog/application.html.slim +2 -3
  25. data/config/routes.rb +9 -8
  26. data/crowdblog.gemspec +2 -1
  27. data/lib/crowdblog.rb +1 -4
  28. data/lib/crowdblog/rspec/crowdblog_shared_examples.rb +70 -73
  29. data/lib/crowdblog/version.rb +1 -1
  30. data/lib/generators/crowdblog/views_generator.rb +11 -0
  31. data/spec/dummy/app/controllers/application_controller.rb +0 -2
  32. data/spec/dummy/config/routes.rb +1 -3
  33. data/spec/dummy/db/schema.rb +1 -42
  34. data/spec/generators/crowdblog/views_generator_spec.rb +16 -0
  35. data/spec/models/post_spec.rb +4 -14
  36. metadata +46 -35
  37. data/app/assets/images/crowdblog/logo.png +0 -0
  38. data/app/controllers/crowdblog/assets_controller.rb +0 -18
  39. data/app/controllers/crowdblog/authors_controller.rb +0 -9
  40. data/app/controllers/crowdblog/devise/sessions_controller.rb +0 -3
  41. data/config/initializers/devise.rb +0 -16
  42. data/db/migrate/20120215232711_create_crowdblog_users.rb +0 -23
  43. data/db/migrate/20120220033923_create_vestal_versions.rb +0 -28
  44. data/spec/dummy/app/controllers/admin_controller.rb +0 -0
  45. data/spec/dummy/app/controllers/home_controller.rb +0 -4
  46. data/spec/dummy/app/controllers/sessions_controller.rb +0 -2
  47. data/spec/dummy/config/initializers/devise.rb +0 -222
  48. data/spec/models/user_spec.rb +0 -81
data/.autotest ADDED
@@ -0,0 +1,5 @@
1
+ require 'autotest/growl'
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.add_exception %w{coverage .autotest spec/dummy}
5
+ end
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ spec/dummy/.sass-cache
12
12
  .sass-cache
13
13
 
14
14
  Gemfile.lock
15
+ tmp
@@ -4,5 +4,5 @@ class Crowdblog.Models.Post extends Backbone.Model
4
4
  paramRoot: 'post'
5
5
 
6
6
  url: ->
7
- '<%= crowdblog.posts_path %>/' + @id
7
+ '<%= crowdblog.admin_posts_path %>/' + @id
8
8
 
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_self
3
+ */
@@ -0,0 +1,20 @@
1
+ module Crowdblog
2
+ module Admin
3
+ class AssetsController < Crowdblog::Admin::BaseController
4
+ # TODO: Skipping filters is the worst solution ever to this problem
5
+ # Someone should fix the uploadify.js thing
6
+ skip_before_filter :verify_authenticity_token, :only => :create
7
+ skip_before_filter :authorize!
8
+
9
+ def create
10
+ @post = Post.find(params[:post_id])
11
+ asset = @post.assets.build
12
+ asset.attachment = params['attachment']
13
+ asset.save!
14
+
15
+ render json: asset
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Crowdblog
2
+ module Admin
3
+ class AuthorsController < Crowdblog::Admin::BaseController
4
+
5
+ def index
6
+ @authors = User.includes(:published_posts).sort {|a,b| b.published_posts.size <=> a.published_posts.size}
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Crowdblog
2
+ module Admin
3
+ class BaseController < Crowdblog::ApplicationController
4
+ before_filter :authenticate_user!
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,71 @@
1
+ module Crowdblog
2
+ module Admin
3
+ class PostsController < Crowdblog::Admin::BaseController
4
+ respond_to :html, :json
5
+ cache_sweeper :post_sweeper
6
+
7
+ before_filter :load_post, :only => [ :edit, :update, :destroy ]
8
+
9
+ def new
10
+ @post = Post.new
11
+ @post.author = current_user
12
+ @post.save!
13
+ redirect_to edit_admin_post_path(@post)
14
+ end
15
+
16
+ def index
17
+ @state = params[:state]
18
+ @posts = Post.scoped_for(current_user).for_admin_index
19
+ @posts = @posts.with_state(@state) if @state
20
+ respond_with @posts
21
+ end
22
+
23
+ def create
24
+ @post = Post.new(post_params)
25
+ @post.author = current_user
26
+ @post.regenerate_permalink
27
+ if @post.save
28
+ respond_with @post, :location => crowdblog.admin_posts_path
29
+ end
30
+ end
31
+
32
+ def destroy
33
+ @post.destroy
34
+ respond_with @post, :location => crowdblog.admin_posts_path
35
+ end
36
+
37
+ def show
38
+ @post = Post.includes(:assets).find(params[:id])
39
+ respond_to do |format|
40
+ format.json { render json: @post.to_json(include: :assets) }
41
+ end
42
+ end
43
+
44
+ def edit
45
+ end
46
+
47
+ def update
48
+ @post.update_attributes(post_params, updated_by: current_user)
49
+ if @post.allowed_to_update_permalink?
50
+ @post.regenerate_permalink
51
+ @post.save!
52
+ end
53
+
54
+ @post.publish_if_allowed(post_params[:transition], current_user) if post_params[:transition]
55
+
56
+ respond_with @post do |format|
57
+ format.html { redirect_to crowdblog.admin_posts_path }
58
+ end
59
+ end
60
+
61
+ private
62
+ def load_post
63
+ @post = Post.scoped_for(current_user).find(params[:id])
64
+ end
65
+
66
+ def post_params
67
+ params.require(:post).permit(:title, :body, :updated_by, :ready_for_review, :transition)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,13 +1,14 @@
1
1
  module Crowdblog
2
2
  class ApplicationController < ActionController::Base
3
- before_filter :authenticate_user!
4
-
5
- def authentication_filter
6
- authenticate_user!
3
+ def method_missing(method_name)
4
+ if method_name == :current_user
5
+ Rails.logger.warn("current_user in Crowdblog::ApplicationController should be overriden")
6
+ User.new
7
+ elsif method_name == :authenticate_user!
8
+ Rails.logger.warn("authenticate_user! in Crowdblog::ApplicationController should be overriden")
9
+ end
7
10
  end
8
11
 
9
- def after_sign_out_path_for(resource_or_scope)
10
- crowdblog.new_user_session_path
11
- end
12
+ helper_method :current_user
12
13
  end
13
14
  end
@@ -1,71 +1,7 @@
1
1
  module Crowdblog
2
- class PostsController < Crowdblog::ApplicationController
3
- before_filter :authenticate_user!
4
-
5
- respond_to :html, :json
6
- cache_sweeper :post_sweeper
7
-
8
- before_filter :load_post, :only => [ :edit, :update, :destroy ]
9
-
10
- def new
11
- @post = Post.new
12
- @post.author = current_user
13
- @post.save!
14
- redirect_to edit_post_path(@post)
15
- end
16
-
2
+ class PostsController < ApplicationController
17
3
  def index
18
- @state = params[:state]
19
- @posts = Post.scoped_for(current_user).for_admin_index
20
- @posts = @posts.with_state(@state) if @state
21
- respond_with @posts
22
- end
23
-
24
- def create
25
- @post = Post.new(post_params)
26
- @post.author = current_user
27
- @post.regenerate_permalink
28
- if @post.save
29
- respond_with @post, :location => crowdblog.posts_path
30
- end
31
- end
32
-
33
- def destroy
34
- @post.destroy
35
- respond_with @post, :location => crowdblog.posts_path
36
- end
37
-
38
- def show
39
- @post = Post.includes(:assets).find(params[:id])
40
- respond_to do |format|
41
- format.json { render json: @post.to_json(include: :assets) }
42
- end
43
- end
44
-
45
- def edit
46
- end
47
-
48
- def update
49
- @post.update_attributes(post_params, updated_by: current_user)
50
- if @post.allowed_to_update_permalink?
51
- @post.regenerate_permalink
52
- @post.save!
53
- end
54
-
55
- @post.publish_if_allowed(post_params[:transition], current_user) if post_params[:transition]
56
-
57
- respond_with @post do |format|
58
- format.html { redirect_to crowdblog.posts_path }
59
- end
60
- end
61
-
62
- private
63
- def load_post
64
- @post = Post.scoped_for(current_user).find(params[:id])
65
- end
66
-
67
- def post_params
68
- params.require(:post).permit(:title, :body, :updated_by, :ready_for_review, :transition)
4
+ @posts = Post.published_and_ordered
69
5
  end
70
6
  end
71
7
  end
@@ -4,8 +4,8 @@ module Crowdblog
4
4
  belongs_to :publisher, class_name: 'User'
5
5
  has_many :assets
6
6
 
7
- delegate :name, to: :author, prefix: true
8
- delegate :email, to: :author, prefix: true
7
+ delegate :name, to: :author, prefix: true, allow_nil: true
8
+ delegate :email, to: :author, prefix: true, allow_nil: true
9
9
  delegate :gravatar_url, to: :author
10
10
 
11
11
  delegate :year, to: :published_at
@@ -1,38 +1,30 @@
1
- module Crowdblog
2
- class User < ActiveRecord::Base
3
- include Gravtastic
4
-
5
- has_many :authored_posts, inverse_of: :author, foreign_key: 'author_id', class_name: 'Post'
6
- has_many :published_posts, inverse_of: :author, foreign_key: 'author_id', class_name: 'Post', conditions: ['state = ?', 'published'], order: 'published_at DESC'
7
- has_one :last_post, class_name: 'Post', foreign_key: :author_id, conditions: ['state = ?', 'published'], order: 'published_at DESC, created_at DESC, id DESC'
8
-
9
- gravtastic :gravatar_email
10
- devise :database_authenticatable, :token_authenticatable, :trackable
11
-
12
- validate :email, uniqueness: true
13
-
14
- attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :is_publisher
1
+ module Crowdblog
2
+ class User
3
+ attr_accessor :email
4
+ attr_accessor :name
5
+ attr_accessor :id
6
+
7
+ def is_publisher?
8
+ true
9
+ end
15
10
 
16
- # INSTANCE METHODS
17
- def gravatar_email
18
- gravatar_alias || email
11
+ def self.primary_key
12
+ "id"
19
13
  end
20
14
 
21
- def last_post_at
22
- last_post.try(:published_at)
15
+ def [](value)
16
+ []
23
17
  end
24
18
 
25
- def last_published_at
26
- published_posts.first ? published_posts.first.published_at : nil
19
+ def destroyed?
20
+ false
27
21
  end
28
22
 
29
- def publisher!
30
- update_attribute(:is_publisher, true)
23
+ def new_record?
24
+ true
31
25
  end
32
26
 
33
- def to_param
34
- [email.split('@').first]
27
+ def save(*)
35
28
  end
36
29
  end
37
30
  end
38
-
@@ -0,0 +1,13 @@
1
+ = content_tag_for :tr, post, :"data-post-id" => post.id, :"data-state" => post.state, :"data-ready-for-review" => post.ready_for_review do
2
+ td= post.title
3
+ td= post.author_email
4
+ td.span2.published-at = post.published_at.try(:to_s, :crowdblog_short)
5
+ td.span1
6
+ - if current_user.is_publisher?
7
+ = link_to 'Publish', '#', :class => "btn btn-small publish #{(post.published? ? 'btn-success' : 'btn-danger')}"
8
+ td.span1
9
+ = link_to 'Review', '#', :class => "btn btn-small review #{(post.ready_for_review ? 'btn-warning' : '')}"
10
+ td.span1
11
+ = link_to 'Delete', crowdblog.admin_post_path(post), :method => :delete, :confirm => 'Are you sure?', :class => "btn btn-small"
12
+ td.span1
13
+ = link_to 'Edit', crowdblog.edit_admin_post_path(post), :class => "btn btn-small"
@@ -1,7 +1,7 @@
1
1
  .span12
2
2
  h2 Edit Post
3
3
 
4
- = form_for @post do |f|
4
+ = form_for [:admin, @post] do |f|
5
5
  = render 'form', :f => f
6
6
 
7
7
  .form-actions.clear
@@ -9,6 +9,6 @@
9
9
  .span1
10
10
  = f.submit "Update", :class => "btn btn-primary"
11
11
  .span1
12
- = link_to 'Cancel', crowdblog.posts_path, :class => "btn"
12
+ = link_to 'Cancel', crowdblog.admin_posts_path, :class => "btn"
13
13
 
14
14
 
@@ -0,0 +1,24 @@
1
+ .span12
2
+ h1 Posts
3
+
4
+ .row
5
+ .span3.new-link
6
+ = link_to 'New Post', crowdblog.new_admin_post_path, :class => "btn btn-primary btn-small"
7
+ .span3.offset6
8
+ ul.nav.nav-pills
9
+ li class="#{@state ? '' : 'active'}"
10
+ = link_to 'All', crowdblog.admin_posts_path
11
+ li class="#{@state == 'published' ? 'active' : ''}"
12
+ = link_to 'Published', crowdblog.admin_posts_by_state_path('published')
13
+ li class="#{@state == 'drafted' ? 'active' : ''}"
14
+ = link_to 'Drafted', crowdblog.admin_posts_by_state_path('drafted')
15
+
16
+ #posts.container
17
+ table.table.table-striped= render :partial => 'post', :collection => @posts
18
+
19
+ - content_for :scripts do
20
+ coffee:
21
+ $ ->
22
+ $('tr.post').each (index, el) ->
23
+ new Crowdblog.Views.PostView
24
+ el: el
@@ -1,11 +1,9 @@
1
1
  .navbar
2
2
  .navbar-inner
3
- = link_to image_tag('crowdblog/logo.png', :width => 227, :height => 74), root_path, :class => 'brand'
3
+ = link_to 'Crowdblog', crowdblog.admin_root_path, :class => 'brand'
4
4
  - if current_user
5
5
  ul.nav
6
6
  li.brand= current_user.email
7
- li= link_to 'Posts', posts_path
8
- li= link_to 'Authors', authors_path
9
- li= link_to 'Sign out', destroy_user_session_path
10
-
11
-
7
+ li= link_to 'Posts', crowdblog.admin_posts_path
8
+ li= link_to 'Authors', crowdblog.admin_authors_path
9
+ li= link_to 'Sign out', '#'
@@ -1,13 +1,4 @@
1
- = content_tag_for :tr, post, :"data-post-id" => post.id, :"data-state" => post.state, :"data-ready-for-review" => post.ready_for_review do
2
- td= post.title
3
- td= post.author_email
4
- td.span2.published-at = post.published_at.try(:to_s, :crowdblog_short)
5
- td.span1
6
- - if current_user.is_publisher?
7
- = link_to 'Publish', '#', :class => "btn btn-small publish #{(post.published? ? 'btn-success' : 'btn-danger')}"
8
- td.span1
9
- = link_to 'Review', '#', :class => "btn btn-small review #{(post.ready_for_review ? 'btn-warning' : '')}"
10
- td.span1
11
- = link_to 'Delete', crowdblog.post_path(post), :method => :delete, :confirm => 'Are you sure?', :class => "btn btn-small"
12
- td.span1
13
- = link_to 'Edit', crowdblog.edit_post_path(post), :class => "btn btn-small"
1
+ = div_for post, :class => "span12" do
2
+ h1= post.title
3
+ h2= post.author_email
4
+ .body= post.html_body
@@ -1,24 +1 @@
1
- .span12
2
- h1 Posts
3
-
4
- .row
5
- .span3.new-link
6
- = link_to 'New Post', crowdblog.new_post_path, :class => "btn btn-primary btn-small"
7
- .span3.offset6
8
- ul.nav.nav-pills
9
- li class="#{@state ? '' : 'active'}"
10
- = link_to 'All', posts_path
11
- li class="#{@state == 'published' ? 'active' : ''}"
12
- = link_to 'Published', posts_by_state_path('published')
13
- li class="#{@state == 'drafted' ? 'active' : ''}"
14
- = link_to 'Drafted', posts_by_state_path('drafted')
15
-
16
- #posts.container
17
- table.table.table-striped= render @posts
18
-
19
- - content_for :scripts do
20
- coffee:
21
- $ ->
22
- $('tr.post').each (index, el) ->
23
- new Crowdblog.Views.PostView
24
- el: el
1
+ = render @posts
@@ -0,0 +1,20 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title Crowd Blog
5
+ = stylesheet_link_tag "//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-combined.min.css"
6
+ = stylesheet_link_tag :crowdblog, media: 'all'
7
+ = javascript_include_tag "//code.jquery.com/jquery.min.js"
8
+ = javascript_include_tag "//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.1/underscore-min.js"
9
+ = javascript_include_tag "//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"
10
+ = javascript_include_tag :crowdblog
11
+ meta name="viewport" content="width=device-width, initial-scale=1.0"
12
+ = csrf_meta_tags
13
+
14
+ = yield :scripts
15
+
16
+ body
17
+ .container
18
+ .row= render '/crowdblog/application/navbar'
19
+ .row= render '/crowdblog/application/notices'
20
+ .row= yield