Konversation/Скрипти/Підручник щодо скриптів

From KDE Wiki Sandbox
This page is a translated version of the page Konversation/Scripts/Scripting guide and the translation is 100% complete.
Other languages:

Вступ

У Konversation передбачено вбудовану підтримку запуску зовнішніх скриптів на основі якої, разом з використанням D-Bus та власних методів D-Bus Konversation, уможливлює керування у найпоширеніших випадках використання скриптів, зокрема показ даних у поточному вікні балачки або керування іншими програмами або навіть самою програмою Konversation. На цій сторінці ви знайдете основі відомості щодо написання скриптів Konversation. Тут наведено лише основні початкові відомості. Дані з використання особливостей мов програмування та операційних систем ви можете здобути самі з відповідної навчальної літератури.

Вимоги

Все, що вам знадобиться, — це текстовий редактор і інтерпретатор мови програмування або скриптів. У Konversation передбачено підтримку будь-якої мови програмування, інтерпретатор якої задовольняє таким вимогам:

  1. Може приймати і обробляти аргументи командного рядка (argv).
  2. Може встановлювати з’єднання і викликати D-Bus або принаймні виконувати зовнішні системні виклики (зокрема виконання програми qdbus). Ймовірно, краще і безпечніше використовувати вбудовані прив’язки D-Bus, якщо такі є, а не виконання системних викликів для запуску qdbus.

У поточній версії перевірено працездатність скриптів мовами Python, BASH (або командної оболонки) та Perl. Приклади скриптів цими мовами є частиною пакунків з Konversation. Але ви можете скористатися будь-якою іншою мовою, яка задовольняє викладені вище вимоги. На цій сторінці всі приклади наведено мовою Python.

Завдання 1. Показ даних у поточному вікні спілкування

Ймовірно, найтиповішим сценарієм для скрипту є отримання певного тексту для показу його на поточній вкладці Konversation (каналі або особистому діалозі) з даними, які зазвичай надходять із зовнішнього джерела. Джерелом може бути сам скрипт, інша програма (як у скрипті media, включеному у Konversation) або дані інтернету (зокрема отримання даних щодо погоди і показу їх у Konversation). Яким би не було джерело, слід виконати три дії:

  1. Отримати вхідні дані — отримати і обробити команду, надіслану користувачем з вікна Konversation.
  2. Обробити дані — зібрати дані з джерела і обробити їх відповідно до надісланої користувачем команди.
  3. Надіслати дані — повернути дані назад до Konversation за допомогою D-Bus.

У наведеному нижче прикладі скрипт Konversation виконує саме ці три дії.


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mood — скрипт Konversation для показу дотепного зауваження щодо настрою користувача.
# Використання: /exec mood [рядок_настрою]

import sys
import subprocess

command = ['qdbus', 'org.kde.konversation', '/irc']

argc = len(sys.argv)

if argc < 2:
    command.append("error")
    text = "Server required"
elif argc < 3:
    command.append("error")
    text = "Target required"
elif argc < 4:
    command.append("error")
    text = "No mood given"
else:
    server = sys.argv[1]
    target = sys.argv[2]
    mood   = sys.argv[3]

    if mood == "hungry":
        text = "Голодний! Зараз з’їм вашого коня!"
    elif mood == "sleepy":
        text = "Позіхаю, хочу спати."
    elif mood == "gloomy":
        text = "Троянди червоні. Нудьга чорна і моя нудьга теж..."
    elif mood == "happy":
        text = "Обдумую щасливі думки (навкруги кружляють феї щастя)."
    elif mood == "hyper":
        text = "Лише ложка цукру? Мені потрібен цілий пакунок!"
    elif mood == "excited":
        text = "Ми вже на місці? Ми вже на місці? Ми вже на місці?"
    else:
        text = "А про що ми, власне, вели розмову?"

        command.append("say")
        command.append(server)
        command.append(target)

command.append(text)

subprocess.Popen(command).communicate()

Отримання вхідних даних

Якщо програма Konversation викликає зовнішній скрипт, вона має передати йому декілька попередньо визначених аргументів, ось так:

назва_скрипту сервер призначення [додаткові аргументи...]

Аргументи зазвичай зберігаються у збірці (списку або масиві, залежно від мови), яка називається "argv", пронумеровані від 0 до N, де N — кількість аргументів.

  • argv[0] завжди має значення назви самого скрипту. Здебільшого ігнорується.
  • argv[1] — адреса сервера, з яким з’єднано користувача. Якщо з’єднання встановлено з багатьма серверами, сервер, з яким з’єднано канал або вікно діалогу.
  • argv[2] — призначення, назва вікна спілкування, з якого надійшла команда щодо виконання скрипту, найчастіше те саме вікно, у якому буде показано виведені дані. Звичайно ж, ви можете змінити значення цього аргументу.
  • від argv[3] до argv[N] будь-які додаткові аргументи, які буде надіслано користувачем, який віддав команду виконання скрипту за допомогою Konversation. Цими аргументами може бути будь-що від прапорців для вмикання або вимикання дій у скрипті до даних або тексту, який слід показати у даних, виведених скриптом. Додаткові аргументи передбачено не у всіх скриптах. Прикладами скриптів без додаткових аргументів є uptime та sysinfo.
