]> jfr.im git - z_archive/twitter.git/commitdiff
Automatically generating _POST_ACTIONS list.
authorHatem Nassrat <redacted>
Wed, 18 Feb 2009 07:04:03 +0000 (03:04 -0400)
committerHatem Nassrat <redacted>
Mon, 2 Mar 2009 03:39:10 +0000 (23:39 -0400)
added script to generate _POST_ACTIONS
added auto generated _POST_ACTIONS file
removed _POST_ACTIONS from api.py

twitter/api.py
twitter/twitter_globals.py [new file with mode: 0644]
twitter/update.py [new file with mode: 0644]

index c913dc2850a2656c47e48b57a505a659014b1885..118d4fb8cf9653e1855e96a11a369992a2395eb7 100644 (file)
@@ -6,6 +6,8 @@ import urllib2
 
 from exceptions import Exception
 
+from twitter.twitter_globals import _POST_ACTIONS
+
 def _py26OrGreater():
     import sys
     return sys.hexversion > 0x20600f0
@@ -22,11 +24,6 @@ class TwitterError(Exception):
     """
     pass
 
-# These actions require POST http requests instead of GET
-_POST_ACTIONS = [
-    "create", "update", "destroy", "new", "follow", "leave",
-    ]
-
 class TwitterCall(object):
     def __init__(
         self, username, password, format, domain, uri="", agent=None):
@@ -56,7 +53,7 @@ class TwitterCall(object):
         id = kwargs.pop('id', None)
         if id:
             uri += "/%s" %(id)
-            
+
         encoded_kwargs = urlencode(kwargs.items())
         argStr = ""
         argData = None
@@ -95,7 +92,7 @@ class TwitterCall(object):
 class Twitter(TwitterCall):
     """
     The minimalist yet fully featured Twitter API class.
-    
+
     Get RESTful data by accessing members of this class. The result
     is decoded python objects (lists and dicts).
 
@@ -103,27 +100,27 @@ class Twitter(TwitterCall):
 
       http://apiwiki.twitter.com/
       http://groups.google.com/group/twitter-development-talk/web/api-documentation
-    
+
     Examples::
-    
+
       twitter = Twitter("hello@foo.com", "password123")
-      
+
       # Get the public timeline
       twitter.statuses.public_timeline()
-      
+
       # Get a particular friend's timeline
       twitter.statuses.friends_timeline(id="billybob")
-      
+
       # Also supported (but totally weird)
       twitter.statuses.friends_timeline.billybob()
-      
+
       # Send a direct message
       twitter.direct_messages.new(
           user="billybob",
           text="I think yer swell!")
 
     Searching Twitter::
-        
+
       twitter_search = Twitter(domain="search.twitter.com")
 
       # Find the latest search trends
@@ -144,14 +141,14 @@ class Twitter(TwitterCall):
 
       # The screen name of the user who wrote the first 'tweet'
       x[0]['user']['screen_name']
-    
+
     Getting raw XML data::
-    
+
       If you prefer to get your Twitter data in XML format, pass
       format="xml" to the Twitter object when you instantiate it:
-      
+
       twitter = Twitter(format="xml")
