~khurshid-alam/gwibber/gwibber-hack

« back to all changes in this revision

Viewing changes to gwibber/accounts.py

  • Committer: Khurshid Alam
  • Date: 2012-04-06 14:38:38 UTC
  • Revision ID: khurshid.alam@linuxmail.org-20120406143838-nz7hjg8vtzi2wl7i
initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (C) 2010 Canonical Ltd
 
3
#
 
4
# This program is free software: you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License version 2 as
 
6
# published by the Free Software Foundation.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
#
 
16
# Copyright (C) 2010 Ken VanDine <ken.vandine@canonical.com>
 
17
#
 
18
# Accounts interface for Gwibber
 
19
#
 
20
 
 
21
try:
 
22
  import gnomekeyring
 
23
except:
 
24
  gnomekeyring = None
 
25
 
 
26
import gettext
 
27
from gettext import lgettext as _
 
28
if hasattr(gettext, 'bind_textdomain_codeset'):
 
29
  gettext.bind_textdomain_codeset('gwibber','UTF-8')
 
30
gettext.textdomain('gwibber')
 
31
 
 
32
import gtk, pango, gconf, os, json, uuid
 
33
from gwibber.lib import GwibberPublic
 
34
import util
 
35
from microblog.util import resources
 
36
 
 
37
for p in resources.get_plugin_dirs()[0]:
 
38
  print "Loading plugin for %s" % p
 
39
  globals()[p] = __import__("%s.gtk.%s" % (p,p), fromlist='*')
 
40
 
 
41
from dbus.mainloop.glib import DBusGMainLoop
 
42
DBusGMainLoop(set_as_default=True)
 
43
 
 
44
class GwibberAccountManager(object):
 
45
  def __init__(self, selected_account=None, condition=None, message=None):
 
46
    self.selected_account = selected_account
 
47
    self.condition = condition
 
48
    self.message = message
 
49
    self.gwibber = GwibberPublic()
 
50
    self.services = json.loads(self.gwibber.GetServices())
 
51
    self.ui = gtk.Builder()
 
52
    self.ui.set_translation_domain("gwibber")
 
53
    self.ui.add_from_file(resources.get_ui_asset("gwibber-accounts-dialog.ui"))
 
54
    self.ui.connect_signals(self)
 
55
 
 
56
    dialog = self.ui.get_object("accounts_dialog")
 
57
    dialog.resize(640,400)
 
58
    dialog.set_icon_from_file(resources.get_ui_asset("gwibber.svg"))
 
59
    dialog.show_all()
 
60
    if hasattr(gtk, "InfoBar"):
 
61
      self.alignment_infobar = self.ui.get_object("alignment_infobar")
 
62
      self.infobar = gtk.InfoBar()
 
63
      self.alignment_infobar.add(self.infobar)
 
64
      self.infobar.hide()
 
65
 
 
66
    # Hide the help button until we have help :)
 
67
    button_help = self.ui.get_object("button_help")
 
68
    button_help.hide()
 
69
 
 
70
    # This should check for configured accounts, and if there are any hide this
 
71
    self.ui.get_object('frame_new_account').hide()
 
72
    self.ui.get_object('vbox_save').hide()
 
73
    self.ui.get_object('vbox_create').hide()
 
74
    
 
75
    self.setup_account_tree()
 
76
    self.populate_account_tree()
 
77
    self.select_account()
 
78
    
 
79
  def setup_account_tree(self):
 
80
    # Protocol title, Icon, Protocol Properties
 
81
    self.service_store = gtk.ListStore(str, gtk.gdk.Pixbuf, str)
 
82
    for name, props in self.services.items():
 
83
      icon = self.get_icon(name)
 
84
      if icon:
 
85
        self.service_store.append((props["name"], icon, name))
 
86
 
 
87
    service_combo = self.ui.get_object("protocol_combobox")
 
88
    service_combo.set_model(self.service_store)
 
89
 
 
90
    celltxt = gtk.CellRendererText()
 
91
    cellimg = gtk.CellRendererPixbuf()
 
92
    
 
93
    service_combo.pack_start(cellimg, False)
 
94
    service_combo.pack_start(celltxt, False)
 
95
    service_combo.add_attribute(cellimg, "pixbuf", 1)
 
