Zwei Discourse-Seiten zu einer zusammenführen

\u003cdiv data-theme-toc="true"\u003e \u003c/div\u003e

Wenn Sie zwei Discourse-Seiten haben, die Sie gerne zu einer zusammenführen möchten, ist diese Anleitung für Sie.

Es gibt ein Tool namens discourse_merger, das eine Discourse-Seite nehmen und in eine andere zusammenführen kann.

Voraussetzungen

Dies ist keine einfache Aufgabe und sollte wie jede andere Migration zu Discourse behandelt werden. Sie werden discourse_merger nicht auf einer Live-Produktionsseite ausführen. Sie führen die Zusammenführung in einer anderen Umgebung durch, in der Sie die Ausgabe überprüfen können, bevor Sie das Ergebnis in die Produktion verschieben.

Kopieren vs. Zusammenführen

Fast alles wird von einer Seite auf die andere kopiert, aber Kategorien und Benutzer können zusammengeführt werden, was Duplizierung vermeidet.

  • Benutzer werden zusammengeführt, wenn ein Benutzer auf beiden Seiten dieselbe E-Mail-Adresse hat.
  • Kategorien werden zusammengeführt, wenn sie denselben Namen haben.

Wenn Sie eine Umstrukturierung Ihrer Daten wünschen, tun Sie dies vor dem Zusammenführen.

Wählen Sie die Zielseite

Wählen Sie aus, welche Seite das Ziel für die Daten sein wird. Dies ist die Seite, die ihr gesamtes Styling und alle Einstellungen beibehält. Die andere Seite wird ihre Benutzer, Kategorien, Themen, Beiträge, Uploads usw. auf die Zielseite kopiert/zusammengeführt bekommen.

Wie man es macht

Erstellen Sie Backups beider Seiten einschließlich Dateien und kopieren Sie diese in die Umgebung, in der Sie die Zusammenführung durchführen werden. Es ist möglich, dass sie von verschiedenen Versionen von Discourse stammen, daher müssen sie auf dieselbe Version gebracht werden. Ich würde empfehlen, für die Zusammenführung die neueste Version von Discourse zu verwenden.

Stellen Sie die Zielseite in der Merger-Umgebung wieder her. Wenn Sie dies über die Befehlszeile tun:

bundle exec ruby script/discourse restore destination-2018-08-02-134227-v2018xxx.tar.gz

Als Nächstes entpacken wir die andere Seite.

cd /path/to/data
tar xvzf other-2018-08-02-134227-v2018xxx.tar.gz

Die Ausgabe enthält den Datenbank-Dump und die Upload-Dateien.

Erstellen Sie eine Datenbank mit den Daten:

psql
CREATE DATABASE "copyme" ENCODING = 'utf8';
\q
gunzip < /path/to/data/other-2018-08-02-134227-v2018xxx.tar.gz | psql -d copyme

Wenn Sie den Import in einem offiziellen Docker-Container durchführen (empfohlen), müssen Sie das postgres-Passwort zurücksetzen, um es dem Skript zur Verfügung zu stellen, da es sonst zu einem Fehler kommen kann, dass der Benutzer postgres nicht auf die Datenbank zugreifen kann.

Um das Passwort zu ändern:

sudo -u postgres psql
\password postgres
(neues Passwort eingeben)
\q

Jetzt ist es Zeit, das Skript auszuführen. Einige Umgebungsvariablen, die Sie festlegen werden:

DB_NAME: Name der Datenbank, die in die Zielseite zusammengeführt wird.
DB_HOST: (optional) Hostname der zusammenzuführenden Datenbank. Leer lassen, wenn sie lokal ist.
DB_PASS: Passwort für den Benutzer postgres für den Zugriff auf die Datenbank
UPLOADS_PATH: Absoluter Pfad (der zusammenzuführenden Seite) des Verzeichnisses, das die Verzeichnisse „original“ und „optimized“ enthält. z.B. /path/to/data/uploads/default
SOURCE_BASE_URL: Basis-URL der zusammenzuführenden Seite. z.B. https://meta.discourse.org
SOURCE_CDN: (optional) Basis-URL des CDN der zusammenzuführenden Seite.

Möglicherweise müssen Sie vor der Ausführung des Importskripts ein bundle install ausführen, um Fehler zu vermeiden. Tun Sie dies mit:

su discourse -c 'bundle config set --local with generic_import && bundle install'

Beim ersten Lauf müssen Sie möglicherweise einige zusätzliche Abhängigkeiten für die im Import benötigten Gems installieren.

Sobald das Bundle abgeschlossen ist, führen Sie den Import aus.

