now_listen.py 5.92 KB
Newer Older
Dicson's avatar
Dicson committed
1 2
# -*- coding: utf-8 -*-

Dicson's avatar
Dicson committed
3 4
from gi.repository import Gtk
from gi.repository import Gdk
5
import os
Dicson's avatar
Dicson committed
6 7 8 9

from plugins import GajimPlugin
from plugins.helpers import log_calls
from plugins.gui import GajimPluginConfigDialog
Tomasz Miąsko's avatar
Tomasz Miąsko committed
10
from plugins.gajimplugin import GajimPluginException
Dicson's avatar
Dicson committed
11 12 13 14 15 16 17 18 19
from common import dbus_support

if dbus_support.supported:
    from music_track_listener import MusicTrackListener

class NowListenPlugin(GajimPlugin):

    @log_calls('NowListenPlugin')
    def init(self):
Dicson's avatar
Dicson committed
20 21
        self.description = _('Copy tune info to conversation input box '
            '(alt + n) at cursor position')
Dicson's avatar
Dicson committed
22 23 24 25 26
        self.config_dialog = NowListenPluginConfigDialog(self)
        self.gui_extension_points = {'chat_control_base':
            (self.connect_with_chat_control, self.disconnect_from_chat_control)}

        self.config_default_values = {
Dicson's avatar
Dicson committed
27 28
        'format_string': ('Now listen:"%title" by %artist from %album', ''),
        'format_string_http': ('Now listen:"%title" by %artist', ''),}
Dicson's avatar
Dicson committed
29 30 31 32

        self.controls = []
        self.first_run = True
        self.music_track_changed_signal = None
33 34 35
        if os.name == 'nt':
            self.available_text = _('Plugin can\'t be run under Windows.')
            self.activatable = False
Dicson's avatar
Dicson committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

    @log_calls('NowListenPlugin')
    def connect_with_chat_control(self, chat_control):
        self.chat_control = chat_control
        control = Base(self, self.chat_control)
        self.controls.append(control)

    @log_calls('NowListenPlugin')
    def disconnect_from_chat_control(self, chat_control):
        for control in self.controls:
            control.disconnect_from_chat_control()
        self.controls = []

    @log_calls('NowListenPlugin')
    def activate(self):
        if not dbus_support.supported:
52
            raise GajimPluginException(_('python-dbus is missing!'))
Dicson's avatar
Dicson committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
        listener = MusicTrackListener.get()
        if not self.music_track_changed_signal:
            self.music_track_changed_signal = listener.connect(
                'music-track-changed', self.music_track_changed)
        track = listener.get_playing_track()
        self.music_track_changed(listener, track)

    @log_calls('NowListenPlugin')
    def deactivate(self):
        if dbus_support.supported:
            listener = MusicTrackListener.get()
            if self.music_track_changed_signal:
                listener.disconnect(self.music_track_changed_signal)
                self.music_track_changed_signal = None

    def music_track_changed(self, unused_listener, music_track_info,
        account=None):
        is_paused = hasattr(music_track_info, 'paused') and \
            music_track_info.paused == 0
        if not music_track_info or is_paused:
            self.artist = self.title = self.source = ''
        else:
            self.artist = music_track_info.artist
            self.title = music_track_info.title
            self.source = music_track_info.album
Dicson's avatar
Dicson committed
78 79 80 81 82
            if hasattr(music_track_info, 'url'):
                self.url = music_track_info.url
                self.albumartist = music_track_info.albumartist
            else:
                self.url = ''
Dicson's avatar
Dicson committed
83 84 85 86 87 88


class Base(object):
    def __init__(self, plugin, chat_control):
        self.plugin = plugin
        self.chat_control = chat_control
Dicson's avatar
Dicson committed
89 90
        self.plugin.artist = self.plugin.title = self.plugin.source = ''
        self.plugin.url = self.plugin.albumartist = ''
Dicson's avatar
Dicson committed
91

Dicson's avatar
Dicson committed
92
        self.id_ = self.chat_control.msg_textview.connect('key_press_event',
Dicson's avatar
Dicson committed
93 94 95 96
            self.on_insert)
        self.chat_control.handlers[self.id_] = self.chat_control.msg_textview

    def disconnect_from_chat_control(self):
97 98
        if self.id_ not in self.chat_control.handlers:
            return
Dicson's avatar
Dicson committed
99 100 101 102
        if self.chat_control.handlers[self.id_].handler_is_connected(self.id_):
            self.chat_control.handlers[self.id_].disconnect(self.id_)
            del self.chat_control.handlers[self.id_]

Dicson's avatar
Dicson committed
103
    def on_insert(self, widget, event):
Dicson's avatar
Dicson committed
104 105 106
        """
        Insert text to conversation input box, at cursor position
        """
Dicson's avatar
Dicson committed
107
        if event.keyval != Gdk.KEY_n:
Dicson's avatar
Dicson committed
108
            return
Dicson's avatar
Dicson committed
109
        if not event.state & Gdk.ModifierType.MOD1_MASK:  # ALT+N
Dicson's avatar
Dicson committed
110 111 112 113 114
            return

        if self.plugin.artist == self.plugin.title == self.plugin.source == '':
            tune_string = 'paused or stopped'
        else:
Dicson's avatar
Dicson committed
115 116 117 118
            format_string = self.plugin.config['format_string']
            if self.plugin.url and not self.plugin.url.startswith('file://'):
                format_string = self.plugin.config['format_string_http']
            tune_string = format_string.replace(
Dicson's avatar
Dicson committed
119
            '%artist', self.plugin.artist).replace(
Dicson's avatar
Dicson committed
120 121
            '%title', self.plugin.title).replace('%album',self.plugin.source).\
            replace('%url', self.plugin.url)
Dicson's avatar
Dicson committed
122 123

        message_buffer = self.chat_control.msg_textview.get_buffer()
124
        message_buffer.insert_at_cursor(tune_string)
Dicson's avatar
Dicson committed
125
        self.chat_control.msg_textview.grab_focus()
Dicson's avatar
Dicson committed
126
        return True
Dicson's avatar
Dicson committed
127 128 129 130 131 132


class NowListenPluginConfigDialog(GajimPluginConfigDialog):
    def init(self):
        self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
                'config_dialog.ui')
Dicson's avatar
Dicson committed
133
        self.xml = Gtk.Builder()
Dicson's avatar
Dicson committed
134
        self.xml.set_translation_domain('gajim_plugins')
Dicson's avatar
Dicson committed
135 136 137 138
        self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
                ['now_listen_config_vbox'])

        self.config_vbox = self.xml.get_object('now_listen_config_vbox')
Dicson's avatar
Dicson committed
139
        self.get_child().pack_start(self.config_vbox, True, True, 0)
Dicson's avatar
Dicson committed
140 141

        self.format_sting = self.xml.get_object('format_sting')
Dicson's avatar
Dicson committed
142
        self.format_sting_http = self.xml.get_object('format_sting_http')
Dicson's avatar
Dicson committed
143 144 145 146 147
        self.xml.connect_signals(self)
        self.connect('hide', self.on_hide)

    def on_run(self):
        self.format_sting.set_text(self.plugin.config['format_string'])
Dicson's avatar
Dicson committed
148
        self.format_sting_http.set_text(self.plugin.config['format_string_http'])
Dicson's avatar
Dicson committed
149 150 151

    def on_hide(self, widget):
        self.plugin.config['format_string'] = self.format_sting.get_text()
Dicson's avatar
Dicson committed
152
        self.plugin.config['format_string_http'] = self.format_sting_http.get_text()