Added searching for all relevant data types

This commit is contained in:
Gnarwhal 2021-02-18 17:21:23 -05:00
parent 4df0a804b3
commit a8cf583569
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174
39 changed files with 1159 additions and 233 deletions

View file

@ -60,7 +60,10 @@ public class SteamAPI extends PlatformAPI {
var newGame = new APIResponse.Game();
newGame.setPlatformGameId(Integer.toString(game.getAppid()));
newGame.setName(game.getName());
newGame.setThumbnail("https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/" + game.getAppid() + "/" + game.getImg_logo_url() + ".jpg");
// Technically this is not the advertised logo url, but it's used be steamcommunity.com
// and steamdb.info and it gives better aspect ratios and it means I don't need the random
// logo_url field
newGame.setThumbnail("https://cdn.cloudflare.steamstatic.com/steam/apps/" + game.getAppid() + "/header.jpg");
newGame.setPlayed(game.getPlaytime_forever() > 0);
var achievements = new HashMap<String, APIResponse.Game.Achievement>();
@ -72,7 +75,6 @@ public class SteamAPI extends PlatformAPI {
.queryParam("appid", game.getAppid())
.toUriString();
var schemaResponse = rest.exchange(gameSchemaUrl, HttpMethod.GET, entity, GetSchemaForGameBody.class).getBody().getGame().getAvailableGameStats();
if (schemaResponse != null && schemaResponse.getAchievements() != null) {
for (var schema : schemaResponse.getAchievements()) {

View file

@ -1,6 +1,8 @@
package achievements.controllers;
import achievements.data.query.SearchAchievements;
import achievements.data.request.SearchAchievements;
import achievements.data.request.SearchGames;
import achievements.data.request.SearchUsers;
import achievements.services.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
@ -23,4 +25,24 @@ public class SearchController {
return ResponseEntity.badRequest().body("[]");
}
}
@PostMapping(value = "/users", consumes = "application/json", produces = "application/json")
public ResponseEntity searchAchievements(@RequestBody SearchUsers searchUsers) {
var users = searchService.searchUsers(searchUsers);
if (users != null) {
return ResponseEntity.ok(users);
} else {
return ResponseEntity.badRequest().body("[]");
}
}
@PostMapping(value = "/games", consumes = "application/json", produces = "application/json")
public ResponseEntity searchAchievements(@RequestBody SearchGames searchGames) {
var users = searchService.searchGames(searchGames);
if (users != null) {
return ResponseEntity.ok(users);
} else {
return ResponseEntity.badRequest().body("[]");
}
}
}

View file

@ -2,9 +2,9 @@ package achievements.controllers;
import achievements.data.APError;
import achievements.data.APPostRequest;
import achievements.data.query.AddPlatform;
import achievements.data.query.RemovePlatform;
import achievements.data.query.SetUsername;
import achievements.data.request.AddPlatform;
import achievements.data.request.RemovePlatform;
import achievements.data.request.SetUsername;
import achievements.services.ImageService;
import achievements.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;

View file

@ -1,31 +0,0 @@
package achievements.data;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class Game {
@JsonProperty("ID")
private int id;
@JsonProperty("name")
private String name;
@JsonProperty("platforms")
private List<String> platforms;
@JsonProperty("achievementCount")
private int achievementCount;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<String> getPlatforms() { return platforms; }
public void setPlatforms(List<String> platforms) { this.platforms = platforms; }
public void addToPlatforms(String platform) { this.platforms.add(platform); }
}

View file

@ -1,5 +1,6 @@
package achievements.data;
import achievements.data.response.search.Achievement;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

View file

@ -1,4 +1,4 @@
package achievements.data.query;
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;

View file

@ -1,4 +1,4 @@
package achievements.data.query;
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;

View file

@ -1,4 +1,4 @@
package achievements.data.query;
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;
@ -22,6 +22,10 @@ public class SearchAchievements {
private Float minQuality;
@JsonProperty("maxQuality")
private Float maxQuality;
@JsonProperty("ordering")
private String ordering;
@JsonProperty("orderDirection")
private String orderDirection;
public String getSearchTerm() {
return searchTerm;
@ -94,4 +98,20 @@ public class SearchAchievements {
public void setMaxQuality(Float maxQuality) {
this.maxQuality = maxQuality;
}
public String getOrdering() {
return ordering;
}
public void setOrdering(String ordering) {
this.ordering = ordering;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
this.orderDirection = orderDirection;
}
}

View file

@ -0,0 +1,117 @@
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SearchGames {
@JsonProperty("searchTerm")
private String searchTerm;
@JsonProperty("userId")
private Integer userId;
@JsonProperty("owned")
private boolean owned;
@JsonProperty("minAvgCompletion")
private Float minAvgCompletion;
@JsonProperty("maxAvgCompletion")
private Float maxAvgCompletion;
@JsonProperty("minNumOwners")
private Float minNumOwners;
@JsonProperty("maxNumOwners")
private Float maxNumOwners;
@JsonProperty("minNumPerfects")
private Float minNumPerfects;
@JsonProperty("maxNumPerfects")
private Float maxNumPerfects;
@JsonProperty("ordering")
private String ordering;
@JsonProperty("orderDirection")
private String orderDirection;
public String getSearchTerm() {
return searchTerm;
}
public void setSearchTerm(String searchTerm) {
this.searchTerm = searchTerm;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public boolean isOwned() {
return owned;
}
public void setOwned(boolean owned) {
this.owned = owned;
}
public Float getMinAvgCompletion() {
return minAvgCompletion;
}
public void setMinAvgCompletion(Float minAvgCompletion) {
this.minAvgCompletion = minAvgCompletion;
}
public Float getMaxAvgCompletion() {
return maxAvgCompletion;
}
public void setMaxAvgCompletion(Float maxAvgCompletion) {
this.maxAvgCompletion = maxAvgCompletion;
}
public Float getMinNumOwners() {
return minNumOwners;
}
public void setMinNumOwners(Float minNumOwners) {
this.minNumOwners = minNumOwners;
}
public Float getMaxNumOwners() {
return maxNumOwners;
}
public void setMaxNumOwners(Float maxNumOwners) {
this.maxNumOwners = maxNumOwners;
}
public Float getMinNumPerfects() {
return minNumPerfects;
}
public void setMinNumPerfects(Float minNumPerfects) {
this.minNumPerfects = minNumPerfects;
}
public Float getMaxNumPerfects() {
return maxNumPerfects;
}
public void setMaxNumPerfects(Float maxNumPerfects) {
this.maxNumPerfects = maxNumPerfects;
}
public String getOrdering() {
return ordering;
}
public void setOrdering(String ordering) {
this.ordering = ordering;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
this.orderDirection = orderDirection;
}
}

View file

@ -0,0 +1,97 @@
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SearchUsers {
@JsonProperty("searchTerm")
private String searchTerm;
@JsonProperty("minOwned")
private Float minOwned;
@JsonProperty("maxOwned")
private Float maxOwned;
@JsonProperty("minCompleted")
private Float minCompleted;
@JsonProperty("maxCompleted")
private Float maxCompleted;
@JsonProperty("minAvgCompletion")
private Float minAvgCompletion;
@JsonProperty("maxAvgCompletion")
private Float maxAvgCompletion;
@JsonProperty("ordering")
private String ordering;
@JsonProperty("orderDirection")
private String orderDirection;
public String getSearchTerm() {
return searchTerm;
}
public void setSearchTerm(String searchTerm) {
this.searchTerm = searchTerm;
}
public Float getMinOwned() {
return minOwned;
}
public void setMinOwned(Float minOwned) {
this.minOwned = minOwned;
}
public Float getMaxOwned() {
return maxOwned;
}
public void setMaxOwned(Float maxOwned) {
this.maxOwned = maxOwned;
}
public Float getMinCompleted() {
return minCompleted;
}
public void setMinCompleted(Float minCompleted) {
this.minCompleted = minCompleted;
}
public Float getMaxCompleted() {
return maxCompleted;
}
public void setMaxCompleted(Float maxCompleted) {
this.maxCompleted = maxCompleted;
}
public Float getMinAvgCompletion() {
return minAvgCompletion;
}
public void setMinAvgCompletion(Float minAvgCompletion) {
this.minAvgCompletion = minAvgCompletion;
}
public Float getMaxAvgCompletion() {
return maxAvgCompletion;
}
public void setMaxAvgCompletion(Float maxAvgCompletion) {
this.maxAvgCompletion = maxAvgCompletion;
}
public String getOrdering() {
return ordering;
}
public void setOrdering(String ordering) {
this.ordering = ordering;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
this.orderDirection = orderDirection;
}
}

View file

@ -1,4 +1,4 @@
package achievements.data.query;
package achievements.data.request;
import com.fasterxml.jackson.annotation.JsonProperty;

View file

@ -1,4 +1,4 @@
package achievements.data;
package achievements.data.response.search;
import com.fasterxml.jackson.annotation.JsonProperty;

View file

@ -0,0 +1,59 @@
package achievements.data.response.search;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Game {
@JsonProperty("ID")
private int ID;
@JsonProperty("name")
private String name;
@JsonProperty("achievement_count")
private int achievement_count;
@JsonProperty("avg_completion")
private Integer avg_completion;
@JsonProperty("num_owners")
private int num_owners;
@JsonProperty("num_perfects")
private int num_perfects;
public int getID() { return ID; }
public void setID(int ID) { this.ID = ID; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAchievement_count() {
return achievement_count;
}
public void setAchievement_count(int achievement_count) {
this.achievement_count = achievement_count;
}
public Integer getAvg_completion() {
return avg_completion;
}
public void setAvg_completion(Integer avg_completion) {
this.avg_completion = avg_completion;
}
public int getNum_owners() {
return num_owners;
}
public void setNum_owners(int num_owners) {
this.num_owners = num_owners;
}
public int getNum_perfects() {
return num_perfects;
}
public void setNum_perfects(int num_perfects) {
this.num_perfects = num_perfects;
}
}

View file

@ -0,0 +1,67 @@
package achievements.data.response.search;
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
@JsonProperty("ID")
private int ID;
@JsonProperty("username")
private String username;
@JsonProperty("game_count")
private int game_count;
@JsonProperty("achievement_count")
private int achievement_count;
@JsonProperty("avg_completion")
private Integer avg_completion;
@JsonProperty("perfect_games")
private int perfect_games;
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getGame_count() {
return game_count;
}
public void setGame_count(int game_count) {
this.game_count = game_count;
}
public int getAchievement_count() {
return achievement_count;
}
public void setAchievement_count(int achievement_count) {
this.achievement_count = achievement_count;
}
public Integer getAvg_completion() {
return avg_completion;
}
public void setAvg_completion(Integer avg_completion) {
this.avg_completion = avg_completion;
}
public int getPerfect_games() {
return perfect_games;
}
public void setPerfect_games(int perfect_games) {
this.perfect_games = perfect_games;
}
}

View file

@ -11,6 +11,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.Types;
import java.util.HashSet;
@Service
public class APIService {
@ -37,10 +38,10 @@ public class APIService {
try {
var response = apis.apis.get(platformId).get(platformUserId);
var addIfNotGame = db.prepareCall("{call AddIfNotGame(?, ?, ?)}");
var addGameToPlatform = db.prepareCall("{call AddGameToPlatform(?, ?, ?)}");
var addGameToUser = db.prepareCall("{call AddGameToPlatform(?, ?, ?)}");
var addIfNotAchievement = db.prepareCall("{call AddIfNotAchievement(?, ?, ?, ?, ?, ?)}");
var addIfNotGame = db.prepareCall("{call AddIfNotGame(?, ?, ?)}");
var addGameToPlatform = db.prepareCall("{call AddGameToPlatform(?, ?, ?)}");
var addGameToUser = db.prepareCall("{call AddGameToUser(?, ?, ?)}");
var addIfNotAchievement = db.prepareCall("{call AddIfNotAchievement(?, ?, ?, ?, ?, ?)}");
var setAchievementProgressForUser = db.prepareCall("{call SetAchievementProgressForUser(?, ?, ?, ?)}");
addIfNotGame.registerOutParameter(3, Types.INTEGER);
@ -70,6 +71,7 @@ public class APIService {
addGameToUser.setInt(3, platformId);
addGameToUser.execute();
var set = new HashSet<Integer>();
for (var achievement : game.getAchievements()) {
addIfNotAchievement.setInt(1, gameId);
addIfNotAchievement.setString(2, achievement.getName());
@ -78,6 +80,7 @@ public class APIService {
addIfNotAchievement.setString(5, getFileType(achievement.getThumbnail()));
addIfNotAchievement.execute();
var achievementId = addIfNotAchievement.getInt(6);
set.add(achievementId);
var achievementIcon = new File("storage/images/achievement/" + achievementId + "." + getFileType(achievement.getThumbnail()));
if (!achievementIcon.exists()) {

View file

@ -24,7 +24,7 @@ public class GameService {
public String[] getIcon(int gameId) {
try {
var stmt = db.prepareCall("{call GetAchievementIcon(?)}");
var stmt = db.prepareCall("{call GetGameIcon(?)}");
return imageService.getImageType(stmt, gameId);
} catch (Exception e) {
e.printStackTrace();

View file

@ -1,7 +1,11 @@
package achievements.services;
import achievements.data.Achievement;
import achievements.data.query.SearchAchievements;
import achievements.data.request.SearchGames;
import achievements.data.request.SearchUsers;
import achievements.data.response.search.Achievement;
import achievements.data.request.SearchAchievements;
import achievements.data.response.search.Game;
import achievements.data.response.search.User;
import achievements.misc.DbConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -9,8 +13,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
@Service
public class SearchService {
@ -26,16 +29,18 @@ public class SearchService {
public List<Achievement> searchAchievements(SearchAchievements query) {
try {
var stmt = db.prepareCall("{call SearchAchievements(?, ?, ?, ?, ?, ?, ?, ?, ?)}");
var stmt = db.prepareCall("{call SearchAchievements(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}");
stmt.setString(1, query.getSearchTerm());
stmt.setBoolean(3, query.isCompleted());
if (query.getUserId() != null) { stmt.setInt( 2, query.getUserId() ); } else { stmt.setString(2, null); }
if (query.getUserId() != null) { stmt.setInt (2, query.getUserId()); } else { stmt.setString(2, null); }
if (query.getMinCompletion() != null) { stmt.setFloat(4, query.getMinCompletion()); } else { stmt.setString(4, null); }
if (query.getMaxCompletion() != null) { stmt.setFloat(5, query.getMaxCompletion()); } else { stmt.setString(5, null); }
if (query.getMinDifficulty() != null) { stmt.setFloat(6, query.getMinDifficulty()); } else { stmt.setString(6, null); }
if (query.getMaxDifficulty() != null) { stmt.setFloat(7, query.getMaxDifficulty()); } else { stmt.setString(7, null); }
if (query.getMinQuality() != null) { stmt.setFloat(8, query.getMinQuality() ); } else { stmt.setString(8, null); }
if (query.getMaxQuality() != null) { stmt.setFloat(9, query.getMaxQuality() ); } else { stmt.setString(9, null); }
if (query.getMinQuality() != null) { stmt.setFloat(8, query.getMinQuality()); } else { stmt.setString(8, null); }
if (query.getMaxQuality() != null) { stmt.setFloat(9, query.getMaxQuality()); } else { stmt.setString(9, null); }
stmt.setString(10, query.getOrdering());
stmt.setString(11, query.getOrderDirection());
var results = stmt.executeQuery();
var achievements = new ArrayList<Achievement>();
@ -56,4 +61,72 @@ public class SearchService {
}
return null;
}
public List<User> searchUsers(SearchUsers query) {
try {
var stmt = db.prepareCall("{call SearchUsers(?, ?, ?, ?, ?, ?, ?, ?, ?)}");
stmt.setString(1, query.getSearchTerm());
if (query.getMinOwned() != null) { stmt.setFloat(2, query.getMinOwned()); } else { stmt.setString(2, null); }
if (query.getMaxOwned() != null) { stmt.setFloat(3, query.getMaxOwned()); } else { stmt.setString(3, null); }
if (query.getMinCompleted() != null) { stmt.setFloat(4, query.getMinCompleted()); } else { stmt.setString(4, null); }
if (query.getMaxCompleted() != null) { stmt.setFloat(5, query.getMaxCompleted()); } else { stmt.setString(5, null); }
if (query.getMinAvgCompletion() != null) { stmt.setFloat(6, query.getMinAvgCompletion()); } else { stmt.setString(6, null); }
if (query.getMaxAvgCompletion() != null) { stmt.setFloat(7, query.getMaxAvgCompletion()); } else { stmt.setString(7, null); }
stmt.setString(8, query.getOrdering());
stmt.setString(9, query.getOrderDirection());
var results = stmt.executeQuery();
var users = new ArrayList<User>();
while (results.next()) {
var user = new User();
user.setID (results.getInt ("ID" ));
user.setUsername (results.getString("Username" ));
user.setGame_count (results.getInt ("GameCount" ));
user.setAchievement_count(results.getInt ("AchievementCount"));
user.setAvg_completion (results.getInt ("AvgCompletion" )); if (results.wasNull()) { user.setAvg_completion(null); }
user.setPerfect_games (results.getInt ("PerfectGames" ));
users.add(user);
}
return users;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<Game> searchGames(SearchGames query) {
try {
var stmt = db.prepareCall("{call SearchGames(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}");
stmt.setString(1, query.getSearchTerm());
stmt.setBoolean(3, query.isOwned());
if (query.getUserId() != null) { stmt.setInt (2, query.getUserId()); } else { stmt.setString(2, null); }
if (query.getMinAvgCompletion() != null) { stmt.setFloat(4, query.getMinAvgCompletion()); } else { stmt.setString(4, null); }
if (query.getMaxAvgCompletion() != null) { stmt.setFloat(5, query.getMaxAvgCompletion()); } else { stmt.setString(5, null); }
if (query.getMinNumOwners() != null) { stmt.setFloat(6, query.getMinNumOwners()); } else { stmt.setString(6, null); }
if (query.getMaxNumOwners() != null) { stmt.setFloat(7, query.getMaxNumOwners()); } else { stmt.setString(7, null); }
if (query.getMinNumPerfects() != null) { stmt.setFloat(8, query.getMinNumPerfects()); } else { stmt.setString(8, null); }
if (query.getMaxNumPerfects() != null) { stmt.setFloat(9, query.getMaxNumPerfects()); } else { stmt.setString(9, null); }
stmt.setString(10, query.getOrdering());
stmt.setString(11, query.getOrderDirection());
var results = stmt.executeQuery();
var games = new ArrayList<Game>();
while (results.next()) {
var game = new Game();
game.setID (results.getInt ("ID" ));
game.setName (results.getString("Name" ));
game.setAchievement_count(results.getInt ("AchievementCount"));
game.setAvg_completion (results.getInt ("AvgCompletion" )); if (results.wasNull()) { game.setAvg_completion(null); }
game.setNum_owners (results.getInt ("NumOwners" ));
game.setNum_perfects (results.getInt ("NumPerfects" ));
games.add(game);
}
return games;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -1,9 +1,9 @@
package achievements.services;
import achievements.data.Profile;
import achievements.data.query.AddPlatform;
import achievements.data.query.RemovePlatform;
import achievements.data.query.SetUsername;
import achievements.data.request.AddPlatform;
import achievements.data.request.RemovePlatform;
import achievements.data.request.SetUsername;
import achievements.misc.DbConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -210,4 +210,6 @@ public class UserService {
}
return -1;
}
}

View file

@ -4,3 +4,5 @@ spring.jackson.default-property-inclusion=always
server.session.cookie.secure = false
spring.servlet.multipart.max-file-size = 10MB
spring.servlet.multipart.max-request-size = 10MB