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/> | |||
<splash | |||
location="xyz.veronie.bgg.ui" /> | |||
<launcher> | |||
<win useIco="false"> | |||
<bmp/> | |||
@@ -1,12 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<classpath> | |||
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | |||
<classpathentry kind="src" path="src"/> | |||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |||
<attributes> | |||
@@ -1,27 +1,23 @@ | |||
Manifest-Version: 1.0 | |||
Bundle-ManifestVersion: 2 | |||
Bundle-Name: Secondtry | |||
Bundle-Name: Bgg Tool Khaki Flavor | |||
Bundle-SymbolicName: xyz.veronie.bgg.ui;singleton:=true | |||
Bundle-Version: 1.0.0.qualifier | |||
Bundle-ClassPath: lib/sqlite-jdbc-3.34.0.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.ui.workbench, | |||
org.eclipse.e4.ui.di, | |||
org.eclipse.e4.core.di.extensions, | |||
javax.annotation, | |||
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, | |||
javax.inject;version="1.0.0", | |||
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 | |||
Automatic-Module-Name: de.wt.secondtry |
@@ -85,7 +85,7 @@ public class SqliteController { | |||
} | |||
try { | |||
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 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));"); | |||
@@ -207,7 +207,7 @@ public class SqliteController { | |||
int listId = getThingListId(name); | |||
PreparedStatement thingStatement = connection | |||
.prepareStatement("INSERT OR REPLACE INTO Thing VALUES (?, ?, ?, ?, ?, ?);"); | |||
.prepareStatement("INSERT OR REPLACE INTO Thing VALUES (?, ?, ?, ?, ?, ?, ?);"); | |||
PreparedStatement listToThingStatement = connection | |||
.prepareStatement("INSERT OR IGNORE INTO ThingListToThing VALUES (?, ?);"); | |||
@@ -225,9 +225,15 @@ public class SqliteController { | |||
} else { | |||
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 { | |||
thingStatement.setString(5, ""); | |||
thingStatement.setNull(6, java.sql.Types.INTEGER); | |||
thingStatement.setNull(7, java.sql.Types.FLOAT); | |||
} | |||
thingStatement.execute(); | |||
// get generated id | |||
@@ -282,7 +288,7 @@ public class SqliteController { | |||
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 ThingList tl on tl.ListId = tltt.ListId " + | |||
"where tl.Name = '" + name + "' order by t.Name asc"; | |||
@@ -299,7 +305,8 @@ public class SqliteController { | |||
res.getString(4)); | |||
ThingUserData userData = new ThingUserData(); | |||
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.setUserData(userData); | |||
thingList.add(thing); | |||
@@ -90,6 +90,8 @@ public class BggApi { | |||
} | |||
} | |||
urlStr.append("&stats=1"); | |||
return getThings(urlStr.toString()); | |||
} | |||
@@ -100,6 +102,7 @@ public class BggApi { | |||
StringBuilder urlStr = new StringBuilder(); | |||
urlStr.append(BASE_URL + COLLECTION | |||
+ "?username=" + resultConfig.user | |||
+ "&stats=1" | |||
+ "&subtype=" + resultConfig.subtype.toApiString() + "&"); | |||
if(resultConfig.subtype == Subtype.BOARDGAME) { | |||
urlStr.append("excludesubtype=" + Subtype.BGEXPANSION.toApiString() + "&"); | |||
@@ -381,6 +384,29 @@ public class BggApi { | |||
details.maxplaytime = getIntegerFromString(getValueAttribute(eElement, "maxplaytime")); | |||
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 | |||
// Only saving up to 20 players | |||
NodeList pollList = eElement.getElementsByTagName("poll"); | |||
@@ -527,19 +553,24 @@ public class BggApi { | |||
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."); | |||
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; | |||
} | |||
private Float getFloatFromString(String s) { | |||
if(s != null && !s.isEmpty()) { | |||
return Float.valueOf(s); | |||
} | |||
return null; | |||
} | |||
private String getValue(Element eElement, String key) { | |||
Node node = eElement.getElementsByTagName(key).item(0); | |||
if(node == null) { | |||
@@ -604,7 +642,7 @@ public class BggApi { | |||
private String getValueAttribute(Element eElement, String key) { | |||
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; | |||
if(elem.hasAttribute("value")) { | |||
return elem.getAttribute("value"); | |||
@@ -41,7 +41,7 @@ public class ThingDetails { | |||
Integer age; | |||
Integer usersrated; | |||
Integer average; | |||
Float average; | |||
Float bayesaverage; | |||
Integer rank; | |||
Integer rank_wg; | |||
@@ -140,6 +140,8 @@ public class ThingProvider { | |||
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 { | |||
private static final String BUNDLE_NAME = "xyz.veronie.bgg.ui"; | |||
@Inject | |||
private ResultConfigManager configManager; | |||
@@ -115,15 +117,15 @@ public class FetchPart { | |||
btnBggUser = new Button(buttonRow, SWT.NONE); | |||
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.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.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); | |||
@@ -155,7 +157,7 @@ public class FetchPart { | |||
lblResultAction.setText("How do you want to apply the result?"); | |||
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.addMouseListener(new MouseAdapter() { | |||
@Override | |||
@@ -165,7 +167,7 @@ public class FetchPart { | |||
}); | |||
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.addMouseListener(new MouseAdapter() { | |||
@Override | |||
@@ -175,7 +177,7 @@ public class FetchPart { | |||
}); | |||
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.addMouseListener(new MouseAdapter() { | |||
@Override | |||
@@ -185,7 +187,7 @@ public class FetchPart { | |||
}); | |||
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.addMouseListener(new MouseAdapter() { | |||
@Override | |||
@@ -195,7 +197,7 @@ public class FetchPart { | |||
}); | |||
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.addMouseListener(new MouseAdapter() { | |||
@Override | |||