Рубрики
Без рубрики

Введение в разработку расширения Ulauncher

Ulauncher – это расширяемая и современная установка приложения для Linux. В этом посте я сделаю быстрое введение в Ulauncher, а затем продемонстрировать, как построить простую расширение конвертации валюты. Помечено Ulauncher, Linux, Tools, Python.

Привет. В этом посте я познакомимся с Ulauncher. И продемонстрировать, насколько просто это создать расширение для него.

Мы построим расширение «конвертации валюты», которое будет выглядеть так:

Следите за обновлениями.

Что такое Ulauncher?

Ulauncher Это задержка приложения с открытым исходным кодом для Linux. Он написан в Python 2 и имеет много приятных функций, таких как ярлыки, расширения и пользовательские темы.

ИМО, это один из лучших пусковых установок для Linux прямо сейчас, и это самая близкая вещь, которую я узнал на MacOS Альфред Отказ Альфред его просто удивительно, и я действительно не понимаю, как там нет популярных альтернатив для Linux. Будучи инструментом Mac, люди Linux не знают об этом или не чувствуют необходимости? Я попробовал несколько альтернатив, таких как синапс, Альберт, Зазу, Деккс, Церебро, каждый со своими плюсами и минусами, пока я наконец-то не нашел Улаунчтер, который я кладу всех лошадей.

Помимо основных функций, одна из вещей, которые заставляет Альфред настолько потрясающе ее сообщество и количество расширений. Вы можете буквально найти все, что уже сделано на таких сайтах, как Упаковка Отказ Ulauncher и другие пусковые установки Linux отсутствуют этой популярности и интересам сообщества.

Это одна из причин, по которой я решил написать этот пост. Чтобы попытаться заработать людей в курсе Ulauncher и вносить вклад как к ядру, либо с расширениями, надеясь, что мы, наконец, сможем увидеть популярный Linux Launcher.

Вы можете увидеть все доступные расширения здесь Отказ

Хорошо, давайте начнем писать расширение.

Предварительные условия

  • У вас должен быть установлен Ulauncher на вашем компьютере. Вы можете найти инструкции по установке в здесь Отказ
  • Требуется базовые знания питона.

Что такое расширение?

От Веб-сайт документации по расширению Ulauncher :

Расширения Ulauncher – это программы Python 2, которые работают как отдельные процессы вместе с приложением.

Когда вы запустите Ulauncher, он запускает все доступные расширения, поэтому они готовы реагировать на пользовательские события. Все расширения прекращаются, когда приложение Ulauncher закрыто или разбито.

В основном расширение состоит из «ключевого слова», который запускает расширение и набор событий и действий.

Некоторые из доступных событий включают в себя:

  • Ценннрукетэверс – срабатывает, когда пользователь ввода текста на Ulauncher
  • ItementereVent – срабатывает, когда пользователь выбирает элемент в Ulauncher
  • ПредпочтениеUpdateEvent – срабатывает, когда пользователь обновляет настройки расширений.

Вы можете прослушать эти события в расширении, и вы можете ответить на действия. Доступные действия включают в себя:

  • Copytoclipboardactiona
  • Запуску
  • OpenUrlation.
  • Руководство
  • Setuserqueryaction.

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

Создайте наше первое расширение

Далее я буду указывать на шаг за шагом, чтобы создать ваше первое расширение. Я покажу вам процесс разработки Это расширение. Это простое расширение, которое позволяет преобразовать значение между двумя валютами, использующими Фиксатор API.

Мы будем использовать это Демо расширение в качестве основы для этого расширения.

Ulauncher ищет расширения в «~/.Cache/Ulauncher_cache/Extensions/». Вы можете закрыть туда напрямую, но я предпочитаю иметь все мои расширения в другом месте, а затем просто симличия их в папку расширений.

С целью этого учебника мы будем развиваться непосредственно в «папке расширений».

Итак, откройте окно терминала и введите:

cd ~/.cache/ulauncher_cache/extensions/
git clone https://github.com/Ulauncher/ulauncher-demo-ext demo-extension

