thredded 0.0.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.mkdn +46 -0
- data/Rakefile +31 -0
- data/app/assets/javascripts/thredded/application.js +15 -0
- data/app/assets/stylesheets/thredded/application.css +13 -0
- data/app/controllers/thredded/application_controller.rb +50 -0
- data/app/controllers/thredded/messageboards_controller.rb +9 -0
- data/app/controllers/thredded/posts_controller.rb +86 -0
- data/app/controllers/thredded/preferences_controller.rb +20 -0
- data/app/controllers/thredded/private_topics_controller.rb +25 -0
- data/app/controllers/thredded/setups_controller.rb +39 -0
- data/app/controllers/thredded/topics_controller.rb +121 -0
- data/app/decorators/thredded/post_decorator.rb +52 -0
- data/app/decorators/thredded/topic_decorator.rb +96 -0
- data/app/helpers/thredded/application_helper.rb +9 -0
- data/app/helpers/thredded/messageboard_helper.rb +52 -0
- data/app/helpers/thredded/posts_helper.rb +7 -0
- data/app/helpers/thredded/topics_helper.rb +21 -0
- data/app/mailers/thredded/post_mailer.rb +28 -0
- data/app/mailers/thredded/topic_mailer.rb +29 -0
- data/app/models/thredded/ability.rb +50 -0
- data/app/models/thredded/attachment.rb +24 -0
- data/app/models/thredded/category.rb +10 -0
- data/app/models/thredded/image.rb +27 -0
- data/app/models/thredded/messageboard.rb +92 -0
- data/app/models/thredded/messageboard_decorator.rb +18 -0
- data/app/models/thredded/messageboard_preference.rb +15 -0
- data/app/models/thredded/null_preference.rb +9 -0
- data/app/models/thredded/null_topic_read.rb +13 -0
- data/app/models/thredded/null_user.rb +27 -0
- data/app/models/thredded/post.rb +75 -0
- data/app/models/thredded/post_notification.rb +6 -0
- data/app/models/thredded/private_topic.rb +33 -0
- data/app/models/thredded/private_user.rb +7 -0
- data/app/models/thredded/role.rb +18 -0
- data/app/models/thredded/topic.rb +145 -0
- data/app/models/thredded/topic_category.rb +7 -0
- data/app/models/thredded/user_detail.rb +6 -0
- data/app/models/thredded/user_extender.rb +27 -0
- data/app/models/thredded/user_preference.rb +6 -0
- data/app/models/thredded/user_topic_read.rb +67 -0
- data/app/uploaders/thredded/attachment_uploader.rb +30 -0
- data/app/uploaders/thredded/image_uploader.rb +17 -0
- data/app/views/thredded/messageboards/_messageboard.html.erb +17 -0
- data/app/views/thredded/messageboards/index.html.erb +15 -0
- data/app/views/thredded/post_mailer/at_notification.html.erb +17 -0
- data/app/views/thredded/post_mailer/at_notification.text.erb +13 -0
- data/app/views/thredded/posts/_form.html.erb +25 -0
- data/app/views/thredded/posts/_null_user.html.erb +0 -0
- data/app/views/thredded/posts/_post.html.erb +25 -0
- data/app/views/thredded/posts/_user.html.erb +7 -0
- data/app/views/thredded/posts/edit.html.erb +28 -0
- data/app/views/thredded/posts/index.html.erb +74 -0
- data/app/views/thredded/preferences/edit.html.erb +23 -0
- data/app/views/thredded/search/_form.html.erb +9 -0
- data/app/views/thredded/setups/_form.html.erb +35 -0
- data/app/views/thredded/setups/new.html.erb +5 -0
- data/app/views/thredded/shared/_currently_online.html.erb +10 -0
- data/app/views/thredded/shared/_error_msgs.html.erb +7 -0
- data/app/views/thredded/shared/_google_analytics.html.erb +10 -0
- data/app/views/thredded/shared/_topic_nav.html.erb +18 -0
- data/app/views/thredded/topic_mailer/message_notification.html.erb +17 -0
- data/app/views/thredded/topic_mailer/message_notification.text.erb +13 -0
- data/app/views/thredded/topics/_form.html.erb +6 -0
- data/app/views/thredded/topics/_topic_condensed.html.erb +20 -0
- data/app/views/thredded/topics/_topic_form.html.erb +27 -0
- data/app/views/thredded/topics/by_category.html.erb +51 -0
- data/app/views/thredded/topics/edit.html.erb +25 -0
- data/app/views/thredded/topics/index.html.erb +52 -0
- data/app/views/thredded/topics/menu/_new_topic.html.erb +3 -0
- data/app/views/thredded/topics/new.html.erb +18 -0
- data/app/views/thredded/topics/search.html.erb +45 -0
- data/config/routes.rb +26 -0
- data/db/migrate/20130425230852_create_thredded_tables.rb +143 -0
- data/lib/tasks/thredded_tasks.rake +4 -0
- data/lib/thredded.rb +38 -0
- data/lib/thredded/at_notification_extractor.rb +15 -0
- data/lib/thredded/at_notifier.rb +65 -0
- data/lib/thredded/at_users.rb +17 -0
- data/lib/thredded/email_processor.rb +74 -0
- data/lib/thredded/engine.rb +17 -0
- data/lib/thredded/filter.rb +4 -0
- data/lib/thredded/filter/at_notification.rb +11 -0
- data/lib/thredded/filter/attachment.rb +51 -0
- data/lib/thredded/filter/base.rb +13 -0
- data/lib/thredded/filter/bbcode.rb +75 -0
- data/lib/thredded/filter/emoji.rb +11 -0
- data/lib/thredded/filter/markdown.rb +25 -0
- data/lib/thredded/filter/syntax.rb +28 -0
- data/lib/thredded/filter/textile.rb +21 -0
- data/lib/thredded/messageboard_user_permissions.rb +27 -0
- data/lib/thredded/post_sql_builder.rb +34 -0
- data/lib/thredded/post_user_permissions.rb +37 -0
- data/lib/thredded/private_topic_notifier.rb +56 -0
- data/lib/thredded/private_topic_user_permissions.rb +32 -0
- data/lib/thredded/search_parser.rb +45 -0
- data/lib/thredded/search_sql_builder.rb +25 -0
- data/lib/thredded/setup_thredded.rb +7 -0
- data/lib/thredded/table_sql_builder.rb +105 -0
- data/lib/thredded/topic_sql_builder.rb +32 -0
- data/lib/thredded/topic_user_permissions.rb +51 -0
- data/lib/thredded/version.rb +3 -0
- metadata +537 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class PostDecorator < SimpleDelegator
|
|
3
|
+
attr_reader :post
|
|
4
|
+
|
|
5
|
+
def initialize(post)
|
|
6
|
+
super
|
|
7
|
+
@post = post
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def user_name
|
|
11
|
+
if user
|
|
12
|
+
user.name
|
|
13
|
+
else
|
|
14
|
+
'Anonymous'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def original
|
|
19
|
+
post
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def created_at_timeago
|
|
23
|
+
if created_at.nil?
|
|
24
|
+
<<-eohtml.strip_heredoc.html_safe
|
|
25
|
+
<abbr>
|
|
26
|
+
a little while ago
|
|
27
|
+
</abbr>
|
|
28
|
+
eohtml
|
|
29
|
+
else
|
|
30
|
+
<<-eohtml.strip_heredoc.html_safe
|
|
31
|
+
<abbr class="timeago" title="#{created_at_utc}">
|
|
32
|
+
#{created_at_str}
|
|
33
|
+
</abbr>
|
|
34
|
+
eohtml
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def gravatar_url
|
|
39
|
+
super.gsub /http:/, ''
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def created_at_str
|
|
45
|
+
created_at.getutc.to_s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def created_at_utc
|
|
49
|
+
created_at.getutc.iso8601
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class TopicDecorator < SimpleDelegator
|
|
3
|
+
include Rails.application.routes.url_helpers
|
|
4
|
+
include ActionView::Helpers::UrlHelper
|
|
5
|
+
|
|
6
|
+
attr_reader :topic
|
|
7
|
+
|
|
8
|
+
def initialize(topic)
|
|
9
|
+
super
|
|
10
|
+
@topic = topic
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def css_class
|
|
14
|
+
classes = []
|
|
15
|
+
classes << 'locked' if locked?
|
|
16
|
+
classes << 'sticky' if sticky?
|
|
17
|
+
classes << 'private' if private?
|
|
18
|
+
classes += ['category'] + categories.map(&:name) if categories.present?
|
|
19
|
+
classes.join(' ')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def user_link
|
|
23
|
+
if user.nil?
|
|
24
|
+
'<a href="#">?</a>'.html_safe
|
|
25
|
+
else
|
|
26
|
+
"<a href='/users/#{user_name}'>#{user_name}</a>".html_safe
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def last_user_link
|
|
31
|
+
if last_user.nil?
|
|
32
|
+
'Anonymous'
|
|
33
|
+
else
|
|
34
|
+
"<a href='/users/#{last_user.name}'>#{last_user.name}</a>".html_safe
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def original
|
|
39
|
+
topic
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def updated_at_timeago
|
|
43
|
+
if updated_at.nil?
|
|
44
|
+
<<-eohtml.html_safe
|
|
45
|
+
<abbr>
|
|
46
|
+
a little while ago
|
|
47
|
+
</abbr>
|
|
48
|
+
eohtml
|
|
49
|
+
else
|
|
50
|
+
<<-eohtml.html_safe
|
|
51
|
+
<abbr class="timeago" title="#{updated_at_utc}">
|
|
52
|
+
#{updated_at_str}
|
|
53
|
+
</abbr>
|
|
54
|
+
eohtml
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def created_at_timeago
|
|
59
|
+
if created_at.nil?
|
|
60
|
+
<<-eohtml.html_safe
|
|
61
|
+
<abbr class="started_at">
|
|
62
|
+
a little while ago
|
|
63
|
+
</abbr>
|
|
64
|
+
eohtml
|
|
65
|
+
else
|
|
66
|
+
<<-eohtml.html_safe
|
|
67
|
+
<abbr class="started_at timeago" title="#{created_at_utc}">
|
|
68
|
+
#{created_at_str}
|
|
69
|
+
</abbr>
|
|
70
|
+
eohtml
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def gravatar_url
|
|
75
|
+
super.gsub /http:/, ''
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def updated_at_str
|
|
81
|
+
updated_at.to_s
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def updated_at_utc
|
|
85
|
+
updated_at.getutc.iso8601
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def created_at_str
|
|
89
|
+
created_at.to_s
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def created_at_utc
|
|
93
|
+
created_at.getutc.iso8601
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
module MessageboardHelper
|
|
3
|
+
def link_or_text_to(messageboard)
|
|
4
|
+
if can? :read, messageboard
|
|
5
|
+
link_to messageboard.name, messageboard_topics_path(messageboard)
|
|
6
|
+
else
|
|
7
|
+
messageboard.name
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def meta_for(messageboard)
|
|
12
|
+
topics = messageboard.topics_count
|
|
13
|
+
posts = messageboard.posts_count
|
|
14
|
+
"#{number_to_human topics} topics,
|
|
15
|
+
#{number_to_human posts} posts".downcase
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def admin_link_for(messageboard)
|
|
19
|
+
if can? :manage, messageboard
|
|
20
|
+
'<p class="admin"><a href="#edit">Edit</a></p>'
|
|
21
|
+
else
|
|
22
|
+
''
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def latest_thread_for(messageboard)
|
|
27
|
+
topic = messageboard.topics.first
|
|
28
|
+
|
|
29
|
+
if topic.present?
|
|
30
|
+
abbr = content_tag :abbr, class: 'updated_at timeago', title: topic.updated_at.strftime('%Y-%m-%dT%H:%M:%S') do
|
|
31
|
+
topic.updated_at.strftime('%b %d, %Y %I:%M:%S %Z')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if can? :read, messageboard
|
|
35
|
+
link_to abbr , messageboard_topic_posts_path(messageboard, topic)
|
|
36
|
+
else
|
|
37
|
+
abbr
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
''
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def latest_user_for(messageboard)
|
|
45
|
+
if messageboard.topics.first.present? && messageboard.topics.first.user.present?
|
|
46
|
+
messageboard.topics.first.last_user.name
|
|
47
|
+
else
|
|
48
|
+
''
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
module TopicsHelper
|
|
3
|
+
require 'digest/md5'
|
|
4
|
+
|
|
5
|
+
def md5(s)
|
|
6
|
+
Digest::MD5.hexdigest(s)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def already_read(topic, tracked_user_reads)
|
|
10
|
+
if tracked_user_reads
|
|
11
|
+
topic_status = tracked_user_reads.select{ |t| t.topic_id == topic.id }.first
|
|
12
|
+
|
|
13
|
+
if topic_status && topic_status.posts_count == topic.posts_count
|
|
14
|
+
'read'
|
|
15
|
+
else
|
|
16
|
+
'unread'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class PostMailer < ActionMailer::Base
|
|
3
|
+
def at_notification(post_id, user_emails)
|
|
4
|
+
@post = Post.find(post_id)
|
|
5
|
+
|
|
6
|
+
headers['X-SMTPAPI'] = %Q{{"category": ["thredded_#{@post.messageboard.name}","at_notification"]}}
|
|
7
|
+
mail from: no_reply,
|
|
8
|
+
to: no_reply,
|
|
9
|
+
bcc: user_emails,
|
|
10
|
+
reply_to: reply_to,
|
|
11
|
+
subject: subject
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def subject
|
|
17
|
+
"#{Thredded.email_outgoing_prefix} #{@post.topic.title}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reply_to
|
|
21
|
+
"#{@post.topic.hash_id}@#{Thredded.email_incoming_host}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def no_reply
|
|
25
|
+
Thredded.email_from
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class TopicMailer < ActionMailer::Base
|
|
3
|
+
def message_notification(topic_id, emails)
|
|
4
|
+
@topic = Topic.find(topic_id)
|
|
5
|
+
headers['X-SMTPAPI'] =
|
|
6
|
+
%Q{{"category": ["thredded_#{@topic.messageboard.name}","at_notification"]}}
|
|
7
|
+
|
|
8
|
+
mail from: no_reply,
|
|
9
|
+
to: no_reply,
|
|
10
|
+
bcc: emails,
|
|
11
|
+
reply_to: reply_to,
|
|
12
|
+
subject: subject
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def subject
|
|
18
|
+
"#{Thredded.email_outgoing_prefix} #{@topic.title}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reply_to
|
|
22
|
+
"#{@topic.hash_id}@#{Thredded.email_incoming_host}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def no_reply
|
|
26
|
+
Thredded.email_from
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class Ability
|
|
3
|
+
include ::CanCan::Ability
|
|
4
|
+
|
|
5
|
+
def initialize(user)
|
|
6
|
+
user ||= Thredded::NullUser.new
|
|
7
|
+
user_details = Thredded::UserDetail.where(user_id: user.id).first
|
|
8
|
+
|
|
9
|
+
can :manage, :all if user_details.try(:superadmin?)
|
|
10
|
+
|
|
11
|
+
can :read, Thredded::Messageboard do |messageboard|
|
|
12
|
+
Thredded::MessageboardUserPermissions.new(messageboard, user).readable?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
can :manage, Thredded::Topic do |topic|
|
|
16
|
+
Thredded::TopicUserPermissions.new(topic, user, user_details).manageable?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
can :read, Thredded::Topic do |topic|
|
|
20
|
+
Thredded::TopicUserPermissions.new(topic, user, user_details).readable?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
can :create, Thredded::Topic do |topic|
|
|
24
|
+
Thredded::TopicUserPermissions.new(topic, user, user_details).creatable?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
cannot :manage, Thredded::PrivateTopic
|
|
28
|
+
|
|
29
|
+
can :manage, Thredded::PrivateTopic do |private_topic|
|
|
30
|
+
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).manageable?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
can :create, Thredded::PrivateTopic do |private_topic|
|
|
34
|
+
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).creatable?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
can :read, Thredded::PrivateTopic do |private_topic|
|
|
38
|
+
Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).readable?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
can :manage, Thredded::Post do |post|
|
|
42
|
+
Thredded::PostUserPermissions.new(post, user, user_details).manageable?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
can :create, Thredded::Post do |post|
|
|
46
|
+
Thredded::PostUserPermissions.new(post, user, user_details).creatable?
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class Attachment < ActiveRecord::Base
|
|
3
|
+
belongs_to :post
|
|
4
|
+
validates_presence_of :attachment
|
|
5
|
+
attr_accessible :attachment
|
|
6
|
+
mount_uploader :attachment, Thredded::AttachmentUploader
|
|
7
|
+
before_save :update_attachment_attributes
|
|
8
|
+
|
|
9
|
+
def cache_dir
|
|
10
|
+
"#{Rails.root}/tmp/uploads"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def filename
|
|
14
|
+
File.basename(attachment.path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def update_attachment_attributes
|
|
18
|
+
if attachment.present? && attachment_changed?
|
|
19
|
+
self.content_type = attachment.file.content_type
|
|
20
|
+
self.file_size = attachment.file.size
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class Category < ActiveRecord::Base
|
|
3
|
+
attr_accessible :description, :messageboard_id, :name
|
|
4
|
+
validates :name, presence: true
|
|
5
|
+
|
|
6
|
+
belongs_to :messageboard
|
|
7
|
+
has_many :topic_categories
|
|
8
|
+
has_many :topics, through: :topic_categories
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class Image < ActiveRecord::Base
|
|
3
|
+
mount_uploader :image, ImageUploader
|
|
4
|
+
attr_accessible :height, :orientation, :width
|
|
5
|
+
validates :image, presence: true
|
|
6
|
+
before_validation :save_dimensions, :save_orientation, :save_position
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def save_dimensions
|
|
11
|
+
if image.path
|
|
12
|
+
self.width = MiniMagick::Image.open(image.path)[:width]
|
|
13
|
+
self.height = MiniMagick::Image.open(image.path)[:height]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def save_orientation
|
|
18
|
+
if image.path
|
|
19
|
+
self.orientation = (height.to_i > width.to_i) ? 'portrait' : 'landscape'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def save_position
|
|
24
|
+
self.position = (self._index + 1) if self.new_record? and self._index
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Thredded
|
|
2
|
+
class Messageboard < ActiveRecord::Base
|
|
3
|
+
SECURITY = %w{private logged_in public}
|
|
4
|
+
PERMISSIONS = %w{members logged_in anonymous}
|
|
5
|
+
|
|
6
|
+
extend FriendlyId
|
|
7
|
+
friendly_id :name
|
|
8
|
+
|
|
9
|
+
attr_accessible :description,
|
|
10
|
+
:name,
|
|
11
|
+
:posting_permission,
|
|
12
|
+
:security
|
|
13
|
+
|
|
14
|
+
default_scope where(closed: false).order('topics_count DESC')
|
|
15
|
+
|
|
16
|
+
validates_numericality_of :topics_count
|
|
17
|
+
validates_inclusion_of :security, in: SECURITY
|
|
18
|
+
validates_inclusion_of :posting_permission, in: PERMISSIONS
|
|
19
|
+
validates_presence_of :name
|
|
20
|
+
validates_format_of :name, with: /\A[\w\-]+\z/, on: :create,
|
|
21
|
+
message: 'should be letters, nums, dash, underscore only.'
|
|
22
|
+
validates_uniqueness_of :name,
|
|
23
|
+
message: 'must be a unique board name. Try again.'
|
|
24
|
+
validates_length_of :name, within: 1..16,
|
|
25
|
+
message: 'should be between 1 and 16 characters'
|
|
26
|
+
|
|
27
|
+
has_many :categories
|
|
28
|
+
has_many :messageboard_preferences
|
|
29
|
+
has_many :posts
|
|
30
|
+
has_many :roles
|
|
31
|
+
has_many :topics
|
|
32
|
+
has_many :private_topics
|
|
33
|
+
has_many :users, through: :roles, class_name: Thredded.user_class
|
|
34
|
+
|
|
35
|
+
def active_users
|
|
36
|
+
Role
|
|
37
|
+
.joins(:user)
|
|
38
|
+
.where(messageboard_id: self.id)
|
|
39
|
+
.where('last_seen > ?', 5.minutes.ago)
|
|
40
|
+
.order(:last_seen)
|
|
41
|
+
.map(&:user)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def decorate
|
|
45
|
+
MessageboardDecorator.new(self)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def add_member(user, as='member')
|
|
49
|
+
roles.create(user_id: user.id, level: as)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def has_member?(user)
|
|
53
|
+
roles.where(user_id: user.id).exists?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def member_is_a?(user, as)
|
|
57
|
+
roles.where(user_id: user.id, level: as).exists?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def members_from_list(user_list)
|
|
61
|
+
users.where('lower(name) in (?)', user_list.map(&:downcase))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def posting_for_anonymous?
|
|
65
|
+
'anonymous' == posting_permission
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def posting_for_logged_in?
|
|
69
|
+
'logged_in' == posting_permission
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def posting_for_members?
|
|
73
|
+
'members' == posting_permission
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def public?
|
|
77
|
+
'public' == security
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def restricted_to_logged_in?
|
|
81
|
+
'logged_in' == security
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def restricted_to_private?
|
|
85
|
+
'private' == security
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def to_param
|
|
89
|
+
name.downcase
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|