96
    service_combo.add_attribute(celltxt, "text", 0)
 
97
    service_combo.set_active(0)
 
98
 
 
99
    # Store: Account name, Icon, Protocol properties, Color
 
100
    self.account_store = gtk.TreeStore(str, gtk.gdk.Pixbuf, object, str)
 
101
 
 
102
    icon_column = gtk.TreeViewColumn('Icon')
 
103
    name_column = gtk.TreeViewColumn('Account')
 
104
 
 
105
    celltxt = gtk.CellRendererText()
 
106
    cellimg = gtk.CellRendererPixbuf()
 
107
 
 
108
    icon_column.pack_start(cellimg, False)
 
109
    icon_column.add_attribute(cellimg, 'pixbuf', 1)
 
110
    icon_column.add_attribute(cellimg, 'cell-background', 3)
 
111
    
 
112
    name_column.pack_start(celltxt, True)
 
113
    name_column.add_attribute(celltxt, 'text', 0)
 
114
    name_column.add_attribute(celltxt, 'cell-background', 3)
 
115
    
 
116
    self.account_tree = self.ui.get_object("accounts_tree")
 
117
    self.account_tree.append_column(icon_column)
 
118
    self.account_tree.append_column(name_column)
 
119
    self.account_tree.set_model(self.account_store)
 
120
 
 
121
  def select_account(self):
 
122
    if not self.selected_account:
 
123
      if len(self.account_store):
 
124
        self.account_tree.set_cursor(0)
 
125
      else: self.add_account()
 
126
    else:
 
127
      for i in self.account_store:
 
128
        if i[2]["id"] == self.selected_account:
 
129
          self.account_tree.set_cursor(i.path)
 
130
      #self.selected_account = None
 
131
 
 
132
 
 
133
  def get_icon(self, name):
 
134
    icf = util.get_service_icon(name)
 
135
    if icf:
 
136
      if os.path.exists(icf):
 
137
        return gtk.gdk.pixbuf_new_from_file(icf)
 
138
    #return gtk.gdk.pixbuf_new_from_file(resources.get_ui_asset("gwibber.png"))
 
139
    return None
 
140
 
 
141
  def get_from_keyring(self, acctid, name):
 
142
    item = {"id": str("%s/%s" % (acctid, name))}
 
143
    try:
 
144
      return gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, item)[0].secret
 
145
    except gnomekeyring.NoMatchError:
 
146
      return None
 
147
 
 
148
  def put_in_keyring(self, acctid, name, value):
 
149
    id = "%s/%s" % (acctid, name)
 
150
    return gnomekeyring.item_create_sync(
 
151
        gnomekeyring.get_default_keyring_sync(),
 
152
        gnomekeyring.ITEM_GENERIC_SECRET,
 
153
        "Gwibber preference: %s" % id,
 
154
        {"id": str(id)}, str(value), True)
 
155
 
 
156
  def populate_account_tree(self):
 
157
    self.account_store.clear()
 
158
    accounts = json.loads(self.gwibber.GetAccounts())
 
159
    for account in accounts:
 
160
        try:
 
161
          icon = self.get_icon(account["service"])
 
162
          if account.has_key("site_display_name"):
 
163
            name = account["site_display_name"]
 
164
          else:
 
165
            name = "%s (%s)" % (self.services[account["service"]]["name"], account["username"])
 
166
          private_fields = [f.split(":")[-1] for f in self.services[account["service"]]["config"] if ":" in f]
 
167
          color = None
 
168
          for f in private_fields:
 
169
            if not account.has_key(f): account[f] = ":KEYRING:MISSING"
 
170
            if account[f].startswith(":KEYRING:"):
 
171
              value = self.get_from_keyring(account["id"], f)
 
172
              if value is None:
 
173
                color = "pink"
 
174
          self.account_store.append(None, [name, icon, account, color])
 
175
        except:
 
176
          pass
 
177
 
 
178
  def verify_account(self, account):
 
179
    for field in self.services[account["service"]]["config"]:
 
180
      if field.split(":")[-1] not in account:
 
181
        print "Couldn't find field:", field.split(":")[-1]
 
182
        return False
 
183
    return True
 
184
 
 
185
  def on_edit_account(self, widget, data=None):
 
186
    self.on_edit_account_save()
 