Пам’ятайте!
Навіть якщо ваш скрипт не потребує додаткових аргументів або користувач не вказує цих аргументів, Konversation завжди надсилатиме аргументи системи та призначення. Тобто argv[1] і argv[2] завжди буде встановлено. Мінімальною кількістю аргументів завжди буде 3 (не забувайте, що нумерація починається з 0).


Обробка даних

У нашому прикладі скрипту змінна mood, яку вказує користувач як argv[3] скрипту, порівнюється з попередньо визначеними значеннями, після чого змінній text надається відповідне значення. Це простий приклад обробки даних. Ви також можете отримувати дна з попередньо визначеного джерела, подібно до того, як це робить скрипт fortune, або збирати дані з операційної системи, як це робить скрипт sysinfo. Які б дані або текст вам не потрібно було показати у Konversation, їх можна визначити у скрипті.

Попередження
Невеличке попередження: будьте обережні зі виведенням багаторядкових повідомлень, оскільки на сервері або каналі, якими ви користуєтеся, можуть бути жорсткі правила щодо розмірів повідомлень (захист від переповнення). Якщо розмір даних може бути доволі значним, краще подати їх у іншому форматі (подібно до текстового редактора).


Тепер, коли потрібні дані оброблено та зібрано, час підготувати їх до надсилання до вікна Konversation. Питання надсилання ми обговоримо у наступному розділі.

Надсилання вихідних даних

Керування Konversation ззовні, зі скрипту чи з командного рядка, пов’язане з використанням методів D-Bus програми. У Konversation передбачено декілька методів, зокрема методи, призначені для показу повідомлень. Надсилання повідомлень D-Bus — справа доволі непроста. На щастя, у Qt передбачено набагато простіший спосіб виконання цього завдання, за допомогою програми "qdbus". Якщо не надто заглиблюватися, всі команди D-Bus, які ми надсилатимемо Konversation з метою показу повідомлень, починатимуться з такого рядка: qdbus org.kde.konversation /irc

Залежно від типу повідомлення, яке надсилатиме скрипт, до команди буде додано додаткові параметри. Ось приклад:

 qdbus org.kde.konversation /irc say сервер призначення повідомлення

Це, ймовірно, команда, яку використовують найчастіше. Команда надсилає «повідомлення» до вікна спілкування «призначення», з’єднаного з сервером «сервер». Якщо повідомлення слід надіслати до того самого вікна, з якого викликано скрипт, скористайтеся змінними argv[1] та argv[2] на місці сервера і призначення, відповідно. Звичайно ж, ви завжди можете змінити призначення на будь-який канал або псевдонім, потрібний вам на певному сервері.

 qdbus org.kde.konversation /irc error повідомлення

За допомогою цієї команди можна показати «повідомлення» у тому самому вікні спілкування, з якого було викликано скрипт. Відмінність полягає у тому, що повідомлення не буде надіслано безпосередньо на сервер IRC, бачитиме його лише користувач скрипту. Повідомлення також буде форматовано: "[D-Bus] Помилка: повідомлення". Цей спосіб корисний для інформування користувача про помилки у використанні скрипту або помилки, які виникли під час виконання самого скрипту. Вказувати призначення у команді не потрібно.

 qdbus org.kde.konversation /irc sayToAll повідомлення

Надіслати повідомлення до всіх каналів та вікон діалогів на всіх серверах. Слід використовувати обережно з врахуванням правил етикету. Сервер і вікно призначення вказувати не потрібно.

 qdbus org.kde.konversation /irc actionToAll повідомлення

Близнюк дії sayToAll. Надсилає повідомлення на всі канали і до всіх вікон діалогів на всіх серверах, але додає перед повідомленням «/me». В результаті користувачі побачать "*ваш_псевдонім повідомлення*". Знову ж таки, врахуйте правила етикету.

Зауваження
Щоб надіслати повідомлення про дію (з «/me») лише у вікно поточного спілкування (звідки було викликано скрипт), створіть текстову частину у форматі «/me повідомлення», а потім скористайтеся командою say (перша у списку, якщо ви не помітили ).


Передбачено і інші пов’язані з /irc команди qdbus, деякі з них змінюють стан користувача у мережі замість показу повідомлень. Дослідіть самі всі можливості. За допомогою ще однієї з програм Qt, "qdbusviewer", ви зможете переглянути у графічному інтерфейсі повний список всіх команд керування Konversation та інших програм, які використовують D-Bus. Такі команди знадобляться вам для наступного скриптового сценарію, описаного нижче.

Запуск скрипту

Тепер можна зробити так, щоб скриптом можна було скористатися у Konversation. Ось що треба зробити:

  • Надайте скрипту право виконуватися. Для цього достатньо команди

