mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 23:23:45 +08:00
196 lines
4.8 KiB
Ruby
196 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module ImportExport
|
|
class BaseExporter
|
|
attr_reader :export_data, :categories
|
|
|
|
CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color,
|
|
:auto_close_hours, :position, :parent_category_id, :auto_close_based_on_last_post,
|
|
:topic_template, :all_topics_wiki, :permissions_params]
|
|
|
|
GROUP_ATTRS = [:id, :name, :created_at, :automatic_membership_email_domains, :primary_group,
|
|
:title, :grant_trust_level, :incoming_email, :bio_raw, :allow_membership_requests,
|
|
:full_name, :default_notification_level, :visibility_level, :public_exit,
|
|
:public_admission, :membership_request_template, :messageable_level, :mentionable_level,
|
|
:members_visibility_level, :publish_read_state]
|
|
|
|
USER_ATTRS = [:id, :email, :username, :name, :created_at, :trust_level, :active, :last_emailed_at]
|
|
|
|
TOPIC_ATTRS = [:id, :title, :created_at, :views, :category_id, :closed, :archived, :archetype]
|
|
|
|
POST_ATTRS = [:id, :user_id, :post_number, :raw, :created_at, :reply_to_post_number, :hidden,
|
|
:hidden_reason_id, :wiki]
|
|
|
|
def categories
|
|
@categories ||= Category.all.to_a
|
|
end
|
|
|
|
def export_categories
|
|
data = []
|
|
|
|
categories.each do |cat|
|
|
data << CATEGORY_ATTRS.inject({}) { |h, a| h[a] = cat.public_send(a); h }
|
|
end
|
|
|
|
data
|
|
end
|
|
|
|
def export_categories!
|
|
@export_data[:categories] = export_categories
|
|
|
|
self
|
|
end
|
|
|
|
def export_groups(group_names)
|
|
data = []
|
|
groups = Group.all
|
|
groups = groups.where(name: group_names) if group_names.present?
|
|
|
|
groups.find_each do |group|
|
|
attrs = GROUP_ATTRS.inject({}) { |h, a| h[a] = group.public_send(a); h }
|
|
attrs[:user_ids] = group.users.pluck(:id)
|
|
data << attrs
|
|
end
|
|
|
|
data
|
|
end
|
|
|
|
def export_groups!
|
|
@export_data[:groups] = export_groups([])
|
|
|
|
self
|
|
end
|
|
|
|
def export_category_groups
|
|
groups = []
|
|
group_names = []
|
|
auto_group_names = Group::AUTO_GROUPS.keys.map(&:to_s)
|
|
|
|
@export_data[:categories].each do |c|
|
|
c[:permissions_params].each do |group_name, _|
|
|
group_names << group_name unless auto_group_names.include?(group_name.to_s)
|
|
end
|
|
end
|
|
|
|
group_names.uniq!
|
|
return [] if group_names.empty?
|
|
|
|
export_groups(group_names)
|
|
end
|
|
|
|
def export_category_groups!
|
|
@export_data[:groups] = export_category_groups
|
|
|
|
self
|
|
end
|
|
|
|
def export_group_users
|
|
user_ids = []
|
|
|
|
@export_data[:groups].each do |g|
|
|
user_ids += g[:user_ids]
|
|
end
|
|
|
|
user_ids.uniq!
|
|
return User.none if user_ids.empty?
|
|
|
|
users = User.where(id: user_ids)
|
|
export_users(users)
|
|
end
|
|
|
|
def export_group_users!
|
|
@export_data[:users] = export_group_users
|
|
|
|
self
|
|
end
|
|
|
|
def export_topics
|
|
data = []
|
|
|
|
@topics.each do |topic|
|
|
puts topic.title
|
|
|
|
topic_data = TOPIC_ATTRS.inject({}) do |h, a|
|
|
h[a] = topic.public_send(a)
|
|
h
|
|
end
|
|
|
|
topic_data[:posts] = []
|
|
|
|
topic.ordered_posts.find_each do |post|
|
|
attributes = POST_ATTRS.inject({}) do |h, a|
|
|
h[a] = post.public_send(a)
|
|
h
|
|
end
|
|
|
|
attributes[:raw] = attributes[:raw].gsub(
|
|
'src="/uploads',
|
|
"src=\"#{Discourse.base_url_no_prefix}/uploads"
|
|
)
|
|
|
|
topic_data[:posts] << attributes
|
|
end
|
|
|
|
data << topic_data
|
|
end
|
|
|
|
data
|
|
end
|
|
|
|
def export_topics!
|
|
@export_data[:topics] = export_topics
|
|
|
|
self
|
|
end
|
|
|
|
def export_topic_users
|
|
return if @export_data[:topics].blank?
|
|
topic_ids = @export_data[:topics].pluck(:id)
|
|
|
|
users = User.joins(:posts).where('posts.topic_id IN (?)', topic_ids).distinct
|
|
|
|
export_users(users)
|
|
end
|
|
|
|
def export_topic_users!
|
|
@export_data[:users] = export_topic_users
|
|
|
|
self
|
|
end
|
|
|
|
def export_users(users)
|
|
data = []
|
|
|
|
users.find_each do |u|
|
|
next if u.id == Discourse::SYSTEM_USER_ID
|
|
|
|
x = USER_ATTRS.inject({}) do |h, a|
|
|
h[a] = u.public_send(a)
|
|
h
|
|
end
|
|
|
|
x.merge(bio_raw: u.user_profile.bio_raw,
|
|
website: u.user_profile.website,
|
|
location: u.user_profile.location)
|
|
data << x
|
|
end
|
|
|
|
data
|
|
end
|
|
|
|
def default_filename_prefix
|
|
raise "Overwrite me!"
|
|
end
|
|
|
|
def save_to_file(filename = nil)
|
|
output_basename = filename || File.join("#{default_filename_prefix}-#{Time.now.strftime("%Y-%m-%d-%H%M%S")}.json")
|
|
File.open(output_basename, "w:UTF-8") do |f|
|
|
f.write(@export_data.to_json)
|
|
end
|
|
puts "Export saved to #{output_basename}"
|
|
output_basename
|
|
end
|
|
|
|
end
|
|
end
|