diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/localdb/SqliteController.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/localdb/SqliteController.java index b5d19e5..5670921 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/localdb/SqliteController.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/localdb/SqliteController.java @@ -90,6 +90,41 @@ public class SqliteController { stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idx1 ON ThingList(Name)"); stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingListToThing (ListId INTEGER, ThingId INTEGER, FOREIGN KEY (ListId) REFERENCES ThingList(ListId), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idx2 ON ThingListToThing(ListId, ThingId)"); + + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Artist (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxArtist ON Artist(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Designer (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idDesigner ON Designer(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Mechanic (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxMechanic ON Mechanic(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Family (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxFamily ON Family(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Category (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxCategory ON Category(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Expansion (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxExpansion ON Expansion(Id)"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Domain (Id INTEGER PRIMARY KEY, Name);"); + stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idxDomain ON Domain(Id)"); + + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingDetails (" + + "ThingId INTEGER PRIMARY KEY, name, yearpublished INTEGER, " + + "minplayers INTEGER, maxplayers INTEGER, playingtime INTEGER, minplaytime INTEGER, maxplaytime INTEGER, " + + "age INTEGER, usersrated INTEGER, average FLOAT, bayesaverage FLOAT, " + + "owning INTEGER, trading INTEGER, wanting INTEGER, wishing INTEGER, " + + "rank INTEGER, rank_wg INTEGER, numcomments INTEGER, numweights INTEGER, " + + "averageweight FLOAT, stddev FLOAT, median FLOAT, image, comment," + + "player1,player2,player3,player4,player5,player6,player7,player8,player9,player10," + + "player11, player12, player13, player14, player15, player16, player17, player18, player19, player20," + + "description, numplays INTEGER, price FLOAT, age_poll FLOAT);"); + + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToArtist (ThingId INTEGER, ArtistId INTEGER, FOREIGN KEY (ArtistId) REFERENCES Artist(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToDesigner (ThingId INTEGER, DesignerId INTEGER, FOREIGN KEY (DesignerId) REFERENCES Designer(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToMechanic (ThingId INTEGER, MechanicId INTEGER, FOREIGN KEY (MechanicId) REFERENCES Mechanic(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToFamily (ThingId INTEGER, FamilyId INTEGER, FOREIGN KEY (FamilyId) REFERENCES Family(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToCategory (ThingId INTEGER, CategoryId INTEGER, FOREIGN KEY (CategoryId) REFERENCES Category(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToExpansion (ThingId INTEGER, ExpansionId INTEGER, FOREIGN KEY (ExpansionId) REFERENCES Expansion(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingToDomain (ThingId INTEGER, DomainId INTEGER, FOREIGN KEY (DomainId) REFERENCES Domain(Id), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); + stmt.close(); } catch (SQLException e) { System.err.println("Couldn't create Schema"); diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java index 0e46668..32db4c7 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java @@ -186,7 +186,7 @@ public class BggApi { // do something with the content System.out.println(content.toString()); - ArrayList output = parseThingMetas(content.toString()); + ArrayList output = parseThings(content.toString()); output.sort((thing1, thing2) -> thing1.getMetaData().getName().compareTo(thing2.getMetaData().getName())); @@ -213,7 +213,7 @@ public class BggApi { - private ArrayList parseThingMetas(String content) throws IllegalArgumentException { + private ArrayList parseThings(String content) throws IllegalArgumentException { ArrayList things = new ArrayList(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -239,124 +239,20 @@ public class BggApi { if( eElement.hasAttribute("objecttype") && eElement.getAttribute("objecttype").equals("thing")) { - Integer id = Integer.parseInt(eElement.getAttribute("objectid")); - if(id != 0) { - ThingMetaData tmd = new ThingMetaData( - id, - getValue(eElement, "name"), - getValue(eElement, "image"), - getValue(eElement, "thumbnail") - ); - ThingUserData tud = new ThingUserData(); - tud.setNumPlays(Integer.valueOf(getValue(eElement, "numplays"))); - tud.setComment(getValue(eElement, "comment")); - - // rating - NodeList statsNodes = eElement.getElementsByTagName("stats"); - if(statsNodes.getLength() > 0) { - Node statsNode = statsNodes.item(0); - NodeList statsChildren = statsNode.getChildNodes(); - if(statsChildren.getLength() > 0) { - Element ratingNode = (Element)statsChildren.item(0); - String ratingValue = ratingNode.getAttribute("value"); - if(!ratingValue.equals("N/A")) { - try { - Float rating = Float.valueOf(ratingValue); - tud.setRating(rating); - } - catch(NumberFormatException e) { - System.out.println("WARN: rating value is not a float."); - } - } - } - } - - NodeList statusNodes = eElement.getElementsByTagName("status"); - if(statusNodes.getLength() > 0) { - Element statusNode = (Element)statusNodes.item(0); - tud.setOwn(attributeToBoolean(statusNode, "own")); - tud.setPrevowned(attributeToBoolean(statusNode, "prevowned")); - tud.setFortrade(attributeToBoolean(statusNode, "fortrade")); - tud.setWant(attributeToBoolean(statusNode, "want")); - tud.setWanttoplay(attributeToBoolean(statusNode, "wanttoplay")); - tud.setWanttobuy(attributeToBoolean(statusNode, "wanttobuy")); - tud.setWishlist(attributeToBoolean(statusNode, "wishlist")); - if(statusNode.hasAttribute("wishlistpriority")) { - tud.setWishlistpriority(Integer.valueOf(statusNode.getAttribute("wishlistpriority"))); - } - tud.setPreordered(attributeToBoolean(statusNode, "preordered")); - tud.setLastmodified(statusNode.getAttribute("lastmodified")); - } - - Thing thing = new Thing(id, tmd); - thing.setUserData(tud); - things.add(thing); - } + extractThingByUser(things, eElement); } // when fetching things by id, type is boardgame else if(eElement.hasAttribute("type") && eElement.getAttribute("type").equals("boardgame")) { - Integer id = Integer.parseInt(eElement.getAttribute("id")); - if(id != 0) { - String name = ""; - NodeList nameList = eElement.getElementsByTagName("name"); - for(int n = 0; n < nameList.getLength(); n++) { - Node nameNode = nameList.item(n); - if (nNode.getNodeType() == Node.ELEMENT_NODE) { - Element nameElement = (Element) nameNode; - if(nameElement.hasAttribute("type") - && nameElement.getAttribute("type").equals("primary")) - { - name = nameElement.getAttribute("value"); - break; - } - } - } - - ThingMetaData tmd = new ThingMetaData( - id, - name, - getValue(eElement, "image"), - getValue(eElement, "thumbnail")); - Thing thing = new Thing(id, tmd); - things.add(thing); - } - } + extractThingsById(things, nNode, eElement); + } + // family has "type" else if(eElement.hasAttribute("type") && eElement.getAttribute("type").equals("boardgamefamily")) { - // get name and description - StringBuilder fInfo = new StringBuilder(); - - NodeList nListName = eElement.getElementsByTagName("name"); - if(nListName.getLength() > 0) { - fInfo.append(nListName.item(0).getTextContent() + "\r\n"); - } - - NodeList nListDesc = doc.getElementsByTagName("description"); - if(nListDesc.getLength() > 0) { - fInfo.append(nListDesc.item(0).getTextContent()); - } - eventBroker.send(EventConstants.TOPIC_FAMILY_INFO, fInfo.toString()); - - NodeList nLinks = eElement.getElementsByTagName("link"); - for(int l = 0; l < nLinks.getLength(); l++) { - Node link = nLinks.item(l); - if (link.getNodeType() == Node.ELEMENT_NODE) { - Element eLink = (Element) link; - Integer id = Integer.parseInt(eLink.getAttribute("id")); - if(id != 0) { - ThingMetaData tmd = new ThingMetaData( - id, - eLink.getAttribute("value"), - "", ""); - Thing thing = new Thing(id, tmd); - things.add(thing); - } - } - } + extractThingByFamily(things, doc, eElement); // because of our input, there shouldn't be more than one family in the result // but do not iterate over items just to make sure @@ -367,35 +263,7 @@ public class BggApi { } // for geeklist result else if(root.getTagName() == "geeklist") { - StringBuilder gInfo = new StringBuilder(); - - NodeList nListTitle = doc.getElementsByTagName("title"); - if(nListTitle.getLength() > 0) { - gInfo.append(nListTitle.item(0).getTextContent() + "\r\n"); - } - - NodeList nListDesc = doc.getElementsByTagName("description"); - if(nListDesc.getLength() > 0) { - gInfo.append(nListDesc.item(0).getTextContent()); - } - eventBroker.send(EventConstants.TOPIC_GEEKLIST_INFO, gInfo.toString()); - - NodeList nList = doc.getElementsByTagName("item"); - for(int i = 0; i < nList.getLength(); i++) { - Node nNode = nList.item(i); - if (nNode.getNodeType() == Node.ELEMENT_NODE) { - Element eElement = (Element) nNode; - Integer id = Integer.parseInt(eElement.getAttribute("objectid")); - if(id != 0) { - ThingMetaData tmd = new ThingMetaData( - id, - eElement.getAttribute("objectname"), - "", ""); - Thing thing = new Thing(id, tmd); - things.add(thing); - } - } - } + extractThingByGeeklist(things, doc); } return things; @@ -413,6 +281,276 @@ public class BggApi { return null; } + private void extractThingByGeeklist(ArrayList things, Document doc) { + StringBuilder gInfo = new StringBuilder(); + + NodeList nListTitle = doc.getElementsByTagName("title"); + if(nListTitle.getLength() > 0) { + gInfo.append(nListTitle.item(0).getTextContent() + "\r\n"); + } + + NodeList nListDesc = doc.getElementsByTagName("description"); + if(nListDesc.getLength() > 0) { + gInfo.append(nListDesc.item(0).getTextContent()); + } + eventBroker.send(EventConstants.TOPIC_GEEKLIST_INFO, gInfo.toString()); + + NodeList nList = doc.getElementsByTagName("item"); + for(int i = 0; i < nList.getLength(); i++) { + Node nNode = nList.item(i); + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + Element eElement = (Element) nNode; + Integer id = Integer.parseInt(eElement.getAttribute("objectid")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + id, + eElement.getAttribute("objectname"), + "", ""); + Thing thing = new Thing(id, tmd); + things.add(thing); + } + } + } + } + + private void extractThingByFamily(ArrayList things, Document doc, Element eElement) { + // get name and description + StringBuilder fInfo = new StringBuilder(); + + NodeList nListName = eElement.getElementsByTagName("name"); + if(nListName.getLength() > 0) { + fInfo.append(nListName.item(0).getTextContent() + "\r\n"); + } + + NodeList nListDesc = doc.getElementsByTagName("description"); + if(nListDesc.getLength() > 0) { + fInfo.append(nListDesc.item(0).getTextContent()); + } + eventBroker.send(EventConstants.TOPIC_FAMILY_INFO, fInfo.toString()); + + NodeList nLinks = eElement.getElementsByTagName("link"); + for(int l = 0; l < nLinks.getLength(); l++) { + Node link = nLinks.item(l); + if (link.getNodeType() == Node.ELEMENT_NODE) { + Element eLink = (Element) link; + Integer id = Integer.parseInt(eLink.getAttribute("id")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + id, + eLink.getAttribute("value"), + "", ""); + Thing thing = new Thing(id, tmd); + things.add(thing); + } + } + } + } + + private void extractThingsById(ArrayList things, Node nNode, Element eElement) { + Integer id = Integer.parseInt(eElement.getAttribute("id")); + if(id != 0) { + String name = ""; + NodeList nameList = eElement.getElementsByTagName("name"); + for(int n = 0; n < nameList.getLength(); n++) { + Node nameNode = nameList.item(n); + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + Element nameElement = (Element) nameNode; + if(nameElement.hasAttribute("type") + && nameElement.getAttribute("type").equals("primary")) + { + name = nameElement.getAttribute("value"); + break; + } + } + } + + ThingMetaData tmd = new ThingMetaData( + id, + name, + getValue(eElement, "image"), + getValue(eElement, "thumbnail")); + + System.out.println("DEBUG: Details for " + id); + + ThingDetails details = new ThingDetails(); + details.yearpublished = getIntegerFromString(getValueAttribute(eElement, "yearpublished")); + details.minplayers = getIntegerFromString(getValueAttribute(eElement, "minplayers")); + details.maxplayers = getIntegerFromString(getValueAttribute(eElement, "maxplayers")); + details.playingtime = getIntegerFromString(getValueAttribute(eElement, "playingtime")); + details.minplaytime = getIntegerFromString(getValueAttribute(eElement, "minplaytime")); + details.maxplaytime = getIntegerFromString(getValueAttribute(eElement, "maxplaytime")); + details.age = getIntegerFromString(getValueAttribute(eElement, "minage")); + + NodeList pollList = eElement.getElementsByTagName("poll"); + for(int n = 0; n < pollList.getLength(); n++) { + Node pollNode = pollList.item(n); + if (pollNode.getNodeType() == Node.ELEMENT_NODE) { + Element pollElement = (Element) pollNode; + if(pollElement.hasAttribute("name")) { + String pollType = pollElement.getAttribute("name"); + if(pollType.equals("suggested_numplayers")) { + for(int p = 0; p < 20; ++p) { + if(p+1 < details.minplayers || p+1 > details.maxplayers) { + details.players.add(Recommendation.N); + } else { + details.players.add(getMajorityRecommendation(pollElement, p+1)); + } + } + } + + } + } // other polls + } + + NodeList linkList = eElement.getElementsByTagName("link"); + for(int n = 0; n < linkList.getLength(); n++) { + Node linkNode = linkList.item(n); + if (linkNode.getNodeType() == Node.ELEMENT_NODE) { + Element linkElement = (Element) linkNode; + if(linkElement.hasAttribute("type")) { + String type = linkElement.getAttribute("type"); + switch(type) { + case "boardgamecategory": + details.category.add(extractLinkFromElement(linkElement)); + break; + case "boardgamemechanic": + details.mechanic.add(extractLinkFromElement(linkElement)); + break; + case "boardgamefamily": + details.family.add(extractLinkFromElement(linkElement)); + break; + case "boardgamedesigner": + details.designer.add(extractLinkFromElement(linkElement)); + break; + case "boardgameartist": + details.artist.add(extractLinkFromElement(linkElement)); + break; + case "boardgamepublisher": + details.publisher.add(extractLinkFromElement(linkElement)); + break; + case "boardgameexpansion": + details.expansion.add(extractLinkFromElement(linkElement)); + break; + case "boardgamedomain": + details.domain.add(extractLinkFromElement(linkElement)); + break; + default: + System.out.println("WARN: ignoring link element: " + type); + } + } + } + } + + Thing thing = new Thing(id, tmd); + thing.setDetails(details); + things.add(thing); + } + } + + + private IdString extractLinkFromElement(Element linkElement) { + if(linkElement.hasAttribute("id") && linkElement.hasAttribute("value")) { + return new IdString(Integer.valueOf(linkElement.getAttribute("id")), linkElement.getAttribute("value")); + } + System.out.println("WARN: Link is missing attributes."); + return null; + } + + private Recommendation getMajorityRecommendation(Element pollElement, int i) { + Recommendation recommendation = null; + + NodeList nodeList = pollElement.getElementsByTagName("results"); + for(int n = 0; n < nodeList.getLength(); ++n) { + Element elem = (Element)nodeList.item(n); + // TODO: numplayers can be X+ where X is the max number of players... + if(elem.hasAttribute("numplayers") && Integer.valueOf(elem.getAttribute("numplayers")) == i) { + int lastvotes = 0; + NodeList results = elem.getElementsByTagName("result"); + for(int r = 0; r < results.getLength(); ++r) { + Element result = (Element)results.item(r); + if(result.hasAttribute("value") && result.hasAttribute("numvotes")) { + Integer numvotes = Integer.valueOf(result.getAttribute("numvotes")); + if(numvotes > lastvotes) { + recommendation = recommendationValueToEnum(result.getAttribute("value")); + } + } + + } + } + } + + return recommendation; + } + + private Recommendation recommendationValueToEnum(String attribute) { + switch(attribute) { + case "Best": + return Recommendation.B; + case "Recommended": + return Recommendation.R; + case "Not Recommended": + return Recommendation.P; + default: + return Recommendation.N; + } + } + + private void extractThingByUser(ArrayList things, Element eElement) { + Integer id = Integer.parseInt(eElement.getAttribute("objectid")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + id, + getValue(eElement, "name"), + getValue(eElement, "image"), + getValue(eElement, "thumbnail") + ); + ThingUserData tud = new ThingUserData(); + tud.setNumPlays(Integer.valueOf(getValue(eElement, "numplays"))); + tud.setComment(getValue(eElement, "comment")); + + // rating + NodeList statsNodes = eElement.getElementsByTagName("stats"); + if(statsNodes.getLength() > 0) { + Node statsNode = statsNodes.item(0); + NodeList statsChildren = statsNode.getChildNodes(); + if(statsChildren.getLength() > 0) { + Element ratingNode = (Element)statsChildren.item(0); + String ratingValue = ratingNode.getAttribute("value"); + if(!ratingValue.equals("N/A")) { + try { + Float rating = Float.valueOf(ratingValue); + tud.setRating(rating); + } + catch(NumberFormatException e) { + System.out.println("WARN: rating value is not a float."); + } + } + } + } + + NodeList statusNodes = eElement.getElementsByTagName("status"); + if(statusNodes.getLength() > 0) { + Element statusNode = (Element)statusNodes.item(0); + tud.setOwn(attributeToBoolean(statusNode, "own")); + tud.setPrevowned(attributeToBoolean(statusNode, "prevowned")); + tud.setFortrade(attributeToBoolean(statusNode, "fortrade")); + tud.setWant(attributeToBoolean(statusNode, "want")); + tud.setWanttoplay(attributeToBoolean(statusNode, "wanttoplay")); + tud.setWanttobuy(attributeToBoolean(statusNode, "wanttobuy")); + tud.setWishlist(attributeToBoolean(statusNode, "wishlist")); + if(statusNode.hasAttribute("wishlistpriority")) { + tud.setWishlistpriority(Integer.valueOf(statusNode.getAttribute("wishlistpriority"))); + } + tud.setPreordered(attributeToBoolean(statusNode, "preordered")); + tud.setLastmodified(statusNode.getAttribute("lastmodified")); + } + + Thing thing = new Thing(id, tmd); + thing.setUserData(tud); + things.add(thing); + } + } + private Boolean attributeToBoolean(Element statusNode, String attribute) { if(statusNode.hasAttribute(attribute)) { @@ -420,7 +558,7 @@ public class BggApi { } return null; } - + private void checkForErrors(Document doc) throws IllegalArgumentException { NodeList nList = doc.getElementsByTagName("error"); if(nList.getLength() > 0) { @@ -433,6 +571,12 @@ public class BggApi { } } + private Integer getIntegerFromString(String s) { + if(s != null && !s.isEmpty()) { + return Integer.valueOf(s); + } + return null; + } private String getValue(Element eElement, String key) { Node node = eElement.getElementsByTagName(key).item(0); @@ -443,5 +587,15 @@ public class BggApi { } } + private String getValueAttribute(Element eElement, String key) { + Node node = (Element)eElement.getElementsByTagName(key).item(0); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element elem = (Element) node; + if(elem.hasAttribute("value")) { + return elem.getAttribute("value"); + } + } + return null; + } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/Thing.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/Thing.java index bf0423c..009a38c 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/Thing.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/Thing.java @@ -150,140 +150,57 @@ public class Thing { } + private static String resultHeader() { + String header = "id,name,image,"; + return header; + } + + public static String makeResultHeader() { + String header = Thing.resultHeader() + ThingUserData.resultHeader() + ThingDetails.resultHeader(); + return header; + } + /// convert the thing into a comma-separated line for a result.txt file /** * The format is (without line breaks): - * id,name,designer,publisher,artist,yearpublished,minplayers,maxplayers,playingtime,minplaytime,maxplaytime, + * id,name,designer, + * + * owned,trading,wanting,wishing,userrating,comment,numplays,wishpriority + * + * designer,publisher,artist,yearpublished,minplayers,maxplayers,playingtime,minplaytime,maxplaytime, * age,usersrated,average,bayesaverage,rank,rank_wg,numcomments,numweights,averageweight,stddev,median, - * owned,trading,wanting,wishing,userrating,image,category,mechanic,comment, + * category,mechanic, * 1player,2player,3player,4player,5player,6player,7player,8player,9player,10player, * 11player,12player,13player,14player,15player,16player,17player,18player,19player,20player, * description,exp,basegame,reimplement,reimplement_name,reimplemented,reimplemented_name, - * contains,contains_name,iscontained,iscontained_name,integration,integration_name, - * numplays,price,userweight,wishpriority,expansions,domain,family,age_poll + * contains,contains_name,iscontained,iscontained_name,integration,integration_name,price, + * expansions,domain,family,age_poll * * @return */ // TODO: rewrite: order isn't important, column names are public String toResultTxtLine() { StringBuilder str = new StringBuilder(); - final String emptyItem = "\"\","; - // id,name,designer,publisher,artist,yearpublished,minplayers,maxplayers,playingtime,minplaytime,maxplaytime, - // age,usersrated,average,bayesaverage,rank,rank_wg,numcomments,numweights,averageweight,stddev,median, + + // id,name,image, str.append(Integer.toString(id)).append(","); str.append(metaData.getName()).append(","); - if(details != null) { - str.append(details.designer).append(","); - str.append(details.publisher).append(","); - str.append(details.artist).append(","); - str.append(details.yearpublished).append(","); - str.append(details.minplayers).append(","); - str.append(details.maxplayers).append(","); - str.append(details.playingtime).append(","); - str.append(details.minplaytime).append(","); - str.append(details.maxplaytime).append(","); - str.append(details.age).append(","); - str.append(details.usersrated).append(","); - str.append(details.average).append(","); - str.append(floatToResult(details.bayesaverage)).append(","); - str.append(details.rank).append(","); - str.append(details.rank_wg).append(","); - str.append(details.numcomments).append(","); - str.append(details.numweights).append(","); - str.append(floatToResult(details.averageweight)).append(","); - str.append(floatToResult(details.stddev)).append(","); - str.append(floatToResult(details.median)).append(","); - } else { - for(int i = 0; i < 20; ++i) { - str.append(emptyItem); - } - } - - // owned,trading,wanting,wishing,userrating, - if(userData != null) { - str.append(userData.getOwn()?"1":"0").append(","); - str.append(userData.getFortrade()?"1":"0").append(","); - str.append(userData.getWant()?"1":"0").append(","); - str.append(userData.getWishlist()?"1":"0").append(","); - str.append(floatToResult(userData.getRating())).append(","); - } - - // image,category,mechanic,comment, str.append(getImagePath()).append(","); - if(details != null) { - str.append(details.category).append(","); - str.append(details.mechanic).append(","); - } else str.append(emptyItem).append(emptyItem); - if(userData != null) { - str.append(userData.getComment()).append(","); - } else str.append(emptyItem); - // 1player,2player,3player,4player,5player,6player,7player,8player,9player,10player, - // 11player,12player,13player,14player,15player,16player,17player,18player,19player,20player, - if(details != null) { - for(Recommendation r : details.players) { - str.append(r.name()).append(","); - } - } else { - for(int i = 0; i < 20; ++i) { - str.append("N,"); - } - } - // description,exp,basegame,reimplement,reimplement_name,reimplemented,reimplemented_name, - // contains,contains_name,iscontained,iscontained_name,integration,integration_name, - if(details != null) { - str.append(details.description).append(","); - str.append(details.expansion).append(","); - str.append(details.basegameId).append(","); - str.append(details.reimplementId).append(","); - str.append(details.reimplement_name).append(","); - str.append(details.reimplementedById).append(","); - str.append(details.reimplementedByName).append(","); - str.append(details.containsId).append(","); - str.append(details.containsName).append(","); - str.append(details.iscontained).append(","); - str.append(details.iscontained_name).append(","); - str.append(details.integration).append(","); - str.append(details.integration_name).append(","); + if(userData != null) { + str.append(userData.toResultTextLine()); } else { - for(int i = 0; i < 13; ++i) { - str.append(emptyItem); - } + str.append(ThingUserData.emptyReplacerLine()); } - // numplays,price,userweight,wishpriority,expansions,domain,family,age_poll - if(userData != null) { - str.append(userData.getNumPlays()).append(","); - } else str.append(emptyItem); - if(details != null) { - str.append(details.price).append(","); - } else str.append(emptyItem); - // TODO: find out how to get userweight... - str.append(emptyItem); - if(userData != null) { - str.append(userData.getWishlistpriority()).append(","); - } else str.append(emptyItem); if(details != null) { - str.append(details.expansions).append(","); - str.append(details.domain).append(","); - str.append(details.family).append(","); - str.append(details.age_poll).append(","); + str.append(details.toResultTextLine()); } else { - str.append(emptyItem); - str.append(emptyItem); - str.append(emptyItem); - str.append(emptyItem); + str.append(ThingDetails.emptyReplacerLine()); } return str.toString(); } - private String floatToResult(Float rating) { - if(rating == null) { - return ""; - } else { - return Float.toString(rating.floatValue()); - } - } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingDetails.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingDetails.java index c4dcd82..a21804b 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingDetails.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingDetails.java @@ -1,16 +1,42 @@ package xyz.veronie.bgg.result; +import java.util.ArrayList; +import java.util.List; + +import xyz.veronie.bgg.result.internal.OutputResultHelper; + public class ThingDetails { Integer id; - String designer; - String publisher; - String artist; + String name; + String description; + String image; + String comment; + Integer yearpublished; Integer minplayers; Integer maxplayers; + + List designer; + List publisher; + List artist; + + List category; + List mechanic; + List expansion; + List domain; + List family; + + Integer playingtime; Integer minplaytime; Integer maxplaytime; + + // poll suggested_numplayers + List players; // 1 to 20 + + // poll suggested_playerage + Float age_poll; + Integer age; Integer usersrated; Integer average; @@ -22,28 +48,120 @@ public class ThingDetails { Float averageweight; Float stddev; Float median; - String image; - IdString[] category; - IdString[] mechanic; - String comment; - Recommendation[] players; // 1 to 20 - String description; - IdString[] expansion; - Integer basegameId; - Integer reimplementId; - String reimplement_name; - Integer reimplementedById; - String reimplementedByName; - Integer containsId; - String containsName; - Integer iscontained; - String iscontained_name; - Integer integration; - String integration_name; + + Integer owning; + Integer trading; + Integer wanting; + Integer wishing; + + + + // Integer basegameId; +// Integer reimplementId; +// String reimplement_name; +// Integer reimplementedById; +// String reimplementedByName; +// Integer containsId; +// String containsName; +// Integer iscontained; +// String iscontained_name; +// Integer integration; +// String integration_name; Integer numplays; Float price; Integer expansions; - String domain; - IdString[] family; - Float age_poll; + + public ThingDetails() { + players = new ArrayList(); + + designer = new ArrayList(); + publisher = new ArrayList(); + artist = new ArrayList(); + category = new ArrayList(); + mechanic = new ArrayList(); + expansion = new ArrayList(); + domain = new ArrayList(); + family = new ArrayList(); + } + + public String toResultTextLine() { + StringBuilder str = new StringBuilder(); + + // designer,publisher,artist,yearpublished,minplayers,maxplayers,playingtime,minplaytime,maxplaytime, + // age,usersrated,average,bayesaverage,rank,rank_wg,numcomments,numweights,averageweight,stddev,median, + // category,mechanic, + str.append(designer).append(","); + str.append(publisher).append(","); + str.append(artist).append(","); + str.append(yearpublished).append(","); + str.append(minplayers).append(","); + str.append(maxplayers).append(","); + str.append(playingtime).append(","); + str.append(minplaytime).append(","); + str.append(maxplaytime).append(","); + str.append(age).append(","); + str.append(usersrated).append(","); + str.append(average).append(","); + str.append(OutputResultHelper.floatToResult(bayesaverage)).append(","); + str.append(rank).append(","); + str.append(rank_wg).append(","); + str.append(numcomments).append(","); + str.append(numweights).append(","); + str.append(OutputResultHelper.floatToResult(averageweight)).append(","); + str.append(OutputResultHelper.floatToResult(stddev)).append(","); + str.append(OutputResultHelper.floatToResult(median)).append(","); + str.append(category).append(","); + str.append(mechanic).append(","); + + // owned,trading,wanting,wishing + str.append(owning).append(","); + str.append(trading).append(","); + str.append(wanting).append(","); + str.append(wishing).append(","); + + // 1player,2player,3player,4player,5player,6player,7player,8player,9player,10player, + // 11player,12player,13player,14player,15player,16player,17player,18player,19player,20player, + for(Recommendation r : players) { + str.append(r.name()).append(","); + } + + // description,exp, + str.append(description).append(","); + str.append(expansion).append(","); + + + // basegame,reimplement,reimplement_name,reimplemented,reimplemented_name, + // contains,contains_name,iscontained,iscontained_name,integration,integration_name, +// str.append(basegameId).append(","); +// str.append(reimplementId).append(","); +// str.append(reimplement_name).append(","); +// str.append(reimplementedById).append(","); +// str.append(reimplementedByName).append(","); +// str.append(containsId).append(","); +// str.append(containsName).append(","); +// str.append(iscontained).append(","); +// str.append(iscontained_name).append(","); +// str.append(integration).append(","); +// str.append(integration_name).append(","); + + // price,expansions,domain,family,age_poll + str.append(price).append(","); + str.append(expansions).append(","); + str.append(domain).append(","); + str.append(family).append(","); + str.append(age_poll); + + return str.toString(); + } + + public static String emptyReplacerLine() { + return ",,,,,,,,,,,0.0,0.0,,,0,0,0.0,0.0,0.0,\"\",\"\",,,,,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,\"\",\"\",0.0,,\"\",\"\",0.0"; + } + + public static String resultHeader() { + return "designer,publisher,artist,yearpublished,minplayers,maxplayers,playingtime,minplaytime,maxplaytime,age,usersrated,average,bayesaverage,rank,rank_wg,numcomments,numweights,averageweight,stddev,median,category,mechanic,1player,2player,3player,4player,5player,6player,7player,8player,9player,10player,11player,12player,13player,14player,15player,16player,17player,18player,19player,20player,description,exp,price,expansions,domain,family,age_poll"; + // not doing: basegame,reimplement,reimplement_name,reimplemented,reimplemented_name,contains,contains_name,iscontained,iscontained_name,integration,integration_name, + } + + } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java index c5ae7eb..30b7fdb 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java @@ -2,10 +2,13 @@ package xyz.veronie.bgg.result; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.function.Predicate; import javax.annotation.PostConstruct; +import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.e4.core.di.annotations.Creatable; @@ -15,6 +18,10 @@ import xyz.veronie.bgg.localdb.LocalDbAdapterService; @Creatable @Singleton public class ThingProvider { + + @Inject + private BggApi bggApi; + private LocalDbAdapterService localDbAdapterService; /// list of things. Each ID is expected to exist exactly once. @@ -118,5 +125,20 @@ public class ThingProvider { return localDbAdapterService.loadThingListNames(); } + public void fetchDetails() { + // prepare list of ids to retrieve + Set ids = new HashSet<>(); + for (Thing thing : things) { + if(thing.getDetails() == null) { + ids.add(thing.getId()); + } + } + + ArrayList thingsWithDetails = bggApi.getThingDetails(ids); + for (Thing thing2 : thingsWithDetails) { + System.out.println(thing2.toResultTxtLine()); + } + + } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingUserData.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingUserData.java index 5cf4e43..8b54102 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingUserData.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingUserData.java @@ -1,5 +1,7 @@ package xyz.veronie.bgg.result; +import xyz.veronie.bgg.result.internal.OutputResultHelper; + public class ThingUserData { private Integer numplays; private String comment; @@ -123,6 +125,25 @@ public class ThingUserData { this.lastmodified = lastmodified; } + public String toResultTextLine() { + StringBuilder str = new StringBuilder(); + + str.append(OutputResultHelper.floatToResult(getRating())).append(","); + str.append(getComment()).append(","); + str.append(getNumPlays()).append(","); + // TODO: find out how to get userweight... + + return str.toString(); + } + + public static String emptyReplacerLine() { + return "N/A,\"\",0,"; + } + + public static String resultHeader() { + return "userrating,comment,numplays"; + } + // public Float getWeight() { // return weight; // } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/internal/OutputResultHelper.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/internal/OutputResultHelper.java new file mode 100644 index 0000000..523efb5 --- /dev/null +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/internal/OutputResultHelper.java @@ -0,0 +1,14 @@ +package xyz.veronie.bgg.result.internal; + +public class OutputResultHelper { + + public static String floatToResult(Float rating) { + if(rating == null) { + return "N/A"; + } else { + return Float.toString(rating.floatValue()); + } + } + + +} diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/ExportResultHandler.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/ExportResultHandler.java index 935d843..2c6e0fe 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/ExportResultHandler.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/ExportResultHandler.java @@ -3,10 +3,14 @@ package xyz.veronie.bgg.ui.handlers; import org.eclipse.e4.core.di.annotations.Execute; +import xyz.veronie.bgg.result.BggApi; import xyz.veronie.bgg.result.Thing; import xyz.veronie.bgg.result.ThingProvider; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.inject.Inject; @@ -17,14 +21,17 @@ public class ExportResultHandler { @Inject ThingProvider thingProvider; + @Inject + private BggApi bggApi; + @Execute public void execute() { - List things = thingProvider.getThings(); - for (Thing thing : things) { - System.out.println(thing.toResultTxtLine()); - } + thingProvider.fetchDetails(); } + + + @CanExecute public boolean canExecute() {