X-Git-Url: https://projects.mako.cc/source/python-simplemediawiki.debian/blobdiff_plain/3d234226e8c056e0de15ce62645daf945fed1a76..49b148ee4c10fdf671288331217bd4dd0304b8b4:/simplemediawiki.py diff --git a/simplemediawiki.py b/simplemediawiki.py index 71bc4fd..ec12a11 100644 --- a/simplemediawiki.py +++ b/simplemediawiki.py @@ -33,12 +33,18 @@ of namespaces are provided for your convenience. import cookielib import gzip -from iso8601 import iso8601 +import iso8601 import json from StringIO import StringIO import urllib import urllib2 +__author__ = 'Ian Weller ' +__version__ = '1.0.2' +DEFAULT_UA = ('python-simplemediawiki/%s ' + '+https://github.com/ianweller/python-simplemediawiki') \ + % __version__ + class MediaWiki(): """ @@ -46,31 +52,86 @@ class MediaWiki(): api_url: URL to api.php (usually similar to http://example.com/w/api.php) """ - _cj = cookielib.CookieJar() _high_limits = None _namespaces = None _psuedo_namespaces = None - def __init__(self, api_url): + def __init__(self, api_url, cookie_file=None, user_agent=DEFAULT_UA): self._api_url = api_url + if cookie_file: + self._cj = cookielib.MozillaCookieJar(cookie_file) + try: + self._cj.load() + except IOError: + self._cj.save() + self._cj.load() + else: + self._cj = cookielib.CookieJar() + self._opener = urllib2.build_opener( + urllib2.HTTPCookieProcessor(self._cj) + ) + self._opener.addheaders = [('User-agent', user_agent)] - def call(self, params): + def _fetch_http(self, url, params): """ - Make a call to the wiki. Returns a dictionary that represents the JSON - returned by the API. + Standard HTTP request handler for this class with gzip and cookie + support. """ - params['format'] = 'json' - opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cj)) - request = urllib2.Request(self._api_url, urllib.urlencode(params)) + request = urllib2.Request(url, urllib.urlencode(params)) request.add_header('Accept-encoding', 'gzip') - response = opener.open(request) + response = self._opener.open(request) + if isinstance(self._cj, cookielib.MozillaCookieJar): + self._cj.save() if response.headers.get('Content-Encoding') == 'gzip': compressed = StringIO(response.read()) gzipper = gzip.GzipFile(fileobj=compressed) data = gzipper.read() else: data = response.read() - return json.loads(data) + return data + + def call(self, params): + """ + Make a call to the wiki. Returns a dictionary that represents the JSON + returned by the API. + """ + params['format'] = 'json' + return json.loads(self._fetch_http(self._api_url, params)) + + def normalize_api_url(self): + """ + This function checks the given URL for a correct API endpoint and + returns that URL, while also helpfully setting this object's API URL to + it. If it can't magically conjure an API endpoint, it returns False. + """ + def tester(self, api_url): + """ + Attempts to fetch general information about the MediaWiki instance + in order to test whether the given URL will return JSON. + """ + data = self._fetch_http(api_url, {'action': 'query', + 'meta': 'siteinfo'}) + try: + data_json = json.loads(data) + return (data, data_json) + except ValueError: + return (data, None) + + data, data_json = tester(self, self._api_url) + if data_json: + return self._api_url + else: + # if there's an index.php in the URL, we might find the API + if 'index.php' in self._api_url: + test_api_url = self._api_url.split('index.php')[0] + 'api.php' + print test_api_url + test_data, test_data_json = tester(self, test_api_url) + print (test_data, test_data_json) + if test_data_json: + self._api_url = test_api_url + return self._api_url + return False + def login(self, user, passwd, token=None): """ @@ -85,12 +146,22 @@ class MediaWiki(): data['lgtoken'] = token result = self.call(data) if result['login']['result'] == 'Success': + self._high_limits = None return True elif result['login']['result'] == 'NeedToken' and not token: return self.login(user, passwd, result['login']['token']) else: return False + def logout(self): + """ + Conveinence function for logging out of the wiki. + """ + data = {'action': 'logout'} + self.call(data) + self._high_limits = None + return True + def limits(self, low, high): """ Convenience function for determining appropriate limits in the API. If @@ -140,7 +211,3 @@ class MediaWiki(): objects. """ return iso8601.parse_date(date) - - -__author__ = 'Ian Weller ' -__version__ = '1.0'