mirror of
https://github.com/discourse/discourse.git
synced 2024-12-02 21:24:04 +08:00
6394d7cddf
* Optional import of custom user fields from phpBB 3.1+ * Optional import of likes from phpBB3 Requires the phpBB "Thanks for posts" extension * Fix import of bookmarks from phpBB3 * Update `created_at` of existing user * Support mapping of phpBB forums to existing Discourse categories This is in addition to the ability of merging phpBB forums and importing into newly created Discourse categories.
284 lines
8.4 KiB
Ruby
284 lines
8.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative '../base'
|
|
require_relative 'support/settings'
|
|
require_relative 'database/database'
|
|
require_relative 'importers/importer_factory'
|
|
|
|
module ImportScripts::PhpBB3
|
|
class Importer < ImportScripts::Base
|
|
# @param settings [ImportScripts::PhpBB3::Settings]
|
|
# @param database [ImportScripts::PhpBB3::Database_3_0 | ImportScripts::PhpBB3::Database_3_1]
|
|
def initialize(settings, database)
|
|
@settings = settings
|
|
super()
|
|
|
|
@database = database
|
|
@php_config = database.get_config_values
|
|
@importers = ImporterFactory.new(@database, @lookup, @uploader, @settings, @php_config)
|
|
end
|
|
|
|
def perform
|
|
super if settings_check_successful?
|
|
end
|
|
|
|
protected
|
|
|
|
def execute
|
|
puts '', "importing from phpBB #{@php_config[:phpbb_version]}"
|
|
|
|
SiteSetting.tagging_enabled = true if @settings.tag_mappings.present?
|
|
|
|
import_users
|
|
import_anonymous_users if @settings.import_anonymous_users
|
|
import_groups
|
|
import_user_groups
|
|
import_new_categories
|
|
import_categories
|
|
import_posts
|
|
import_private_messages if @settings.import_private_messages
|
|
import_bookmarks if @settings.import_bookmarks
|
|
import_likes if @settings.import_likes
|
|
end
|
|
|
|
def change_site_settings
|
|
super
|
|
|
|
@importers.permalink_importer.change_site_settings
|
|
end
|
|
|
|
def get_site_settings_for_import
|
|
settings = super
|
|
|
|
max_file_size_kb = @database.get_max_attachment_size
|
|
settings[:max_image_size_kb] = [max_file_size_kb, SiteSetting.max_image_size_kb].max
|
|
settings[:max_attachment_size_kb] = [max_file_size_kb, SiteSetting.max_attachment_size_kb].max
|
|
|
|
# temporarily disable validation since we want to import all existing images and attachments
|
|
SiteSetting.type_supervisor.load_setting(:max_image_size_kb, max: settings[:max_image_size_kb])
|
|
SiteSetting.type_supervisor.load_setting(:max_attachment_size_kb, max: settings[:max_attachment_size_kb])
|
|
|
|
settings
|
|
end
|
|
|
|
def settings_check_successful?
|
|
true
|
|
end
|
|
|
|
def import_users
|
|
puts '', 'creating users'
|
|
total_count = @database.count_users
|
|
importer = @importers.user_importer
|
|
last_user_id = 0
|
|
|
|
batches do |offset|
|
|
rows, last_user_id = @database.fetch_users(last_user_id, @settings.custom_fields)
|
|
rows = rows.to_a.uniq { |row| row[:user_id] }
|
|
break if rows.size < 1
|
|
|
|
create_users(rows, total: total_count, offset: offset) do |row|
|
|
begin
|
|
next if user_id_from_imported_user_id(@settings.prefix(row[:user_id]))
|
|
importer.map_user(row)
|
|
rescue => e
|
|
log_error("Failed to map user with ID #{row[:user_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_anonymous_users
|
|
puts '', 'creating anonymous users'
|
|
total_count = @database.count_anonymous_users
|
|
importer = @importers.user_importer
|
|
last_username = ''
|
|
|
|
batches do |offset|
|
|
rows, last_username = @database.fetch_anonymous_users(last_username)
|
|
break if rows.size < 1
|
|
|
|
create_users(rows, total: total_count, offset: offset) do |row|
|
|
begin
|
|
next if user_id_from_imported_user_id(@settings.prefix(row[:post_username]))
|
|
importer.map_anonymous_user(row)
|
|
rescue => e
|
|
log_error("Failed to map anonymous user with ID #{row[:user_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_groups
|
|
puts '', 'creating groups'
|
|
rows = @database.fetch_groups
|
|
|
|
create_groups(rows) do |row|
|
|
begin
|
|
next if row[:group_type] == 3
|
|
|
|
group_name = if @settings.site_name.present?
|
|
"#{@settings.site_name}_#{row[:group_name]}"
|
|
else
|
|
row[:group_name]
|
|
end[0..19].gsub(/[^a-zA-Z0-9\-_. ]/, '_')
|
|
|
|
bio_raw = @importers.text_processor.process_raw_text(row[:group_desc]) rescue row[:group_desc]
|
|
|
|
{
|
|
id: @settings.prefix(row[:group_id]),
|
|
name: group_name,
|
|
full_name: row[:group_name],
|
|
bio_raw: bio_raw
|
|
}
|
|
rescue => e
|
|
log_error("Failed to map group with ID #{row[:group_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_user_groups
|
|
puts '', 'creating user groups'
|
|
rows = @database.fetch_group_users
|
|
|
|
rows.each do |row|
|
|
group_id = @lookup.group_id_from_imported_group_id(@settings.prefix(row[:group_id]))
|
|
next if !group_id
|
|
|
|
user_id = @lookup.user_id_from_imported_user_id(@settings.prefix(row[:user_id]))
|
|
|
|
begin
|
|
GroupUser.find_or_create_by(user_id: user_id, group_id: group_id, owner: row[:group_leader])
|
|
rescue => e
|
|
log_error("Failed to add user #{row[:user_id]} to group #{row[:group_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_new_categories
|
|
puts '', 'creating new categories'
|
|
|
|
create_categories(@settings.new_categories) do |row|
|
|
next if row == "SKIP"
|
|
|
|
{
|
|
id: @settings.prefix(row[:forum_id]),
|
|
name: row[:name],
|
|
parent_category_id: @lookup.category_id_from_imported_category_id(@settings.prefix(row[:parent_id]))
|
|
}
|
|
end
|
|
end
|
|
|
|
def import_categories
|
|
puts '', 'creating categories'
|
|
rows = @database.fetch_categories
|
|
importer = @importers.category_importer
|
|
|
|
create_categories(rows) do |row|
|
|
next if @settings.category_mappings.dig(row[:forum_id].to_s, :skip)
|
|
|
|
importer.map_category(row)
|
|
end
|
|
end
|
|
|
|
def import_posts
|
|
puts '', 'creating topics and posts'
|
|
total_count = @database.count_posts
|
|
importer = @importers.post_importer
|
|
last_post_id = 0
|
|
|
|
batches do |offset|
|
|
rows, last_post_id = @database.fetch_posts(last_post_id)
|
|
break if rows.size < 1
|
|
|
|
create_posts(rows, total: total_count, offset: offset) do |row|
|
|
begin
|
|
next if post_id_from_imported_post_id(@settings.prefix(row[:post_id]))
|
|
importer.map_post(row)
|
|
rescue => e
|
|
log_error("Failed to map post with ID #{row[:post_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_private_messages
|
|
puts '', 'creating private messages'
|
|
total_count = @database.count_messages
|
|
importer = @importers.message_importer
|
|
last_msg_id = 0
|
|
|
|
batches do |offset|
|
|
rows, last_msg_id = @database.fetch_messages(last_msg_id)
|
|
break if rows.size < 1
|
|
|
|
create_posts(rows, total: total_count, offset: offset) do |row|
|
|
begin
|
|
next if post_id_from_imported_post_id(@settings.prefix("pm:#{row[:msg_id]}"))
|
|
importer.map_message(row)
|
|
rescue => e
|
|
log_error("Failed to map message with ID #{row[:msg_id]}", e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_bookmarks
|
|
puts '', 'creating bookmarks'
|
|
total_count = @database.count_bookmarks
|
|
importer = @importers.bookmark_importer
|
|
last_user_id = last_topic_id = 0
|
|
|
|
batches do |offset|
|
|
rows, last_user_id, last_topic_id = @database.fetch_bookmarks(last_user_id, last_topic_id)
|
|
break if rows.size < 1
|
|
|
|
create_bookmarks(rows, total: total_count, offset: offset) do |row|
|
|
begin
|
|
importer.map_bookmark(row)
|
|
rescue => e
|
|
log_error("Failed to map bookmark (#{row[:user_id]}, #{row[:topic_first_post_id]})", e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def import_likes
|
|
puts '', 'importing likes'
|
|
total_count = @database.count_likes
|
|
last_post_id = last_user_id = 0
|
|
|
|
batches do |offset|
|
|
rows, last_post_id, last_user_id = @database.fetch_likes(last_post_id, last_user_id)
|
|
break if rows.size < 1
|
|
|
|
create_likes(rows, total: total_count, offset: offset) do |row|
|
|
{
|
|
post_id: @settings.prefix(row[:post_id]),
|
|
user_id: @settings.prefix(row[:user_id]),
|
|
created_at: Time.zone.at(row[:thanks_time])
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def update_last_seen_at
|
|
# no need for this since the importer sets last_seen_at for each user during the import
|
|
end
|
|
|
|
# Do not use the bbcode_to_md in base.rb. It will be used in text_processor.rb instead.
|
|
def use_bbcode_to_md?
|
|
false
|
|
end
|
|
|
|
def batches
|
|
super(@settings.database.batch_size)
|
|
end
|
|
|
|
def log_error(message, e)
|
|
puts message
|
|
puts e.message
|
|
puts e.backtrace.join("\n")
|
|
end
|
|
end
|
|
end
|