О разработке одного desktop-приложения на Python

    Всем привет. В этой статье я хочу рассказать о разработке программы с открытым исходным кодом для оффлайнового хранения заметок — OutWiker. Этим проектом я занимаюсь в свободное время, первая версия программы вышла в далеком 2010 году, и OutWiker до сих пор продолжает развиваться. Так уж исторически сложилось, что кодом я занимаюсь практически в одиночку (хотя изредка получаю полезные отдельные патчи), но зато пользователи активно участвуют в переводе программы на свой родной язык и иногда присылают стили оформления для страниц, которые затем я включаю в сборку. А уж о том, сколько интересных идей они присылают, и говорить не стоит.


    Что такое OutWiker


    Когда-то я писал об этой программе на Хабре, но это было так давно, что прежде чем говорить об особенностях внутреннего устройства и процесса разработки, нужно сказать, что представляет собой программа с точки зрения пользователя. Все ссылки, связанные с проектом даны в конце статьи. Итак, OutWiker — это программа для хранения заметок в виде дерева, в англоязычном интернете такой софт обычно называют outliner (поэтому у программы такое название). Среди более известных «коллег» OutWiker с подобным функционалом можно назвать Zim, WikidPad, CherryTree, и множество других (ну и, разумеется, org mode для Emacs). Логичный вопрос с точки зрения пользователя — чем OutWiker отличается от других представителей древовидных записных книжек. На данный момент, по прошествии такого количества времени с момента начала разработки, я уже не готов развернуто сравнить весь этот софт. В стародавние времена я перепробовал десятки outliner-ов, штук пять использовал достаточно долгое время, но везде чего-то не хватало, хотелось одну возможность взять из WikidPad, другую — из викидвижка, который может работать оффлайново и т.д. Поэтому в качестве ответа на такой вопрос просто перечислю основные особенности, которыми обладает OutWiker.



    1. Все заметки хранятся в виде папок на диске. Это сделано по двум причинам — для надежности, чтобы, например, при постепенном умирании харда все заметки не отправились на тот свет вместе с одним файлом. И, кроме того, это позволяет просматривать и редактировать заметки без OutWiker. Разумеется, в таком способе хранения есть свои недостатки, но ничего не дается просто так.
    2. К каждой заметке можно прикреплять произвольное количество файлов (на самом деле и папок, но эта возможность не особо афишируется). Одно из назначений прикрепленных файлов (в основном картинок) — это использование их в тексте заметок. Таким образом, изменяя прикрепленную картинку, мы сразу видим новую картинку в тексте страницы.
    3. У OutWiker нет визуального редактора (я думаю, что он когда-нибудь появится, но пока руки до него не доходят), но есть несколько типов страниц — HTML-страницы, викистраницы и Markdown-страницы (после установки соответствующего плагина). В OutWiker упор сделан на викистраницы. Викинотация напоминает pmWiki (не очень распространенный движок для сайтов), но с некоторыми отличиями, об особенностях викинотации и ее реализации я скажу ниже.
    4. Как вы уже поняли по предыдущему пункту, программа умеет работать с плагинами, которых на данный момент больше 20. Например, с помощью плагинов для викистраниц можно добавить раскраску кода для разных языков программирования, поддержку формул в формате LaTeX, возможность вставки разных счетчиков (например, номеров рисунков), графики и диаграммы по данным, можно добавить шаблоны для часто вводимых фраз, создавать страницы, скачивая их из интернета и многое другое.
    5. Каждая заметка может быть помечена произвольным количеством тегов. Облако тегов показывается сбоку в окне программы.
    6. Программа кроссплатформенная, есть сборки под Windows и Linux (с Mac OS X у меня пока дела не складываются).
    7. Исходный код открыт и распространяется по лицензии GPL 3.



    Кое-что о внутренней кухне разработки


    Язык и основные библиотеки


    Теперь я расскажу, как OutWiker устроен изнутри, а также с какими проблемами пришлось столкнуться при разработке.


    Весь проект написан на Python, причем на Python 2.7, переход на Python 3.x планируется, но не в ближайшее время (почему, скажу чуть позже). Для создания интерфейса используется библиотека wxPython. На этапе зарождения проекта в качестве библиотеки для интерфейса выбирал между wxPython и PyQt, остальные подобные библиотеки были отвергнуты, потому что они создают интерфейс, который выглядит чужеродно или под Windows, или под Linux, и может быть и там, и там. В результате остановился на wxPython из-за того, что размер программы получался меньше. Точные цифры размеров я уже не назову, да и проект с того времени уже сильно разросся. Выбором wxPython я доволен, хотя с ней были связаны некоторые неприятные моменты (о них тоже скажу позже).


    Язык Python выбрал, потому что у него все замечательно с кроссплатформенностью. Изначально планировалось добавить в программу возможность создания плагинов, а поскольку плагины — это обычные Python-скрипты, то нет надобности их отдельно собирать под разные операционные системы. В общем, о выборе языка я нисколько не жалею, и тормозов, которые бы возникали именно из-за языка, замечено не было. Есть участки программы, которые работают не очень быстро, но там причины в другом, в основном в необходимости чтения большого количества файлов с диска.


    Что касается кроссплатформенности, то в программе не так много мест, работа которых зависит от операционной системы, и все они связаны с интерфейсом. Пожалуй, наибольшее различие заключается в способе отображения HTML-страниц. Под Windows используется движок Internet Explorer, а под Linux — WebKit. Раньше OutWiker работал под wxPython 2.8 и движки Internet Explorer и WebKit использовались с помощью хаков, которые перестали быть актуальными с выходом wxPython 3.0, теперь классы для работы с этими движками встроены в библиотеку. Правда, Internet Explorer я продолжаю использовать через хак с вызовом COM-объекта, потому что такое использование дает больше возможностей для настроек поведения движка. Теоретически у класса wx.html2.WebView, который должен под Windows работать через Internet Explorer, а под Linux через WebKit, есть метод GetNativeBackend(), который должен вернуть указатель на «настоящий» движок, но почему-то у меня этот метод всегда возвращал None.


    Надо признаться, что на проект большое влияние оказала программа WikidPad. Я сам ей долго пользовался, она тоже написана на Python + wxPython, и иногда я даже подсматривал в ее исходники, чтобы посмотреть, как некоторые моменты там сделаны. Надо сказать, что такое подсматривание сэкономило немало времени.


    Викинотация


    Для страниц с оформлением предназначены три типа страниц: HTML-страницы, Markdown-страницы (требуется добавить соответствующий плагин) и викистраницы. То, что в программе должны быть викистраницы я решил с момента зарождения проекта. В отличие от HTML, викинотации более лаконичны и их легко расширять, добавляя новые команды. Другое преимущество викинотаций — это возможность преобразования встроенного текстового описания в некий графический объект. Например, в OutWiker есть команда для вставки формул в формате LaTeX, вставки графиков, которые строятся либо по данным из текстового файла, либо по данным, которые вставлены непосредственно в код страницы, есть плагин, который из текстового описания создает описание диаграмм и т.п. Кроме того, поскольку викистраница в итоге преобразуется в HTML для отображения пользователю, то это тоже можно использовать, например, при подготовке статей на сайт, если движок сайта ожидает ввода в формате HTML. Например, сейчас эту статью я пишу в виде викинотации, а в конце переключусь на вкладку HTML и получу готовый HTML-код, который нужно будет только немного подогнать под особенности конкретного сайта.


    Викинотация:



    Результат:



    HTML:



    В качестве викинотации я ориентируюсь на движок pmWiki, он не очень распространен, но у меня уже был опыт работы с ним и мне нравится продуманность его нотации. В некоторых моментах при реализации парсера я отходил от оригинальной нотации, но в целом стараюсь придерживаться ее. В эту викинотацию очень легко добавлять свои команды в формате (:command_name:)...(:command_nameend:).


    Иногда спрашивают, почему я не использовал изначально Markdown, но на мой взгляд это слишком ограниченный язык, к тому же pmWiki более логичный. Например, в Markdown я вечно путаюсь с порядком аргументов для ссылки: [текст](http://example.com/) — два вида скобок, еще важен их порядок. В используемой викинотации ссылка оформляется в виде: [[текст -> example.com]]. Стрелка указывает направление ссылки. На самом деле есть еще второй формат ссылок, но лично я обычно пользуюсь таким.


    Кстати, в OutWiker не обязательно запоминать викинотацию, все элементы оформления можно вставлять через меню или с помощью панели инструментов. Для HTML- и Markdown-страниц такие кнопки и пункты меню тоже имеются.


    Для создания википарсера используется очень удобная библиотека pyparsing. Удобная она в первую очередь тем, что представляет собой всего лишь один файл pyparsing.py, который можно положить в исходники и не тянуть лишнюю зависимость в проекте. С помощью этой библиотеки описываются все используемые токены викинотации, а затем они преобразуются в HTML. Про pyparsing есть подробная документация с множеством примеров и даже небольшая книжка. Кроме того, автор библиотеки активно участвует на форуме на сайте и готов помочь с использованием библиотеки.


    Локализация


    Над переводом OutWiker на другие языки активно работают некоторые пользователи, за что им огромное спасибо. Для совместного перевода используется сервис crowdin.com. Это достаточно удобный сервис, на котором пользователи могут предлагать свои варианты перевода фраз, обсуждать их.



    На данный момент программа поддерживает английский, русский, украинский и шведский языки. К сожалению, поддержка некоторых языков прекратилась. Так, например, нужны переводчики, которые доделают итальянскую локализацию (итальянский парень, который когда-то активно поддерживал эту локализацию, куда-то пропал) и немецкую локализацию (сейчас часть немецкого перевода сделана немцем, а часть моей женой в качестве практики немецкого языка, который она учит. Надо, чтобы кто-то проверил и одобрил вторую часть перевода. Кроме того, на немецкий язык не переводились плагины). Есть несколько языков, на которые кто-то начинал делать переводы, но они не доведены до ума (болгарский язык и португальский бразильский). Ну и разумеется, любые другие переводы приветствуются.


    Вот, например, как выглядит украинская и шведская локализация.




    Для использования локализаций внутри OutWiker используется стандартный модуль gettext.


    Особенности сборки


    Поскольку Python — интерпретируемый язык программирования, то для того, чтобы пользователь мог запустить программу, теоретически у него должны быть установлены Python и все необходимые библиотеки. Разумеется, заставлять обычных пользователей устанавливать Python, wxPython и другие требуемые библиотеки, да еще и нужных версий, негуманно. Пользователь должен скачать программу, распаковать ее установить с помощью инсталятора и метода «Next — Next — Next», после чего запустить иконку на рабочем столе. К счастью, для программ, написанных на Python, это все делается сравнительно просто. Если говорить про Windows, то интерпретатор Python без стандартных библиотек умещается в dll-ку размером чуть больше 3 МБ. Существуют несколько утилит, которые делают запускаемые файлы (exe-шники, если говорить про Windows) из Python-скриптов. Наиболее известные из них — cx_Freeze и pyInstaller. По возможностям они примерно равноценны (хотя pyInstaller позволяет создавать единственный exe-шник из Python-скрипта, а у cx_Freeze такой возможности нет), но у них разных подход к тому, где хранить файлы *.pyc библиотек, и по поводу того, как задавать параметры сборки.


    Для создания exe-шников OutWiker долгое время использовался cx_Freeze. Проблем с ним не было, пока не вышел cx_Freeze 5.0, в этой версии автор сильно переписал внутренности утилиты. Видно из-за этого что-то пошло не так. Сборка OutWiker, созданная с помощью cx_Freeze 5.0 начала виснуть при старте, причем судя по результатам отладки, на ровном месте, где никаких проблем не ожидается (скорее всего это как-то было связано с многопоточностью). После выхода cx_Freeze 5.0.2 эта проблема исчезла, но OutWiker перестал выгружаться из памяти при закрытии программы. Эту проблему можно было решить явным вызовом sys.exit(0) в конце программы, но это костыль, который не хотелось добавлять. К тому же, кто знает, какие еще проблемы могли возникнуть при использовании cx_Freeze 5.0.x. Можно было бы остаться на проверенной временем cx_Freeze 4.x, но я не люблю использовать устаревшие библиотеки. Тогда было решено перейти на pyInstaller. Переезд оказался достаточно быстрым, буквально за один день. Никаких проблем с новой сборкой не возникло. Поэтому теперь для сборки используется pyInstaller. С точки зрения пользователей внешне ничего не должно поменяться.


    Те же самые cx_Freeze / pyInstaller можно использовать и для создания бинарных сборок под Linux, чтобы полученная сборка могла запускаться в разных дистрибутивах Linux. Под Windows из полученной сборки создается инсталятор с помощью Inno Setup, а под Linux из подобной сборки создается deb-пакеты (на виртуальных машинах, что будет описано ниже).


    Другая особенность сборки заключается в том, как запускаются разные цели сборки. Все начиналось с небольшого Makefile, который постепенно рос, и проблем с ним становилось все больше. В основном они были связаны с кроссплатформенностью — поддерживать единый Makefile под Windows и Linux было тяжело. В свое время мне это надоело и я начал искать альтернативу, желательно, чтобы она была написана на Python. Альтернатива нашлась достаточно быстро в виде программы Fabric. Теперь все бывшие цели Makefile переписаны в обычные функции Python, да и вообще система сборки разрослась неимоверно. Вот, например, как сейчас выглядит список задач Fabric.



    $ fab -l
    Available commands:
    
        apiversion            Print current OutWiker API versions
        apiversions           Print current OutWiker API versions
        build                 Create artefacts for current version.
        clear                 Remove artefacts after all assemblies
        create_tree           Create wiki tree for the tests
        deb                   Assemble the deb packages
        deb_binary            Create binary deb package
        deb_binary_clear      Remove binary deb package
        deb_clear             Remove the deb packages
        deb_install           Assemble deb package for current Ubuntu release
        deb_single            Assemble the deb package for the current Ubuntu release
        deb_sources_included  Create files for uploading in PPA (including sources)
        deploy                Upload unstable version to site
        doc                   Build documentation
        linux_binary          Assemble binary builds for Linux
        linux_clear           Remove binary builds for Linux
        locale                Update the localization file (outwiker.pot)
        locale_plugin         Create or update the localization file for pluginname plug-in
        outwiker_changelog    Generate OutWiker's changelog for the site
        plugin_changelog      Generate plugin's changelog for the site
        plugin_locale         Create or update the localization file for pluginname plug-in
        plugins               Create an archive with plugins (7z required)
        plugins_clear         Remove an archive with plugins (7z required)
        plugins_list          Print plugins list for th site
        prepare_virtual       Prepare virtual machine
        run                   Run OutWiker from sources
        site_versions         Compare current OutWiker and plugins versions with versions on the site
        sources               Create the sources archives
        sources_clear         Remove the sources archives.
        test                  Run the unit tests
        test_build            Run the build unit tests
        upload_binary         Upload unstable version to site
        upload_plugin         Upload plugin to site
        upload_plugins_pack   Upload archive with all plugins to site
        vm_halt               Stop virtual machines for build
        vm_linux_binary       Create 32- and 64-bit assembly on virtual machines
        vm_prepare            Prepare virtual machines for build
        vm_remove_keys        Remove local SSH keys for remote virual machines
        vm_run                Run virtual machines for build
        vm_stop               Stop virtual machines for build
        vm_update             Update the virtual machines
        win                   Build OutWiker for Windows with cx_Freeze
        win_clear             Remove assemblies under Windows
    

    Как видите, команд достаточно много, все они описаны в документации. Сюда входят команды для сборки под Windows и Linux, запуска тестов, работы с виртуальными машинами для сборки, обновления локализаций, выкладывания новых версий на сайт и другие. Несмотря на то, что, судя по документации, Fabric больше ориентирован на работу с удаленными серверами (условный аналог Ansible), но в качестве замены Makefile мне он очень нравится.


    Войны с Ubuntu


    С wxPython были связаны еще несколько неприятных моментов, которые, к счастью, удалось достаточно быстро решить. Все эти проблемы возникали под Ubuntu, на которую я в первую очередь ориентируюсь при разработке (из-за того, что у меня это основная операционная система). Первый неприятный момент был связан с переходом с wxPython 2.8 на 3.0 (не путать с Python 3.x). Дело в том, что при переходе с версии 2.8 к 3.0 были некоторые проблемы с обратной совместимостью, но, к счастью, эти две версии можно было ставить одновременно и из python-скрипта выбирать нужную версию с помощью wxversion. (с выходом wxPython 4.0 такой возможности больше не будет). Поскольку Python — интерпретируемый язык, и в Ubuntu он всегда присутствует, то для запуска под этой операционной системой нет необходимости создания бинарных сборок, а просто при установке deb-пакета исходники раскидываются по нужным папкам и запускаются с помощью команды python runoutwiker.py. Все необходимые библиотеки для работы wxPython и WebKit указаны как зависимости. Однако с выходом Ubuntu 16.04 LTS возникли две проблемы. Первая была связана с тем, что в этой версии Ubuntu убрали wxPython 2.8, поэтому пришлось срочно мигрировать на wxPython 3.0 и отказаться от поддержки другой долгоживущей версии Ubuntu 14.04 LTS. Но это еще не все, оказалось, что в Ubuntu 16.04 (в следующих версиях это исправили) wxPython как-то неправильно скомпилирован, и в нем без шаманств не работает движок WebKit. К счастью, тут помогли продвинутые пользователи OutWiker, которые подсказали, что проблема обходится с помощью LD_PRELOAD и указанием пути до одной библиотеки, относящейся к wxPython. Как я уже сказал, надобность в этом костыле в последующих версиях Ubuntu отпала, но ради поддержки Ubuntu 16.04 его приходится использовать до сих пор.


    Чтобы в будущем обезопасить себя и пользователей от подобных изменений в Ubuntu, недавно начал делать бинарные сборки под Linux. Такие сборки делаются для 32- и 64-битных систем. В перспективе это позволит самостоятельно компилировать wxPython с нужными параметрами и не зависеть от имеющихся библиотек в репозиториях Ubuntu. Для того, чтобы создавать бинарные сборки (и deb-пакеты на основе их) используется связка Ansible, Vagrant и VirtualBox. С помощью Vagrant запускаются две виртуальные машины (32 и 64 бита), туда с помощью Ansible через SSH закачиваются исходники программы, там создаются бинарные сборки и deb-пакеты, которые скачиваются обратно на рабочий комп (хост). Но недавно и тут разработчики Ubuntu подложили свинью. Дело в том, что виртуальные машины создаются на основе Ubuntu 17.04, и в перспективе я собирался переводить виртуальные машины на Ubuntu 17.10. Я бы рад был использовать для сборки версию Ubuntu 16.04 LTS, но, как я уже говорил, там есть проблемы с wxPython. Но внезапно разработчики Ubuntu решили отказаться от поддержки 32-битных систем. Возможно, в будущем для сборки на виртуальных машинах придется переходить на другой дистрибутив. Конечно, можно было бы тоже отказаться от поддержки 32-битных систем, но в данный момент такая поддержка мне как разработчику не мешает, а пользователям может быть полезна.


    Другие используемые библиотеки


    Кроме уже упоминавшихся библиотек wxPython и pyparsing в проекте используются и другие библиотеки. Коротко перечислю их.


    • PyEnchant. Используется для проверки орфографии.
    • Pygments. Используется в плагине Source для раскраски исходников кусков кода. На вход библиотеке мы подаем исходник, на выходе получаем красиво оформленный HTML. Pygments понимает огромное количество языков программирования, в том числе экзотических и редко используемых, а также дает выбирать стиль оформления (к библиотеке прилагается более десятка стилей).
    • Python Markdown. Как следует из названия, предназначен для разбора нотации Markdown.
    • KaTeX. Используется в плагине TeXEquation. JavaScript-библиотека для рендеринга формул в формате LaTeX. Раньше использовалась программа mimeTeX, но формулы, созданные с помощью нее выглядели не очень эстетично и были проблемы с отображением формул на страницах с темным фоном, потому что mimeTeX создает картинку с черным текстом.
    • Beautiful Soup. Используется в плагине WebPage, предназначенном для создания страниц из страниц в интернете (при этом скачиваются все картинки, стили CSS и скрипты JavaScript). Библиотека используется для разбора и правки скачанного HTML-кода. Например, чтобы заменить исходные ссылки на картинки в HTML-коде на пути до скачанных картинок.
    • Chardet. Используется в том же плагине WebPage, чтобы определить кодировку скачанной страницы.
    • Jinja2. Используется в плагине Snippets, который предназначен для вставки в заметки шаблонного текста. Шаблоны создаются в формате Jinja (с некоторыми упрощениями).
    • Blockdiag. Используется в плагине Diagrammer, который по текстовому описанию строит схему из кубиков, связанных между собой стрелками. Основную работу в плагине выполняет библиотека Diagrammer. Ее можно рассматривать как упрощенную версию dot и Graphviz.

    Планы на дальнейшее развитие


    Проект OutWiker активно развивается, доказательство чему статистика коммитов на github:



    Сейчас исходники занимают около 90 МБ, куда входят почти 4300 файлов, из них 1772 — python-скрипты.

    Планов и идей огромное количество (количество issues на github сейчас чуть меньше 350). Туда попадают любые пожелания пользователей, даже если в ближайшее время до их реализации руки точно не дойдут. Поскольку кодом занимаюсь я практически в одиночку, то новые возможности появляются не так быстро, как хотелось бы. В последнее время стабильные версии OutWiker выходят примерно раз в год, но каждый месяц я выкладываю нестабильные версии. На самом деле их нестабильность — вопрос философский, потому что я не выкладываю откровенно неработающие версии, и иногда нестабильные версии «стабильнее» стабильных в том плане, что после релиза в них исправляются какие-то найденные не критичные недоработки из последнего релиза. Но в нестабильных версиях я могу себе позволить что-то не успеть отшлифовать, а может быть что-то не заметить после добавления новой возможности.


    В данный момент работа идет по двум направлениям — сделать более современный внешний вид программы и уменьшить количество файлов, создаваемых для каждой заметки. Что касается интерфейса, то я хочу избавиться от имеющихся панелей инструментов и сделать их стиле Delphi. Но скорее всего эту глобальную переделку оставлю до следующей версии 2.2.


    В свете описанных выше вечно возникающих проблем с Ubuntu хочется попробовать под Linux сделать snap-пакет или/и flatpak-пакет.


    Нужно писать документацию (я имею в виду техническую, со справкой пока все в порядке). В документации я описываю внутреннее устройство программы, особенности сборки и т.п. Пока практически вся документация написана на русском языке, надеюсь, что к релизу я возьму себя в руки и переведу хотя бы часть ее на английский язык.


    В более дальней перспективе нужно будет перейти на wxPython 4.0, который, надеюсь, скоро получит статус релиза, и на Python 3.x. Логично сначала будет перейти на wxPython 4.0, который поддерживает обе версии Python, а потом перейти на Python 3.


    Ссылки


    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 35
    • +1
      Спасибо за программу! Уже больше года пользуюсь и не нарадуюсь.
      • 0
        Спасибо за программку. Одно время активно пользовался, но потому перешел на Mars Notebook — wysiwyg таки полезная фишка.
        • 0
          Уже лет 10 использую Mars Notebook за возможность удобного шифрования и удобного дерева с редактором. Начинал использовать когда сидел на винде, потом перекочевал на линукс и запускаю под wine. выглядит не очень, но функционально.
        • –9
          Будущее за javascript и nodejs

          • +1
            Будущее, даже по своему смыслу, не может быть «за» чем-то. Оно всегда впереди. А насчет языков, тут Вы, по моему мнению, ошибаетесь. Чуть ли не каждый год появляются новые, имеющие свои достоинства и предназначения.
            Тем не менее, продолжают жить основополагающие языки типа C или кроссплатформенные скриптовые. Вот к последним и относится python…
            Да и здесь не рекламируют язык, а представляют комплекс по работе с заметками.
            Автору большое спасибо.
            • –3
              Сейчас js становится основополагающим.

              Уже пишут компиляторы, чтобы js код сразу преобразовывать в машинный код.

              js код уже работает на сервере, и на клиенте

              Ваш питон — говно, как и Perl

              Там жуткое оформление и стилистика кода с пробелами и переводами строк в качестве разделителя операторов — код превращается в сплошную кашу.

              Perl уже давно умер, вот и питон скоро уйдёт.

              На js можно писать кроссплатформенные приложения, которые работают не только в ОС как десктоп, но и просто в браузере.
              • 0
                > Сейчас js становится основополагающим.
                Не наблюдаю никаких особых признаков этого, кроме разумеется нездорового хайпа вокруг веб-приложений и попыток пиарить их как замену десктопным.

                > Уже пишут компиляторы, чтобы js код сразу преобразовывать в машинный код.
                Когда напишут, тогда и поговорим. Пока что кроме JIT ничего нет. И неважно, с JIT, без JIT, но веб-приложения на js вчистую сливают десктопным по производительности, не говоря уже о ресурсоёмкости.

                > js код уже работает на сервере, и на клиенте
                При чём здесь это? Мир не ограничивается вебом.

                > Ваш питон — говно, как и Perl
                > Там жуткое оформление и стилистика кода с пробелами и переводами строк в качестве разделителя операторов — код превращается в сплошную кашу.

                Сразу видно эксперта, путающего перевод строки (\n) c табуляцией (\t), а операторы — с блоками кода. А также синтаксис языка — со стилем кодинга и оформления. Читаемый код — вопрос скилла и аккуратности разработчика, а не языка и его разделительных символов.

                > Perl уже давно умер, вот и питон скоро уйдёт.
                Дада, как только вы напишете на js аналоги numpy, scipy и ещё тонны библиотек, достаточной для того, чтобы отобрать у питона звание дефолтного языка для data science. А также создадите нормальную реализацию js/ECMAScript общего назначения, не привязанную к браузеру. Perl живее всех живых, если что. Попробуйте удалить Perl из дебиана/убунты и понаблюдайте что произойдёт.

                > На js можно писать кроссплатформенные приложения, которые работают не только в ОС как десктоп, но и просто в браузере.
                Это хвалёный Electron, что ли, простейшие приложения на котором жрут память сотнями Мб и не тормозят только на топовом железе?
                Perl/Python внезапно тоже кроссплатформенны.
          • +1
            Выглядит очень интересно, спасибо за вашу работу!
            Мне, как пользователю своей вики, была бы интересна возможность держать такой сервис в онлайне, чтобы был доступ к заметкам в поездках и с телефона. Есть ли такие планы или воркараунды?
            • 0
              Тоже думал об этом, но вряд ли в ближайшее время дойдут руки до полноценной реализации. Хотя (открывая страшную тайну) я собираюсь сделать для OutWiker отдельный сайт, движок которого должен будет работать со страницами в формате викистраниц OutWiker, но страницы там будут храниться все-тати в базе. Это будет первым шагом к веб-версии программы.
              • 0
                А WikidPad вы изучали? Как конкурента… :-)
                • 0
                  Не только изучал, а даже некоторое время активно им пользовался, пока не начал делать OutWiker. И в статье его я упоминаю.
              • 0
                Была на хабре статья, Самая нужная программа на свете примерно про такой же проект, правда написаный на плюсах. Там был какой то способ работы в онлайне и даже можно было делиться кусками своей базы знаний.
              • +1
                Большое спасибо за такую программу! Надеюсь, приживётся.
                Давно искал что-то типа Evernote, но с поддержкой markdown и чтобы все файлы были в папках, а не в одном закрытом формате. В последний раз смотрел TagSpaces. Там, вроде, тоже всё по папкам, но самого дерева не было, из-за этого как-то не прижилось.

                А тут ещё и на wxPython :-)
                • +1
                  Это сделано по двум причинам — для надежности, чтобы, например, при постепенном умирании харда все заметки не отправились на тот свет вместе с одним файлом. И, кроме того, это позволяет просматривать и редактировать заметки без OutWiker.


                  Забыли еще упомянуть, что такое хранение позволяет удобно синхронизировать заметки через любое облачное хранилище или даже BitTorrent Sync (или как он теперь называется)
                  • 0
                    Монетизация программы есть? Какие-то планы насчет коммерческой версии и прочее?
                    • 0
                      В данный момент нет. Есть кнопка для доната, но толку от нее не много.
                    • +1
                      Наконец то! Давно было пора уже написать про OutWiker. Даже сам планировал когда то, но руки не дошли. Пользуюсь уже не первый год. Почти всем доволен. «Почти» потому что еще не дошли руки до написания своего стиля css. Сразу успокоился и перестал косится по сторонам в поиске чего то нового после того как понял насколько это просто довести до ума внешний вид (отображения) не идеальной для меня markdown-разметки.

                      Надеюсь статья на habrahabr-е добавит новых пользователей, а значит больше идей, а может, чем черт не шутит, и новых разработчиков.
                      • 0
                        Пожалуй, наибольшее различие заключается в способе отображения HTML-страниц. Под Windows используется движок Internet Explorer, а под Linux — WebKit.


                        ИМХО использование настолько тяжёлых движков в такой простой вещи, как редактор заметок, — это оверкилл. :) Пользователям этой программы скорее нужен просто rich text + вставка картинок. Вряд ли они для создания заметки будут использовать например JS и вообще всю мощь современного HTML. Я бы стартовал с простейшего легковесного html рендерера, например litehtml, и потом сверху реализовал бы рендеринг картинок и всего остального что понадобится.
                        • 0
                          На самом деле пользователи мне присылали собственные шаблоны, в которых активно используют CSS и JS-скрипты, которые я потом оформил в виде плагинов (например, jenyay.net/Outwiker/Spoiler и jenyay.net/Outwiker/Lightbox). А еще CSS используется для раскраски исходников, а JS — для отображения формул.
                        • +2
                          Боже мой, это ведь то самое, что я искал: опенсорс, без облачной синхронизации, в виде файлов и папок… Спасибо большое. Пойду хоть с переводами помогу.
                          • 0
                            Спасибо за то, что Вы начали переводить на китайский язык. Среди всех файлов лучше сначала перевести outwiker.pot — это строки из основной программы, остальные файлы — это локализации плагинов.
                          • 0
                            Хотелка: Шифрование файлов по ключу, на лету.
                            Можно писать в шифрованый раздел, но немного не то, хотелось бы на без сторонних движений.
                            • 0
                              Подскажите плиз, шифрование фрагмента заметки(например как в Evernote) возможно?
                              • +1
                                Нет, специально не делал шифрование, потому что недежное шифрование — сложная задача, которую хорошо решают сторонние приложения (VeraCrypt и т.п.) Пусть лучше не будет никакого шифрования, чем ненадежное. Лично я для шифрования заметок использую VeraCrypt под Виндой и encfs под Линуксом.
                                • 0
                                  Согласен, для действительно «чувствительных» данных я и сам подобный подход пропагандирую. Однако, чисто для предотвращения подглядывания, шифрование фрагмента в Evernote очень удобно ИМХО. Правда в остальном Evernote уже достал, вот и ищу альтернативу…
                              • 0

                                Кто-нибудь знает, есть ли программы для ведения заметок/вики, работающие и на десктопе, и на андроиде?


                                Я пока нашёл только tiddlywiki, но оно на мой взгляд не слишком удобное.

                                • 0
                                  Спасибо за программу, Евгений!

                                  Пользуюсь уже почти 3 года. Очень не хватает rst-формата, т.к. markdown — это все-таки html-only.

                                  А есть где-нибудь список лайфхаков, как удобно использовать OutWiker под андроид?
                                  • 0
                                    Под Андроид уже два человека начинали писать приложение, но проект быстро останавливался.
                                  • 0

                                    Скажите пожалуйста, позволяет ли API плагинов интегрировать в OutWiker содержимое существующих документов в другом формате или с другой структурой? В первую очередь меня интересует дерево с данными от ScrapBook.


                                    И позволяет ли API плагинов добавлять различные синтаксисы языка представления, например, DokuWiki или упоминавшийся reStructured?

                                    • 0

                                      s/DokuWiki/MediaWiki/

                                      • 0
                                        Добавить страницы в другом формате или с другой нотацией точно можно (например, поддержка Markdown сделана в виде плагина). По поводу другой структуры — вопрос сложный. Изначально API на такое не рассчитан.
                                      • 0
                                        >В свете описанных выше вечно возникающих проблем с Ubuntu хочется попробовать под Linux сделать snap-пакет или/и flatpak-пакет.

                                        Это было бы печальной капитуляцией. Эти обёртки приведут и к увеличению потребления памяти, когда будут использоваться библиотеки из пакета, вместо переиспользования уже загруженных в память системных, и к увеличению времени запуска. Самое печальное будет в уменьшении интеграции с системой. Я сейчас в лагере пользователей Zim, и благодаря его нормальной установке могу делать как-нибудь так:
                                        $ grep -m1 zim .git/hooks/pre-commit
                                        from zim.formats.wiki import Parser, Dumper


                                        Просто импортирую системные библиотеки и получаю возможность парсить заметки из своих скриптов!
                                        • +1

                                          Память в мире, где одна вкладка браузера легко пару сотен мегабайт, никого уже так сильно не волнует. Юз-кейс с использовнием библиотек из своего приложения — откровенно экзотический, 99.99% пользователей zim оно не надо. Кому надо — могут стянуть сорцы из гита и положить в свой локальный virtualenv. И тем же 99.99% пользователей надо, чтобы программа установилась в их системе без лишних телодвижений и спокойно сама обновлялась.


                                          IMHO попробовать snap/flatpack стоит, и потом сравнить процент установок с ним и обычным способом.

                                          • 0
                                            Отказываться от deb я не планирую, snap/flatpak рассматриваю как дополнительную альтернативу.
                                          • +1
                                            Спасибо за вашу программу.

                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.