beef-articles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +7 -0
  5. data/Rakefile +58 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/admin/articles_controller.rb +89 -0
  8. data/app/controllers/admin/categories_controller.rb +83 -0
  9. data/app/controllers/admin/comments_controller.rb +30 -0
  10. data/app/controllers/articles_controller.rb +55 -0
  11. data/app/controllers/comments_controller.rb +50 -0
  12. data/app/helpers/articles_helper.rb +92 -0
  13. data/app/helpers/comments_helper.rb +7 -0
  14. data/app/models/article.rb +37 -0
  15. data/app/models/category.rb +17 -0
  16. data/app/models/comment.rb +16 -0
  17. data/app/views/admin/articles/index.html.erb +45 -0
  18. data/app/views/admin/articles/preview.js.rjs +1 -0
  19. data/app/views/admin/articles/show.html.erb +58 -0
  20. data/app/views/admin/categories/index.html.erb +31 -0
  21. data/app/views/admin/categories/show.html.erb +18 -0
  22. data/app/views/admin/comments/index.html.erb +33 -0
  23. data/app/views/articles/_article.html.erb +12 -0
  24. data/app/views/articles/index.html.erb +40 -0
  25. data/app/views/articles/index.rss.builder +18 -0
  26. data/app/views/articles/show.html.erb +55 -0
  27. data/app/views/comments/_comment.html.erb +4 -0
  28. data/app/views/comments/_form.html.erb +25 -0
  29. data/app/views/comments/new.html.erb +4 -0
  30. data/articles.gemspec +79 -0
  31. data/config/routes.rb +32 -0
  32. data/generators/articles_migration/articles_migration_generator.rb +11 -0
  33. data/generators/articles_migration/templates/migration.rb +45 -0
  34. data/lib/articles.rb +7 -0
  35. data/rails/init.rb +9 -0
  36. data/test/articles_test.rb +7 -0
  37. data/test/test_helper.rb +10 -0
  38. metadata +110 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Steve England
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.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = articles
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Steve England. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "articles"
8
+ gem.summary = %Q{Article/Blogging engine}
9
+ gem.email = "steve@wearebeef.co.uk"
10
+ gem.homepage = "http://github.com/beef/articles"
11
+ gem.authors = ["Steve England"]
12
+ gem.add_dependency( "mbleigh-acts-as-taggable-on")
13
+ gem.add_dependency( "jackdempsey-acts_as_commentable")
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION.yml')
47
+ config = YAML.load(File.read('VERSION.yml'))
48
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "articles #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,89 @@
1
+ class Admin::ArticlesController < Admin::BaseController
2
+ sortable_attributes :title, :permalink, :published_at, :published_to, :body, :description, :allow_comments
3
+
4
+ # GET /articles
5
+ # GET /articles.xml
6
+ def index
7
+ @articles = Article.paginate :page => params[:page], :order => sort_order
8
+
9
+ respond_to do |format|
10
+ format.html # index.html.erb
11
+ format.xml { render :xml => @articles }
12
+ end
13
+ end
14
+
15
+ # GET /articles/1
16
+ # GET /articles/1.xml
17
+ def show
18
+ @article = Article.find(params[:id])
19
+
20
+ respond_to do |format|
21
+ format.html
22
+ format.xml { render :xml => @article }
23
+ end
24
+ end
25
+
26
+ # GET /articles/new
27
+ # GET /articles/new.xml
28
+ def new
29
+ @article = Article.new
30
+
31
+ respond_to do |format|
32
+ format.html { render :action =>'show' }
33
+ format.xml { render :xml => @article }
34
+ end
35
+ end
36
+
37
+ # POST /articles
38
+ # POST /articles.xml
39
+ def create
40
+ @article = Article.new(params[:article])
41
+ @article.updated_by = @article.created_by = current_user
42
+
43
+ respond_to do |format|
44
+ if @article.save
45
+ flash[:notice] = 'Article was successfully created.'
46
+ format.html { redirect_to(admin_articles_url) }
47
+ format.xml { render :xml => @article, :status => :created, :location => @article }
48
+ else
49
+ format.html { render :action => "show" }
50
+ format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
51
+ end
52
+ end
53
+ end
54
+
55
+ # PUT /articles/1
56
+ # PUT /articles/1.xml
57
+ def update
58
+ @article = Article.find(params[:id])
59
+ @article.updated_by = current_user
60
+
61
+ respond_to do |format|
62
+ if @article.update_attributes(params[:article])
63
+ flash[:notice] = 'Article was successfully updated.'
64
+ format.html { redirect_to(admin_articles_url) }
65
+ format.xml { head :ok }
66
+ else
67
+ format.html { render :action => "show" }
68
+ format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
69
+ end
70
+ end
71
+ end
72
+
73
+ # DELETE /articles/1
74
+ # DELETE /articles/1.xml
75
+ def destroy
76
+ @article = Article.find(params[:id])
77
+ @article.destroy
78
+ flash[:notice] = 'Article was successfully deleted.'
79
+
80
+ respond_to do |format|
81
+ format.html { redirect_to(admin_articles_url) }
82
+ format.xml { head :ok }
83
+ end
84
+ end
85
+
86
+ def preview
87
+ session[:article_study_preview] = params[:article_study]
88
+ end
89
+ end
@@ -0,0 +1,83 @@
1
+ class Admin::CategoriesController < Admin::BaseController
2
+ sortable_attributes :title, :description
3
+
4
+ # GET /categories
5
+ # GET /categories.xml
6
+ def index
7
+ @categories = Category.paginate :page => params[:page], :order => sort_order
8
+
9
+ respond_to do |format|
10
+ format.html # index.html.erb
11
+ format.xml { render :xml => @categories }
12
+ end
13
+ end
14
+
15
+ # GET /categories/1
16
+ # GET /categories/1.xml
17
+ def show
18
+ @category = Category.find(params[:id])
19
+
20
+ respond_to do |format|
21
+ format.html
22
+ format.xml { render :xml => @category }
23
+ end
24
+ end
25
+
26
+ # GET /categories/new
27
+ # GET /categories/new.xml
28
+ def new
29
+ @category = Category.new
30
+
31
+ respond_to do |format|
32
+ format.html { render :action =>'show' }
33
+ format.xml { render :xml => @category }
34
+ end
35
+ end
36
+
37
+ # POST /categories
38
+ # POST /categories.xml
39
+ def create
40
+ @category = Category.new(params[:category])
41
+
42
+ respond_to do |format|
43
+ if @category.save
44
+ flash[:notice] = 'Category was successfully created.'
45
+ format.html { redirect_to(admin_categories_url) }
46
+ format.xml { render :xml => @category, :status => :created, :location => @category }
47
+ else
48
+ format.html { render :action => "new" }
49
+ format.xml { render :xml => @category.errors, :status => :unprocessable_entity }
50
+ end
51
+ end
52
+ end
53
+
54
+ # PUT /categories/1
55
+ # PUT /categories/1.xml
56
+ def update
57
+ @category = Category.find(params[:id])
58
+
59
+ respond_to do |format|
60
+ if @category.update_attributes(params[:category])
61
+ flash[:notice] = 'Category was successfully updated.'
62
+ format.html { redirect_to(admin_categories_url) }
63
+ format.xml { head :ok }
64
+ else
65
+ format.html { render :action => "edit" }
66
+ format.xml { render :xml => @category.errors, :status => :unprocessable_entity }
67
+ end
68
+ end
69
+ end
70
+
71
+ # DELETE /categories/1
72
+ # DELETE /categories/1.xml
73
+ def destroy
74
+ @category = Category.find(params[:id])
75
+ @category.destroy
76
+ flash[:notice] = 'Category was successfully deleted.'
77
+
78
+ respond_to do |format|
79
+ format.html { redirect_to(admin_categories_url) }
80
+ format.xml { head :ok }
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,30 @@
1
+ class Admin::CommentsController < Admin::BaseController
2
+ sortable_attributes :created_at, :name, :comment
3
+
4
+ def index
5
+
6
+ case
7
+ when params[:article_id]
8
+ @commentable = Article.find_by_id( params[:article_id] )
9
+ @comments = @commentable.comments.paginate :page => params[:page], :order => sort_order
10
+ else
11
+ @comments = Comment.paginate :page => params[:page], :order => sort_order
12
+ end
13
+
14
+ respond_to do |format|
15
+ format.html # index.html.erb
16
+ format.xml { render :xml => @articles }
17
+ end
18
+ end
19
+
20
+ def destroy
21
+ @comment = Comment.find(params[:id])
22
+ @comment.destroy
23
+ flash[:notice] = 'Comment was successfully deleted.'
24
+
25
+ respond_to do |format|
26
+ format.html { redirect_to( :back ) }
27
+ format.xml { head :ok }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ class ArticlesController < ApplicationController
2
+
3
+ def index
4
+ @page_title = 'Articles'
5
+ if params[:category_id]
6
+ @category = Category.find_by_permalink(params[:category_id])
7
+ @page_title << " in category #{@category.title}"
8
+ end
9
+ if params[:tag]
10
+ @page_title << " tagged with '#{params[:tag]}'"
11
+ end
12
+ if params[:user_id]
13
+ @user = User.find(params[:user_id])
14
+ @page_title << " writen by 'params[:tag]'"
15
+ end
16
+ if params[:year]
17
+ @page_title << " from #{params[:day]} #{Date::MONTHNAMES[params[:month].to_i] unless params[:month].nil?} #{params[:year]}"
18
+ end
19
+
20
+ @articles = Article.in_time_delta( params[:year], params[:month], params[:day] ).published.tagged_with(params[:tag], :on => :tags).authored_by(params[:user_id]).categorised(@category).paginate( :page => params[:page], :per_page => params[:per_page] || 6, :order => 'published_at DESC', :include => [:created_by] )
21
+
22
+ @tags = Article.published.authored_by(params[:user_id]).categorised(@category).tag_counts
23
+
24
+ respond_to do |format|
25
+ format.html # index.html.erb
26
+ format.xml { render :xml => @articles }
27
+ format.json { render :json => @articles }
28
+ format.rss
29
+ end
30
+ end
31
+
32
+ def show
33
+ @article = Article.published.find_by_permalink(params[:year], params[:month], params[:day], params[:permalink])
34
+
35
+ @page_title = @article.title
36
+ @page_description = @article.description
37
+ @page_keywords = @article.tag_list
38
+
39
+ @tags = @article.tag_counts
40
+
41
+ respond_to do |format|
42
+ format.html # show.html.erb
43
+ format.xml { render :xml => @article }
44
+ end
45
+ end
46
+
47
+ def preview
48
+ @page_class = 'show'
49
+ @article = Article.new(session[:article_preview])
50
+ @article.published_at = Time.now
51
+ @article.permalink = 'preview'
52
+ session[:article_preview] = nil
53
+ render :action => "show"
54
+ end
55
+ end
@@ -0,0 +1,50 @@
1
+ class CommentsController < ApplicationController
2
+
3
+ before_filter :find_commentable
4
+
5
+ def create
6
+ raise ActionController::UnknownAction unless @commentable.allow_comments?
7
+
8
+ @comment = @commentable.comments.build(params[:comment])
9
+
10
+ unless Settings.defensio_api_key.blank?
11
+ viking_response = viking.check_comment( :user_ip => request.remote_ip,
12
+ :article_date => @commentable.published_at,
13
+ :comment_author => @comment.author,
14
+ :comment_type => 'comment',
15
+ :comment_content => @comment.comment,
16
+ :comment_author_email => @comment.email,
17
+ :user_logged_in => logged_in?,
18
+ :referrer => request.referer,
19
+ :permalink => permalink( @commentable ))
20
+
21
+
22
+ logger.info "VIKING RESPONSE: #{viking_response.inspect}"
23
+ @comment.spam_filter = !viking_response[:spam]
24
+ else
25
+ @comment.spam_filter = true
26
+ end
27
+
28
+ respond_to do |format|
29
+ if @comment.save
30
+ format.html { redirect_to permalink( @commentable, :anchor => "comment-#{@comment.id}" ) }
31
+ format.json { render :json => @comment.to_json(:except => [:commentable_type, :commentable_id ]), :status => :created, :location => permalink(@commentable, :anchor => "comment-#{@comment.id}") }
32
+ else
33
+ format.html { render :action => 'new' }
34
+ format.json { render :json => @comment.errors.full_messages, :status => :unprocessable_entity }
35
+ end
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ def find_commentable
42
+ case
43
+ when params[:article_id]
44
+ @commentable = Article.published.find(params[:article_id])
45
+ end
46
+
47
+ raise ActionController::UnknownAction if @commentable.nil?
48
+ end
49
+
50
+ end
@@ -0,0 +1,92 @@
1
+ module ArticlesHelper
2
+
3
+ def article_categories
4
+ tabs = Category.with( :articles ).collect do |category|
5
+ content_tag :li, link_to( h(category.title), [category, :articles] )
6
+ end
7
+ content_tag( :h2, 'Categories' ) + content_tag( :ul, tabs.join, :class => "categories" )
8
+ end
9
+
10
+ def comments_link(article)
11
+ if(article.comments.count!=0)
12
+ "|&nbsp;&nbsp;#{link_to('Comment'.pluralize, article_permalink(article, :anchor => 'comments'))} (#{article.comments.count.to_s})"
13
+ else
14
+ "#{(article.commentable?)? '|' : ''}&nbsp;&nbsp;#{link_to 'Comment', article_permalink(article, :anchor => 'comments') if article.commentable?}"
15
+ end
16
+ end
17
+
18
+ def digg_link(article, html_options = {})
19
+ link_to 'Digg', "http://digg.com/submit?phase=2&amp;url=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'digg-submit', :title => 'Digg this!')
20
+ end
21
+
22
+ def delicious_link(article, html_options = {})
23
+ link_to 'delicious', "http://del.icio.us/post?url=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'delicious-submit', :title => 'Save to delicious')
24
+ end
25
+
26
+ def facebook_link(article, html_options = {})
27
+ link_to 'Facebook', "http://www.facebook.com/sharer.php?u=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'facebook-submit', :title => 'Share on Facebook')
28
+ end
29
+
30
+ def stumble_link(article, html_options = {})
31
+ link_to 'Stumble Upon', "http://www.stumbleupon.com/submit?url=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'stumble-submit', :title => 'Stumble on this')
32
+ end
33
+
34
+ def mail_link(article, html_options = {})
35
+ mail_to nil, "Email", html_options.reverse_merge( :subject => article.title, :body => article_permalink(article, :only_path => false), :class => 'share-link', :id => 'mail-link', :title => 'Email this to a friend')
36
+ end
37
+
38
+ def twitter_link(article, html_options = {})
39
+ link_to 'Twitter', "http://twitter.com/home?status=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'twitter-submit', :title => 'Tweet this')
40
+ end
41
+
42
+ def reddit_link(article, html_options = {})
43
+ link_to 'Reddit', "http://www.reddit.com/submit?url=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'reddit-submit', :title => 'Reddit this!')
44
+ end
45
+
46
+ def technorati_link(article, html_options = {})
47
+ link_to 'Technorati', "http://technorati.com/faves/?add=#{article_permalink(article, :only_path => false)}", html_options.reverse_merge(:class => 'share-link', :id => 'technorati-submit', :title => 'Technorati this!')
48
+ end
49
+
50
+ def archive(options = {} )
51
+ this_year = params[:year] || Time.now.year
52
+ html = ''
53
+
54
+ all_articles = Article.find(:all, :select => 'published_at', :order => "published_at DESC", :conditions => ['published_at <= ?', Time.now ])
55
+ grouped_by_year = all_articles.group_by{ |a| a.published_at.year }.sort.reverse
56
+ grouped_by_year.each do |year, articles|
57
+ html << '<li>'
58
+ html << link_to("#{year}", {:controller => '/articles', :action => 'index', :year => year, :month => nil, :day => nil})
59
+ html << (" (#{articles.size})")
60
+ if this_year.to_i == year
61
+ grouped_by_month = articles.group_by{ |a| a.published_at.month }.sort.reverse
62
+ html << '<ul>'
63
+ grouped_by_month.each do |month, articles|
64
+ html << '<li>'
65
+ html << link_to("#{Date::MONTHNAMES[month]}", {:controller => '/articles', :action => 'index', :year => year, :month => month, :day => nil})
66
+ html << (" (#{articles.size})")
67
+ html << '</li>'
68
+ end
69
+ html << '</ul>'
70
+ end
71
+ html << '</li>'
72
+ end
73
+ content_tag :ul, html, options.reverse_merge!( :class => 'archive' ) unless html.empty?
74
+ end
75
+
76
+ def related_articles(content_node)
77
+ articles = Article.find_tagged_with content_node.tag_list, :conditions => ['published_at <= ? AND content_nodes.id != ?', Time.now, content_node.id ], :limit => 3, :include => :created_by
78
+ articles_list(articles)
79
+ end
80
+
81
+ def recent_articles(limit = 3)
82
+ articles = Article.published.all( :limit => limit, :order => 'published_at DESC')
83
+ articles_list(articles)
84
+ end
85
+
86
+ def articles_list(articles)
87
+ return if articles.empty?
88
+ articles.collect! { |article| content_tag( 'li', "#{link_to(article.title, article_permalink(article))}") }
89
+ content_tag( 'ul', articles.join, :class => 'article-list' )
90
+ end
91
+
92
+ end