Created
February 25, 2011 04:56
-
-
Save jmoy/843376 to your computer and use it in GitHub Desktop.
Get Wikipedia watchlist as an RSS/ATOM feed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Get Wikipedia watchlist as an RSS/ATOM feed | |
(c) Jyotirmoy Bhattacharya, 2007 | |
Usage: wikiwatch <username> <password> [format] | |
[format] is either 'rss' or 'atom' | |
""" | |
import sys | |
import xml.sax,xml.sax.handler | |
import urllib,urllib2,cookielib,httplib | |
#Constants | |
version="0.2alpha" | |
user_agent="wikiwatch.py ([email protected])/"+version | |
usage="Usage: wikiwatch <Username> <Password> [rss/atom]" | |
apiURL="http://en.wikipedia.org/w/api.php" | |
class LoginFailedException(Exception): | |
"""Login to Wikipedia failed | |
""" | |
def __init__(self,status): | |
self.message=status | |
class RunTimeError(Exception): | |
"""Run-time error | |
""" | |
def __init__(self,what): | |
self.message=what | |
class BadCmdException(Exception): | |
"""Bad command-line arguments to program | |
""" | |
def __init__(self): | |
self.message="Bad command-line argument" | |
def callapi(data,cookie_jar): | |
"""Make an API call | |
data: list of tuples containing data to be sent in the PUT request | |
cookie_jar: cookielib.CookieJar used for the request | |
Returns a file-like object containing the response | |
""" | |
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar)) | |
req=urllib2.Request(apiURL,urllib.urlencode(data)) | |
req.add_header("User-Agent",user_agent) | |
return opener.open(req) | |
def wikiauth(uname,passwd,cookie_jar): | |
"""Authenticate to Wikipedia and return authentication tokens as cookies | |
uname: Wikipedia username | |
passwd: Wikipedia password | |
cookie_jar: cookielib.CookieJar to store authentication cookies | |
Returns nothing | |
Raises LoginFailedException in case of failure | |
""" | |
class LoginResp(xml.sax.ContentHandler): | |
def __init__(self): | |
self.result="" | |
def startElement(self,name,attrs): | |
if name=="login": | |
self.result=attrs["result"] | |
try: | |
#Create SAX parser | |
parser=xml.sax.make_parser() | |
parser.setFeature(xml.sax.handler.feature_namespaces,0) | |
lr=LoginResp() | |
parser.setContentHandler(lr) | |
#Get login response | |
r=callapi([("action","login"), | |
("format","xml"), | |
("lgname",uname), | |
("lgpassword",passwd)], | |
cookie_jar) | |
#Parse login response to get tokens and see if login succeeded | |
parser.parse(r) | |
if lr.result!="Success": | |
raise LoginFailedException("Authentication denied: "+lr.result) | |
pass | |
except xml.sax.SAXException,inst: | |
raise LoginFailedException("Parse error in login response: " | |
+inst.getMessage()) | |
def getfeed(uname,passwd,feedformat): | |
"""Get Wikipedia watchlist feed | |
uname: Wikipedia username | |
passwd: Wikipedia password | |
feedformat: format of the feed, must be 'rss' or 'atom' | |
Returns a file-like object containing the feed | |
""" | |
jar=cookielib.CookieJar() | |
wikiauth(uname,passwd,jar) | |
return callapi([("action","feedwatchlist"), | |
("feedformat",feedformat)], | |
jar) | |
def do_fetch(argv): | |
"""Parse command-line arguments and fetch feed | |
argv: list of command-line arguments | |
Returns feed as a string | |
Raises BadCmdException if arguments are not proper | |
""" | |
format="atom" | |
if len(argv)==3: | |
pass | |
elif len(argv)==4: | |
if (argv[3]=="rss" or argv[3]=="atom"): | |
format=argv[3] | |
else: | |
raise BadCmdException() | |
else: | |
raise BadCmdException() | |
try: | |
r=getfeed(argv[1],argv[2],format) | |
return r.read() | |
except httplib.HTTPException,inst: | |
raise RunTimeError("httplib Exception: "+str(inst)) | |
except urllib2.URLError, inst: | |
raise RunTimeError("urllib Exception: "+str(inst.reason)) | |
#Main program | |
if __name__=="__main__": | |
try: | |
print do_fetch(sys.argv) | |
except BadCmdException: | |
sys.stderr.write("%s\n"%usage) | |
sys.exit(1) | |
except LoginFailedException,inst: | |
sys.stderr.write("Login failed: %s\n"%inst.message) | |
sys.exit(2) | |
except RunTimeError, inst: | |
sys.stderr.write("Runtime error: %s\n"%inst.message) | |
sys.exit(2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment