thredded 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.mkdn +202 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.mkdn +391 -0
  5. data/app/assets/images/thredded/breadcrumb-chevron.svg +1 -0
  6. data/app/assets/javascripts/thredded/currently_online.es6 +25 -0
  7. data/app/assets/javascripts/thredded/post_form.es6 +20 -0
  8. data/app/assets/javascripts/thredded/time_stamps.es6 +8 -0
  9. data/app/assets/javascripts/thredded/topic_form.es6 +55 -0
  10. data/app/assets/javascripts/thredded/users_select.es6 +5 -0
  11. data/app/assets/javascripts/thredded.es6 +10 -0
  12. data/app/assets/stylesheets/thredded/_base.scss +11 -0
  13. data/app/assets/stylesheets/thredded/_dependencies.scss +1 -0
  14. data/app/assets/stylesheets/thredded/_thredded.scss +27 -0
  15. data/app/assets/stylesheets/thredded/base/_alerts.scss +40 -0
  16. data/app/assets/stylesheets/thredded/base/_buttons.scss +39 -0
  17. data/app/assets/stylesheets/thredded/base/_forms.scss +79 -0
  18. data/app/assets/stylesheets/thredded/base/_grid.scss +19 -0
  19. data/app/assets/stylesheets/thredded/base/_lists.scss +31 -0
  20. data/app/assets/stylesheets/thredded/base/_tables.scss +25 -0
  21. data/app/assets/stylesheets/thredded/base/_typography.scss +36 -0
  22. data/app/assets/stylesheets/thredded/base/_variables.scss +54 -0
  23. data/app/assets/stylesheets/thredded/components/_base.scss +13 -0
  24. data/app/assets/stylesheets/thredded/components/_currently-online.scss +48 -0
  25. data/app/assets/stylesheets/thredded/components/_empty.scss +11 -0
  26. data/app/assets/stylesheets/thredded/components/_flash-message.scss +19 -0
  27. data/app/assets/stylesheets/thredded/components/_form-list.scss +35 -0
  28. data/app/assets/stylesheets/thredded/components/_main-section.scss +3 -0
  29. data/app/assets/stylesheets/thredded/components/_messageboard.scss +55 -0
  30. data/app/assets/stylesheets/thredded/components/_pagination.scss +26 -0
  31. data/app/assets/stylesheets/thredded/components/_post-form.scss +21 -0
  32. data/app/assets/stylesheets/thredded/components/_post.scss +66 -0
  33. data/app/assets/stylesheets/thredded/components/_preferences.scss +6 -0
  34. data/app/assets/stylesheets/thredded/components/_select2.scss +42 -0
  35. data/app/assets/stylesheets/thredded/components/_topic-delete.scss +9 -0
  36. data/app/assets/stylesheets/thredded/components/_topic-header.scss +20 -0
  37. data/app/assets/stylesheets/thredded/components/_topics.scss +113 -0
  38. data/app/assets/stylesheets/thredded/layout/_main-container.scss +15 -0
  39. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +45 -0
  40. data/app/assets/stylesheets/thredded/layout/_topic-navigation.scss +53 -0
  41. data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +87 -0
  42. data/app/assets/stylesheets/thredded/utilities/_is-compact.scss +26 -0
  43. data/app/assets/stylesheets/thredded/utilities/_is-expanded.scss +16 -0
  44. data/app/assets/stylesheets/thredded.scss +3 -0
  45. data/app/commands/thredded/at_notification_extractor.rb +15 -0
  46. data/app/commands/thredded/members_marked_notified.rb +18 -0
  47. data/app/commands/thredded/messageboard_destroyer.rb +60 -0
  48. data/app/commands/thredded/notify_mentioned_users.rb +68 -0
  49. data/app/commands/thredded/notify_private_topic_users.rb +51 -0
  50. data/app/commands/thredded/user_reads_private_topic.rb +22 -0
  51. data/app/commands/thredded/user_resets_private_topic_to_unread.rb +23 -0
  52. data/app/controllers/thredded/application_controller.rb +105 -0
  53. data/app/controllers/thredded/messageboards_controller.rb +58 -0
  54. data/app/controllers/thredded/posts_controller.rb +78 -0
  55. data/app/controllers/thredded/preferences_controller.rb +28 -0
  56. data/app/controllers/thredded/private_topics_controller.rb +65 -0
  57. data/app/controllers/thredded/setups_controller.rb +53 -0
  58. data/app/controllers/thredded/theme_previews_controller.rb +59 -0
  59. data/app/controllers/thredded/topics_controller.rb +153 -0
  60. data/app/decorators/thredded/base_topic_decorator.rb +14 -0
  61. data/app/decorators/thredded/base_user_topic_decorator.rb +63 -0
  62. data/app/decorators/thredded/messageboard_decorator.rb +41 -0
  63. data/app/decorators/thredded/post_decorator.rb +40 -0
  64. data/app/decorators/thredded/private_topic_decorator.rb +23 -0
  65. data/app/decorators/thredded/topic_decorator.rb +25 -0
  66. data/app/decorators/thredded/topic_email_decorator.rb +24 -0
  67. data/app/decorators/thredded/user_private_topic_decorator.rb +13 -0
  68. data/app/decorators/thredded/user_topic_decorator.rb +37 -0
  69. data/app/forms/thredded/private_topic_form.rb +126 -0
  70. data/app/forms/thredded/topic_form.rb +94 -0
  71. data/app/helpers/thredded/application_helper.rb +41 -0
  72. data/app/jobs/thredded/activity_updater_job.rb +20 -0
  73. data/app/jobs/thredded/at_notifier_job.rb +11 -0
  74. data/app/jobs/thredded/notify_private_topic_users_job.rb +11 -0
  75. data/app/mailers/thredded/base_mailer.rb +4 -0
  76. data/app/mailers/thredded/post_mailer.rb +15 -0
  77. data/app/mailers/thredded/private_post_mailer.rb +15 -0
  78. data/app/mailers/thredded/private_topic_mailer.rb +15 -0
  79. data/app/models/concerns/thredded/post_common.rb +105 -0
  80. data/app/models/concerns/thredded/topic_common.rb +48 -0
  81. data/app/models/thredded/ability.rb +60 -0
  82. data/app/models/thredded/category.rb +12 -0
  83. data/app/models/thredded/messageboard.rb +50 -0
  84. data/app/models/thredded/messageboard_user.rb +12 -0
  85. data/app/models/thredded/notification_preference.rb +17 -0
  86. data/app/models/thredded/null_preference.rb +11 -0
  87. data/app/models/thredded/null_topic.rb +15 -0
  88. data/app/models/thredded/null_topic_read.rb +19 -0
  89. data/app/models/thredded/null_user.rb +51 -0
  90. data/app/models/thredded/post.rb +37 -0
  91. data/app/models/thredded/post_notification.rb +17 -0
  92. data/app/models/thredded/private_post.rb +25 -0
  93. data/app/models/thredded/private_topic.rb +60 -0
  94. data/app/models/thredded/private_user.rb +6 -0
  95. data/app/models/thredded/stats.rb +37 -0
  96. data/app/models/thredded/topic.rb +104 -0
  97. data/app/models/thredded/topic_category.rb +6 -0
  98. data/app/models/thredded/user_detail.rb +26 -0
  99. data/app/models/thredded/user_extender.rb +33 -0
  100. data/app/models/thredded/user_permissions/admin/if_admin_column_true.rb +12 -0
  101. data/app/models/thredded/user_permissions/admin/none.rb +12 -0
  102. data/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb +13 -0
  103. data/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb +25 -0
  104. data/app/models/thredded/user_permissions/moderate/none.rb +25 -0
  105. data/app/models/thredded/user_permissions/read/all.rb +25 -0
  106. data/app/models/thredded/user_permissions/write/all.rb +25 -0
  107. data/app/models/thredded/user_permissions/write/none.rb +25 -0
  108. data/app/models/thredded/user_preference.rb +6 -0
  109. data/app/models/thredded/user_topic_read.rb +10 -0
  110. data/app/views/layouts/thredded/application.html.erb +15 -0
  111. data/app/views/thredded/categories/_category.html.erb +1 -0
  112. data/app/views/thredded/kaminari/_first_page.html.erb +11 -0
  113. data/app/views/thredded/kaminari/_gap.html.erb +8 -0
  114. data/app/views/thredded/kaminari/_last_page.html.erb +11 -0
  115. data/app/views/thredded/kaminari/_next_page.html.erb +11 -0
  116. data/app/views/thredded/kaminari/_page.html.erb +12 -0
  117. data/app/views/thredded/kaminari/_paginator.html.erb +23 -0
  118. data/app/views/thredded/kaminari/_prev_page.html.erb +11 -0
  119. data/app/views/thredded/messageboards/_messageboard.html.erb +15 -0
  120. data/app/views/thredded/messageboards/index.html.erb +20 -0
  121. data/app/views/thredded/messageboards/new.html.erb +18 -0
  122. data/app/views/thredded/post_mailer/at_notification.html.erb +14 -0
  123. data/app/views/thredded/post_mailer/at_notification.text.erb +10 -0
  124. data/app/views/thredded/posts/_content_field.html.erb +4 -0
  125. data/app/views/thredded/posts/_form.html.erb +1 -0
  126. data/app/views/thredded/posts/_post.html.erb +1 -0
  127. data/app/views/thredded/posts/_user.html.erb +3 -0
  128. data/app/views/thredded/posts/edit.html.erb +13 -0
  129. data/app/views/thredded/posts_common/_form.html.erb +10 -0
  130. data/app/views/thredded/posts_common/_post.html.erb +20 -0
  131. data/app/views/thredded/preferences/_form.html.erb +28 -0
  132. data/app/views/thredded/preferences/_header.html.erb +1 -0
  133. data/app/views/thredded/preferences/edit.html.erb +12 -0
  134. data/app/views/thredded/private_post_mailer/at_notification.html.erb +11 -0
  135. data/app/views/thredded/private_posts/_form.html.erb +1 -0
  136. data/app/views/thredded/private_posts/_private_post.html.erb +1 -0
  137. data/app/views/thredded/private_topic_mailer/message_notification.html.erb +17 -0
  138. data/app/views/thredded/private_topic_mailer/message_notification.text.erb +13 -0
  139. data/app/views/thredded/private_topics/_breadcrumbs.html.erb +4 -0
  140. data/app/views/thredded/private_topics/_form.html.erb +24 -0
  141. data/app/views/thredded/private_topics/_no_private_topics.html.erb +6 -0
  142. data/app/views/thredded/private_topics/_private_topic.html.erb +22 -0
  143. data/app/views/thredded/private_topics/index.html.erb +23 -0
  144. data/app/views/thredded/private_topics/new.html.erb +13 -0
  145. data/app/views/thredded/private_topics/show.html.erb +14 -0
  146. data/app/views/thredded/search/_form.html.erb +7 -0
  147. data/app/views/thredded/shared/_currently_online.html.erb +16 -0
  148. data/app/views/thredded/shared/_flash_messages.html.erb +7 -0
  149. data/app/views/thredded/shared/_header.html.erb +4 -0
  150. data/app/views/thredded/shared/_messageboard_topics_breadcrumbs.html.erb +6 -0
  151. data/app/views/thredded/shared/_notification_preferences.html.erb +7 -0
  152. data/app/views/thredded/shared/_page.html.erb +6 -0
  153. data/app/views/thredded/shared/_time_ago.html.erb +7 -0
  154. data/app/views/thredded/shared/_top_nav.html.erb +36 -0
  155. data/app/views/thredded/shared/_topic_nav.html.erb +22 -0
  156. data/app/views/thredded/theme_previews/_section_title.html.erb +3 -0
  157. data/app/views/thredded/theme_previews/show.html.erb +108 -0
  158. data/app/views/thredded/topics/_form.html.erb +23 -0
  159. data/app/views/thredded/topics/_recent_topics_by_user.html.erb +8 -0
  160. data/app/views/thredded/topics/_topic.html.erb +29 -0
  161. data/app/views/thredded/topics/_topic_form_admin_options.html.erb +12 -0
  162. data/app/views/thredded/topics/by_category.html.erb +56 -0
  163. data/app/views/thredded/topics/edit.html.erb +38 -0
  164. data/app/views/thredded/topics/index.html.erb +18 -0
  165. data/app/views/thredded/topics/menu/_new_topic.html.erb +3 -0
  166. data/app/views/thredded/topics/new.html.erb +11 -0
  167. data/app/views/thredded/topics/search.html.erb +9 -0
  168. data/app/views/thredded/topics/show.html.erb +31 -0
  169. data/app/views/thredded/topics_common/_header.html.erb +6 -0
  170. data/app/views/thredded/users/_link.html.erb +9 -0
  171. data/config/routes.rb +28 -0
  172. data/db/migrate/20160329231848_create_thredded.rb +173 -0
  173. data/lib/generators/thredded/install/USAGE +13 -0
  174. data/lib/generators/thredded/install/install_generator.rb +23 -0
  175. data/lib/generators/thredded/install/templates/initializer.rb +51 -0
  176. data/lib/html/pipeline/at_mention_filter.rb +20 -0
  177. data/lib/html/pipeline/bbcode_filter.rb +19 -0
  178. data/lib/tasks/thredded_tasks.rake +18 -0
  179. data/lib/thredded/at_users.rb +19 -0
  180. data/lib/thredded/engine.rb +35 -0
  181. data/lib/thredded/errors.rb +67 -0
  182. data/lib/thredded/main_app_route_delegator.rb +24 -0
  183. data/lib/thredded/messageboard_user_permissions.rb +22 -0
  184. data/lib/thredded/post_sql_builder.rb +12 -0
  185. data/lib/thredded/post_user_permissions.rb +32 -0
  186. data/lib/thredded/private_topic_user_permissions.rb +26 -0
  187. data/lib/thredded/search_parser.rb +45 -0
  188. data/lib/thredded/search_sql_builder.rb +21 -0
  189. data/lib/thredded/seed_database.rb +76 -0
  190. data/lib/thredded/table_sql_builder.rb +41 -0
  191. data/lib/thredded/topic_sql_builder.rb +11 -0
  192. data/lib/thredded/topic_user_permissions.rb +32 -0
  193. data/lib/thredded/version.rb +3 -0
  194. data/lib/thredded.rb +85 -0
  195. data/thredded.gemspec +68 -0
  196. metadata +248 -122
