source: josm/trunk/src/org/openstreetmap/josm/tools/Mediawiki.java@ 16988

Last change on this file since 16988 was 16988, checked in by simon04, 4 years ago

Extract and test Mediawiki.getImageUrl

File size: 3.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.io.IOException;
5import java.io.InputStream;
6import java.net.URL;
7import java.util.List;
8import java.util.Optional;
9import java.util.stream.Collectors;
10
11import javax.xml.parsers.ParserConfigurationException;
12import javax.xml.xpath.XPath;
13import javax.xml.xpath.XPathConstants;
14import javax.xml.xpath.XPathExpressionException;
15import javax.xml.xpath.XPathFactory;
16
17import org.w3c.dom.Document;
18import org.w3c.dom.Node;
19import org.xml.sax.SAXException;
20
21/**
22 * Interaction with Mediawiki instances, such as the OSM wiki.
23 * @since 14641
24 */
25public class Mediawiki {
26
27 private final String baseUrl;
28
29 /**
30 * Constructs a new {@code Mediawiki} for the given base URL.
31 * @param baseUrl The wiki base URL
32 */
33 public Mediawiki(String baseUrl) {
34 this.baseUrl = baseUrl;
35 }
36
37 /**
38 * Determines which page exists on the Mediawiki instance.
39 * @param pages the pages to check
40 * @return the first existing page
41 * @throws IOException if any I/O error occurs
42 * @throws ParserConfigurationException if a parser cannot be created
43 * @throws SAXException if any XML error occurs
44 * @throws XPathExpressionException if any error in an XPath expression occurs
45 */
46 public Optional<String> findExistingPage(List<String> pages)
47 throws IOException, ParserConfigurationException, SAXException, XPathExpressionException {
48 List<String> distinctPages = pages.stream().distinct().collect(Collectors.toList());
49 // find a page that actually exists in the wiki
50 // API documentation: https://wiki.openstreetmap.org/w/api.php?action=help&modules=query
51 final URL url = new URL(baseUrl + "/w/api.php?action=query&format=xml&titles=" + distinctPages.stream()
52 .map(Utils::encodeUrl)
53 .collect(Collectors.joining(Utils.encodeUrl("|")))
54 );
55 final HttpClient.Response conn = HttpClient.create(url).connect();
56 final Document document;
57 try (InputStream content = conn.getContent()) {
58 document = XmlUtils.parseSafeDOM(content);
59 }
60 conn.disconnect();
61 final XPath xPath = XPathFactory.newInstance().newXPath();
62 for (String page : distinctPages) {
63 String normalized = xPath.evaluate("/api/query/normalized/n[@from='" + page + "']/@to", document);
64 if (normalized == null || normalized.isEmpty()) {
65 normalized = page;
66 }
67 final Node node = (Node) xPath.evaluate("/api/query/pages/page[@title='" + normalized + "']", document, XPathConstants.NODE);
68 if (node != null
69 && node.getAttributes().getNamedItem("missing") == null
70 && node.getAttributes().getNamedItem("invalid") == null) {
71 return Optional.of(page);
72 }
73 }
74 return Optional.empty();
75 }
76
77 /**
78 * Computes the URL for the given filename on the MediaWiki server
79 * @param fileBaseUrl the base URL of the file MediaWiki storage, such as {@code "https://upload.wikimedia.org/wikipedia/commons/"}
80 * @param filename the filename
81 * @return the URL for the given filename on the MediaWiki server
82 * @see <a href="https://www.mediawiki.org/wiki/Manual:$wgHashedUploadDirectory">MediaWiki $wgHashedUploadDirectory</a>
83 */
84 public static String getImageUrl(String fileBaseUrl, String filename) {
85 final String md5 = Utils.md5Hex(filename);
86 return String.join("/", Utils.strip(fileBaseUrl, "/"), md5.substring(0, 1), md5.substring(0, 2), filename);
87 }
88}
Note: See TracBrowser for help on using the repository browser.