mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
FEATURE: smf2 import script
This commit is contained in:
parent
71c67c43a1
commit
7b5e6ff744
2 changed files with 611 additions and 0 deletions
|
@ -19,12 +19,18 @@ class ImportScripts::Base
|
|||
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
|
||||
|
||||
@bbcode_to_md = true if ARGV.include?('bbcode-to-md')
|
||||
@existing_groups = {}
|
||||
@failed_groups = []
|
||||
@existing_users = {}
|
||||
@failed_users = []
|
||||
@categories = {}
|
||||
@posts = {}
|
||||
@topic_lookup = {}
|
||||
|
||||
GroupCustomField.where(name: 'import_id').pluck(:group_id, :value).each do |group_id, import_id|
|
||||
@existing_groups[import_id] = group_id
|
||||
end
|
||||
|
||||
UserCustomField.where(name: 'import_id').pluck(:user_id, :value).each do |user_id, import_id|
|
||||
@existing_users[import_id] = user_id
|
||||
end
|
||||
|
@ -84,6 +90,15 @@ class ImportScripts::Base
|
|||
post_id ? @topic_lookup[post_id] : nil
|
||||
end
|
||||
|
||||
# Get the Discourse Group id based on the id of the source group
|
||||
def group_id_from_imported_group_id(import_id)
|
||||
@existing_groups[import_id] || @existing_groups[import_id.to_s] || find_group_by_import_id(import_id).try(:id)
|
||||
end
|
||||
|
||||
def find_group_by_import_id(import_id)
|
||||
GroupCustomField.where(name: 'import_id', value: import_id.to_s).first.try(:group)
|
||||
end
|
||||
|
||||
# Get the Discourse User id based on the id of the source user
|
||||
def user_id_from_imported_user_id(import_id)
|
||||
@existing_users[import_id] || @existing_users[import_id.to_s] || find_user_by_import_id(import_id).try(:id)
|
||||
|
@ -110,6 +125,54 @@ class ImportScripts::Base
|
|||
admin
|
||||
end
|
||||
|
||||
# Iterate through a list of groups to be imported.
|
||||
# Takes a collection and yields to the block for each element.
|
||||
# Block should return a hash with the attributes for each element.
|
||||
# Required fields are :id and :name, where :id is the id of the
|
||||
# group in the original datasource. The given id will not be used
|
||||
# to create the Discourse group record.
|
||||
def create_groups(results, opts={})
|
||||
groups_created = 0
|
||||
groups_skipped = 0
|
||||
total = opts[:total] || results.size
|
||||
|
||||
results.each do |result|
|
||||
g = yield(result)
|
||||
|
||||
if group_id_from_imported_group_id(g[:id])
|
||||
groups_skipped += 1
|
||||
else
|
||||
new_group = create_group(g, g[:id])
|
||||
|
||||
if new_group.valid?
|
||||
@existing_groups[g[:id].to_s] = new_group.id
|
||||
groups_created += 1
|
||||
else
|
||||
@failed_groups << g
|
||||
puts "Failed to create group id #{g[:id]} #{new_group.name}: #{new_group.errors.full_messages}"
|
||||
end
|
||||
end
|
||||
|
||||
print_status groups_created + groups_skipped + @failed_groups.length + (opts[:offset] || 0), total
|
||||
end
|
||||
|
||||
return [groups_created, groups_skipped]
|
||||
end
|
||||
|
||||
def create_group(opts, import_id)
|
||||
opts = opts.dup.tap {|o| o.delete(:id) }
|
||||
import_name = opts[:name]
|
||||
opts[:name] = UserNameSuggester.suggest(import_name)
|
||||
|
||||
existing = Group.where(name: opts[:name]).first
|
||||
return existing if existing and existing.custom_fields["import_id"].to_i == import_id.to_i
|
||||
g = existing || Group.new(opts)
|
||||
g.custom_fields["import_id"] = import_id
|
||||
g.custom_fields["import_name"] = import_name
|
||||
|
||||
g.tap(&:save)
|
||||
end
|
||||
|
||||
# Iterate through a list of user records to be imported.
|
||||
# Takes a collection, and yields to the block for each element.
|
||||
# Block should return a hash with the attributes for the User model.
|
||||
|
@ -151,6 +214,7 @@ class ImportScripts::Base
|
|||
|
||||
def create_user(opts, import_id)
|
||||
opts.delete(:id)
|
||||
post_create_action = opts.delete(:post_create_action)
|
||||
existing = User.where(email: opts[:email].downcase, username: opts[:username]).first
|
||||
return existing if existing and existing.custom_fields["import_id"].to_i == import_id.to_i
|
||||
|
||||
|
@ -181,6 +245,7 @@ class ImportScripts::Base
|
|||
u = existing
|
||||
end
|
||||
end
|
||||
post_create_action.try(:call, u) if u.persisted?
|
||||
|
||||
u # If there was an error creating the user, u.errors has the messages
|
||||
end
|
||||
|
@ -214,6 +279,7 @@ class ImportScripts::Base
|
|||
existing = category_from_imported_category_id(import_id)
|
||||
return existing if existing
|
||||
|
||||
post_create_action = opts.delete(:post_create_action)
|
||||
new_category = Category.new(
|
||||
name: opts[:name],
|
||||
user_id: -1,
|
||||
|
@ -223,6 +289,7 @@ class ImportScripts::Base
|
|||
)
|
||||
new_category.custom_fields["import_id"] = import_id if import_id
|
||||
new_category.save!
|
||||
post_create_action.try(:call, new_category)
|
||||
new_category
|
||||
end
|
||||
|
||||
|
@ -279,6 +346,7 @@ class ImportScripts::Base
|
|||
|
||||
def create_post(opts, import_id)
|
||||
user = User.find(opts[:user_id])
|
||||
post_create_action = opts.delete(:post_create_action)
|
||||
opts = opts.merge(skip_validations: true)
|
||||
opts[:import_mode] = true
|
||||
opts[:custom_fields] ||= {}
|
||||
|
@ -290,9 +358,25 @@ class ImportScripts::Base
|
|||
|
||||
post_creator = PostCreator.new(user, opts)
|
||||
post = post_creator.create
|
||||
post_create_action.try(:call, post) if post
|
||||
post ? post : post_creator.errors.full_messages
|
||||
end
|
||||
|
||||
# Creates an upload.
|
||||
# Expects path to be the full path and filename of the source file.
|
||||
def create_upload(user_id, path, source_filename)
|
||||
tmp = Tempfile.new('discourse-upload')
|
||||
src = File.open(path)
|
||||
FileUtils.copy_stream(src, tmp)
|
||||
src.close
|
||||
tmp.rewind
|
||||
|
||||
Upload.create_for(user_id, tmp, source_filename, File.size(tmp))
|
||||
ensure
|
||||
tmp.close rescue nil
|
||||
tmp.unlink rescue nil
|
||||
end
|
||||
|
||||
def close_inactive_topics(opts={})
|
||||
num_days = opts[:days] || 30
|
||||
puts '', "Closing topics that have been inactive for more than #{num_days} days."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue