mirror of
https://github.com/discourse/discourse.git
synced 2024-11-24 18:29:54 +08:00
30990006a9
This reduces chances of errors where consumers of strings mutate inputs and reduces memory usage of the app. Test suite passes now, but there may be some stuff left, so we will run a few sites on a branch prior to merging
213 lines
5.8 KiB
Ruby
213 lines
5.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "mysql2"
|
|
require File.expand_path(File.dirname(__FILE__) + "/base.rb")
|
|
|
|
class ImportScripts::Drupal < ImportScripts::Base
|
|
|
|
DRUPAL_DB = ENV['DRUPAL_DB'] || "newsite3"
|
|
VID = ENV['DRUPAL_VID'] || 1
|
|
|
|
def initialize
|
|
super
|
|
|
|
@client = Mysql2::Client.new(
|
|
host: "localhost",
|
|
username: "root",
|
|
#password: "password",
|
|
database: DRUPAL_DB
|
|
)
|
|
end
|
|
|
|
def categories_query
|
|
@client.query("SELECT tid, name, description FROM term_data WHERE vid = #{VID}")
|
|
end
|
|
|
|
def execute
|
|
create_users(@client.query("SELECT uid id, name, mail email, created FROM users;")) do |row|
|
|
{ id: row['id'], username: row['name'], email: row['email'], created_at: Time.zone.at(row['created']) }
|
|
end
|
|
|
|
# You'll need to edit the following query for your Drupal install:
|
|
#
|
|
# * Drupal allows duplicate category names, so you may need to exclude some categories or rename them here.
|
|
# * Table name may be term_data.
|
|
# * May need to select a vid other than 1.
|
|
create_categories(categories_query) do |c|
|
|
{ id: c['tid'], name: c['name'], description: c['description'] }
|
|
end
|
|
|
|
# "Nodes" in Drupal are divided into types. Here we import two types,
|
|
# and will later import all the comments/replies for each node.
|
|
# You will need to figure out what the type names are on your install and edit the queries to match.
|
|
if ENV['DRUPAL_IMPORT_BLOG']
|
|
create_blog_topics
|
|
end
|
|
|
|
create_forum_topics
|
|
|
|
create_replies
|
|
|
|
begin
|
|
create_admin(email: 'neil.lalonde@discourse.org', username: UserNameSuggester.suggest('neil'))
|
|
rescue => e
|
|
puts '', "Failed to create admin user"
|
|
puts e.message
|
|
end
|
|
end
|
|
|
|
def create_blog_topics
|
|
puts '', "creating blog topics"
|
|
|
|
create_category({
|
|
name: 'Blog',
|
|
user_id: -1,
|
|
description: "Articles from the blog"
|
|
}, nil) unless Category.find_by_name('Blog')
|
|
|
|
results = @client.query("
|
|
SELECT n.nid nid,
|
|
n.title title,
|
|
n.uid uid,
|
|
n.created created,
|
|
n.sticky sticky,
|
|
nr.body body
|
|
FROM node n
|
|
LEFT JOIN node_revisions nr ON nr.vid=n.vid
|
|
WHERE n.type = 'blog'
|
|
AND n.status = 1
|
|
", cache_rows: false)
|
|
|
|
create_posts(results) do |row|
|
|
{
|
|
id: "nid:#{row['nid']}",
|
|
user_id: user_id_from_imported_user_id(row['uid']) || -1,
|
|
category: 'Blog',
|
|
raw: row['body'],
|
|
created_at: Time.zone.at(row['created']),
|
|
pinned_at: row['sticky'].to_i == 1 ? Time.zone.at(row['created']) : nil,
|
|
title: row['title'].try(:strip),
|
|
custom_fields: { import_id: "nid:#{row['nid']}" }
|
|
}
|
|
end
|
|
end
|
|
|
|
def create_forum_topics
|
|
puts '', "creating forum topics"
|
|
|
|
total_count = @client.query("
|
|
SELECT COUNT(*) count
|
|
FROM node n
|
|
LEFT JOIN forum f ON f.vid=n.vid
|
|
WHERE n.type = 'forum'
|
|
AND n.status = 1
|
|
").first['count']
|
|
|
|
batch_size = 1000
|
|
|
|
batches(batch_size) do |offset|
|
|
results = @client.query("
|
|
SELECT n.nid nid,
|
|
n.title title,
|
|
f.tid tid,
|
|
n.uid uid,
|
|
n.created created,
|
|
n.sticky sticky,
|
|
nr.body body
|
|
FROM node n
|
|
LEFT JOIN forum f ON f.vid=n.vid
|
|
LEFT JOIN node_revisions nr ON nr.vid=n.vid
|
|
WHERE n.type = 'forum'
|
|
AND n.status = 1
|
|
LIMIT #{batch_size}
|
|
OFFSET #{offset};
|
|
", cache_rows: false)
|
|
|
|
break if results.size < 1
|
|
|
|
next if all_records_exist? :posts, results.map { |p| "nid:#{p['nid']}" }
|
|
|
|
create_posts(results, total: total_count, offset: offset) do |row|
|
|
{
|
|
id: "nid:#{row['nid']}",
|
|
user_id: user_id_from_imported_user_id(row['uid']) || -1,
|
|
category: category_id_from_imported_category_id(row['tid']),
|
|
raw: row['body'],
|
|
created_at: Time.zone.at(row['created']),
|
|
pinned_at: row['sticky'].to_i == 1 ? Time.zone.at(row['created']) : nil,
|
|
title: row['title'].try(:strip)
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_replies
|
|
puts '', "creating replies in topics"
|
|
|
|
if ENV['DRUPAL_IMPORT_BLOG']
|
|
node_types = "('forum','blog')"
|
|
else
|
|
node_types = "('forum')"
|
|
end
|
|
|
|
total_count = @client.query("
|
|
SELECT COUNT(*) count
|
|
FROM comments c
|
|
LEFT JOIN node n ON n.nid=c.nid
|
|
WHERE n.type IN #{node_types}
|
|
AND n.status = 1
|
|
AND c.status=0;
|
|
").first['count']
|
|
|
|
batch_size = 1000
|
|
|
|
batches(batch_size) do |offset|
|
|
results = @client.query("
|
|
SELECT c.cid,
|
|
c.pid,
|
|
c.nid,
|
|
c.uid,
|
|
c.timestamp,
|
|
c.comment body
|
|
FROM comments c
|
|
LEFT JOIN node n ON n.nid=c.nid
|
|
WHERE n.type IN #{node_types}
|
|
AND n.status = 1
|
|
AND c.status=0
|
|
LIMIT #{batch_size}
|
|
OFFSET #{offset};
|
|
", cache_rows: false)
|
|
|
|
break if results.size < 1
|
|
|
|
next if all_records_exist? :posts, results.map { |p| "cid:#{p['cid']}" }
|
|
|
|
create_posts(results, total: total_count, offset: offset) do |row|
|
|
topic_mapping = topic_lookup_from_imported_post_id("nid:#{row['nid']}")
|
|
if topic_mapping && topic_id = topic_mapping[:topic_id]
|
|
h = {
|
|
id: "cid:#{row['cid']}",
|
|
topic_id: topic_id,
|
|
user_id: user_id_from_imported_user_id(row['uid']) || -1,
|
|
raw: row['body'],
|
|
created_at: Time.zone.at(row['timestamp']),
|
|
}
|
|
if row['pid']
|
|
parent = topic_lookup_from_imported_post_id("cid:#{row['pid']}")
|
|
h[:reply_to_post_number] = parent[:post_number] if parent && parent[:post_number] > (1)
|
|
end
|
|
h
|
|
else
|
|
puts "No topic found for comment #{row['cid']}"
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
if __FILE__ == $0
|
|
ImportScripts::Drupal.new.perform
|
|
end
|