1 ;; See ../LICENSE for info
2 (in-package :cl-mediawiki
)
4 (defmacro define-proxy
(name &key core req based-on props doc
(processor 'identity
))
5 "Defines a function with NAME with REQ required parameters. The
6 symbols in the BASED-ON and PROPS lists are concatenated with pairs
7 from the CORE list and passed to the MAKE-PARAMETERS function."
9 (let ((par-sym (gensym)))
10 `(defun ,name
(,@req
&key
,@props
,@based-on
) ,(if doc doc
"no documentation given")
11 (let ((,par-sym
(make-parameters
12 (list ,@(mapcar #'(lambda (x) (if (listp x
)
13 `(list ',(car x
) ',(cadr x
))))
15 ,@(mapcar #'(lambda (x) (if (listp x
)
16 `(list ',(car x
) ,(car x
))
18 (concatenate 'list req props based-on
))))))
21 (parse-api-response-to-sxml (make-api-request ,par-sym
)))))))
24 (define-proxy list-category-members
26 (list categorymembers
))
28 :based-on
(version maxlag smaxage maxage requestid titles pageids revids prop
29 meta generator redirects indexpageids
)
30 :props
(cmprop cmnamespace cmcontinue cmlimit cmsort cmdir cmstart cmend cmstartsortkey cmendsortkey
)
33 (let ((rows (find-nodes-by-name "cm" sxml
)))
35 collecting
(loop for
(attr val
) in
(second row
)
36 collecting
(list (symbolize-string attr
) val
) ))) )
38 "List all pages in a given category.
41 cmtitle - Which category to enumerate (required). Must include Category: prefix
42 cmprop - What pieces of information to include
43 Values (separate with '|'): ids, title, sortkey, timestamp
45 cmnamespace - Only include pages in these namespaces
46 Values (separate with '|'): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101
47 cmcontinue - For large categories, give the value retured from previous query
48 cmlimit - The maximum number of pages to return.
49 No more than 500 (5000 for bots) allowed.
51 cmsort - Property to sort by. One value: sortkey, timestamp,Default: sortkey
52 cmdir - In which direction to sort. One value: asc, desc Default: asc
53 cmstart - Timestamp to start listing from. Can only be used with cmsort=timestamp
54 cmend - Timestamp to end listing at. Can only be used with cmsort=timestamp
55 cmstartsortkey - Sortkey to start listing from. Can only be used with cmsort=sortkey
56 cmendsortkey - Sortkey to end listing at. Can only be used with cmsort=sortkey
59 Get first 10 pages in [[Category:Physics]]:
60 (list-category-members \"Category:Physics\")
62 Get page info about first 10 pages in [[Category:Physics]]:
63 (list-category-members \"Category:Physics\" :prop 'info)
65 Returns a list of alists, each representing a CategoryMember
66 alist keys are: :title :ns :pageid
71 (define-proxy get-page-content
78 (let ((rows (find-nodes-by-name "rev" sxml
)))
79 (third (first rows
))))
81 "Get the content for a given page
84 titles - the title of the page
86 Examples: (get-page-content \"Physics\")
88 Returns: a string with the given page content
91 (define-proxy pages-that-embed
95 :props
(eicontinue einamespace eifilterredir eilimit
)
98 (let* ((rows (find-nodes-by-name "ei" sxml
))
99 (c-blob (first (find-nodes-by-name "embeddedin" (find-nodes-by-name "query-continue" sxml
))))
100 (continuation (when c-blob
101 (destructuring-bind (_1 ((_2 continuation
))) c-blob
102 (declare (ignore _1 _2
))
105 (loop for row in rows
106 do
(destructuring-bind (_1 ((_2 title
) &rest _3
)) row
107 (declare (ignore _1 _2 _3
))
108 (push title titles
)))
109 (values (nreverse titles
) continuation
)))
111 "List pages that embed a given template or other page
114 eititle - Title to search. If null, titles= parameter will be used instead, but will be obsolete soon.
115 eicontinue - When more results are available, use this to continue.
116 einamespace - The namespace to enumerate.
117 Values (separate with '|'): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101, 102, 103
118 eifilterredir - How to filter for redirects
119 One value: all, redirects, nonredirects
121 eilimit - How many total pages to return.
122 No more than 500 (5000 for bots) allowed.
125 Examples: (pages-that-embed \"Template:Client\")
127 Returns: a list of pagetitles and a continuation (if there is one)
130 (defclass token-bag
()
131 ((page-attributes :accessor page-attributes
:initarg
:page-attributes
:initform nil
132 :documentation
"An alist of page attributes returned by the api")
133 (timestamp :accessor timestamp
:initarg
:timestamp
:initform nil
)
134 (tokens :accessor tokens
:initarg
:tokens
:initform nil
135 :documentation
"either a single token, or an
136 alist mapping type to value" )))
138 (defmethod print-object ((token-bag token-bag
) stream
)
139 (with-accessors ((timestamp timestamp
)
140 (tokens tokens
)) token-bag
141 (format stream
"#<Token-bag ~a ~a>" timestamp tokens
)))
143 (defmethod edit-token ((token-bag token-bag
))
144 (cdr (assoc :edit
(tokens token-bag
))))
146 (defmethod move-token ((token-bag token-bag
))
147 (cdr (assoc :move
(tokens token-bag
))))
149 (defmethod delete-token ((token-bag token-bag
))
150 (cdr (assoc :delete
(tokens token-bag
) )))
152 (define-proxy get-action-tokens
153 :core
((action query
)
156 :props
((intoken :edit
))
159 (let ((pages (find-nodes-by-name "page" sxml
)))
160 (let ((result (loop for
(page alist
) in pages
164 :page-attributes
(convert-sxml-attribs-to-alist alist
)
166 (loop for token in
(ensure-list intoken
)
169 (sxml-attribute-value (format nil
"~atoken" token
) alist
)))
170 :timestamp
(sxml-attribute-value "touched" alist
)))))
171 (if (eq 1 (length result
)) (car result
) result
))))
173 "Gets the tokens necessary for perform edits.
176 titles - the title of the page we wish to edit
177 intoken - which tokens do we want (out of :edit :move :delete :block :unblock or a list of those)
179 Examples: (get-action-tokens \"Physics\")
180 (get-action-tokens \"Physics\" :intoken '(:edit :move :delete))
181 (get-action-tokens '(\"Main Page\" \"User:Russ\") :intoken '(:move :edit :delete :protect))
183 Returns: a token bag (or list of them if you asked for multiple pages)
186 (define-proxy get-page-info
187 :core
((action query
)
192 (convert-sxml-attribs-to-alist
193 (second (first (find-nodes-by-name "page" sxml
))
196 "Gets the info for a given page as an alist
199 titles - the title of the page we wish to retrieve the info of
201 Returns: an alist of attributes about the page
204 (define-proxy recent-changes
205 :core
((action query
)
206 (list recentchanges
))
208 :props
(rcstart rcend rcdir rcnamespace rctitles
(rcprop "user|comment|title|timestamp|ids") rcshow rclimit rctype
)
211 (mapcar #'(lambda (n)
212 (convert-sxml-attribs-to-alist
214 (cddr (first (cddr (find "query" (cddr sxml
)
216 :test
#'string-equal
)))))
220 "Enumerates the recent changes
223 rcstart - The timestamp to start enumerating from.
224 rcend - The timestamp to end enumerating.
225 rcdir - In which direction to enumerate.
226 One value: newer, older
228 rcnamespace - Filter log entries to only this namespace(s)
229 Values (separate with '|'): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101, 102, 103
230 rctitles - Filter log entries to only these page titles
231 rcprop - Include additional pieces of information
232 Values (separate with '|'): user, comment, flags, timestamp, title, ids, sizes, redirect, patrolled
233 Default: title|timestamp|ids
234 rcshow - Show only items that meet this criteria.
235 For example, to see only minor edits done by logged-in users, set show=minor|!anon
236 Values (separate with '|'): minor, !minor, bot, !bot, anon, !anon, redirect, !redirect, patrolled, !patrolled
237 rclimit - How many total changes to return.
238 No more than 500 (5000 for bots) allowed.
240 rctype - Which types of changes to show.
241 Values (separate with '|'): edit, new, log
246 (define-proxy user-contribs
247 :core
((action query
)
250 :props
(uclimit ucstart ucend ucuserprefix ucdir ucnamespace
(ucprop "comment|title|timestamp|ids") ucshow
)
253 (mapcar #'(lambda (n)
254 (convert-sxml-attribs-to-alist
256 (cddr (first (cddr (find "query" (cddr sxml
)
258 :test
#'string-equal
)))))
262 " Get all edits by a user
264 uclimit - The maximum number of contributions to return.
265 No more than 500 (5000 for bots) allowed.
267 ucstart - The start timestamp to return from.
268 ucend - The end timestamp to return to.
269 ucuser - The user to retrieve contributions for.
270 ucuserprefix - Retrieve contibutions for all users whose names begin with this value. Overrides ucuser.
271 ucdir - The direction to search (older or newer).
272 One value: newer, older
274 ucnamespace - Only list contributions in these namespaces
275 Values (separate with '|'): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101, 102, 103
276 ucprop - Include additional pieces of information
277 Values (separate with '|'): ids, title, timestamp, comment, flags
278 Default: ids|title|timestamp|flags|comment
279 ucshow - Show only items that meet this criteria, e.g. non minor edits only: show=!minor
280 Values (separate with '|'): minor, !minor
287 ;; Copyright (c) 2008 Accelerated Data Works, Russ Tyndall
289 ;; Permission is hereby granted, free of charge, to any person
290 ;; obtaining a copy of this software and associated documentation files
291 ;; (the "Software"), to deal in the Software without restriction,
292 ;; including without limitation the rights to use, copy, modify, merge,
293 ;; publish, distribute, sublicense, and/or sell copies of the Software,
294 ;; and to permit persons to whom the Software is furnished to do so,
295 ;; subject to the following conditions:
297 ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
298 ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
299 ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
300 ;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
301 ;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
302 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
303 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.