187
    #self.ui.get_object('vbox_save').show()
 
188
    #self.ui.get_object('vbox_create').hide()
 
189
 
 
190
  def on_edit_account_cancel(self, widget):
 
191
    #self.ui.get_object('vbox_save').hide()
 
192
    #self.ui.get_object('vbox_create').hide()
 
193
    self.select_account()
 
194
 
 
195
  def on_account_delete(self, widget):
 
196
    if not hasattr(self, 'account'):
 
197
      pass
 
198
    else:  
 
199
      if "id" in self.account:
 
200
        try:
 
201
          private_fields = [f.split(":")[-1] for f in self.services[self.account["service"]]["config"] if ":" in f]
 
202
          for f in private_fields:
 
203
            if self.account[f].startswith(":KEYRING:"):
 
204
              keyring_id = int(self.account[f].split(":")[-1])
 
205
              gnomekeyring.item_delete_sync(gnomekeyring.get_default_keyring_sync(), keyring_id)
 
206
        except:
 
207
          pass  
 
208
        self.gwibber.accounts.Delete(self.account["id"])
 
209
      self.populate_account_tree()
 
210
      self.select_account()
 
211
 
 
212
  def on_edit_account_save(self, widget=None):
 
213
    print "Saving..."
 
214
    
 
215
    service = self.services[self.account["service"]]
 
216
    is_new = "id" not in self.account
 
217
      
 
218
    if is_new: self.account["id"] = uuid.uuid1().hex
 
219
    
 
220
    for config in service["config"]:
 
221
      is_private = config.startswith("private:")
 
222
      config = config.replace("private:", "")
 
223
      widget = self.account_widget.ui.get_object(config)
 
224
 
 
225
      value = None
 
226
 
 
227
      for p in ["text", "active", "color"]:
 
228
        if widget and hasattr(widget.props, p):
 
229
          value = getattr(widget.props, p)
 
230
          self.account[config] = value
 
231
 
 
232
      if is_private and self.account.has_key(config):
 
233
        if not self.account[config].startswith(":KEYRING:"):
 
234
          self.account[config] = ":KEYRING:%s" % self.put_in_keyring(
 
235
              self.account["id"], config, self.account[config])
 
236
 
 
237
      if value:
 
238
        if isinstance(value, gtk.gdk.Color):
 
239
          value = gtk.color_selection_palette_to_string(
 
240
            gtk.color_selection_palette_from_string(value.to_string()))
 
241
          self.account[config] = value
 
242
 
 
243
    if not self.verify_account(self.account): return False
 
244
 
 
245
    fn = "Create" if is_new else "Update"
 
246
    getattr(self.gwibber.accounts, fn)(json.dumps(self.account))
 
247
 
 
248
    self.ui.get_object('vbox_save').hide()
 
249
    self.ui.get_object('vbox_create').hide()
 
250
 
 
251
    # if we just fixed a failure case, hide the infobar
 
252
    if self.account["id"] == self.selected_account:
 
253
      if hasattr(gtk, "InfoBar"):
 
254
        self.infobar.hide()
 
255
      self.selected_account = None
 
256
 
 
257
    self.populate_account_tree()
 
258
 
 
259
    # Set the autostart gconf key so we get loaded on login
 
260
    gc = gconf.client_get_default()
 
261
    if gc.get("/apps/gwibber/preferences/autostart") is None:
 
262
      gc.set_bool("/apps/gwibber/preferences/autostart", True)
 
263
 
 
264
    return True
 
265
 
 
266
  def on_button_add_activate(self, widget=None, data=None):
 
267
    self.add_account()
 
268
 
 
269
  def add_account(self):
 
270
    # Populate protocols combobox
 
271
    self.ui.get_object('frame_new_account').show()
 
272
    self.ui.get_object('vbox_details').hide()
 
273
    self.ui.get_object('vbox_account').hide()
 
274
    self.ui.get_object('vbox_save').hide()
 
275
    self.ui.get_object('vbox_create').hide()
 
276
 
 
277
  def on_button_create_clicked(self, widget, data=None):
 
278
    model = widget.get_model()
 
279
    iter = widget.get_active_iter()
 
280
    icon = model.get_value(iter, 1)
 
281
    service = model.get_value(iter, 2)
 
282
    self.account_show(service, icon)
 
