thredded 0.6.2 → 0.6.3
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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +1 -1
- data/app/assets/stylesheets/thredded/base/_buttons.scss +17 -0
- data/app/assets/stylesheets/thredded/base/_variables.scss +8 -1
- data/app/commands/thredded/mark_all_read.rb +21 -0
- data/app/controllers/thredded/messageboard_groups_controller.rb +1 -1
- data/app/controllers/thredded/moderation_controller.rb +1 -1
- data/app/controllers/thredded/read_states_controller.rb +12 -0
- data/app/forms/thredded/topic_form.rb +0 -1
- data/app/helpers/thredded/urls_helper.rb +1 -1
- data/app/models/concerns/thredded/post_common.rb +14 -2
- data/app/models/concerns/thredded/topic_common.rb +9 -1
- data/app/models/thredded/messageboard.rb +7 -0
- data/app/models/thredded/post.rb +11 -18
- data/app/models/thredded/private_post.rb +1 -5
- data/app/models/thredded/private_topic.rb +0 -4
- data/app/models/thredded/topic.rb +26 -12
- data/app/view_models/thredded/topic_view.rb +1 -0
- data/app/view_models/thredded/topics_page_view.rb +3 -2
- data/app/views/thredded/preferences/_form.html.erb +1 -1
- data/app/views/thredded/private_topic_mailer/message_notification.html.erb +1 -1
- data/app/views/thredded/private_topic_mailer/message_notification.text.erb +1 -1
- data/app/views/thredded/private_topics/index.html.erb +14 -6
- data/config/locales/en.yml +2 -1
- data/config/locales/pt-BR.yml +9 -10
- data/config/routes.rb +2 -1
- data/db/seeds.rb +1 -118
- data/heroku.gemfile +1 -2
- data/heroku.gemfile.lock +60 -64
- data/lib/thredded/database_seeder.rb +269 -0
- data/lib/thredded/main_app_route_delegator.rb +1 -1
- data/lib/thredded/version.rb +1 -1
- data/thredded.gemspec +3 -3
- metadata +12 -9
@@ -0,0 +1,269 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'factory_girl_rails'
|
3
|
+
|
4
|
+
# rubocop:disable HandleExceptions
|
5
|
+
begin
|
6
|
+
if FactoryGirl.factories.instance_variable_get(:@items).none?
|
7
|
+
require_relative '../../spec/factories'
|
8
|
+
end
|
9
|
+
rescue NameError
|
10
|
+
end
|
11
|
+
# rubocop:enable HandleExceptions
|
12
|
+
module Thredded
|
13
|
+
class DatabaseSeeder
|
14
|
+
SKIP_CALLBACKS = [
|
15
|
+
[Thredded::Post, :commit, :after, :auto_follow_and_notify],
|
16
|
+
[Thredded::PrivatePost, :commit, :after, :notify_users],
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def self.run(users: 200, topics: 55, posts: (1..60))
|
20
|
+
STDERR.puts 'Seeding the database...'
|
21
|
+
# Disable callbacks to avoid creating notifications and performing unnecessary updates
|
22
|
+
SKIP_CALLBACKS.each { |(klass, *args)| klass.skip_callback(*args) }
|
23
|
+
s = new
|
24
|
+
Messageboard.transaction do
|
25
|
+
s.seed(users: users, topics: topics, posts: posts)
|
26
|
+
s.log 'Running after_commit callbacks'
|
27
|
+
end
|
28
|
+
ensure
|
29
|
+
# Re-enable callbacks
|
30
|
+
SKIP_CALLBACKS.each { |(klass, *args)| klass.set_callback(*args) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def seed(users: 200, topics: 55, posts: (1..60))
|
34
|
+
users(count: users)
|
35
|
+
first_messageboard
|
36
|
+
topics(count: topics)
|
37
|
+
private_topics(count: topics)
|
38
|
+
posts(count: posts)
|
39
|
+
private_posts(count: posts)
|
40
|
+
create_additional_messageboards
|
41
|
+
follow_some_topics
|
42
|
+
read_some_topics
|
43
|
+
end
|
44
|
+
|
45
|
+
def log(message)
|
46
|
+
STDERR.puts "- #{message}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def first_user
|
50
|
+
@first_user ||= FirstUser.new(self).find_or_create
|
51
|
+
end
|
52
|
+
|
53
|
+
def users(count: 1)
|
54
|
+
@users ||= Users.new(self).find_or_create(count: count)
|
55
|
+
end
|
56
|
+
|
57
|
+
def first_messageboard
|
58
|
+
@first_messageboard ||= FirstMessageboard.new(self).find_or_create
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_additional_messageboards
|
62
|
+
meta_group_id = MessageboardGroup.create!(name: 'Meta').id
|
63
|
+
additional_messageboards = [
|
64
|
+
['Off-Topic', "Talk about whatever here, it's all good."],
|
65
|
+
['Help, Bugs, and Suggestions',
|
66
|
+
'Need help using the forum? Want to report a bug or make a suggestion? This is the place.', meta_group_id],
|
67
|
+
['Praise', 'Want to tell us how great we are? This is the place.', meta_group_id]
|
68
|
+
]
|
69
|
+
log "Creating #{additional_messageboards.length} additional messageboards..."
|
70
|
+
additional_messageboards.each do |(name, description, group_id)|
|
71
|
+
messageboard = Messageboard.create!(name: name, description: description, messageboard_group_id: group_id)
|
72
|
+
FactoryGirl.create_list(:topic, 1 + rand(3), messageboard: messageboard, with_posts: 1)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def topics(count: 1)
|
77
|
+
@topics ||= Topics.new(self).find_or_create(count: count)
|
78
|
+
end
|
79
|
+
|
80
|
+
def private_topics(count: 1)
|
81
|
+
@private_topics ||= PrivateTopics.new(self).find_or_create(count: count)
|
82
|
+
end
|
83
|
+
|
84
|
+
def posts(count: (1..1))
|
85
|
+
@posts ||= Posts.new(self).find_or_create(count: count)
|
86
|
+
end
|
87
|
+
|
88
|
+
def private_posts(count: (1..1))
|
89
|
+
@private_posts ||= PrivatePosts.new(self).find_or_create(count: count)
|
90
|
+
end
|
91
|
+
|
92
|
+
def follow_some_topics(count: (5..10), count_users: (1..5))
|
93
|
+
log 'Following some topics...'
|
94
|
+
posts.each do |post|
|
95
|
+
Thredded::UserTopicFollow.create_unless_exists(post.user_id, post.postable_id, :posted) if post.user_id
|
96
|
+
end
|
97
|
+
follow_some_topics_by_user(first_user, count: count)
|
98
|
+
users.sample(count_users.min + rand(count_users.max - count_users.min + 2)).each do |user|
|
99
|
+
follow_some_topics_by_user(user, count: count)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def follow_some_topics_by_user(user, count: (1..10))
|
104
|
+
topics.sample(count.min + rand(count.max - count.min + 2)).each do |topic|
|
105
|
+
Thredded::UserTopicFollow.create_unless_exists(user.id, topic.id)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def read_some_topics(count: (5..10), count_users: (1..5))
|
110
|
+
log 'Reading some topics...'
|
111
|
+
topics.each do |topic|
|
112
|
+
read_topic(topic, topic.last_user_id) if topic.last_user_id
|
113
|
+
end
|
114
|
+
read_some_topics_by_user(first_user, count: count)
|
115
|
+
@users.sample(count_users.min + rand(count_users.max - count_users.min + 2)).each do |user|
|
116
|
+
read_some_topics_by_user(user, count: count)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def read_some_topics_by_user(user, count: (1..10))
|
121
|
+
topics.sample(count.min + rand(count.max - count.min + 2)).each do |topic|
|
122
|
+
read_topic(topic, user.id)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def read_topic(topic, user_id)
|
127
|
+
Thredded::UserTopicReadState.find_or_initialize_by(user_id: user_id, postable_id: topic.id)
|
128
|
+
.update!(read_at: topic.updated_at, page: 1)
|
129
|
+
end
|
130
|
+
|
131
|
+
class BaseSeedData
|
132
|
+
attr_reader :seeder
|
133
|
+
|
134
|
+
def initialize(seed_database)
|
135
|
+
@seeder = seed_database
|
136
|
+
end
|
137
|
+
|
138
|
+
delegate :log, to: :seeder
|
139
|
+
|
140
|
+
def find_or_create(*args)
|
141
|
+
return @stored if @stored
|
142
|
+
@stored = (find || create(*args))
|
143
|
+
end
|
144
|
+
|
145
|
+
protected
|
146
|
+
|
147
|
+
def model_class
|
148
|
+
self.class::MODEL_CLASS
|
149
|
+
end
|
150
|
+
|
151
|
+
# @abstract
|
152
|
+
def create(*_args)
|
153
|
+
fail 'Unimplemented'
|
154
|
+
end
|
155
|
+
|
156
|
+
# @abstract
|
157
|
+
def find
|
158
|
+
fail 'Unimplemented'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class FirstSeedData < BaseSeedData
|
163
|
+
def find
|
164
|
+
model_class.first
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class CollectionSeedData < BaseSeedData
|
169
|
+
def find
|
170
|
+
return nil unless model_class.exists?
|
171
|
+
model_class.all.to_a
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class FirstUser < FirstSeedData
|
176
|
+
MODEL_CLASS = User
|
177
|
+
|
178
|
+
def create
|
179
|
+
log 'Creating first user...'
|
180
|
+
FactoryGirl.create(:user, :approved, :admin, name: 'Joe', email: 'joe@example.com')
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class Users < CollectionSeedData
|
185
|
+
MODEL_CLASS = User
|
186
|
+
|
187
|
+
def create(count: 1)
|
188
|
+
log "Creating #{count} users..."
|
189
|
+
approved_users_count = (count * 0.97).round
|
190
|
+
[seeder.first_user] +
|
191
|
+
FactoryGirl.create_list(:user, approved_users_count, :approved) +
|
192
|
+
FactoryGirl.create_list(:user, count - approved_users_count)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class FirstMessageboard < FirstSeedData
|
197
|
+
MODEL_CLASS = Messageboard
|
198
|
+
|
199
|
+
def create
|
200
|
+
log 'Creating a messageboard...'
|
201
|
+
@first_messageboard = FactoryGirl.create(
|
202
|
+
:messageboard,
|
203
|
+
name: 'Main Board',
|
204
|
+
slug: 'main-board',
|
205
|
+
description: 'A board is not a board without some posts'
|
206
|
+
)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
class Topics < CollectionSeedData
|
211
|
+
MODEL_CLASS = Topic
|
212
|
+
|
213
|
+
def create(count: 1, messageboard: seeder.first_messageboard)
|
214
|
+
log "Creating #{count} topics in #{messageboard.name}..."
|
215
|
+
FactoryGirl.create_list(
|
216
|
+
:topic, count,
|
217
|
+
messageboard: messageboard,
|
218
|
+
user: seeder.users.sample,
|
219
|
+
last_user: seeder.users.sample
|
220
|
+
)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class PrivateTopics < CollectionSeedData
|
225
|
+
MODEL_CLASS = PrivateTopic
|
226
|
+
|
227
|
+
def create(count: 1)
|
228
|
+
FactoryGirl.create_list(
|
229
|
+
:private_topic, count,
|
230
|
+
user: seeder.users[1..-1].sample,
|
231
|
+
last_user: seeder.users.sample,
|
232
|
+
users: [seeder.first_user]
|
233
|
+
)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
class Posts < CollectionSeedData
|
238
|
+
MODEL_CLASS = Post
|
239
|
+
|
240
|
+
def create(count: (1..1))
|
241
|
+
log "Creating #{count} additional posts in each topic..."
|
242
|
+
seeder.topics.flat_map do |topic|
|
243
|
+
written = (1 + rand(5)).days.ago
|
244
|
+
posts = Array.new((count.min + rand(count.max + 1))) do
|
245
|
+
written += (1 + rand(60)).minutes
|
246
|
+
FactoryGirl.create(:post, postable: topic, messageboard: seeder.first_messageboard,
|
247
|
+
user: seeder.users.sample, created_at: written, updated_at: written)
|
248
|
+
end
|
249
|
+
topic.update!(last_user_id: posts.last.user.id, updated_at: written)
|
250
|
+
posts
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
class PrivatePosts < CollectionSeedData
|
256
|
+
MODEL_CLASS = PrivatePost
|
257
|
+
|
258
|
+
def create(count: (1..1))
|
259
|
+
log "Creating #{count} additional posts in each private topic..."
|
260
|
+
seeder.private_topics.flat_map do |topic|
|
261
|
+
(count.min + rand(count.max + 1)).times do
|
262
|
+
FactoryGirl.create(:private_post, postable: topic, user: seeder.users.sample)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/thredded/version.rb
CHANGED
data/thredded.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.version = Thredded::VERSION
|
10
10
|
s.authors = ['Joel Oliveira', 'Gleb Mazovetskiy']
|
11
11
|
s.email = ['joel@thredded.com', 'glex.spb@gmail.com']
|
12
|
-
s.homepage = 'https://
|
12
|
+
s.homepage = 'https://thredded.org'
|
13
13
|
s.summary = 'The best Rails forums engine ever.'
|
14
14
|
s.license = 'MIT'
|
15
15
|
s.description = 'The best Rails 4.2+ forums engine ever. Its goal is to be as simple and feature rich as possible.
|
@@ -56,8 +56,8 @@ Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. See the demo at htt
|
|
56
56
|
s.add_development_dependency 'factory_girl_rails'
|
57
57
|
s.add_development_dependency 'faker', '>= 1.6.2'
|
58
58
|
s.add_development_dependency 'launchy'
|
59
|
-
s.add_development_dependency 'rspec-rails'
|
60
|
-
s.add_development_dependency 'rubocop', '
|
59
|
+
s.add_development_dependency 'rspec-rails', '>= 3.5.0'
|
60
|
+
s.add_development_dependency 'rubocop', '= 0.42.0'
|
61
61
|
s.add_development_dependency 'test-unit'
|
62
62
|
|
63
63
|
# dummy app dependencies
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thredded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-08-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bbcoder
|
@@ -423,28 +423,28 @@ dependencies:
|
|
423
423
|
requirements:
|
424
424
|
- - ">="
|
425
425
|
- !ruby/object:Gem::Version
|
426
|
-
version:
|
426
|
+
version: 3.5.0
|
427
427
|
type: :development
|
428
428
|
prerelease: false
|
429
429
|
version_requirements: !ruby/object:Gem::Requirement
|
430
430
|
requirements:
|
431
431
|
- - ">="
|
432
432
|
- !ruby/object:Gem::Version
|
433
|
-
version:
|
433
|
+
version: 3.5.0
|
434
434
|
- !ruby/object:Gem::Dependency
|
435
435
|
name: rubocop
|
436
436
|
requirement: !ruby/object:Gem::Requirement
|
437
437
|
requirements:
|
438
|
-
- -
|
438
|
+
- - '='
|
439
439
|
- !ruby/object:Gem::Version
|
440
|
-
version:
|
440
|
+
version: 0.42.0
|
441
441
|
type: :development
|
442
442
|
prerelease: false
|
443
443
|
version_requirements: !ruby/object:Gem::Requirement
|
444
444
|
requirements:
|
445
|
-
- -
|
445
|
+
- - '='
|
446
446
|
- !ruby/object:Gem::Version
|
447
|
-
version:
|
447
|
+
version: 0.42.0
|
448
448
|
- !ruby/object:Gem::Dependency
|
449
449
|
name: test-unit
|
450
450
|
requirement: !ruby/object:Gem::Requirement
|
@@ -668,6 +668,7 @@ files:
|
|
668
668
|
- app/assets/stylesheets/thredded/utilities/_is-expanded.scss
|
669
669
|
- app/commands/thredded/at_notification_extractor.rb
|
670
670
|
- app/commands/thredded/autofollow_mentioned_users.rb
|
671
|
+
- app/commands/thredded/mark_all_read.rb
|
671
672
|
- app/commands/thredded/members_marked_notified.rb
|
672
673
|
- app/commands/thredded/messageboard_destroyer.rb
|
673
674
|
- app/commands/thredded/moderate_post.rb
|
@@ -683,6 +684,7 @@ files:
|
|
683
684
|
- app/controllers/thredded/preferences_controller.rb
|
684
685
|
- app/controllers/thredded/private_post_permalinks_controller.rb
|
685
686
|
- app/controllers/thredded/private_topics_controller.rb
|
687
|
+
- app/controllers/thredded/read_states_controller.rb
|
686
688
|
- app/controllers/thredded/theme_previews_controller.rb
|
687
689
|
- app/controllers/thredded/topics_controller.rb
|
688
690
|
- app/forms/thredded/private_topic_form.rb
|
@@ -861,6 +863,7 @@ files:
|
|
861
863
|
- lib/tasks/thredded_tasks.rake
|
862
864
|
- lib/thredded.rb
|
863
865
|
- lib/thredded/content_formatter.rb
|
866
|
+
- lib/thredded/database_seeder.rb
|
864
867
|
- lib/thredded/engine.rb
|
865
868
|
- lib/thredded/errors.rb
|
866
869
|
- lib/thredded/main_app_route_delegator.rb
|
@@ -868,7 +871,7 @@ files:
|
|
868
871
|
- lib/thredded/topics_search.rb
|
869
872
|
- lib/thredded/version.rb
|
870
873
|
- thredded.gemspec
|
871
|
-
homepage: https://
|
874
|
+
homepage: https://thredded.org
|
872
875
|
licenses:
|
873
876
|
- MIT
|
874
877
|
metadata: {}
|