An Eclipse RCP reimplementation of bgg1tool by Nand. See http://www.nand.it/nandeck/ for the original tool.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

319 líneas
10KB

  1. package xyz.veronie.bgg.result;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.StringReader;
  6. import java.io.UnsupportedEncodingException;
  7. import java.net.HttpURLConnection;
  8. import java.net.MalformedURLException;
  9. import java.net.URL;
  10. import java.net.URLEncoder;
  11. import java.util.ArrayList;
  12. import java.util.Iterator;
  13. import java.util.Map.Entry;
  14. import javax.inject.Inject;
  15. import javax.xml.parsers.DocumentBuilder;
  16. import javax.xml.parsers.DocumentBuilderFactory;
  17. import javax.xml.parsers.ParserConfigurationException;
  18. import org.eclipse.e4.core.di.annotations.Creatable;
  19. import org.eclipse.e4.core.services.events.IEventBroker;
  20. import org.w3c.dom.Document;
  21. import org.w3c.dom.Element;
  22. import org.w3c.dom.Node;
  23. import org.w3c.dom.NodeList;
  24. import org.xml.sax.InputSource;
  25. import org.xml.sax.SAXException;
  26. import xyz.veronie.bgg.types.EventConstants;
  27. import xyz.veronie.bgg.types.FamilyType;
  28. import xyz.veronie.bgg.types.FilterFlagState;
  29. import xyz.veronie.bgg.types.Subtype;
  30. import xyz.veronie.bgg.types.UserFlag;
  31. @Creatable
  32. public class BggApi {
  33. @Inject private ResultConfigManager configManager;
  34. @Inject private IEventBroker eventBroker;
  35. public static String BASE_URL = "https://www.boardgamegeek.com/xmlapi2/";
  36. public static String USER = "user";
  37. public static String COLLECTION = "collection";
  38. public static String SEARCH = "search";
  39. public static String FAMILY = "family";
  40. public static String GEEKLIST = "geeklist";
  41. private static int RETRIES = 5;
  42. public ArrayList<ThingMetaData> getThingsForUser(String user) throws IllegalArgumentException {
  43. ResultConfig resultConfig = configManager.getResultConfig();
  44. StringBuilder urlStr = new StringBuilder();
  45. urlStr.append(BASE_URL + COLLECTION
  46. + "?username=" + resultConfig.user
  47. + "&subtype=" + resultConfig.subtype.toApiString() + "&");
  48. if(resultConfig.subtype == Subtype.BOARDGAME) {
  49. urlStr.append("excludesubtype=" + Subtype.BGEXPANSION.toApiString() + "&");
  50. }
  51. Iterator<Entry<UserFlag, FilterFlagState>> ufIterator
  52. = resultConfig.userFlags.entrySet().iterator();
  53. try {
  54. while(ufIterator.hasNext()) {
  55. Entry<UserFlag, FilterFlagState> elem = ufIterator.next();
  56. String apiString = elem.getKey().toApiString();
  57. FilterFlagState state = elem.getValue();
  58. if(state == FilterFlagState.IS) {
  59. urlStr.append(URLEncoder.encode(apiString, "UTF-8"));
  60. urlStr.append("=1&");
  61. } else if (state == FilterFlagState.ISNOT) {
  62. urlStr.append(URLEncoder.encode(apiString, "UTF-8"));
  63. urlStr.append("=0&");
  64. }
  65. }
  66. }
  67. catch (UnsupportedEncodingException e) {
  68. e.printStackTrace();
  69. return null;
  70. }
  71. return getThings(urlStr.toString());
  72. }
  73. public ArrayList<ThingMetaData> getThingsForGeeklist(int geeklistId) throws IllegalArgumentException {
  74. ResultConfig resultConfig = configManager.getResultConfig();
  75. StringBuilder urlStr = new StringBuilder();
  76. urlStr.append(BASE_URL + GEEKLIST + "/" + String.valueOf(resultConfig.geeklistId));
  77. return getThings(urlStr.toString());
  78. }
  79. public ArrayList<ThingMetaData> getThingsForFamily(int familyId) throws IllegalArgumentException {
  80. ResultConfig resultConfig = configManager.getResultConfig();
  81. StringBuilder urlStr = new StringBuilder();
  82. urlStr.append(BASE_URL + FAMILY + "?id=" + String.valueOf(resultConfig.familyId));
  83. if(resultConfig.familyType != FamilyType.ALL) {
  84. urlStr.append("?type=" + resultConfig.familyType);
  85. }
  86. return getThings(urlStr.toString());
  87. }
  88. private ArrayList<ThingMetaData> getThings(String urlString) throws IllegalArgumentException {
  89. System.out.println("URL: " + urlString);
  90. try {
  91. int retry = 0;
  92. do {
  93. // send a GET request and check for ok...
  94. URL url = new URL(urlString);
  95. HttpURLConnection con = (HttpURLConnection) url.openConnection();
  96. con.setRequestMethod("GET");
  97. int status = con.getResponseCode();
  98. if(status == HttpURLConnection.HTTP_ACCEPTED) {
  99. Thread.sleep(2000);
  100. eventBroker.send(EventConstants.TOPIC_STATUS, "Waiting for server to prepare result...");
  101. }
  102. else if(status != HttpURLConnection.HTTP_OK) {
  103. eventBroker.send(EventConstants.TOPIC_STATUS, "Http Response: " + status);
  104. con.disconnect();
  105. return null;
  106. } else {
  107. // HTTP_OK, go on...
  108. BufferedReader in = new BufferedReader(
  109. new InputStreamReader(con.getInputStream()));
  110. String inputLine;
  111. StringBuffer content = new StringBuffer();
  112. while ((inputLine = in.readLine()) != null) {
  113. content.append(inputLine);
  114. }
  115. in.close();
  116. con.disconnect();
  117. // do something with the content
  118. System.out.println(content.toString());
  119. ArrayList<ThingMetaData> output = parseThingMetas(content.toString());
  120. return output;
  121. }
  122. ++retry;
  123. } while (retry < RETRIES);
  124. }
  125. catch (MalformedURLException e) {
  126. eventBroker.send(EventConstants.TOPIC_STATUS, "[ERROR] Malformed URL: " + urlString);
  127. e.printStackTrace();
  128. } catch (IOException e) {
  129. eventBroker.send(EventConstants.TOPIC_STATUS, "[ERROR] Could not open connection for URL: " + urlString);
  130. e.printStackTrace();
  131. } catch (InterruptedException e) {
  132. // this will not happen, but we have to catch it anyways...
  133. e.printStackTrace();
  134. }
  135. return null;
  136. }
  137. private ArrayList<ThingMetaData> parseThingMetas(String content) throws IllegalArgumentException {
  138. ArrayList<ThingMetaData> metas = new ArrayList<ThingMetaData>();
  139. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  140. try {
  141. DocumentBuilder builder = factory.newDocumentBuilder();
  142. InputSource is = new InputSource(new StringReader(content));
  143. is.setEncoding("UTF-8");
  144. Document doc = builder.parse(is);
  145. Element root = doc.getDocumentElement();
  146. checkForErrors(doc);
  147. // BGG XMLAPI2
  148. if(root.getTagName() == "items") {
  149. NodeList nList = doc.getElementsByTagName("item");
  150. for(int i = 0; i < nList.getLength(); i++) {
  151. Node nNode = nList.item(i);
  152. if (nNode.getNodeType() == Node.ELEMENT_NODE) {
  153. Element eElement = (Element) nNode;
  154. // thing
  155. if( eElement.hasAttribute("objecttype")
  156. && eElement.getAttribute("objecttype").equals("thing"))
  157. {
  158. Integer id = Integer.parseInt(eElement.getAttribute("objectid"));
  159. if(id != 0) {
  160. ThingMetaData tmd = new ThingMetaData(
  161. id,
  162. getValue(eElement, "name"),
  163. getValue(eElement, "image"),
  164. getValue(eElement, "thumbnail"),
  165. getValue(eElement, "comment"),
  166. Integer.parseInt(getValue(eElement, "numplays"))
  167. );
  168. metas.add(tmd);
  169. }
  170. }
  171. // family has "type"
  172. else if(eElement.hasAttribute("type")
  173. && eElement.getAttribute("type").equals("boardgamefamily"))
  174. {
  175. // get name and description
  176. StringBuilder fInfo = new StringBuilder();
  177. NodeList nListName = eElement.getElementsByTagName("name");
  178. if(nListName.getLength() > 0) {
  179. fInfo.append(nListName.item(0).getTextContent() + "\r\n");
  180. }
  181. NodeList nListDesc = doc.getElementsByTagName("description");
  182. if(nListDesc.getLength() > 0) {
  183. fInfo.append(nListDesc.item(0).getTextContent());
  184. }
  185. eventBroker.send(EventConstants.TOPIC_FAMILY_INFO, fInfo.toString());
  186. NodeList nLinks = eElement.getElementsByTagName("link");
  187. for(int l = 0; l < nLinks.getLength(); l++) {
  188. Node link = nLinks.item(l);
  189. if (link.getNodeType() == Node.ELEMENT_NODE) {
  190. Element eLink = (Element) link;
  191. Integer id = Integer.parseInt(eLink.getAttribute("id"));
  192. if(id != 0) {
  193. ThingMetaData tmd = new ThingMetaData(
  194. id,
  195. eLink.getAttribute("value"),
  196. "", "", "", null);
  197. metas.add(tmd);
  198. }
  199. }
  200. }
  201. // because of our input, there shouldn't be more than one family in the result
  202. // but do not iterate over items just to make sure
  203. break;
  204. }
  205. }
  206. }
  207. }
  208. // for geeklist result
  209. else if(root.getTagName() == "geeklist") {
  210. StringBuilder gInfo = new StringBuilder();
  211. NodeList nListTitle = doc.getElementsByTagName("title");
  212. if(nListTitle.getLength() > 0) {
  213. gInfo.append(nListTitle.item(0).getTextContent() + "\r\n");
  214. }
  215. NodeList nListDesc = doc.getElementsByTagName("description");
  216. if(nListDesc.getLength() > 0) {
  217. gInfo.append(nListDesc.item(0).getTextContent());
  218. }
  219. eventBroker.send(EventConstants.TOPIC_GEEKLIST_INFO, gInfo.toString());
  220. NodeList nList = doc.getElementsByTagName("item");
  221. for(int i = 0; i < nList.getLength(); i++) {
  222. Node nNode = nList.item(i);
  223. if (nNode.getNodeType() == Node.ELEMENT_NODE) {
  224. Element eElement = (Element) nNode;
  225. Integer id = Integer.parseInt(eElement.getAttribute("objectid"));
  226. if(id != 0) {
  227. ThingMetaData tmd = new ThingMetaData(
  228. Integer.parseInt(eElement.getAttribute("objectid")),
  229. eElement.getAttribute("objectname"),
  230. "", "", "", null);
  231. metas.add(tmd);
  232. }
  233. }
  234. }
  235. }
  236. return metas;
  237. } catch (ParserConfigurationException e) {
  238. e.printStackTrace();
  239. } catch (SAXException e) {
  240. e.printStackTrace();
  241. } catch (IOException e) {
  242. e.printStackTrace();
  243. }
  244. return null;
  245. }
  246. private void checkForErrors(Document doc) throws IllegalArgumentException {
  247. NodeList nList = doc.getElementsByTagName("error");
  248. if(nList.getLength() > 0) {
  249. Element el = (Element)nList.item(0);
  250. String val = getValue(el, "message");
  251. if(val.equals("")) {
  252. val = el.getAttribute("message");
  253. }
  254. throw new IllegalArgumentException(val);
  255. }
  256. }
  257. private String getValue(Element eElement, String key) {
  258. Node node = eElement.getElementsByTagName(key).item(0);
  259. if(node == null) {
  260. return "";
  261. } else {
  262. return node.getTextContent();
  263. }
  264. }
  265. }