discourse/script/discourse
2014-01-31 16:37:05 +11:00

123 lines
3.5 KiB
Ruby
Executable file

#!/usr/bin/env ruby
require "thor"
class DiscourseCLI < Thor
class_option :verbose, default: false, aliases: :v
desc "remap", "Remap a string sequence accross all tables"
def remap(from, to)
load_rails
puts "Rewriting all occurences of #{from} to #{to}"
puts "THIS TASK WILL REWRITE DATA, ARE YOU SURE (type YES)"
text = STDIN.gets
if text.strip != "YES"
puts "aborting."
exit
end
sql = "SELECT table_name, column_name
FROM information_schema.columns
WHERE table_schema='public' and (data_type like 'char%' or data_type like 'text%')"
cnn = ActiveRecord::Base.connection.raw_connection
results = cnn.async_exec(sql).to_a
results.each do |result|
table_name = result["table_name"]
column_name = result["column_name"]
puts "Reampping #{table_name} #{column_name}"
result = cnn.async_exec("UPDATE #{table_name}
SET #{column_name} = replace(#{column_name}, $1, $2)
WHERE NOT #{column_name} IS NULL
AND #{column_name} <> replace(#{column_name}, $1, $2)", [from, to])
puts "#{result.cmd_tuples} rows affected!"
end
end
desc "export", "Export a Discourse backup"
def export(filename=nil)
load_rails
filename = File.expand_path(filename) if filename
puts 'Starting export...'
output_filename = Jobs::Exporter.new.execute( format: :json, filename: filename)
puts 'Export done.'
puts "Output file is in: #{output_filename}", ''
end
desc "import", "Import a Discourse backup"
def import(filename)
load_rails
begin
filename = File.expand_path(filename)
puts "Starting import: #{filename}"
Jobs::Importer.new.execute( format: :json, filename: filename)
puts 'Import done.'
rescue Import::FilenameMissingError
puts '', 'The filename argument was missing.', ''
usage
rescue Import::ImportDisabledError
puts '', 'Imports are not allowed.', 'An admin needs to set allow_import to true in the site settings before imports can be run.', ''
puts 'Import cancelled.', ''
end
end
desc "migrate", "Make sure all the posts are pointing to the new domain"
option :from, type: :array, required: true, banner: "http://previous.domain.com"
option :database, default: "default", aliases: :db
def migrate
verbose = options[:verbose]
database = options[:database]
from = options[:from].map { |f| schemaless f }
begin
puts "loading rails..." if verbose
load_rails
puts "connecting to #{database}..." if verbose
RailsMultisite::ConnectionManagement.establish_connection(db: database)
base_url = schemaless Discourse.base_url_no_prefix
puts "updating #{Post.count} posts to #{base_url}" if verbose
Post.find_each do |post|
raw, cooked = post.raw.dup, post.cooked.dup
from.each do |f|
raw.gsub!(f, base_url)
cooked.gsub!(f, base_url)
end
if raw != post.raw || cooked != post.cooked
Post.where(id: post.id).update_all(raw: raw, cooked: cooked)
putc "#" if verbose
else
putc "."
end
end
rescue => e
puts "Cannot connect to database: #{database}"
puts e
puts e.backtrace.join("\n")
end
puts "", "done!" if verbose
end
private
def load_rails
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
end
def schemaless(url)
url.gsub(/^https?:/, "")
end
end
DiscourseCLI.start(ARGV)