Эмулятор терминала Pyte


    Как и было обещано, мы выпускаем под LGPL нашу библиотеку эмуляции эмулятора терминала linux, которую мы используем для показа консолей виртуальных машин в облаке. Называется она, соответственно, pyte (PYthon Terminal Emulator).

    По нашим собственным оценкам, покрытие «текстового» функционала console_codes приближается к 100% (от 80 до 90%, как подсказывают пессимисты из числа оппортунистов среди разработчиков).

    Не реализованы: коды загрузки шрифтов в знакогенератор VGA-адаптера, управление энергосбережением VESA, звуковая сигнализация (коды управления частотой и длительностью звука), управление палитрой, собственные чарсеты; в общем всё то, что не имеет отношения к тексту.

    Зато реализованы все остальные сложные функции, такие, как блокировка регионов экрана для записи, скроллинга, управление режимами переноса строк, правильная обработка атрибутов при различных видов удаления текста и т.д. — всё то, что нужно существующим приложениям, таким как nano, adom (на картинке фрагмент ESC-кодов и получающегося изображения как раз из ADOM'а), vim, emacs, mc, aptitude, dialog, yast2 и т.д. для полноценной отрисовки.

    Библиотека написана на питоне и заточена под удобство манипуляций над экраном, абстрагируясь от графического представления изображения, что позволяет её использовать в коде, осуществляющим дальнейшие преобразования (например, передачи экрана в JS или сериализации в БД).

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

    История создания

    В начале была замечательная в своей наивности библиотека vt102. Она кое-как рисует часть esc-кодов vt102, совсем не задумываясь о unicode, тонких нюансах скроллинга регионов экрана, производительности и стабильности работы. Как о ней писал автор, она была предназначена для читинга в игре nethack, и не более.

    Начинали мы с неё. Некоторое время мы пытались исправлять ошибки и дорабатывать, но потом у нас оказалось, что во-первых vt102 не поддерживает некоторых кнопок (PgUp, например), а во-вторых… Как я писал раньше, главное достоинство терминала linux состоит в том, что его ожидает по-умолчанию linux.

    Пришлось 'from scratch' реализовывать весь функционал linux console (с упомянутыми выше ограничениями на особенности последовательного порта по сравнению с VGA-адаптерами). Таким образом, библиотека плавно переименовалась с vt102 на pyte (Python Terminal Emulator).

    Не смотря на то, что библиотека сейчас написана с нуля, мы решили её так же опубликовать под LGPL, в основном из уважения к автору vt102, код которого мы хоть тактично и удалили, но часть идей всё же использовали, например, концепцию диспетчера.

    Внутреннее устройство


    Библиотека состоит из классов screen и stream. Screen содержит в себе копию экрана (символы и атрибуты), Stream — конечный автомат, отвечающий за обработку ESC и (в особенности) CSI-последовательностей. Стриму кормится последовательность символов, причём, у нас предусмотрена ситуация, когда использующая библиотеку программа ничего не знает про «символы» и оперирует потоком байтов с настраиваемой кодировкой (incremental decoder, для того, чтобы не было странных квадратиков из-за разрыва на середине UTF-8 символа). В принципе, мы работаем не только с UTF-8, но и с другими кодировками. Мы этот функционал в облаке сейчас не используем, но для чистоты совести таки реализовали.

    После съедания всей последовательности символов, формирующих CSI-последовательность (это особый класс ESC-последовательностей, начинающихся с кодов ESC [, после которых идут параметры и команда, например, ESC[1;31m генерирует красный жирный цвет тона). Каждый вывод генерирует то или иное событие (вывод символа, скроллинг и т.д.) для всех подписчиков, среди которых и сама библиотека, обрабатывающая эти события. Разумеется, в числе желающих могут быть и внешний код, например, таким образом мы узнаём о появлении новых символов и сообщаем их Java-скрипту в панельке управления.

    Объекты внутри Screen хранятся как обычные объекты python. У нас была версия, использующая более быстрые сишные массивы, но мы наткнулись на некоторые затруднения с конвертацией между «удобным» для библиотеки форматом и массивом, так что производительность массивов была сильно смазана постоянными конвертациями. Кстати, использование змеиных объектов упрощает доступ к их потрохам и, главное, сериализацию в базу данных (что и является «киллер-фичей» нашей консоли, которая переживает перенос виртуальной машины между серверов без обрывов и обнуления содержимого экрана).

    Кстати, эта библиотека замечательно работает под питоны с 2.6 по 3.2+ и даже под PyPy.

    Планы на будущее


    В ближайшей перспективе планируется дополнение библиотеки поддержкой скроллинга (то самое Shift-PgUp), которое, кстати, мы добавим и в наше облако.

    Кроме того, есть мысль заняться немного бесполезным перфекционизмом и соответствовать стандартам лучше самой консоли линукса, то бишь проходить vttest без единой ошибки.

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

    Если кому-то эта библиотека будет полезна, то мы будем благодарны за сообщения об использовании, багрепорты и рекламации.

    Ссылки


    easy_install pyte
    github.com/selectel/pyte

    Кому говорить спасибо?
    bobry за код,
    o_l и akme за согласие на публикацию под LGPL.
    Селектел 71,35
    Selectel — крупнейший российский IaaS-провайдер
    Поделиться публикацией
    Похожие публикации

    Вакансии компании Селектел

    Комментарии 35
    • +9
      Спасибо, за то что делитесь :)
      • +1
        А можно пример, как реализовать отрисовку на javascript?
        • +2
          Э… ну, сырцы не отдадим, а вот посмотреть можете в саппорте в облаке — js-то грузится прямо туды.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              100x100 ячеек и страничка будет тормозить, как crysis.
              • НЛО прилетело и опубликовало эту надпись здесь
            • +2
              по-моему, это есть тут — github.com/red-brigade/vtjs
              • НЛО прилетело и опубликовало эту надпись здесь
            • +15
              bobry, o_l, akme, вы — мои герои.
              • +5
                А картинка справа — скриншот из ADoM'а.
                • +4
                  как вы узнали???

                  … всё то, что нужно существующим приложениям, таким как nano, adom (на картинке фрагмент ESC-кодов и получающегося изображения как раз из ADOM'а), vim, emacs...
                  • 0
                    То-то я думаю Бискап с JADE оживился…
                • +4
                  Вы — молодцы!
                  Консоль просто потрясающая.
                  • 0
                    Полноценный звук — понятно, что не особо нужен в консоли к серверу.
                    А простой звуковой сигнал "\a" насколько сложно реализовать?
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        Понял. Спасибо.
                    • 0
                      Понял. Спасибо.
                      • +11
                        У меня такое впечатление, что Селектел одна и лучших IT компаний в России! Если будет нужен VPS то я уже знаю какой выбрать.
                        • 0
                          На это все и рассчитано ;)
                          • +3
                            Да-да, ещё один шаг к покупке Google и установлению мирового господства.
                        • +4
                          Спасибо огромное, перевел на вашу библиотеку плагин терминала в Ajenti. Теперь все работает намного лучше (:
                          • НЛО прилетело и опубликовало эту надпись здесь
                            • 0
                              спасибо за ссылку на посте, но я думаю, что из англоязычного поста ссылка на гитхаб будет куда лучше смотреться. Тут слишком много мунспика.
                              • +1
                                Вы правы, исправил
                            • –4
                              Пожалуйста, добавьте в какой-нибудь из эмуляторов терминала поддержку мыши.
                              Ведь в вебе мышь продолжает оставаться основным рабочим инструментом, а в облаке можно же запустить консольное приложение со встроенной поддержкой мыши, например mc. Ну или же даже специально написать мышиное терминальное приложение.

                              P.S. Я отдаю себе полный отчет что мой реквест опять будет заминусован, и даже готов к очередному сливу своей кармы за этот коммент.
                              Но, просто — наболело.
                              • –2
                                Так я и знал… без комментариев
                                • +2
                                  Просто ваш запрос не никак относится к данной библиотеке, которая только разбирает поступающие из pty escape-последовательности. Передача данных о мыши идет в обратном направлении — man console_codes
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                • НЛО прилетело и опубликовало эту надпись здесь
                                  • –3
                                    Именно поэтому-то я и не могу понять того яростного сопротивления разработчиков интерфейса виртуального терминала.
                                    Например, если фронт-енд будет реализован в браузере через джава-скрипт, то и, нажатия кнопок мыши, и перемещение указателя отследить (и передать в терминалку) будет ничуть не сложнее, чем передать информацию о нажатии-отпускании обычных клавиш, а отрисовать изменение положения курсора — ничуть не сложнее, чем изменение цвета и фона у двух экранных знакомест.
                                    В своей терминалке (с блек-джеком) я мышой управлял по способу «Управление указателем с клавиатуры» в панели управления Windows (вкладка «Специальные возможности»). Клиентское приложение отслеживало перемещение мыши поверх терминального окна (а так же нажатия и отпускания кнопок), и при изменении «ячейки» отправляло на терминальный сервер скан-коды аналогичных нажатий обычных клавиш клавиатуры (приводящих к аналогичным действиям при управлении курсором с цифровой панели клавиатуры при отключенном режиме «Num-Lock»).
                                    Терминальный же сервер реагировал на такие действия путем отправки ответной команды на перерисовку двух знакомест экрана с новыми атрибутами цвета.
                                    • +3
                                      Поясняю: я не вижу в этом необходимости, так как общепринятая практика применения последовательного порта подразумевает использование только текстового ввода; весь применяемый на практике софт прекрасно работает без использования мыши. (повторю: в практике эксплуатации серверов, а не в рисовании спрайтов и других странных вещей).

                                      Более практическое соображение: консоль перехватывает ввод с клавиатуры, когда активна. Если она при этом будет ещё перехватывать мышь, это создаст дискомфорт тем пользователям, которые применяют консоль по назначению (для администрирования серверов). Выбирая между абстрактным «в панели управления windows» и удобством администраторов linux-серверов, я очевидно выбираю удобство администраторов linux-серверов. Возможность легко выделить любой текст мышью (вне зависимости от мнения об этом приложения) — это существенный плюс, и я не хочу его лишаться или обременять интерфейс лишними переключателями режима захвата мыши.

                                      Более того, я сейчас очень страдаю из-за того, что консоль не поддерживает копипейст выделением/средней кнопкой мыши — но как это сделать пока не знаю.
                                      • –2
                                        Хорошо, обещаю: попрошайничать больше не буду. Нет, так нет…
                                        Несмотря на то, что «Не реализованы: коды загрузки шрифтов в знакогенератор VGA-адаптера» (я не думаю, что через последовательный порт будет какая-то объективная проблема залить «юзер-фонт» для текстового ввода, который фактически и есть «спрайт»).
                                        Что же касается вопроса про «копипейст выделением/средней кнопкой мыши», то я предложил бы «промежуточное» (совместимое) решение:
                                        Если проблема связана всего лишь с перехватом факта нажатия на «среднюю» кнопку мыши, то ее можно успешно эмулировать путем одновременного нажатия/отпускания левой и правой кнопок.
                                        Согласен, что такой компромиссный способ не слишком удобен для конечного пользователя, но, тем не менее, я надеюсь что он поможет поможет уменьшить «страдания».
                                        • 0
                                          консоль не поддерживает копипейст
                                          А как у вас сейчас работает отрисовка консоли? Сам не имею возможности увидеть.
                                          • 0
                                            Не так, я имею в виду X'овый копипейст: если в одном окне текст выделен, в другом его можно вставить средней кнопкой мыши. Без предварительного нажатия «copy». Очень удобно, и страшно раздражает, когда его нет.

                                            (особо оно удобно с поправкой на то, что есть второй буффер обмена, который «с нажатием кнопок»).
                                    • +8
                                      Добрый день, Kindman.

                                      Спасибо за обращение в нашу компанию и ценные предложения по совершенствованию наших продуктов.

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

                                      Приносим извинения за доставленные неудобства, надеемся на плодотворное сотрудничество в будущем.

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

                                    Самое читаемое