Если у вас есть Ulauncher работает, закройте его и запустите с терминала ulauncher. -v . Это запустит ULAUNCHER в Verbose Mode, очень полезен для разработки, как позволит увидеть любые журналы или ошибки для всех установленных расширений.

Наконечник: Если у вас установлено много расширений, будет трудно обнаружить журналы вашего расширения. Вы можете использовать «GREP», чтобы фильтровать вывод, например:

ulauncher -v |& grep -A 5 "ulauncher-currency"

Если вы вводите «DM» на окне Ulauncher, вы должны увидеть демонстрацию демонстрации DEMO.

Примечание. После изменения кода в расширении, просто «Ctrl-C» в вашем терминале, чтобы остановить Ulauncher и запускать его снова, используя «ULAUNCHER -V».

Теперь откройте проект в вашем редакторе и давайте начнем разработку.

В вашем расширении существуют основные файлы. “Манифест.json” и “main.py”. Файл Mainest – это то, где вы определяете, ваша расширение информации, ключевое слово, которое запускает его, а также любые другие предпочтения, которые вы хотите, чтобы ваши пользователи могли настроить.

Так что обновите свой файл mainest и измените значение «Имя» и «значение по умолчанию» в настройках ключевых слов:

 {
            "id": "kw",
            "type": "keyword",
            "name": "Currency Converter",
            "default_value": "currency"
 },

«Default_Value» – это само по себе ключевое слово, которое будет вызвать ваше расширение. «Имя» – это значение, которое появится, когда вы ищете внутри Ulauncher.

Мы вернемся к этому файлу позже.

Если вы перезагружаете Ulauncher, вы теперь должны быть в состоянии запустить демонстрацию демонстрации с ключевым словом «Валюта» вместо ключевого слова «DM».

Вы можете узнать больше о доступных параметрах в Mainest.json здесь Отказ

Теперь давайте открытым «Main.py». Это где ваш расширенный код живет. Поскольку это расширение довольно простое, мы будем кодировать все в этом файле. Для более сложных расширений можно будет разделить свой код в несколько файлов или модулей.

Main.py содержит кучу импорта в верхней части, а затем класс расширения, с методом init:

def __init__(self):
        super(DemoExtension, self).__init__()
        self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())
        self.subscribe(ItemEnterEvent, ItemEnterEventListener())

Это метод конструктора вызывается при запуске вашего расширения. Любая логика инициализации и подписка для событий должна быть размещена здесь.

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

class KeywordQueryEventListener(EventListener):

    def on_event(self, event, extension):
        items = []
        logger.info('preferences %s' % json.dumps(extension.preferences))
        for i in range(5):
            item_name = extension.preferences['item_name']
            data = {'new_name': '%s %s was clicked' % (item_name, i)}
            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name='%s %s' % (item_name, i),
                                             description='Item description %s' % i,
                                             on_enter=ExtensionCustomAction(data, keep_app_open=True)))

        return RenderResultListAction(items)

Это похоже на основную точку входа для вашего расширения. Каждый раз, когда пользователь вводит текст в ULAUNCHER, после вашего ключевого слова расширения он будет вызвать метод «on_Event» этого класса. Аргумент «События» содержит данные о событии, как, например, текст, ввенный пользователем. ” event.get_argument () “. Аргумент «расширения» позволяет получить доступ к способам и свойствам, которые вы определяете в своем классе расширения, а также на предпочтениях расширения.

Этот метод всегда должен вернуть список «ExtellyResultItem». ” ExtercieldResultItem »представляет собой элемент в списке результатов и содержит, как свойства, такие как« Имя »,« Описание »,« Иконка »и« On_enter », который будет функцией, которая будет обрабатывать выбор элемента.

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

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

Увеличение уланктер – это просто это. События и действия.

