# Migrate a vBulletin 4 forum to Discourse

**URL:** <https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881>\
**Category:** Sysadmins\
**Tags:** how-to\
**Created:** [28.Декабрь.2016 14:59:29 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881 "2016-12-28T14:59:29Z")\
**Posts on this page:** 20\
**Page:** 9

<div class="post-metadata">

**Author:** ![taravasya](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/taravasya/32/214539_2.png) [@taravasya](https://meta.discourse.org/u/taravasya)\
**Post date:** [27.Июль.2024 22:56:17 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/177 "2024-07-27T22:56:17Z")

</div>

Привет. Просто хочу поделиться своим решением.

Что касается проблем с кавычками. Как я уже говорил, я сталкивался с проблемами — регулярное выражение не захватывало кавычки, когда:

- имя пользователя и ID поста могли быть заключены в двойные кавычки
- были вложенные кавычки

Я решил выполнить поиск и замену с использованием другой логики. Вместо поиска тегов и их содержимого я использовал регулярное выражение, которое ищет **только теги** :

было:  
` raw.gsub!(%r{\[quote="?([^;]+);(\d+)"?\](.+?)\[\/quote\]}im) do`

 ![image](https://global.discourse-cdn.com/meta/original/4X/3/4/7/347dbb3650251efb12bdc9680b24b96ec91b9264.png)

стало:  
` raw.gsub!(%r{(\[QUOTE(="?([^;]+);(\d+)"?)?\])|(\[\/QUOTE\])}im) do`

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/4/0/140429e87f9779262c555cda18c9092336f9bf6b.png)

а затем немного изменил определение источника цитаты:

```plaintext
      if $3 && $4
        if topic_lookup = topic_lookup_from_imported_post_id(post_id)
          post_number = topic_lookup[:post_number]
          topic_id = topic_lookup[:topic_id]
          "\n[quote=\"#{new_username},post:#{post_number},topic:#{topic_id}\"]\n"
        else
          "\n[quote=\"#{new_username}\"]\n"
        end
      elsif $5
        "\n[/quote]\n"        
      end

```

Также я изменил код для спойлеров. Вместо:

```plaintext
    # [spoiler=Some hidden stuff]SPOILER HERE!![/spoiler]
    raw.gsub!(%r{\[spoiler="?(.+?)"?\](.+?)\[/spoiler\]}im) do
      "\n#{$1}\n[spoiler]#{$2}[/spoiler]\n"
    end

```

который размывал текст, я конвертировал его в тег details:

```plaintext
    raw.gsub!(%r{(\[spoiler(="?(.*?)"?)?\])|(\[\/spoiler\])}im) do
      if $3
        "\n[details=#{$3}]\n"
      elsif $1
        "\n[details]\n"
      elsif $4
        "\n[/details]\n"
      end
    end

```

Дело в том, что в мире vBulletin спойлер — это не размытый контент, а скорее свернутый. Поэтому я считаю, что для скрипта импорта из vBulletin гораздо уместнее конвертировать спойлеры в details, а не в размытый спойлер.

Я также заметил тег упоминаний. В моем случае в vBulletin упоминания выглядели так:  
[mention=XXX]username[/mention]

Регулярное выражение, используемое в скрипте, не учитывает, что тег может содержать ID пользователя.

```plaintext
    # [MENTION]<username>[/MENTION]
    raw.gsub!(%r{\[mention\](.+?)\[/mention\]}i) do
      new_username = get_username_for_old_username($1)
      "@#{new_username}"
    end

```

Я исправил это по-своему:

```plaintext
    # [MENTION]<username>[/MENTION]
    raw.gsub!(%r{\[mention(=\d+)?\](.+?)\[/mention\]}i) do
      new_username = get_username_for_old_username($2)
      "@#{new_username}"
    end

```

---

<div class="post-metadata">

**Author:** ![elmuerte](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/elmuerte/32/456517_2.png) [@elmuerte](https://meta.discourse.org/u/elmuerte)\
**Post date:** [14.Декабрь.2024 12:20:59 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/178 "2024-12-14T12:20:59Z")

</div>

> [@enigmaty](#):
>
> Скрипт vBulletin совместим с vBulletin 3

Это не соответствует действительности, когда я начал миграцию своего 24-летнего форума vBulletin, работающего на vB 3. Скрипт имел множество несовместимостей и других проблем. Однако я приложил много усилий для создания импортера для vBulletin 3 на основе скрипта для vB4.

[Улучшенный скрипт включен в Discourse](https://github.com/discourse/discourse/blob/main/script/import_scripts/vbulletin3.rb), он называется `vbulletin3.rb`. Использование скрипта импорта vB3 такое же, как описано в этом руководстве. Просто выполните `bundle exec ruby script/import_scripts/vbulletin3.rb` вместо этого.

В vBulletin3 есть несколько значительных изменений/улучшений:

1. Копируются права доступа к форумам
2. Создаются группы модераторов форумов
3. Создаются группы пользователей, в которые можно вступить, с правильной конфигурацией
4. Вложенность форумов импортируется до 3 уровней в глубину (максимум для Discourse)
5. Для всех тем и сообщений регистрируются постоянные ссылки, предотвращая потерю ссылок
6. Копируются некоторые базовые настройки форумов (например, заголовок, email для уведомлений, название компании)
7. Импортируются опросы
8. Значительные улучшения в конвертации bbcode в markdown
9. Глубокие ссылки на темы, сообщения и вложения преобразуются в ссылки Discourse; для этого необходимо установить переменную окружения `FORUM_URL` в значение `forum.hostname/path` (без протокола).

Вместо попытки конвертировать личные сообщения vBulletin в личные сообщения Discourse пользователи получат системное личное сообщение, содержащее архив их личных сообщений. Структура личных сообщений в vBulletin не совсем совместима с Discourse. Попытка их конвертации также могла бы нарушить конфиденциальность в зависимости от того, как люди использовали личные сообщения в vBulletin.

Как и в случае с другими импортерами, конвертация может занять довольно много времени. Скрипт конвертации работал 5,5 часов на моей рабочей станции для 7 тысяч пользователей, 16 тысяч тем и 415 тысяч сообщений. Я не знаю, сколько времени заняла постобработка — я оставил её работать на ночь. С момента начала до конца форум был недоступен в течение 30 часов. В итоге я доволен [результатом](https://forum.magicball.net/).

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [14.Декабрь.2024 12:34:38 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/179 "2024-12-14T12:34:38Z")

</div>

> [@elmuerte](#):
>
> В конце концов я доволен [результатом](https://forum.magicball.net/).

Вот это ностальгия 🙂

![](https://media.tenor.com/DZ93fcHp1GgAAAAC/twinsen-lba.gif)

Ваш форум выглядит очень приятно. Мне нравится чередование цветов в строках тем.

---

<div class="post-metadata">

**Author:** ![dahamsta](https://avatars.discourse-cdn.com/v4/letter/d/e56c9b/32.png) [@dahamsta](https://meta.discourse.org/u/dahamsta)\
**Post date:** [07.Май.2025 11:47:16 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/180 "2025-05-07T11:47:16Z")

</div>

Похоже, что и эта тема, и инструмент импорта уже давно устарели. С помощью этой темы я решил несколько проблем, но теперь застрял на этапе импорта пользователей с следующей ошибкой. Кто-нибудь знает, как это исправить?

`<internal:timev>:286:in `at’: can’t convert NilClass into an exact number (TypeError)`

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [07.Май.2025 13:16:13 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/181 "2025-05-07T13:16:13Z")

</div>

Либо запрос составлен неверно, либо в таблице отсутствует значение.

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [06.Август.2025 18:58:24 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/182 "2025-08-06T18:58:24Z")

</div>

> [@wishspinner](#):
>
> Да, довольно много ошибок типа «Файл вложения не существует» с некоторыми вкраплениями «Не удалось найти запись вложения для post.id=xxx, import\_id=xxx».

Довольно странно отвечать на это спустя столько лет, но сейчас я выполняю импорт из VB с помощью массового импортера, и оказалось, что многие изображения отсутствуют. Причина в том, что имя файла вложения было перемещено в другое поле.

```plaintext
 SELECT a.filedataid attachment_id, a.userid user_id, a.filename filename
             FROM attachment a
            WHERE a.attachmentid = 383075;

```

Теперь поле `NUMBER.attach` соответствует полю `filedataid`, а не полю `attachment_id`. Поэтому этот запрос нужно обновить в скрипте.

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [31.Октябрь.2025 19:18:21 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/183 "2025-10-31T19:18:21Z")

</div>

Мне поручили мигрировать форум vBulletin 4.25 на Discourse… Чтение этой ветки вызывает смешанные чувства… Похоже, это возможно, но потенциально это огромная головная боль и трата времени (чего я бы сейчас хотел избежать)…

Неужели нигде нет обновлённого скрипта для vBulletin 4.25? На официальной странице я вижу только версии 3 и 5?

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [31.Октябрь.2025 19:36:51 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/184 "2025-10-31T19:36:51Z")

</div>

Что ж, в директории [массового импорта](https://github.com/discourse/discourse/tree/main/script/bulk_import) находятся скрипты `vbulletin` и `vbulletin5`, которым всего несколько месяцев. Запуск таких массовых импортов довольно сложен и плохо документирован.

Я выполнил более 100 импортов и уверен, что ни один из них не обошёлся без доработки скрипта по той или иной причине.

Я писал несколько скриптов импорта ещё до того, как по-настоящему выучил Ruby (но один профессор в середине 1980-х заверил меня, что после его курса «Языки программирования» я смогу сказать, что знаю любой язык, если у меня есть выходные и книга; он был в основном прав).

Но да, скорее всего, это будет не менее болезненным и затратным по времени, чем вы предполагаете.

Я подозреваю, что скрипт для vbulletin справится вполне достойно; я бы не рекомендовал использовать скрипт массового импорта, если у вас нет более миллиона постов и пользователей.

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [31.Октябрь.2025 21:02:34 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/185 "2025-10-31T21:02:34Z")

</div>

Спасибо за это 🙂

Кажется, мне нужно решить, чем я буду заниматься в эти выходные 😃

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [06.Ноябрь.2025 19:36:41 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/186 "2025-11-06T19:36:41Z")

</div>

Я был бы очень признателен за помощь с этим 😵‍💫

Я прочитал всю ветку и выполнил несколько шагов, которые здесь видел, но застрял.

1. Подключаюсь по SSH к моему VPS
2. Захожу в образ Docker
3. Устанавливаю mariadb-server
4. Пытаюсь выполнить команду mysql для создания базы данных, но получаю ошибку: ‘can’t connect to local server through socket’

Инструкции здесь датированы несколькими годами назад — я видел, что несколько человек столкнулись с той же ошибкой, но не нашёл решений.

Кто-нибудь выполнял этот процесс недавно и может указать правильное направление? Не думаю, что где-то упускаю пошаговое руководство, верно?

Редактирование: добавлю, что я перепробовал всевозможные ухищрения и в итоге установил образ Docker с MariaDB на локальный хост (не в Docker), после чего открыл порт. Теперь я могу подключиться к базе данных из образа Docker… но при запуске скрипта возникает ошибка: `Gemfile`: Undefined local variable or method `mysql2`. Я пытался установить gem, но это не удаётся… И прежде чем углубляться в устранение неполадок, у меня возникает ощущение, что я использую устаревшую информацию и, возможно, старые пакеты… Я просто очень запутался и мне нужна помощь!

Любая помощь будет оценена!

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [06.Ноябрь.2025 22:47:53 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/187 "2025-11-06T22:47:53Z")

</div>

…Я продолжил и в итоге добрался до запуска скрипта! Однако после начала выполнения он завершается с ошибкой:

```plaintext
"root@vps-xxxxxxxx-app:/var/www/discourse/script/import_scripts# bundle exec ruby vbulletin.rb
/var/www/discourse/config/initializers/013-excon_defaults.rb:4:in `<main>': can't modify frozen Hash: {:chunk_size=>1048576, :ciphers=>"ECDHE-ECDSA- [................]"

```

…и, кажется, я исчерпал свои возможности по устранению неполадок.

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [07.Ноябрь.2025 17:45:17 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/188 "2025-11-07T17:45:17Z")

</div>

Не знаю, имеет ли значение запуск из `/var/www/discourse`, но я всегда делаю именно так. Вот что рекомендуется в первом сообщении.

> [@enigmaty](#):
>
> ```plaintext
> su discourse -c 'bundle exec ruby script/import_scripts/vbulletin.rb'
> 
> ```

> [@tom1984](#):
>
> …и, кажется, я достиг предела своих возможностей по устранению неполадок

Мне не знакома эта ошибка.

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [07.Ноябрь.2025 17:49:16 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/189 "2025-11-07T17:49:16Z")

</div>

> [@pfaffman](#):
>
> Я не узнаю эту ошибку.

К тому моменту, когда я вчера вечером сдался после часов «исследований», я так много экспериментировал с вещами вне моей зоны комфорта, что начал беспокоиться: не причиняю ли я больше вреда, чем пользы. Мне также очень хотелось узнать, делал ли кто-то это недавно и есть ли какой-то волшебный шаг, который я упустил, вместо того чтобы снова погружаться в повторяющиеся кроличьи норы 😜

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [07.Ноябрь.2025 20:19:40 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/190 "2025-11-07T20:19:40Z")

</div>

Возможно, возникла какая-то новая проблема. На днях я импортировал файл mbox и, думаю, это задействовало тот же код, который вызвал у вас ошибку.

> [@enigmaty](#):
>
> Настройте среду разработки, следуя инструкциям для [Ubuntu](https://meta.discourse.org/t/beginners-guide-to-install-discourse-on-ubuntu-for-development/14727) (или используйте [Vagrant](https://github.com/discourse/discourse/blob/master/docs/VAGRANT.md), если вы работаете на Mac или ПК).

Ах, я сделал это в контейнере, а эти инструкции предназначены для среды разработки. Вы настраивали среду разработки? Удалось ли вам запустить всё? Это непросто сделать через VPN.

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [07.Ноябрь.2025 20:27:58 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/191 "2025-11-07T20:27:58Z")

</div>

Сегодня у меня мигрень, поэтому я удалю всё и попробую снова завтра.

Дам знать, как всё пройдёт 🙂

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [07.Ноябрь.2025 20:29:16 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/192 "2025-11-07T20:29:16Z")

</div>

Вы настроили среду разработки? Это был ваш первый шаг?

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [07.Ноябрь.2025 20:33:14 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/193 "2025-11-07T20:33:14Z")

</div>

Я пробовал сделать это через хост-сервер VPS, а позже пытался исправить всё через контейнер. К тому моменту, как я закончил, я уже не был уверен, что и где именно делал. Скорее всего, это проблема моих навыков… Завтра я начну всё заново с чистого листа.

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [07.Ноябрь.2025 22:49:28 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/194 "2025-11-07T22:49:28Z")

</div>

Если вы делаете это на виртуальной машине, то использование контейнера, скорее всего, будет проще. Я бы посмотрел другие примеры инструкций по импорту (в них будет шаблон MySQL).

Вы зайдёте в контейнер, возможно, отредактируете файл Gem и выполните bundle install.

Использование контейнера для MySQL или MariaDB, вероятно, имеет смысл (но тогда нужно убедиться, что контейнеры видят друг друга).

---

<div class="post-metadata">

**Author:** ![tom1984](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom1984/32/528342_2.png) [@tom1984](https://meta.discourse.org/u/tom1984)\
**Post date:** [08.Ноябрь.2025 11:41:04 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/195 "2025-11-08T11:41:04Z")

</div>

У меня есть отличная новость…

Скрипт работает (я составлю руководство, когда всё будет готово), он импортировал группы пользователей, но застрял на импорте самих пользователей. Думаю, дело в переменной часового пояса?

```plaintext
importing users
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/tzinfo-2.0.6/lib/tzinfo/timestamp.rb:138:in `for': Integer values are not supported (ArgumentError)

            raise ArgumentError, "#{value.class} values are not supported" unless is_time_like?(value)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/tzinfo-2.0.6/lib/tzinfo/timezone.rb:575:in `utc_to_local'
        from script/import_scripts/vbulletin.rb:1019:in `parse_timestamp'
        from script/import_scripts/vbulletin.rb:166:in `block (2 levels) in import_users'
        from /var/www/discourse/script/import_scripts/base.rb:267:in `block in create_users'
        from /var/www/discourse/script/import_scripts/base.rb:266:in `each'
        from /var/www/discourse/script/import_scripts/base.rb:266:in `create_users'
        from script/import_scripts/vbulletin.rb:148:in `block in import_users'
        from /var/www/discourse/script/import_scripts/base.rb:951:in `block in batches'
        from <internal:kernel>:187:in `loop'
        from /var/www/discourse/script/import_scripts/base.rb:950:in `batches'
        from script/import_scripts/vbulletin.rb:126:in `import_users'
        from script/import_scripts/vbulletin.rb:82:in `execute'
        from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
        from script/import_scripts/vbulletin.rb:1027:in `<main>'

```

В скрипте по умолчанию указано «America/Los Angeles». Форум vBulletin настроен на (GMT) Западноевропейское время (Лондон, Лиссабон, Касабланка), а в экземпляр Discourse, в который я импортирую данные, добавлены два часовых пояса: America/Los Angeles и Europe/Paris.

Подскажите, какой из них выбрать?

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [08.Ноябрь.2025 12:39:50 UTC](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881/196 "2025-11-08T12:39:50Z")

</div>

Не так важно, что именно вы выберете.

Думаю, проблема в том, что дата хранится не так, как ожидает скрипт.

[Предыдущая страница](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881.md?page=8)

[Следующая страница](https://meta.discourse.org/t/migrate-a-vbulletin-4-forum-to-discourse/54881.md?page=10)
