[gwibber/f13/master] update to 2.3.91, move twitter to oauth
Tom Callaway
spot at fedoraproject.org
Tue Aug 31 22:05:09 UTC 2010
commit 9024f4fd3725cee080c378d0ceaed1648e6e277b
Author: Tom "spot" Callaway <tcallawa at redhat.com>
Date: Tue Aug 31 18:05:13 2010 -0400
update to 2.3.91, move twitter to oauth
gwibber-832bzr-twitter-oauth.patch | 683 ++++++++++++++++++++++++++++++++++++
gwibber.spec | 19 +-
sources | 2 +-
3 files changed, 700 insertions(+), 4 deletions(-)
---
diff --git a/gwibber-832bzr-twitter-oauth.patch b/gwibber-832bzr-twitter-oauth.patch
new file mode 100644
index 0000000..9d75302
--- /dev/null
+++ b/gwibber-832bzr-twitter-oauth.patch
@@ -0,0 +1,683 @@
+diff -up gwibber-832bzr/gwibber/actions.py.oauth gwibber-832bzr/gwibber/actions.py
+--- gwibber-832bzr/gwibber/actions.py.oauth 2010-08-31 16:35:46.829133992 -0400
++++ gwibber-832bzr/gwibber/actions.py 2010-08-31 16:36:06.056134002 -0400
+@@ -1,5 +1,12 @@
+ import gtk, gwui, microblog, resources, util, json
+ from microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from microblog.util.custom import *
++except:
++ pass
++
+ import gwibber.microblog.util
+ import mx.DateTime
+ import re
+diff -up gwibber-832bzr/gwibber/client.py.oauth gwibber-832bzr/gwibber/client.py
+--- gwibber-832bzr/gwibber/client.py.oauth 2010-08-31 16:36:19.253134002 -0400
++++ gwibber-832bzr/gwibber/client.py 2010-08-31 16:36:41.540134018 -0400
+@@ -12,6 +12,13 @@ gettext.textdomain('gwibber')
+
+ from gwibber.microblog.util import log
+ from microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from microblog.util.custom import *
++except:
++ pass
++
+ from dbus.mainloop.glib import DBusGMainLoop
+ import dbus, dbus.service
+
+diff -up gwibber-832bzr/gwibber/gwui.py.oauth gwibber-832bzr/gwibber/gwui.py
+--- gwibber-832bzr/gwibber/gwui.py.oauth 2010-08-31 16:36:51.402133877 -0400
++++ gwibber-832bzr/gwibber/gwui.py 2010-08-31 16:37:14.636134002 -0400
+@@ -14,6 +14,12 @@ from mako.template import Template
+ from mako.lookup import TemplateLookup
+
+ from microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from microblog.util.custom import *
++except:
++ pass
+
+ gtk.gdk.threads_init()
+
+diff -up gwibber-832bzr/gwibber/lib/gtk/buzz.py.oauth gwibber-832bzr/gwibber/lib/gtk/buzz.py
+--- gwibber-832bzr/gwibber/lib/gtk/buzz.py.oauth 2010-08-31 16:23:47.646134002 -0400
++++ gwibber-832bzr/gwibber/lib/gtk/buzz.py 2010-08-31 16:23:52.683134080 -0400
+@@ -16,7 +16,7 @@ class AccountWidget(gtk.VBox):
+ """
+
+ def __init__(self, account=None, dialog=None):
+- """Creates the account pane for configuring facebook accounts"""
++ """Creates the account pane for configuring Buzz accounts"""
+ gtk.VBox.__init__( self, False, 20 )
+ self.ui = gtk.Builder()
+ self.ui.set_translation_domain ("gwibber")
+diff -up gwibber-832bzr/gwibber/lib/gtk/facebook.py.oauth gwibber-832bzr/gwibber/lib/gtk/facebook.py
+--- gwibber-832bzr/gwibber/lib/gtk/facebook.py.oauth 2010-08-31 16:37:24.159133944 -0400
++++ gwibber-832bzr/gwibber/lib/gtk/facebook.py 2010-08-31 16:37:47.612134002 -0400
+@@ -28,6 +28,12 @@ import gwibber.microblog
+ from gwibber.microblog import facebook
+ from gwibber.microblog.util import facelib
+ from gwibber.microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from gwibber.microblog.util.custom import *
++except:
++ pass
+ import json, urlparse, gnomekeyring, uuid
+ from gettext import gettext as _
+
+diff -up gwibber-832bzr/gwibber/lib/gtk/twitter.py.oauth gwibber-832bzr/gwibber/lib/gtk/twitter.py
+--- gwibber-832bzr/gwibber/lib/gtk/twitter.py.oauth 2010-08-31 16:24:03.696133995 -0400
++++ gwibber-832bzr/gwibber/lib/gtk/twitter.py 2010-08-31 17:02:13.397134077 -0400
+@@ -18,16 +18,26 @@
+ # Twitter widgets for Gwibber
+ #
+
+-import gtk
++import gtk, webkit, gnomekeyring
++import urllib, urllib2, json, urlparse, uuid
++from oauth import oauth
++
+ from gtk import Builder
+ import gwibber.microblog
++from gwibber.microblog import twitter
++from gwibber.microblog.util import resources
++from gettext import gettext as _
++
++gtk.gdk.threads_init()
++
++sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
+
+ class AccountWidget(gtk.VBox):
+ """AccountWidget: A widget that provides a user interface for configuring twitter accounts in Gwibber
+ """
+
+ def __init__(self, account=None, dialog=None):
+- """Creates the account pane for configuring twitter accounts"""
++ """Creates the account pane for configuring Twitter accounts"""
+ gtk.VBox.__init__( self, False, 20 )
+ self.ui = gtk.Builder()
+ self.ui.set_translation_domain ("gwibber")
+@@ -36,5 +46,105 @@ class AccountWidget(gtk.VBox):
+ self.vbox_settings = self.ui.get_object("vbox_settings")
+ self.pack_start(self.vbox_settings, False, False)
+ self.show_all()
+- if dialog:
+- dialog.get_object("vbox_create").show()
++
++ self.account = account or {}
++ self.dialog = dialog
++ has_secret_key = True
++ if self.account.has_key("id"):
++ try:
++ value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "secret_token"))})[0].secret
++ except gnomekeyring.NoMatchError:
++ has_secret_key = False
++
++ try:
++ if self.account.has_key("access_token") and self.account.has_key("secret_token") and self.account.has_key("username") and has_secret_key:
++ self.ui.get_object("hbox_twitter_auth").hide()
++ self.ui.get_object("fb_auth_done_label").set_label(_("%s has been authorized by Twitter") % self.account["username"])
++ self.ui.get_object("hbox_twitter_auth_done").show()
++ else:
++ self.ui.get_object("hbox_twitter_auth_done").hide()
++ self.ui.get_object("twitter_auth_button").modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
++ if self.dialog:
++ self.dialog.get_object('vbox_create').hide()
++ except:
++ self.ui.get_object("hbox_twitter_auth_done").hide()
++ if self.dialog:
++ self.dialog.get_object("vbox_create").hide()
++
++ def on_twitter_auth_clicked(self, widget, data=None):
++ self.winsize = self.window.get_size()
++
++ web = webkit.WebView()
++ web.load_html_string(_("<p>Please wait...</p>"), "file:///")
++
++ self.consumer = oauth.OAuthConsumer(*resources.get_twitter_keys())
++
++ request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, http_method="POST",
++ callback="http://gwibber.com/0/auth.html",
++ http_url="https://api.twitter.com/oauth/request_token")
++
++ request.sign_request(sigmeth, self.consumer, token=None)
++
++ tokendata = urllib2.urlopen(request.http_url, request.to_postdata()).read()
++ self.token = oauth.OAuthToken.from_string(tokendata)
++
++ url = "http://api.twitter.com/oauth/authorize?oauth_token=" + self.token.key
++
++ web.open(url)
++ web.set_size_request(550, 400)
++ web.connect("title-changed", self.on_twitter_auth_title_change)
++
++ scroll = gtk.ScrolledWindow()
++ scroll.add(web)
++
++ self.pack_start(scroll, True, True, 0)
++ self.show_all()
++
++ self.ui.get_object("vbox1").hide()
++ self.ui.get_object("expander1").hide()
++
++ def on_twitter_auth_title_change(self, web=None, title=None, data=None):
++ if title.get_title() == "Success":
++ try:
++ url = web.get_main_frame().get_uri()
++ data = urlparse.parse_qs(url.split("?", 1)[1])
++
++ token = data["oauth_token"][0]
++ verifier = data["oauth_verifier"][0]
++
++ request = oauth.OAuthRequest.from_consumer_and_token(
++ self.consumer, self.token,
++ http_url="https://api.twitter.com/oauth/access_token",
++ parameters={"oauth_verifier": str(verifier)})
++ request.sign_request(sigmeth, self.consumer, self.token)
++
++ tokendata = urllib2.urlopen(request.http_url, request.to_postdata()).read()
++ data = urlparse.parse_qs(tokendata)
++
++ self.account["access_token"] = data["oauth_token"][0]
++ self.account["secret_token"] = data["oauth_token_secret"][0]
++ self.account["username"] = data["screen_name"][0]
++ self.account["user_id"] = data["user_id"][0]
++
++ self.ui.get_object("hbox_twitter_auth").hide()
++ self.ui.get_object("fb_auth_done_label").set_label(_("%s has been authorized by Twitter") % str(self.account["username"]))
++ self.ui.get_object("hbox_twitter_auth_done").show()
++ if self.dialog and self.account.has_key("id"):
++ self.dialog.get_object("vbox_save").show()
++ elif self.dialog:
++ self.dialog.get_object("vbox_create").show()
++ except:
++ pass
++
++ web.hide()
++ self.window.resize(*self.winsize)
++ self.ui.get_object("vbox1").show()
++ self.ui.get_object("expander1").show()
++
++ if title.get_title() == "Failure":
++ d = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
++ gtk.BUTTONS_OK, _("Authorization failed. Please try again."))
++ if d.run(): d.destroy()
++
++ web.hide()
++ self.window.resize(*self.winsize)
+diff -up gwibber-832bzr/gwibber/lib/gtk/widgets.py.oauth gwibber-832bzr/gwibber/lib/gtk/widgets.py
+--- gwibber-832bzr/gwibber/lib/gtk/widgets.py.oauth 2010-08-31 16:45:27.997134002 -0400
++++ gwibber-832bzr/gwibber/lib/gtk/widgets.py 2010-08-31 16:45:56.099133987 -0400
+@@ -21,6 +21,13 @@
+ from dbus.mainloop.glib import DBusGMainLoop
+ import gobject, gtk
+ from gwibber.microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from gwibber.microblog.util.custom import *
++except:
++ pass
++
+ import gwibber.gwui, gwibber.microblog.util, gwibber.resources
+ import gettext
+ from gettext import lgettext as _
+diff -up gwibber-832bzr/gwibber/microblog/config.py.oauth gwibber-832bzr/gwibber/microblog/config.py
+--- gwibber-832bzr/gwibber/microblog/config.py.oauth 2010-08-31 16:46:09.325133999 -0400
++++ gwibber-832bzr/gwibber/microblog/config.py 2010-08-31 16:46:30.115134011 -0400
+@@ -4,6 +4,12 @@ except: from gnome import gconf
+
+ from . import gwp
+ from util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from util.custom import *
++except:
++ pass
+
+ GCONF_DIR = "/apps/gwibber"
+ GCONF_PREFERENCES_DIR = GCONF_DIR + "/preferences"
+diff -up gwibber-832bzr/gwibber/microblog/dispatcher.py.oauth gwibber-832bzr/gwibber/microblog/dispatcher.py
+--- gwibber-832bzr/gwibber/microblog/dispatcher.py.oauth 2010-08-31 16:46:38.366134002 -0400
++++ gwibber-832bzr/gwibber/microblog/dispatcher.py 2010-08-31 16:46:55.106134002 -0400
+@@ -12,6 +12,13 @@ from util import resources
+ from util import exceptions
+ from util.const import *
+
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from util.custom import *
++except:
++ pass
++
+ try:
+ import indicate
+ except:
+diff -up gwibber-832bzr/gwibber/microblog/facebook.py.oauth gwibber-832bzr/gwibber/microblog/facebook.py
+--- gwibber-832bzr/gwibber/microblog/facebook.py.oauth 2010-08-31 16:47:02.423134016 -0400
++++ gwibber-832bzr/gwibber/microblog/facebook.py 2010-08-31 16:47:16.441134001 -0400
+@@ -5,6 +5,12 @@ import hashlib, mx.DateTime, time
+ from os.path import join, getmtime, exists
+ from gettext import lgettext as _
+ from util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from util.custom import *
++except:
++ pass
+
+ log.logger.name = "Facebook"
+
+diff -up gwibber-832bzr/gwibber/microblog/twitter.py.oauth gwibber-832bzr/gwibber/microblog/twitter.py
+--- gwibber-832bzr/gwibber/microblog/twitter.py.oauth 2010-08-31 16:27:51.634133991 -0400
++++ gwibber-832bzr/gwibber/microblog/twitter.py 2010-08-31 16:55:04.130134002 -0400
+@@ -1,6 +1,7 @@
+ import network, util, htmllib, re
+-from util import log
+-from util import exceptions
++import gnomekeyring
++from oauth import oauth
++from util import log, exceptions
+ from gettext import lgettext as _
+ log.logger.name = "Twitter"
+
+@@ -9,14 +10,15 @@ PROTOCOL_INFO = {
+ "version": "1.0",
+
+ "config": [
+- "private:password",
++ "secret_token",
++ "access_token",
+ "username",
+ "color",
+ "receive_enabled",
+ "send_enabled",
+ ],
+
+- "authtype": "login",
++ "authtype": "oauth1a",
+ "color": "#729FCF",
+
+ "features": [
+@@ -48,6 +50,7 @@ PROTOCOL_INFO = {
+ }
+
+ URL_PREFIX = "https://twitter.com"
++API_PREFIX = "https://api.twitter.com/1"
+
+ import htmlentitydefs
+ import unicodedata
+@@ -95,7 +98,13 @@ def unescape(s):
+
+ class Client:
+ def __init__(self, acct):
++ if not acct.has_key("access_token") and not acct.has_key("secret_token"):
++ raise exceptions.GwibberServiceError("keyring")
++ if acct.has_key("secret_token") and acct.has_key("password"): acct.pop("password")
+ self.account = acct
++ self.sigmethod = oauth.OAuthSignatureMethod_HMAC_SHA1()
++ self.consumer = oauth.OAuthConsumer(*util.resources.get_twitter_keys())
++ self.token = oauth.OAuthToken(acct["access_token"], acct["secret_token"])
+
+ def _common(self, data):
+ m = {};
+@@ -208,10 +217,16 @@ class Client:
+ }
+
+ def _get(self, path, parse="message", post=False, single=False, **args):
+- url = "/".join((URL_PREFIX, path))
++ url = "/".join((API_PREFIX, path))
++
++ request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, self.token,
++ http_method=post and "POST" or "GET", http_url=url, parameters=util.compact(args))
++ request.sign_request(self.sigmethod, self.consumer, self.token)
+
+- data = network.Download(url, util.compact(args) or None, post,
+- self.account["username"], self.account["password"]).get_json()
++ if post:
++ data = network.Download(request.to_url(), util.compact(args), post).get_json()
++ else:
++ data = network.Download(request.to_url(), None, post).get_json()
+
+ if isinstance(data, dict) and data.get("errors", 0):
+ if "authenticate" in data["errors"][0]["message"]:
+@@ -223,6 +238,9 @@ class Client:
+ return []
+ elif isinstance(data, dict) and data.get("error", 0):
+ log.logger.error("%s failure - %s", PROTOCOL_INFO["name"], data["error"])
++ if "Incorrect signature" in data["error"]:
++ print data
++ raise exceptions.GwibberServiceError("keyring")
+ return []
+ elif isinstance(data, str):
+ log.logger.error("%s unexpected result - %s", PROTOCOL_INFO["name"], data)
+@@ -279,7 +297,7 @@ class Client:
+
+ def send(self, message):
+ return self._get("statuses/update.json", post=True, single=True,
+- status=message, source="gwibbernet")
++ status=message)
+
+ def send_private(self, message, private):
+ return self._get("direct_messages/new.json", "private", post=True, single=True,
+@@ -287,4 +305,4 @@ class Client:
+
+ def send_thread(self, message, target):
+ return self._get("statuses/update.json", post=True, single=True,
+- status=message, source="gwibbernet", in_reply_to_status_id=target["mid"])
++ status=message, in_reply_to_status_id=target["mid"])
+diff -up gwibber-832bzr/gwibber/microblog/util/const.py.oauth gwibber-832bzr/gwibber/microblog/util/const.py
+--- gwibber-832bzr/gwibber/microblog/util/const.py.oauth 2010-08-31 16:49:48.009134056 -0400
++++ gwibber-832bzr/gwibber/microblog/util/const.py 2010-08-31 16:50:12.243134017 -0400
+@@ -17,6 +17,8 @@ if environ.has_key("FB_APP_KEY"):
+ else:
+ FB_APP_KEY = "71b85c6d8cb5bbb9f1a3f8bbdcdd4b05"
+
++TWITTER_OAUTH_KEY = "VDOuA5qCJ1XhjaSa4pl76g"
++TWITTER_OAUTH_SECRET = "BqHlB8sMz5FhZmmFimwgiIdB0RiBr72Y0bio49IVJM"
+
+ # Gwibber
+ MAX_MESSAGE_LENGTH = 140
+diff -up gwibber-832bzr/gwibber/microblog/util/custom.py.oauth gwibber-832bzr/gwibber/microblog/util/custom.py
+--- gwibber-832bzr/gwibber/microblog/util/custom.py.oauth 2010-08-31 17:09:53.519134001 -0400
++++ gwibber-832bzr/gwibber/microblog/util/custom.py 2010-08-31 17:10:37.514134003 -0400
+@@ -0,0 +1,17 @@
++"""
++WHY ARE YOU LOOKING IN HERE? THIS IS TOP SEKRIT!
++
++Seriously, though. This is really, really dumb. Twitter doesn't understand how to use oauth.
++
++So, we have to explicitly hardcode a key for this client to use. In plain text.
++
++Dumb, dumbdumbdumb.
++
++Google gets it right, heck, even Facebook gets it right, why can't Twitter?
++
++Tom "spot" Callaway <tcallawa at redhat.com>
++Tuesday Aug 31, 2010
++"""
++
++TWITTER_OAUTH_KEY = "GDbYbywyvbcPfe26MqrifQ"
++TWITTER_OAUTH_SECRET = "U4C34CzUW6YYNFinX8RjSTsWWn2bWX08WVdFsxyQ"
+diff -up gwibber-832bzr/gwibber/microblog/util/__init__.py.oauth gwibber-832bzr/gwibber/microblog/util/__init__.py
+--- gwibber-832bzr/gwibber/microblog/util/__init__.py.oauth 2010-08-31 16:49:10.855133922 -0400
++++ gwibber-832bzr/gwibber/microblog/util/__init__.py 2010-08-31 16:49:35.321134001 -0400
+@@ -4,6 +4,13 @@ import log, resources
+ import dbus
+ from const import *
+
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from custom import *
++except:
++ pass
++
+ COUNT = 200
+
+ def parsetime(t):
+diff -up gwibber-832bzr/gwibber/microblog/util/resources.py.oauth gwibber-832bzr/gwibber/microblog/util/resources.py
+--- gwibber-832bzr/gwibber/microblog/util/resources.py.oauth 2010-08-31 16:29:16.131134001 -0400
++++ gwibber-832bzr/gwibber/microblog/util/resources.py 2010-08-31 16:51:05.777134002 -0400
+@@ -9,6 +9,14 @@ from os.path import join, isdir, realpat
+ from os import makedirs
+ import Image, log
+ from gwibber.microblog import network
++from const import *
++
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from custom import *
++except:
++ pass
+
+ log.logger.name = "Gwibber Dispatcher Resources"
+
+@@ -36,6 +44,10 @@ except:
+
+ DATA_DIRS += [os.path.join(d, PROGRAM_NAME) for d in DATA_BASE_DIRS]
+
++def get_twitter_keys():
++ # Distros should register their own keys and not rely on the defaults
++ return TWITTER_OAUTH_KEY, TWITTER_OAUTH_SECRET
++
+ def get_avatar_path(url):
+ avatar_cache_dir = realpath(join(CACHE_BASE_DIR, "gwibber", "avatars"))
+ if not isdir(avatar_cache_dir):
+diff -up gwibber-832bzr/gwibber/preferences.py.oauth gwibber-832bzr/gwibber/preferences.py
+--- gwibber-832bzr/gwibber/preferences.py.oauth 2010-08-31 16:51:17.825134001 -0400
++++ gwibber-832bzr/gwibber/preferences.py 2010-08-31 16:51:46.682134018 -0400
+@@ -36,6 +36,13 @@ if hasattr(gettext, 'bind_textdomain_cod
+ gettext.textdomain('gwibber')
+
+ from microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from microblog.util.custom import *
++except:
++ pass
++
+ from microblog.urlshorter import PROTOCOLS as urlshorters
+
+ from dbus.mainloop.glib import DBusGMainLoop
+diff -up gwibber-832bzr/gwibber/upgrade.py.oauth gwibber-832bzr/gwibber/upgrade.py
+--- gwibber-832bzr/gwibber/upgrade.py.oauth 2010-08-31 16:51:52.866134001 -0400
++++ gwibber-832bzr/gwibber/upgrade.py 2010-08-31 16:52:27.140133874 -0400
+@@ -1,6 +1,13 @@
+ import gconf
+ import gwibber.lib, gwibber.util
+ from gwibber.microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from gwibber.microblog.util.custom import *
++except:
++ pass
++
+ from desktopcouch.records.server import CouchDatabase
+ from desktopcouch.records.record import Record as CouchRecord
+
+diff -up gwibber-832bzr/gwibber/util.py.oauth gwibber-832bzr/gwibber/util.py
+--- gwibber-832bzr/gwibber/util.py.oauth 2010-08-31 16:52:32.791134100 -0400
++++ gwibber-832bzr/gwibber/util.py 2010-08-31 16:52:46.877133979 -0400
+@@ -1,5 +1,11 @@
+ import gtk, dbus, resources, os, mx.DateTime, webbrowser
+ from microblog.util.const import *
++# Try to import * from custom, install custom.py to include packaging
++# customizations like distro API keys, etc
++try:
++ from microblog.util.custom import *
++except:
++ pass
+
+ import gettext
+ from gettext import ngettext
+diff -up gwibber-832bzr/ui/gwibber-accounts-twitter.ui.oauth gwibber-832bzr/ui/gwibber-accounts-twitter.ui
+--- gwibber-832bzr/ui/gwibber-accounts-twitter.ui.oauth 2010-08-31 16:30:20.416133999 -0400
++++ gwibber-832bzr/ui/gwibber-accounts-twitter.ui 2010-08-31 16:32:40.235133923 -0400
+@@ -7,79 +7,46 @@
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+- <object class="GtkTable" id="table_common_settings">
++ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+- <property name="n_rows">3</property>
+- <property name="n_columns">3</property>
+- <property name="column_spacing">12</property>
+- <property name="row_spacing">6</property>
++ <property name="orientation">vertical</property>
+ <child>
+- <object class="GtkEntry" id="password">
++ <object class="GtkHBox" id="hbox_twitter_auth">
+ <property name="visible">True</property>
+- <property name="can_focus">True</property>
+- <property name="visibility">False</property>
+- <property name="invisible_char">●</property>
+- </object>
+- <packing>
+- <property name="left_attach">1</property>
+- <property name="right_attach">3</property>
+- <property name="top_attach">2</property>
+- <property name="bottom_attach">3</property>
+- <property name="y_options"></property>
+- </packing>
+- </child>
+- <child>
+- <object class="GtkEntry" id="username">
+- <property name="visible">True</property>
+- <property name="can_focus">True</property>
+- <property name="invisible_char">●</property>
+- </object>
+- <packing>
+- <property name="left_attach">1</property>
+- <property name="right_attach">3</property>
+- <property name="y_options"></property>
+- </packing>
+- </child>
+- <child>
+- <object class="GtkLabel" id="label_username">
+- <property name="visible">True</property>
+- <property name="xalign">0</property>
+- <property name="label" translatable="yes">Login I_D:</property>
+- <property name="use_underline">True</property>
+- <property name="mnemonic_widget">username</property>
+- </object>
+- <packing>
+- <property name="x_options">GTK_FILL</property>
+- <property name="y_options"></property>
+- </packing>
+- </child>
+- <child>
+- <object class="GtkLabel" id="label_password">
+- <property name="visible">True</property>
+- <property name="xalign">0</property>
+- <property name="label" translatable="yes">Pass_word:</property>
+- <property name="use_underline">True</property>
+- <property name="justify">right</property>
+- <property name="mnemonic_widget">password</property>
++ <child>
++ <object class="GtkButton" id="twitter_auth_button">
++ <property name="label" translatable="yes">_Authorize</property>
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="receives_default">True</property>
++ <property name="use_underline">True</property>
++ <signal name="clicked" handler="on_twitter_auth_clicked"/>
++ </object>
++ <packing>
++ <property name="position">0</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="fb_auth_label">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Authorize with twitter</property>
++ </object>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
+ </object>
+ <packing>
+- <property name="top_attach">2</property>
+- <property name="bottom_attach">3</property>
+- <property name="x_options">GTK_FILL</property>
+- <property name="y_options"></property>
++ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+- <object class="GtkVBox" id="vbox1">
++ <object class="GtkHBox" id="hbox_twitter_auth_done">
+ <property name="visible">True</property>
+- <property name="orientation">vertical</property>
+ <child>
+- <object class="GtkLabel" id="label_username_example">
++ <object class="GtkLabel" id="fb_auth_done_label">
+ <property name="visible">True</property>
+- <property name="xalign">0</property>
+- <property name="xpad">3</property>
+- <property name="label" translatable="yes"><span size="small"><b>Example:</b> username</span></property>
+- <property name="use_markup">True</property>
++ <property name="label" translatable="yes">Twitter authorized</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+@@ -87,22 +54,11 @@
+ </child>
+ </object>
+ <packing>
+- <property name="left_attach">1</property>
+- <property name="right_attach">2</property>
+- <property name="top_attach">1</property>
+- <property name="bottom_attach">2</property>
++ <property name="position">1</property>
+ </packing>
+ </child>
+- <child>
+- <placeholder/>
+- </child>
+- <child>
+- <placeholder/>
+- </child>
+ </object>
+ <packing>
+- <property name="expand">False</property>
+- <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+--- gwibber-832bzr/gwibber/accounts.py.oauth 2010-08-31 17:52:29.405133913 -0400
++++ gwibber-832bzr/gwibber/accounts.py 2010-08-31 17:53:55.884134015 -0400
+@@ -134,15 +134,15 @@
+ self.account_store.clear()
+ accounts = json.loads(self.gwibber.GetAccounts())
+ for account in accounts:
+- if self.verify_account(account):
+ icon = self.get_icon(account["service"])
+ name = "%s (%s)" % (self.services[account["service"]]["name"], account["username"])
+ private_fields = [f.split(":")[-1] for f in self.services[account["service"]]["config"] if ":" in f]
+ color = None
+ for f in private_fields:
++ if not account.has_key(f): account[f] = ":KEYRING:MISSING"
+ if account[f].startswith(":KEYRING:"):
+ value = self.get_from_keyring(account["id"], f)
+- if not value:
++ if value is None:
+ color = "pink"
+ self.account_store.append(None, [name, icon, account, color])
+
+@@ -189,6 +189,8 @@
+ config = config.replace("private:", "")
+ widget = self.account_widget.ui.get_object(config)
+
++ value = None
++
+ for p in ["text", "active", "color"]:
+ if widget and hasattr(widget.props, p):
+ value = getattr(widget.props, p)
+@@ -199,7 +201,7 @@
+ self.account[config] = ":KEYRING:%s" % self.put_in_keyring(
+ self.account["id"], config, self.account[config])
+
+- if value is not None:
++ if value:
+ if isinstance(value, gtk.gdk.Color):
+ value = gtk.color_selection_palette_to_string(
+ gtk.color_selection_palette_from_string(value.to_string()))
diff --git a/gwibber.spec b/gwibber.spec
index a92e7ff..3fbd3f8 100644
--- a/gwibber.spec
+++ b/gwibber.spec
@@ -1,11 +1,11 @@
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
-%global basever 2.31.90
-%global bzr_rev 825
+%global basever 2.31.91
+%global bzr_rev 832
Name: gwibber
Version: %{basever}
-Release: 4%{?dist}
+Release: 1.%{bzr_rev}bzr%{?dist}
Epoch: 1
Summary: An open source microblogging client for GNOME developed with Python and GTK
Group: Applications/Internet
@@ -40,6 +40,9 @@ Patch4: gwibber-794bzr-quit-when-minimized.patch
# https://bugs.launchpad.net/gwibber/+bug/624918
Patch5: gwibber-825bzr-threads-gone-wild.patch
+# Move twitter to oauth
+Patch6: gwibber-832bzr-twitter-oauth.patch
+
Requires: libsoup, python-pycurl, PyXML
Requires: python
Requires: dbus-python >= 0.80.2
@@ -57,6 +60,7 @@ Requires: python-mako >= 0.2.2
Requires: python-sexy, gnome-python2-gnomekeyring
Requires: python-oauth
Requires: gnome-python2-libwnck
+Requires: gnome-python2-gtkspell
BuildRequires: python-devel, desktop-file-utils, python-distutils-extra, intltool, gettext
BuildArch: noarch
@@ -73,6 +77,7 @@ and GTK. It supports Twitter, Jaiku, Identi.ca, Facebook, and Digg.
%patch3 -p1 -b .no-position-printing
%patch4 -p1 -b .quit
%patch5 -p1 -b .threads-gone-wild
+%patch6 -p1 -b .oauth
sed -i -e '/^#! \?\//, 1d' $(find %{name} | grep "\.py$")
@@ -116,6 +121,14 @@ rm -rf %{buildroot}
%{_datadir}/indicators/messages/applications/gwibber
%changelog
+* Tue Aug 31 2010 Tom "spot" Callaway <tcallawa at redhat.com> - 1:2.31.91-1.832bzr
+- update to 2.31.91 (832bzr)
+- move twitter to oauth
+
+* Fri Aug 27 2010 Tom "spot" Callaway <tcallawa at redhat.com> - 1:2.31.90-5
+- add Requires: gnome-python2-gtkspell for spell checking support
+- update to bzr 830
+
* Thu Aug 26 2010 Tom "spot" Callaway <tcallawa at redhat.com> - 1:2.31.90-4
- fix "threads gone wild" problem (bz627686), thanks to Bill Nottingham
diff --git a/sources b/sources
index 2f97c24..0087326 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-793d68bb313a16278d8c86ca15089ea6 gwibber-825bzr.tar.gz
+b43b5b7f09e5d58bc3c1452455c822df gwibber-832bzr.tar.gz
More information about the scm-commits
mailing list