diff --git a/gossamer_forums.rb b/gossamer_forums.rb index 04cdaff..dd6f1e7 100644 --- a/gossamer_forums.rb +++ b/gossamer_forums.rb @@ -5,6 +5,7 @@ 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", @@ -18,9 +19,58 @@ class GossamerForumsImporter < ImportScripts::Base @mysql_client.query(query, as: :hash) end - # Sanitize usernames from non-alphanumeric chars - def sanitize_username(username) - username.gsub(/[^a-zA-Z0-9.\-]/, '_') + # 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 @@ -29,10 +79,9 @@ class GossamerForumsImporter < ImportScripts::Base 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'], + 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']), @@ -51,25 +100,19 @@ class GossamerForumsImporter < ImportScripts::Base # 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_username = sanitize_username(user[:username], user[:email], user[:name]) 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 @@ -80,7 +123,6 @@ class GossamerForumsImporter < ImportScripts::Base # 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 @@ -89,19 +131,23 @@ class GossamerForumsImporter < ImportScripts::Base user.bio_raw += "\n\n![#{file['File_Name']}](#{file_url})" user.save! end - # print "\rImporting files for user #{user.username}... Done.\n" + 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: Time.at(row['created_at']), - updated_at: Time.at(row['updated_at']) + created_at: created_at, + updated_at: updated_at ) end end