discourse-import_scripts/gossamer_forums.rb
2024-06-17 19:33:54 +10:00

281 lines
9.3 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require 'mysql2'
require File.expand_path("../../../config/environment", __FILE__)
require_relative 'base'
class GossamerForumsImporter < ImportScripts::Base
def initialize
super
# Initialize MySQL client with connection details
@mysql_client = Mysql2::Client.new(
host: "slowtwitch.northend.network",
username: "admin",
password: "yxnh93Ybbz2Nm8#mp28zCVv",
database: "slowtwitch"
)
end
# Execute a query on the MySQL database
def execute_query(query)
@mysql_client.query(query, as: :hash)
end
# Sanitize username to comply with Discourse's rules
def sanitize_username(username, email, name)
original_username = username
# Replace unacceptable characters with underscores
sanitized = username.gsub(/[^a-zA-Z0-9._-]/, '_')
# Ensure the username is at least 3 characters long
sanitized = "#{sanitized}." if sanitized.length < 2
# Ensure the username is no more than 20 characters long
sanitized = sanitized[0, 20] if sanitized.length > 20
original_sanitized = sanitized
# Check for existing user with the same username
existing_user = User.find_by(username: sanitized)
if existing_user
# If email and name match, do not modify the username
if existing_user.email == email && existing_user.name == name
return sanitized
else
# Ensure the username is unique
counter = 1
while User.exists?(username: sanitized)
sanitized = "#{original_sanitized}_#{counter}"
sanitized = sanitized[0, 20] if sanitized.length > 20
counter += 1
end
end
end
# Print the original and sanitized usernames if they differ
if original_username != sanitized
puts "Sanitized username: '#{original_username}' --> '#{sanitized}'"
else
puts "UNsanitized username: '#{original_username}' --> '#{sanitized}'"
end
sanitized
end
# Sanitize email to replace restricted domains
def sanitize_email(email)
# mailinator.com is not allowed by
restricted_domains = ['mailinator.com', 'example.com'] # Add more restricted domains as needed
domain = email.split('@').last
if restricted_domains.include?(domain)
sanitized_email = email.gsub(domain, 'email.invalid') # Change to a permissible domain
puts "Sanitized email: '#{email}' --> '#{sanitized_email}'"
return sanitized_email
end
email
end
# Import users from gforum_User table
def import_users
puts "Importing users..."
users = []
execute_query("SELECT * FROM gforum_User").each do |row|
users << {
id: row['user_id'],
username: sanitize_username(row['user_username'], row['user_email'], row['user_real_name']),
email: row['user_email'],
created_at: Time.at(row['user_registered']),
updated_at: Time.at(row['user_last_seen']),
name: row['user_real_name'],
title: row['user_title'],
bio_raw: row['user_about'],
website: row['user_homepage'],
location: row['user_location']
}
end
# Create users in Discourse with the required block
create_users(users) do |user|
user
end
# Update user passwords and import user files
users.each do |user|
discourse_username = sanitize_username(user[:username], user[:email], user[:name])
discourse_user = User.find_by(username: discourse_username)
if discourse_user.nil?
puts "User #{user[:username]} --> #{discourse_username} not found in Discourse. Skipping password update."
next
end
if discourse_user.custom_fields.nil?
discourse_user.custom_fields = {}
end
execute_query("SELECT * FROM gforum_User WHERE user_id = #{user[:id]}").each do |row|
discourse_user.custom_fields['md5_password'] = row['user_password']
discourse_user.save_custom_fields
end
import_user_files(discourse_user)
end
end
# Import user files and append to user's bio
def import_user_files(user)
print "\rImporting files for user #{user.username}..."
execute_query("SELECT * FROM gforum_User_Files WHERE ForeignColName = 'user_id' AND ForeignColKey = #{user.id}").each do |file|
# Construct file URL
file_url = "https://forum.slowtwitch.com/images/users/images/#{file['ID'] % 10}/#{file['ID']}-#{file['File_Name']}"
# Append image link to user's bio
user.bio_raw += "\n\n![#{file['File_Name']}](#{file_url})"
user.save!
end
print "\rImporting files for user #{user.username}... Done.\n"
end
# Import categories from gforum_Category table
def import_categories
puts "Importing categories..."
execute_query("SELECT * FROM gforum_Category").each do |row|
# Use current time if created_at or updated_at is null
created_at = row['created_at'] ? Time.at(row['created_at']) : Time.now
updated_at = row['updated_at'] ? Time.at(row['updated_at']) : Time.now
create_category(
id: row['category_id'],
name: row['name'],
description: row['description'],
created_at: created_at,
updated_at: updated_at
)
end
end
# Import topics and posts from gforum_Post table
def import_topics_and_posts
puts "Importing topics and posts..."
execute_query("SELECT * FROM gforum_Post ORDER BY post_root_id, post_time").each do |row|
if row['post_id'] == row['post_root_id']
# This is the root post, create a new topic
topic = create_topic(
id: row['post_id'],
title: row['post_subject'],
user_id: row['user_id_fk'],
created_at: Time.at(row['post_time']),
updated_at: Time.at(row['post_latest_reply']),
category_id: row['forum_id_fk']
)
# Create the first post in the topic
create_post(
id: row['post_id'],
topic_id: row['post_id'],
user_id: row['user_id_fk'],
raw: import_post_attachments(row['post_message'], row['post_id']),
created_at: Time.at(row['post_time']),
updated_at: Time.at(row['post_latest_reply'])
)
else
# This is a reply post, add to the existing topic
create_post(
id: row['post_id'],
topic_id: row['post_root_id'],
user_id: row['user_id_fk'],
raw: import_post_attachments(row['post_message'], row['post_id']),
created_at: Time.at(row['post_time']),
updated_at: Time.at(row['post_latest_reply']),
reply_to_post_number: row['post_father_id']
)
end
end
end
# Import post attachments from gforum_PostAttachment table
def import_post_attachments(post_message, post_id)
# Query for attachments related to the post
attachments = execute_query("SELECT * FROM gforum_PostAttachment WHERE post_id_fk = #{post_id}")
attachments.each do |attachment|
# Append attachment link to the post message
post_message += "\n\n![#{attachment['postatt_filename']}](https://forum.slowtwitch.com/forum/?do=post_attachment;postatt_id=#{attachment['postatt_filename']})"
end
post_message
end
# Import personal messages (both inbox and sent messages)
def import_personal_messages
puts "Importing personal messages..."
import_inbox_messages
import_sent_messages
end
# Import inbox messages from gforum_Message table
def import_inbox_messages
puts "Importing inbox messages..."
execute_query("SELECT * FROM gforum_Message").each do |row|
# Create a private message topic in Discourse
topic = create_topic(
title: row['msg_subject'],
user_id: row['from_user_id_fk'],
archetype: Archetype.private_message,
created_at: Time.at(row['msg_time']),
updated_at: Time.at(row['msg_time'])
)
# Create the message as a post in the private topic
create_post(
topic_id: topic.id,
user_id: row['from_user_id_fk'],
raw: row['msg_body'],
created_at: Time.at(row['msg_time']),
updated_at: Time.at(row['msg_time'])
)
# Add recipient user to the private message topic
topic.add_user_by_id(row['to_user_id_fk'])
topic.save!
end
end
# Import sent messages from gforum_SentMessage table
def import_sent_messages
puts "Importing sent messages..."
execute_query("SELECT * FROM gforum_SentMessage").each do |row|
# Create a private message topic in Discourse
topic = create_topic(
title: row['msg_subject'],
user_id: row['from_user_id_fk'],
archetype: Archetype.private_message,
created_at: Time.at(row['msg_time']),
updated_at: Time.at(row['msg_time'])
)
# Create the message as a post in the private topic
create_post(
topic_id: topic.id,
user_id: row['from_user_id_fk'],
raw: row['msg_body'],
created_at: Time.at(row['msg_time']),
updated_at: Time.at(row['msg_time'])
)
# Add recipient user to the private message topic
topic.add_user_by_id(row['to_user_id_fk'])
topic.save!
end
end
# Perform the full import process
def perform_import
import_users
import_categories
import_topics_and_posts
import_personal_messages
end
end
# Create an instance of the importer and start the import process
importer = GossamerForumsImporter.new
importer.perform_import