diff --git a/src/main/java/fastily/jwiki/core/MQuery.java b/src/main/java/fastily/jwiki/core/MQuery.java index 98f4e26..3b4fed4 100644 --- a/src/main/java/fastily/jwiki/core/MQuery.java +++ b/src/main/java/fastily/jwiki/core/MQuery.java @@ -483,5 +483,5 @@ public static HashMap getTextExtracts(Wiki wiki, Collection l.put(k, v == null ? null : v.getAsString())); return l; - } + } } \ No newline at end of file diff --git a/src/main/java/fastily/jwiki/core/WQuery.java b/src/main/java/fastily/jwiki/core/WQuery.java index 2686c70..8e16661 100644 --- a/src/main/java/fastily/jwiki/core/WQuery.java +++ b/src/main/java/fastily/jwiki/core/WQuery.java @@ -120,6 +120,11 @@ class WQuery public static final QTemplate PROTECTEDTITLES = new QTemplate( FL.pMap("list", "protectedtitles", "ptprop", "timestamp|level|user|comment"), "ptlimit", "protectedtitles"); + /** + * Default parameters for listing the results of querying Special pages. + */ + public static final QTemplate QUERYPAGES = new QTemplate(FL.pMap("list", "querypage", "qppage", null), "qplimit", "querypage"); + /** * Default parameters for listing random pages */ @@ -182,7 +187,7 @@ class WQuery * Default parameters for getting a user's username and id. */ public static final QTemplate USERINFO = new QTemplate(FL.pMap("meta", "userinfo"), null); - + /** * Default parameters for listing users and their rights. */ @@ -199,7 +204,7 @@ class WQuery */ private static Type strMapT = new TypeToken>() { }.getType(); - + /** * The master parameter list. Tracks current query status. */ @@ -444,9 +449,9 @@ protected static class QReply private QReply(JsonObject input) { this.input = input; - - if(GSONP.nestedHas(input, FL.toSAL("query", "normalized"))) - normalized = GSONP.pairOff(GSONP.getJAofJO(GSONP.getNestedJA(input, FL.toSAL("query", "normalized"))), "from", "to"); + + if (GSONP.nestedHas(input, FL.toSAL("query", "normalized"))) + normalized = GSONP.pairOff(GSONP.getJAofJO(GSONP.getNestedJA(input, FL.toSAL("query", "normalized"))), "from", "to"); } /** diff --git a/src/main/java/fastily/jwiki/core/Wiki.java b/src/main/java/fastily/jwiki/core/Wiki.java index 31a5b90..0c2cfe3 100644 --- a/src/main/java/fastily/jwiki/core/Wiki.java +++ b/src/main/java/fastily/jwiki/core/Wiki.java @@ -387,12 +387,12 @@ public String talkPageOf(String title) public String talkPageBelongsTo(String title) { NS ns = whichNS(title); - - if(ns.v < 0 || ns.v % 2 == 0 ) + + if (ns.v < 0 || ns.v % 2 == 0) return null; - else if(ns.equals(NS.TALK)) + else if (ns.equals(NS.TALK)) return nss(title); - + return (String) nsl.nsM.get(ns.v - 1) + ":" + nss(title); } @@ -1070,6 +1070,35 @@ public ArrayList prefixIndex(NS namespace, String prefix) return allPages(prefix, false, false, -1, namespace); } + /** + * Queries a special page. + * + * @param title The special page to query, without the {@code Special:} prefix. CAVEAT: this is CASE-sensitive, so be + * sure to use the exact title (e.g. {@code UnusedFiles}, {@code BrokenRedirects}). For a full list of + * titles, see the + * official documentation. + * @param cap The maximum number of elements to return. Use {@code -1} to get everything, but be careful because some + * pages can have 10k+ entries. + * @return A List of titles returned by this special page. + */ + public ArrayList querySpecialPage(String title, int cap) + { + WQuery wq = new WQuery(this, cap, WQuery.QUERYPAGES).set("qppage", nss(title)); + + ArrayList l = new ArrayList<>(); + while (wq.has()) + try + { + l.addAll(FL.toAL(FL.streamFrom(GSONP.getNestedJA(wq.next().input, FL.toSAL("query", "querypage", "results"))) + .map(e -> GSONP.getStr(e.getAsJsonObject(), "title")))); + } + catch (Throwable e) + { + e.printStackTrace(); + } + return l; + } + /** * Attempts to resolve title redirects on a Wiki. * diff --git a/src/test/java/fastily/jwiki/test/MockQueryTests.java b/src/test/java/fastily/jwiki/test/MockQueryTests.java index 7387deb..e6ca9cb 100644 --- a/src/test/java/fastily/jwiki/test/MockQueryTests.java +++ b/src/test/java/fastily/jwiki/test/MockQueryTests.java @@ -169,4 +169,19 @@ public void testGetLogs() assertEquals("FastilyBot", l.get(2).user); assertEquals("Test", l.get(2).title); } + + /** + * Tests querying of special pages. + */ + @Test + public void testQuerySpecialPage() + { + addResponse("mockQuerySpecialPage"); + + ArrayList l = wiki.querySpecialPage("Deadendpages", 10); + + assertTrue(l.contains("TestPage")); + assertTrue(l.contains("File:Example.jpg")); + assertTrue(l.contains("Talk:Main page")); + } } \ No newline at end of file diff --git a/src/test/resources/fastily/jwiki/test/mockQuerySpecialPage.json b/src/test/resources/fastily/jwiki/test/mockQuerySpecialPage.json new file mode 100644 index 0000000..19a0096 --- /dev/null +++ b/src/test/resources/fastily/jwiki/test/mockQuerySpecialPage.json @@ -0,0 +1,27 @@ +{ + "query": { + "querypage": { + "name": "Deadendpages", + "cached": "", + "cachedtimestamp": "2017-01-01T01:17:04Z", + "maxresults": 5000, + "results": [ + { + "value": "0", + "ns": 0, + "title": "TestPage" + }, + { + "value": "0", + "ns": 6, + "title": "File:Example.jpg" + }, + { + "value": "0", + "ns": 1, + "title": "Talk:Main page" + } + ] + } + } +} \ No newline at end of file