su discourse -c 'DB_NAME=copyme DB_PASS=password SOURCE_BASE_URL=http://copy.othersite.com UPLOADS_PATH=/shared/import/data/uploads/default bundle exec ruby script/bulk_import/discourse_merger.rb'

Wenn es fertig ist, überprüfen Sie die Ausgabe in einem Webbrowser.

Sie können das remap-Tool verwenden, um Links vom alten Forum zu aktualisieren.

bundle exec ruby script/discourse remap 'copy.othersite.com' 'hot.newsite.com'

Backen Sie auch alle Beiträge mit Uploads neu:

rake posts:rebake_match["upload:"]

Wenn alles gut aussieht, erstellen Sie ein Backup des Ergebnisses und stellen Sie es auf Ihrem Produktionsserver wieder her.

bundle exec ruby script/discourse backup
45 „Gefällt mir“

Es scheint zu funktionieren, aber wenn ich ein Backup ausführe, erhalte ich

pg_dump: error: query failed: ERROR:  permission denied for table migration_mappings

Das ist sehr seltsam.

EDIT: gelöst mit

ALTER USER discourse WITH SUPERUSER;
1 „Gefällt mir“

Hat jemand das kürzlich benutzt? Wie ist es gelaufen?

Außerdem weiß jemand, ob es möglich ist, Benutzer automatisch einer Gruppe für jedes Herkunftsforum zuzuweisen? (Um es ihnen zu erleichtern, Berechtigungen zum Anzeigen der Themen aus den Foren, aus denen sie stammen, zu erteilen.)

Es war etwas holprig. Ich glaube, ich musste einiges auskommentieren. Es gab auch ein Problem mit den Merger-Bildern.

Ich würde alle Benutzer der neuen Website zu einer Gruppe hinzufügen, damit sie in dieser Gruppe sind, wenn Sie sie zusammenführen. Das wäre einfacher, als es danach oder als Teil der Zusammenführung zu tun.

2 „Gefällt mir“

Beim letzten Mal, als ich das gemacht habe, fehlten alle Uploads von der zusammengeführten Website. Ich habe eine Liste der Uploads aus tar tf backupfile.tar.gz erhalten, sie in allfiles.txtx eingefügt und sie in das Upload-Verzeichnis kopiert. Dieses Skript (das wahrscheinlich ohne Anpassung für Sie nicht funktioniert) hat für jede dieser Dateien einen Upload erstellt, und dann hat das erneute Backen der Beiträge alle (oder die meisten?) fehlenden Bilder behoben.

def process_uploads
  begin
    # Lies die Liste der Dateinamen
    filenames = File.readlines('/shared/uploads/allfiles.txt').map(&:strip)
    count = 0

    filenames.each do |filename|
      # Füge /shared am Anfang des Dateinamens ein
      filename.gsub!(/\.\//,"")
      full_path = File.join('/shared/uploads/default/original/', filename)

      begin
        # Prüfe, ob der Pfad existiert und eine reguläre Datei ist (kein Verzeichnis)
        count += 1
        
        if File.exist?(full_path) && File.file?(full_path)
          # Öffne die Datei
          File.open(full_path, 'r') do |tempfile|
            # Erstelle einen Upload mit den angegebenen Parametern
            u = UploadCreator.new(tempfile, 'imported', {}).create_for(-1)
            puts "#{count} -- #{u.id}: #{u.url}"
          end
        else
          puts "Warnung: Pfad nicht gefunden oder keine reguläre Datei: #{full_path}"
        end
      rescue => e
        puts "Fehler bei der Verarbeitung der Datei #{full_path}: #{e.message}"
        # Fahre mit der nächsten Datei fort, auch wenn die aktuelle fehlschlägt
        next
      end
    end
  rescue Errno::ENOENT
    puts "Fehler: Konnte files.txt nicht finden"
  rescue => e
    puts "Fehler beim Lesen von files.txt: #{e.message}"
  end
end

# Führe die Verarbeitung aus
process_uploads;

Ich habe die fehlerhaften Beiträge wie folgt erhalten:

bad=Post.where("cooked like '%/images/transparent.png%'")

und dann dies, um sie als “rebake” zu markieren:

bad.update_all(baked_version: nil)

Ich war ungeduldig, also habe ich Folgendes verwendet:

rake posts:rebake_uncooked_posts

um sie erneut zu backen.

2 „Gefällt mir“

Ich frage mich, ob es nicht einfacher wäre, das Diskursforum, das ich zusammenführen möchte, in XenForo zu konvertieren (ihre Importer sind normalerweise ausgezeichnet), dann mit den anderen Foren zusammenzuführen, die Teil der Zusammenführung sein sollen (die selbst von vBulletin in XenForo konvertiert werden), und dann schließlich das neue zusammengeführte XenForo-Forum in Diskurs zu importieren.