mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 13:06:56 +08:00
DEV: speed up posts base imports
This commit is contained in:
@ -174,15 +174,14 @@ class PostCreator
|
|||||||
update_user_counts
|
update_user_counts
|
||||||
create_embedded_topic
|
create_embedded_topic
|
||||||
link_post_uploads
|
link_post_uploads
|
||||||
|
|
||||||
ensure_in_allowed_users if guardian.is_staff?
|
ensure_in_allowed_users if guardian.is_staff?
|
||||||
unarchive_message
|
unarchive_message
|
||||||
@post.advance_draft_sequence
|
@post.advance_draft_sequence unless @opts[:import_mode]
|
||||||
@post.save_reply_relationships
|
@post.save_reply_relationships
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if @post && errors.blank?
|
if @post && errors.blank? && !@opts[:import_mode]
|
||||||
# update counters etc.
|
# update counters etc.
|
||||||
@post.topic.reload
|
@post.topic.reload
|
||||||
|
|
||||||
@ -194,12 +193,10 @@ class PostCreator
|
|||||||
|
|
||||||
trigger_after_events unless opts[:skip_events]
|
trigger_after_events unless opts[:skip_events]
|
||||||
|
|
||||||
auto_close unless @opts[:import_mode]
|
auto_close
|
||||||
end
|
end
|
||||||
|
|
||||||
if @post || @spam
|
handle_spam if !opts[:import_mode] && (@post || @spam)
|
||||||
handle_spam unless @opts[:import_mode]
|
|
||||||
end
|
|
||||||
|
|
||||||
@post
|
@post
|
||||||
end
|
end
|
||||||
@ -428,6 +425,8 @@ class PostCreator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_topic_auto_close
|
def update_topic_auto_close
|
||||||
|
return if @opts[:import_mode]
|
||||||
|
|
||||||
if @topic.closed?
|
if @topic.closed?
|
||||||
@topic.delete_topic_timer(TopicTimer.types[:close])
|
@topic.delete_topic_timer(TopicTimer.types[:close])
|
||||||
else
|
else
|
||||||
@ -510,9 +509,7 @@ class PostCreator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def publish
|
def publish
|
||||||
return if @opts[:import_mode]
|
return if @opts[:import_mode] || @post.post_number == 1
|
||||||
return unless @post.post_number > 1
|
|
||||||
|
|
||||||
@post.publish_change_to_clients! :created
|
@post.publish_change_to_clients! :created
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -522,7 +519,7 @@ class PostCreator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def track_topic
|
def track_topic
|
||||||
return if @opts[:auto_track] == false
|
return if @opts[:import_mode] || @opts[:auto_track] == false
|
||||||
|
|
||||||
unless @user.user_option.disable_jump_reply?
|
unless @user.user_option.disable_jump_reply?
|
||||||
TopicUser.change(@post.user_id,
|
TopicUser.change(@post.user_id,
|
||||||
@ -540,8 +537,7 @@ class PostCreator
|
|||||||
|
|
||||||
if @user.staged
|
if @user.staged
|
||||||
TopicUser.auto_notification_for_staging(@user.id, @topic.id, TopicUser.notification_reasons[:auto_watch])
|
TopicUser.auto_notification_for_staging(@user.id, @topic.id, TopicUser.notification_reasons[:auto_watch])
|
||||||
else
|
elsif !@topic.private_message?
|
||||||
return if @topic.private_message?
|
|
||||||
notification_level = @user.user_option.notification_level_when_replying || NotificationLevels.topic_levels[:tracking]
|
notification_level = @user.user_option.notification_level_when_replying || NotificationLevels.topic_levels[:tracking]
|
||||||
TopicUser.auto_notification(@user.id, @topic.id, TopicUser.notification_reasons[:created_post], notification_level)
|
TopicUser.auto_notification(@user.id, @topic.id, TopicUser.notification_reasons[:created_post], notification_level)
|
||||||
end
|
end
|
||||||
|
@ -80,8 +80,8 @@ class UploadCreator
|
|||||||
end
|
end
|
||||||
|
|
||||||
fixed_original_filename = nil
|
fixed_original_filename = nil
|
||||||
if is_image
|
|
||||||
|
|
||||||
|
if is_image
|
||||||
current_extension = File.extname(@filename).downcase.sub("jpeg", "jpg")
|
current_extension = File.extname(@filename).downcase.sub("jpeg", "jpg")
|
||||||
expected_extension = ".#{image_type}".downcase.sub("jpeg", "jpg")
|
expected_extension = ".#{image_type}".downcase.sub("jpeg", "jpg")
|
||||||
|
|
||||||
@ -89,11 +89,7 @@ class UploadCreator
|
|||||||
# otherwise validation will fail and we can not save
|
# otherwise validation will fail and we can not save
|
||||||
# TODO decide if we only run the validation on the extension
|
# TODO decide if we only run the validation on the extension
|
||||||
if current_extension != expected_extension
|
if current_extension != expected_extension
|
||||||
basename = File.basename(@filename, current_extension)
|
basename = File.basename(@filename, current_extension).presence || "image"
|
||||||
|
|
||||||
if basename.length == 0
|
|
||||||
basename = "image"
|
|
||||||
end
|
|
||||||
fixed_original_filename = "#{basename}#{expected_extension}"
|
fixed_original_filename = "#{basename}#{expected_extension}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -173,10 +169,7 @@ class UploadCreator
|
|||||||
MIN_CONVERT_TO_JPEG_SAVING_RATIO = 0.70
|
MIN_CONVERT_TO_JPEG_SAVING_RATIO = 0.70
|
||||||
|
|
||||||
def convert_to_jpeg!
|
def convert_to_jpeg!
|
||||||
|
return if filesize < MIN_CONVERT_TO_JPEG_BYTES_SAVED
|
||||||
if filesize < MIN_CONVERT_TO_JPEG_BYTES_SAVED
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
jpeg_tempfile = Tempfile.new(["image", ".jpg"])
|
jpeg_tempfile = Tempfile.new(["image", ".jpg"])
|
||||||
|
|
||||||
@ -290,7 +283,6 @@ class UploadCreator
|
|||||||
|
|
||||||
def crop!
|
def crop!
|
||||||
max_pixel_ratio = Discourse::PIXEL_RATIOS.max
|
max_pixel_ratio = Discourse::PIXEL_RATIOS.max
|
||||||
|
|
||||||
filename_with_correct_ext = "image.#{@image_info.type}"
|
filename_with_correct_ext = "image.#{@image_info.type}"
|
||||||
|
|
||||||
case @opts[:type]
|
case @opts[:type]
|
||||||
|
@ -54,6 +54,8 @@ class ImportScripts::Base
|
|||||||
update_last_posted_at
|
update_last_posted_at
|
||||||
update_last_seen_at
|
update_last_seen_at
|
||||||
update_user_stats
|
update_user_stats
|
||||||
|
update_topic_users
|
||||||
|
update_post_timings
|
||||||
update_feature_topic_users
|
update_feature_topic_users
|
||||||
update_category_featured_topics
|
update_category_featured_topics
|
||||||
update_topic_count_replies
|
update_topic_count_replies
|
||||||
@ -313,7 +315,7 @@ class ImportScripts::Base
|
|||||||
|
|
||||||
unless opts[:email][EmailValidator.email_regex]
|
unless opts[:email][EmailValidator.email_regex]
|
||||||
opts[:email] = fake_email
|
opts[:email] = fake_email
|
||||||
puts "Invalid email #{original_email} for #{opts[:username]}. Using: #{opts[:email]}"
|
puts "Invalid email '#{original_email}' for '#{opts[:username]}'. Using '#{opts[:email]}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
opts[:name] = original_username if original_name.blank? && opts[:username] != original_username
|
opts[:name] = original_username if original_name.blank? && opts[:username] != original_username
|
||||||
@ -326,7 +328,7 @@ class ImportScripts::Base
|
|||||||
u = User.new(opts)
|
u = User.new(opts)
|
||||||
(opts[:custom_fields] || {}).each { |k, v| u.custom_fields[k] = v }
|
(opts[:custom_fields] || {}).each { |k, v| u.custom_fields[k] = v }
|
||||||
u.custom_fields["import_id"] = import_id
|
u.custom_fields["import_id"] = import_id
|
||||||
u.custom_fields["import_username"] = opts[:username] if original_username.present?
|
u.custom_fields["import_username"] = original_username if original_username.present? && original_username != opts[:username]
|
||||||
u.custom_fields["import_avatar_url"] = avatar_url if avatar_url.present?
|
u.custom_fields["import_avatar_url"] = avatar_url if avatar_url.present?
|
||||||
u.custom_fields["import_pass"] = opts[:password] if opts[:password].present?
|
u.custom_fields["import_pass"] = opts[:password] if opts[:password].present?
|
||||||
u.custom_fields["import_email"] = original_email if original_email != opts[:email]
|
u.custom_fields["import_email"] = original_email if original_email != opts[:email]
|
||||||
@ -506,21 +508,19 @@ class ImportScripts::Base
|
|||||||
import_id = params.delete(:id).to_s
|
import_id = params.delete(:id).to_s
|
||||||
|
|
||||||
if post_id_from_imported_post_id(import_id)
|
if post_id_from_imported_post_id(import_id)
|
||||||
skipped += 1 # already imported this post
|
skipped += 1
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
new_post = create_post(params, import_id)
|
new_post = create_post(params, import_id)
|
||||||
if new_post.is_a?(Post)
|
if new_post.is_a?(Post)
|
||||||
add_post(import_id, new_post)
|
add_post(import_id, new_post)
|
||||||
add_topic(new_post)
|
add_topic(new_post)
|
||||||
|
|
||||||
created_post(new_post)
|
created_post(new_post)
|
||||||
|
|
||||||
created += 1
|
created += 1
|
||||||
else
|
else
|
||||||
skipped += 1
|
skipped += 1
|
||||||
puts "Error creating post #{import_id}. Skipping."
|
puts "Error creating post #{import_id}. Skipping."
|
||||||
puts new_post.inspect
|
p new_post
|
||||||
end
|
end
|
||||||
rescue Discourse::InvalidAccess => e
|
rescue Discourse::InvalidAccess => e
|
||||||
skipped += 1
|
skipped += 1
|
||||||
@ -632,7 +632,7 @@ class ImportScripts::Base
|
|||||||
def update_topic_status
|
def update_topic_status
|
||||||
puts "", "Updating topic status"
|
puts "", "Updating topic status"
|
||||||
|
|
||||||
DB.exec(<<~SQL)
|
DB.exec <<~SQL
|
||||||
UPDATE topics AS t
|
UPDATE topics AS t
|
||||||
SET closed = TRUE
|
SET closed = TRUE
|
||||||
WHERE EXISTS(
|
WHERE EXISTS(
|
||||||
@ -642,7 +642,7 @@ class ImportScripts::Base
|
|||||||
)
|
)
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(<<~SQL)
|
DB.exec <<~SQL
|
||||||
UPDATE topics AS t
|
UPDATE topics AS t
|
||||||
SET archived = TRUE
|
SET archived = TRUE
|
||||||
WHERE EXISTS(
|
WHERE EXISTS(
|
||||||
@ -652,7 +652,7 @@ class ImportScripts::Base
|
|||||||
)
|
)
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(<<~SQL)
|
DB.exec <<~SQL
|
||||||
DELETE FROM topic_custom_fields
|
DELETE FROM topic_custom_fields
|
||||||
WHERE name IN ('import_closed', 'import_archived')
|
WHERE name IN ('import_closed', 'import_archived')
|
||||||
SQL
|
SQL
|
||||||
@ -660,13 +660,16 @@ class ImportScripts::Base
|
|||||||
|
|
||||||
def update_bumped_at
|
def update_bumped_at
|
||||||
puts "", "Updating bumped_at on topics"
|
puts "", "Updating bumped_at on topics"
|
||||||
DB.exec("update topics t set bumped_at = COALESCE((select max(created_at) from posts where topic_id = t.id and post_type = #{Post.types[:regular]}), bumped_at)")
|
DB.exec <<~SQL
|
||||||
|
UPDATE topics t
|
||||||
|
SET bumped_at = COALESCE((SELECT MAX(created_at) FROM posts WHERE topic_id = t.id AND post_type = #{Post.types[:regular]}), bumped_at)
|
||||||
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_last_posted_at
|
def update_last_posted_at
|
||||||
puts "", "Updating last posted at on users"
|
puts "", "Updating last posted at on users"
|
||||||
|
|
||||||
sql = <<-SQL
|
DB.exec <<~SQL
|
||||||
WITH lpa AS (
|
WITH lpa AS (
|
||||||
SELECT user_id, MAX(posts.created_at) AS last_posted_at
|
SELECT user_id, MAX(posts.created_at) AS last_posted_at
|
||||||
FROM posts
|
FROM posts
|
||||||
@ -679,8 +682,6 @@ class ImportScripts::Base
|
|||||||
WHERE u1.id = users.id
|
WHERE u1.id = users.id
|
||||||
AND users.last_posted_at <> lpa.last_posted_at
|
AND users.last_posted_at <> lpa.last_posted_at
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(sql)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_user_stats
|
def update_user_stats
|
||||||
@ -699,7 +700,7 @@ class ImportScripts::Base
|
|||||||
|
|
||||||
puts "", "Updating first_post_created_at..."
|
puts "", "Updating first_post_created_at..."
|
||||||
|
|
||||||
sql = <<-SQL
|
DB.exec <<~SQL
|
||||||
WITH sub AS (
|
WITH sub AS (
|
||||||
SELECT user_id, MIN(posts.created_at) AS first_post_created_at
|
SELECT user_id, MIN(posts.created_at) AS first_post_created_at
|
||||||
FROM posts
|
FROM posts
|
||||||
@ -713,11 +714,9 @@ class ImportScripts::Base
|
|||||||
AND user_stats.first_post_created_at <> sub.first_post_created_at
|
AND user_stats.first_post_created_at <> sub.first_post_created_at
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(sql)
|
|
||||||
|
|
||||||
puts "", "Updating user post_count..."
|
puts "", "Updating user post_count..."
|
||||||
|
|
||||||
sql = <<-SQL
|
DB.exec <<~SQL
|
||||||
WITH sub AS (
|
WITH sub AS (
|
||||||
SELECT user_id, COUNT(*) AS post_count
|
SELECT user_id, COUNT(*) AS post_count
|
||||||
FROM posts
|
FROM posts
|
||||||
@ -731,11 +730,9 @@ class ImportScripts::Base
|
|||||||
AND user_stats.post_count <> sub.post_count
|
AND user_stats.post_count <> sub.post_count
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(sql)
|
|
||||||
|
|
||||||
puts "", "Updating user topic_count..."
|
puts "", "Updating user topic_count..."
|
||||||
|
|
||||||
sql = <<-SQL
|
DB.exec <<~SQL
|
||||||
WITH sub AS (
|
WITH sub AS (
|
||||||
SELECT user_id, COUNT(*) AS topic_count
|
SELECT user_id, COUNT(*) AS topic_count
|
||||||
FROM topics
|
FROM topics
|
||||||
@ -748,8 +745,6 @@ class ImportScripts::Base
|
|||||||
WHERE u1.user_id = user_stats.user_id
|
WHERE u1.user_id = user_stats.user_id
|
||||||
AND user_stats.topic_count <> sub.topic_count
|
AND user_stats.topic_count <> sub.topic_count
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
DB.exec(sql)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# scripts that are able to import last_seen_at from the source data should override this method
|
# scripts that are able to import last_seen_at from the source data should override this method
|
||||||
@ -760,6 +755,31 @@ class ImportScripts::Base
|
|||||||
DB.exec("UPDATE users SET last_seen_at = last_posted_at WHERE last_posted_at IS NOT NULL")
|
DB.exec("UPDATE users SET last_seen_at = last_posted_at WHERE last_posted_at IS NOT NULL")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_topic_users
|
||||||
|
puts "", "Updating topic users"
|
||||||
|
|
||||||
|
DB.exec <<~SQL
|
||||||
|
INSERT INTO topic_users (user_id, topic_id, posted, last_read_post_number, highest_seen_post_number, first_visited_at, last_visited_at, total_msecs_viewed)
|
||||||
|
SELECT user_id, topic_id, 't' , MAX(post_number), MAX(post_number), MIN(created_at), MAX(created_at), COUNT(id) * 5000
|
||||||
|
FROM posts
|
||||||
|
WHERE user_id > 0
|
||||||
|
GROUP BY user_id, topic_id
|
||||||
|
ON CONFLICT DO NOTHING
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_post_timings
|
||||||
|
puts "", "Updating post timings"
|
||||||
|
|
||||||
|
DB.exec <<~SQL
|
||||||
|
INSERT INTO post_timings (topic_id, post_number, user_id, msecs)
|
||||||
|
SELECT topic_id, post_number, user_id, 5000
|
||||||
|
FROM posts
|
||||||
|
WHERE user_id > 0
|
||||||
|
ON CONFLICT DO NOTHING
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
def update_feature_topic_users
|
def update_feature_topic_users
|
||||||
puts "", "Updating featured topic users"
|
puts "", "Updating featured topic users"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user