- DroidScript – простой и функциональный инструмент для разработки мобильных приложений под Android
- Что такое DroidScript?
- Установка и настройка
- Об автоматизации и скриптинге для Android
- Содержание статьи
- Tasker
- Основные понятия
- Хакер #166. DDoS
- Создаем профиль
- Особенности контекста «Место»
- Создание задач
- Переключение музыки в плеере встряхиванием телефона
- Scripting Level for Android
- Уровнем выше
- Взаимодействие с пользователем
- Что дальше?
- Shell-скриптинг в среде Android
- Содержание статьи
- Особенности Android-окружения
- Хакер #185. Докажи баг!
- Первый пример
- Автозапуск
- Запуск скриптов до и после установки прошивки
- Что еще?
- Вместо выводов
- Евгений Зобнин
DroidScript – простой и функциональный инструмент для разработки мобильных приложений под Android
Что такое DroidScript?
DroidScript представляет собой приложение Android, которое включает в себя среду разработки и выполнения программного кода на Android устройстве. Он позволяет создавать приложения двух типов – JavaScript (с нативным интерфейсом) и HTML (гибридные).
Для создания нативного UI и доступа к программно-аппаратным ресурсам Android, JavaScript используется совместно с API DroidScript, который позволяет работать с WebView, SQLite, email, SMS, WebGL, сенсорами, Web-серверами, сокетами, спрайтовой анимацией и многим другим, а также осуществлять взаимодействие с внешними устройствами посредством Bluetooth, WiFi, USB и LAN.
Впечатляющая функциональность ”из коробки” – это одна из особенностей DroidScript. Другая особенность – простота его использования. В чём она состоит? Прежде всего, в кодировании. Ниже дан пример кода простого приложения:
Всё кодируется на JavaScript и API DroidScript без использования xml-разметки, подключения библиотек, создания классов и др.
В DroidScript нет визуальных средств проектирования интерфейса, как в Android Studio, AIDE или MIT App Inventor, но в нём можно реализовать LivePreview на Android для ещё более быстрой разработки интерактивных прототипов, а также расширить функциональность при помощи плагинов, написанных на JavaScript или Java.
Простота работы с DroidScript заключается не только в кодировании. Он изначально разрабатывался так, чтобы дать начинающим разработчикам под Android просто и быстро погрузиться в этот процесс.
Установка и настройка
В случае отсутствия под рукой телефона или планшета с операционной системой Android можно воспользоваться её эмулятором, например, BlueStacks или Nox APP Player.
Устанавливаем DroidScript из Google Play и открываем его. На экране появляется интерфейс с единственным приложением Hello World в области приложений.
Короткое касание пиктограммы приложения приведёт к его запуску. Для редактирования кода нужно выполнить долгое касание пиктограммы и выбрать опцию Edit в появившемся списке действий.
Панель управления включает в себя кнопки для доступа к документации, соединения с WiFi IDE, общим командам и примерам.
Настройка удалённой среды разработки WiFi IDE происходит так:
В левой части окна располагаются вкладки с областью приложений, редактором, ресурсными файлами, а в правой — вкладки с новостями, справкой, примерами и отладчиком.
В WiFi IDE заложена возможность расширения его функциональности за счёт добавления вкладок. Вкладка “Espruino” является примером данного расширения.
В самом простом случае приложение может состоять из одного файла с расширением js, в котором код хранится в исходном виде. Для обмена проектом в исходном коде его можно запаковать в spk-архив. Также возможна сборка проекта в apk-файл, но для этого необходимо купить и установить плагин ApkBuilder.
Когда впервые видишь столь простые интерфейсы DroidScript и WiFi IDE, после работы в десктопной или web-среде, то возникает логичный вопрос, а можно ли с помощью этого cделать что-то серьёзное? Безусловно! Как известно, и с помощью простых инструментов можно создавать впечатляющие вещи!
Источник
Об автоматизации и скриптинге для Android
Содержание статьи
Привет, читатель. Не знаю как ты, а я ну очень ленивый. И я не люблю вновь и вновь повторять какие-то стандартные действия, если можно написать скрипт. В Android для этого можно использовать визуальный инструмент автоматизации Tasker и среду исполнения скриптов SL4A, которые, работая в паре, позволяют сделать смартфон по-настоящему умным девайсом.
Tasker
Tasker представляет собой небольшое, но очень мощное приложение для автоматизации устройств под управлением Android. Принцип его действия основан на выполнении определенных задач в момент возникновения событий, так или иначе меняющих состояние смартфона. Я знаю, что звучит это не особо впечатляюще, однако в умелых руках Tasker позволяет творить настоящие чудеса. Для затравки приведу несколько примеров.
Что ты обычно делаешь при включении громкой связи? Правильно, кладешь телефон на стол. А что, если громкая связь включится сама, когда ты положишь телефон экраном вниз во время разговора? Удобно? Так вот, Tasker позволяет реализовать такое поведение буквально за минуту. Также можно настроить автоматический запуск плеера при подключении наушников, автоматическую отправку SMS, когда доезжаешь до дома, или переключение музыки в плеере встряхиванием телефона. С помощью Tasker все это достижимо в несколько тапов по экрану.
Приложение это платное и стоит 3,49 фунта стерлингов (примерно пять долларов), но прежде чем покупать, можно ознакомиться с программой, скачав trial-версию на семь дней с сайта разработчика tasker.dinglisch.net. Недели будет вполне достаточно: например, лично я без сомнений купил программу всего через два дня использования и уверен, что ты поступишь также. Кстати, учти, что версия с Play Market не имеет функции шифрования из-за ограничений законов США.
Основные понятия
Скриншот 1: главное окно Tasker
Хакер #166. DDoS
В разделе «Profiles» отображаются, как понятно из его названия, пользовательские профили.Профиль — это один или несколько Контекстов и привязанная к ним Задача, где контекст— это некоторое условие, такое как, например, переворот телефона экраном вниз, включение GPS или проседание заряда батареи до определенного уровня. Если все контексты профиля становятся активными, то активизируется сам профиль и начинает выполняться Начальная задача профиля. Если хоть один из контекстов профиля становится неактивен, профиль дезактивируется и выполняется Конечная задача.
Например, для профиля с одним контекстом «Телефон лежит экраном вниз» начальная задача выполнится после того, как устройство приобретет нужную позицию (то есть экраном вниз), а конечная — когда оно покинет эту позицию. Задача — это одно или целая цепочка Действий, где действие — это какая-то элементарная операция. Разработчики предоставили нам очень много действий, начиная от вывода сообщений на экран и заканчивая файловыми операциями. Наличие и их последовательность в задаче определяем мы. Действия можно поделить на настройки и собственно действия. Настройки отличаются от действий тем, что они возобновляют прежнее состояние после дезактивации контекста. Например, звонок по определенному номеру является действием, а включение громкой связи — настройкой. В приложении их можно отличить по пиктограмме: молния — это действие, шестеренка — настройка.
Создаем профиль
Вооружившись знаниями, попробуем создать наш первый профиль: автоматическое включение громкой связи в том случае, если телефон переворачивают экраном вниз. Для создания нового профиля нажимаем кнопку «+» внизу по центру экрана. Появится окошко с приглашением к вводу имени профиля. Имя указывать не обязательно, но рекомендуется, дабы в будущем не запутаться среди профилей (я ввел «Громкая связь»). Далее ты увидишь меню выбора типа первого контекста (скриншот 2). Рассмотрим все типы подробнее:
Особенности контекста «Место»
Контекст «Место», как уже упоминалось, активизируется, когда смартфон находится в некотором радиусе от указанной на карте точки. Можно выбрать, использовать ли GPS или же данные от сети, а также нужный радиус, значение которого можно указать от 30 метров до 999 километров. Для относительно большого радиуса в пределах города, где точность данных из сети достаточно высока, лучше не использовать GPS, который жрет батарею совсем не по-детски. Также запомни, что если точность определения положения больше, чем радиус срабатывания, то контекст не активизируется.
Выбираем пункт «Состояние» и видим несколько категорий (скриншот 3). Нам нужна категория «Sensor», а в ней пункт «Ориентация». Далее в выпадающем списке нужно выбрать необходимую ориентацию устройства. В нашем случае следует выбрать «Экраном вниз» и нажать на зеленую галочку. Выскочит меню выбора задачи для заданного контекста. Так как задач у нас пока нет, нажимаем «Новая задача». Вводим название задачи (можно не вводить, но рекомендую) и попадаем в меню редактирования задачи.
Скриншот 3: разделы контекста «Состояние»
Создание задач
Как я уже говорил, задачи — это последовательности действий. Чтобы добавить к задаче действие, следует нажать кнопку «плюс» (скриншот 4). Все действия разбиты на несколько категорий, названия которых говорят сами за себя. Для цели, поставленной нами, нужно выбрать пункт «Аудио», затем выбрать настройку «Громкая связь» и в выпадающем списке — «Включить». Галочка «Если» позволяет навесить дополнительные условия на конкретную задачу (если интересно, подробнее тут. Нажимаем зеленую галочку — действие добавлено к задаче. Можно добавить еще несколько действий, но в нашем случае это не требуется, так что еще раз нажимаем зеленую галочку, и только что созданная задача становится начальной задачей профиля. Так как громкая связь является настройкой, то после дезактивации контекста она будет отключена.
Скриншот 4: экран создания задачи
Переключение музыки в плеере встряхиванием телефона
В этом примере я обещал рассказать об особенностях контекста «Событие». Контекст «Событие» активизируется только на короткий промежуток времени, запуская привязанную задачу, и сразу дезактивируется. Поэтому в профиле может быть только один контекст такого типа и у профиля с событием не может быть конечной задачи. Также для профилей с событием настройки не возобновляют своего значения.
Приступим к реализации нашего профиля. Добавляем новый профиль (не забываем дать ему имя) и выбираем для него контекст «Событие». Выбираем категорию событий «Sensor», а затем «Shake». Выставляем нужные нам значения осей, чувствительности и продолжительности. Для этого профиля нам нужно создать новую задачу — создаем! В окне редактирования задачи нажимаем плюс; нам нужна категория «Медиа» и действие «Упр. Медиаплеером». Выбираем нужную команду управления и заканчиваем создание задачи. Добавим еще один контекст к профилю (на этот раз это контекст «Приложение») и выберем из списка наш плеер. Теперь опрос сенсора будет происходить только при включенном плеере. Все, данный профиль готов, можешь проверить.
Scripting Level for Android
Я описал лишь основные фичи Tasker. Этих знаний тебе вполне хватит для создания самых простых профилей, но возможности этой замечательной программы этим не ограничиваются. В Tasker встроены средства создания и анализа переменных, можно реализовать условные операторы, циклы и даже создавать UI для запроса данных от пользователя (именно для этого и предназначены «Scenes»). Но и это еще не все, возможности Tasker можно существенно расширить, используя в качестве действий скрипты, созданные с помощью SL4A.
SL4A (Scripting Level for Android) — это среда исполнения (и создания) скриптов для Android на языках Python, JavaScript, Perl, Ruby, Lua, BeanShell и Tcl. В скриптах может быть использован API Android через специальную обвязку вокруг стандартного JSON RPC платформы Android, благодаря чему из скриптов можно вызывать функции телефонии, отправлять SMS, получать данные с GPS, камеры и акселерометров, формировать GUI. Скриптовым языком де-факто для этой платформы считается Python, и мы возьмем на вооружение именно его.
Для начала работы необходимо скачать и установить SL4A и Python. После установки Python запускаем его и нажимаем на кнопку «Install», чтобы скачались все необходимые библиотеки для работы на Android.
Для примера напишем несколько простых скриптов. Можно делать это прямо на устройстве, но можно писать и на обычном компе, а потом скидывать код в каталог SL4A/Scripts на карте памяти. Для создания нового скрипта запускаем SL4A, вызываем меню и нажимаем «Add», в появившемся списке выбираем «Python». Попадаем в окно создания скрипта. В верхнее поле вводим имя, внизу у нас уже написано две строчки кода:
Этот код просто импортирует библиотеку для работы с API и создает объект, с помощью которого API будет нам доступен. Разобрать все функции API или даже их четверть нереально в одной статье, поэтому будем рассматривать необходимые нам функции в процессе создания скриптов (полное описание API есть во встроенной справке SL4A или же здесь. Первой функцией, которую мы рассмотрим, будет makeToast: она просто отображает уведомление. Дописываем две строки к коду:
Далее сохраняем скрипт и запускаем его, тапнув по его имени. Появится меню, показанное на скриншоте 5. Первый пункт означает запуск скрипта с консолью, второй — в фоновом режиме.
Скриншот 5: запуск SL4A-скриптов
Скриншот 6: результат работы HelloWorld.py
Уровнем выше
Теперь заскриптим что-нибудь поинтересней. Давай попробуем научить смартфон анализировать последнее входящее SMS-сообщение на наличие некоторых команд, выполнять их и выдавать ответ об успешно выполненной операции. Для примера пусть у нас будет всего одна команда play music, после получения которой будет проигран определенный медиафайл.
Можно зациклить эту проверку, но гораздо эффективнее получится, если связать выполнение этого скрипта с событием Tasker «Получено текст. сообщ.» из раздела «Телефон».
Рассмотрим более полезный скрипт. Знаю, что у многих (в том числе у меня) есть проблема с отображением кириллических символов в ID3-тегах MP3-файлов. Удобного решения этой проблемы я так и не нашел, поэтому и написал скрипт. Для его работы мне потребовалась сторонняя библиотека Stagger. Кстати, из SL4A можно использовать любые сторонние pure Python библиотеки, просто копируя их в каталог com.googlecode.python.python3forandroid/extras/python3 на карте памяти. Полный код скрипта с подробными комментариями можно найти на прилагаемом к журналу диске, здесь же ограничусь только кодом, который перебирает MP3-файлы на карте памяти:
Этот скрипт можно запускать вручную, когда потребуется, но я привязал выполнение этого скрипта к событию «Кар. памяти доступна» из раздела «Аппаратура» Tasker.
Взаимодействие с пользователем
SL4A предоставляет нам разные способы взаимодействия с пользователем: webViews (HTML5 + JavaScript), fullScreenAPI (подробнее можно почитать в моей статье и dialogAPI, который мы вкратце и рассмотрим. Опять же полный код примера можно увидеть на диске, а здесь только часть, касающаяся dialogAPI. Я не сказал, что за скрипт? Он отправляет выбранные пользователем фотки на FTP-сервер.
Что дальше?
Благодаря Tasker и SL4A возможности автоматизировать пользовательские действия на Android становятся просто безграничными. Сам же SL4A предоставляет мощный потенциал для скриптинга Android. В этой статье я описал лишь самую малость из всех возможностей программ. Остальную информацию ищи по ссылкам, приведенным в боковых выносах, или же жди от меня новых, более специализированных статей.
Источник
Shell-скриптинг в среде Android
Содержание статьи
Android основан на ядре Linux, включает в себя набор стандартных UNIX-команд и простой шелл sh. Все это значит, что мы можем не только использовать командную строку для выполнения низкоуровневых операций, но и писать шелл-скрипты, которые будут выполнять функции, недоступные из графического интерфейса. В этой статье мы поговорим о том, что с их помощью можно сделать и зачем все это нужно.
Для прошлого номера журнала я написал статью о Tasker — системе, которая позволяет автоматизировать работу Android и заменить сотни сторонних приложений. К сожалению, Tasker ограничен высокоуровневыми функциями Android и не позволяет выполнять такие низкоуровневые операции, как монтирование файловых систем, изменение параметров ядра, системных переменных или запуск демонов. Зато все это можно сделать с помощью скриптов.
Сразу оговорюсь, что в этой статье речь пойдет о шелл-скриптах в традиционном для Linux понимании, без использования инструментов вроде SL4A, QPython или Roboto. Главное назначение таких скриптов — изменение поведения системы, параметров ядра, работа с демонами (ADB, например) и тому подобное. Скрипты могут стартовать на этапе загрузки ОС, установки новой прошивки, после тапа по кнопке или же по традиции — из терминала.
В статье я расскажу, как писать такие скрипты, как заставить их стартовать автоматически, привязывать к определенному системному событию. В качестве бонуса также объясню, как заставить консоль восстановления (recovery) выполнить необходимые тебе действия перед установкой или сразу после установки новой прошивки. Начинаем.
Особенности Android-окружения
В самой своей основе, там, где нет Java и Dalvik, Android представляет собой минималистичный Linux-дистрибутив со всеми свойственными ему атрибутами: ядром, системой инициализации, набором библиотек, демонов, консольных команд и, конечно же, шеллом. Последний — это не что иное, как mksh из MirBSD, переименованный в sh; простой командный интерпретатор с поддержкой языковых конструкций классического Bourne shell из UNIX и автодополнением по нажатию Tab.
В качестве комплекта базовых UNIX-команд здесь используется toolbox, своего рода урезанная альтернатива BusyBox, которая позволяет вызывать несколько разных команд из одного бинарника (с помощью симлинков). Toolbox включает в себя очень ограниченный набор команд, в котором нет не только grep или sort, но даже cp. Поэтому для полноценной работы со скриптами настоятельно рекомендуется установка BusyBox, благо в маркете полно бесплатных инсталляторов.
Основное назначение скриптинга в Android — работа с ядром и системными утилитами. Ядро тут стандартное и экспортирует все те же интерфейсы /proc и /sys, через которые можно рулить железом и состоянием системы. Плюс есть набор специфичных для Android утилит, которые будут очень полезны при разработке скриптов:
Хакер #185. Докажи баг!
Первый пример
Теперь давайте попробуем написать первый скрипт. Делать это лучше на компе, а еще лучше в Linux или редакторе, который умеет создавать текстовые файлы без символа возврата каретки (который при открытии в Android будет выглядеть как ^M в конце каждой строки). Наш первый скрипт будет состоять всего из двух строк, которые делают бэкап всех установленных приложений на карту памяти. Его код (требует BusyBox):
Сохраняем (пусть он называется apk_backup.sh) и перекидываем на смартфон с помощью ADB:
Теперь его нужно запустить. Проще всего сделать это с помощью все того же ADB:
Примерно таким же образом скрипт можно запустить из консоли на самом смартфоне/планшете:
Само собой, такой способ не очень удобен. Поэтому нам нужен какой-то быстрый способ запуска скрипта. Наиболее удобное из найденных мной решений — это приложение QuickTerminal. Устанавливаем, запускаем, переходим на вкладку Quick Command, нажимаем кнопку «+», вбиваем имя (произвольное) и команду (sh /sdcard/apk_backup.sh), в поле Output Type выбираем либо Dialog Output, либо Nothing. В первом случае во время выполнения скрипта на экране появится окно с результатом, во втором все пройдет в фоне. Кому что удобнее. Далее сохраняем и получаем кнопку, с помощью которой скрипт можно будет запустить быстро и легко.
Теперь напишем скрипт, который восстановит наш бэкап:
Почти все команды Android имеют подробную справку
Имея рут, можно даже сделать бэкап настроек всех приложений с помощью копирования и архивации каталога /data/data/, однако восстановить его будет очень проблематично, так как в Android каждое приложение исполняется от имени созданного специально для него Linux-юзера и хранит настройки внутри каталога, принадлежащего этому пользователю. Проблема здесь в том, что идентификатор Linux-юзера для каждого приложения генерируется динамически, поэтому после восстановления бэкапа в заново установленной системе идентификаторы не будут совпадать и приложения не смогут прочитать свои настройки. Придется вручную выяснять ID юзера для каждого приложения и менять права доступа на каталоги с данными.
С другой стороны, мы можем использовать встроенный в Android Backup Manager, позволяющий сторонним приложениям использовать возможности системы для бэкапа и восстановления приложений и их данных. Управлять им можно из консоли (а значит, и с помощью скриптов), но сам по себе он никакого бэкапа не производит, а возлагает эту работу на сторонние приложения. Helium — одно из таких приложений. Если установить и настроить его, операцию бэкапа и восстановления можно будет заскриптовать. Например, следующий простой скрипт сделает резервную копию всех сторонних приложений:
Автозапуск
Другой популярный способ автозапуска — это использование средств автоматического исполнения скриптов при загрузке в сторонних прошивках. Сегодня почти все сколько-нибудь известные кастомные прошивки умеют стартовать скрипты из каталога /system/etc/init.d/, а в стоке такую функциональность можно получить с помощью приложения Universal init.d из маркета. С последним, однако, надо быть осторожным, так как оно запускает скрипты не на раннем этапе загрузки, как это происходит в том же CyanogenMod, а уже после полной загрузки системы.
Итак, что мы можем поместить в автозагрузку? Например, скрипт запуска демона ADB в сетевом режиме:
Для подключения к нему с ПК набираем такую команду:
Также мы можем применить некоторые оптимизации подсистемы виртуальной памяти:
Ну или подогнать механизм lowmemorykiller (автоматическое убийство фоновых приложений при нехватке памяти) под наши нужды:
Ну и конечно же, автоматический выбор планировщика процессов:
Все это можно сделать с помощью специализированного софта, но зачем загружать систему дополнительным ПО, которое еще и будет висеть в фоне, когда можно обойтись несколькими простыми скриптами?
Как запустить скрипт с помощью Tasker
Запуск скриптов до и после установки прошивки
Почти каждый, кто устанавливает на свой гаджет стороннюю прошивку, также ставит поверх нее пакет с фирменными приложениями Google (gapps), который включает в себя маркет, YouTube, Gmail и другой софт. Каждый раз, когда происходит обновление прошивки, раздел /system, содержащий ее и gapps, полностью стирается, но приложения Google всегда остаются на месте. Это происходит потому, что, кроме всего прочего, gapps содержит в своем составе специальный скрипт, который размещается в каталоге /system/addon.d/ и запускается консолью восстановления до и после установки прошивки. Этот скрипт делает бэкап и восстановление приложений Google.
Мы можем использовать эту возможность для выполнения наших собственных действий до и после установки прошивки. Вот так, например, выглядит мой скрипт восстановления, который ничего не бэкапит, но подчищает прошивку от мусора сразу после ее установки:
Скрипт удаляет рингтоны, уведомления, движок синтеза речи и несколько приложений. Все эти действия запускаются в ответ на передачу скрипту опции командной строки restore (это делает консоль восстановления после установки прошивки), однако также предусмотрены и варианты обработки таких опций, как backup, pre-backup, post-backup, pre-restore и post-restore. Здесь это просто заглушки, но если бы мы захотели сделать бэкап некоторых файлов и приложений перед установкой прошивки, мы могли бы добавить их в блок backup, как это сделано в скрипте /system/addon.d/70-gapps.sh:
Этот кусок скрипта прекрасно иллюстрирует, как сделать бэкап файлов. Ключевые элементы здесь: функция listfiles, которая при запуске выводит листинг файлов, и функция backupfile, которая является частью консоли восстановления (определена в файле /tmp/backuptool.functions). Она делает бэкап файлов в цикле.
Содержимое /system/addon.d/ в CyanogenMod 11 на Motorola Defy
Скрипт бэкапа приложений Google
По словам разработчика mksh, изначально пользовательские версии Android-смартфонов вообще не должны были иметь в своем составе шелл, но после выпуска смартфона для разработчиков HTC (T-Mobile) G1 он фактически стал стандартной частью системы.
Версии Android 2.3 и ниже вместо mksh использовали минималистичный шелл ash, который входит в базовый комплект всех BSD-систем.
Чтобы получить одни и те же скрипты на всех устройствах, можно использовать приложение DropSync или FolderSync (автоматическая синхронизация через Dropbox).
Что еще?
С помощью скриптов в Android можно сделать намного больше, чем бэкапы и настройка параметров системы. Вот, например, скрипт, который просыпается каждые десять минут и, если уровень заряда батареи стал меньше 30%, отключает Wi-Fi и Bluetooth:
Чтобы скрипт работал в фоне, достаточно вызвать его следующим образом:
А это скрипт, который позволяет быстро заполнять формы, требующие ввода имэйла и пароля (в приложениях и на веб-сайтах):
Запускать его можно разными способами. Либо перед запуском приложения, установив задержку:
Не ахти как удобно, зато работает. Как мы можем использовать такую функциональность? Например, сделать простенький скрипт clip.sh:
Или просто открыть окно номеронабирателя с нужным номером:
Примерно таким же образом можно отправить SMS:
Скрипт принимает два аргумента: номер телефона и содержимое SMS. После запуска он откроет окно SMS-приложения, вставит в него нужный текст, а затем нажмет кнопку Enter для отправки, после чего окно закроется.
Другие полезные при скриптинге команды:
Вместо выводов
Для кого-то все описанное в статье может показаться несколько надуманным. Дескать, все это можно сделать с помощью стандартного софта и Tasker. Но зачем использовать тяжелый Java-софт там, где нужное действие можно выполнить с помощью простенького скрипта, который не занимает лишней памяти и может быть легко перенесен на другое устройство? Скрипты удобны, просты, быстро отрабатывают и дают возможность тонкой настройки под себя.
Евгений Зобнин
Редактор рубрики X-Mobile. По совместительству сисадмин. Большой фанат Linux, Plan 9, гаджетов и древних видеоигр.
Источник