<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -17,7 +17,7 @@
 
 
 application: davepeck-go
-version: 2remind
+version: 2twitterfix
 runtime: python
 api_version: 1
 </diff>
      <filename>app.yaml</filename>
    </modified>
    <modified>
      <diff>@@ -86,6 +86,12 @@ def pos_to_coord(pos):
 # Exception Handling &amp; AppEngine Helpers
 #------------------------------------------------------------------------------
 
+# Work around dev_appserver limitations (stdout goes to browser.)
+def BREAKPOINT():
+  import pdb
+  p = pdb.Pdb(None, sys.__stdin__, sys.__stdout__)
+  p.set_trace()
+
 class ExceptionHelper:
     @staticmethod
     def _typename(t):
@@ -611,6 +617,14 @@ Hi %s,
 # Twitter Support
 #------------------------------------------------------------------------------
 
+class TwitterBuffer(object):
+    def __init__(self, text):
+        super(TwitterBuffer, self).__init__()
+        self._text = text
+        
+    def read(self):
+        return self._text
+        
 class TwitterHelper(object):
     @staticmethod
     def _open_basic_auth_url(username, password, url, params):
@@ -618,15 +632,29 @@ class TwitterHelper(object):
         data = None
         if params is not None:
             data = urllib.urlencode(params)
+        # BREAKPOINT()
         req = urllib2.Request(url, data)
         base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
         authheader =  &quot;Basic %s&quot; % base64string
         req.add_header(&quot;Authorization&quot;, authheader)
         try:
             handle = urllib2.urlopen(req)
-        except:
-            logging.warn(&quot;Failed to make twitter request: %s&quot; % ExceptionHelper.exception_string())
-            return None
+        except urllib2.HTTPError, e:
+            raw_message = e.read()
+            message = raw_message
+            try:
+                message = simplejson.loads(message)[u'error']
+            except:
+                pass
+            logging.warn(&quot;Got HTTP %d during twitter request for URL %s: %s&quot; % (e.code, url, message))
+            # HACK HACK HACK to get around the new (and, I think, bad) change to the twitter API
+            # that causes an HTTP 403 (forbidden) to get returned on friendship creation 
+            # IF you're already following that person. 403 seems like the wrong answer, and it
+            # screws up the design of my code...            
+            if (e.code == 403) and ('friendships/create' in url):
+                return TwitterBuffer(raw_message)
+            else:
+                return None            
         return handle
 
     @staticmethod
@@ -639,7 +667,7 @@ class TwitterHelper(object):
         except:
             logging.warn(&quot;Couldn't process json result from twitter: %s&quot; % ExceptionHelper.exception_string())
             return None
-        return result        
+        return result
     
     @staticmethod
     def _make_twitter_call(url, params):
@@ -679,7 +707,7 @@ class TwitterHelper(object):
     @staticmethod
     def does_follow(a, b):
         # Does &quot;a&quot; follow &quot;b&quot;?
-        return TwitterHelper._make_boolean_twitter_call(&quot;http://twitter.com/friendships/exists.json&quot;, {&quot;user_a&quot;: a, &quot;user_b&quot;: b})
+        return TwitterHelper._make_boolean_twitter_call(&quot;http://twitter.com/friendships/exists.json?user_a=%s&amp;user_b=%s&quot; % (a, b), None)
 
     @staticmethod
     def are_mutual_followers(a, b):
@@ -696,7 +724,8 @@ class TwitterHelper(object):
     @staticmethod
     def create_follow(a, b, a_password):
         # {&quot;ignore&quot;: &quot;this&quot;} forces a POST
-        return TwitterHelper._make_success_twitter_call_as(&quot;http://twitter.com/friendships/create/%s.json?follow=true&quot; % b, {&quot;ignore&quot;: &quot;this&quot;}, a, a_password)
+        # NOTE: WAS _make_success_twitter_call_as, but they changed the API -- you now get a HTTP 403 when you attempt to follow someone you're already following.
+        return TwitterHelper._make_twitter_call_as(&quot;http://twitter.com/friendships/create/%s.json?follow=true&quot; % b, {&quot;ignore&quot;: &quot;this&quot;}, a, a_password)
 
     @staticmethod
     def does_go_account_follow_user(user):</diff>
      <filename>go.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5e439e44dd9325be1730107f29cc9b29a6009b57</id>
    </parent>
  </parents>
  <author>
    <name>Dave Peck</name>
    <email>c-github@delver.org</email>
  </author>
  <url>http://github.com/davepeck/appengine-go/commit/fef3b65442ef1853a4b9bc3024483a6c2ef56449</url>
  <id>fef3b65442ef1853a4b9bc3024483a6c2ef56449</id>
  <committed-date>2009-10-19T20:20:59-07:00</committed-date>
  <authored-date>2009-10-19T20:20:59-07:00</authored-date>
  <message>Bring the twitter code up to date with the latest (and, frankly, not very good) changes that they've made to the twitter friendship APIs.</message>
  <tree>d7e3cc3fe9ceb1a1ed99cd53b8a9db07c5252261</tree>
  <committer>
    <name>Dave Peck</name>
    <email>c-github@delver.org</email>
  </committer>
</commit>