chmod +x script_name. Варто не додавати суфікса до назви вашого скрипту (.sh, .py, .pl тощо), щоб скрипт простіше було викликати.

  • Розташуйте скрипт одній з двох тек:
    • Якщо вашим скриптом будуть користуватися всі користувачі системи, скопіюйте його до теки, у якій зберігаються інші скрипти, встановлені разом з Konversation. Точна адреса теки залежить від вашого дистрибутива (або ваших особистих налаштувань), типовою є адреса /usr/share/apps/konversation/scripts/. Якщо такої теки у вашій системі немає, спробуйте скористатися даними, виведеними командою kde4-config --install data, додавши до назви теки /konversation/scripts/. Порадьтеся з каналом підтримки дистрибутива, якщо і так не вдасться визначити потрібну адресу.
    • Якщо скриптом користуватиметеся лише ви, просто скопіюйте його до ~/.kde/share/apps/konversation/scripts/. У деяких дистрибутивах все ще використовується тека, ~/.kde4/. Виправте адресу, якщо у вашому дистрибутиві використано саме цю теку.
    • Зауваження щодо версій, новіших за 1.3.1: ще одним способом визначення теки, куди встановлено скрипти, є така команда, віддана у рядку введення повідомлення Konversation (у нашому прикладі використано скрипт media, оскільки цей скрипти встановлюється разом з Konversation): /exec --showpath media. Зауважте, що якщо існує два скрипти з однаковими назвами, один у домашній теці користувача і один у загальносистемній теці, пріоритет матиме скрипт з теки користувача, саме його адресу буде показано у відповідь на вказану вище команду.
  • Для виконання скрипту вам слід викликати його з командного рядка Konversation:

/exec назва_скрипту [додаткові аргументи]

Ця команда викличе ваш скрипт і передасть йому аргументи. Зауважте, що значенням argv[0] завжди буде «назва_скрипту», а назву сервера та вікна спілкування буде передано як argv[1] і argv[2], навіть якщо ви не вкажете значення цих змінних у вашій команді. Тому додаткові аргументи буде передано як argv[3] тощо.

  • Для полегшення користування ви можете створити у Konversation псевдоніми (скорочення) команд. Тоді ваш скрипт можна буде виликати за допомогою команди /назва_скрипту замість наведеного вище загального варіанта. Для додавання псевдоніма вручну, скористайтеся сторінкою Параметри -> Налаштувати Konversation -> Скорочення команд. Натисніть кнопку Створити і вкажіть «назву_скрипту» у полі Замінник' і "/exec script_name" у полі Заміна. Надалі ви зможете запускати ваш скрипт за допомогою команди /назва_скрипту [аргументи]
  • Крім того, під час запуску Konversation програма автоматично створюватиме замінники команд у форматі "/назва_скрипту" для "/exec назва_скрипту" всіх скриптів, які буде знайдено у теках scripts/ тек, про які ми говорили раніше.

Для скрипту, описаного у нашому попередньому прикладі, назвою буде "mood", а викликати скрипт можна буде командою /mood [настрій] або /exec mood [настрій], ось так:

/mood gloomy

Це в основному все, що вам потрібно знати для створення скрипту Konversation. Щоб додати ще трохи цікавинки, розгляньмо інший поширений випадок використання скриптів.

Завдання 2. Керування зовнішньою програмою з вікна Konversation

Завдяки D-Bus та тому, що у багатьох програмах KDE передбачено можливість використання методів D-Bus, ви можете керувати будь-якою програмою KDE безпосередньо з вікна Konversation. Навіть без D-Bus ви, за допомогою свого скрипту, можете запускати, зупиняти та навіть керувати іншими програмами простою командою Konversation. Таким чином можна виконувати безліч завдань, зокрема надсилати команду емулятору термінала, відкривати повідомлення щодо вад у вікні переглядача за номером звіту щодо вади (як це реалізовано у скрипті bug) або просто виконати системну команду (і можливо показати результати її виконання, як це робить скрипт cmd).

Наведений вище скрипт реалізує першу можливість. Він розкриває вікно Yakuake і виконує у ньому вказану користувачем команду. Скрипт доволі примітивний: він не показуватиме виведених даних користувачеві, хіба що станеться помилка у самому скрипті.

#!/usr/bin/env python
# yakrun — скрипт Konversation, який виконує вказану користувачем команду у Yakuake і перемикає стан Yakuake
# Використання: /exec yakrun [команда]

import sys
import subprocess

errorCommand  = ['qdbus', 'org.kde.konversation', '/irc', 'error']
toggleCommand = ['qdbus', 'org.kde.yakuake', '/yakuake/window', 'toggleWindowState']
runCommand    = ['qdbus', 'org.kde.yakuake', '/yakuake/sessions', 'runCommand']

argc = len(sys.argv)

if argc < 4:
    text = "Не вказано команди."

    errorCommand.append(text)

    subprocess.Popen(errorCommand).communicate()
else:
    command = " ".join(sys.argv[3:])

    runCommand.append(command)

    subprocess.Popen(toggleCommand).communicate()
    subprocess.Popen(runCommand).communicate()

Нотатки щодо використання певних мов

  • Будьте обережними з обробкою аргументів і збиранням їх до одного рядка з пробілами. Подібні дії можуть призвести до повідомлень про помилки у деяких мовах програмування, зокрема BASH.