-      
+
       The output will not be parsed in any way. It will be a raw string
       of XML.
     """
diff --git a/twitter/twitter_globals.py b/twitter/twitter_globals.py
new file mode 100644 (file)
index 0000000..46e1005
--- /dev/null
@@ -0,0 +1,32 @@
+'''
+    This module is automatically generated using `update.py`
+
+    ..data::
+
+        `_POST_ACTIONS`: Methods that require the use of POST
+'''
+
+_POST_ACTIONS = [
+
+    # Status Methods
+    'update', 
+
+    # Direct Message Methods
+    'new', 
+
+    # Account Methods
+    'update_profile_image', 'update_delivery_device', 'update_profile', 
+    'update_profile_background_image', 'update_profile_colors', 
+    'update_location', 'end_session', 
+
+    # Notification Methods
+    'leave', 'follow', 
+
+    # Status Methods, Block Methods, Direct Message Methods, 
+    # Friendship Methods, Favorite Methods
+    'destroy', 
+
+    # Block Methods, Friendship Methods, Favorite Methods
+    'create', 
+
+]
diff --git a/twitter/update.py b/twitter/update.py
new file mode 100644 (file)
index 0000000..9ad8374
--- /dev/null
@@ -0,0 +1,136 @@
+'''
+This is a development script, intended for office use only.
+
+This script generates output the _POST_ACTIONS variable
+for placement in the twitter_globals.py
+
+Example Util:
+
+    python update.py >twitter_globals.py
+
+Dependencies:
+
+    * (easy_install) BeautifulSoup
+'''
+
+import sys
+from urllib import urlopen as _open
+from BeautifulSoup import BeautifulSoup
+from htmlentitydefs import codepoint2name
+
+def uni2html(u):
+    '''
+    Convert unicode to html.
+
+    Basically leaves ascii chars as is, and attempts to encode unicode chars as
+    HTML entities. If the conversion fails the character is skipped.
+    '''
+    htmlentities = list()
+    for c in u:
+        ord_c = ord(c)
+        if ord_c < 128:
+            # ignoring all ^chars like ^M ^R ^E
+            if ord_c >31:
+                htmlentities.append(c)
+        else:
+            try:
+                htmlentities.append('&%s;' % codepoint2name[ord_c])
+            except KeyError:
+                pass # Charachter unknown
+    return ''.join(htmlentities)
+
+def print_fw(iterable, joins=', ', prefix='', indent=0, width=79, trail=False):
+    '''
+    PPrint an iterable (of stringable elements).
+
+        Entries are joined using `joins`
+        A fixed_width (fw) is maintained of `width` chars per line
+        Each line is indented with `indent`*4 spaces
+        Lines are then prefixed with `prefix` string
+        if `trail` a trailing comma is sent to stdout
+        A newline is written after all is printed.
+    '''
+    shift_width = 4
+    preline = '%s%s' %(' '*shift_width, prefix)
+    linew = len(preline)
+    sys.stdout.write(preline)
+    for i, entry in enumerate(iterable):
+        if not trail and i == len(iterable) - 1:
+            sentry = str(entry)
+        else:
+            sentry = '%s%s' %(str(entry), joins)
+        if linew + len(sentry) > width:
+            sys.stdout.write('\n%s' %(preline))
+            linew = len(preline)
+        sys.stdout.write(sentry)
+        linew += len(sentry)
+    sys.stdout.write('\n')
+
+
+def main():
+    '''
+    Main function the prints twitter's _POST_ACTIONS to stdout
+
+    TODO: look at possibly dividing up this function
+    '''
+
+    apifile = _open('http://apiwiki.twitter.com/REST+API+Documentation')
+    try:
+        apihtml = uni2html(apifile.read())
+    finally:
+        apifile.close()
+
+    ## Parsing the ApiWiki Page
+
+    apidoc = BeautifulSoup(apihtml)
+    toc = apidoc.find('div', {'class':'toc'})
+    toc_entries = toc.findAll('li', text=lambda text: 'Methods' in text)
+    method_links = {}
+    for entry in toc_entries:
+        links = entry.parent.parent.findAll('a')
+        method_links[links[0].string] = [x['href'] for x in links[1:]]
+
+    # Create unique hash of mehods with POST_ACTIONS
+    POST_ACTION_HASH = {}
+    for method_type, methods in method_links.items():
+        for method in methods:
+            # Strip the hash (#) mark from the method id/name
+            method = method[1:]
+            method_body = apidoc.find('a', {'name': method})
+            value = list(method_body.findNext(
+                    'b', text=lambda text: 'Method' in text
+                ).parent.parent.childGenerator())[-1]
+            if 'POST' in value:
+                method_name = method_body.findNext('h3').string
+                try:
+                    POST_ACTION_HASH[method_name] += (method_type,)
+                except KeyError:
+                    POST_ACTION_HASH[method_name] = (method_type,)
+
+    # Reverse the POST_ACTION_HASH
+    # this is really only done to generate comment strings
+    POST_ACTION_HASH_R = {}
+    for method, method_types in POST_ACTION_HASH.items():
+        try:
+            POST_ACTION_HASH_R[method_types].append(method)
+        except KeyError:
+            POST_ACTION_HASH_R[method_types] = [method]
+
+    ## Print the _POST_ACTIONS to stdout as a Python List
+    print """'''
+    This module is automatically generated using `update.py`
+
+    ..data::
+
+        `_POST_ACTIONS`: Methods that require the use of POST
+'''
+"""
+    print '_POST_ACTIONS = [\n'
+    for method_types, methods in POST_ACTION_HASH_R.items():
+        print_fw(method_types, prefix='# ', indent=1)
+        print_fw([repr(str(x)) for x in methods], indent=1, trail=True)
+        print ""
+    print ']'
+
+if __name__ == "__main__":
+    main()