savage-beast 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/README.rdoc +42 -0
- data/Rakefile +25 -0
- data/VERSION +1 -0
- data/app/controllers/application.rb +6 -0
- data/app/controllers/beast_application_controller.rb +3 -0
- data/app/controllers/forums_controller.rb +64 -0
- data/app/controllers/moderators_controller.rb +10 -0
- data/app/controllers/monitorships_controller.rb +22 -0
- data/app/controllers/posts_controller.rb +134 -0
- data/app/controllers/topics_controller.rb +110 -0
- data/app/helpers/count_helper.rb +13 -0
- data/app/helpers/forums_helper.rb +15 -0
- data/app/helpers/moderators_helper.rb +2 -0
- data/app/helpers/monitorships_helper.rb +2 -0
- data/app/helpers/posts_helper.rb +3 -0
- data/app/helpers/topics_helper.rb +3 -0
- data/app/models/forum.rb +26 -0
- data/app/models/moderatorship.rb +6 -0
- data/app/models/monitorship.rb +5 -0
- data/app/models/monitorships_sweeper.rb +9 -0
- data/app/models/post.rb +33 -0
- data/app/models/posts_sweeper.rb +12 -0
- data/app/models/topic.rb +94 -0
- data/app/views/forums/_form.html.erb +21 -0
- data/app/views/forums/edit.html.erb +12 -0
- data/app/views/forums/index.html.erb +77 -0
- data/app/views/forums/new.html.erb +10 -0
- data/app/views/forums/show.html.erb +94 -0
- data/app/views/layouts/_head.html.erb +34 -0
- data/app/views/layouts/_post.rss.builder +9 -0
- data/app/views/layouts/application.html.erb +29 -0
- data/app/views/layouts/beast.html.erb +29 -0
- data/app/views/monitorships/create.js.rjs +4 -0
- data/app/views/monitorships/destroy.js.rjs +4 -0
- data/app/views/posts/_edit.html.erb +38 -0
- data/app/views/posts/edit.html.erb +14 -0
- data/app/views/posts/edit.js.rjs +6 -0
- data/app/views/posts/index.html.erb +53 -0
- data/app/views/posts/index.rss.builder +20 -0
- data/app/views/posts/monitored.html.erb +55 -0
- data/app/views/posts/monitored.rss.builder +15 -0
- data/app/views/posts/update.js.rjs +3 -0
- data/app/views/topics/_form.html.erb +28 -0
- data/app/views/topics/edit.html.erb +10 -0
- data/app/views/topics/index.html.erb +2 -0
- data/app/views/topics/new.html.erb +18 -0
- data/app/views/topics/show.html.erb +183 -0
- data/app/views/topics/show.rss.builder +16 -0
- data/config/routes.rb +18 -0
- data/generators/beast/beast_generator.rb +88 -0
- data/generators/beast/templates/migrations/create_savage_tables.rb +73 -0
- data/generators/beast/templates/public/images/clearbits/_readme.txt +12 -0
- data/generators/beast/templates/public/images/clearbits/add.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/addressbook.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/alert.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/apple.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_e.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_n.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_ne.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_nw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_s.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_se.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_sw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow1_w.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_e.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_n.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_ne.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_nw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_s.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_se.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_sw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow2_w.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_e.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_n.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_ne.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_nw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_s.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_se.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_sw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/arrow3_w.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/ascii.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/back.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_blank.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_circle.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_rounded.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_rounded_ne.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_rounded_nw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_rounded_se.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bg_rounded_sw.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bigsmile.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/binary.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/blah.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/bstop.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/buy.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/calday.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/calendar.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/camera.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/cart.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/cd.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/cellphone.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/chat.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/check.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/close.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/comment.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/cube.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/day.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/denied.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/document.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/download.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/edit.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/eject.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/equalizer.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/first.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/flag.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/flash.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/folder.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/forward.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/frown.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/ftp.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/graph.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/heart.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/home.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/html.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/ipod.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/last.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/lock.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/loop.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/mail.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/man.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/manman.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/music.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/mute.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/mute_centered.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/newwindow.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/next.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/night.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/open.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/pause.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/phone.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/play.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/previous.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/quicktime.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/redo.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/reload.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/sad.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/save.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/scream.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/search.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/seconds.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/smile.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/smirk.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/star.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/stop.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/subtract.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/switch.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/target.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/tcp.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/time.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/toggle.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/tongue.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/tools.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/trackback.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/trash.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/tv.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/type.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/undo.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/unlock.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/upload.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/user.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/video.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/volume_high.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/volume_low.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/wifi.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/window.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/woman.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/womanman.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/work.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/zoomin.gif +0 -0
- data/generators/beast/templates/public/images/clearbits/zoomout.gif +0 -0
- data/generators/beast/templates/public/images/feed-icon.png +0 -0
- data/generators/beast/templates/public/images/rails.png +0 -0
- data/generators/beast/templates/public/images/reply_background.png +0 -0
- data/generators/beast/templates/public/images/small_circle.gif +0 -0
- data/generators/beast/templates/public/images/spinner.gif +0 -0
- data/generators/beast/templates/public/images/spinner_black.gif +0 -0
- data/generators/beast/templates/public/images/spinner_bounce.gif +0 -0
- data/generators/beast/templates/public/javascripts/beast.js +80 -0
- data/generators/beast/templates/public/stylesheets/display.css +941 -0
- data/lang/en.yml +206 -0
- data/lib/beast.rb +79 -0
- data/lib/savage_beast/application_helper.rb +91 -0
- data/lib/savage_beast/authentication_system.rb +47 -0
- data/lib/savage_beast/user_init.rb +79 -0
- data/lib/tasks/capistrano.rake +90 -0
- data/lib/tasks/deploy_edge.rake +44 -0
- data/lib/tasks/savage_beast.rake +133 -0
- data/po/beast.pot +712 -0
- data/po/nl/beast.po +700 -0
- data/tested_plugins/acts_as_list/README +23 -0
- data/tested_plugins/acts_as_list/init.rb +3 -0
- data/tested_plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
- data/tested_plugins/acts_as_list/test/list_test.rb +332 -0
- data/tested_plugins/gibberish/LICENSE +18 -0
- data/tested_plugins/gibberish/README +118 -0
- data/tested_plugins/gibberish/Rakefile +14 -0
- data/tested_plugins/gibberish/init.rb +3 -0
- data/tested_plugins/gibberish/lang/es.yml +3 -0
- data/tested_plugins/gibberish/lang/fr.yml +3 -0
- data/tested_plugins/gibberish/lib/gibberish.rb +8 -0
- data/tested_plugins/gibberish/lib/gibberish/localize.rb +88 -0
- data/tested_plugins/gibberish/lib/gibberish/string_ext.rb +17 -0
- data/tested_plugins/gibberish/test/gibberish_test.rb +203 -0
- data/tested_plugins/gibberish/test/lang/es.yml +1 -0
- data/tested_plugins/gibberish/test/lang/fr.yml +1 -0
- data/tested_plugins/mislav-will_paginate/CHANGELOG.rdoc +110 -0
- data/tested_plugins/mislav-will_paginate/LICENSE +18 -0
- data/tested_plugins/mislav-will_paginate/README.rdoc +107 -0
- data/tested_plugins/mislav-will_paginate/Rakefile +53 -0
- data/tested_plugins/mislav-will_paginate/examples/apple-circle.gif +0 -0
- data/tested_plugins/mislav-will_paginate/examples/index.haml +69 -0
- data/tested_plugins/mislav-will_paginate/examples/index.html +92 -0
- data/tested_plugins/mislav-will_paginate/examples/pagination.css +90 -0
- data/tested_plugins/mislav-will_paginate/examples/pagination.sass +91 -0
- data/tested_plugins/mislav-will_paginate/init.rb +1 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate.rb +78 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/array.rb +16 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/collection.rb +146 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/core_ext.rb +32 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/finder.rb +264 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope.rb +170 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope_patch.rb +37 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/version.rb +9 -0
- data/tested_plugins/mislav-will_paginate/lib/will_paginate/view_helpers.rb +402 -0
- data/tested_plugins/mislav-will_paginate/test/boot.rb +21 -0
- data/tested_plugins/mislav-will_paginate/test/collection_test.rb +143 -0
- data/tested_plugins/mislav-will_paginate/test/console +8 -0
- data/tested_plugins/mislav-will_paginate/test/database.yml +22 -0
- data/tested_plugins/mislav-will_paginate/test/finder_test.rb +476 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/admin.rb +3 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/developer.rb +14 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/developers_projects.yml +13 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/project.rb +15 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/projects.yml +6 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/replies.yml +29 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/reply.rb +7 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/schema.rb +38 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/topic.rb +10 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/topics.yml +30 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/user.rb +2 -0
- data/tested_plugins/mislav-will_paginate/test/fixtures/users.yml +35 -0
- data/tested_plugins/mislav-will_paginate/test/helper.rb +40 -0
- data/tested_plugins/mislav-will_paginate/test/lib/activerecord_test_case.rb +43 -0
- data/tested_plugins/mislav-will_paginate/test/lib/activerecord_test_connector.rb +75 -0
- data/tested_plugins/mislav-will_paginate/test/lib/load_fixtures.rb +11 -0
- data/tested_plugins/mislav-will_paginate/test/lib/view_test_process.rb +178 -0
- data/tested_plugins/mislav-will_paginate/test/tasks.rake +59 -0
- data/tested_plugins/mislav-will_paginate/test/view_test.rb +365 -0
- data/tested_plugins/white_list/README +29 -0
- data/tested_plugins/white_list/Rakefile +22 -0
- data/tested_plugins/white_list/init.rb +2 -0
- data/tested_plugins/white_list/lib/white_list_helper.rb +97 -0
- data/tested_plugins/white_list/test/white_list_test.rb +132 -0
- data/tested_plugins/white_list_formatted_content/init.rb +27 -0
- metadata +322 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
module ForumsHelper
|
2
|
+
|
3
|
+
# used to know if a topic has changed since we read it last
|
4
|
+
def recent_topic_activity(topic)
|
5
|
+
return false if not logged_in?
|
6
|
+
return topic.replied_at > ((session[:topics] && session[:topics][topic.id]) || 3.days.ago) # was: last_active. TODO: Could implement something to look at the user
|
7
|
+
end
|
8
|
+
|
9
|
+
# used to know if a forum has changed since we read it last
|
10
|
+
def recent_forum_activity(forum)
|
11
|
+
return false unless logged_in? && forum.recent_topic
|
12
|
+
return forum.recent_topic.replied_at > ((session[:forums] && session[:forums][forum.id]) || 3.days.ago) # was: last_active. TODO: Could implement something to look at the user
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/app/models/forum.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Forum < ActiveRecord::Base
|
2
|
+
acts_as_list
|
3
|
+
|
4
|
+
validates_presence_of :name
|
5
|
+
|
6
|
+
has_many :moderatorships, :dependent => :delete_all
|
7
|
+
has_many :moderators, :through => :moderatorships, :source => :user
|
8
|
+
|
9
|
+
has_many :topics, :order => 'sticky desc, replied_at desc', :dependent => :delete_all
|
10
|
+
has_one :recent_topic, :class_name => 'Topic', :order => 'sticky desc, replied_at desc'
|
11
|
+
|
12
|
+
# this is used to see if a forum is "fresh"... we can't use topics because it puts
|
13
|
+
# stickies first even if they are not the most recently modified
|
14
|
+
has_many :recent_topics, :class_name => 'Topic', :order => 'replied_at DESC'
|
15
|
+
has_one :recent_topic, :class_name => 'Topic', :order => 'replied_at DESC'
|
16
|
+
|
17
|
+
has_many :posts, :order => "#{Post.table_name}.created_at DESC", :dependent => :delete_all
|
18
|
+
has_one :recent_post, :order => "#{Post.table_name}.created_at DESC", :class_name => 'Post'
|
19
|
+
|
20
|
+
format_attribute :description
|
21
|
+
|
22
|
+
# retrieves forums ordered by position
|
23
|
+
def self.find_ordered(options = {})
|
24
|
+
find :all, options.update(:order => 'position')
|
25
|
+
end
|
26
|
+
end
|
data/app/models/post.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
def self.per_page() 25 end
|
3
|
+
|
4
|
+
belongs_to :forum
|
5
|
+
belongs_to :user
|
6
|
+
belongs_to :topic
|
7
|
+
|
8
|
+
format_attribute :body
|
9
|
+
before_create { |r| r.forum_id = r.topic.forum_id }
|
10
|
+
after_create :update_cached_fields
|
11
|
+
after_destroy :update_cached_fields
|
12
|
+
|
13
|
+
validates_presence_of :user_id, :body, :topic
|
14
|
+
attr_accessible :body
|
15
|
+
|
16
|
+
def editable_by?(user)
|
17
|
+
user && (user.id == user_id || user.admin? || user.moderator_of?(forum_id))
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_xml(options = {})
|
21
|
+
options[:except] ||= []
|
22
|
+
options[:except] << :topic_title << :forum_name
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
# using count isn't ideal but it gives us correct caches each time
|
28
|
+
def update_cached_fields
|
29
|
+
Forum.update_all ['posts_count = ?', Post.count(:id, :conditions => {:forum_id => forum_id})], ['id = ?', forum_id]
|
30
|
+
User.update_posts_count(user_id)
|
31
|
+
topic.update_cached_post_fields(self)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class PostsSweeper < ActionController::Caching::Sweeper
|
2
|
+
observe Post
|
3
|
+
|
4
|
+
def after_save(post)
|
5
|
+
FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'forums', post.forum_id.to_s, 'posts.rss')
|
6
|
+
FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'forums', post.forum_id.to_s, 'topics', "#{post.topic_id}.rss")
|
7
|
+
FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'users')
|
8
|
+
FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'posts.rss')
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method :after_destroy, :after_save
|
12
|
+
end
|
data/app/models/topic.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
class Topic < ActiveRecord::Base
|
2
|
+
validates_presence_of :forum, :user, :title
|
3
|
+
before_create :set_default_replied_at_and_sticky
|
4
|
+
before_update :check_for_changing_forums
|
5
|
+
after_save :update_forum_counter_cache
|
6
|
+
before_destroy :update_post_user_counts
|
7
|
+
after_destroy :update_forum_counter_cache
|
8
|
+
|
9
|
+
belongs_to :forum
|
10
|
+
belongs_to :user
|
11
|
+
belongs_to :last_post, :class_name => "Post", :foreign_key => 'last_post_id'
|
12
|
+
has_many :monitorships
|
13
|
+
has_many :monitors, :through => :monitorships, :conditions => ["#{Monitorship.table_name}.active = ?", true], :source => :user
|
14
|
+
|
15
|
+
has_many :posts, :order => "#{Post.table_name}.created_at", :dependent => :delete_all
|
16
|
+
has_one :recent_post, :order => "#{Post.table_name}.created_at DESC", :class_name => 'Post'
|
17
|
+
|
18
|
+
has_many :voices, :through => :posts, :source => :user, :uniq => true
|
19
|
+
belongs_to :replied_by_user, :foreign_key => "replied_by", :class_name => "User"
|
20
|
+
|
21
|
+
attr_accessible :title
|
22
|
+
# to help with the create form
|
23
|
+
attr_accessor :body
|
24
|
+
|
25
|
+
def hit!
|
26
|
+
self.class.increment_counter :hits, id
|
27
|
+
end
|
28
|
+
|
29
|
+
def sticky?() sticky == 1 end
|
30
|
+
|
31
|
+
def views() hits end
|
32
|
+
|
33
|
+
def paged?() posts_count > Post.per_page end
|
34
|
+
|
35
|
+
def last_page
|
36
|
+
[(posts_count.to_f / Post.per_page).ceil.to_i, 1].max
|
37
|
+
end
|
38
|
+
|
39
|
+
def editable_by?(user)
|
40
|
+
user && (user.id == user_id || user.admin? || user.moderator_of?(forum_id))
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_cached_post_fields(post)
|
44
|
+
# these fields are not accessible to mass assignment
|
45
|
+
remaining_post = post.frozen? ? recent_post : post
|
46
|
+
if remaining_post
|
47
|
+
self.class.update_all(['replied_at = ?, replied_by = ?, last_post_id = ?, posts_count = ?',
|
48
|
+
remaining_post.created_at, remaining_post.user_id, remaining_post.id, posts.count], ['id = ?', id])
|
49
|
+
else
|
50
|
+
self.destroy
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def set_default_replied_at_and_sticky
|
56
|
+
self.replied_at = Time.now.utc
|
57
|
+
self.sticky ||= 0
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_post_forum_id
|
61
|
+
Post.update_all ['forum_id = ?', forum_id], ['topic_id = ?', id]
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_for_changing_forums
|
65
|
+
old = Topic.find(id)
|
66
|
+
@old_forum_id = old.forum_id if old.forum_id != forum_id
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
# using count isn't ideal but it gives us correct caches each time
|
71
|
+
def update_forum_counter_cache
|
72
|
+
forum_conditions = ['topics_count = ?', Topic.count(:id, :conditions => {:forum_id => forum_id})]
|
73
|
+
# if the topic moved forums
|
74
|
+
if !frozen? && @old_forum_id && @old_forum_id != forum_id
|
75
|
+
set_post_forum_id
|
76
|
+
Forum.update_all ['topics_count = ?, posts_count = ?',
|
77
|
+
Topic.count(:id, :conditions => {:forum_id => @old_forum_id}),
|
78
|
+
Post.count(:id, :conditions => {:forum_id => @old_forum_id})], ['id = ?', @old_forum_id]
|
79
|
+
end
|
80
|
+
# if the topic moved forums or was deleted
|
81
|
+
if frozen? || (@old_forum_id && @old_forum_id != forum_id)
|
82
|
+
forum_conditions.first << ", posts_count = ?"
|
83
|
+
forum_conditions << Post.count(:id, :conditions => {:forum_id => forum_id})
|
84
|
+
end
|
85
|
+
# User doesn't have update_posts_count method in SB2, as reported by Ryan
|
86
|
+
#@voices.each &:update_posts_count if @voices
|
87
|
+
Forum.update_all forum_conditions, ['id = ?', forum_id]
|
88
|
+
@old_forum_id = @voices = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def update_post_user_counts
|
92
|
+
@voices = voices.to_a
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<p style="float:right; margin-top:0">
|
2
|
+
</p>
|
3
|
+
|
4
|
+
<p id="forum_name">
|
5
|
+
|
6
|
+
<table border="0" cellspacing="0" cellpadding="0" class="noborder nopad wide">
|
7
|
+
<td>
|
8
|
+
<%= form.label :name %><br />
|
9
|
+
<%= form.text_field :name, :class => "primary" %>
|
10
|
+
</td>
|
11
|
+
<td style="text-align:right">
|
12
|
+
<%=form.label :position %><br />
|
13
|
+
<%= form.text_field :position, :size => 5 %>
|
14
|
+
|
15
|
+
</td>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
</p>
|
19
|
+
<p id="forum_descripion">
|
20
|
+
<%= form.label(:description) %><br />
|
21
|
+
<%= form.text_area :description, :rows => 7 %></p>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="crumbs">
|
2
|
+
<%= link_to 'Forums'[:forums_title], forums_path %> <span class="arrow">→</span>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<h1><%= 'Edit Forum'[:edit_forum] %></h1>
|
6
|
+
|
7
|
+
<% form_for :forum,
|
8
|
+
:url => forum_path(@forum),
|
9
|
+
:html => { :method => :put } do |f| -%>
|
10
|
+
<%= render :partial => "form", :object => f %>
|
11
|
+
<%= submit_tag 'Save Forum'[:save_forum] -%> or <%= link_to('Cancel'[:cancel], forums_path) %>
|
12
|
+
<% end -%>
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<% content_for :right do %>
|
2
|
+
|
3
|
+
<% if admin? %>
|
4
|
+
<h6><%=t(:admin_title) %></h6>
|
5
|
+
<p><%= link_to t(:create_new_forum), new_forum_path, :class => "utility" %></p>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<h1 style="margin-top:0;"><%= t(:forums_title) %></h1>
|
11
|
+
<p class="subtitle">
|
12
|
+
<%= feed_icon_tag t(:recent_posts), all_posts_path(:format => 'rss') %>
|
13
|
+
<%= t(:topics_count, :count => Topic.count, :n => number_with_delimiter(Topic.count)) %>,
|
14
|
+
<%= t(:posts_count, :count => Post.count, :n => number_with_delimiter(Post.count)) %>,
|
15
|
+
<% users_count = User.count(:conditions => "posts_count > 0") %>
|
16
|
+
<%= t(:voices_count, :count => users_count, :n => number_with_delimiter(users_count)) %>
|
17
|
+
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<table border="0" cellspacing="0" cellpadding="0" class="wide forums">
|
21
|
+
<tr>
|
22
|
+
<th class="la" width="70%" colspan="3"><%= t(:forum_title) %></th>
|
23
|
+
<!--
|
24
|
+
<th width="5%">Topics</th>
|
25
|
+
<th width="5%">Posts</th>
|
26
|
+
-->
|
27
|
+
<th class="la" width="30%" colspan="1"><%= t(:last_post) %></th>
|
28
|
+
</tr>
|
29
|
+
<% for forum in @forums do %>
|
30
|
+
<tr>
|
31
|
+
<td class="vat c1">
|
32
|
+
|
33
|
+
<% if recent_forum_activity(forum) %>
|
34
|
+
<%= image_tag "savage_beast/clearbits/comment.gif", :class => "icon green", :title => 'Recent activity'[:recent_activity] %>
|
35
|
+
<% else %>
|
36
|
+
<%= image_tag "savage_beast/clearbits/comment.gif", :class => "icon grey", :title => 'No recent activity'[:no_recent_activity] %>
|
37
|
+
<% end %>
|
38
|
+
</td>
|
39
|
+
<td class="c2 vat">
|
40
|
+
<%= link_to h(forum.name), forum_path(forum), :class => "title" %>
|
41
|
+
<div class="posts">
|
42
|
+
<%= t(:topics_count, :count => forum.topics.size, :n => number_with_delimiter(forum.topics.size)) %>,
|
43
|
+
<%= t(:posts_count, :count => forum.posts.size, :n => number_with_delimiter(forum.posts.size)) %>
|
44
|
+
</div>
|
45
|
+
<p class="desc"><%= forum.description_html %>
|
46
|
+
</p>
|
47
|
+
</td>
|
48
|
+
<td class="c3">
|
49
|
+
<%= link_to t(:edit_title), edit_forum_path(forum), :class => "tiny", :rel => "directory", :style => "float:right" if admin? %>
|
50
|
+
</td>
|
51
|
+
|
52
|
+
<td class="inv lp">
|
53
|
+
<% if forum.recent_post %>
|
54
|
+
<%= time_ago_in_words(forum.recent_post.created_at) %><br />
|
55
|
+
<%= t(:by_user, :user => "<strong>#{h(forum.recent_post.user.display_name)}</strong>") %>
|
56
|
+
<span>(<%= link_to t(:view), forum_topic_path(:forum_id => forum, :id => forum.recent_post.topic_id, :page => forum.recent_post.topic.last_page, :anchor => forum.recent_post.dom_id) %>)</span>
|
57
|
+
<% end %>
|
58
|
+
</td>
|
59
|
+
</tr>
|
60
|
+
<% end %>
|
61
|
+
</table>
|
62
|
+
|
63
|
+
<p>
|
64
|
+
<%= link_to t(:recent_posts), all_posts_path %>
|
65
|
+
</p>
|
66
|
+
|
67
|
+
<% online_users = User.currently_online -%>
|
68
|
+
<% unless !online_users || online_users.empty? %>
|
69
|
+
<div class="stats">
|
70
|
+
<div class="users">
|
71
|
+
<% unless !online_users || online_users.empty? %>
|
72
|
+
<%= t(:users_online) %> <%= online_users.map { |u| link_to "<strong>#{h u.display_name}</strong>", user_path(u) } * ", " %><br />
|
73
|
+
<% end %>
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
<% end %>
|
77
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="crumbs">
|
2
|
+
<%= link_to "Forums"[:forums_title], forums_path %> <span class="arrow">→</span>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<h1><%= t(:new_forum) %></h1>
|
6
|
+
|
7
|
+
<% form_for :forum, :url => forums_path do |f| -%>
|
8
|
+
<%= render :partial => "form", :object => f %>
|
9
|
+
<%= submit_tag t(:create) -%> <%= t(:or) %> <%= link_to(t(:cancel), forums_path) -%>
|
10
|
+
<% end -%>
|
@@ -0,0 +1,94 @@
|
|
1
|
+
<% content_for :right do %>
|
2
|
+
|
3
|
+
<% unless @forum.description.blank? %>
|
4
|
+
<%= @forum.description_html %>
|
5
|
+
<hr />
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<h5 style="margin-bottom:1.0em;"><%= t(:moderators_title) %></h5>
|
9
|
+
|
10
|
+
<% unless @forum.moderators.empty? -%>
|
11
|
+
<ul class="flat" style="margin-top:1em;">
|
12
|
+
<% @forum.moderators.each do |user| -%>
|
13
|
+
<li><%= link_to user.display_name, user_path(user) %></li>
|
14
|
+
<% end -%>
|
15
|
+
</ul>
|
16
|
+
<% else -%>
|
17
|
+
<p><%= t(:forum_is_unmoderated) %></p>
|
18
|
+
<p><%= t(:please_be_courteous) %></p>
|
19
|
+
<% end -%>
|
20
|
+
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% @page_title = @forum.name %>
|
24
|
+
|
25
|
+
<div class="crumbs">
|
26
|
+
<%= link_to t(:forums_title), forums_path %> <span class="arrow">→</span>
|
27
|
+
</div>
|
28
|
+
<h1 style="margin-top:0.5em">
|
29
|
+
<%= h @forum.name %>
|
30
|
+
</h1>
|
31
|
+
|
32
|
+
<p class="subtitle">
|
33
|
+
<%= feed_icon_tag @forum.name, forum_posts_path(@forum, :format => :rss) %>
|
34
|
+
<%= t(:topics_count, :count => @forum.topics.size, :n => number_with_delimiter(@forum.topics.size)) %>,
|
35
|
+
<%= t(:posts_count, :count => @forum.posts.size, :n => number_with_delimiter(@forum.posts.size)) %>
|
36
|
+
</p>
|
37
|
+
|
38
|
+
<% if @topics.total_pages > 1 -%>
|
39
|
+
<% if logged_in? %>
|
40
|
+
<p style="float:right; margin-top:0;"><%= link_to t(:new_topic), new_forum_topic_path(@forum), :class => "utility" %></p>
|
41
|
+
<% end %>
|
42
|
+
<%= will_paginate @topics %>
|
43
|
+
<% end -%>
|
44
|
+
|
45
|
+
<table border="0" cellspacing="0" cellpadding="0" class="wide topics">
|
46
|
+
<tr>
|
47
|
+
<th class="la" colspan="2"><%= t(:topic_title) %></th>
|
48
|
+
<th width="1%"><%= t(:posts_title) %></th>
|
49
|
+
<th width="1%"><%= t(:views_title) %></th>
|
50
|
+
<th class="la"><%= t(:last_post) %></th>
|
51
|
+
</tr>
|
52
|
+
<% for topic in @topics %>
|
53
|
+
<tr class="hentry">
|
54
|
+
<td style="padding:5px; width:16px;" class="c1">
|
55
|
+
<%
|
56
|
+
icon = "comment"
|
57
|
+
color = ""
|
58
|
+
if topic.locked?
|
59
|
+
icon = "lock"
|
60
|
+
post = ", this topic is locked."[:comma_locked_topic]
|
61
|
+
color = "darkgrey"
|
62
|
+
end
|
63
|
+
%>
|
64
|
+
<% if recent_topic_activity(topic) %>
|
65
|
+
<%= image_tag "savage_beast/clearbits/#{icon}.gif", :class => "icon green", :title => "Recent activity"[]+"#{post}" %>
|
66
|
+
<% else %>
|
67
|
+
<%= image_tag "savage_beast/clearbits/#{icon}.gif", :class => "icon grey #{color}", :title => "No recent activity"[]+"#{post}" %>
|
68
|
+
<% end %>
|
69
|
+
</td>
|
70
|
+
<td class="c2">
|
71
|
+
<%= "Sticky"[:sticky_title]+": <strong>" if topic.sticky? %>
|
72
|
+
<%= topic_title_link (topic), :class => "entry-title", :rel => "bookmark" %>
|
73
|
+
<%#= link_to h(topic.title), topic_path(@forum, topic), :class => "entry-title", :rel => "bookmark" %>
|
74
|
+
<%= "</strong>" if topic.sticky? %>
|
75
|
+
<% if topic.paged? -%>
|
76
|
+
<small><%= link_to 'last'[], forum_topic_path(:forum_id => @forum, :id => topic, :page => topic.last_page) %></small>
|
77
|
+
<% end -%>
|
78
|
+
</td>
|
79
|
+
<td class="ca inv stat"><%= topic.posts.size %></td>
|
80
|
+
<td class="ca inv stat"><%= number_with_delimiter(topic.views) %></td>
|
81
|
+
<td class="lp">
|
82
|
+
<abbr class="updated" title="<%= topic.replied_at.xmlschema %>"><%= time_ago_in_words(topic.replied_at) %></abbr>
|
83
|
+
<%= 'by {user}'[:by_user, "<span class=\"author\"><strong class=\"fn\">#{h(topic.replied_by_user.display_name)}</strong></span>"] %>
|
84
|
+
<span><%= link_to 'view'[], forum_topic_path(:forum_id => @forum, :id => topic, :page => topic.last_page, :anchor => "posts-#{topic.last_post_id}") %></span>
|
85
|
+
</td>
|
86
|
+
</tr>
|
87
|
+
<% end %>
|
88
|
+
</table>
|
89
|
+
|
90
|
+
<%= will_paginate @topics %>
|
91
|
+
|
92
|
+
<% if logged_in? %>
|
93
|
+
<p><%= link_to t(:new_topic), new_forum_topic_path(@forum), :class => "utility" %></p>
|
94
|
+
<% end%>
|