User rating is now saved in local DB, and loaded when opening local save. Fetching thing details via id now loads ratings and weights from bgg. TODO: join both thing information together and output joined resultpull/21/head
@@ -15,6 +15,8 @@ | |||||
<windowImages/> | <windowImages/> | ||||
<splash | |||||
location="xyz.veronie.bgg.ui" /> | |||||
<launcher> | <launcher> | ||||
<win useIco="false"> | <win useIco="false"> | ||||
<bmp/> | <bmp/> | ||||
@@ -1,12 +1,8 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
<classpath> | <classpath> | ||||
<classpathentry exported="true" kind="lib" path="lib/"/> | <classpathentry exported="true" kind="lib" path="lib/"/> | ||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |||||
<attributes> | |||||
<attribute name="maven.pomderived" value="true"/> | |||||
</attributes> | |||||
</classpathentry> | |||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | |||||
<classpathentry kind="src" path="src"/> | <classpathentry kind="src" path="src"/> | ||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | ||||
<attributes> | <attributes> | ||||
@@ -1,27 +1,23 @@ | |||||
Manifest-Version: 1.0 | Manifest-Version: 1.0 | ||||
Bundle-ManifestVersion: 2 | Bundle-ManifestVersion: 2 | ||||
Bundle-Name: Secondtry | |||||
Bundle-Name: Bgg Tool Khaki Flavor | |||||
Bundle-SymbolicName: xyz.veronie.bgg.ui;singleton:=true | Bundle-SymbolicName: xyz.veronie.bgg.ui;singleton:=true | ||||
Bundle-Version: 1.0.0.qualifier | Bundle-Version: 1.0.0.qualifier | ||||
Bundle-ClassPath: lib/sqlite-jdbc-3.34.0.jar, | Bundle-ClassPath: lib/sqlite-jdbc-3.34.0.jar, | ||||
swing2swt.jar | swing2swt.jar | ||||
Require-Bundle: org.eclipse.core.runtime, | |||||
org.eclipse.swt, | |||||
Require-Bundle: javax.inject, | |||||
javax.annotation, | |||||
org.eclipse.core.runtime, | |||||
org.eclipse.e4.core.services, | |||||
org.eclipse.e4.core.di, | org.eclipse.e4.core.di, | ||||
org.eclipse.e4.ui.workbench, | org.eclipse.e4.ui.workbench, | ||||
org.eclipse.e4.ui.di, | org.eclipse.e4.ui.di, | ||||
org.eclipse.e4.core.di.extensions, | |||||
javax.annotation, | |||||
org.eclipse.jface, | org.eclipse.jface, | ||||
org.eclipse.e4.core.services, | |||||
org.eclipse.osgi.services, | |||||
javax.inject, | |||||
org.eclipse.e4.ui.model.workbench | |||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||||
org.eclipse.e4.ui.model.workbench, | |||||
com.ibm.icu | |||||
Bundle-RequiredExecutionEnvironment: JavaSE-11 | |||||
Import-Package: javax.annotation;version="1.0.0";resolution:=optional, | Import-Package: javax.annotation;version="1.0.0";resolution:=optional, | ||||
javax.inject;version="1.0.0", | javax.inject;version="1.0.0", | ||||
org.eclipse.e4.core.commands, | org.eclipse.e4.core.commands, | ||||
org.eclipse.e4.core.contexts;version="1.7.0", | |||||
org.eclipse.e4.ui.model.application.descriptor.basic, | |||||
org.eclipse.e4.core.contexts, | |||||
org.eclipse.e4.ui.model.application.ui.basic | org.eclipse.e4.ui.model.application.ui.basic | ||||
Automatic-Module-Name: de.wt.secondtry |
@@ -85,7 +85,7 @@ public class SqliteController { | |||||
} | } | ||||
try { | try { | ||||
Statement stmt = connection.createStatement(); | Statement stmt = connection.createStatement(); | ||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Thing (ThingId INTEGER PRIMARY KEY, Name, ImgUrl, ThumbUrl, Comment, NumPlays);"); | |||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS Thing (ThingId INTEGER PRIMARY KEY, Name, ImgUrl, ThumbUrl, Comment, NumPlays, UserRating);"); | |||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingList (ListId INTEGER PRIMARY KEY, Name);"); | stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ThingList (ListId INTEGER PRIMARY KEY, Name);"); | ||||
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));"); | ||||
@@ -207,7 +207,7 @@ public class SqliteController { | |||||
int listId = getThingListId(name); | int listId = getThingListId(name); | ||||
PreparedStatement thingStatement = connection | PreparedStatement thingStatement = connection | ||||
.prepareStatement("INSERT OR REPLACE INTO Thing VALUES (?, ?, ?, ?, ?, ?);"); | |||||
.prepareStatement("INSERT OR REPLACE INTO Thing VALUES (?, ?, ?, ?, ?, ?, ?);"); | |||||
PreparedStatement listToThingStatement = connection | PreparedStatement listToThingStatement = connection | ||||
.prepareStatement("INSERT OR IGNORE INTO ThingListToThing VALUES (?, ?);"); | .prepareStatement("INSERT OR IGNORE INTO ThingListToThing VALUES (?, ?);"); | ||||
@@ -225,9 +225,15 @@ public class SqliteController { | |||||
} else { | } else { | ||||
thingStatement.setNull(6, java.sql.Types.INTEGER); | thingStatement.setNull(6, java.sql.Types.INTEGER); | ||||
} | } | ||||
if(userData.getRating() != null) { | |||||
thingStatement.setFloat(7, userData.getRating()); | |||||
} else { | |||||
thingStatement.setNull(7, java.sql.Types.FLOAT); | |||||
} | |||||
} else { | } else { | ||||
thingStatement.setString(5, ""); | thingStatement.setString(5, ""); | ||||
thingStatement.setNull(6, java.sql.Types.INTEGER); | thingStatement.setNull(6, java.sql.Types.INTEGER); | ||||
thingStatement.setNull(7, java.sql.Types.FLOAT); | |||||
} | } | ||||
thingStatement.execute(); | thingStatement.execute(); | ||||
// get generated id | // get generated id | ||||
@@ -282,7 +288,7 @@ public class SqliteController { | |||||
stmt = connection.createStatement(); | stmt = connection.createStatement(); | ||||
String str = "SELECT t.ThingId, t.Name, ImgUrl, ThumbUrl, Comment, NumPlays from Thing t " + | |||||
String str = "SELECT t.ThingId, t.Name, ImgUrl, ThumbUrl, Comment, NumPlays, UserRating from Thing t " + | |||||
"join ThingListToThing tltt on t.ThingId = tltt.ThingId " + | "join ThingListToThing tltt on t.ThingId = tltt.ThingId " + | ||||
"join ThingList tl on tl.ListId = tltt.ListId " + | "join ThingList tl on tl.ListId = tltt.ListId " + | ||||
"where tl.Name = '" + name + "' order by t.Name asc"; | "where tl.Name = '" + name + "' order by t.Name asc"; | ||||
@@ -299,7 +305,8 @@ public class SqliteController { | |||||
res.getString(4)); | res.getString(4)); | ||||
ThingUserData userData = new ThingUserData(); | ThingUserData userData = new ThingUserData(); | ||||
userData.setComment(res.getString(5)); | userData.setComment(res.getString(5)); | ||||
userData.setNumPlays(res.getInt(6)); | |||||
userData.setNumPlays(res.getInt(6)); | |||||
userData.setRating(res.getFloat(7)); | |||||
Thing thing = new Thing(id, metaData); | Thing thing = new Thing(id, metaData); | ||||
thing.setUserData(userData); | thing.setUserData(userData); | ||||
thingList.add(thing); | thingList.add(thing); | ||||
@@ -90,6 +90,8 @@ public class BggApi { | |||||
} | } | ||||
} | } | ||||
urlStr.append("&stats=1"); | |||||
return getThings(urlStr.toString()); | return getThings(urlStr.toString()); | ||||
} | } | ||||
@@ -100,6 +102,7 @@ public class BggApi { | |||||
StringBuilder urlStr = new StringBuilder(); | StringBuilder urlStr = new StringBuilder(); | ||||
urlStr.append(BASE_URL + COLLECTION | urlStr.append(BASE_URL + COLLECTION | ||||
+ "?username=" + resultConfig.user | + "?username=" + resultConfig.user | ||||
+ "&stats=1" | |||||
+ "&subtype=" + resultConfig.subtype.toApiString() + "&"); | + "&subtype=" + resultConfig.subtype.toApiString() + "&"); | ||||
if(resultConfig.subtype == Subtype.BOARDGAME) { | if(resultConfig.subtype == Subtype.BOARDGAME) { | ||||
urlStr.append("excludesubtype=" + Subtype.BGEXPANSION.toApiString() + "&"); | urlStr.append("excludesubtype=" + Subtype.BGEXPANSION.toApiString() + "&"); | ||||
@@ -381,6 +384,29 @@ public class BggApi { | |||||
details.maxplaytime = getIntegerFromString(getValueAttribute(eElement, "maxplaytime")); | details.maxplaytime = getIntegerFromString(getValueAttribute(eElement, "maxplaytime")); | ||||
details.age = getIntegerFromString(getValueAttribute(eElement, "minage")); | details.age = getIntegerFromString(getValueAttribute(eElement, "minage")); | ||||
NodeList statsNodes = eElement.getElementsByTagName("statistics"); | |||||
if(statsNodes.getLength() > 0) { | |||||
Node statsNode = statsNodes.item(0); | |||||
if (statsNode.getNodeType() == Node.ELEMENT_NODE) { | |||||
Element statsElement = (Element) statsNode; | |||||
NodeList ratingNodes = statsElement.getElementsByTagName("ratings"); | |||||
if(ratingNodes.getLength() > 0) { | |||||
Node ratingNode = ratingNodes.item(0); | |||||
if (ratingNode.getNodeType() == Node.ELEMENT_NODE) { | |||||
Element ratingElement = (Element)ratingNode; | |||||
details.usersrated = getIntegerFromString(getValueAttribute(ratingElement, "usersrated")); | |||||
details.average = getFloatFromString(getValueAttribute(ratingElement, "average")); | |||||
details.averageweight = getFloatFromString(getValueAttribute(ratingElement, "averageweight")); | |||||
details.stddev = getFloatFromString(getValueAttribute(ratingElement, "stddev")); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// number of players recommendations | // number of players recommendations | ||||
// Only saving up to 20 players | // Only saving up to 20 players | ||||
NodeList pollList = eElement.getElementsByTagName("poll"); | NodeList pollList = eElement.getElementsByTagName("poll"); | ||||
@@ -527,19 +553,24 @@ public class BggApi { | |||||
NodeList statsNodes = eElement.getElementsByTagName("stats"); | NodeList statsNodes = eElement.getElementsByTagName("stats"); | ||||
if(statsNodes.getLength() > 0) { | if(statsNodes.getLength() > 0) { | ||||
Node statsNode = statsNodes.item(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."); | |||||
if (statsNode.getNodeType() == Node.ELEMENT_NODE) { | |||||
Element statsElement = (Element) statsNode; | |||||
NodeList ratingNodes = statsElement.getElementsByTagName("rating"); | |||||
if(ratingNodes.getLength() > 0) { | |||||
Element ratingNode = (Element)ratingNodes.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."); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -593,6 +624,13 @@ public class BggApi { | |||||
return null; | return null; | ||||
} | } | ||||
private Float getFloatFromString(String s) { | |||||
if(s != null && !s.isEmpty()) { | |||||
return Float.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); | ||||
if(node == null) { | if(node == null) { | ||||
@@ -604,7 +642,7 @@ public class BggApi { | |||||
private String getValueAttribute(Element eElement, String key) { | private String getValueAttribute(Element eElement, String key) { | ||||
Node node = (Element)eElement.getElementsByTagName(key).item(0); | Node node = (Element)eElement.getElementsByTagName(key).item(0); | ||||
if (node.getNodeType() == Node.ELEMENT_NODE) { | |||||
if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { | |||||
Element elem = (Element) node; | Element elem = (Element) node; | ||||
if(elem.hasAttribute("value")) { | if(elem.hasAttribute("value")) { | ||||
return elem.getAttribute("value"); | return elem.getAttribute("value"); | ||||
@@ -41,7 +41,7 @@ public class ThingDetails { | |||||
Integer age; | Integer age; | ||||
Integer usersrated; | Integer usersrated; | ||||
Integer average; | |||||
Float average; | |||||
Float bayesaverage; | Float bayesaverage; | ||||
Integer rank; | Integer rank; | ||||
Integer rank_wg; | Integer rank_wg; | ||||
@@ -140,6 +140,8 @@ public class ThingProvider { | |||||
System.out.println(thing.toResultTxtLine()); | System.out.println(thing.toResultTxtLine()); | ||||
} | } | ||||
// TODO: | |||||
// Now join the details with the things that already contain user data, and output THOSE. | |||||
} | } | ||||
} | } |
@@ -47,6 +47,8 @@ import org.eclipse.swt.widgets.Label; | |||||
public class FetchPart { | public class FetchPart { | ||||
private static final String BUNDLE_NAME = "xyz.veronie.bgg.ui"; | |||||
@Inject | @Inject | ||||
private ResultConfigManager configManager; | private ResultConfigManager configManager; | ||||
@@ -115,15 +117,15 @@ public class FetchPart { | |||||
btnBggUser = new Button(buttonRow, SWT.NONE); | btnBggUser = new Button(buttonRow, SWT.NONE); | ||||
btnBggUser.setToolTipText("Fetch by bgg user"); | btnBggUser.setToolTipText("Fetch by bgg user"); | ||||
btnBggUser.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Meeple_60x60.png")); | |||||
btnBggUser.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/noun_Meeple_60x60.png")); | |||||
btnFamily = new Button(buttonRow, SWT.NONE); | btnFamily = new Button(buttonRow, SWT.NONE); | ||||
btnFamily.setToolTipText("Fetch by family"); | btnFamily.setToolTipText("Fetch by family"); | ||||
btnFamily.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Family_60x60.png")); | |||||
btnFamily.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/noun_Family_60x60.png")); | |||||
btnGeeklist = new Button(buttonRow, SWT.NONE); | btnGeeklist = new Button(buttonRow, SWT.NONE); | ||||
btnGeeklist.setToolTipText("Fetch by geeklist"); | btnGeeklist.setToolTipText("Fetch by geeklist"); | ||||
btnGeeklist.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_List_60x60.png")); | |||||
btnGeeklist.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/noun_List_60x60.png")); | |||||
centerComposite = new Composite(main, SWT.NONE); | centerComposite = new Composite(main, SWT.NONE); | ||||
@@ -155,7 +157,7 @@ public class FetchPart { | |||||
lblResultAction.setText("How do you want to apply the result?"); | lblResultAction.setText("How do you want to apply the result?"); | ||||
Button btnReplace = new Button(applyComposite, SWT.NONE); | Button btnReplace = new Button(applyComposite, SWT.NONE); | ||||
btnReplace.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_replace_60x60.png")); | |||||
btnReplace.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/result_replace_60x60.png")); | |||||
btnReplace.setToolTipText("Replace"); | btnReplace.setToolTipText("Replace"); | ||||
btnReplace.addMouseListener(new MouseAdapter() { | btnReplace.addMouseListener(new MouseAdapter() { | ||||
@Override | @Override | ||||
@@ -165,7 +167,7 @@ public class FetchPart { | |||||
}); | }); | ||||
Button btnOnlyNew = new Button(applyComposite, SWT.NONE); | Button btnOnlyNew = new Button(applyComposite, SWT.NONE); | ||||
btnOnlyNew.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/only_new_60x60.png")); | |||||
btnOnlyNew.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/only_new_60x60.png")); | |||||
btnOnlyNew.setToolTipText("Keep only new"); | btnOnlyNew.setToolTipText("Keep only new"); | ||||
btnOnlyNew.addMouseListener(new MouseAdapter() { | btnOnlyNew.addMouseListener(new MouseAdapter() { | ||||
@Override | @Override | ||||
@@ -175,7 +177,7 @@ public class FetchPart { | |||||
}); | }); | ||||
Button btnAdd = new Button(applyComposite, SWT.NONE); | Button btnAdd = new Button(applyComposite, SWT.NONE); | ||||
btnAdd.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_add_60x60.png")); | |||||
btnAdd.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/result_add_60x60.png")); | |||||
btnAdd.setToolTipText("Add"); | btnAdd.setToolTipText("Add"); | ||||
btnAdd.addMouseListener(new MouseAdapter() { | btnAdd.addMouseListener(new MouseAdapter() { | ||||
@Override | @Override | ||||
@@ -185,7 +187,7 @@ public class FetchPart { | |||||
}); | }); | ||||
Button btnIntersect = new Button(applyComposite, SWT.NONE); | Button btnIntersect = new Button(applyComposite, SWT.NONE); | ||||
btnIntersect.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_intersect_60x60.png")); | |||||
btnIntersect.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/result_intersect_60x60.png")); | |||||
btnIntersect.setToolTipText("Intersect"); | btnIntersect.setToolTipText("Intersect"); | ||||
btnIntersect.addMouseListener(new MouseAdapter() { | btnIntersect.addMouseListener(new MouseAdapter() { | ||||
@Override | @Override | ||||
@@ -195,7 +197,7 @@ public class FetchPart { | |||||
}); | }); | ||||
Button btnSubtract = new Button(applyComposite, SWT.NONE); | Button btnSubtract = new Button(applyComposite, SWT.NONE); | ||||
btnSubtract.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_subtract_60x60.png")); | |||||
btnSubtract.setImage(ResourceManager.getPluginImage(BUNDLE_NAME, "icons/result_subtract_60x60.png")); | |||||
btnSubtract.setToolTipText("Subtract"); | btnSubtract.setToolTipText("Subtract"); | ||||
btnSubtract.addMouseListener(new MouseAdapter() { | btnSubtract.addMouseListener(new MouseAdapter() { | ||||
@Override | @Override | ||||