Теперь давайте начнем писать ваше расширение. Сначала давайте обновим наш файл манифеста с новым полевым полем для «API_KEY». Это поле требуется для использования API Fixer, чтобы получить обменные курсы. Также удалите все из демонстрации, помимо «ключевого слова» предпочтения.

Наши окончательные показатели предпочтения будут выглядеть так:

    "preferences": [{
            "id": "kw",
            "type": "keyword",
            "name": "Currency Converter",
            "description": "Currency Conversion",
            "default_value": "currency"
        },
        {
            "id": "api_key",
            "type": "input",
            "name": "Fixer API key",
            "description": "API key for Fixer.io API. Get yours here",
            "default_value": ""
        }
    ]

Далее в вашем «Main.py», замените все ссылки на «Демо» с «CommentConverter», а также удалитететелентеревент, который нам не понадобится.

Мы добавим метод в класс валютного контроллератекса, который получит «сумму», «из_Currence» и «to_currence» и вернуть сумму, преобразующую в «to_currence». Вот как класс расширения выглядит с этим изменениями:

class CurrencyConverterExtension(Extension):

    def __init__(self):
        super(CurrencyConverterExtension, self).__init__()
        self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())

    def convert_currency(self, amount, from_currency, to_currency):
        """ Converts an amount from one currency to another """

        params = {'access_key': self.preferences['api_key'], 'symbols': '%s,%s' % (
            from_currency, to_currency)}

        r = requests.get("http://data.fixer.io/api/latest", params=params)
        response = r.json()

        if r.status_code != 200:
            raise ConversionException(
                "Error connecting to conversion service.")

        if not response['success']:
            raise ConversionException(response['error']['info'])

        # Calculate the amount from the conversion rates.
        # Fixer.io base Currency is Eur.
        rates = response['rates']

        result = (float(amount) / rates[from_currency]) * rates[to_currency]

        return str(round(result, 2))

Единственная логика SELAUNCHER в этом методе является эта строка:

self.preferences['api_key']

Это более простой способ получить доступ к вашим настройкам расширений. Тем не менее, Там могут быть случаи, когда вы не хотите получить доступ к ней каждый раз и хотите, чтобы он хранился в недвижимости на расширении. Для этого вы можете слушать «ПредпочтениеUpDateEvent» и «Предпочтителен», который будет срабатывать, когда предпочтения в первую очередь загружаются и когда пользователь обновляет их в настройках расширения для реального примера, см. здесь Отказ

Остаток его просто обычный код Python, который использует библиотеку «запросов» для выполнения вызова API для Fixer API для получения обменных курсов и выполнить преобразование.

Мы также создали пользовательский класс «ConversionException», который мы будем бросать в случае ошибки.

Добавьте это в конец файла, перед «если Имя == ‘ Главная ‘ ‘Line:

class ConversionException(Exception):
    """ Exception thrown when there was an error calling the conversion API """
    pass

Ok. Теперь нам нужно реализовать наше «слушатель события ключевых слов ключевых слов».

Наше расширение будет вести себя так. Пользователю нужно будет ввести выражение, как «20 долларов США до EUR», чтобы вызвать преобразование. Мы будем использовать Regex, чтобы соответствовать этому. После матча с выражением мы вызовем метод «Convert_Currence», который мы определили в нашем классе расширения и оказывают результат.

Итак, вот окончательный код для «KeyboardQueryEventListener:

class KeywordQueryEventListener(EventListener):

    def on_event(self, event, extension):
        items = []

        regex = r"(\d+\.?\d*)\s([a-zA-Z]{3})\sto\s([a-zA-Z]{3})"
        query = event.get_argument() or ""

        matches = re.findall(regex, query, re.IGNORECASE)

        if not matches:
            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name='Keep typing your query ...',
                                             description='It should be in the format: "20 EUR to USD"',
                                             highlightable=False,
                                             on_enter=HideWindowAction()))

            return RenderResultListAction(items)

        try:
            params = matches[0]

            amount = params[0]
            from_currency = params[1].upper()
            to_currency = params[2].upper()

            value = extension.convert_currency(
                amount, from_currency, to_currency)

            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name="%s %s" % (
                                                 value, to_currency),
                                             highlightable=False,
                                             on_enter=CopyToClipboardAction(value)))

            return RenderResultListAction(items)

        except ConversionException as e:
            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name='An error ocurred during the conversion process',
                                             description=e.message,
                                             highlightable=False,
                                             on_enter=HideWindowAction()))

            return RenderResultListAction(items)

