thredded 0.1.0 → 0.2.2

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 (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