1# Copyright 2005-2006 Sergey Fedoseev <fedoseev.sergey@gmail.com>
2# Copyright 2007 Simon Morgan <zen84964@zen.co.uk>
3#           2017 Nick Boultbee
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9
10import os
11import sys
12
13if os.name == "nt" or sys.platform == "darwin":
14    from quodlibet.plugins import PluginNotSupportedError
15    raise PluginNotSupportedError
16
17from gi.repository import GLib
18from gi.repository import Gio
19from gi.repository import Gtk
20
21from quodlibet import _
22from quodlibet.plugins.events import EventPlugin
23from quodlibet.pattern import Pattern
24from quodlibet.qltk import Frame, Icons
25from quodlibet import config
26
27# Translators: statuses relating to Instant Messenger apps
28_STATUSES = {'online': _('online'),
29             'offline': _('offline'),
30             'chat': _('chat'),
31             'away': _('away'),
32             'xa': _('xa'),
33             'invisible': _('invisible')}
34
35
36class GajimStatusMessage(EventPlugin):
37    PLUGIN_ID = 'Gajim status message'
38    PLUGIN_NAME = _('Gajim Status Message')
39    PLUGIN_DESC = _("Changes Gajim status message according to what "
40                    "you are currently listening to.")
41    PLUGIN_ICON = Icons.FACE_SMILE
42
43    c_accounts = __name__ + '_accounts'
44    c_paused = __name__ + '_paused'
45    c_statuses = __name__ + '_statuses'
46    c_pattern = __name__ + '_pattern'
47
48    def __init__(self):
49        try:
50            self.accounts = config.get('plugins', self.c_accounts).split()
51        except:
52            self.accounts = []
53            config.set('plugins', self.c_accounts, '')
54
55        try:
56            self.paused = config.getboolean('plugins', self.c_paused)
57        except:
58            self.paused = True
59            config.set('plugins', self.c_paused, 'True')
60
61        try:
62            self.statuses = config.get('plugins', self.c_statuses).split()
63        except:
64            self.statuses = ['online', 'chat']
65            config.set('plugins', self.c_statuses, " ".join(self.statuses))
66
67        try:
68            self.pattern = config.get('plugins', self.c_pattern)
69        except:
70            self.pattern = '<artist> - <title>'
71            config.set('plugins', self.c_pattern, self.pattern)
72
73    def enabled(self):
74        self.interface = None
75        self.current = ''
76
77    def disabled(self):
78        if self.current != '':
79            self.change_status(self.accounts, '')
80
81    def change_status(self, enabled_accounts, status_message):
82        if not self.interface:
83            try:
84                self.interface = Gio.DBusProxy.new_for_bus_sync(
85                    Gio.BusType.SESSION, Gio.DBusProxyFlags.NONE, None,
86                    'org.gajim.dbus', '/org/gajim/dbus/RemoteObject',
87                    'org.gajim.dbus.RemoteInterface', None)
88            except GLib.Error:
89                self.interface = None
90
91        if self.interface:
92            try:
93                for account in self.interface.list_accounts():
94                    status = self.interface.get_status('(s)', account)
95                    if enabled_accounts != [] and \
96                            account not in enabled_accounts:
97                        continue
98                    if status in self.statuses:
99                        self.interface.change_status('(sss)',
100                            status, status_message, account)
101            except GLib.Error:
102                self.interface = None
103
104    def plugin_on_song_started(self, song):
105        if song:
106            self.current = Pattern(self.pattern) % song
107        else:
108            self.current = ''
109        self.change_status(self.accounts, self.current)
110
111    def plugin_on_paused(self):
112        if self.paused and self.current != '':
113            self.change_status(self.accounts,
114                               "%s [%s]" % (self.current, _("paused")))
115
116    def plugin_on_unpaused(self):
117        self.change_status(self.accounts, self.current)
118
119    def accounts_changed(self, entry):
120        self.accounts = entry.get_text().split()
121        config.set('plugins', self.c_accounts, entry.get_text())
122
123    def pattern_changed(self, entry):
124        self.pattern = entry.get_text()
125        config.set('plugins', self.c_pattern, self.pattern)
126
127    def paused_changed(self, c):
128        config.set('plugins', self.c_paused, str(c.get_active()))
129
130    def statuses_changed(self, b):
131        if b.get_active() and b.get_name() not in self.statuses:
132            self.statuses.append(b.get_name())
133        elif b.get_active() is False and b.get_name() in self.statuses:
134            self.statuses.remove(b.get_name())
135        config.set('plugins', self.c_statuses, " ".join(self.statuses))
136
137    def PluginPreferences(self, parent):
138        vb = Gtk.VBox(spacing=6)
139
140        pattern_box = Gtk.HBox(spacing=6)
141        pattern_box.set_border_width(3)
142        pattern = Gtk.Entry()
143        pattern.set_text(self.pattern)
144        pattern.connect('changed', self.pattern_changed)
145        pattern_box.pack_start(Gtk.Label(label=_("Pattern:")), False, True, 0)
146        pattern_box.pack_start(pattern, True, True, 0)
147
148        accounts_box = Gtk.HBox(spacing=3)
149        accounts_box.set_border_width(3)
150        accounts = Gtk.Entry()
151        accounts.set_text(" ".join(self.accounts))
152        accounts.connect('changed', self.accounts_changed)
153        accounts.set_tooltip_text(
154            _("List accounts, separated by spaces, for "
155              "changing status message. If none are specified, "
156              "status message of all accounts will be changed."))
157        accounts_box.pack_start(Gtk.Label(label=_("Accounts:")),
158                                False, True, 0)
159        accounts_box.pack_start(accounts, True, True, 0)
160
161        c = Gtk.CheckButton(label=_("Add '[paused]'"))
162        c.set_active(self.paused)
163        c.connect('toggled', self.paused_changed)
164        c.set_tooltip_text(_("If checked, '[paused]' will be added to "
165                             "status message on pause"))
166
167        table = Gtk.Table()
168        self.list = []
169        i = 0
170        j = 0
171        for status, translated in _STATUSES.items():
172            button = Gtk.CheckButton(label=translated)
173            button.set_name(status)
174            if status in self.statuses:
175                button.set_active(True)
176            button.connect('toggled', self.statuses_changed)
177            self.list.append(button)
178            table.attach(button, i, i + 1, j, j + 1)
179            if i == 2:
180                i = 0
181                j += 1
182            else:
183                i += 1
184
185        vb.pack_start(pattern_box, True, True, 0)
186        vb.pack_start(accounts_box, True, True, 0)
187        vb.pack_start(c, True, True, 0)
188        frame = Frame(label=_("Statuses for which message will be changed"),
189                      child=table)
190        vb.pack_start(frame, True, True, 6)
191        return vb
192