@@ -24,12 +24,14 @@ | |||||
<handlers xmi:id="_a0tuEGAUEeuNUoCJDLJTzQ" elementId="xyz.veronie.bgg.ui.handler.save" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.SaveGamelistHandler" command="_lA5t8F9TEeuvNqpgCDWpdQ"/> | <handlers xmi:id="_a0tuEGAUEeuNUoCJDLJTzQ" elementId="xyz.veronie.bgg.ui.handler.save" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.SaveGamelistHandler" command="_lA5t8F9TEeuvNqpgCDWpdQ"/> | ||||
<handlers xmi:id="_xJXjUG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.handler.load" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.LoadGamelistHandler" command="_qyrHAG3zEeuCP7xCflu8WA"/> | <handlers xmi:id="_xJXjUG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.handler.load" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.LoadGamelistHandler" command="_qyrHAG3zEeuCP7xCflu8WA"/> | ||||
<handlers xmi:id="_y97SUG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.handler.importResultTxt" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.ImportResultTxtHandler" command="_rkauIG7REeutwMlAyj2x8w"/> | <handlers xmi:id="_y97SUG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.handler.importResultTxt" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.ImportResultTxtHandler" command="_rkauIG7REeutwMlAyj2x8w"/> | ||||
<handlers xmi:id="_I0EUoHOzEeuMU7Jt9moleA" elementId="xyz.veronie.bgg.ui.handler.export" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.ExportResultHandler" command="_OUnzIHOzEeuMU7Jt9moleA"/> | |||||
<menuContributions xmi:id="_AitwEHBeEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.menucontribution.gamelists" accessibilityPhrase="Game Lists" positionInParent="0"> | <menuContributions xmi:id="_AitwEHBeEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.menucontribution.gamelists" accessibilityPhrase="Game Lists" positionInParent="0"> | ||||
<children xsi:type="menu:HandledMenuItem" xmi:id="_JvwHYHBeEeuk7d_98DxC5A" elementId="importResult" label="Import..." tooltip="Import thing list from bgg1tool result.txt file" command="_rkauIG7REeutwMlAyj2x8w"/> | <children xsi:type="menu:HandledMenuItem" xmi:id="_JvwHYHBeEeuk7d_98DxC5A" elementId="importResult" label="Import..." tooltip="Import thing list from bgg1tool result.txt file" command="_rkauIG7REeutwMlAyj2x8w"/> | ||||
</menuContributions> | </menuContributions> | ||||
<commands xmi:id="_lA5t8F9TEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.command.save" commandName="Save" description="save game list"/> | <commands xmi:id="_lA5t8F9TEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.command.save" commandName="Save" description="save game list"/> | ||||
<commands xmi:id="_qyrHAG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.command.load" commandName="Load" description="load game list"/> | <commands xmi:id="_qyrHAG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.command.load" commandName="Load" description="load game list"/> | ||||
<commands xmi:id="_rkauIG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.command.importResultTxt" commandName="ImportResultTxt" description="Import result.txt from bgg1tool"/> | <commands xmi:id="_rkauIG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.command.importResultTxt" commandName="ImportResultTxt" description="Import result.txt from bgg1tool"/> | ||||
<commands xmi:id="_OUnzIHOzEeuMU7Jt9moleA" elementId="xyz.veronie.bgg.ui.command.export" commandName="Export" description="export result.txt file"/> | |||||
<addons xmi:id="_Lw_ZsUqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | <addons xmi:id="_Lw_ZsUqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | ||||
<addons xmi:id="_Lw_ZskqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> | <addons xmi:id="_Lw_ZskqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> | ||||
<addons xmi:id="_Lw_Zs0qSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/> | <addons xmi:id="_Lw_Zs0qSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/> | ||||
@@ -14,6 +14,7 @@ import java.util.List; | |||||
import xyz.veronie.bgg.result.Thing; | import xyz.veronie.bgg.result.Thing; | ||||
import xyz.veronie.bgg.result.ThingMetaData; | import xyz.veronie.bgg.result.ThingMetaData; | ||||
import xyz.veronie.bgg.result.ThingUserData; | |||||
import xyz.veronie.bgg.ui.helpers.Resources; | import xyz.veronie.bgg.ui.helpers.Resources; | ||||
public class SqliteController { | public class SqliteController { | ||||
@@ -89,6 +90,41 @@ public class SqliteController { | |||||
stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idx1 ON ThingList(Name)"); | 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 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 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(); | stmt.close(); | ||||
} catch (SQLException e) { | } catch (SQLException e) { | ||||
System.err.println("Couldn't create Schema"); | System.err.println("Couldn't create Schema"); | ||||
@@ -181,10 +217,16 @@ public class SqliteController { | |||||
thingStatement.setString(2, metaData.getName()); | thingStatement.setString(2, metaData.getName()); | ||||
thingStatement.setString(3, metaData.getImgURL()); | thingStatement.setString(3, metaData.getImgURL()); | ||||
thingStatement.setString(4, metaData.getThumbURL()); | thingStatement.setString(4, metaData.getThumbURL()); | ||||
thingStatement.setString(5, metaData.getComment()); | |||||
if(metaData.getNumPlays() != null) { | |||||
thingStatement.setInt(6, metaData.getNumPlays()); | |||||
ThingUserData userData = thing.getUserData(); | |||||
if(userData != null) { | |||||
thingStatement.setString(5, userData.getComment()); | |||||
if(userData.getNumPlays() != null) { | |||||
thingStatement.setInt(6, userData.getNumPlays()); | |||||
} else { | |||||
thingStatement.setNull(6, java.sql.Types.INTEGER); | |||||
} | |||||
} else { | } else { | ||||
thingStatement.setString(5, ""); | |||||
thingStatement.setNull(6, java.sql.Types.INTEGER); | thingStatement.setNull(6, java.sql.Types.INTEGER); | ||||
} | } | ||||
thingStatement.execute(); | thingStatement.execute(); | ||||
@@ -254,10 +296,12 @@ public class SqliteController { | |||||
ThingMetaData metaData = new ThingMetaData(id, | ThingMetaData metaData = new ThingMetaData(id, | ||||
res.getString(2), | res.getString(2), | ||||
res.getString(3), | res.getString(3), | ||||
res.getString(4), | |||||
res.getString(5), | |||||
res.getInt(6)); | |||||
res.getString(4)); | |||||
ThingUserData userData = new ThingUserData(); | |||||
userData.setComment(res.getString(5)); | |||||
userData.setNumPlays(res.getInt(6)); | |||||
Thing thing = new Thing(id, metaData); | Thing thing = new Thing(id, metaData); | ||||
thing.setUserData(userData); | |||||
thingList.add(thing); | thingList.add(thing); | ||||
} | } | ||||
@@ -78,6 +78,21 @@ public class BggApi { | |||||
return getThings(urlStr.toString()); | return getThings(urlStr.toString()); | ||||
} | } | ||||
public ArrayList<Thing> getThingDetails(Set<Integer> ids) { | |||||
StringBuilder urlStr = new StringBuilder(); | |||||
urlStr.append(BASE_URL + "thing?id="); | |||||
String sep = ""; | |||||
for (Integer integer : ids) { | |||||
urlStr.append(sep + integer.toString()); | |||||
if(sep.isEmpty()) { | |||||
sep = ","; | |||||
} | |||||
} | |||||
return getThings(urlStr.toString()); | |||||
} | |||||
public ArrayList<Thing> getThingsForUser(String user) throws IllegalArgumentException { | public ArrayList<Thing> getThingsForUser(String user) throws IllegalArgumentException { | ||||
ResultConfig resultConfig = configManager.getResultConfig(); | ResultConfig resultConfig = configManager.getResultConfig(); | ||||
@@ -171,7 +186,7 @@ public class BggApi { | |||||
// do something with the content | // do something with the content | ||||
System.out.println(content.toString()); | System.out.println(content.toString()); | ||||
ArrayList<Thing> output = parseThingMetas(content.toString()); | |||||
ArrayList<Thing> output = parseThings(content.toString()); | |||||
output.sort((thing1, thing2) -> thing1.getMetaData().getName().compareTo(thing2.getMetaData().getName())); | output.sort((thing1, thing2) -> thing1.getMetaData().getName().compareTo(thing2.getMetaData().getName())); | ||||
@@ -198,7 +213,7 @@ public class BggApi { | |||||
private ArrayList<Thing> parseThingMetas(String content) throws IllegalArgumentException { | |||||
private ArrayList<Thing> parseThings(String content) throws IllegalArgumentException { | |||||
ArrayList<Thing> things = new ArrayList<Thing>(); | ArrayList<Thing> things = new ArrayList<Thing>(); | ||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||||
@@ -224,87 +239,20 @@ public class BggApi { | |||||
if( eElement.hasAttribute("objecttype") | if( eElement.hasAttribute("objecttype") | ||||
&& eElement.getAttribute("objecttype").equals("thing")) | && 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"), | |||||
getValue(eElement, "comment"), | |||||
Integer.parseInt(getValue(eElement, "numplays")) | |||||
); | |||||
Thing thing = new Thing(id, tmd); | |||||
things.add(thing); | |||||
} | |||||
extractThingByUser(things, eElement); | |||||
} | } | ||||
// when fetching things by id, type is boardgame | // when fetching things by id, type is boardgame | ||||
else if(eElement.hasAttribute("type") && | else if(eElement.hasAttribute("type") && | ||||
eElement.getAttribute("type").equals("boardgame")) | 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"), | |||||
getValue(eElement, "comment"), | |||||
null | |||||
); | |||||
Thing thing = new Thing(id, tmd); | |||||
things.add(thing); | |||||
} | |||||
} | |||||
extractThingsById(things, nNode, eElement); | |||||
} | |||||
// family has "type" | // family has "type" | ||||
else if(eElement.hasAttribute("type") | else if(eElement.hasAttribute("type") | ||||
&& eElement.getAttribute("type").equals("boardgamefamily")) | && 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"), | |||||
"", "", "", null); | |||||
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 | // 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 | // but do not iterate over items just to make sure | ||||
@@ -315,35 +263,7 @@ public class BggApi { | |||||
} | } | ||||
// for geeklist result | // for geeklist result | ||||
else if(root.getTagName() == "geeklist") { | 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"), | |||||
"", "", "", null); | |||||
Thing thing = new Thing(id, tmd); | |||||
things.add(thing); | |||||
} | |||||
} | |||||
} | |||||
extractThingByGeeklist(things, doc); | |||||
} | } | ||||
return things; | return things; | ||||
@@ -361,7 +281,299 @@ public class BggApi { | |||||
return null; | return null; | ||||
} | } | ||||
private void extractThingByGeeklist(ArrayList<Thing> 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<Thing> 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<Thing> 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")); | |||||
// number of players recommendations | |||||
// Only saving up to 20 players | |||||
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); | |||||
if(elem.hasAttribute("numplayers")) { | |||||
String attr = elem.getAttribute("numplayers"); | |||||
boolean numPlayersDoesMatch = false; | |||||
// numplayers can be X+ where X is the max number of players... | |||||
if(attr.endsWith("+")) { | |||||
attr = attr.substring(0, attr.length()-1); | |||||
if(Integer.valueOf(attr) <= i) { | |||||
numPlayersDoesMatch = true; | |||||
} | |||||
} else { | |||||
numPlayersDoesMatch = Integer.valueOf(attr) == i; | |||||
} | |||||
if(numPlayersDoesMatch) { | |||||
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<Thing> 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)) { | |||||
return statusNode.getAttribute(attribute).equals("0") ? false : true; | |||||
} | |||||
return null; | |||||
} | |||||
private void checkForErrors(Document doc) throws IllegalArgumentException { | private void checkForErrors(Document doc) throws IllegalArgumentException { | ||||
NodeList nList = doc.getElementsByTagName("error"); | NodeList nList = doc.getElementsByTagName("error"); | ||||
if(nList.getLength() > 0) { | if(nList.getLength() > 0) { | ||||
@@ -374,6 +586,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) { | private String getValue(Element eElement, String key) { | ||||
Node node = eElement.getElementsByTagName(key).item(0); | Node node = eElement.getElementsByTagName(key).item(0); | ||||
@@ -384,5 +602,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; | |||||
} | |||||
} | } |
@@ -0,0 +1,12 @@ | |||||
package xyz.veronie.bgg.result; | |||||
/// Holds an id and its string representation, for example for Family, Extension, Mechanic, or Category. | |||||
public class IdString { | |||||
public int id; | |||||
public String string; | |||||
public IdString(int id, String string) { | |||||
this.id = id; | |||||
this.string = string; | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
package xyz.veronie.bgg.result; | |||||
public enum Recommendation { | |||||
N, // (N)onplayable | |||||
P, // (P)layable, not recommended | |||||
R, // (R)ecommended | |||||
B // (B)est with... | |||||
} | |||||
@@ -14,16 +14,19 @@ import org.eclipse.swt.graphics.Image; | |||||
import org.eclipse.swt.graphics.ImageData; | import org.eclipse.swt.graphics.ImageData; | ||||
import org.eclipse.swt.graphics.ImageLoader; | import org.eclipse.swt.graphics.ImageLoader; | ||||
import xyz.veronie.bgg.result.internal.OutputResultHelper; | |||||
import xyz.veronie.bgg.ui.helpers.Resources; | import xyz.veronie.bgg.ui.helpers.Resources; | ||||
public class Thing { | public class Thing { | ||||
private int id; | private int id; | ||||
private ThingMetaData metaData; | private ThingMetaData metaData; | ||||
private ThingUserData userData; | |||||
private ThingDetails details; | private ThingDetails details; | ||||
// cache | // cache | ||||
private Image thumbImage; | private Image thumbImage; | ||||
private Path imagePath; | |||||
public static final String IdHeader = "ID"; | public static final String IdHeader = "ID"; | ||||
public static final String ThumbHeader = "Thumbnail"; | public static final String ThumbHeader = "Thumbnail"; | ||||
@@ -49,9 +52,19 @@ public class Thing { | |||||
public void setMetaData(ThingMetaData metaData) { | public void setMetaData(ThingMetaData metaData) { | ||||
this.metaData = metaData; | this.metaData = metaData; | ||||
} | } | ||||
public void setUserData(ThingUserData userData) { | |||||
this.userData = userData; | |||||
} | |||||
public ThingUserData getUserData() { | |||||
return userData; | |||||
} | |||||
public ThingDetails getDetails() { | public ThingDetails getDetails() { | ||||
return details; | return details; | ||||
} | } | ||||
public void setDetails(ThingDetails details) { | public void setDetails(ThingDetails details) { | ||||
this.details = details; | this.details = details; | ||||
} | } | ||||
@@ -63,14 +76,22 @@ public class Thing { | |||||
return thumbImage; | return thumbImage; | ||||
} | } | ||||
public String getImagePath() { | |||||
if(imagePath != null) | |||||
return imagePath.toString(); | |||||
else | |||||
return Paths.get(Resources.INSTANCE.getThumbsDir().toString() | |||||
+ File.separator + String.valueOf(id) + ".png").toString(); | |||||
} | |||||
private void getThumbImage(int thingId) { | private void getThumbImage(int thingId) { | ||||
Path tmpDir = Resources.INSTANCE.getTmpDir(); | Path tmpDir = Resources.INSTANCE.getTmpDir(); | ||||
if(tmpDir != null) { | if(tmpDir != null) { | ||||
Path imageFile = Paths.get(Resources.INSTANCE.getThumbsDir().toString() | |||||
imagePath = Paths.get(Resources.INSTANCE.getThumbsDir().toString() | |||||
+ File.separator + String.valueOf(thingId) + ".png"); | + File.separator + String.valueOf(thingId) + ".png"); | ||||
if(Files.exists(imageFile, LinkOption.NOFOLLOW_LINKS)) { | |||||
String filename = imageFile.toString().replace("\\","/"); | |||||
if(Files.exists(imagePath, LinkOption.NOFOLLOW_LINKS)) { | |||||
String filename = imagePath.toString().replace("\\","/"); | |||||
thumbImage = Resources.INSTANCE.getResourceManager().createImage( | thumbImage = Resources.INSTANCE.getResourceManager().createImage( | ||||
ImageDescriptor.createFromFile(null, filename)); | ImageDescriptor.createFromFile(null, filename)); | ||||
} else { | } else { | ||||
@@ -81,7 +102,7 @@ public class Thing { | |||||
ImageLoader saver = new ImageLoader(); | ImageLoader saver = new ImageLoader(); | ||||
saver.data = new ImageData[] { thumbImage.getImageData() }; | saver.data = new ImageData[] { thumbImage.getImageData() }; | ||||
saver.save(imageFile.toString(), SWT.IMAGE_PNG); | |||||
saver.save(imagePath.toString(), SWT.IMAGE_PNG); | |||||
} catch (MalformedURLException e) { | } catch (MalformedURLException e) { | ||||
System.out.println("INFO: Malformed URL for ThingId " + thingId); | System.out.println("INFO: Malformed URL for ThingId " + thingId); | ||||
} | } | ||||
@@ -130,4 +151,60 @@ 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, | |||||
* | |||||
* 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, | |||||
* 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,price, | |||||
* expansions,domain,family,age_poll | |||||
* | |||||
* @return | |||||
*/ | |||||
// TODO: rewrite: order isn't important, column names are | |||||
public String toResultTxtLine() { | |||||
StringBuilder str = new StringBuilder(); | |||||
// id,name,image, | |||||
OutputResultHelper.appendToResult(str, id); | |||||
OutputResultHelper.appendToResult(str, metaData.getName()); | |||||
OutputResultHelper.appendToResult(str, getImagePath()); | |||||
if(userData != null) { | |||||
userData.appendToResult(str); | |||||
} else { | |||||
str.append(ThingUserData.emptyReplacerLine()); | |||||
} | |||||
if(details != null) { | |||||
str.append(details.toResultTextLine()); | |||||
} else { | |||||
str.append(ThingDetails.emptyReplacerLine()); | |||||
} | |||||
return str.toString(); | |||||
} | |||||
} | } |
@@ -1,17 +1,44 @@ | |||||
package xyz.veronie.bgg.result; | package xyz.veronie.bgg.result; | ||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import xyz.veronie.bgg.result.internal.OutputResultHelper; | |||||
public class ThingDetails { | public class ThingDetails { | ||||
Integer id; | Integer id; | ||||
String name; | String name; | ||||
String designer; | |||||
String publisher; | |||||
String artist; | |||||
String description; | |||||
String image; | |||||
String comment; | |||||
Integer yearpublished; | Integer yearpublished; | ||||
Integer minplayers; | Integer minplayers; | ||||
Integer maxplayers; | Integer maxplayers; | ||||
List<IdString> designer; | |||||
List<IdString> publisher; | |||||
List<IdString> artist; | |||||
List<IdString> category; | |||||
List<IdString> mechanic; | |||||
List<IdString> expansion; | |||||
List<IdString> domain; | |||||
List<IdString> family; | |||||
Integer playingtime; | Integer playingtime; | ||||
Integer minplaytime; | Integer minplaytime; | ||||
Integer maxplaytime; | Integer maxplaytime; | ||||
// poll suggested_numplayers | |||||
// The index in the list indicates the number of players | |||||
// Recommendation indicates how well it plays based on what the majority thinks | |||||
List<Recommendation> players; | |||||
// poll suggested_playerage | |||||
Float age_poll; | |||||
Integer age; | Integer age; | ||||
Integer usersrated; | Integer usersrated; | ||||
Integer average; | Integer average; | ||||
@@ -23,35 +50,127 @@ public class ThingDetails { | |||||
Float averageweight; | Float averageweight; | ||||
Float stddev; | Float stddev; | ||||
Float median; | Float median; | ||||
Boolean owned; | |||||
Boolean trading; | |||||
Boolean wanting; | |||||
Boolean wishing; | |||||
Float userrating; | |||||
String image; | |||||
Integer category; | |||||
Integer mechanic; | |||||
String comment; | |||||
Integer[] players; // 1 to 20 | |||||
String description; | |||||
// exp, | |||||
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; | Integer numplays; | ||||
Float price; | Float price; | ||||
Float userweight; | |||||
Integer wishpriority; | |||||
Integer expansions; | Integer expansions; | ||||
String domain; | |||||
String family; | |||||
Float age_poll; | |||||
public ThingDetails() { | |||||
players = new ArrayList<Recommendation>(); | |||||
designer = new ArrayList<IdString>(); | |||||
publisher = new ArrayList<IdString>(); | |||||
artist = new ArrayList<IdString>(); | |||||
category = new ArrayList<IdString>(); | |||||
mechanic = new ArrayList<IdString>(); | |||||
expansion = new ArrayList<IdString>(); | |||||
domain = new ArrayList<IdString>(); | |||||
family = new ArrayList<IdString>(); | |||||
} | |||||
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, | |||||
OutputResultHelper.appendToResult(str, OutputResultHelper.getFirstIdListItem(designer)); | |||||
OutputResultHelper.appendToResult(str, OutputResultHelper.getFirstIdListItem(publisher)); | |||||
OutputResultHelper.appendToResult(str, OutputResultHelper.getFirstIdListItem(artist)); | |||||
OutputResultHelper.appendToResult(str, yearpublished); | |||||
OutputResultHelper.appendToResult(str, minplayers); | |||||
OutputResultHelper.appendToResult(str, maxplayers); | |||||
OutputResultHelper.appendToResult(str, playingtime); | |||||
OutputResultHelper.appendToResult(str, minplaytime); | |||||
OutputResultHelper.appendToResult(str, maxplaytime); | |||||
OutputResultHelper.appendToResult(str, age); | |||||
OutputResultHelper.appendToResult(str, usersrated); | |||||
OutputResultHelper.appendToResult(str, average); | |||||
OutputResultHelper.appendToResult(str, bayesaverage); | |||||
OutputResultHelper.appendToResult(str, rank); | |||||
OutputResultHelper.appendToResult(str, rank_wg); | |||||
OutputResultHelper.appendToResult(str, numcomments); | |||||
OutputResultHelper.appendToResult(str, numweights); | |||||
OutputResultHelper.appendToResult(str, averageweight); | |||||
OutputResultHelper.appendToResult(str, stddev); | |||||
OutputResultHelper.appendToResult(str, median); | |||||
OutputResultHelper.appendToResult(str, category); | |||||
OutputResultHelper.appendToResult(str, mechanic); | |||||
// owned,trading,wanting,wishing | |||||
OutputResultHelper.appendToResult(str, owning); | |||||
OutputResultHelper.appendToResult(str, trading); | |||||
OutputResultHelper.appendToResult(str, wanting); | |||||
OutputResultHelper.appendToResult(str, wishing); | |||||
// 1player,2player,3player,4player,5player,6player,7player,8player,9player,10player, | |||||
// 11player,12player,13player,14player,15player,16player,17player,18player,19player,20player, | |||||
for(int i = 0; i < players.size(); ++i) { | |||||
Recommendation r = players.get(i); | |||||
if(r != null) { | |||||
str.append(r.name()); | |||||
} | |||||
str.append(","); | |||||
} | |||||
// description,exp, | |||||
OutputResultHelper.appendToResult(str, description); | |||||
OutputResultHelper.appendToResult(str, expansion); | |||||
// basegame,reimplement,reimplement_name,reimplemented,reimplemented_name, | |||||
// contains,contains_name,iscontained,iscontained_name,integration,integration_name, | |||||
// TODO: | |||||
// 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(","); | |||||
// str.append("0,,\"\",,\"\",,\"\",,\"\",,\"\""); | |||||
// price,expansions,domain,family,age_poll | |||||
OutputResultHelper.appendToResult(str, price); | |||||
OutputResultHelper.appendToResult(str, expansions); | |||||
OutputResultHelper.appendToResult(str, domain); | |||||
OutputResultHelper.appendToResult(str, family); | |||||
str.append(OutputResultHelper.floatToResult(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,owned,trading,wanting,wishing,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, | |||||
} | |||||
} | } |
@@ -1,74 +0,0 @@ | |||||
package xyz.veronie.bgg.result; | |||||
import java.awt.Label; | |||||
import javax.annotation.PostConstruct; | |||||
import org.eclipse.swt.SWT; | |||||
import org.eclipse.swt.layout.GridData; | |||||
import org.eclipse.swt.layout.GridLayout; | |||||
import org.eclipse.swt.widgets.Composite; | |||||
public class ThingDetailsComposite extends Composite { | |||||
ThingDetails thingDetails; | |||||
private Label nameField; | |||||
private Label designerField; | |||||
private Label publisherField; | |||||
private Label yearField; | |||||
public ThingDetailsComposite(Composite parent, int style) { | |||||
super(parent, style); | |||||
} | |||||
@PostConstruct | |||||
public void create() { | |||||
setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |||||
GridLayout layout = new GridLayout(2, false); | |||||
setLayout(layout); | |||||
Label nameLbl = new Label("Name"); | |||||
applyLayout(nameLbl); | |||||
nameField = new Label(""); | |||||
Label designerLbl = new Label("Designer"); | |||||
applyLayout(designerLbl); | |||||
designerField = new Label(""); | |||||
Label publisherLbl = new Label("Publisher"); | |||||
applyLayout(publisherLbl); | |||||
publisherField = new Label(""); | |||||
Label yearLbl = new Label("Publisher"); | |||||
applyLayout(yearLbl); | |||||
yearField = new Label(""); | |||||
this.getParent().layout(); | |||||
} | |||||
private void applyLayout(Label label) { | |||||
label.setAlignment(SWT.RIGHT); | |||||
} | |||||
public void selectedThingChanged(Thing thing) { | |||||
System.out.println("TOPIC_THING_SELECTION: " + thing); | |||||
thingDetails = thing.getDetails(); | |||||
if(thingDetails != null) { | |||||
nameField.setText(thingDetails.name); | |||||
designerField.setText(thingDetails.designer); | |||||
publisherField.setText(thingDetails.publisher); | |||||
yearField.setText(Integer.toString(thingDetails.yearpublished)); | |||||
} else { | |||||
nameField.setText(""); | |||||
designerField.setText(""); | |||||
publisherField.setText(""); | |||||
yearField.setText(""); | |||||
} | |||||
this.getParent().layout(); | |||||
} | |||||
} |
@@ -2,7 +2,6 @@ package xyz.veronie.bgg.result; | |||||
import java.beans.PropertyChangeListener; | import java.beans.PropertyChangeListener; | ||||
import java.beans.PropertyChangeSupport; | import java.beans.PropertyChangeSupport; | ||||
//import com.google.gson.Gson; | |||||
public class ThingMetaData implements java.io.Serializable { | public class ThingMetaData implements java.io.Serializable { | ||||
private static final long serialVersionUID = -5268898737006538509L; | private static final long serialVersionUID = -5268898737006538509L; | ||||
@@ -11,21 +10,15 @@ public class ThingMetaData implements java.io.Serializable { | |||||
private String name; | private String name; | ||||
private String imgURL; | private String imgURL; | ||||
private String thumbURL; | private String thumbURL; | ||||
private String comment; | |||||
private Integer numPlays; | |||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); | private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); | ||||
public ThingMetaData(int id, String name, | public ThingMetaData(int id, String name, | ||||
String imgURL, String thumURL, | |||||
String comment, Integer numPlays) { | |||||
String imgURL, String thumURL) { | |||||
this.setId(id); | this.setId(id); | ||||
this.setName(name); | this.setName(name); | ||||
this.setImgURL(imgURL); | this.setImgURL(imgURL); | ||||
this.setThumbURL(thumURL); | this.setThumbURL(thumURL); | ||||
this.setComment(comment); | |||||
this.setNumPlays(numPlays); | |||||
} | } | ||||
@@ -78,29 +71,9 @@ public class ThingMetaData implements java.io.Serializable { | |||||
this.thumbURL = thumbURL); | this.thumbURL = thumbURL); | ||||
} | } | ||||
public Integer getNumPlays() { | |||||
return numPlays; | |||||
} | |||||
public void setNumPlays(Integer numPlays) { | |||||
this.numPlays = numPlays; | |||||
} | |||||
public String getComment() { | |||||
return comment; | |||||
} | |||||
public void setComment(String comment) { | |||||
propertyChangeSupport.firePropertyChange("comment", this.comment, | |||||
this.comment = comment); | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return String.valueOf(id); | return String.valueOf(id); | ||||
// Gson gson = new Gson(); | |||||
// return gson.toJson(this); | |||||
} | } | ||||
@@ -2,10 +2,13 @@ package xyz.veronie.bgg.result; | |||||
import java.sql.SQLException; | import java.sql.SQLException; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashSet; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Set; | |||||
import java.util.function.Predicate; | import java.util.function.Predicate; | ||||
import javax.annotation.PostConstruct; | import javax.annotation.PostConstruct; | ||||
import javax.inject.Inject; | |||||
import javax.inject.Singleton; | import javax.inject.Singleton; | ||||
import org.eclipse.e4.core.di.annotations.Creatable; | import org.eclipse.e4.core.di.annotations.Creatable; | ||||
@@ -15,6 +18,10 @@ import xyz.veronie.bgg.localdb.LocalDbAdapterService; | |||||
@Creatable | @Creatable | ||||
@Singleton | @Singleton | ||||
public class ThingProvider { | public class ThingProvider { | ||||
@Inject | |||||
private BggApi bggApi; | |||||
private LocalDbAdapterService localDbAdapterService; | private LocalDbAdapterService localDbAdapterService; | ||||
/// list of things. Each ID is expected to exist exactly once. | /// list of things. Each ID is expected to exist exactly once. | ||||
@@ -118,5 +125,21 @@ public class ThingProvider { | |||||
return localDbAdapterService.loadThingListNames(); | return localDbAdapterService.loadThingListNames(); | ||||
} | } | ||||
public void fetchDetails() { | |||||
// prepare list of ids to retrieve | |||||
Set<Integer> ids = new HashSet<>(); | |||||
for (Thing thing : things) { | |||||
if(thing.getDetails() == null) { | |||||
ids.add(thing.getId()); | |||||
} | |||||
} | |||||
System.out.println(Thing.makeResultHeader()); | |||||
ArrayList<Thing> thingsWithDetails = bggApi.getThingDetails(ids); | |||||
for (Thing thing : thingsWithDetails) { | |||||
System.out.println(thing.toResultTxtLine()); | |||||
} | |||||
} | |||||
} | } |
@@ -0,0 +1,157 @@ | |||||
package xyz.veronie.bgg.result; | |||||
import xyz.veronie.bgg.result.internal.OutputResultHelper; | |||||
public class ThingUserData { | |||||
private Integer numplays; | |||||
private String comment; | |||||
private Float rating; | |||||
private Boolean own; | |||||
private Boolean prevowned; | |||||
private Boolean fortrade; | |||||
private Boolean want; | |||||
private Boolean wanttoplay; | |||||
private Boolean wanttobuy; | |||||
private Boolean wishlist; | |||||
private Integer wishlistpriority; | |||||
private Boolean preordered; | |||||
private String lastmodified; | |||||
//private Float weight; | |||||
public Integer getNumPlays() { | |||||
return numplays; | |||||
} | |||||
public void setNumPlays(Integer numPlays) { | |||||
this.numplays = numPlays; | |||||
} | |||||
public String getComment() { | |||||
return comment; | |||||
} | |||||
public void setComment(String comment) { | |||||
this.comment = comment; | |||||
} | |||||
public Float getRating() { | |||||
return rating; | |||||
} | |||||
public void setRating(Float rating) { | |||||
this.rating = rating; | |||||
} | |||||
public Boolean getOwn() { | |||||
return own; | |||||
} | |||||
public void setOwn(Boolean own) { | |||||
this.own = own; | |||||
} | |||||
public Boolean getPrevowned() { | |||||
return prevowned; | |||||
} | |||||
public void setPrevowned(Boolean prevowned) { | |||||
this.prevowned = prevowned; | |||||
} | |||||
public Boolean getFortrade() { | |||||
return fortrade; | |||||
} | |||||
public void setFortrade(Boolean fortrade) { | |||||
this.fortrade = fortrade; | |||||
} | |||||
public Boolean getWant() { | |||||
return want; | |||||
} | |||||
public void setWant(Boolean want) { | |||||
this.want = want; | |||||
} | |||||
public Boolean getWanttoplay() { | |||||
return wanttoplay; | |||||
} | |||||
public void setWanttoplay(Boolean wanttoplay) { | |||||
this.wanttoplay = wanttoplay; | |||||
} | |||||
public Boolean getWanttobuy() { | |||||
return wanttobuy; | |||||
} | |||||
public void setWanttobuy(Boolean wanttobuy) { | |||||
this.wanttobuy = wanttobuy; | |||||
} | |||||
public Boolean getWishlist() { | |||||
return wishlist; | |||||
} | |||||
public void setWishlist(Boolean wishlist) { | |||||
this.wishlist = wishlist; | |||||
} | |||||
public Integer getWishlistpriority() { | |||||
return wishlistpriority; | |||||
} | |||||
public void setWishlistpriority(Integer wishlistpriority) { | |||||
this.wishlistpriority = wishlistpriority; | |||||
} | |||||
public Boolean getPreordered() { | |||||
return preordered; | |||||
} | |||||
public void setPreordered(Boolean preordered) { | |||||
this.preordered = preordered; | |||||
} | |||||
public String getLastmodified() { | |||||
return lastmodified; | |||||
} | |||||
public void setLastmodified(String lastmodified) { | |||||
this.lastmodified = lastmodified; | |||||
} | |||||
public void appendToResult(StringBuilder str) { | |||||
OutputResultHelper.appendToResult(str, getRating()); | |||||
OutputResultHelper.appendToResult(str, getComment()); | |||||
OutputResultHelper.appendToResult(str, getNumPlays()); | |||||
// TODO: find out how to get userweight... | |||||
} | |||||
public String toString() { | |||||
StringBuilder str = new StringBuilder(); | |||||
appendToResult(str); | |||||
return str.toString(); | |||||
} | |||||
public static String emptyReplacerLine() { | |||||
return "N/A,\"\",0,"; | |||||
} | |||||
public static String resultHeader() { | |||||
return "userrating,comment,numplays,"; | |||||
} | |||||
// public Float getWeight() { | |||||
// return weight; | |||||
// } | |||||
// | |||||
// public void setWeight(Float weight) { | |||||
// this.weight = weight; | |||||
// } | |||||
} |
@@ -0,0 +1,60 @@ | |||||
package xyz.veronie.bgg.result.internal; | |||||
import java.util.List; | |||||
import xyz.veronie.bgg.result.IdString; | |||||
public class OutputResultHelper { | |||||
public static String floatToResult(Float f) { | |||||
if(f == null) { | |||||
return "N/A"; | |||||
} else { | |||||
return Float.toString(f.floatValue()); | |||||
} | |||||
} | |||||
public static String getFirstIdListItem(List<IdString> list) { | |||||
if(list != null && list.size() > 0) { | |||||
return list.get(0).string; | |||||
} | |||||
return ""; | |||||
} | |||||
public static void appendToResult(StringBuilder str, String string) { | |||||
str.append("\""); | |||||
if(string != null) { | |||||
str.append(string); | |||||
} | |||||
str.append("\","); | |||||
} | |||||
public static void appendToResult(StringBuilder str, Integer i) { | |||||
if(i != null) { | |||||
str.append(Integer.toString(i)); | |||||
} | |||||
str.append(","); | |||||
} | |||||
public static void appendToResult(StringBuilder str, Float f) { | |||||
str.append(OutputResultHelper.floatToResult(f)).append(","); | |||||
} | |||||
public static void appendToResult(StringBuilder str, List<IdString> list) { | |||||
if(list == null) { | |||||
str.append(","); | |||||
return; | |||||
} | |||||
str.append("\""); | |||||
String nanDeckSeparator = ""; | |||||
for (IdString idString : list) { | |||||
str.append(nanDeckSeparator); | |||||
nanDeckSeparator = "\\13\\"; | |||||
str.append(idString.string); | |||||
} | |||||
str.append("\","); | |||||
} | |||||
} |
@@ -106,6 +106,8 @@ public class LoadGameListDialog extends Dialog { | |||||
tableViewer.setInput(thingLists); | tableViewer.setInput(thingLists); | ||||
int selection = 0; | int selection = 0; | ||||
tableViewer.setSelection(new StructuredSelection(tableViewer.getElementAt(selection)), true); | tableViewer.setSelection(new StructuredSelection(tableViewer.getElementAt(selection)), true); | ||||
selectedName = (String)tableViewer.getStructuredSelection().getFirstElement(); | |||||
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { | tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { | ||||
@Override | @Override | ||||
@@ -87,7 +87,7 @@ public class BggUserSourceFilter { | |||||
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); | bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); | ||||
Label infoLabel = new Label(bottomComposite, SWT.LEFT); | Label infoLabel = new Label(bottomComposite, SWT.LEFT); | ||||
infoLabel.setText("Select which flags are used as filter. Filters follow 'AND' rule."); | |||||
infoLabel.setText("Select which flags are used as filter. Filters follow 'AND' rule for each game."); | |||||
GridData gdInfo = new GridData(SWT.FILL, SWT.FILL, true, false); | GridData gdInfo = new GridData(SWT.FILL, SWT.FILL, true, false); | ||||
gdInfo.horizontalSpan = 2; | gdInfo.horizontalSpan = 2; | ||||
infoLabel.setLayoutData(gdInfo); | infoLabel.setLayoutData(gdInfo); | ||||
@@ -0,0 +1,41 @@ | |||||
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; | |||||
import org.eclipse.e4.core.di.annotations.CanExecute; | |||||
public class ExportResultHandler { | |||||
@Inject | |||||
ThingProvider thingProvider; | |||||
@Inject | |||||
private BggApi bggApi; | |||||
@Execute | |||||
public void execute() { | |||||
thingProvider.fetchDetails(); | |||||
} | |||||
@CanExecute | |||||
public boolean canExecute() { | |||||
return thingProvider != null; | |||||
} | |||||
} |
@@ -148,6 +148,16 @@ public class BatMain { | |||||
btnUndo.setEnabled(false); | btnUndo.setEnabled(false); | ||||
btnExport = new Button(buttonRow, SWT.NONE); | btnExport = new Button(buttonRow, SWT.NONE); | ||||
btnExport.addMouseListener(new MouseAdapter() { | |||||
@Override | |||||
public void mouseUp(MouseEvent e) { | |||||
ParameterizedCommand cmd = | |||||
commandService.createCommand("xyz.veronie.bgg.ui.command.export", null); | |||||
if (handlerService.canExecute(cmd)){ | |||||
handlerService.executeHandler(cmd); | |||||
} | |||||
} | |||||
}); | |||||
btnExport.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/export_nandeck_60x60.png")); | btnExport.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/export_nandeck_60x60.png")); | ||||
btnExport.setToolTipText("Export for nanDeck"); | btnExport.setToolTipText("Export for nanDeck"); | ||||
btnExport.setEnabled(false); | btnExport.setEnabled(false); | ||||
@@ -222,20 +232,7 @@ public class BatMain { | |||||
TableViewerColumn colThumbnail = createTableViewerColumn(Thing.ThumbHeader, 120, 0); | TableViewerColumn colThumbnail = createTableViewerColumn(Thing.ThumbHeader, 120, 0); | ||||
// colThumbnail.setLabelProvider(new ColumnLabelProvider() { | |||||
// @Override | |||||
// public Image getImage(Object element) { | |||||
// Thing t = (Thing) element; | |||||
// Image img = t.getThumbnail(); | |||||
// return img; | |||||
// } | |||||
// | |||||
// @Override | |||||
// public String getText(Object element) { | |||||
// return ""; | |||||
// } | |||||
// | |||||
// }); | |||||
colThumbnail.setLabelProvider(new OwnerDrawLabelProvider() { | colThumbnail.setLabelProvider(new OwnerDrawLabelProvider() { | ||||
@Override | @Override | ||||
protected void measure(Event event, Object element) { | protected void measure(Event event, Object element) { | ||||
@@ -11,12 +11,9 @@ import org.eclipse.swt.layout.GridLayout; | |||||
import org.eclipse.swt.widgets.Composite; | import org.eclipse.swt.widgets.Composite; | ||||
import xyz.veronie.bgg.result.Thing; | import xyz.veronie.bgg.result.Thing; | ||||
import xyz.veronie.bgg.result.ThingDetailsComposite; | |||||
import xyz.veronie.bgg.types.EventConstants; | import xyz.veronie.bgg.types.EventConstants; | ||||
public class ThingListPart { | public class ThingListPart { | ||||
private ThingDetailsComposite thingDetailsComposite; | |||||
@PostConstruct | @PostConstruct | ||||
public void createControls(Composite parent) { | public void createControls(Composite parent) { | ||||
Composite main = new Composite(parent, SWT.FILL); | Composite main = new Composite(parent, SWT.FILL); | ||||
@@ -24,14 +21,11 @@ public class ThingListPart { | |||||
GridLayout layout = new GridLayout(2, false); | GridLayout layout = new GridLayout(2, false); | ||||
main.setLayout(layout); | main.setLayout(layout); | ||||
thingDetailsComposite = new ThingDetailsComposite(main, SWT.BORDER); | |||||
} | } | ||||
@Inject | @Inject | ||||
@Optional | @Optional | ||||
private void selectedThingChanged(@UIEventTopic(EventConstants.TOPIC_THING_SELECTION) Thing thing) { | private void selectedThingChanged(@UIEventTopic(EventConstants.TOPIC_THING_SELECTION) Thing thing) { | ||||
thingDetailsComposite.selectedThingChanged(thing); | |||||
} | } | ||||