Это довольно просто понять, если вы знаете Python. Мы получаем текст пользователя, используя: метод «Event.get_argument ()», а затем мы видим, соответствует ли он нашему Regex.

Если нет, мы просто отображаем сообщение для пользователя, чтобы сохранить ввод. Если это соответствует, мы извлекаем каждые части из нашего Regex и вызовите метод «Convert_Currence». В конце концов мы всегда возвращаем список «ExteliveResultItem».

Так вот как последний «Main.py» выглядит как:

import requests
import re
from ulauncher.api.client.Extension import Extension
from ulauncher.api.client.EventListener import EventListener
from ulauncher.api.shared.event import KeywordQueryEvent
from ulauncher.api.shared.item.ExtensionResultItem import ExtensionResultItem
from ulauncher.api.shared.action.RenderResultListAction import RenderResultListAction
from ulauncher.api.shared.action.HideWindowAction import HideWindowAction
from ulauncher.api.shared.action.CopyToClipboardAction import CopyToClipboardAction

class CurrencyConverterExtension(Extension):

    def __init__(self):
        super(CurrencyConverterExtension, self).__init__()
        self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())

    def convert_currency(self, amount, from_currency, to_currency):
        params = {'access_key': self.preferences['api_key'], 'symbols': '%s,%s' % (
            from_currency, to_currency)}

        r = requests.get("http://data.fixer.io/api/latest", params=params)
        response = r.json()

        if r.status_code != 200:
            raise ConversionException(
                "Error connecting to conversion service.")

        if not response['success']:
            raise ConversionException(response['error']['info'])

        # Calculate the amount from the conversion rates.
        # Fixer.io base Currency is Eur.
        rates = response['rates']

        result = (float(amount) / rates[from_currency]) * rates[to_currency]

        return str(round(result, 2))


class KeywordQueryEventListener(EventListener):

    def on_event(self, event, extension):
        """ Handles the event """
        items = []

        regex = r"(\d+\.?\d*)\s([a-zA-Z]{3})\sto\s([a-zA-Z]{3})"
        query = event.get_argument() or ""

        matches = re.findall(regex, query, re.IGNORECASE)

        if not matches:
            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name='Keep typing your query ...',
                                             description='It should be in the format: "20 EUR to USD"',
                                             highlightable=False,
                                             on_enter=HideWindowAction()))

            return RenderResultListAction(items)

        try:
            params = matches[0]

            amount = params[0]
            from_currency = params[1].upper()
            to_currency = params[2].upper()

            value = extension.convert_currency(
                amount, from_currency, to_currency)

            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name="%s %s" % (
                                                 value, to_currency),
                                             highlightable=False,
                                             on_enter=CopyToClipboardAction(value)))

            return RenderResultListAction(items)

        except ConversionException as e:
            items.append(ExtensionResultItem(icon='images/icon.png',
                                             name='An error ocurred during the conversion process',
                                             description=e.message,
                                             highlightable=False,
                                             on_enter=HideWindowAction()))

            return RenderResultListAction(items)


class ConversionException(Exception):
    pass


if __name__ == '__main__':
    CurrencyConverterExtension().run()

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

Вы можете установить окончательную версию этого расширения здесь Отказ

Вот и все. Как вы можете увидеть его действительно простой процесс. Надеюсь, что это было достаточно ясно, и я получаю ваш интерес к самой системе Ulauncher и его расширению.

Надеюсь увидеть количество расширений, идущих вверх;)

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

Спасибо!

Оригинал: “https://dev.to/brpaz/an-introduction-to-ulauncher-extension-development-1m69”