Wie kann ich nur Themes von XenForo importieren? Und sie in eine bestimmte Kategorie in Disc verschieben
Wir können Themes von XenForo migrieren?! Ich bin ziemlich sicher, dass das nicht möglich ist
*Themen
Entschuldigung ![]()
Wenn Sie meine Threads hier durchsehen, antwortet Jay auf einen meiner Beiträge mit einer Änderung am xenforo.rb-Skript, um dies zu tun
Ich habe im letzten Schritt einen Fehler erhalten:
private Nachrichten werden importiert...
Topic ID 0 nicht gefunden, überspringe Beitrag 14 von 0
1 / 28302 ( 0.0%) [80733 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 15 von 0
2 / 28302 ( 0.0%) [115895 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 17 von 0
3 / 28302 ( 0.0%) [141468 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 18 von 0
4 / 28302 ( 0.0%) [160596 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 22 von 0
5 / 28302 ( 0.0%) [158134 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 28 von 0
6 / 28302 ( 0.0%) [167920 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 29 von 0
7 / 28302 ( 0.0%) [178637 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 44 von 0
8 / 28302 ( 0.0%) [188301 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 45 von 0
9 / 28302 ( 0.0%) [196423 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 48 von 0
10 / 28302 ( 0.0%) [202985 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 50 von 0
11 / 28302 ( 0.0%) [204726 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 51 von 0
12 / 28302 ( 0.0%) [209394 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 52 von 0
13 / 28302 ( 0.0%) [213452 Elemente/min] Topic ID 0 nicht gefunden, überspringe Beitrag 55 von 0
14 / 28302 ( 0.0%) /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/php_serialize-1.2/lib/php_serialize.rb:315:in `do_unserialize': Unable to unserialize type '{' (TypeError)
raise TypeError, "Unable to unserialize type '#{type}'"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/php_serialize-1.2/lib/php_serialize.rb:214:in `unserialize'
from script/import_scripts/xenforo.rb:349:in `block (2 levels) in import_private_messages'
from /var/www/discourse/script/import_scripts/base.rb:548:in `block in create_posts'
from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
from /var/www/discourse/script/import_scripts/base.rb:547:in `create_posts'
from script/import_scripts/xenforo.rb:325:in `block in import_private_messages'
from /var/www/discourse/script/import_scripts/base.rb:948:in `block in batches'
from /var/www/discourse/script/import_scripts/base.rb:947:in `loop'
from /var/www/discourse/script/import_scripts/base.rb:947:in `batches'
from script/import_scripts/xenforo.rb:314:in `import_private_messages'
from script/import_scripts/xenforo.rb:45:in `execute'
from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
from script/import_scripts/xenforo.rb:569:in `<main>'
Kann mir jemand helfen?
Ich würde dort, wo es fehlschlägt, ein puts einfügen oder dem aufrufenden Teil von php serialize ein rescue hinzufügen.
Aber wenn all diese PMs fehlschlagen, dann ist der PM-Importer vielleicht für Ihre Version von Xenforo einfach kaputt. Sie müssen sich also möglicherweise die Abfrage ansehen, die er ausführt.
Das ist alles, was ich vorschlagen kann, ohne mich in Ihre Datenbank und den Code einzuarbeiten.
Vielleicht braucht es jemand in Zukunft.
Mein modifizierter Importer mit reparierten Anhängen, Avataren, Likes (Reaktionen in neuer XenForo) und immer noch kaputten PMs (da ich sie nicht brauche).
# frozen_string_literal: true
require "mysql2"
begin
require "php_serialize" # https://github.com/jqr/php-serialize
rescue LoadError
puts
puts „php_serialize nicht gefunden.“
puts „Füge es zur Gemfile hinzu, wie folgt: “
puts
puts "echo gem \\'php-serialize\\' >> Gemfile"
puts "bundle install"
exit
end
require File.expand_path(File.dirname(__FILE__) + "/base.rb")
# Aufruf wie folgt:
# RAILS_ENV=production bundle exec ruby script/import_scripts/xenforo.rb
class ImportScripts::XenForo < ImportScripts::Base
XENFORO_DB = "import_db"
TABLE_PREFIX = "xf_"
BATCH_SIZE = 1000
ATTACHMENT_DIR = "/shared/attachments"
AVATAR_DIR = "/shared/avatars"
def initialize
super
@client =
Mysql2::Client.new(
host: "localhost",
username: "root",
password: "password",
database: "import_db",
)
@category_mappings = {}
@prefix_as_category = false
end
def execute
import_users
import_categories
import_posts
# import_private_messages
import_likes
end
def import_avatar(id, imported_user)
filename = File.join(AVATAR_DIR, "l", (id / 1000).to_s, "#{id}.jpg")
return nil unless File.exist?(filename)
upload = create_upload(imported_user.id, filename, "avatar_#{id}")
return if !upload.persisted?
imported_user.create_user_avatar
imported_user.user_avatar.update(custom_upload_id: upload.id)
imported_user.update(uploaded_avatar_id: upload.id)
end
def import_users
puts "", "Erstelle Benutzer"
total_count =
mysql_query(
"SELECT count(*) count FROM #{TABLE_PREFIX}user WHERE user_state = 'valid' AND is_banned = 0;",
).first[
"count"
]
batches(BATCH_SIZE) do |offset|
results =
mysql_query(
"SELECT user_id id, username, email, custom_title title, register_date created_at,
last_activity last_visit_time, user_group_id, is_moderator, is_admin, is_staff
FROM #{TABLE_PREFIX}user
WHERE user_state = 'valid' AND is_banned = 0
LIMIT #{BATCH_SIZE}
OFFSET #{offset};",
)
break if results.size < 1
next if all_records_exist? :users, results.map { |u| u["id"].to_i }
create_users(results, total: total_count, offset: offset) do |user|
next if user["username"].blank?
{
id: user["id"],
email: user["email"],
username: user["username"],
title: user["title"],
created_at: Time.zone.at(user["created_at"]),
last_seen_at: Time.zone.at(user["last_visit_time"]),
moderator: user["is_moderator"] == 1 || user["is_staff"] == 1,
admin: user["is_admin"] == 1,
post_create_action: proc { |u| import_avatar(user["id"], u) },
}
end
end
end
def import_categories
puts "", "Importiere Kategorien..."
categories =
mysql_query(
"
SELECT node_id id,
title,
description,
parent_node_id,
node_name,
display_order
FROM #{TABLE_PREFIX}node
ORDER BY parent_node_id, display_order
",
).to_a
top_level_categories = categories.select { |c| c["parent_node_id"] == 0 }
create_categories(top_level_categories) do |c|
{
id: c["id"],
name: c["title"],
description: c["description"],
position: c["display_order"],
post_create_action:
proc do |category|
url = "board/#{c["node_name"]}"
Permalink.find_or_create_by(url: url, category_id: category.id)
end,
}
end
top_level_category_ids = Set.new(top_level_categories.map { |c| c["id"] })
subcategories = categories.select { |c| top_level_category_ids.include?(c["parent_node_id"]) }
create_categories(subcategories) do |c|
{
id: c["id"],
name: c["title"],
description: c["description"],
position: c["display_order"],
parent_category_id: category_id_from_imported_category_id(c["parent_node_id"]),
post_create_action:
proc do |category|
url = "board/#{c["node_name"]}"
Permalink.find_or_create_by(url: url, category_id: category.id)
end,
}
end
subcategory_ids = Set.new(subcategories.map { |c| c["id"] })
# Tiefere Kategorien müssen als Tags behandelt werden
categories.each do |c|
next if c["parent_node_id"] == 0
next if top_level_category_ids.include?(c["id"])
next if subcategory_ids.include?(c["id"])
# Finde eine Unterkategorie für Themen in dieser Kategorie
parent = c
while !parent.nil? && !subcategory_ids.include?(parent["id"])
parent = categories.find { |subcat| subcat["id"] == parent["parent_node_id"] }
end
if parent
tag_name = DiscourseTagging.clean_tag(c["title"])
@category_mappings[c["id"]] = {
category_id: category_id_from_imported_category_id(parent["id"]),
tag: Tag.find_by_name(tag_name) || Tag.create(name: tag_name),
}
else
puts "", "Konnte keine Kategorie für #{c["id"]} '#{c["title"]}' finden!"
end
end
end
# Diese Methode ist eine Alternative zu import_categories.
# Sie verwendet Präfixe statt Nodes.
def import_categories_from_thread_prefixes
puts "", "Importiere Kategorien..."
categories =
mysql_query(
"
SELECT prefix_id id
FROM #{TABLE_PREFIX}thread_prefix
ORDER BY prefix_id ASC
",
).to_a
create_categories(categories) do |category|
{ id: category["id"], name: "Kategorie-#{category["id"]}" }
end
@prefix_as_category = true
end
def import_likes
puts "", "Importiere Likes"
total_count =
mysql_query(
"SELECT COUNT(*) AS count FROM #{TABLE_PREFIX}reaction_content WHERE content_type = 'post'",
).first[
"count"
]
batches(BATCH_SIZE) do |offset|
results =
mysql_query(
"SELECT reaction_content_id, content_id, reaction_user_id, reaction_date
FROM #{TABLE_PREFIX}reaction_content
WHERE content_type = 'post'
ORDER BY reaction_content_id
LIMIT #{BATCH_SIZE}
OFFSET #{offset};",
)
break if results.size < 1
create_likes(results, total: total_count, offset: offset) do |row|
{
post_id: row["content_id"],
user_id: row["reaction_user_id"],
created_at: Time.zone.at(row["reaction_date"]),
}
end
end
end
def import_posts
puts "", "Erstelle Themen und Beiträge"
total_count = mysql_query("SELECT count(*) count from #{TABLE_PREFIX}post").first["count"]
posts_sql =
"
SELECT p.post_id id,
t.thread_id topic_id,
#{@prefix_as_category ? "t.prefix_id" : "t.node_id"} category_id,
t.title title,
t.first_post_id first_post_id,
t.view_count,
p.user_id user_id,
p.message raw,
p.post_date created_at
FROM #{TABLE_PREFIX}post p,
#{TABLE_PREFIX}thread t
WHERE p.thread_id = t.thread_id
AND p.message_state = 'visible'
AND t.discussion_state = 'visible'
ORDER BY p.post_date
LIMIT #{BATCH_SIZE}" # benötigt OFFSET
batches(BATCH_SIZE) do |offset|
results = mysql_query("#{posts_sql} OFFSET #{offset};").to_a
break if results.size < 1
next if all_records_exist? :posts, results.map { |p| p["id"] }
create_posts(results, total: total_count, offset: offset) do |m|
skip = false
mapped = {}
mapped[:id] = m["id"]
mapped[:user_id] = user_id_from_imported_user_id(m["user_id"]) || -1
mapped[:raw] = process_xenforo_post(m["raw"], m["id"])
mapped[:created_at] = Time.zone.at(m["created_at"])
if m["id"] == m["first_post_id"]
if m["category_id"].to_i == 0 || m["category_id"].nil?
mapped[:category] = SiteSetting.uncategorized_category_id
else
mapped[:category] = category_id_from_imported_category_id(m["category_id"].to_i) ||
@category_mappings[m["category_id"]].try(:[], :category_id)
end
mapped[:title] = CGI.unescapeHTML(m["title"])
mapped[:views] = m["view_count"]
mapped[:post_create_action] = proc do |pp|
Permalink.find_or_create_by(url: "threads/#{m["topic_id"]}", topic_id: pp.topic_id)
end
else
parent = topic_lookup_from_imported_post_id(m["first_post_id"])
if parent
mapped[:topic_id] = parent[:topic_id]
else
puts "Elternbeitrag #{m["first_post_id"]} existiert nicht. Überspringe #{m["id"]}: #{m["title"][0..40]}"
skip = true
end
end
skip ? nil : mapped
end
end
# Wende Tags an
batches(BATCH_SIZE) do |offset|
results = mysql_query("#{posts_sql} OFFSET #{offset};").to_a
break if results.size < 1
results.each do |m|
next unless m["id"] == m["first_post_id"] && m["category_id"].to_i > 0
next unless tag = @category_mappings[m["category_id"]].try(:[], :tag)
next unless topic_mapping = topic_lookup_from_imported_post_id(m["id"])
topic = Topic.find_by_id(topic_mapping[:topic_id])
topic.tags = [tag] if topic
end
end
end
def import_private_messages
puts "", "Importiere private Nachrichten..."
post_count = mysql_query("SELECT COUNT(*) count FROM xf_conversation_message").first["count"]
batches(BATCH_SIZE) do |offset|
posts = mysql_query <<-SQL
SELECT c.conversation_id, c.recipients, c.title, m.message, m.user_id, m.message_date, m.message_id, IF(c.first_message_id != m.message_id, c.first_message_id, 0) as topic_id
FROM xf_conversation_master c
LEFT JOIN xf_conversation_message m ON m.conversation_id = c.conversation_id
ORDER BY c.conversation_id, m.message_id
LIMIT #{BATCH_SIZE}
OFFSET #{offset}
SQL
break if posts.size < 1
next if all_records_exist? :posts, posts.map { |post| "pm_#{post["message_id"]}" }
create_posts(posts, total: post_count, offset: offset) do |post|
user_id = user_id_from_imported_user_id(post["user_id"]) || Discourse::SYSTEM_USER_ID
title = post["title"]
message_id = "pm_#{post["message_id"]}"
raw = process_xenforo_post(post["message"], 0)
if raw.present?
msg = {
id: message_id,
user_id: user_id,
raw: raw,
created_at: Time.zone.at(post["message_date"].to_i),
import_mode: true,
}
if post["topic_id"] <= 0
topic_id = post["topic_id"]
if t = topic_lookup_from_imported_post_id("pm_#{topic_id}")
msg[:topic_id] = t[:topic_id]
else
puts "Themen-ID #{topic_id} nicht gefunden, überspringe Beitrag #{post["message_id"]} von #{post["user_id"]}"
next
end
else
msg[:title] = post["title"]
msg[:archetype] = Archetype.private_message
to_user_array = PHP.unserialize(post["recipients"])
if to_user_array.size > 0
discourse_user_ids = to_user_array.keys.map { |id| user_id_from_imported_user_id(id) }
usernames = User.where(id: [discourse_user_ids]).pluck(:username)
msg[:target_usernames] = usernames.join(",")
end
end
msg
else
puts "Leere Nachricht, überspringe Beitrag #{post["message_id"]}"
next
end
end
end
end
def process_xenforo_post(raw, import_id)
s = raw.dup
# :) wird kodiert als <!-- s:) --><img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
s.gsub!(%r{<!-- s(\S+) --><img (?:[^>]+) /><!-- s(?:\S+) -->}, '\1')
# Einige Links sehen so aus: <!-- m --><a class="postlink" href="http://www.onegameamonth.com">http://www.onegameamonth.com</a><!-- m -->
s.gsub!(%r{<!-- \w --><a(?:.+)href="(\S+)"(?:.*)>(.+)</a><!-- \w -->}, '[\2](\1)')
# Viele phpBB-BBCode-Tags haben einen Hash angehängt. Beispiele:
# [url=https://google.com:1qh1i7ky]hier klicken[/url:1qh1i7ky]
# [quote="cybereality":b0wtlzex]Einige Text.[/quote:b0wtlzex]
s.gsub!(/:(?:\w{8})\]/, "]")
# Entferne meine MyBB-Video-Tags.
s.gsub!(%r{(^\[video=.*?\])|(\[/video\]$)}, "")
s = CGI.unescapeHTML(s)
# phpBB kürzt Linktexte so, was unsere Markdown-Verarbeitung unterbricht:
# [http://answers.yahoo.com/question/index ... 223AAkkPli](http://answers.yahoo.com/question/index?qid=20070920134223AAkkPli)
#
# Fix für den Fehler: xenforo.rb: 160: in `gsub!': ungültige Byte-Sequenz in UTF-8 (ArgumentError)
s = s.encode("UTF-16be", invalid: :replace, replace: "?").encode("UTF-8") if !s.valid_encoding?
# Workaround vorläufig:
s.gsub!(%r{\[http(s)?://(www\.)?}, "[")
# [QUOTE]...[/QUOTE]
s.gsub!(%r{\[quote\](.+?)\[/quote\]}im) { "\n> #{$1}\n" }
# Verschachtelte Zitate
s.gsub!(%r{(\[/?QUOTE.*?\])}mi) { |q| "\n#{q}\n" }
# [QUOTE="username, post: 28662, member: 1283"]
s.gsub!(/\[quote="(\w+), post: (\d*), member: (\d*)"\]/i) do
username, imported_post_id, _imported_user_id = $1, $2, $3
topic_mapping = topic_lookup_from_imported_post_id(imported_post_id)
if topic_mapping
"\n[quote=\"#{username}, post:#{topic_mapping[:post_number]}, topic:#{topic_mapping[:topic_id]}\"]\n"
else
"\n[quote=\"#{username}\"]\n"
end
end
# [URL=...]...[/URL]
s.gsub!(%r{\[url="?(.+?)"?\](.+?)\[/url\]}i) { "[#{$2}](#{$1})" }
# [URL]...[/URL]
s.gsub!(%r{\[url\](.+?)\[/url\]}i) { " #{$1} " }
# [IMG]...[/IMG]
s.gsub!(%r{\[/?img\]}i, "")
# Konvertiere List-Tags zu ul und list=1-Tags zu ol
# (im Grunde fehlt uns hier nur list=a...)
s.gsub!(%r{\[list\](.*?)\[/list\]}im, '[ul]\1[/ul]')
s.gsub!(%r{\[list=1\](.*?)\[/list\]}im, '[ol]\1[/ol]')
s.gsub!(%r{\[list\](.*?)\[/list:u\]}im, '[ul]\1[/ul]')
s.gsub!(%r{\[list=1\](.*?)\[/list:o\]}im, '[ol]\1[/ol]')
# Konvertiere *-Tags zu li-Tags, damit bbcode-to-md seine Magie mit phpBB-Listen vollführen kann:
s.gsub!(/\[\*\]\n/, "")
s.gsub!(%r{\[\*\](.*?)\[/\*:m\]}, '[li]\1[/li]')
s.gsub!(/\[\*\](.*?)\n/, '[li]\1[/li]')
s.gsub!(/\[\*=1\]/, "")
# [YOUTUBE]<id>[/YOUTUBE]
s.gsub!(%r{\[youtube\](.+?)\[/youtube\]}i) { "\nhttps://www.youtube.com/watch?v=#{$1}\n" }
# [youtube=425,350]id[/youtube]
s.gsub!(%r{\[youtube="?(.+?)"?\](.+?)\[/youtube\]}i) do
"\nhttps://www.youtube.com/watch?v=#{$2}\n"
end
# [MEDIA=youtube]id[/MEDIA]
s.gsub!(%r{\[MEDIA=youtube\](.+?)\[/MEDIA\]}i) { "\nhttps://www.youtube.com/watch?v=#{$1}\n" }
# [ame="youtube_link"]title[/ame]
s.gsub!(%r{\[ame="?(.+?)"?\](.+?)\[/ame\]}i) { "\n#{$1}\n" }
# [VIDEO=youtube;<id>]...[/VIDEO]
s.gsub!(%r{\[video=youtube;([^\]]+)\].*?\[/video\]}i) do
"\nhttps://www.youtube.com/watch?v=#{$1}\n"
end
# [USER=706]@username[/USER]
s.gsub!(%r{\[user="?(.+?)"?\](.+?)\[/user\]}i) { $2 }
# Entferne das Color-Tag
s.gsub!(/\[color=[#a-z0-9]+\]/i, "")
s.gsub!(%r{\[/color\]}i, "")
# [HR]...[/HR]
s.gsub!(%r{\[/?hr\]}i, "\n")
# [CENTER]...[/CENTER]
s.gsub!(%r{\[/?CENTER\]}i, "")
# [HEADING=1]id[/HEADING]
s.gsub!(%r{\[HEADING=1\](.+?)\[/HEADING\]}i) { "#{$1}\n" }
if Dir.exist? ATTACHMENT_DIR
s = process_xf_attachments(:gallery, s, import_id)
s = process_xf_attachments(:attachment, s, import_id)
end
s
end
def process_xf_attachments(xf_type, s, import_id)
ids = Set.new
ids.merge(s.scan(get_xf_regexp(xf_type)).map { |x| x[0].to_i })
# Nicht alle Anhänge haben ein [ATTACH=]-Tag, daher müssen wir die anderen IDs aus der xf_attachment-Tabelle holen
if xf_type == :attachment && import_id > 0
sql =
"SELECT attachment_id FROM #{TABLE_PREFIX}attachment WHERE content_id=#{import_id} and content_type='post';"
ids.merge(mysql_query(sql).to_a.map { |v| v["attachment_id"].to_i })
end
ids.each do |id|
next unless id
sql = get_xf_sql(xf_type, id).dup.squish!
results = mysql_query(sql)
if results.size < 1
# Entferne Anhang
s.gsub!(get_xf_regexp(xf_type, id), "")
STDERR.puts "#{xf_type.capitalize} ID #{id} nicht in der Quelldatenbank gefunden. Entferne."
next
end
original_filename = results.first["filename"]
result = results.first
upload =
import_xf_attachment(
result["data_id"],
result["file_hash"],
result["user_id"],
original_filename,
)
if upload && upload.present? && upload.persisted?
html = @uploader.html_for_upload(upload, original_filename)
s = s + "\n\n#{html}\n\n" unless s.gsub!(get_xf_regexp(xf_type, id), html)
else
STDERR.puts "Konnte Upload nicht verarbeiten: #{original_filename}. Überspringe Anhang-ID #{id}"
end
end
s
end
def import_xf_attachment(data_id, file_hash, owner_id, original_filename)
current_filename = "#{data_id}-#{file_hash}.data"
path = Pathname.new(ATTACHMENT_DIR + "/#{data_id / 1000}/#{current_filename}")
new_path = path.dirname + original_filename
upload = nil
if File.exist? path
FileUtils.cp path, new_path
upload = @uploader.create_upload owner_id, new_path, original_filename
FileUtils.rm new_path
else
STDERR.puts "Konnte Datei #{path} nicht finden. Überspringe Anhang-ID #{data_id}"
end
upload
end
def get_xf_regexp(type, id = nil)
case type
when :gallery
Regexp.new(/\[GALLERY=media,\s#{id ? id : '(\d+)'}\].+?\]/i)
when :attachment
Regexp.new(%r{\[ATTACH(?>=\w+)?\]#{id ? id : '(\d+)'}\[/ATTACH\]}i)
end
end
def get_xf_sql(type, id)
case type
when :gallery
<<-SQL
SELECT m.media_id, m.media_title, a.attachment_id, a.data_id, d.filename, d.file_hash, d.user_id
FROM xengallery_media AS m
INNER JOIN #{TABLE_PREFIX}attachment a ON (m.attachment_id = a.attachment_id AND a.content_type = 'xengallery_media')
INNER JOIN #{TABLE_PREFIX}attachment_data d ON a.data_id = d.data_id
WHERE media_id = #{id}
SQL
when :attachment
<<-SQL
SELECT a.attachment_id, a.data_id, d.filename, d.file_hash, d.user_id
FROM #{TABLE_PREFIX}attachment AS a
INNER JOIN #{TABLE_PREFIX}attachment_data d ON a.data_id = d.data_id
WHERE attachment_id = #{id}
AND content_type = 'post'
SQL
end
end
def mysql_query(sql)
@client.query(sql, cache_rows: false)
end
end
ImportScripts::XenForo.new.perform
Bitte zusammenführen, jemand vom Discourse-Team.
Danke.
Sie müssen mariadb mit service mariadb start starten
Ich habe einen Rewrite versucht, um die Links von XenForo nicht unbrauchbar zu machen. Hier ist das Ergebnis.
Um einen permanenten Rewrite zu schreiben, habe ich die folgende Hilfe verwendet: Set up Let’s Encrypt with multiple domains / redirects sowie die von @pfaffman
hooks:
...
after_ssl:
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: /#\s*auth_basic_user_file\s*.*;/
to: |
# auth_basic_user_file /etc/nginx/htpasswd;
location /threads/ {
rewrite ^/threads/(.*)\.\d+/?$ /t/$1 permanent;
}
Hast du also ein XenForo-Plugin, das deine URLs anders aussehen lässt als threads/#{m[\"topic_id\"]}?
Was du wirklich tun wolltest (oder wolltest) war, dies zu ändern:
um den Permalink zu erstellen, der deine Slug (falls du eine hast) anstelle der XenForo topic_id (oder vielleicht zusätzlich zu ihr) enthält.
Entschuldigung, aber ich kann Ihnen im Moment nicht ganz folgen. XenForo-URLs sehen so aus:
https://TDL/threads/THREADNAME.THREADID
und dann lasse ich die Weiterleitung zur URL von Discourse weiterleiten:
https://TDL/t/THREADNAME
Ich habe dies jetzt mit mehr als einem Dutzend Links versucht und es funktioniert immer ohne Probleme.
Ich verstehe den Mapping-Teil nicht, was macht das?
Ich interessiere mich für Links, die auf anderen Websites gepostet wurden, und wenn der Besucher jetzt auf das Forum kommt, wird kein 404 angezeigt.
Was ich beim Import auch nicht ganz verstanden habe: Warum werden Kategorien ab der 3. Ebene in Tags umgewandelt und nicht weiter Unterkategorien erstellt?
Wenn die eingehenden Links die Thread-ID enthalten, müssen Sie nur die Einstellung permalink_normalization korrigieren.
Discourse hat nur zwei Ebenen von Kategorien (eigentlich stimmt das jetzt nur so ungefähr), daher verwendet das Skript Tags für die Unter-Unterkategorien.
aber die ID aus dem Import ist anders als die ID davor
Wenn du /threads/ALT-THREAD-ID versuchst, landest du beim richtigen Thema.
Wenn du dir /admin/customize/permalinks ansiehst, wirst du sehen, dass es für alle Permalinks gibt, die zum richtigen Thema weiterleiten. Aber da ich verstanden habe, dass deine alten URLs keine Themen-ID enthielten, habe ich dir mit deiner gewünschten Lösung und nicht mit der richtigen geholfen.
Auf jeden Fall hast du die Lösung bekommen, die du wolltest.
dann muss ich es mir nochmal ansehen, weil es am Anfang nicht wirklich funktioniert hat.
Danke für die Erklärung
Es ist ziemlich verwirrend, und die permalink_normalization zu verstehen, ist besonders schwer nachzuvollziehen.
Wenn ich einen zweiten Import durchführe, wird dann eine Delta-Aktualisierung importiert oder werden die Threads dupliziert?
Wenn Sie das Skript erneut ausführen, werden nur die Elemente importiert, die noch nicht importiert wurden. Wenn Sie eine neuere Datenbank mit neuen Benutzern und Beiträgen haben, ist dies großartig. Wenn Sie das Skript so modifiziert haben, dass es beim Importieren der Benutzer und Beiträge etwas anderes tut, bedeutet dies, dass Sie alles löschen und mit einer leeren Website beginnen müssen.
Beim Delta-Import trat dann folgender Fehler auf:
importing private messages...
Topic ID 0 not found, skipping post 1 from 24
1 / 120735 ( 0.0%) [250209 items/min] Topic ID 0 not found, skipping post 2 from 3
...
5800 / 120735 ( 4.8%) [38592 items/min] Topic ID 0 not found, skipping post 5854 from 1822
5801 / 120735 ( 4.8%) [38598 items/min] /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/php_serialize-1.2/lib/php_serialize.rb:315:in `do_unserialize': Unable to unserialize type '{' (TypeError)
raise TypeError, "Unable to unserialize type '#{type}'"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/php_serialize-1.2/lib/php_serialize.rb:214:in `unserialize'
from script/import_scripts/xenforo.rb:350:in `block (2 levels) in import_private_messages'
from /var/www/discourse/script/import_scripts/base.rb:548:in `block in create_posts'
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/mysql2/alias_method.rb:8:in `each'
from /var/www/discourse/script/import_scripts/base.rb:547:in `create_posts'
from script/import_scripts/xenforo.rb:326:in `block in import_private_messages'
from /var/www/discourse/script/import_scripts/base.rb:948:in `block in batches'
from <internal:kernel>:187:in `loop'
from /var/www/discourse/script/import_scripts/base.rb:947:in `batches'
from script/import_scripts/xenforo.rb:315:in `import_private_messages'
from script/import_scripts/xenforo.rb:46:in `execute'
from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
from script/import_scripts/xenforo.rb:559:in `<main>'
root@rpgforen-app:/var/www/discourse#