3 # NOTICE: This script is currently broken as the libpurple DBus
4 # bindings have been removed.
6 # This is a dbus script to show a docklet for Finch. This should work
7 # for any 'compatible' purple client.
9 # By 'compatible', I mean any client that sets and updates the
10 # "unseen-count" data on the conversations.
12 # It allows doing the following things:
13 # - It allows changing status.
14 # - It shows the current status and info about unread messages in
16 # - It can blink on unread IM/Chat messages, and it allows canging
17 # the preference for that.
19 # It requires GTK+ 2.10 or above, since it uses GtkStatusIcon.
21 # Sadrul <sadrul@pidgin.im>
23 from __future__
import absolute_import
, division
, print_function
25 import os
# to get the pkg-config output
28 pygtk
.require("2.0") # noqa
34 bus
= dbus
.SessionBus()
35 obj
= bus
.get_object("im.pidgin.purple.PurpleService",
36 "/im/pidgin/purple/PurpleObject")
37 purple
= dbus
.Interface(obj
, "im.pidgin.purple.PurpleInterface")
40 def pack_image_label(menu
, image
, label
):
41 item
= gtk
.ImageMenuItem(label
)
44 img
.set_from_stock(image
, 1)
50 def activate_primitive_status(item
, status
):
51 saved
= purple
.PurpleSavedstatusFindTransientByTypeAndMessage(status
, "")
53 saved
= purple
.PurpleSavedstatusNew("", status
)
54 purple
.PurpleSavedstatusActivate(saved
)
57 def activate_popular_status(item
, time
):
58 saved
= purple
.PurpleSavedstatusFindByCreationTime(time
)
60 purple
.PurpleSavedstatusActivate(saved
)
63 def generate_status_menu(menu
):
64 item
= gtk
.MenuItem("Available")
65 item
.connect("activate", activate_primitive_status
, 2)
68 item
= gtk
.MenuItem("Away")
69 item
.connect("activate", activate_primitive_status
, 5)
72 item
= gtk
.MenuItem("Invisible")
73 item
.connect("activate", activate_primitive_status
, 4)
76 item
= gtk
.MenuItem("Offline")
77 item
.connect("activate", activate_primitive_status
, 1)
80 menu
.append(gtk
.MenuItem())
82 popular
= purple
.PurpleSavedstatusesGetPopular(10)
84 title
= purple
.PurpleSavedstatusGetTitle(pop
).replace('_', '__')
85 item
= gtk
.MenuItem(title
)
86 item
.set_data("timestamp",
87 purple
.PurpleSavedstatusGetCreationTime(pop
))
88 item
.connect("activate", activate_popular_status
,
89 purple
.PurpleSavedstatusGetCreationTime(pop
))
93 def toggle_pref(item
, pref
):
94 purple
.PurplePrefsSetBool(pref
, item
.get_active())
97 def quit_finch(item
, null
):
99 purple
.PurpleCoreQuit()
103 def close_docklet(item
, null
):
107 def popup_menu(icon
, button
, tm
, none
):
110 # item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
111 # item.connect("activate", quit_finch, None)
114 item
= gtk
.ImageMenuItem(gtk
.STOCK_CLOSE
)
115 item
.connect("activate", close_docklet
, None)
118 menu
.append(gtk
.MenuItem())
120 item
= gtk
.CheckMenuItem("Blink for unread IM")
122 purple
.PurplePrefsGetBool("/plugins/dbus/docklet/blink/im"))
123 item
.connect("activate", toggle_pref
, "/plugins/dbus/docklet/blink/im")
126 item
= gtk
.CheckMenuItem("Blink for unread Chats")
128 purple
.PurplePrefsGetBool("/plugins/dbus/docklet/blink/chat"))
129 item
.connect("activate", toggle_pref
, "/plugins/dbus/docklet/blink/chat")
132 menu
.append(gtk
.MenuItem())
134 # item = pack_image_label(menu, None, "Change Status...")
135 item
= gtk
.MenuItem("Change Status...")
138 item
.set_submenu(submenu
)
139 generate_status_menu(submenu
)
142 menu
.popup(None, None, None, button
, tm
)
145 def get_status_message():
153 status
= purple
.PurpleSavedstatusGetCurrent()
154 msg
= purple
.PurpleSavedstatusGetMessage(status
)
155 if msg
and len(msg
) > 0:
159 text
+= "(" + status_names
[purple
.PurpleSavedstatusGetType(status
)] + ")"
163 def detect_unread_conversations():
164 im
= purple
.PurplePrefsGetBool("/plugins/dbus/docklet/blink/im")
165 chat
= purple
.PurplePrefsGetBool("/plugins/dbus/docklet/blink/chat")
169 convs
= purple
.PurpleGetConversations()
171 convs
= purple
.PurpleGetIms()
173 convs
= purple
.PurpleGetChats()
177 count
= purple
.PurpleConversationGetData(conv
, "unseen-count")
178 if count
and count
> 0:
180 tooltip
+= "\n%s (%d)" % (purple
.PurpleConversationGetName(conv
),
182 t
.set_from_file(path
+ "/share/pixmaps/pidgin.png")
185 # t.set_from_file(path +
186 # "/share/pixmaps/pidgin/tray/22/tray-message.png")
187 tooltip
= "\nUnread Messages:" + tooltip
188 # There's going to be some way to expose the client's display name in
189 # 2.1.0. Use that instead of hardcoding Finch here.
190 t
.set_tooltip("Finch: " + get_status_message() + tooltip
)
191 t
.set_blinking(blink
)
194 def conversation_updated(conv
, type):
195 detect_unread_conversations()
198 def savedstatus_changed(new
, old
):
199 # Change the icon for status perhaps?
200 detect_unread_conversations()
204 if not purple
.PurplePrefsExists("/plugins/dbus/docklet/blink"):
205 purple
.PurplePrefsAddNone("/plugins")
206 purple
.PurplePrefsAddNone("/plugins/dbus")
207 purple
.PurplePrefsAddNone("/plugins/dbus/docklet")
208 purple
.PurplePrefsAddNone("/plugins/dbus/docklet/blink")
209 purple
.PurplePrefsAddBool("/plugins/dbus/docklet/blink/im", True)
210 purple
.PurplePrefsAddBool("/plugins/dbus/docklet/blink/chat", True)
213 pkg
= os
.popen("pkg-config --variable=prefix pidgin")
214 path
= pkg
.readline().rstrip()
216 bus
.add_signal_receiver(conversation_updated
,
217 dbus_interface
="im.pidgin.purple.PurpleInterface",
218 signal_name
="ConversationUpdated")
220 bus
.add_signal_receiver(savedstatus_changed
,
221 dbus_interface
="im.pidgin.purple.PurpleInterface",
222 signal_name
="SavedstatusChanged")
225 t
.connect("popup-menu", popup_menu
, None)
229 detect_unread_conversations()
232 dialog
= gtk
.Dialog("pietray: Error", None,
233 gtk
.DIALOG_NO_SEPARATOR | gtk
.DIALOG_MODAL
,
234 ("Close", gtk
.RESPONSE_CLOSE
))
235 dialog
.set_resizable(False)
236 error_label
= gtk
.Label("There was some error. Perhaps a purple client is "
238 dialog
.vbox
.pack_start(error_label
, False, False, 0)