]> 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 exceptions import Exception
 
+from twitter.twitter_globals import _POST_ACTIONS
+
 def _py26OrGreater():
     import sys
     return sys.hexversion > 0x20600f0
 def _py26OrGreater():
     import sys
     return sys.hexversion > 0x20600f0
@@ -22,11 +24,6 @@ class TwitterError(Exception):
     """
     pass
 
     """
     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):
 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)
         id = kwargs.pop('id', None)
         if id:
             uri += "/%s" %(id)
-            
+
         encoded_kwargs = urlencode(kwargs.items())
         argStr = ""
         argData = None
         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.
 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).
 
     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
 
       http://apiwiki.twitter.com/
       http://groups.google.com/group/twitter-development-talk/web/api-documentation
-    
+
     Examples::
     Examples::
-    
+
       twitter = Twitter("hello@foo.com", "password123")
       twitter = Twitter("hello@foo.com", "password123")
-      
+
       # Get the public timeline
       twitter.statuses.public_timeline()
       # Get the public timeline
       twitter.statuses.public_timeline()
-      
+
       # Get a particular friend's timeline
       twitter.statuses.friends_timeline(id="billybob")
       # Get a particular friend's timeline
       twitter.statuses.friends_timeline(id="billybob")
-      
+
       # Also supported (but totally weird)
       twitter.statuses.friends_timeline.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::
       # 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
       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']
 
       # The screen name of the user who wrote the first 'tweet'
       x[0]['user']['screen_name']
-    
+
     Getting raw XML data::
     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:
       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")
       twitter = Twitter(format="xml")
-      
+
       The output will not be parsed in any way. It will be a raw string
       of 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()