Make some changes to README and HACKING
[mw] / src / mw / api.py
1 ###
2 # mw - VCS-like nonsense for MediaWiki websites
3 # Copyright (C) 2010  Ian Weller <ian@ianweller.org>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program.  If not, see <http://www.gnu.org/licenses/>.
17 ###
18
19 import cookielib
20 import gzip
21 import json
22 import mw
23 import mw.metadir
24 import os
25 from StringIO import StringIO
26 import urllib
27 import urllib2
28
29
30 class API(object):
31
32     def __init__(self, api_url, metadir):
33         self.api_url = api_url
34         self.metadir = metadir
35         self.cookiejar = cookielib.MozillaCookieJar(os.path.join(
36                 self.metadir.location, 'cookies'))
37         try:
38             self.cookiejar.load()
39         except IOError:
40             self.cookiejar.save()
41             self.cookiejar.load()
42         self.opener = urllib2.build_opener(
43                 urllib2.HTTPCookieProcessor(self.cookiejar))
44         self._high_limits = None
45
46     def call(self, data):
47         data['format'] = 'json'
48         user_agent = 'mw/%s +http://github.com/ianweller/mw' % mw.version
49         request = urllib2.Request(self.api_url, urllib.urlencode(data),
50                                   {'User-Agent': user_agent})
51         request.add_header('Accept-encoding', 'gzip')
52         response = self.opener.open(request)
53         self.cookiejar.save()
54         if response.headers.get('Content-Encoding') == 'gzip':
55             compressed = StringIO(response.read())
56             gzipper = gzip.GzipFile(fileobj=compressed)
57             data = gzipper.read()
58         else:
59             data = response.read()
60         the_data = json.loads(data)
61         if 'error' in the_data.keys():
62             raise APIError(the_data['error']['info'])
63         return the_data
64
65     def limits(self, low, high):
66         if self._high_limits == None:
67             result = self.call({'action': 'query',
68                                 'meta': 'userinfo',
69                                 'uiprop': 'rights'})
70             self._high_limits = 'apihighlimits' in \
71                     result['query']['userinfo']['rights']
72         if self._high_limits:
73             return high
74         else:
75             return low
76
77
78 class APIError(Exception):
79
80     def __init__(self, info):
81         self.info = info
82
83     def __str__(self):
84         return self.info
85
86
87 def pagename_to_filename(name):
88     name = name.replace(' ', '_')
89     name = name.replace('/', '!')
90     return name
91
92
93 def filename_to_pagename(name):
94     name = name.replace('!', '/')
95     name = name.replace('_', ' ')
96     return name

Benjamin Mako Hill || Want to submit a patch?