thredded 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.mkdn +46 -0
  4. data/Rakefile +31 -0
  5. data/app/assets/javascripts/thredded/application.js +15 -0
  6. data/app/assets/stylesheets/thredded/application.css +13 -0
  7. data/app/controllers/thredded/application_controller.rb +50 -0
  8. data/app/controllers/thredded/messageboards_controller.rb +9 -0
  9. data/app/controllers/thredded/posts_controller.rb +86 -0
  10. data/app/controllers/thredded/preferences_controller.rb +20 -0
  11. data/app/controllers/thredded/private_topics_controller.rb +25 -0
  12. data/app/controllers/thredded/setups_controller.rb +39 -0
  13. data/app/controllers/thredded/topics_controller.rb +121 -0
  14. data/app/decorators/thredded/post_decorator.rb +52 -0
  15. data/app/decorators/thredded/topic_decorator.rb +96 -0
  16. data/app/helpers/thredded/application_helper.rb +9 -0
  17. data/app/helpers/thredded/messageboard_helper.rb +52 -0
  18. data/app/helpers/thredded/posts_helper.rb +7 -0
  19. data/app/helpers/thredded/topics_helper.rb +21 -0
  20. data/app/mailers/thredded/post_mailer.rb +28 -0
  21. data/app/mailers/thredded/topic_mailer.rb +29 -0
  22. data/app/models/thredded/ability.rb +50 -0
  23. data/app/models/thredded/attachment.rb +24 -0
  24. data/app/models/thredded/category.rb +10 -0
  25. data/app/models/thredded/image.rb +27 -0
  26. data/app/models/thredded/messageboard.rb +92 -0
  27. data/app/models/thredded/messageboard_decorator.rb +18 -0
  28. data/app/models/thredded/messageboard_preference.rb +15 -0
  29. data/app/models/thredded/null_preference.rb +9 -0
  30. data/app/models/thredded/null_topic_read.rb +13 -0
  31. data/app/models/thredded/null_user.rb +27 -0
  32. data/app/models/thredded/post.rb +75 -0
  33. data/app/models/thredded/post_notification.rb +6 -0
  34. data/app/models/thredded/private_topic.rb +33 -0
  35. data/app/models/thredded/private_user.rb +7 -0
  36. data/app/models/thredded/role.rb +18 -0
  37. data/app/models/thredded/topic.rb +145 -0
  38. data/app/models/thredded/topic_category.rb +7 -0
  39. data/app/models/thredded/user_detail.rb +6 -0
  40. data/app/models/thredded/user_extender.rb +27 -0
  41. data/app/models/thredded/user_preference.rb +6 -0
  42. data/app/models/thredded/user_topic_read.rb +67 -0
  43. data/app/uploaders/thredded/attachment_uploader.rb +30 -0
  44. data/app/uploaders/thredded/image_uploader.rb +17 -0
  45. data/app/views/thredded/messageboards/_messageboard.html.erb +17 -0
  46. data/app/views/thredded/messageboards/index.html.erb +15 -0
  47. data/app/views/thredded/post_mailer/at_notification.html.erb +17 -0
  48. data/app/views/thredded/post_mailer/at_notification.text.erb +13 -0
  49. data/app/views/thredded/posts/_form.html.erb +25 -0
  50. data/app/views/thredded/posts/_null_user.html.erb +0 -0
  51. data/app/views/thredded/posts/_post.html.erb +25 -0
  52. data/app/views/thredded/posts/_user.html.erb +7 -0
  53. data/app/views/thredded/posts/edit.html.erb +28 -0
  54. data/app/views/thredded/posts/index.html.erb +74 -0
  55. data/app/views/thredded/preferences/edit.html.erb +23 -0
  56. data/app/views/thredded/search/_form.html.erb +9 -0
  57. data/app/views/thredded/setups/_form.html.erb +35 -0
  58. data/app/views/thredded/setups/new.html.erb +5 -0
  59. data/app/views/thredded/shared/_currently_online.html.erb +10 -0
  60. data/app/views/thredded/shared/_error_msgs.html.erb +7 -0
  61. data/app/views/thredded/shared/_google_analytics.html.erb +10 -0
  62. data/app/views/thredded/shared/_topic_nav.html.erb +18 -0
  63. data/app/views/thredded/topic_mailer/message_notification.html.erb +17 -0
  64. data/app/views/thredded/topic_mailer/message_notification.text.erb +13 -0
  65. data/app/views/thredded/topics/_form.html.erb +6 -0
  66. data/app/views/thredded/topics/_topic_condensed.html.erb +20 -0
  67. data/app/views/thredded/topics/_topic_form.html.erb +27 -0
  68. data/app/views/thredded/topics/by_category.html.erb +51 -0
  69. data/app/views/thredded/topics/edit.html.erb +25 -0
  70. data/app/views/thredded/topics/index.html.erb +52 -0
  71. data/app/views/thredded/topics/menu/_new_topic.html.erb +3 -0
  72. data/app/views/thredded/topics/new.html.erb +18 -0
  73. data/app/views/thredded/topics/search.html.erb +45 -0
  74. data/config/routes.rb +26 -0
  75. data/db/migrate/20130425230852_create_thredded_tables.rb +143 -0
  76. data/lib/tasks/thredded_tasks.rake +4 -0
  77. data/lib/thredded.rb +38 -0
  78. data/lib/thredded/at_notification_extractor.rb +15 -0
  79. data/lib/thredded/at_notifier.rb +65 -0
  80. data/lib/thredded/at_users.rb +17 -0
  81. data/lib/thredded/email_processor.rb +74 -0
  82. data/lib/thredded/engine.rb +17 -0
  83. data/lib/thredded/filter.rb +4 -0
  84. data/lib/thredded/filter/at_notification.rb +11 -0
  85. data/lib/thredded/filter/attachment.rb +51 -0
  86. data/lib/thredded/filter/base.rb +13 -0
  87. data/lib/thredded/filter/bbcode.rb +75 -0
  88. data/lib/thredded/filter/emoji.rb +11 -0
  89. data/lib/thredded/filter/markdown.rb +25 -0
  90. data/lib/thredded/filter/syntax.rb +28 -0
  91. data/lib/thredded/filter/textile.rb +21 -0
  92. data/lib/thredded/messageboard_user_permissions.rb +27 -0
  93. data/lib/thredded/post_sql_builder.rb +34 -0
  94. data/lib/thredded/post_user_permissions.rb +37 -0
  95. data/lib/thredded/private_topic_notifier.rb +56 -0
  96. data/lib/thredded/private_topic_user_permissions.rb +32 -0
  97. data/lib/thredded/search_parser.rb +45 -0
  98. data/lib/thredded/search_sql_builder.rb +25 -0
  99. data/lib/thredded/setup_thredded.rb +7 -0
  100. data/lib/thredded/table_sql_builder.rb +105 -0
  101. data/lib/thredded/topic_sql_builder.rb +32 -0
  102. data/lib/thredded/topic_user_permissions.rb +51 -0
  103. data/lib/thredded/version.rb +3 -0
  104. metadata +537 -0
