1# -*- coding: utf-8 -*-
2# Copyright 2008, 2009 Mr.Z-man
3
4# This file is part of wikitools.
5# wikitools 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 3 of the License, or
8# (at your option) any later version.
9
10# wikitools 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
16# along with wikitools.  If not, see <http://www.gnu.org/licenses/>.
17
18import api
19import page
20import category
21import wikifile
22import math
23
24def listFromQuery(site, queryresult):
25	"""Generate a list of pages from an API query result
26
27	queryresult is the list of pages from a list or generator query
28	e.g. - for a list=categorymembers query, use result['query']['categorymembers']
29	for a generator query, use result['query']['pages']
30
31	"""
32	ret = []
33	if isinstance(queryresult, list):
34		for item in queryresult:
35			pageid = False
36			if 'pageid' in item:
37				pageid = item['pageid']
38			if item['ns'] == 14:
39				item = category.Category(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
40			if item['ns'] == 6:
41				item = wikifile.File(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
42			else:
43				item = page.Page(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
44			ret.append(item)
45	else:
46		for key in queryresult.keys():
47			item = queryresult[key]
48			pageid = False
49			if 'pageid' in item:
50				pageid = item['pageid']
51			if item['ns'] == 14:
52				item = category.Category(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
53			if item['ns'] == 6:
54				item = wikifile.File(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
55			else:
56				item = page.Page(site, title=item['title'], check=False, followRedir=False, pageid=pageid)
57			ret.append(item)
58	return ret
59
60def listFromTitles(site, titles, check=True, followRedir=False):
61	"""Create a list of page objects from a list of titles
62
63	check and followRedir have the same meaning as in page.Page
64
65	"""
66	ret = []
67	if not check:
68		for title in titles:
69			title = page.Page(site, title=title, check=False)
70			ret.append(title)
71	else:
72		querylist = []
73		limit = int(site.limit)
74		if len(titles) > limit/10:
75			iters = int(math.ceil(float(len(titles)) / (limit/10)))
76			for x in range(0,iters):
77				lower = x*limit/10
78				upper = (x+1)*limit/10
79				querylist.append(titles[lower:upper])
80		else:
81			querylist.append(titles)
82		response = False
83		for item in querylist:
84			tlist = '|'.join(item)
85			if not isinstance(tlist, unicode):
86				tlist = unicode(tlist, 'utf8')
87			params = {'action':'query',
88				'titles':tlist,
89			}
90			if followRedir:
91				params['redirects'] = ''
92			req = api.APIRequest(site, params)
93			res = req.query(False)
94			if not response:
95				response = res
96			else:
97				# This breaks on non-existent titles, the api gives them negative numbers
98				# resultCombine doesn't account for this and ignores or overwrites the
99				# duplicate pageids
100				response = api.resultCombine('', response, res)
101		for key in response['query']['pages'].keys():
102			res = response['query']['pages'][key]
103			item = makePage(key, res, site)
104			ret.append(item)
105	return ret
106
107def listFromPageids(site, pageids, check=True, followRedir=False):
108	"""Create a list of page objects from a list of pageids
109
110	check and followRedir have the same meaning as in page.Page
111
112	"""
113	ret = []
114	if not check:
115		for id in pageids:
116			title = page.Page(site, pageid=id, check=False)
117			ret.append(title)
118	else:
119		querylist = []
120		limit = int(site.limit)
121		if len(pageids) > limit/10:
122			iters = int(math.ceil(float(len(pageids)) / (limit/10)))
123			for x in range(0,iters):
124				lower = x*limit/10
125				upper = (x+1)*limit/10
126				querylist.append(pageids[lower:upper])
127		else:
128			querylist.append(pageids)
129		response = False
130		for item in querylist:
131			ids = [str(id) for id in item]
132			idlist = '|'.join(ids)
133			params = {'action':'query',
134				'pageids':idlist,
135			}
136			if followRedir:
137				params['redirects'] = ''
138			req = api.APIRequest(site, params)
139			res = req.query()
140			if not response:
141				response = res
142			else:
143				response = api.resultCombine('', response, res)
144		for key in response['query']['pages'].keys():
145			res = response['query']['pages'][key]
146			item = makePage(key, res, site)
147			ret.append(item)
148	return ret
149
150def makePage(key, result, site):
151	title=False
152	if 'title' in result:
153		title = result['title']
154	if 'ns' in result and result['ns'] == 14:
155		item = category.Category(site, title=title, check=False, followRedir=False, pageid=key)
156	elif 'ns' in result and result['ns'] == 6:
157		item = wikifile.File(site, title=title, check=False, followRedir=False, pageid=key)
158	else:
159		item = page.Page(site, title=title, check=False, followRedir=False, pageid=key)
160	if 'missing' in result:
161		item.exists = False
162	if 'invalid' in result:
163		item = False
164	if 'ns' in result:
165		item.setNamespace(int(result['ns']))
166	return item
167