22 March, 2010

Общение со Skype через D-Bus на Python

Summary: в данной заметке описывается работа с программой Skype через D-Bus на Python.

Введение

Захотелось мне странного - когда я ухожу домой, мне нужно выключить amarok, kopete и Skype. Собственно, решено было через D-Bus отправлять вышеперечисленным приложениям релевантные сообщения.

Используем dbus-send

Сначала я использовал обычный dbus-send, что оформилось в виде следующего скрипта go2home:

#!/bin/sh

# Stop amarok
dbus-send --session --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop

# Logout from kopete
dbus-send --session --type=method_call --dest=org.kde.kopete /Kopete org.kde.Kopete.disconnectAll 

# Logout from Skype
skypeapi.py 'SET USERSTATUS OFFLINE'

# Lock screen
dbus-send --session --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Lock
Детали и параметры работы команды dbus-send описаны в man-странице

Проблема со скайпом

Со скайпом пришлось немного повозиться, так как для работы с ним необходима постоянная сессия, что нельзя сделать с помощью dbus-send.

Прочитав описание протокола на сайте

был создан нижеследующий скрипт: skypeapi.py

#!/usr/bin/env python
import dbus, sys

def main():
    remote_bus = dbus.SessionBus()
    
    # Check if skype is running.
    system_service_list = remote_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus').ListNames()
    skype_api_found = 0
    for service in system_service_list:
        if service=='com.Skype.API':
            skype_api_found = 1
            break
    if not skype_api_found:
        sys.exit('No running API-capable Skype found')

    # Get skype dbus api
    skype_service = remote_bus.get_object('com.Skype.API', '/com/Skype')

    # Connect to skype.
    answer = skype_service.Invoke('NAME SkypeApiClient')
    if answer != 'OK':
        sys.exit('Could not bind to Skype client')

    # Check if protocol is supported.
    answer = skype_service.Invoke('PROTOCOL 1')
    if answer != 'PROTOCOL 1':
        sys.exit('This test program only supports Skype API protocol version 1')

    # Invoke operations
    for arg in sys.argv:
        skype_service.Invoke(arg)
    
    return 0    

if __name__ == "__main__":
    main()

При первом запуске скрипта появится скайповский диалог с вопросом, можно ли разрешить приложению доступ к скайпу. После нажатия на "Да" Skype добавит наш скрипт в разрешённые и мы сможем управлять скайпом.

После этого для скрипта go2home был создана иконка на панели.

Заключение

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

4 comments:

  1. То есть по нажатию кнопки выключались три приложения, правильно?!

    ReplyDelete
  2. @karri Не выключались, а только меняли статус. :) Амарок прекращал играть, скайп и kopete уходили в оффлайн.

    ReplyDelete
  3. Написать
    skype_api_found = False

    религия не позволила?

    ReplyDelete
    Replies
    1. В данном случае это не так уж и важно.

      Delete