require 'mysql2' require File.expand_path("../../../config/environment", __FILE__) require_relative 'base' class GossamerForumsImporter < ImportScripts::Base def initialize super @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 usernames from non-alphanumeric chars def sanitize_username(username) username.gsub(/[^a-zA-Z0-9.\-]/, '_') end # Import users from gforum_User table def import_users puts "Importing users..." users = [] execute_query("SELECT * FROM gforum_User").each do |row| # Map Gossamer Forum user data to Discourse user data users << { id: row['user_id'], username: row['user_username'], 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| # DSDS # Replace spaces with underscores in the username # DSDS discourse_username = user[:username].gsub(' ', '_') discourse_username = sanitize_username(user[:username]) discourse_user = User.find_by(username: discourse_username) if discourse_user.nil? # DSDS puts "User #{user[:username]} not found in Discourse. Skipping password update." 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 # Add the MD5 password as a custom field execute_query("SELECT * FROM gforum_User WHERE user_id = #{user[:id]}").each do |row| # discourse_user.update_columns( # discourse_user.update_columns(encrypted_password: row['user_password'], password_salt: nil) 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) # puts "Importing files for user #{user.username}..." 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| create_category( id: row['category_id'], name: row['name'], description: row['description'], created_at: Time.at(row['created_at']), updated_at: Time.at(row['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