История одного бага или почему OutWiker не использует последние версии wxPython
Пока идет подготовка очередной нестабильной версии OutWiker, я решил написать об одной проблеме, которая меня давно волнует и может стать серьезной проблемой в будущем.
Эту детективную историю начнем с представления действующих лиц. Для отображения страниц OutWiker использует движок Internet Explorer под Windows и WebKit под Linux. Программа OutWiker написана с использованием библиотеки wxPython, которая предоставляет доступ к этим движкам, причем для работы с WebKit используется компонент WebKitGTK+, который используется в таких не самых известных браузерах как Epiphany и Midori. wxPython может использовать разные версии WebKit, это зависит от того, какие пакеты установлены на компьютере, на котором происходит компиляция библиотеки. Если в системе установлен пакет libwebkit2gtk-4.0-dev (я буду использовать в названия пакетов в Ubuntu), то библиотека wxPython будет собрана с поддержкой более новой версии WebKit 2, а если этого пакета в системе нет, но установлен пакет libwebkitgtk-3.0-dev, то будет использоваться WebKit 1. Причем первая версия WebKit уже считается устаревшей и, например, в Arch Linux она не поддерживается, но все еще находится в репозиторях Ubuntu.
Когда только вышла 4-я версия wxPython с поддержкой Python 3.x (wxPython 4.0.0 и 4.0.1), то бинарные сборки этой библиотеки, которые можно скачать здесь, были собраны с использованием WebKit 1. Именно в этот момент мы с Владимиром Тубольцевым перевели OutWiker на Python 3.x и wxPython 4. И не было никаких проблем.
Проблемы возникли, когда вышла новая версия wxPython 4.0.2. Изменение номера в третьем знаке не сулило никаких проблем при обновлении, и я, ничего не подозревая начал ее использовать в программе. И даже была одна нестабильная сборка OutWiker с этой версией wxPython. Тогда мне стали писать пользователи с сообщениями о том, что новая сборка как-то странно себя ведет. Сразу при открытии программы она зачем-то запускает браузер и открывает отображаемую страницу в ней. Позже я заметил и более критичные проблемы — на странице не отображаются картинки из прикрепленных файлов, не грузятся скрипты JavaScript, необходимые для работы плагина TeXEquation, который предназначен для отображения формул. Причем проблемы проявлялись только в бинарных сборках, созданных в docker, а при запуске у себя на компьютере напрямую из исходников я проблем не наблюдал. Проблема исчезала, когда я откатывался к wxPython 4.0.1.
После недели экспериментов оказалось, что все дело в версии WebKit. У меня на компьютере не было установлено пакета libwebkit2gtk-4.0-dev, а поскольку библиотеку wxPython я собирал сам из исходников, то она была скомпилирована с поддержкой WebKit 1, а бинарные сборки wxPython, которые использовались в docker, теперь собираются с поддержкой WebKit 2.
О проблеме сообщил разработчикам wxPython (Issue #1071), но разработчики говорят: «Не можем повторить, сделай минимальный пример». Сделал короткий пример на 30 строчек. У меня 100% повторяемость — если установлен wxPython с поддержкой WebKit 1, то все работает, а если с поддержкой WebKit 2, то картинки не отображаются. А разработчики говорят: «У нас все нормально».
Время шло… Недавно вышла новая версия wxPython 4.0.4. Не сильно надеясь на чудо, я ее установил, чтобы убедиться, что проблема осталась. И тут случайно увидел странную вещь — на одной из страниц OutWiker с использованием WebKit 2 картинки отобразились, а на другой — нет. При более пристальном разглядывании оказалось, что картинки не отображаются в том случае, если в пути до страницы, есть русские буквы. Позже оказалось, что такая же проблема возникает, если в имени картинки есть русские буквы. Или обобщая все выше сказанное, в полном пути до картинок не должно быть русских букв. То же самое относится к путям до скриптов JavaScript и скорее всего до файлов CSS, то этого я уже не проверял.
Теперь понятно, почему англоязычные разработчики не смогли поймать баг, о котором я им писал. Бегу на github и добавляю комментарий о только что найденных уликах. На следующий день мне пишут, что да, проблема подтверждена. Это было перед Новым Годом. Я решил, что это будет хороший подарок к празднику, если проблему починят, обычно такие ошибки исправляют быстро.
Но я рано радовался. Через какое-то время мне пишут, что похоже проблема не в wxPython, а на более низком уровне — в самом WebKit 2, и вроде бы разработчик @swt2c даже сообщил, куда следует. Это уже не так радостно, потому что кто знает, когда ошибку исправят в самом WebKit, а тем более, когда исправленная версия появится в дистрибутивах.
После новогодних праздников я решил поискать сообщения об этой проблеме в интернете, может быть известны пути ее обхода. В процессе гугления наткнулся на сообщение в багтрекере WebKitGTK+ — Bug 184660. Некий французский пользователь в апреле прошлого года описал похожую проблему, но немного под другим углом зрения — не отображаются локальные файлы картинок, если путь до имеет неанглоязычные символы. К сожалению, разработчики WebKit как-то неохотно приняли сообщение об ошибке, ссылаясь на то, что может это виновата операционная система, что она неправильно интерпретирует путь до файла? Но потом вроде задумались, что проблемы может быть действительно есть, но пока этой проблемой никто не занялся.
Для эксперимента я установил браузер Epiphany и убедился, что проблема выявляется и в нем — он не отображает локальные файлы картинок, если в пути до них есть русскоязычные символы, о чем и написал в комментариях к ошибке. К сожалению, пока решения проблемы не появилось.
Это меня очень расстраивает, потому что мне хочется в OutWiker использовать более новую версию wxPython, потому что в ней исправлены некоторые другие, менее критичные проблемы, с которыми я столкнулся. Я даже сделал себе несколько docker-контейнеров, чтобы собирать более новые версии wxPython с использованием WebKit 1, но это сильно усложняет сборку OutWiker для неподготовленных пользователей и на сервере непрерывной интеграции. Ведь сейчас можно просто скачать сборку wxPython 4.0.1, которая работает с WebKit 1, но более новые сборки работают с WebKit 2. И тут надо либо каждый раз на сервере непрерывной интеграции собирать wxPython из исходников, а это у меня на компьютере занимает около 40-45 минут, либо один раз скомпилировать такую сборку где-то у себя и положить ее в исходники. Но такая сборка увеличит размер исходников более чем на 100 МБ, к тому же это будет сборка лишь под одну версию Ubuntu. Можно ее закачать себе на сайт, причем для разных версий Ubuntu, но не знаю, насколько обрадуется мой хостер, когда ежедневно с сайта будут скачиваться множество раз такие большие файлы. И это решит проблему только для Ubuntu, а, как я уже сказал, например, в Arch Linux в принципе уже нет поддержки WebKit 1.
Еще меня пугает то, что WebKit 1 считается устаревшим, и я не знаю, в какой момент пакет libwebkitgtk-3.0-dev уберут из репозиториев Ubuntu. Пока он существует. В этом плане большие надежды на формат snap, потому что его контейнеры собираются в Ubuntu 16.04, а в будущем это будет Ubuntu 18.04, в которых WebKit 1 еще присутствует. К тому же не известно, как долго будет поддерживать WebKit 1 сама библиотека wxPython.
На данный момент, если использовать WebKit 2 в OutWiker, то пропадает большая часть необходимой функциональности. Недавно я начал эксперименты по нахождению способа обхода проблемы с помощью символических ссылок, в путях к которым есть только англоязычные символы. Эксперимент почти удачный, но все равно не отображаются картинки, которые сами называются по-русски. Такие картинки можно обнаруживать в процессе работы и встраивать непосредственно в тело HTML-страницы с помощью кодирования base64, но уж очень мне не хочется идти на этот хак. К тому же позже я обнаружил и другие менее критичные проблемы, связанные с русскими буквами. Например, не работают ссылки со страницы на страницу, если ссылка оформлена не через идентификатор страницы (page://…), а по ее имени (/страница 1/страница 2/…) Недавно обнаружил и другие проблемы в WebKit 2, не связанные с русскими буквами, но те проблемы еще можно попытаться обойти.
На сегодня это все, что известно о данной ошибке. Посмотрим, как будет дальше развиваться ситуация. Ужасно не люблю проблемы со сторонними библиотеками, которые не можешь поправить сам. И этот ад с версиями библиотек. Все-таки будущее за контейнерными форматами типа snap / flatpak, если конечно не придумают способа иметь в системе множество библиотек разных версий.
PS. Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
BaNru:
А URL encode/decode не помогает в этом случае?
22 апреля 2019, 10:29 ппНа stackoverflow.com предлагают для этого urllib (urllib.quote and urllib.unquote)
https://docs.python.org/2/library/urllib.html
Jenyay:
К сожалению, нет. Такая ошибка возникает даже с кодированными путями. Я в тексте оставил ссылку на баг в WebKitGTK (https://bugs.webkit.org/show_bug.cgi?id=184660), там в изначальном посте ссылки уже закодированы.
22 апреля 2019, 11:31 ппBaNru:
Если есть сильное желание переехать на новый WebKitGTK+, то можно использовать в вебките файлы из временной папки (временную папку можешь сам выбрать /var/tmp или создать ~/.tmp). Перед рендером делать копию файла(ов) во временную папку и/или замену ссылок.
Из проблемы я не совсем понял:
1) ошибка только если страница содержит в пути не английские буквы и если они английские, то картинки с русскими буквами отображаются?
2) или ошибка в любых случаях, все русские буквы не принимает, то есть на англоязычной странице картинки с русскими буквами тоже не отображаются?
Если только первый вариант, то тут проще — достаточно только сам файл перемещать в TMP. Но появится проблема относительными путями
Если второй вариант, то проще будет переместить все папки в TMP с рекурсивной заменой на транслит (транслитерацией).
Вопрос: стоил ли на это тратить силы или лучше подождать годик-другой исправлений в WebKitGTK+?
24 апреля 2019, 5:20 дп