namespace :my_forum do namespace :service do desc 'Recalculate category posts count' task recalculate_posts_count: :environment do MyForum::Forum.all.each do |forum| topic_ids = MyForum::Topic.where(forum_id: forum.id).pluck(:id) count = MyForum::Post.where(topic_id: topic_ids).count forum.update(posts_count: count) end end end namespace :import do namespace :smf do if Rails.env.test? require 'sqlite3' $connection = SQLite3::Database.new('test.db') else $connection = Mysql2::Client.new(Rails.configuration.database_configuration['smf_import']) end desc "Import Boards" task boards: :environment do MyForum::Category.delete_all MyForum::Forum.delete_all sql = <<-SQL SELECT `smf_categories`.`name` AS category_name, `smf_boards`.`name` AS board_name, `smf_boards`.`description` AS board_description FROM smf_boards INNER JOIN `smf_categories` ON `smf_boards`.`id_cat` = `smf_categories`.`id_cat` SQL user_groups = MyForum::UserGroup.all result = $connection.query sql result.each do |row| category = MyForum::Category.find_or_create_by(name: row['category_name']) category.user_groups << user_groups if user_groups.any? category.forums.create(name: row['board_name'], description: row['board_description']) end end desc "Import Users" task users: :environment do MyForum::User.destroy_all user_group = MyForum::UserGroup.where(name: 'Member').first sql = "SELECT member_name, date_registered, real_name, email_address, personal_text, birthdate, website_title, website_url, signature, avatar, is_activated FROM smf_members;" result = $connection.query sql result.each do |row| begin date_registered = Time.at(row['date_registered'].to_i) rescue nil user = MyForum::User.create!( login: row['member_name'], email: row['email_address'], real_name: row['real_name'], birthdate: row['birthdate'], signature: row['signature'], avatar: row['avatar'], created_at: date_registered, additional_info: { personal_text: row['personal_text'], website_title: row['website_title'], website_url: row['website_url'], is_activated: row['is_activated'] }) user.user_groups << user_group if user_group rescue => e print e end end end desc "Import Topics and Posts" task topics: :environment do MyForum::Topic.delete_all MyForum::Post.delete_all sql = <<-SQL SELECT `smf_boards`.`name` AS board_name, `smf_messages`.`poster_email`, `smf_messages`.`poster_name`, `smf_messages`.`body`, `smf_messages`.`subject`, `smf_messages`.`poster_time`, `smf_messages`.`id_topic` FROM `smf_messages` INNER JOIN `smf_boards` ON `smf_messages`.`id_board` = `smf_boards`.`id_board` ORDER BY `id_msg` ASC, `id_topic` ASC; SQL result = $connection.query sql result.each do |row| begin user = MyForum::User.find_by_email(row['poster_email']) || MyForum::User.find_by_login(row['poster_name']) user = MyForum::User.create!(login: row['poster_name'], email: row['poster_email'], is_deleted: true) unless user forum = MyForum::Forum.find_or_create_by(name: row['board_name']) # smf does not uses description field, so i use it temponary while import process unless topic = MyForum::Topic.where(description: row['id_topic']).first topic = forum.topics.create!(name: row['subject'], description: row['id_topic']) end post_time = Time.at(row['poster_time'].to_i) topic.posts.create!(user: user, text: row['body'], forum_id: forum.id, created_at: post_time, updated_at: post_time) rescue => e print e end end MyForum::Topic.update_all(description: nil) end desc "Import Private Messages" task pms: :environment do MyForum::PrivateMessage.delete_all sql = <<-SQL SELECT smf_personal_messages.msgtime, smf_personal_messages.subject, smf_personal_messages.body, smf_personal_messages.from_name, smf_pm_recipients.id_member as to_member, smf_members.member_name FROM smf_personal_messages LEFT JOIN smf_pm_recipients ON smf_personal_messages.id_pm = smf_pm_recipients.id_pm LEFT JOIN smf_members ON smf_members.id_member = smf_pm_recipients.id_member SQL result = $connection.query sql result.each do |row| sender = MyForum::User.find_by_login(row['from_name']) recipient = MyForum::User.find_by_login(row['member_name']) next unless sender and recipient pm_time = Time.at(row['msgtime'].to_i) MyForum::PrivateMessage.create!( sender_id: sender.id, sender_login: sender.login, recipient_id: recipient.id, recipient_login: recipient.login, sender_deleted: false, recipient_deleted: false, unread: false, subject: row['subject'], body: row['body'], created_at: pm_time, updated_at: pm_time) end end end end end