@@ -0,0 +1,30 @@
1
+ require 'carrierwave/processing/mini_magick'
2
+
3
+ module Thredded
4
+ class AttachmentUploader < CarrierWave::Uploader::Base
5
+ include CarrierWave::MiniMagick
6
+ storage :file
7
+
8
+ def store_dir
9
+ "uploads/#{mounted_as}/#{model.id}"
10
+ end
11
+
12
+ version :thumb, if: :image? do
13
+ process :resize_to_fit => [90, 90]
14
+ end
15
+
16
+ version :mobile, if: :image? do
17
+ process :resize_to_limit => [480, 2000]
18
+ end
19
+
20
+ def extension_white_list
21
+ %w(jpg jpeg gif png pdf zip tgz txt)
22
+ end
23
+
24
+ protected
25
+
26
+ def image?(new_file)
27
+ new_file.content_type.include? 'image'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require 'carrierwave/processing/mini_magick'
2
+
3
+ module Thredded
4
+ class ImageUploader < CarrierWave::Uploader::Base
5
+ include CarrierWave::MiniMagick
6
+
7
+ storage :file
8
+
9
+ def store_dir
10
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
11
+ end
12
+
13
+ def extension_white_list
14
+ %w(jpg jpeg gif png)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ <% if can? :read, messageboard %>
2
+ <div class="messageboard">
3
+ <header>
4
+ <h2><%= link_or_text_to(messageboard) %></h2>
5
+ <div class="meta"><%= meta_for(messageboard) %></div>
6
+ </header>
7
+ <% content_tag :p, messageboard.description if messageboard.description %>
8
+ <% admin_link_for(messageboard) %>
9
+
10
+ <footer>
11
+ <p>
12
+ <%= latest_thread_for(messageboard) %>
13
+ <cite>by <%= latest_user_for(messageboard) %></cite>
14
+ </p>
15
+ </footer>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <header>
2
+ <nav>
3
+ <ul class="breadcrumbs">
4
+ <li><span>Forums</span></li>
5
+ </ul>
6
+ </nav>
7
+ <h2>
8
+ <%= number_to_human(Thredded::Messageboard.all.count) %> messageboards,
9
+ <%= number_to_human(Thredded::Messageboard.all.map(&:topics_count).sum, precision: 4) %> topics,
10
+ and <%= number_to_human(Thredded::Messageboard.all.map(&:posts_count).sum, precision: 5) %> posts</h2>
11
+ </header>
12
+
13
+ <section id="messageboards">
14
+ <%= render @messageboards %>
15
+ </section>
@@ -0,0 +1,17 @@
1
+ <p><span style="font-size:11px; color: gray;">- write above this line to post a reply -</span></p>
2
+
3
+ <%= @post.filtered_content %>
4
+
5
+ <hr />
6
+
7
+ <p>
8
+ This email was sent to you because <%= @post.user.name %> mentioned you in
9
+ "<%= link_to @post.topic.title, messageboard_topic_posts_url(@post.messageboard, @post.topic, anchor: "post_#{@post.id}") %>"
10
+ Feel free to reply above or <%= link_to 'head to the thread', messageboard_topic_posts_url(@post.messageboard, @post.topic) %>
11
+ to view the conversation.
12
+ </p>
13
+
14
+ <p>
15
+ To unsubscribe from these emails, update your
16
+ <%= link_to 'preferences', edit_messageboard_preferences_url(@post.messageboard) %>.
17
+ </p>
@@ -0,0 +1,13 @@
1
+ - write above this line to post a reply -
2
+
3
+ <%= @post.content %>
4
+
5
+ ---
6
+
7
+ This email was sent to you because <%= @post.user.name %> mentioned you in
8
+ "<%= @post.topic.title %>". Feel free to reply above or head to the following
9
+ to view the conversation:
10
+ <%= messageboard_topic_posts_url @post.messageboard, @post.topic, anchor: "post_#{@post.id}" %>
11
+
12
+ To unsubscribe from these emails, update your preferences here:
13
+ <%= edit_messageboard_preferences_url @post.messageboard %>
@@ -0,0 +1,25 @@
1
+ <li class="content">
2
+ <%= f.label :content %>
3
+ <%= f.text_area :content, { rows: 5 } %>
4
+ </li>
5
+
6
+ <%= f.fields_for :attachments do |attachment_form| %>
7
+ <li class="attachment">
8
+ <%= attachment_form.file_field :attachment %>
9
+ <%= attachment_form.link_to_remove 'Remove this attachment',
10
+ { class: 'remove_attachment' } %>
11
+ </li>
12
+ <% end %>
13
+
14
+ <li>
15
+ <%= f.link_to_add 'Add an attachment', :attachments,
16
+ { class: :add_attachment } %>
17
+ </li>
18
+
19
+ <li>
20
+ <%= f.select :filter, Thredded::Post.filters, {} %>
21
+ <a href="#pseudo-help"
22
+ title="huh?"
23
+ class="hide-for-small filter-help"
24
+ id="filter-help">?</a>
25
+ </li>
File without changes
@@ -0,0 +1,25 @@
1
+ <% post = Thredded::PostDecorator.new(post) %>
2
+ <%= content_tag_for(:article, post) do %>
3
+ <% cache post do %>
4
+ <header>
5
+ <%= image_tag post.gravatar_url, class: 'avatar' %>
6
+ <cite>
7
+ <%= post.user_name %>
8
+ <%= post.created_at_timeago %>
9
+ </cite>
10
+ </header>
11
+
12
+ <div class="content">
13
+ <p><%= post.filtered_content %></p>
14
+ <ul class="attachments"><%= render post.attachments %></ul>
15
+ </div>
16
+ <% end %>
17
+
18
+ <footer>
19
+ <% if can? :edit, post.original %>
20
+ <%= link_to 'edit post',
21
+ edit_messageboard_topic_post_path(messageboard, topic, post),
22
+ class: 'edit' %>
23
+ <% end %>
24
+ </footer>
25
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <span class="roles">
2
+ <%= post.user_roles %>
3
+ </span>
4
+
5
+ <span class="posts_count">
6
+ <%= post.user_posts_count %> posts
7
+ </span>
@@ -0,0 +1,28 @@
1
+ <header>
2
+ <nav>
3
+ <ul class="breadcrumbs">
4
+ <li><%= link_to 'Forums', thredded.root_path %></li>
5
+ <li><%= link_to messageboard.name,
6
+ messageboard_topic_posts_path(messageboard, topic) %></li>
7
+ <li>
8
+ <span>
9
+ Editing Post - <%= link_to "##{@post.id}",
10
+ messageboard_topic_posts_path(messageboard, topic) + "#post_#{@post.id}" %>
11
+ </span>
12
+ </li>
13
+ </ul>
14
+ </nav>
15
+ </header>
16
+
17
+ <div class="forms">
18
+ <%= nested_form_for([messageboard, topic, @post], url: { action: 'update' },
19
+ html: { method: :put, class: :topic_form }) do |f| %>
20
+ <ul>
21
+ <%= render 'form', f: f %>
22
+
23
+ <li class="submit">
24
+ <%= f.submit 'Update Post', { tabindex: 2 } %>
25
+ </li>
26
+ </ul>
27
+ <% end %>
28
+ </div>
@@ -0,0 +1,74 @@
1
+ <header>
2
+ <nav>
3
+ <ul class="breadcrumbs">
4
+ <li><%= link_to 'Forums', thredded.root_path %></li>
5
+ <li><%= link_to messageboard.name, messageboard_topics_path(messageboard) %></li>
6
+ <li>
7
+ <span>
8
+ <%= topic.title %>
9
+
10
+ <% if can? :edit, topic %>
11
+ <%= link_to 'edit', edit_messageboard_topic_path(messageboard, topic) %>
12
+ <% end %>
13
+ </span>
14
+ </li>
15
+ </ul>
16
+ <ul class="actions">
17
+ <%= render 'thredded/search/form' %>
18
+ <% if can? :create, Thredded::Topic %>
19
+ <li class='new_topic'><%= link_to 'new topic', new_messageboard_topic_path(messageboard) %></li>
20
+ <li class='new_private_topic'><%= link_to 'private topic', new_messageboard_topic_path(messageboard, type: 'private') %></li>
21
+ <% end %>
22
+ </ul>
23
+ </nav>
24
+
25
+ <% if topic.users_to_sentence.present? %>
26
+ <cite><%= topic.users_to_sentence %></cite>
27
+ <% end %>
28
+
29
+ <%= render 'thredded/shared/currently_online' %>
30
+ <%= render 'thredded/shared/topic_nav' %>
31
+ </header>
32
+
33
+ <%= content_tag_for :section, topic, class: topic.decorate.css_class do %>
34
+ <header><h1><%= topic.title %></h1></header>
35
+
36
+ <section class="posts">
37
+ <%= render @posts %>
38
+ </section>
39
+ <% end %>
40
+
41
+ <footer>
42
+ <%= paginate @posts %>
43
+
44
+ <% if can? :create, @post %>
45
+ <div class="forms">
46
+ <%= nested_form_for [messageboard, topic, @post], html: { multipart: true } do |f| %>
47
+ <ul>
48
+ <%= render 'form', f: f %>
49
+ <li class="submit">
50
+ <%= f.submit 'Submit reply' %>
51
+ </li>
52
+ </ul>
53
+ <% end %>
54
+ </div>
55
+ <% end %>
56
+
57
+ <nav>
58
+ <ul class="breadcrumbs">
59
+ <li><%= link_to 'Forums', thredded.root_path %></li>
60
+ <li><%= link_to messageboard.name,
61
+ messageboard_topics_path(messageboard) %></li>
62
+ <li>
63
+ <span>
64
+ <%= topic.title %>
65
+
66
+ <% if can? :edit, topic %>
67
+ <%= link_to 'edit',
68
+ edit_messageboard_topic_path(messageboard, topic) %>
69
+ <% end %>
70
+ </span>
71
+ </li>
72
+ </ul>
73
+ </nav>
74
+ </footer>
@@ -0,0 +1,23 @@
1
+ <fieldset>
2
+ <legend>Update Preferences For <%= messageboard.name %></legend>
3
+
4
+ <%= form_for [messageboard, preference], url: messageboard_preferences_path(messageboard) do |f| %>
5
+ <%= render 'thredded/shared/error_msgs' %>
6
+
7
+ <ul>
8
+ <li>
9
+ <%= f.label :notify_on_mention, "Notify me when I am @'ed" %>
10
+ <%= f.check_box :notify_on_mention %>
11
+ </li>
12
+ <li>
13
+ <%= f.label :notify_on_message, 'Notify me when I am included in a private topic' %>
14
+ <%= f.check_box :notify_on_message %>
15
+ </li>
16
+ <li>
17
+ <%= f.label :filter, 'Preferred post filter' %>
18
+ <%= f.select :filter, Thredded::Post.filters %>
19
+ </li>
20
+ <li class="submit"><%= f.submit 'Update Preferences' %></li>
21
+ </ul>
22
+ <% end %>
23
+ </fieldset>
@@ -0,0 +1,9 @@
1
+ <li class="search_form">
2
+ <%= form_tag messageboard_topics_path(messageboard), method: 'get' do %>
3
+ <%= label :q, :search, 'Search', for: 'q', class: 'show-for-small',
4
+ data: {toggle: '#q'} %>
5
+ <%= text_field_tag(:q, params[:q],
6
+ { placeholder: 'Search Topics and Posts', type: 'search', class: 'input-search' }) %>
7
+ <%= submit_tag('Search', name: '') %>
8
+ <% end %>
9
+ </li>
@@ -0,0 +1,35 @@
1
+ <%= form_for @messageboard do |f| %>
2
+ <div id="setup-container">
3
+ <p class="setup-overview-text">
4
+ These will be the settings and permissions for your first thredded
5
+ messageboard.
6
+ </p>
7
+
8
+ <dl>
9
+ <dt><%= f.label :name %></dt>
10
+ <dd><%= f.text_field :name %></dd>
11
+
12
+ <dt><%= f.label :description %></dt>
13
+ <dd><%= f.text_field :description %></dd>
14
+
15
+ <dt><%= f.label :security %></dt>
16
+ <dd>
17
+ <%= f.select :security, [:private, :public, :logged_in] %>
18
+ <p class="setup-explanation-text">
19
+ This will set the visibility of your messageboard to the public
20
+ members.
21
+ </p>
22
+ </dd>
23
+
24
+ <dt><%= f.label :posting_permission %></dt>
25
+ <dd>
26
+ <%= f.select :posting_permission, [:members, :logged_in, :anonymous] %>
27
+ <p class="setup-explanation-text">
28
+ The required minimum permissions to post in your messageboard.
29
+ </p>
30
+ </dd>
31
+ </dl>
32
+
33
+ <%= f.submit 'Continue' %>
34
+ </div>
35
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% content_for :page_title do %>Thredded Setup<% end %>
2
+
3
+ <h1>Setup</h1>
4
+
5
+ <%= render 'form' %>
@@ -0,0 +1,10 @@
1
+ <% if messageboard %>
2
+ <div class="online">
3
+ <h3>Currently Online</h3>
4
+ <ul>
5
+ <% messageboard.active_users.each do |u| %>
6
+ <li><%= u.name %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% [:info, :error, :notice, :alert, :warning].each do |key| %>
2
+ <% if flash[key] %>
3
+ <div class="<%= key %>" id="flash">
4
+ <%= flash[key] %>
5
+ </div>
6
+ <% end %>
7
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <script type="text/javascript">
2
+ var _gaq = _gaq || [];
3
+ _gaq.push(['_setAccount', '<%= ENV['GOOGLE_ANALYTICS_ID'] %>']);
4
+ _gaq.push(['_trackPageview']);
5
+ (function() {
6
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
7
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
8
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
9
+ })();
10
+ </script>
@@ -0,0 +1,18 @@
1
+ <div class="topic_nav">
2
+ <% if can? :create, messageboard.topics.build %>
3
+ <ul class="actions">
4
+ <li class='new_topic'><%= link_to 'new topic', new_messageboard_topic_path(messageboard) %></li>
5
+ <li class='new_private_topic'><%= link_to 'private topic', new_messageboard_private_topic_path(messageboard) %></li>
6
+ </ul>
7
+ <% end %>
8
+
9
+ <ul class="listings">
10
+ <li class="topic_list"><%= link_to 'topics', messageboard_topics_path %></li>
11
+
12
+ <% if can? :list, messageboard.private_topics.build %>
13
+ <li class="private_topic_list"><%= link_to 'private topics', messageboard_private_topics_path %></li>
14
+ <% end %>
15
+
16
+ <%= render 'thredded/search/form' %>
17
+ </ul>
18
+ </div>
@@ -0,0 +1,17 @@
1
+ <p><span style="font-size:11px; color: gray;">- write above this line to post a reply -</span></p>
2
+
3
+ <%= @topic.posts.first.filtered_content %>
4
+
5
+ <hr />
6
+
7
+ <p>
8
+ This email was sent to you because <%= @topic.user.name %> included you in a
9
+ private topic, "<%= link_to @topic.title, messageboard_topic_posts_url(@topic.messageboard, @topic) %>".
10
+ Feel free to reply above or <%= link_to 'head to the thread', messageboard_topic_posts_url(@topic.messageboard, @topic) %>
11
+ to view the conversation.
12
+ </p>
13
+
14
+ <p>
15
+ To unsubscribe from these emails, update your
16
+ <%= link_to 'preferences', edit_messageboard_preferences_url(@topic.messageboard) %>.
17
+ </p>
@@ -0,0 +1,13 @@
1
+ - write above this line to post a reply -
2
+
3
+ <%= @topic.posts.first.content %>
4
+
5
+ ---
6
+
7
+ This email was sent to you because <%= @topic.user.name %>
8
+ included you in the private topic "<%= @topic.title %>". Feel free to reply
9
+ above or head to the following to view the conversation:
10
+ <%= messageboard_topic_posts_url(@topic.messageboard, @topic) %>
11
+
12
+ To unsubscribe from these emails, update your preferences here:
13
+ <%= edit_messageboard_preferences_url(@topic.messageboard) %>