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.
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,6 @@
1
+ <li class="title">
2
+ <%= form.label :title %>
3
+ <%= form.text_field :title, { placeholder: 'Title', autofocus: 'autofocus', } %>
4
+ </li>
5
+
6
+ <%= render 'topic_form', form: form, messageboard: messageboard %>
@@ -0,0 +1,20 @@
1
+ <% if can? :read, topic.original %>
2
+ <%= content_tag_for :article, topic, class: topic.css_class do %>
3
+ <div class="post_count"><%= topic.posts_count %></div>
4
+
5
+ <h1>
6
+ <%= link_to topic.title, [messageboard, topic],
7
+ class: already_read(topic, @tracked_user_reads) %>
8
+ </h1>
9
+
10
+ <cite class="updated_by">
11
+ <%= topic.updated_at_timeago %>
12
+ <%= topic.last_user_link %>
13
+ </cite>
14
+
15
+ <cite class="started_by">
16
+ <%= topic.created_at_timeago %>
17
+ <%= topic.user_link %>
18
+ </cite>
19
+ <% end %>
20
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <% if messageboard.categories.any? %>
2
+ <li class="category">
3
+ <%= form.select :category_ids,
4
+ messageboard.category_options,
5
+ {}, { multiple: true, 'data-placeholder' => 'Categories' } %>
6
+ </li>
7
+ <% end %>
8
+
9
+ <% if can? :manage, form.object %>
10
+ <li class="locked">
11
+ <%= form.label :locked do %>
12
+ Locked <%= form.check_box :locked %>
13
+ <% end %>
14
+ </li>
15
+
16
+ <li class="sticky">
17
+ <%= form.label :sticky do %>
18
+ Sticky <%= form.check_box :sticky %>
19
+ <% end %>
20
+ </li>
21
+ <% end %>
22
+
23
+ <% if action_name != 'edit' %>
24
+ <%= form.fields_for :posts do |post_form| %>
25
+ <%= render 'thredded/posts/form', f: post_form %>
26
+ <% end %>
27
+ <% end %>
@@ -0,0 +1,51 @@
1
+ <% content_for :breadcrumbs do %>
2
+ <ul class="breadcrumbs">
3
+ <li><%= link_to 'Forums', thredded.root_path %></li>
4
+ <li><%= link_to messageboard.title, messageboard_topics_path(messageboard) %></li>
5
+ <li><span>Category</span></li>
6
+ </ul>
7
+ <% end %>
8
+
9
+ <% content_for :actions do %>
10
+ <ul class="actions">
11
+ <%= render 'thredded/search/form' %>
12
+
13
+ <% if can? :create, Thredded::Topic %>
14
+ <li class='new_topic'>
15
+ <%= link_to 'new topic', new_messageboard_topic_path(messageboard) %>
16
+ </li>
17
+ <li class='new_private_topic'>
18
+ <%= link_to 'private topic', new_messageboard_private_topic_path(messageboard) %>
19
+ </li>
20
+ <% end %>
21
+ </ul>
22
+ <% end %>
23
+
24
+ <header>
25
+ <nav>
26
+ <%= yield :breadcrumbs %>
27
+ <%= yield :actions %>
28
+ </nav>
29
+
30
+ <%= render 'thredded/shared/currently_online' %>
31
+ </header>
32
+
33
+ <section class="topics">
34
+ <% if @sticky.any? %>
35
+ <div class="stuck">
36
+ <%= render partial: 'thredded/topics/topic_condensed', collection: @sticky, as: :t %>
37
+ </div>
38
+ <% end %>
39
+
40
+ <div class="currently">
41
+ <%= render partial: 'thredded/topics/topic_condensed', collection: @topics, as: :t %>
42
+ </div>
43
+ </section>
44
+
45
+ <footer>
46
+ <%= paginate @topics %>
47
+ <nav>
48
+ <%= yield :actions %>
49
+ <%= yield :breadcrumbs %>
50
+ </nav>
51
+ </footer>
@@ -0,0 +1,25 @@
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, topic) %></li>
6
+ <li>
7
+ <span>
8
+ Editing Topic <em><%= link_to topic.title, [messageboard, topic] %></em>
9
+ </span>
10
+ </li>
11
+ </ul>
12
+ </nav>
13
+ </header>
14
+
15
+ <div class="forms">
16
+ <ul>
17
+ <%= nested_form_for [@messageboard, @topic], html: { class: :topic_form, multipart: true } do |form| %>
18
+ <%= render 'form', form: form, messageboard: messageboard.decorate %>
19
+
20
+ <li class="submit">
21
+ <%= form.submit 'Update Topic' %>
22
+ </li>
23
+ <% end %>
24
+ </ul>
25
+ </div>
@@ -0,0 +1,52 @@
1
+ <% content_for :breadcrumbs do %>
2
+ <ul class="breadcrumbs">
3
+ <li><%= link_to 'Forums', thredded.root_path %></li>
4
+ <li><span><%= messageboard.name %></span></li>
5
+ </ul>
6
+ <% end %>
7
+
8
+ <% content_for :actions do %>
9
+ <ul class="actions">
10
+ <%= render 'thredded/search/form' %>
11
+
12
+ <% if can? :create, Thredded::Topic %>
13
+ <li class='new_topic'>
14
+ <%= link_to 'new topic', new_messageboard_topic_path(messageboard) %>
15
+ </li>
16
+ <li class='new_private_topic'>
17
+ <%= link_to 'private topic', new_messageboard_private_topic_path(messageboard) %>
18
+ </li>
19
+ <% end %>
20
+ </ul>
21
+ <% end %>
22
+
23
+ <header>
24
+ <nav>
25
+ <%= yield :breadcrumbs %>
26
+ <%= yield :actions %>
27
+ </nav>
28
+
29
+ <%= render 'thredded/shared/currently_online' %>
30
+ </header>
31
+
32
+ <section class="topics">
33
+ <% if @sticky.any? %>
34
+ <div class="stuck">
35
+ <%= render partial: 'thredded/topics/topic_condensed',
36
+ collection: @sticky.decorate, as: :topic %>
37
+ </div>
38
+ <% end %>
39
+
40
+ <div class="currently">
41
+ <%= render partial: 'thredded/topics/topic_condensed',
42
+ collection: @topics.decorate, as: :topic %>
43
+ </div>
44
+ </section>
45
+
46
+ <footer>
47
+ <%= paginate @topics %>
48
+ <nav>
49
+ <%= yield :actions %>
50
+ <%= yield :breadcrumbs %>
51
+ </nav>
52
+ </footer>
@@ -0,0 +1,3 @@
1
+ <li>
2
+ <%= link_to 'New Topic', new_messageboard_topic_path %>
3
+ </li>
@@ -0,0 +1,18 @@
1
+ <header>
2
+ <nav>
3
+ <ul class="breadcrumbs">
4
+ <li><%= link_to 'Forums', thredded.root_path %></li>
5
+ <li><%= link_to messageboard.name, [messageboard, @topic] %></li>
6
+ <li><span>Create New Topic</span></li>
7
+ </ul>
8
+ </nav>
9
+ </header>
10
+
11
+ <div class="topic form">
12
+ <%= nested_form_for [messageboard, @topic], html: { multipart: true } do |form| %>
13
+ <ul>
14
+ <%= render 'form', form: form, messageboard: messageboard.decorate %>
15
+ <li class="submit"><%= form.submit 'Create New Topic' %></li>
16
+ </ul>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,45 @@
1
+ <% content_for :breadcrumbs do %>
2
+ <ul class="breadcrumbs">
3
+ <li><%= link_to 'Forums', thredded.root_path %></li>
4
+ <li><%= link_to messageboard.title,
5
+ messageboard_topics_path(messageboard) %></li>
6
+ <li><span>Results for "<%= params[:q]%>"</span></li>
7
+ </ul>
8
+ <% end %>
9
+
10
+ <% content_for :actions do %>
11
+ <ul class="actions">
12
+ <%= render 'thredded/search/form' %>
13
+
14
+ <% if can? :create, Thredded::Topic %>
15
+ <li class='new_topic'>
16
+ <%= link_to 'new topic', new_messageboard_topic_path(messageboard) %>
17
+ </li>
18
+ <li class='new_private_topic'>
19
+ <%= link_to 'private topic', new_messageboard_private_topic_path(messageboard) %>
20
+ </li>
21
+ <% end %>
22
+ </ul>
23
+ <% end %>
24
+
25
+ <header>
26
+ <nav>
27
+ <%= yield :breadcrumbs %>
28
+ <%= yield :actions %>
29
+ </nav>
30
+
31
+ <%= render partial: 'shared/currently_online' %>
32
+ </header>
33
+
34
+ <section class="topics">
35
+ <div class="currently">
36
+ <%= render partial: 'topics/topic_condensed', collection: @topics, as: :t %>
37
+ </div>
38
+ </section>
39
+
40
+ <footer>
41
+ <nav>
42
+ <%= yield :actions %>
43
+ <%= yield :breadcrumbs %>
44
+ </nav>
45
+ </footer>
data/config/routes.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'thredded/setup_thredded'
2
+
3
+ Thredded::Engine.routes.draw do
4
+ constraints(Thredded::SetupThredded.new) do
5
+ resources :setups, path: '', only: [:new, :create]
6
+ root to: 'setups#new'
7
+ end
8
+
9
+ constraints(lambda{|req| req.env['QUERY_STRING'].include? 'q=' }) do
10
+ get '/:messageboard_id(.:format)' => 'topics#search', as: :messageboard_search
11
+ end
12
+
13
+ get '/:messageboard_id/new(.:format)' => 'topics#new', as: :new_messageboard_topic
14
+ get '/:messageboard_id/:id/edit.(:format)' => 'topics#edit', as: :edit_messageboard_topic
15
+
16
+ resources :messageboards, only: [:index], path: '' do
17
+ resource :preferences
18
+ resources :private_topics, only: [:new, :create]
19
+
20
+ resources :topics, except: [:show], path: '' do
21
+ resources :posts, path: ''
22
+ end
23
+ end
24
+
25
+ root to: 'messageboards#index'
26
+ end
@@ -0,0 +1,143 @@
1
+ class CreateThreddedTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :thredded_attachments do |t|
4
+ t.string :attachment
5
+ t.string :content_type
6
+ t.integer :file_size
7
+ t.integer :post_id
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :thredded_categories do |t|
12
+ t.integer :messageboard_id, null: false
13
+ t.string :name, null: false
14
+ t.string :description
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :thredded_images do |t|
19
+ t.integer :post_id
20
+ t.integer :width
21
+ t.integer :height
22
+ t.string :orientation
23
+ t.timestamps
24
+ end
25
+
26
+ create_table :thredded_messageboards do |t|
27
+ t.string :name, null: false
28
+ t.string :slug
29
+ t.text :description
30
+ t.string :security, default: 'public'
31
+ t.string :posting_permission, default: 'anonymous'
32
+ t.integer :topics_count, default: 0
33
+ t.integer :posts_count, default: 0
34
+ t.boolean :closed, default: false, null: false
35
+ t.timestamps
36
+ end
37
+
38
+ add_index :thredded_messageboards, :closed
39
+
40
+ create_table :thredded_post_notifications do |t|
41
+ t.string :email, null: false
42
+ t.integer :post_id, null: false
43
+ t.timestamps
44
+ end
45
+
46
+ create_table :thredded_posts do |t|
47
+ t.integer :user_id
48
+ t.string :user_email
49
+ t.text :content
50
+ t.string :ip
51
+ t.string :filter, default: 'markdown'
52
+ t.string :source, default: 'web'
53
+ t.integer :topic_id, null: false
54
+ t.integer :messageboard_id, null: false
55
+ t.timestamps
56
+ end
57
+
58
+ create_table :thredded_private_users do |t|
59
+ t.integer :private_topic_id
60
+ t.integer :user_id
61
+ t.timestamps
62
+ end
63
+
64
+ create_table :thredded_messageboard_preferences do |t|
65
+ t.boolean :notify_on_mention, default: true
66
+ t.boolean :notify_on_message, default: true
67
+ t.string :filter, default: 'markdown', null: false
68
+ t.integer :user_id, null: false
69
+ t.integer :messageboard_id, null: false
70
+ t.timestamps
71
+ end
72
+
73
+ add_index :thredded_messageboard_preferences, :user_id
74
+ add_index :thredded_messageboard_preferences, :messageboard_id
75
+
76
+ create_table :thredded_roles do |t|
77
+ t.string :level
78
+ t.integer :user_id
79
+ t.integer :messageboard_id
80
+ t.datetime :last_seen
81
+ t.timestamps
82
+ end
83
+
84
+ add_index :thredded_roles, :user_id
85
+ add_index :thredded_roles, :messageboard_id
86
+
87
+ create_table :thredded_topic_categories do |t|
88
+ t.integer :topic_id, null: false
89
+ t.integer :category_id, null: false
90
+ end
91
+
92
+ create_table :thredded_topics do |t|
93
+ t.integer :user_id, null: false
94
+ t.integer :last_user_id, null: false
95
+ t.string :title, null: false
96
+ t.string :slug, null: false
97
+ t.integer :messageboard_id, null: false
98
+ t.integer :posts_count, default: 0
99
+ t.string :attribs, default: '[]'
100
+ t.boolean :sticky, default: false
101
+ t.boolean :locked, default: false
102
+ t.string :hash_id, null: false
103
+ t.string :state, default: 'approved', null: false
104
+ t.string :type
105
+ t.timestamps
106
+ end
107
+
108
+ create_table :thredded_user_details do |t|
109
+ t.integer :user_id, null: false
110
+ t.datetime :latest_activity_at
111
+ t.integer :posts_count, default: 0
112
+ t.integer :topics_count, default: 0
113
+ t.boolean :superadmin, default: false
114
+ t.timestamps
115
+ end
116
+
117
+ add_index :thredded_user_details, :user_id
118
+ add_index :thredded_user_details, :latest_activity_at
119
+
120
+ create_table :thredded_user_preferences do |t|
121
+ t.integer :user_id, null: false
122
+ t.string :time_zone, default: 'Eastern Time (US & Canada)'
123
+ t.timestamps
124
+ end
125
+
126
+ add_index :thredded_user_preferences, :user_id
127
+
128
+ create_table :thredded_user_topic_reads do |t|
129
+ t.integer :user_id, null: false
130
+ t.integer :topic_id, null: false
131
+ t.integer :post_id, null: false
132
+ t.integer :posts_count, default: 0, null: false
133
+ t.integer :page, default: 1, null: false
134
+ t.timestamps
135
+ end
136
+
137
+ add_index :thredded_user_topic_reads, :user_id
138
+ add_index :thredded_user_topic_reads, :topic_id
139
+ add_index :thredded_user_topic_reads, :post_id
140
+ add_index :thredded_user_topic_reads, :page
141
+ add_index :thredded_user_topic_reads, :posts_count
142
+ end
143
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :thredded do
3
+ # # Task goes here
4
+ # end
data/lib/thredded.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'thredded/engine'
2
+ require 'cancan'
3
+ require 'carrierwave'
4
+ require 'kaminari'
5
+ require 'friendly_id'
6
+ require 'nested_form'
7
+ require 'thredded/filter/base'
8
+ require 'thredded/filter/at_notification'
9
+ require 'thredded/filter/attachment'
10
+ require 'thredded/filter/bbcode'
11
+ require 'thredded/filter/emoji'
12
+ require 'thredded/filter/markdown'
13
+ require 'thredded/filter/textile'
14
+ require 'thredded/messageboard_user_permissions'
15
+ require 'thredded/post_user_permissions'
16
+ require 'thredded/private_topic_user_permissions'
17
+ require 'thredded/topic_user_permissions'
18
+
19
+ module Thredded
20
+ mattr_accessor :user_class,
21
+ :email_incoming_host,
22
+ :email_from,
23
+ :email_outgoing_prefix
24
+
25
+ def self.user_class
26
+ if @@user_class.is_a?(Class)
27
+ raise 'Please use a string instead of a class'
28
+ end
29
+
30
+ if @@user_class.is_a?(String)
31
+ begin
32
+ Object.const_get(@@user_class)
33
+ rescue NameError
34
+ @@user_class.constantize
35
+ end
36
+ end
37
+ end
38
+ end