283
 
 
284
  def account_show(self, service_id, icon=None, account=None, condition=None, message=None):
 
285
    if hasattr(gtk, "InfoBar"):
 
286
      if condition == "error":
 
287
        self.infobar.set_message_type(gtk.MESSAGE_ERROR)
 
288
      if condition == "info":
 
289
        self.infobar.set_message_type(gtk.MESSAGE_INFO)
 
290
      if message and condition:
 
291
        if hasattr(self, "infobar_content_area"):
 
292
          for child in self.infobar_content_area.get_children(): child.destroy()
 
293
        self.infobar_content_area = self.infobar.get_content_area()
 
294
        message_label = gtk.Label(message)
 
295
        message_label.set_use_markup(True)
 
296
        message_label.set_ellipsize(pango.ELLIPSIZE_END)
 
297
        self.infobar_content_area.add(message_label)
 
298
        self.infobar.show_all()
 
299
      else:
 
300
        self.infobar.hide()
 
301
 
 
302
    vbox_account = self.ui.get_object('vbox_account')
 
303
    for child in vbox_account.get_children(): child.destroy()
 
304
 
 
305
    self.ui.get_object('vbox_details').show()
 
306
    self.ui.get_object('vbox_account').show()
 
307
    self.ui.get_object('frame_new_account').hide()
 
308
 
 
309
    service = self.services[service_id]
 
310
    self.ui.get_object('label_name').set_label(service["name"])
 
311
 
 
312
    if icon:
 
313
      self.ui.get_object('image_type').set_from_pixbuf(icon)
 
314
 
 
315
    if service_id in globals():
 
316
      if not account:
 
317
        account = {"service": service_id}
 
318
        is_new = True
 
319
      else:
 
320
        is_new = False
 
321
 
 
322
      aw = globals()[service_id].AccountWidget(account, self)
 
323
 
 
324
      vbox_account.pack_start(aw, False, False)
 
325
      vbox_account.show()
 
326
 
 
327
      if "color" not in account:
 
328
        account["color"] = service["color"]
 
329
 
 
330
      for config in service["config"]:
 
331
        is_private = config.startswith("private:")
 
332
        config = config.replace("private:", "")
 
333
 
 
334
        if config in account:
 
335
          value = account[config]
 
336
          widget = aw.ui.get_object(config)
 
337
          
 
338
          if isinstance(widget, gtk.Entry):
 
339
            if is_private and account[config].startswith(":KEYRING:"):
 
340
              value = self.get_from_keyring(account["id"], config)
 
341
              if not value:
 
342
                widget.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("pink"))
 
343
            if value:
 
344
              widget.set_text(value)
 
345
            widget.connect("changed", self.on_edit_account)
 
346
 
 
347
          elif isinstance(widget, gtk.CheckButton):
 
348
            widget.set_active(value)
 
349
            widget.connect("toggled", self.on_edit_account)
 
350
 
 
351
          elif isinstance(widget, gtk.ColorButton):
 
352
            widget.set_color(gtk.color_selection_palette_from_string(value)[0])
 
353
            widget.connect("color-set", self.on_edit_account)
 
354
 
 
355
      self.account = account
 
356
      self.account_widget = aw
 
357
    if not is_new:
 
358
      self.ui.get_object('vbox_create').hide()
 
359
 
 
360
  def on_accounts_dialog_destroy(self, widget, data=None):
 
361
    gtk.main_quit()
 
362
 
 
363
  def on_accounts_tree_row_activated(self, widget, data=None):
 
364
    self.ui.get_object('vbox_save').hide()
 
365
    self.ui.get_object('vbox_create').hide()
 
366
    
 
367
    model, rows = widget.get_selection().get_selected_rows()
 
368
 
 
369
    if rows:
 
370
      iter = model.get_iter(rows[0][0])
 
371
      icon = model.get_value(iter, 1)
 
372
      acct = model.get_value(iter, 2)
 
373
      if self.selected_account == acct["id"] and self.condition:
 
374
        self.account_show(acct["service"], icon, acct, self.condition, self.message)
 
375
      else:
 
376
        self.account_show(acct["service"], icon, acct)
 
377
 
 
378
  def on_button_close_clicked(self, widget, data=None):
 
379
    gtk.main_quit()