Advertisement
Guest User

Untitled

a guest
Feb 21st, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 19.74 KB | None | 0 0
  1. require 'mysql2'
  2. require File.expand_path(File.dirname(__FILE__) + "/base.rb")
  3. require 'htmlentities'
  4.  
  5. class ImportScripts::VBulletin < ImportScripts::Base
  6.   BATCH_SIZE = 1000
  7.   DBPREFIX = "vb_"
  8.   ROOT_NODE=2
  9.  
  10.   # CHANGE THESE BEFORE RUNNING THE IMPORTER
  11.   DATABASE = "vb4"
  12.   TIMEZONE = "Australia/Sydney"
  13.   ATTACHMENT_DIR = '/vagrant/attachments'
  14.   AVATAR_DIR = '/vagrant/avatars'
  15.  
  16.   def initialize
  17.     super
  18.  
  19.     @old_username_to_new_usernames = {}
  20.  
  21.     @tz = TZInfo::Timezone.get(TIMEZONE)
  22.  
  23.     @htmlentities = HTMLEntities.new
  24.  
  25.     @client = Mysql2::Client.new(
  26.       host: "localhost",
  27.       username: "root",
  28.       database: DATABASE,
  29.       password: "root"
  30.     )
  31.  
  32.   end
  33.  
  34.   def execute
  35.     import_groups
  36.     import_users
  37.     import_categories
  38.     import_topics
  39.     import_posts
  40.     import_attachments
  41.     close_topics
  42.     post_process_posts
  43.   end
  44.  
  45.   def import_groups
  46.     puts "", "importing groups..."
  47.  
  48.     groups = mysql_query <<-SQL
  49.         SELECT usergroupid, title
  50.           FROM #{DBPREFIX}usergroup
  51.       ORDER BY usergroupid
  52.     SQL
  53.  
  54.     create_groups(groups) do |group|
  55.       {
  56.         id: group["usergroupid"],
  57.         name: @htmlentities.decode(group["title"]).strip
  58.       }
  59.     end
  60.   end
  61.  
  62.   def import_users
  63.     puts "", "importing users"
  64.  
  65.     user_count = mysql_query("SELECT COUNT(userid) count FROM #{DBPREFIX}user").first["count"]
  66.  
  67.     batches(BATCH_SIZE) do |offset|
  68.       users = mysql_query <<-SQL
  69.           SELECT u.userid, u.username, u.homepage, u.usertitle, u.usergroupid, u.joindate, u.email,
  70.             CASE WHEN u.scheme='blowfish:10' THEN token
  71.                  WHEN u.scheme='legacy' THEN REPLACE(token, ' ', ':')
  72.             END AS password,
  73.             IF(ug.title = 'Administrators', 1, 0) AS admin
  74.             FROM #{DBPREFIX}user u
  75.             LEFT JOIN #{DBPREFIX}usergroup ug ON ug.usergroupid = u.usergroupid
  76.         ORDER BY userid
  77.            LIMIT #{BATCH_SIZE}
  78.           OFFSET #{offset}
  79.       SQL
  80.  
  81.       break if users.size < 1
  82.  
  83.       # disabled line below, caused issues
  84.       # next if all_records_exist? :users, users.map {|u| u["userid"].to_i}
  85.  
  86.       create_users(users, total: user_count, offset: offset) do |user|
  87.         username = @htmlentities.decode(user["username"]).strip
  88.         {
  89.           id: user["userid"],
  90.           name: username,
  91.           username: username,
  92.           email: user["email"].presence || fake_email,
  93.           admin: user['admin'] == 1,
  94.           password: user["password"],
  95.           website: user["homepage"].strip,
  96.           title: @htmlentities.decode(user["usertitle"]).strip,
  97.           primary_group_id: group_id_from_imported_group_id(user["usergroupid"]),
  98.           created_at: parse_timestamp(user["joindate"]),
  99.           post_create_action: proc do |u|
  100.             @old_username_to_new_usernames[user["username"]] = u.username
  101.             import_profile_picture(user, u)
  102.             import_profile_background(user, u)
  103.           end
  104.         }
  105.       end
  106.     end
  107.   end
  108.  
  109.   def import_profile_picture(old_user, imported_user)
  110.     query = mysql_query <<-SQL
  111.         SELECT filedata, filename
  112.           FROM #{DBPREFIX}customavatar
  113.          WHERE userid = #{old_user["userid"]}
  114.       ORDER BY dateline DESC
  115.          LIMIT 1
  116.     SQL
  117.  
  118.     picture = query.first
  119.  
  120.     return if picture.nil?
  121.  
  122.     if picture['filedata']
  123.       file = Tempfile.new("profile-picture")
  124.       file.write(picture["filedata"].encode("ASCII-8BIT").force_encoding("UTF-8"))
  125.       file.rewind
  126.       upload = Upload.create_for(imported_user.id, file, picture["filename"], file.size)
  127.     else
  128.       filename = File.join(AVATAR_DIR, picture['filename'])
  129.       unless File.exists?(filename)
  130.         puts "Avatar file doesn't exist: #{filename}"
  131.         return nil
  132.       end
  133.       upload = create_upload(imported_user.id, filename, picture['filename'])
  134.     end
  135.  
  136.     return if !upload.persisted?
  137.  
  138.     imported_user.create_user_avatar
  139.     imported_user.user_avatar.update(custom_upload_id: upload.id)
  140.     imported_user.update(uploaded_avatar_id: upload.id)
  141.   ensure
  142.     file.close rescue nil
  143.     file.unlind rescue nil
  144.   end
  145.  
  146.   def import_profile_background(old_user, imported_user)
  147.     query = mysql_query <<-SQL
  148.         SELECT filedata, filename
  149.           FROM #{DBPREFIX}customprofilepic
  150.          WHERE userid = #{old_user["userid"]}
  151.       ORDER BY dateline DESC
  152.          LIMIT 1
  153.     SQL
  154.  
  155.     background = query.first
  156.  
  157.     return if background.nil?
  158.  
  159.     file = Tempfile.new("profile-background")
  160.     file.write(background["filedata"].encode("ASCII-8BIT").force_encoding("UTF-8"))
  161.     file.rewind
  162.  
  163.     upload = Upload.create_for(imported_user.id, file, background["filename"], file.size)
  164.  
  165.     return if !upload.persisted?
  166.  
  167.     imported_user.user_profile.update(profile_background: upload.url)
  168.   ensure
  169.     file.close rescue nil
  170.     file.unlink rescue nil
  171.   end
  172.  
  173.   def import_categories
  174.     puts "", "importing top level categories..."
  175.  
  176.     categories = mysql_query("SELECT nodeid AS forumid, title, description, displayorder, parentid
  177.           FROM #{DBPREFIX}node
  178.          WHERE parentid=#{ROOT_NODE}
  179.        UNION
  180.          SELECT nodeid, title, description, displayorder, parentid
  181.          FROM #{DBPREFIX}node
  182.          WHERE contenttypeid = 20
  183.            AND parentid IN (SELECT nodeid FROM #{DBPREFIX}node WHERE parentid=#{ROOT_NODE})").to_a
  184.  
  185.     top_level_categories = categories.select { |c| c["parentid"] == ROOT_NODE }
  186.  
  187.     create_categories(top_level_categories) do |category|
  188.       {
  189.         id: category["forumid"],
  190.         name: @htmlentities.decode(category["title"]).strip,
  191.         position: category["displayorder"],
  192.         description: @htmlentities.decode(category["description"]).strip
  193.       }
  194.     end
  195.  
  196.     puts "", "importing child categories..."
  197.  
  198.     children_categories = categories.select { |c| c["parentid"] != ROOT_NODE }
  199.     top_level_category_ids = Set.new(top_level_categories.map { |c| c["forumid"] })
  200.  
  201.     # cut down the tree to only 2 levels of categories
  202.     children_categories.each do |cc|
  203.       while !top_level_category_ids.include?(cc["parentid"])
  204.         cc["parentid"] = categories.detect { |c| c["forumid"] == cc["parentid"] }["parentid"]
  205.       end
  206.     end
  207.  
  208.     create_categories(children_categories) do |category|
  209.       {
  210.         id: category["forumid"],
  211.         name: @htmlentities.decode(category["title"]).strip,
  212.         position: category["displayorder"],
  213.         description: @htmlentities.decode(category["description"]).strip,
  214.         parent_category_id: category_id_from_imported_category_id(category["parentid"])
  215.       }
  216.     end
  217.   end
  218.  
  219.   def import_topics
  220.     puts "", "importing topics..."
  221.  
  222.     # keep track of closed topics
  223.     @closed_topic_ids = []
  224.  
  225.     topic_count = mysql_query("select count(nodeid) cnt from #{DBPREFIX}node where parentid in (  
  226.        select nodeid from #{DBPREFIX}node where contenttypeid=20 ) and contenttypeid=24;").first["cnt"]
  227.  
  228.     batches(BATCH_SIZE) do |offset|
  229.       topics = mysql_query <<-SQL
  230.         SELECT t.nodeid AS threadid, t.title, t.parentid AS forumid,t.open,t.userid AS postuserid,t.publishdate AS dateline,
  231.             nv.count views, 1 AS visible, t.sticky,
  232.             CONVERT(CAST(rawtext AS BINARY)USING utf8) AS raw
  233.         FROM #{DBPREFIX}node t
  234.         LEFT JOIN #{DBPREFIX}nodeview nv ON nv.nodeid=t.nodeid
  235.         LEFT JOIN #{DBPREFIX}text txt ON txt.nodeid=t.nodeid
  236.         WHERE t.parentid in ( select nodeid from #{DBPREFIX}node where contenttypeid=20 )
  237.           AND t.contenttypeid = 24
  238.         ORDER BY t.nodeid
  239.            LIMIT #{BATCH_SIZE}
  240.           OFFSET #{offset}
  241.       SQL
  242.  
  243.       break if topics.size < 1
  244.  
  245.       # disabled line below, caused issues
  246.       # next if all_records_exist? :posts, topics.map {|t| "thread-#{topic["threadid"]}" }
  247.  
  248.       create_posts(topics, total: topic_count, offset: offset) do |topic|
  249.         raw = preprocess_post_raw(topic["raw"]) rescue nil
  250.         next if raw.blank?
  251.         topic_id = "thread-#{topic["threadid"]}"
  252.         @closed_topic_ids << topic_id if topic["open"] == "0"
  253.         t = {
  254.           id: topic_id,
  255.           user_id: user_id_from_imported_user_id(topic["postuserid"]) || Discourse::SYSTEM_USER_ID,
  256.           title: @htmlentities.decode(topic["title"]).strip[0...255],
  257.           category: category_id_from_imported_category_id(topic["forumid"]),
  258.           raw: raw,
  259.           created_at: parse_timestamp(topic["dateline"]),
  260.           visible: topic["visible"].to_i == 1,
  261.           views: topic["views"],
  262.         }
  263.         t[:pinned_at] = t[:created_at] if topic["sticky"].to_i == 1
  264.         t
  265.       end
  266.     end
  267.   end
  268.  
  269.   def import_posts
  270.     puts "", "importing posts..."
  271.  
  272.     # make sure `firstpostid` is indexed
  273.     begin
  274.       mysql_query("CREATE INDEX firstpostid_index ON thread (firstpostid)")
  275.     rescue
  276.     end
  277.  
  278.     post_count = mysql_query("SELECT COUNT(nodeid) cnt FROM #{DBPREFIX}node WHERE parentid NOT IN (  
  279.        SELECT nodeid FROM #{DBPREFIX}node WHERE contenttypeid=23 ) AND contenttypeid=20;").first["cnt"]
  280.  
  281.     batches(BATCH_SIZE) do |offset|
  282.       posts = mysql_query <<-SQL
  283.         SELECT p.nodeid AS postid, p.userid AS userid, p.parentid AS threadid,
  284.             CONVERT(CAST(rawtext AS BINARY)USING utf8) AS raw, p.publishdate AS dateline,
  285.             1 AS visible, p.parentid AS parentid
  286.         FROM #{DBPREFIX}node p
  287.         LEFT JOIN #{DBPREFIX}nodeview nv ON nv.nodeid=p.nodeid
  288.         LEFT JOIN #{DBPREFIX}text txt ON txt.nodeid=p.nodeid
  289.         WHERE p.parentid NOT IN ( select nodeid from #{DBPREFIX}node where contenttypeid=23 )
  290.           AND p.contenttypeid = 20
  291.         ORDER BY postid
  292.            LIMIT #{BATCH_SIZE}
  293.           OFFSET #{offset}
  294.       SQL
  295.  
  296.       break if posts.size < 1
  297.  
  298.       # disabled line below, caused issues
  299.       # next if all_records_exist? :posts, posts.map {|p| p["postid"] }
  300.  
  301.       create_posts(posts, total: post_count, offset: offset) do |post|
  302.         raw = preprocess_post_raw(post["raw"])
  303.         next if raw.blank?
  304.         next unless topic = topic_lookup_from_imported_post_id("thread-#{post["threadid"]}")
  305.         p = {
  306.           id: post["postid"],
  307.           user_id: user_id_from_imported_user_id(post["userid"]) || Discourse::SYSTEM_USER_ID,
  308.           topic_id: topic[:topic_id],
  309.           raw: raw,
  310.           created_at: parse_timestamp(post["dateline"]),
  311.           hidden: post["visible"].to_i == 0,
  312.         }
  313.         if parent = topic_lookup_from_imported_post_id(post["parentid"])
  314.           p[:reply_to_post_number] = parent[:post_number]
  315.         end
  316.         p
  317.       end
  318.     end
  319.   end
  320.  
  321.   # find the uploaded file information from the db
  322.   def find_upload(post, attachment_id)
  323.     sql = "SELECT a.filedataid, a.filename, fd.userid, LENGTH(fd.filedata) AS dbsize, filedata
  324.             FROM #{DBPREFIX}attach a
  325.             LEFT JOIN #{DBPREFIX}filedata fd ON fd.filedataid = a.filedataid
  326.            WHERE a.nodeid = #{attachment_id}"
  327.     results = mysql_query(sql)
  328.  
  329.     unless (row = results.first)
  330.       puts "Couldn't find attachment record for post.id = #{post.id}, import_id = #{post.custom_fields['import_id']}"
  331.       return nil
  332.     end
  333.  
  334.     filename = File.join(ATTACHMENT_DIR, row['userid'].to_s.split('').join('/'), "#{row['filedataid']}.attach")
  335.     real_filename = row['filename']
  336.     real_filename.prepend SecureRandom.hex if real_filename[0] == '.'
  337.  
  338.     unless File.exists?(filename)
  339.       if row['dbsize'].to_i == 0
  340.         puts "Attachment file #{row['filedataid']} doesn't exist"
  341.         return nil
  342.       end
  343.  
  344.       tmpfile = 'attach_' + row['filedataid'].to_s
  345.       filename = File.join('/tmp/', tmpfile)
  346.       File.open(filename, 'wb') { |f|
  347.         #f.write(PG::Connection.unescape_bytea(row['filedata']))
  348.         f.write(row['filedata'])
  349.       }
  350.     end
  351.  
  352.     upload = create_upload(post.user.id, filename, real_filename)
  353.  
  354.     if upload.nil? || !upload.valid?
  355.       puts "Upload not valid :("
  356.       puts upload.errors.inspect if upload
  357.       return nil
  358.     end
  359.  
  360.     return upload, real_filename
  361.   rescue Mysql2::Error => e
  362.     puts "SQL Error"
  363.     puts e.message
  364.     puts sql
  365.     return nil
  366.   end
  367.  
  368.   def import_attachments
  369.     puts '', 'importing attachments...'
  370.  
  371.     current_count = 0
  372.     total_count = mysql_query("SELECT COUNT(nodeid) cnt FROM #{DBPREFIX}node WHERE contenttypeid=22 ").first["cnt"]
  373.  
  374.     success_count = 0
  375.     fail_count = 0
  376.  
  377.     attachment_regex = /\[attach[^\]]*\]n(\d+)\[\/attach\]/i
  378.  
  379.     Post.find_each do |post|
  380.       current_count += 1
  381.       print_status current_count, total_count
  382.  
  383.       new_raw = post.raw.dup
  384.       new_raw.gsub!(attachment_regex) do |s|
  385.         matches = attachment_regex.match(s)
  386.         attachment_id = matches[1]
  387.  
  388.         upload, filename = find_upload(post, attachment_id)
  389.         unless upload
  390.           fail_count += 1
  391.           next
  392.         end
  393.         html_for_upload(upload, filename)
  394.       end
  395.  
  396.       if new_raw != post.raw
  397.         PostRevisor.new(post).revise!(post.user, { raw: new_raw }, { bypass_bump: true, edit_reason: 'Import attachments from vBulletin' })
  398.       end
  399.  
  400.       success_count += 1
  401.     end
  402.   end
  403.  
  404.   def close_topics
  405.     puts "", "Closing topics..."
  406.  
  407.     sql = <<-SQL
  408.       WITH closed_topic_ids AS (
  409.         SELECT t.id AS topic_id
  410.         FROM post_custom_fields pcf
  411.         JOIN posts p ON p.id = pcf.post_id
  412.         JOIN topics t ON t.id = p.topic_id
  413.         WHERE pcf.name = 'import_id'
  414.         AND pcf.value IN (?)
  415.       )
  416.       UPDATE topics
  417.       SET closed = true
  418.       WHERE id IN (SELECT topic_id FROM closed_topic_ids)
  419.     SQL
  420.  
  421.     Topic.exec_sql(sql, @closed_topic_ids)
  422.   end
  423.  
  424.   def post_process_posts
  425.     puts "", "Postprocessing posts..."
  426.  
  427.     current = 0
  428.     max = Post.count
  429.  
  430.     Post.find_each do |post|
  431.       begin
  432.         new_raw = postprocess_post_raw(post.raw)
  433.         if new_raw != post.raw
  434.           post.raw = new_raw
  435.           post.save
  436.         end
  437.       rescue PrettyText::JavaScriptError
  438.         nil
  439.       ensure
  440.         print_status(current += 1, max)
  441.       end
  442.     end
  443.   end
  444.  
  445.   def preprocess_post_raw(raw)
  446.     return "" if raw.blank?
  447.  
  448.     # decode HTML entities
  449.     raw = @htmlentities.decode(raw)
  450.  
  451.     # fix whitespaces
  452.     raw = raw.gsub(/(\\r)?\\n/, "\n")
  453.              .gsub("\\t", "\t")
  454.  
  455.     # [HTML]...[/HTML]
  456.     raw = raw.gsub(/\[html\]/i, "\n```html\n")
  457.              .gsub(/\[\/html\]/i, "\n```\n")
  458.  
  459.     # [PHP]...[/PHP]
  460.     raw = raw.gsub(/\[php\]/i, "\n```php\n")
  461.              .gsub(/\[\/php\]/i, "\n```\n")
  462.  
  463.     # [HIGHLIGHT="..."]
  464.     raw = raw.gsub(/\[highlight="?(\w+)"?\]/i) { "\n```#{$1.downcase}\n" }
  465.  
  466.     # [CODE]...[/CODE]
  467.     # [HIGHLIGHT]...[/HIGHLIGHT]
  468.     raw = raw.gsub(/\[\/?code\]/i, "\n```\n")
  469.              .gsub(/\[\/?highlight\]/i, "\n```\n")
  470.  
  471.     # [SAMP]...[/SAMP]
  472.     raw = raw.gsub(/\[\/?samp\]/i, "`")
  473.  
  474.     # replace all chevrons with HTML entities
  475.     # NOTE: must be done
  476.     #  - AFTER all the "code" processing
  477.     #  - BEFORE the "quote" processing
  478.     raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub("<", "\u2603") + "`" }
  479.             .gsub("<", "&lt;")
  480.             .gsub("\u2603", "<")
  481.  
  482.    raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub(">", "\u2603") + "`" }
  483.              .gsub(">", "&gt;")
  484.              .gsub("\u2603", ">")
  485.  
  486.     # [URL=...]...[/URL]
  487.     raw.gsub!(/\[url="?(.+?)"?\](.+?)\[\/url\]/i) { "<a href=\"#{$1}\">#{$2}</a>" }
  488.  
  489.     # [URL]...[/URL]
  490.     # [MP3]...[/MP3]
  491.     raw = raw.gsub(/\[\/?url\]/i, "")
  492.              .gsub(/\[\/?mp3\]/i, "")
  493.  
  494.     # [MENTION]<username>[/MENTION]
  495.     raw = raw.gsub(/\[mention\](.+?)\[\/mention\]/i) do
  496.       old_username = $1
  497.       if @old_username_to_new_usernames.has_key?(old_username)
  498.         old_username = @old_username_to_new_usernames[old_username]
  499.       end
  500.       "@#{old_username}"
  501.     end
  502.  
  503.     # [USER=<user_id>]<username>[/USER]
  504.     raw = raw.gsub(/\[user="?(\d+)"?\](.+?)\[\/user\]/i) do
  505.       user_id, old_username = $1, $2
  506.       if @old_username_to_new_usernames.has_key?(old_username)
  507.         new_username = @old_username_to_new_usernames[old_username]
  508.       else
  509.         new_username = old_username
  510.       end
  511.       "@#{new_username}"
  512.     end
  513.  
  514.     # [FONT=blah] and [COLOR=blah]
  515.     # no idea why the /i is not matching case insensitive..
  516.     raw.gsub! /\[color=.*?\](.*?)\[\/color\]/im, '\1'
  517.     raw.gsub! /\[COLOR=.*?\](.*?)\[\/COLOR\]/im, '\1'
  518.     raw.gsub! /\[font=.*?\](.*?)\[\/font\]/im, '\1'
  519.     raw.gsub! /\[FONT=.*?\](.*?)\[\/FONT\]/im, '\1'
  520.  
  521.     # [CENTER]...[/CENTER]
  522.     raw.gsub! /\[CENTER\](.*?)\[\/CENTER\]/im, '\1'
  523.  
  524.     # fix LIST
  525.     raw.gsub! /\[LIST\](.*?)\[\/LIST\]/im, '<ul>\1</ul>'
  526.     raw.gsub! /\[\*\]/im, '<li>'
  527.  
  528.     # [QUOTE]...[/QUOTE]
  529.     raw = raw.gsub(/\[quote\](.+?)\[\/quote\]/im) { "\n> #{$1}\n" }
  530.  
  531.     # [QUOTE=<username>]...[/QUOTE]
  532.     raw = raw.gsub(/\[quote=([^;\]]+)\](.+?)\[\/quote\]/im) do
  533.       old_username, quote = $1, $2
  534.  
  535.       if @old_username_to_new_usernames.has_key?(old_username)
  536.         old_username = @old_username_to_new_usernames[old_username]
  537.       end
  538.       "\n[quote=\"#{old_username}\"]\n#{quote}\n[/quote]\n"
  539.     end
  540.  
  541.     # [YOUTUBE]<id>[/YOUTUBE]
  542.     raw = raw.gsub(/\[youtube\](.+?)\[\/youtube\]/i) { "\n//youtu.be/#{$1}\n" }
  543.  
  544.     # [VIDEO=youtube;<id>]...[/VIDEO]
  545.     raw = raw.gsub(/\[video=youtube;([^\]]+)\].*?\[\/video\]/i) { "\n//youtu.be/#{$1}\n" }
  546.  
  547.     raw
  548.   end
  549.  
  550.   def postprocess_post_raw(raw)
  551.     # [QUOTE=<username>;<post_id>]...[/QUOTE]
  552.     raw = raw.gsub(/\[quote=([^;]+);n(\d+)\](.+?)\[\/quote\]/im) do
  553.       old_username, post_id, quote = $1, $2, $3
  554.  
  555.       if @old_username_to_new_usernames.has_key?(old_username)
  556.         old_username = @old_username_to_new_usernames[old_username]
  557.       end
  558.  
  559.       if topic_lookup = topic_lookup_from_imported_post_id(post_id)
  560.         post_number = topic_lookup[:post_number]
  561.         topic_id    = topic_lookup[:topic_id]
  562.         "\n[quote=\"#{old_username},post:#{post_number},topic:#{topic_id}\"]\n#{quote}\n[/quote]\n"
  563.       else
  564.         "\n[quote=\"#{old_username}\"]\n#{quote}\n[/quote]\n"
  565.       end
  566.     end
  567.  
  568.     # remove attachments
  569.     raw = raw.gsub(/\[attach[^\]]*\]\d+\[\/attach\]/i, "")
  570.  
  571.     # [THREAD]<thread_id>[/THREAD]
  572.     # ==> http://my.discourse.org/t/slug/<topic_id>
  573.     raw = raw.gsub(/\[thread\](\d+)\[\/thread\]/i) do
  574.       thread_id = $1
  575.       if topic_lookup = topic_lookup_from_imported_post_id("thread-#{thread_id}")
  576.         topic_lookup[:url]
  577.       else
  578.         $&
  579.       end
  580.     end
  581.  
  582.     # [THREAD=<thread_id>]...[/THREAD]
  583.     # ==> [...](http://my.discourse.org/t/slug/<topic_id>)
  584.     raw = raw.gsub(/\[thread=(\d+)\](.+?)\[\/thread\]/i) do
  585.       thread_id, link = $1, $2
  586.       if topic_lookup = topic_lookup_from_imported_post_id("thread-#{thread_id}")
  587.         url = topic_lookup[:url]
  588.         "[#{link}](#{url})"
  589.       else
  590.         $&
  591.       end
  592.     end
  593.  
  594.     # [POST]<post_id>[/POST]
  595.     # ==> http://my.discourse.org/t/slug/<topic_id>/<post_number>
  596.     raw = raw.gsub(/\[post\](\d+)\[\/post\]/i) do
  597.       post_id = $1
  598.       if topic_lookup = topic_lookup_from_imported_post_id(post_id)
  599.         topic_lookup[:url]
  600.       else
  601.         $&
  602.       end
  603.     end
  604.  
  605.     # [POST=<post_id>]...[/POST]
  606.     # ==> [...](http://my.discourse.org/t/<topic_slug>/<topic_id>/<post_number>)
  607.     raw = raw.gsub(/\[post=(\d+)\](.+?)\[\/post\]/i) do
  608.       post_id, link = $1, $2
  609.       if topic_lookup = topic_lookup_from_imported_post_id(post_id)
  610.         url = topic_lookup[:url]
  611.         "[#{link}](#{url})"
  612.       else
  613.         $&
  614.       end
  615.     end
  616.  
  617.     raw
  618.   end
  619.  
  620.   def parse_timestamp(timestamp)
  621.     Time.zone.at(@tz.utc_to_local(timestamp))
  622.   end
  623.  
  624.   def fake_email
  625.     SecureRandom.hex << "@domain.com"
  626.   end
  627.  
  628.   def mysql_query(sql)
  629.     @client.query(sql, cache_rows: false)
  630.   end
  631.  
  632. end
  633.  
  634. ImportScripts::VBulletin.new.perform
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement