discourse_dev 0.0.7 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/README.md +40 -4
- data/auth/app/views/fake_discourse_connect/form.html.erb +120 -0
- data/auth/plugin.rb +219 -0
- data/avatars/03F55412-DE8A-4F83-AAA6-D67EE5CE48DA-200w.jpeg +0 -0
- data/avatars/1C4EEDC2-FE9C-40B3-A2C9-A038873EE692-200w.jpeg +0 -0
- data/avatars/26CFEFB3-21C8-49FC-8C19-8E6A62B6D2E0-200w.jpeg +0 -0
- data/avatars/282A12CA-E0D7-4011-8BDD-1FAFAAB035F7-200w.jpeg +0 -0
- data/avatars/2DDDE973-40EC-4004-ABC0-73FD4CD6D042-200w.jpeg +0 -0
- data/avatars/344CFC24-61FB-426C-B3D1-CAD5BCBD3209-200w.jpeg +0 -0
- data/avatars/852EC6E1-347C-4187-9D42-DF264CCF17BF-200w.jpeg +0 -0
- data/avatars/A7299C8E-CEFC-47D9-939A-3C8CA0EA4D13-200w.jpeg +0 -0
- data/avatars/AEF44435-B547-4B84-A2AE-887DFAEE6DDF-200w.jpeg +0 -0
- data/avatars/B3CF5288-34B0-4A5E-9877-5965522529D6-200w.jpeg +0 -0
- data/avatars/BA0CB1F2-8C79-4376-B13B-DD5FB8772537-200w.jpeg +0 -0
- data/avatars/E0B4CAB3-F491-4322-BEF2-208B46748D4A-200w.jpeg +0 -0
- data/avatars/FBEBF655-4886-455A-A4A4-D62B77DD419B-200w.jpeg +0 -0
- data/config/dev.yml +38 -0
- data/config/locales/client.en.yml +6 -0
- data/{lib/faker/locales/en.yml → config/locales/faker.en.yml} +0 -0
- data/discourse_dev.gemspec +1 -0
- data/lib/discourse_dev.rb +49 -4
- data/lib/discourse_dev/category.rb +3 -3
- data/lib/discourse_dev/config.rb +101 -29
- data/lib/discourse_dev/group.rb +4 -5
- data/lib/discourse_dev/post.rb +35 -16
- data/lib/discourse_dev/record.rb +13 -11
- data/lib/discourse_dev/tag.rb +14 -2
- data/lib/discourse_dev/tasks/dev.rake +6 -2
- data/lib/discourse_dev/topic.rb +48 -11
- data/lib/discourse_dev/user.rb +58 -7
- data/lib/discourse_dev/version.rb +1 -1
- data/lib/faker/discourse_markdown.rb +96 -0
- metadata +36 -4
- data/lib/discourse_dev/config.yml +0 -4
data/lib/discourse_dev/tag.rb
CHANGED
@@ -7,8 +7,20 @@ require 'faker'
|
|
7
7
|
module DiscourseDev
|
8
8
|
class Tag < Record
|
9
9
|
|
10
|
-
def initialize
|
11
|
-
super(::Tag, count)
|
10
|
+
def initialize
|
11
|
+
super(::Tag, DiscourseDev.config.tag[:count])
|
12
|
+
end
|
13
|
+
|
14
|
+
def create!
|
15
|
+
super
|
16
|
+
rescue ActiveRecord::RecordInvalid => e
|
17
|
+
# If the name is taken, try again
|
18
|
+
retry
|
19
|
+
end
|
20
|
+
|
21
|
+
def populate!
|
22
|
+
return unless SiteSetting.tagging_enabled
|
23
|
+
super
|
12
24
|
end
|
13
25
|
|
14
26
|
def data
|
@@ -4,6 +4,9 @@ def check_environment!
|
|
4
4
|
if !Rails.env.development?
|
5
5
|
raise "Database commands are only supported in development environment"
|
6
6
|
end
|
7
|
+
|
8
|
+
ENV['SKIP_TEST_DATABASE'] = "1"
|
9
|
+
ENV['SKIP_MULTISITE'] = "1"
|
7
10
|
end
|
8
11
|
|
9
12
|
desc 'Run db:migrate:reset task and populate sample content for development environment'
|
@@ -17,11 +20,12 @@ end
|
|
17
20
|
|
18
21
|
desc 'Initialize development environment'
|
19
22
|
task 'dev:config' => ['db:load_config'] do |_, args|
|
20
|
-
DiscourseDev
|
23
|
+
DiscourseDev.config.update!
|
21
24
|
end
|
22
25
|
|
23
26
|
desc 'Populate sample content for development environment'
|
24
27
|
task 'dev:populate' => ['db:load_config'] do |_, args|
|
28
|
+
system("redis-cli flushall")
|
25
29
|
Rake::Task['groups:populate'].invoke
|
26
30
|
Rake::Task['users:populate'].invoke
|
27
31
|
Rake::Task['categories:populate'].invoke
|
@@ -38,6 +42,6 @@ task 'dev:repopulate' => ['db:load_config'] do |_, args|
|
|
38
42
|
if (answer == "" || answer.downcase == 'y')
|
39
43
|
Rake::Task['dev:reset'].invoke
|
40
44
|
else
|
41
|
-
puts "You can run `dev:reset`
|
45
|
+
puts "You can run `bin/rails dev:reset` to repopulate anytime."
|
42
46
|
end
|
43
47
|
end
|
data/lib/discourse_dev/topic.rb
CHANGED
@@ -6,33 +6,58 @@ require 'faker'
|
|
6
6
|
module DiscourseDev
|
7
7
|
class Topic < Record
|
8
8
|
|
9
|
-
def initialize
|
10
|
-
|
9
|
+
def initialize
|
10
|
+
@settings = DiscourseDev.config.topic
|
11
|
+
super(::Topic, @settings[:count])
|
11
12
|
end
|
12
13
|
|
13
14
|
def data
|
15
|
+
max_views = 0
|
16
|
+
|
17
|
+
case Faker::Number.between(from: 0, to: 5)
|
18
|
+
when 0
|
19
|
+
max_views = 10
|
20
|
+
when 1
|
21
|
+
max_views = 100
|
22
|
+
when 2
|
23
|
+
max_views = SiteSetting.topic_views_heat_low
|
24
|
+
when 3
|
25
|
+
max_views = SiteSetting.topic_views_heat_medium
|
26
|
+
when 4
|
27
|
+
max_views = SiteSetting.topic_views_heat_high
|
28
|
+
when 5
|
29
|
+
max_views = SiteSetting.topic_views_heat_high + SiteSetting.topic_views_heat_medium
|
30
|
+
end
|
31
|
+
|
14
32
|
{
|
15
33
|
title: title[0, SiteSetting.max_topic_title_length],
|
16
|
-
raw: Faker::
|
34
|
+
raw: Faker::DiscourseMarkdown.sandwich(sentences: 5),
|
17
35
|
category: @category.id,
|
36
|
+
created_at: Faker::Time.between(from: DiscourseDev.config.start_date, to: DateTime.now),
|
18
37
|
tags: tags,
|
19
|
-
topic_opts: {
|
38
|
+
topic_opts: {
|
39
|
+
import_mode: true,
|
40
|
+
views: Faker::Number.between(from: 1, to: max_views),
|
41
|
+
custom_fields: { dev_sample: true }
|
42
|
+
},
|
20
43
|
skip_validations: true
|
21
44
|
}
|
22
45
|
end
|
23
46
|
|
24
47
|
def title
|
25
|
-
if
|
48
|
+
if current_count < I18n.t("faker.discourse.topics").count
|
26
49
|
Faker::Discourse.unique.topic
|
27
50
|
else
|
28
|
-
Faker::Lorem.unique.sentence(word_count:
|
51
|
+
Faker::Lorem.unique.sentence(word_count: 5, supplemental: true, random_words_to_add: 4).chomp(".")
|
29
52
|
end
|
30
53
|
end
|
31
54
|
|
32
55
|
def tags
|
56
|
+
return unless SiteSetting.tagging_enabled
|
57
|
+
|
33
58
|
@tags = []
|
34
59
|
|
35
|
-
Faker::Number.between(from:
|
60
|
+
Faker::Number.between(from: @settings.dig(:tags, :min), to: @settings.dig(:tags, :max)).times do
|
36
61
|
@tags << Faker::Discourse.tag
|
37
62
|
end
|
38
63
|
|
@@ -41,18 +66,24 @@ module DiscourseDev
|
|
41
66
|
|
42
67
|
def create!
|
43
68
|
@category = Category.random
|
44
|
-
|
69
|
+
user = self.user
|
70
|
+
topic = Faker::DiscourseMarkdown.with_user(user.id) { data }
|
45
71
|
post = PostCreator.new(user, topic).create!
|
46
72
|
|
47
|
-
if
|
48
|
-
reply_count =
|
73
|
+
if override = @settings.dig(:replies, :overrides).find { |o| o[:title] == topic[:title] }
|
74
|
+
reply_count = override[:count]
|
49
75
|
else
|
50
|
-
reply_count = Faker::Number.between(from:
|
76
|
+
reply_count = Faker::Number.between(from: @settings.dig(:replies, :min), to: @settings.dig(:replies, :max))
|
51
77
|
end
|
52
78
|
|
53
79
|
Post.new(post.topic, reply_count).populate!
|
54
80
|
end
|
55
81
|
|
82
|
+
def populate!
|
83
|
+
super
|
84
|
+
delete_unwanted_sidekiq_jobs
|
85
|
+
end
|
86
|
+
|
56
87
|
def user
|
57
88
|
return User.random if @category.groups.blank?
|
58
89
|
|
@@ -67,5 +98,11 @@ module DiscourseDev
|
|
67
98
|
category_definition_topic_ids = ::Category.pluck(:topic_id)
|
68
99
|
::Topic.where(archetype: :regular).where.not(id: category_definition_topic_ids).count
|
69
100
|
end
|
101
|
+
|
102
|
+
def delete_unwanted_sidekiq_jobs
|
103
|
+
Sidekiq::ScheduledSet.new.each do |job|
|
104
|
+
job.delete if job.item["class"] == "Jobs::UserEmail"
|
105
|
+
end
|
106
|
+
end
|
70
107
|
end
|
71
108
|
end
|
data/lib/discourse_dev/user.rb
CHANGED
@@ -6,16 +6,22 @@ require 'faker'
|
|
6
6
|
|
7
7
|
module DiscourseDev
|
8
8
|
class User < Record
|
9
|
+
attr_reader :images
|
9
10
|
|
10
|
-
def initialize
|
11
|
-
super(::User, count)
|
11
|
+
def initialize
|
12
|
+
super(::User, DiscourseDev.config.user[:count])
|
13
|
+
|
14
|
+
# Using the stock avatar images from https://tinyfac.es
|
15
|
+
# Tiny Faces is a free crowd-sourced avatar gallery
|
16
|
+
@images = Dir[File.join(__dir__, '..', '..', 'avatars', '*.*')]
|
12
17
|
end
|
13
18
|
|
14
19
|
def data
|
15
20
|
name = Faker::Name.unique.name
|
16
|
-
email = Faker::Internet.unique.email(name: name)
|
17
|
-
username = Faker::Internet.unique.username(specifier:
|
18
|
-
|
21
|
+
email = Faker::Internet.unique.email(name: name, domain: "faker.invalid")
|
22
|
+
username = Faker::Internet.unique.username(specifier: ::User.username_length)
|
23
|
+
username = UserNameSuggester.suggest(username)
|
24
|
+
username_lower = ::User.normalize_username(username)
|
19
25
|
|
20
26
|
{
|
21
27
|
name: name,
|
@@ -23,16 +29,18 @@ module DiscourseDev
|
|
23
29
|
username: username,
|
24
30
|
username_lower: username_lower,
|
25
31
|
moderator: Faker::Boolean.boolean(true_ratio: 0.1),
|
26
|
-
trust_level: Faker::Number.between(from: 1, to: 4)
|
32
|
+
trust_level: Faker::Number.between(from: 1, to: 4),
|
33
|
+
created_at: Faker::Time.between(from: DiscourseDev.config.start_date, to: DateTime.now),
|
27
34
|
}
|
28
35
|
end
|
29
36
|
|
30
37
|
def create!
|
31
38
|
super do |user|
|
32
39
|
user.activate
|
40
|
+
set_random_avatar(user)
|
33
41
|
Faker::Number.between(from: 0, to: 2).times do
|
34
42
|
group = Group.random
|
35
|
-
|
43
|
+
|
36
44
|
group.add(user)
|
37
45
|
end
|
38
46
|
end
|
@@ -41,5 +49,48 @@ module DiscourseDev
|
|
41
49
|
def self.random
|
42
50
|
super(::User)
|
43
51
|
end
|
52
|
+
|
53
|
+
def set_random_avatar(user)
|
54
|
+
return if images.blank?
|
55
|
+
return unless Faker::Boolean.boolean
|
56
|
+
|
57
|
+
avatar_index = Faker::Number.between(from: 0, to: images.count - 1)
|
58
|
+
avatar_path = images[avatar_index]
|
59
|
+
create_avatar(user, avatar_path)
|
60
|
+
@images.delete_at(avatar_index)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_avatar(user, avatar_path)
|
64
|
+
tempfile = copy_to_tempfile(avatar_path)
|
65
|
+
filename = "avatar#{File.extname(avatar_path)}"
|
66
|
+
upload = UploadCreator.new(tempfile, filename, type: "avatar").create_for(user.id)
|
67
|
+
|
68
|
+
if upload.present? && upload.persisted?
|
69
|
+
user.create_user_avatar
|
70
|
+
user.user_avatar.update(custom_upload_id: upload.id)
|
71
|
+
user.update(uploaded_avatar_id: upload.id)
|
72
|
+
else
|
73
|
+
STDERR.puts "Failed to upload avatar for user #{user.username}: #{avatar_path}"
|
74
|
+
STDERR.puts upload.errors.inspect if upload
|
75
|
+
end
|
76
|
+
rescue
|
77
|
+
STDERR.puts "Failed to create avatar for user #{user.username}: #{avatar_path}"
|
78
|
+
ensure
|
79
|
+
tempfile.close! if tempfile
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def copy_to_tempfile(source_path)
|
85
|
+
extension = File.extname(source_path)
|
86
|
+
tmp = Tempfile.new(['discourse-upload', extension])
|
87
|
+
|
88
|
+
File.open(source_path) do |source_stream|
|
89
|
+
IO.copy_stream(source_stream, tmp)
|
90
|
+
end
|
91
|
+
|
92
|
+
tmp.rewind
|
93
|
+
tmp
|
94
|
+
end
|
44
95
|
end
|
45
96
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faker'
|
4
|
+
require 'net/http'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module Faker
|
8
|
+
class DiscourseMarkdown < Markdown
|
9
|
+
class << self
|
10
|
+
attr_writer(:user_id)
|
11
|
+
|
12
|
+
def user_id
|
13
|
+
@user_id || ::Discourse::SYSTEM_USER_ID
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_user(user_id)
|
17
|
+
current_user_id = self.user_id
|
18
|
+
self.user_id = user_id
|
19
|
+
begin
|
20
|
+
yield
|
21
|
+
ensure
|
22
|
+
self.user_id = current_user_id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def image
|
27
|
+
image = next_image
|
28
|
+
image_file = load_image(image)
|
29
|
+
|
30
|
+
upload = ::UploadCreator.new(
|
31
|
+
image_file,
|
32
|
+
image[:filename],
|
33
|
+
origin: image[:url]
|
34
|
+
).create_for(user_id)
|
35
|
+
|
36
|
+
::UploadMarkdown.new(upload).to_markdown if upload.present? && upload.persisted?
|
37
|
+
rescue => e
|
38
|
+
STDERR.puts e
|
39
|
+
STDERR.puts e.backtrace.join("\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def next_image
|
45
|
+
if @images.blank?
|
46
|
+
if @stop_loading_images
|
47
|
+
@images = @all_images.dup
|
48
|
+
else
|
49
|
+
@next_page = (@next_page || 0) + 1
|
50
|
+
url = URI("https://picsum.photos/v2/list?page=#{@next_page}&limit=50")
|
51
|
+
response = Net::HTTP.get(url)
|
52
|
+
json = JSON.parse(response)
|
53
|
+
|
54
|
+
if json.blank?
|
55
|
+
@stop_loading_images = true
|
56
|
+
@images = @all_images.dup
|
57
|
+
else
|
58
|
+
@images = json.sort_by { |image| image["id"] }
|
59
|
+
@all_images = (@all_images || []).concat(@images)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
image = @images.pop
|
65
|
+
{ filename: "#{image['id']}.jpg", url: "#{image['download_url']}.jpg" }
|
66
|
+
end
|
67
|
+
|
68
|
+
def image_cache_dir
|
69
|
+
@image_cache_dir ||= ::File.join(Rails.root, "tmp", "discourse_dev", "images")
|
70
|
+
end
|
71
|
+
|
72
|
+
def load_image(image)
|
73
|
+
cache_path = ::File.join(image_cache_dir, image[:filename])
|
74
|
+
|
75
|
+
if !::File.exists?(cache_path)
|
76
|
+
FileUtils.mkdir_p(image_cache_dir)
|
77
|
+
temp_file = ::FileHelper.download(
|
78
|
+
image[:url],
|
79
|
+
max_file_size: [SiteSetting.max_image_size_kb.kilobytes, 10.megabytes].max,
|
80
|
+
tmp_file_name: "image",
|
81
|
+
follow_redirect: true
|
82
|
+
)
|
83
|
+
FileUtils.cp(temp_file, cache_path)
|
84
|
+
end
|
85
|
+
|
86
|
+
::File.open(cache_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def available_methods
|
90
|
+
methods = super
|
91
|
+
methods << :image if ::DiscourseDev.config.post[:include_images]
|
92
|
+
methods
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discourse_dev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vinoth Kannan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faker
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 12.3.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-discourse
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Rake helper tasks for Discourse developers
|
56
70
|
email:
|
57
71
|
- svkn.87@gmail.com
|
@@ -61,16 +75,34 @@ extra_rdoc_files: []
|
|
61
75
|
files:
|
62
76
|
- ".github/workflows/gem-push.yml"
|
63
77
|
- ".gitignore"
|
78
|
+
- ".rubocop.yml"
|
64
79
|
- Gemfile
|
65
80
|
- LICENSE.txt
|
66
81
|
- README.md
|
67
82
|
- Rakefile
|
83
|
+
- auth/app/views/fake_discourse_connect/form.html.erb
|
84
|
+
- auth/plugin.rb
|
85
|
+
- avatars/03F55412-DE8A-4F83-AAA6-D67EE5CE48DA-200w.jpeg
|
86
|
+
- avatars/1C4EEDC2-FE9C-40B3-A2C9-A038873EE692-200w.jpeg
|
87
|
+
- avatars/26CFEFB3-21C8-49FC-8C19-8E6A62B6D2E0-200w.jpeg
|
88
|
+
- avatars/282A12CA-E0D7-4011-8BDD-1FAFAAB035F7-200w.jpeg
|
89
|
+
- avatars/2DDDE973-40EC-4004-ABC0-73FD4CD6D042-200w.jpeg
|
90
|
+
- avatars/344CFC24-61FB-426C-B3D1-CAD5BCBD3209-200w.jpeg
|
91
|
+
- avatars/852EC6E1-347C-4187-9D42-DF264CCF17BF-200w.jpeg
|
92
|
+
- avatars/A7299C8E-CEFC-47D9-939A-3C8CA0EA4D13-200w.jpeg
|
93
|
+
- avatars/AEF44435-B547-4B84-A2AE-887DFAEE6DDF-200w.jpeg
|
94
|
+
- avatars/B3CF5288-34B0-4A5E-9877-5965522529D6-200w.jpeg
|
95
|
+
- avatars/BA0CB1F2-8C79-4376-B13B-DD5FB8772537-200w.jpeg
|
96
|
+
- avatars/E0B4CAB3-F491-4322-BEF2-208B46748D4A-200w.jpeg
|
97
|
+
- avatars/FBEBF655-4886-455A-A4A4-D62B77DD419B-200w.jpeg
|
98
|
+
- config/dev.yml
|
99
|
+
- config/locales/client.en.yml
|
100
|
+
- config/locales/faker.en.yml
|
68
101
|
- config/routes.rb
|
69
102
|
- discourse_dev.gemspec
|
70
103
|
- lib/discourse_dev.rb
|
71
104
|
- lib/discourse_dev/category.rb
|
72
105
|
- lib/discourse_dev/config.rb
|
73
|
-
- lib/discourse_dev/config.yml
|
74
106
|
- lib/discourse_dev/engine.rb
|
75
107
|
- lib/discourse_dev/group.rb
|
76
108
|
- lib/discourse_dev/post.rb
|
@@ -83,7 +115,7 @@ files:
|
|
83
115
|
- lib/discourse_dev/user.rb
|
84
116
|
- lib/discourse_dev/version.rb
|
85
117
|
- lib/faker/discourse.rb
|
86
|
-
- lib/faker/
|
118
|
+
- lib/faker/discourse_markdown.rb
|
87
119
|
homepage: https://github.com/discourse/discourse_dev
|
88
120
|
licenses:
|
89
121
|
- MIT
|