Error importing from vanilla: invalid byte sequence in UTF-8

I’m trying to import from a Vanilla forum using the instructions posted here. However, I get the following error when I run the vanilla.rb import script:

Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...
parsing file...
reading file...
Traceback (most recent call last):
	5: from script/import_scripts/vanilla.rb:254:in `<main>'
	4: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
	3: from script/import_scripts/vanilla.rb:17:in `execute'
	2: from script/import_scripts/vanilla.rb:37:in `parse_file'
	1: from script/import_scripts/vanilla.rb:72:in `read_file'
script/import_scripts/vanilla.rb:72:in `gsub': invalid byte sequence in UTF-8 (ArgumentError)

I’ve tried changing the MySQL database character set to UTF8 following the instructions here and then re-exporting the porter file, but that didn’t resolve the issue. Any suggestions?

You either need to keep trying to get it to really be UTF-8 or modify the import script to do it. It is a frustrating problem.

@dpkoch Вы когда-нибудь разобрались с этим?

Вы можете поискать информацию об кодировке UTF-8 в Google. Вам нужно сделать что-то, чтобы привести таблицу к кодировке UTF-8. В тот раз, когда я это делал, возникли дополнительные сложности, потому что некоторые строки были в одном формате, а другие — в другом. Кажется, я делал какую-то ерунду, приводя значения к нужному формату по отдельности.

Звучит ужасно… Придётся поэкспериментировать с кодировкой таблицы и посмотреть, что получится. Спасибо!

Ох. Это ужасно. Лучший совет, основанный на смутном воспоминании о единственном случае, когда я делал это более года назад, — перебрать как можно больше различных конвертаций, пока не найдёшь ту, которая подойдёт для всех или большинства данных. Я думаю, что я делал множество поочерёдных преобразований, которые оказались пустой тратой времени, пока не наткнулся на конвертацию, которая сработала для всех (большинства?) данных.

Вот что я делал. Используйте на свой страх и риск. (Кстати, это был vbulletin).

  def char_map(raw_original)
    raw = raw_original.dup
    debug = false # (raw.length > 50)

    # windows 1252
    all = ''
    win_encoded = ''

    ### Кодировка WIN1252
    win_encoded = ''
    begin
      win_encoded = raw.force_encoding('utf-8').encode("Windows-1252",
                            invalid: :replace, undef: :replace, replace: ""
                           ).force_encoding('utf-8').scrub
    rescue => e
      puts "\n#{'-'*50}\nWin1252 не сработал для \n\n#{raw}\n\n"
      win_encoded = ''
    end

    ### Кодировка ISO 8859
    iso_encoded = ''
    if all.length == 0 && win_encoded.length > 0 && win_encoded != raw
      all = (debug ? "Win1252--" : '') + win_encoded
    else
      all = raw
    end
    all = old_char_map(all)
    all
  end

Этот код используется в скрипте импорта или на стороне сервера/базы данных?

В скрипте импорта. Я не люблю лезть в базу данных.

Где-то вы вызываете эту функцию над raw, чтобы исправить raw (и, возможно, заголовки?).

Отлично, большое спасибо! Это даст мне огромный старт в отладке этого.

Нам удалось это исправить, добавив простую команду для кодирования файла в UTF-8 при чтении, используя что-то вроде encode"UTF-8" в строках 76–80 скрипта импорта vanilla.rb.

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

Вот что он использовал для исправления этого, начиная со строки 76 файла vanilla.rb

def read_file
  puts "чтение файла..."
  string = [File.read](http://file.read/)(@vanilla_file)
    .force_encoding('UTF-8').encode("UTF-8").gsub("\\N", "")
    .force_encoding('UTF-8').encode("UTF-8").gsub(/\\$\n/m, "\\n")
    .force_encoding('UTF-8').encode("UTF-8").gsub("\\,", ",")
    .force_encoding('UTF-8').encode("UTF-8").gsub(/(?<!\\)\\"/, '""')
    .force_encoding('UTF-8').encode("UTF-8").gsub(/\\\\\\"/, '\\""')
  [StringIO.new](http://stringio.new/)(string)
end

Это не работает. Та же ошибка.

Вам нужно погуглить информацию о кодировке и разобраться, как исправить проблему с повреждённой кодировкой.

Привет, @ddeveloper,

Я проходил этот процесс всего пару месяцев назад (и я не разработчик :slightly_smiling_face:) и успешно мигрировал самодостаточный форум Vanilla на самодостаточный Discourse. Ключевым моментом для меня было убедиться, что при экспорте данных с помощью Vanilla Porter в первом выпадающем меню выбран тип исходного форума «Vanilla 2».

Я использовал версию Vanilla Porter 2.6, доступную для загрузки в виде zip-файла здесь: Vanilla Porter 2.6 RC1 — Vanilla Forums, вместо версии 2.5, ссылки на которую есть в Migrate a Vanilla forum to Discourse.

Если я правильно помню, при использовании более нового скрипта Vanilla Porter и типа форума «Vanilla 2» ошибка UTF-8 больше не возникала.

Если эти два совета не помогут при вашем импорте, пожалуйста, предоставьте несколько деталей о выполненных вами шагах и о том, что именно вы видите. Иногда незначительные различия в «одной и той же ошибке» могут иметь большое значение при устранении неполадок.

Я следовал той же инструкции, но использовал версию Porter 2.6. Я экспортирую файл из версии 2.6 и обновлю информацию здесь.

Хорошо, я попробовал Porter 2.6, и это привело к той же ошибке UTF-8:

На данный момент я следовал этому руководству: Migrate a Vanilla forum to Discourse

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

Я также попробовал решение от @Nick_Chomey, упомянутое выше: попытку принудительно установить кодировку UTF-8 при чтении txt-файла, но, к сожалению, это тоже не помогло.

Для уверенности, какой Тип исходного форума вы выбрали в выпадающем меню Vanilla Porter?

Можете сообщить, какой компьютер вы используете? Инструкция по конвертации вашего файла в кодировку UTF-8 будет зависеть от этого.

Спасибо, что нашли время помочь коллеге-дискурсеру.

Я выбрал «Vanilla 2» в поле Source Forum Type.

У меня есть доступ как к устройствам на базе Windows, так и к устройствам на базе Linux.