@@ -0,0 +1,26 @@
1
+ module Thredded
2
+ class PrivateTopicUserPermissions
3
+ def initialize(private_topic, user, _user_details)
4
+ @private_topic = private_topic
5
+ @user = user
6
+ end
7
+
8
+ def readable?
9
+ @private_topic.users.include?(@user)
10
+ end
11
+
12
+ def manageable?
13
+ user_started_topic?
14
+ end
15
+
16
+ def creatable?
17
+ !@user.thredded_anonymous?
18
+ end
19
+
20
+ private
21
+
22
+ def user_started_topic?
23
+ @user.id == @private_topic.user_id
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ module Thredded
2
+ class SearchParser
3
+ def initialize(query)
4
+ @query = query
5
+ @keywords = %w(in by order)
6
+ end
7
+
8
+ def parse
9
+ parsed_input = parse_keywords
10
+ parsed_input['text'] = parse_text
11
+ parsed_input
12
+ end
13
+
14
+ def parse_keywords
15
+ found_terms_hash = {}
16
+
17
+ @keywords.each do |keyword|
18
+ regex = Regexp.new(keyword + '\s*:\s*\w+', Regexp::IGNORECASE)
19
+ keyword_scan = @query.scan(regex)
20
+ @query = @query.gsub(regex, '')
21
+
22
+ if keyword_scan.present?
23
+ keyword_scan.each do |term|
24
+ keyword_term = term.gsub(' ', '').split(':')
25
+
26
+ if found_terms_hash[keyword].nil?
27
+ found_terms_hash[keyword] = []
28
+ end
29
+
30
+ found_terms_hash[keyword] << keyword_term[1]
31
+ end
32
+ end
33
+ end
34
+
35
+ found_terms_hash
36
+ end
37
+
38
+ def parse_text
39
+ regex = Regexp.new('\"[^"]*\"')
40
+ found_terms = @query.scan(regex)
41
+ @query = @query.sub(regex, '')
42
+ found_terms.concat(@query.split(/\s+/))
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ require 'thredded/topic_sql_builder'
2
+ require 'thredded/post_sql_builder'
3
+
4
+ module Thredded
5
+ class SearchSqlBuilder
6
+ def initialize(query, messageboard)
7
+ @topic_builder = TopicSqlBuilder.new(query, messageboard)
8
+ @post_builder = PostSqlBuilder.new(query, messageboard)
9
+ @order_by = 'ORDER BY updated_at DESC'
10
+ end
11
+
12
+ def build
13
+ [
14
+ 'SELECT * FROM thredded_topics WHERE id IN (', @post_builder.sql,
15
+ 'UNION', @topic_builder.sql,
16
+ ')', @order_by,
17
+ 'LIMIT 50'
18
+ ].join(' ')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,76 @@
1
+ require 'factory_girl_rails'
2
+
3
+ # rubocop:disable HandleExceptions
4
+ begin
5
+ if FactoryGirl.factories.instance_variable_get(:@items).none?
6
+ require_relative '../../../spec/factories'
7
+ end
8
+ rescue NameError
9
+ end
10
+ # rubocop:enable HandleExceptions
11
+
12
+ module Thredded
13
+ class SeedDatabase
14
+ attr_reader :user, :users, :messageboard, :topics, :private_topics, :posts
15
+
16
+ def self.run(users: 5, topics: 26, posts: (0..20))
17
+ s = new
18
+ s.create_messageboard
19
+ s.create_first_user
20
+ s.create_users(count: users)
21
+ s.create_topics(count: topics)
22
+ s.create_posts(count: posts)
23
+ s.create_private_posts(count: posts)
24
+ end
25
+
26
+ def create_first_user
27
+ @user ||= begin
28
+ ::User.first ||
29
+ ::User.create(name: 'joe', email: 'joe@example.com')
30
+ end
31
+ end
32
+
33
+ def create_users(count: 5)
34
+ @users = [user] + FactoryGirl.create_list(:user, count)
35
+ end
36
+
37
+ def create_messageboard
38
+ @messageboard = FactoryGirl.create(
39
+ :messageboard,
40
+ name: 'Main Board',
41
+ slug: 'main-board',
42
+ description: 'A board is not a board without some posts'
43
+ )
44
+ end
45
+
46
+ def create_topics(count: 26)
47
+ @topics = FactoryGirl.create_list(
48
+ :topic, count,
49
+ messageboard: messageboard,
50
+ user: users.sample,
51
+ last_user: users.sample)
52
+
53
+ @private_topics = FactoryGirl.create_list(
54
+ :private_topic, count,
55
+ user: users.sample,
56
+ last_user: users.sample,
57
+ users: [user])
58
+ end
59
+
60
+ def create_posts(count: (0..30))
61
+ @posts = topics.flat_map do |topic|
62
+ (count.min + rand(count.max + 1)).times do
63
+ FactoryGirl.create(:post, postable: topic, messageboard: messageboard, user: users.sample)
64
+ end
65
+ end
66
+ end
67
+
68
+ def create_private_posts(count: (0..30))
69
+ @private_posts = private_topics.flat_map do |topic|
70
+ (count.min + rand(count.max + 1)).times do
71
+ FactoryGirl.create(:private_post, postable: topic, user: users.sample)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,41 @@
1
+ require 'thredded/search_parser'
2
+ module Thredded
3
+ class TableSqlBuilder
4
+ def initialize(query, messageboard)
5
+ @terms = SearchParser.new(query).parse
6
+ @scope = Thredded::Topic.select(:id).where(messageboard_id: messageboard.id)
7
+ @search_categories = @search_users = @search_text = nil
8
+ end
9
+
10
+ def sql
11
+ apply_filters
12
+ @scope.to_sql
13
+ end
14
+
15
+ protected
16
+
17
+ def categories
18
+ @search_categories ||=
19
+ if @terms['in']
20
+ DbTextSearch::CaseInsensitiveEq.new(Category, :name)
21
+ .find(@terms['in']).pluck(:id)
22
+ else
23
+ []
24
+ end
25
+ end
26
+
27
+ def users
28
+ @search_users ||=
29
+ if @terms['by']
30
+ DbTextSearch::CaseInsensitiveEq.new(Thredded.user_class, Thredded.user_name_column)
31
+ .find(@terms['by']).pluck(:id)
32
+ else
33
+ []
34
+ end
35
+ end
36
+
37
+ def text
38
+ @terms['text']
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,11 @@
1
+ require 'thredded/table_sql_builder'
2
+
3
+ module Thredded
4
+ class TopicSqlBuilder < TableSqlBuilder
5
+ def apply_filters
6
+ @scope = @scope.joins(:topic_categories).where(category_id: categories) if categories.present?
7
+ @scope = @scope.where(user_id: users) if users.present?
8
+ @scope = DbTextSearch::FullTextSearch.new(@scope, :title).find(text) if text.present?
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Thredded
2
+ class TopicUserPermissions
3
+ def initialize(topic, user, _user_details)
4
+ @topic = topic
5
+ @messageboard = topic.messageboard
6
+ @messageboard_user_permission = MessageboardUserPermissions.new(topic.messageboard, user)
7
+ @user = user
8
+ end
9
+
10
+ def creatable?
11
+ @messageboard_user_permission.postable?
12
+ end
13
+
14
+ def adminable?
15
+ @messageboard_user_permission.moderatable?
16
+ end
17
+
18
+ def editable?
19
+ started_by_user? || adminable?
20
+ end
21
+
22
+ def readable?
23
+ @messageboard_user_permission.readable?
24
+ end
25
+
26
+ private
27
+
28
+ def started_by_user?
29
+ @topic.user_id == @user.id
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Thredded
2
+ VERSION = '0.2.2'
3
+ end
data/lib/thredded.rb ADDED
@@ -0,0 +1,85 @@
1
+ # Backend
2
+ require 'cancan'
3
+ require 'db_text_search'
4
+ require 'friendly_id'
5
+ require 'html/pipeline'
6
+ require 'html/pipeline/at_mention_filter'
7
+ require 'html/pipeline/bbcode_filter'
8
+ require 'kaminari'
9
+ require 'rb-gravatar'
10
+ require 'active_job'
11
+
12
+ # Asset compilation
13
+ require 'autoprefixer-rails'
14
+ require 'autosize/rails'
15
+ require 'jquery/rails'
16
+ require 'rails-timeago'
17
+ require 'select2-rails'
18
+ require 'sprockets/es6'
19
+
20
+ require 'thredded/engine'
21
+ require 'thredded/errors'
22
+ require 'thredded/messageboard_user_permissions'
23
+ require 'thredded/post_user_permissions'
24
+ require 'thredded/private_topic_user_permissions'
25
+ require 'thredded/topic_user_permissions'
26
+ require 'thredded/search_sql_builder'
27
+ require 'thredded/main_app_route_delegator'
28
+
29
+ module Thredded
30
+ mattr_accessor :user_class,
31
+ :user_name_column,
32
+ :avatar_url,
33
+ :email_incoming_host,
34
+ :email_from,
35
+ :email_outgoing_prefix,
36
+ :email_reply_to,
37
+ :user_path,
38
+ :layout,
39
+ :active_user_threshold
40
+
41
+ # @return [Symbol] The name of the moderator flag column on the users table for the default permissions model
42
+ mattr_accessor :moderator_column
43
+
44
+ # @return [Symbol] The name of the admin flag column on the users table for the default permissions model
45
+ mattr_accessor :admin_column
46
+
47
+ self.user_name_column = :name
48
+ self.avatar_url = ->(user) { Gravatar.src(user.email, 128, 'mm') }
49
+ self.active_user_threshold = 5.minutes
50
+ self.layout = 'thredded/application'
51
+ self.email_reply_to = -> postable { "#{postable.hash_id}@#{Thredded.email_incoming_host}" }
52
+ self.moderator_column = :admin
53
+ self.admin_column = :admin
54
+
55
+ # @return [Class<Thredded::UserExtender>] the user class from the host application.
56
+ def self.user_class
57
+ if @@user_class.is_a?(Class)
58
+ fail 'Please use a string instead of a class'
59
+ end
60
+
61
+ if @@user_class.is_a?(String)
62
+ begin
63
+ Object.const_get(@@user_class)
64
+ rescue NameError
65
+ @@user_class.constantize
66
+ end
67
+ end
68
+ end
69
+
70
+ # @param view_context [Object] context to execute the lambda in.
71
+ # @param user [Thredded.user_class]
72
+ # @return [String] path to the user evaluated in the specified context.
73
+ def self.user_path(view_context, user)
74
+ if @@user_path.respond_to? :call
75
+ view_context.instance_exec(user, &@@user_path)
76
+ else
77
+ '/'
78
+ end
79
+ end
80
+
81
+ # Whether the layout is a thredded layout as opposed to the application layout.
82
+ def self.standalone_layout?
83
+ layout.is_a?(String) && layout.start_with?('thredded/')
84
+ end
85
+ end
data/thredded.gemspec ADDED
@@ -0,0 +1,68 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+
3
+ require 'thredded/version'
4
+
5
+ # Describe your gem and declare its dependencies:
6
+ Gem::Specification.new do |s|
7
+ s.name = 'thredded'
8
+ s.version = Thredded::VERSION
9
+ s.authors = ['Joel Oliveira', 'Gleb Mazovetskiy']
10
+ s.email = ['joel@thredded.com', 'glex.spb@gmail.com']
11
+ s.homepage = 'https://www.thredded.com'
12
+ s.summary = 'A messageboard engine'
13
+ s.license = 'MIT'
14
+ s.description = 'A messageboard engine for Rails 4.1+ apps'
15
+
16
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|script)/|^\.}) } -
17
+ %w(Dockerfile docker-compose.yml Rakefile Gemfile shared.gemfile)
18
+
19
+ # backend
20
+ s.add_dependency 'bbcoder', '~> 1.0'
21
+ s.add_dependency 'cancancan'
22
+ s.add_dependency 'db_text_search', '~> 0.1.1'
23
+ s.add_dependency 'friendly_id'
24
+ s.add_dependency 'html-pipeline'
25
+ s.add_dependency 'htmlentities'
26
+ s.add_dependency 'kaminari'
27
+ s.add_dependency 'nokogiri'
28
+ s.add_dependency 'rails', '>= 4.1.0'
29
+ s.add_dependency 'rb-gravatar'
30
+
31
+ # html-pipeline dependencies, see https://github.com/jch/html-pipeline#dependencies
32
+ s.add_dependency 'gemoji'
33
+ s.add_dependency 'github-markdown'
34
+ s.add_dependency 'rinku'
35
+ s.add_dependency 'sanitize'
36
+
37
+ # frontend
38
+ s.add_dependency 'sass', '>= 3.4.21'
39
+ s.add_dependency 'autoprefixer-rails'
40
+ s.add_dependency 'rails-timeago'
41
+ s.add_dependency 'select2-rails', '~> 3.5'
42
+ s.add_dependency 'autosize-rails'
43
+ s.add_dependency 'sprockets-es6'
44
+ s.add_dependency 'jquery-rails'
45
+
46
+ # test dependencies
47
+ s.add_development_dependency 'capybara', '~> 2.4'
48
+ s.add_development_dependency 'chronic'
49
+ s.add_development_dependency 'database_cleaner'
50
+ s.add_development_dependency 'factory_girl_rails'
51
+ s.add_development_dependency 'faker'
52
+ s.add_development_dependency 'launchy'
53
+ s.add_development_dependency 'rspec-rails'
54
+ s.add_development_dependency 'rubocop', '0.32.0'
55
+ s.add_development_dependency 'shoulda-matchers', '~> 2.7'
56
+ s.add_development_dependency 'test-unit'
57
+ s.add_development_dependency 'timecop'
58
+
59
+ # dummy app dependencies
60
+ s.add_development_dependency 'mysql2'
61
+ s.add_development_dependency 'pg'
62
+ s.add_development_dependency 'sqlite3'
63
+ s.add_development_dependency 'puma'
64
+
65
+ # dummy app frontend
66
+ s.add_development_dependency 'jquery-turbolinks'
67
+ s.add_development_dependency 'turbolinks'
68
+ end