diff --git a/configs.properties.example b/configs.properties.example
index 2934e7a..3de2f63 100644
--- a/configs.properties.example
+++ b/configs.properties.example
@@ -1,9 +1,10 @@
-# Web server config
+# Web server configs
webserver.http.port=4000
webserver.maxThreads=512
# Twitch config
twitch.user_url=https://api.twitch.tv/kraken/user
+twitch.users_url=https://api.twitch.tv/kraken/users/
twitch.client_id=cs5900eog2wajva8rnvf2jtx6gazsvd
twitch.channels_url=https://api.twitch.tv/kraken/channels/
twitch.accept_header=application/vnd.twitchtv.v5+json
diff --git a/database/5-ffs-add-check-subscription.sql b/database/5-ffs-add-check-subscription.sql
new file mode 100644
index 0000000..b0f66d9
--- /dev/null
+++ b/database/5-ffs-add-check-subscription.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `ffs`.`account_event_status`
+ADD COLUMN `subscribe_to_winner` TINYINT(1) NULL ;
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c7208ab..3266eb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,9 +2,9 @@
4.0.0
tv.zerator.ffs
api
- 0.9.2-SNAPSHOT
+ 0.9.8
- 0.6.2
+ 0.6.4
@@ -22,14 +22,39 @@
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.6.0
+
+
+ run
+ none
+
+ exec
+
+
+ java
+ ${basedir}/config
+
+ -classpath
+
+ tv.zerator.ffs.api.Main
+
+
+
+
+
+
maven-compiler-plugin
3.2
- 1.7
- 1.7
+ 1.8
+ 1.8
diff --git a/src/main/java/tv/zerator/ffs/api/dao/AccountsDao.java b/src/main/java/tv/zerator/ffs/api/dao/AccountsDao.java
index 027db37..81fcd0c 100644
--- a/src/main/java/tv/zerator/ffs/api/dao/AccountsDao.java
+++ b/src/main/java/tv/zerator/ffs/api/dao/AccountsDao.java
@@ -1,10 +1,8 @@
package tv.zerator.ffs.api.dao;
-import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
-import com.jolbox.bonecp.BoneCPDataSource;
import com.jolbox.bonecp.PreparedStatementHandle;
import alexmog.apilib.dao.DAO;
@@ -12,16 +10,10 @@
import tv.zerator.ffs.api.dao.beans.AccountBean;
@Dao(database = "general")
-public class AccountsDao extends DAO {
+public class AccountsDao extends DAO {
- public AccountsDao(BoneCPDataSource dataSource) {
- super(dataSource);
- }
-
- @Override
public int insert(AccountBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO accounts "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO accounts "
+ "(twitch_id, username, email, views, followers, broadcaster_type, url, grade, email_activation_key, logo) VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
prep.setInt(1, data.getTwitchId());
@@ -39,10 +31,8 @@ public int insert(AccountBean data) throws SQLException {
}
}
- @Override
public AccountBean update(AccountBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE accounts SET "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE accounts SET "
+ "username = ?, email = ?, views = ?, followers = ?, broadcaster_type = ?, url = ?, grade = ?, email_activation_key = ?, logo = ? "
+ "WHERE twitch_id = ?")) {
prep.setString(1, data.getUsername());
@@ -61,8 +51,7 @@ public AccountBean update(AccountBean data) throws SQLException {
}
public AccountBean getAccountFromToken(String token) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT "
+ "a.broadcaster_type, a.email, a.email_activation_key, a.followers, a.grade, a.twitch_id, a.url, a.username, a.views, a.logo "
+ "FROM accounts a LEFT JOIN auth_tokens t ON t.account_id = a.twitch_id WHERE t.token = ?")) {
prep.setString(1, token);
@@ -100,8 +89,7 @@ private AccountBean constructAccountBean(ResultSet rs) throws SQLException {
}
public AccountBean get(int twitchId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM accounts WHERE twitch_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM accounts WHERE twitch_id = ?")) {
prep.setInt(1, twitchId);
try (ResultSet rs = prep.executeQuery()) {
if (!rs.next()) return null;
@@ -111,8 +99,7 @@ public AccountBean get(int twitchId) throws SQLException {
}
public AccountBean getFromValidationCode(String code) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM accounts WHERE email_activation_key = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM accounts WHERE email_activation_key = ?")) {
prep.setString(1, code);
try (ResultSet rs = prep.executeQuery()) {
if (!rs.next()) return null;
diff --git a/src/main/java/tv/zerator/ffs/api/dao/EventsDao.java b/src/main/java/tv/zerator/ffs/api/dao/EventsDao.java
index a003aee..03c6a68 100644
--- a/src/main/java/tv/zerator/ffs/api/dao/EventsDao.java
+++ b/src/main/java/tv/zerator/ffs/api/dao/EventsDao.java
@@ -1,13 +1,11 @@
package tv.zerator.ffs.api.dao;
-import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
-import com.jolbox.bonecp.BoneCPDataSource;
import com.jolbox.bonecp.PreparedStatementHandle;
import alexmog.apilib.dao.DAO;
@@ -18,16 +16,10 @@
import tv.zerator.ffs.api.dao.beans.EventBean;
@Dao(database = "general")
-public class EventsDao extends DAO {
+public class EventsDao extends DAO {
- public EventsDao(BoneCPDataSource dataSource) {
- super(dataSource);
- }
-
- @Override
public int insert(EventBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO events "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO events "
+ "(name, description, status, reserved_to_affiliates, reserved_to_partners, minimum_views, minimum_followers, ranking_type) VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) {
prep.setString(1, data.getName());
@@ -62,8 +54,7 @@ private EventBean constructEvent(ResultSet rs) throws SQLException {
}
public List getEvents(EventBean.Status status, int start, int end) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM events WHERE status = ? ORDER BY id DESC LIMIT ?, ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM events WHERE status = ? ORDER BY id DESC LIMIT ?, ?")) {
prep.setString(1, status.name());
prep.setInt(2, start);
prep.setInt(3, end);
@@ -76,8 +67,7 @@ public List getEvents(EventBean.Status status, int start, int end) th
}
public List getEvents(int start, int end) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM events ORDER BY id DESC LIMIT ?, ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM events ORDER BY id DESC LIMIT ?, ?")) {
prep.setInt(1, start);
prep.setInt(2, end);
try (ResultSet rs = prep.executeQuery()) {
@@ -89,8 +79,7 @@ public List getEvents(int start, int end) throws SQLException {
}
public EventBean getEvent(int id) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM events WHERE id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM events WHERE id = ?")) {
prep.setInt(1, id);
try (ResultSet rs = prep.executeQuery()) {
if (!rs.next()) return null;
@@ -100,8 +89,7 @@ public EventBean getEvent(int id) throws SQLException {
}
public EventBean getCurrent() throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT * FROM events WHERE is_current = 1")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT * FROM events WHERE is_current = 1")) {
try (ResultSet rs = prep.executeQuery()) {
if (!rs.next()) return null;
return constructEvent(rs);
@@ -109,10 +97,8 @@ public EventBean getCurrent() throws SQLException {
}
}
- @Override
public EventBean update(EventBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE events SET "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE events SET "
+ "name = ?, description = ?, status = ?, reserved_to_affiliates = ?, "
+ "reserved_to_partners = ?, is_current = ?, minimum_views = ?, minimum_followers = ?, ranking_type = ? WHERE id = ?")) {
prep.setString(1, data.getName());
@@ -126,7 +112,7 @@ public EventBean update(EventBean data) throws SQLException {
prep.setString(9, data.getRankingType().name());
prep.setInt(10, data.getId());
if (data.isCurrent()) {
- try (PreparedStatementHandle prep2 = (PreparedStatementHandle) conn.prepareStatement("UPDATE events SET "
+ try (PreparedStatementHandle prep2 = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE events SET "
+ "is_current = 0 WHERE is_current = 1")) {
prep2.executeUpdate();
}
@@ -137,8 +123,7 @@ public EventBean update(EventBean data) throws SQLException {
}
public List getRounds(int eventId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT round_id FROM event_rounds WHERE event_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT round_id FROM event_rounds WHERE event_id = ?")) {
prep.setInt(1, eventId);
try (ResultSet rs = prep.executeQuery()) {
List ret = new ArrayList<>();
@@ -149,8 +134,7 @@ public List getRounds(int eventId) throws SQLException {
}
public boolean roundExists(int eventId, int roundId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT round_id FROM event_rounds WHERE event_id = ? AND round_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT round_id FROM event_rounds WHERE event_id = ? AND round_id = ?")) {
prep.setInt(1, eventId);
prep.setInt(2, roundId);
try (ResultSet rs = prep.executeQuery()) {
@@ -160,8 +144,7 @@ public boolean roundExists(int eventId, int roundId) throws SQLException {
}
public int addRound(int eventId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO event_rounds "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO event_rounds "
+ "(event_id) VALUES "
+ "(?)", Statement.RETURN_GENERATED_KEYS)) {
prep.setInt(1, eventId);
@@ -174,8 +157,7 @@ public int addRound(int eventId) throws SQLException {
}
public void deleteRound(int eventId, int roundId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("DELETE FROM event_rounds "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("DELETE FROM event_rounds "
+ "WHERE event_id = ? AND round_id = ?")) {
prep.setInt(1, eventId);
prep.setInt(2, roundId);
@@ -184,8 +166,7 @@ public void deleteRound(int eventId, int roundId) throws SQLException {
}
public void addScore(int roundId, int accountId, double score) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO round_scores "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO round_scores "
+ "(round_id, account_id, score) VALUES "
+ "(?, ?, ?)")) {
prep.setInt(1, roundId);
@@ -196,8 +177,7 @@ public void addScore(int roundId, int accountId, double score) throws SQLExcepti
}
public void updateScore(int roundId, int accountId, double score) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE round_scores SET "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE round_scores SET "
+ "score = ? WHERE round_id = ? AND account_id = ?")) {
prep.setDouble(1, score);
prep.setInt(2, roundId);
@@ -214,8 +194,7 @@ public void updateScore(int roundId, int accountId, double score) throws SQLExce
}
public List getScores(int roundId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT s.score, a.username, a.url, a.twitch_id, a.logo FROM accounts a LEFT JOIN round_scores s ON s.account_id = a.twitch_id WHERE s.round_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT s.score, a.username, a.url, a.twitch_id, a.logo FROM accounts a LEFT JOIN round_scores s ON s.account_id = a.twitch_id WHERE s.round_id = ?")) {
prep.setInt(1, roundId);
try (ResultSet rs = prep.executeQuery()) {
List ret = new ArrayList<>();
@@ -226,8 +205,7 @@ public List getScores(int roundId) throws SQLException {
}
public List getAllScores(int eventId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT s.score, s.round_id, a.username, a.url, a.twitch_id, a.logo FROM accounts a "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT s.score, s.round_id, a.username, a.url, a.twitch_id, a.logo FROM accounts a "
+ "LEFT JOIN round_scores s ON s.account_id = a.twitch_id "
+ "INNER JOIN event_rounds e ON s.round_id = e.round_id "
+ "WHERE e.event_id = ?")) {
@@ -241,8 +219,7 @@ public List getAllScores(int eventId) throws SQLException {
}
public Double getScore(int roundId, int accountId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT score FROM round_scores WHERE round_id = ? AND account_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT score FROM round_scores WHERE round_id = ? AND account_id = ?")) {
prep.setInt(1, roundId);
prep.setInt(2, accountId);
try (ResultSet rs = prep.executeQuery()) {
@@ -253,8 +230,7 @@ public Double getScore(int roundId, int accountId) throws SQLException {
}
public List getUsers(int eventId, UserStatus status) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo, s.status, s.rank "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo, s.status, s.rank "
+ " FROM accounts a LEFT JOIN account_event_status s ON s.account_id = a.twitch_id WHERE s.event_id = ? AND s.status = ?")) {
prep.setInt(1, eventId);
prep.setString(2, status.name());
@@ -273,6 +249,7 @@ public List getUsers(int eventId, UserStatus status) throws S
bean.setLogo(rs.getString("a.logo"));
bean.setStatus(UserStatus.valueOf(rs.getString("s.status")));
bean.setRank(rs.getInt("s.rank"));
+ bean.setSubscribeToWinner(rs.getBoolean("s.subscribe_to_winner"));
ret.add(bean);
}
return ret;
@@ -281,8 +258,7 @@ public List getUsers(int eventId, UserStatus status) throws S
}
public List getUsers(int eventId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo, s.status, s.rank "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo, s.status, s.rank, s.subscribe_to_winner "
+ " FROM accounts a LEFT JOIN account_event_status s ON s.account_id = a.twitch_id WHERE s.event_id = ?")) {
prep.setInt(1, eventId);
try (ResultSet rs = prep.executeQuery()) {
@@ -300,6 +276,7 @@ public List getUsers(int eventId) throws SQLException {
bean.setLogo(rs.getString("a.logo"));
bean.setStatus(UserStatus.valueOf(rs.getString("s.status")));
bean.setRank(rs.getInt("s.rank"));
+ bean.setSubscribeToWinner(rs.getBoolean("s.subscribe_to_winner"));
ret.add(bean);
}
return ret;
@@ -308,8 +285,7 @@ public List getUsers(int eventId) throws SQLException {
}
public void delete(int eventId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("DELETE FROM events WHERE id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("DELETE FROM events WHERE id = ?")) {
prep.setInt(1, eventId);
prep.executeUpdate();
}
@@ -323,8 +299,7 @@ public enum UserStatus {
}
public void registerUser(int eventId, int accountId, UserStatus status, String emailActivationKey) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO account_event_status "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO account_event_status "
+ "(account_id, event_id, status, email_activation_key) VALUES (?, ?, ?, ?)")) {
prep.setInt(1, accountId);
prep.setInt(2, eventId);
@@ -342,8 +317,7 @@ public void registerUser(int eventId, int accountId, UserStatus status, String e
}
public UserStatusBean getUser(int eventId, int accountId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT s.event_id, s.status, s.email_activation_key, a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT s.event_id, s.status, s.email_activation_key, a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, a.logo "
+ " FROM accounts a LEFT JOIN account_event_status s ON s.account_id = a.twitch_id "
+ "WHERE s.account_id = ? AND s.event_id = ?")) {
prep.setInt(1, accountId);
@@ -371,8 +345,7 @@ public UserStatusBean getUser(int eventId, int accountId) throws SQLException {
}
public void removeUser(int eventId, int accountId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("DELETE FROM account_event_status WHERE account_id = ? AND event_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("DELETE FROM account_event_status WHERE account_id = ? AND event_id = ?")) {
prep.setInt(1, accountId);
prep.setInt(2, eventId);
prep.executeUpdate();
@@ -380,8 +353,7 @@ public void removeUser(int eventId, int accountId) throws SQLException {
}
public void updateUser(int eventId, int accountId, UserStatus status) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE account_event_status SET status = ? WHERE account_id = ? AND event_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE account_event_status SET status = ? WHERE account_id = ? AND event_id = ?")) {
prep.setString(1, status.name());
prep.setInt(2, accountId);
prep.setInt(3, eventId);
@@ -390,23 +362,30 @@ public void updateUser(int eventId, int accountId, UserStatus status) throws SQL
}
public void updateUserRank(int eventId, int accountId, int rank) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE account_event_status SET rank = ? WHERE account_id = ? AND event_id = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE account_event_status SET rank = ? WHERE account_id = ? AND event_id = ?")) {
prep.setInt(1, rank);
prep.setInt(2, accountId);
prep.setInt(3, eventId);
prep.executeUpdate();
}
}
+ public void updateUserSubscriptionToWinner(int eventId, int accountId, boolean hasSubscribe) throws SQLException {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE account_event_status SET subscribe_to_winner = ? WHERE account_id = ? AND event_id = ?")) {
+ prep.setBoolean(1, hasSubscribe);
+ prep.setInt(2, accountId);
+ prep.setInt(3, eventId);
+ prep.executeUpdate();
+ }
+ }
public @Data class AccountStatusBean extends AccountBean {
public UserStatus status;
public Integer rank;
+ public boolean subscribeToWinner;
}
public AccountStatusBean getRegistered(int eventId, int accountId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, s.status, a.logo, s.rank "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, s.status, a.logo, s.rank, s.subscribe_to_winner "
+ " FROM accounts a LEFT JOIN account_event_status s ON s.account_id = a.twitch_id WHERE s.event_id = ? AND a.twitch_id = ?")) {
prep.setInt(1, eventId);
prep.setInt(2, accountId);
@@ -424,6 +403,7 @@ public AccountStatusBean getRegistered(int eventId, int accountId) throws SQLExc
bean.setLogo(rs.getString("a.logo"));
bean.status = UserStatus.valueOf(rs.getString("s.status"));
bean.rank = rs.getInt("s.rank");
+ bean.subscribeToWinner = rs.getBoolean("s.subscribe_to_winner");
return bean;
}
return null;
@@ -432,8 +412,7 @@ public AccountStatusBean getRegistered(int eventId, int accountId) throws SQLExc
}
public UserStatus getUserStatusFromEmailKey(int eventId, int accountId, String emailKey) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT status FROM account_event_status "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT status FROM account_event_status "
+ "WHERE event_id = ? AND account_id = ? AND email_activation_key = ?")) {
prep.setInt(1, eventId);
prep.setInt(2, accountId);
@@ -444,6 +423,33 @@ public UserStatus getUserStatusFromEmailKey(int eventId, int accountId, String e
}
}
}
+
+ public AccountStatusBean getUserFromRank(int eventId, int rank) throws SQLException {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT a.twitch_id, a.username, a.email, a.views, a.followers, a.broadcaster_type, a.url, a.grade, s.status, a.logo, s.rank, s.subscribe_to_winner "
+ + " FROM accounts a LEFT JOIN account_event_status s ON s.account_id = a.twitch_id WHERE s.event_id = ? AND s.rank = ?")) {
+ prep.setInt(1, eventId);
+ prep.setInt(2, rank);
+ try (ResultSet rs = prep.executeQuery()) {
+ if (rs.next()) {
+ AccountStatusBean bean = new AccountStatusBean();
+ bean.setTwitchId(rs.getInt("a.twitch_id"));
+ bean.setUsername(rs.getString("a.username"));
+ bean.setEmail(rs.getString("a.email"));
+ bean.setViews(rs.getInt("a.views"));
+ bean.setFollowers(rs.getInt("a.followers"));
+ bean.setBroadcasterType(BroadcasterType.valueOf(rs.getString("a.broadcaster_type")));
+ bean.setUrl(rs.getString("a.url"));
+ bean.setGrade(rs.getInt("a.grade"));
+ bean.setLogo(rs.getString("a.logo"));
+ bean.status = UserStatus.valueOf(rs.getString("s.status"));
+ bean.rank = rs.getInt("s.rank");
+ bean.subscribeToWinner = rs.getBoolean("s.subscribe_to_winner");
+ return bean;
+ }
+ return null;
+ }
+ }
+ }
public static @Data class AccountEventBean {
public EventBean event;
@@ -451,8 +457,7 @@ public UserStatus getUserStatusFromEmailKey(int eventId, int accountId, String e
}
public List getEventsForAccount(int accountId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT s.status, e.id, e.name, e.description, e.status, e.reserved_to_affiliates, e.reserved_to_partners, e.is_current, e.ranking_type "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT s.status, e.id, e.name, e.description, e.status, e.reserved_to_affiliates, e.reserved_to_partners, e.is_current, e.ranking_type "
+ "FROM events e LEFT JOIN account_event_status s ON s.event_id = e.id WHERE s.account_id = ?")) {
prep.setInt(1, accountId);
try (ResultSet rs = prep.executeQuery()) {
@@ -478,8 +483,7 @@ public List getEventsForAccount(int accountId) throws SQLExcep
}
public List getEventsForAccountAndStatus(int accountId, UserStatus status) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("SELECT s.status, e.name, e.description, e.status, e.reserved_to_affiliates, e.reserved_to_partners, e.is_current, e.minimum_views, e.minimum_followers, e.ranking_type "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("SELECT s.status, e.name, e.description, e.status, e.reserved_to_affiliates, e.reserved_to_partners, e.is_current, e.minimum_views, e.minimum_followers, e.ranking_type "
+ "FROM events e LEFT JOIN account_event_status s ON s.event_id = e.id WHERE s.account_id = ? AND s.status = ?")) {
prep.setInt(1, accountId);
prep.setString(2, status.name());
diff --git a/src/main/java/tv/zerator/ffs/api/dao/TokensDao.java b/src/main/java/tv/zerator/ffs/api/dao/TokensDao.java
index b8920bb..71a31f5 100644
--- a/src/main/java/tv/zerator/ffs/api/dao/TokensDao.java
+++ b/src/main/java/tv/zerator/ffs/api/dao/TokensDao.java
@@ -1,9 +1,7 @@
package tv.zerator.ffs.api.dao;
-import java.sql.Connection;
import java.sql.SQLException;
-import com.jolbox.bonecp.BoneCPDataSource;
import com.jolbox.bonecp.PreparedStatementHandle;
import alexmog.apilib.dao.DAO;
@@ -11,16 +9,10 @@
import tv.zerator.ffs.api.dao.beans.TokenBean;
@Dao(database = "general")
-public class TokensDao extends DAO {
+public class TokensDao extends DAO {
- public TokensDao(BoneCPDataSource dataSource) {
- super(dataSource);
- }
-
- @Override
public int insert(TokenBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("INSERT INTO auth_tokens "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("INSERT INTO auth_tokens "
+ "(account_id, token, last_used_timestamp) VALUES (?, ?, ?)")) {
prep.setInt(1, data.getAccountId());
prep.setString(2, data.getToken());
@@ -31,17 +23,14 @@ public int insert(TokenBean data) throws SQLException {
}
public void delete(String tokenId) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("DELETE FROM auth_tokens WHERE token = ?")) {
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("DELETE FROM auth_tokens WHERE token = ?")) {
prep.setString(1, tokenId);
prep.executeUpdate();
}
}
- @Override
public TokenBean update(TokenBean data) throws SQLException {
- try (Connection conn = mDataSource.getConnection();
- PreparedStatementHandle prep = (PreparedStatementHandle) conn.prepareStatement("UPDATE auth_tokens SET "
+ try (PreparedStatementHandle prep = (PreparedStatementHandle) getConnection().prepareStatement("UPDATE auth_tokens SET "
+ "account_id = ?, last_used_timestamp = ? WHERE token = ?")) {
prep.setInt(1, data.getAccountId());
prep.setLong(2, data.getLastUsedTimestamp());
diff --git a/src/main/java/tv/zerator/ffs/api/v1/ApiV1.java b/src/main/java/tv/zerator/ffs/api/v1/ApiV1.java
index 46b4c38..758a374 100644
--- a/src/main/java/tv/zerator/ffs/api/v1/ApiV1.java
+++ b/src/main/java/tv/zerator/ffs/api/v1/ApiV1.java
@@ -23,6 +23,7 @@
import tv.zerator.ffs.api.v1.resources.LoginResource;
import tv.zerator.ffs.api.v1.resources.MeEventsResource;
import tv.zerator.ffs.api.v1.resources.MeResource;
+import tv.zerator.ffs.api.v1.resources.EventCheckSubscriptionResource;
import tv.zerator.ffs.api.v1.verifiers.OAuthVerifier;
public class ApiV1 extends ApiBase {
@@ -66,6 +67,7 @@ protected void configureRouter(int group, Router router) {
break;
case USER:
router.attach("/event/{EVENT_ID}/register", EventRegisterResource.class);
+ router.attach("/event/{EVENT_ID}/check_subscription", EventCheckSubscriptionResource.class);
break;
case MODERATOR:
router.attach("/event/{EVENT_ID}/round/{ROUND_ID}/score/{USER_ID}", EventRoundUserScoreResource.class);
diff --git a/src/main/java/tv/zerator/ffs/api/v1/resources/EventCheckSubscriptionResource.java b/src/main/java/tv/zerator/ffs/api/v1/resources/EventCheckSubscriptionResource.java
new file mode 100644
index 0000000..19b81ba
--- /dev/null
+++ b/src/main/java/tv/zerator/ffs/api/v1/resources/EventCheckSubscriptionResource.java
@@ -0,0 +1,112 @@
+package tv.zerator.ffs.api.v1.resources;
+
+import alexmog.apilib.api.validation.ValidationErrors;
+import alexmog.apilib.exceptions.BadAuthenticationException;
+import alexmog.apilib.exceptions.BadEntityException;
+import alexmog.apilib.exceptions.ConflictException;
+import alexmog.apilib.exceptions.NotFoundException;
+import alexmog.apilib.exceptions.InternalServerError;
+import alexmog.apilib.managers.DaoManager;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.restlet.data.Status;
+import org.restlet.resource.Post;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+import tv.zerator.ffs.api.Main;
+import tv.zerator.ffs.api.dao.EventsDao;
+import tv.zerator.ffs.api.dao.beans.AccountBean;
+import tv.zerator.ffs.api.dao.beans.EventBean;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+public class EventCheckSubscriptionResource extends ServerResource {
+ @DaoManager.DaoInject
+ private static EventsDao mEvents;
+
+ private int mEventId;
+
+ private final CloseableHttpClient mHttpClient = HttpClients.createDefault();
+ private static String mTwitchUsersUrl = null, mTwitchClientId, mTwitchAccept;
+
+ public EventCheckSubscriptionResource() {
+ if (mTwitchUsersUrl != null) return;
+ mTwitchUsersUrl = Main.getInstance().getConfig().getProperty("twitch.users_url");
+ mTwitchClientId = Main.getInstance().getConfig().getProperty("twitch.client_id");
+ mTwitchAccept = Main.getInstance().getConfig().getProperty("twitch.accept_header");
+ }
+
+ @Override
+ protected void doInit() throws ResourceException {
+ mEventId = Integer.parseInt(getAttribute("EVENT_ID"));
+ }
+
+ @Post
+ public Status checkSubscription(LoginBean entity) throws SQLException {
+ EventBean event = mEvents.getEvent(mEventId);
+ if (event == null) throw new NotFoundException("EVENT_NOT_FOUND");
+
+ if (event.getStatus() != EventBean.Status.ENDED) throw new ConflictException("EVENT_NOT_ENDED");
+
+ AccountBean acc = (AccountBean) getRequest().getAttributes().get("account");
+
+ ValidationErrors err = new ValidationErrors();
+
+ if (entity == null) throw new BadEntityException("Entity not found.");
+
+ err.verifyFieldEmptyness("twitch_token", entity.twitch_token, 1);
+
+ err.checkErrors("LOGIN_ERROR");
+
+ AccountBean winnerAccount = mEvents.getUserFromRank(mEventId,1);
+
+ if (winnerAccount == null){
+ throw new ConflictException("WINNER_NOT_DEFINED");
+ }
+
+ int retCode;
+ try {
+ HttpGet httpGet = new HttpGet(new URI(mTwitchUsersUrl + acc.getTwitchId() + "/subscriptions/" + winnerAccount.getTwitchId()));
+
+ httpGet.addHeader("Accept", mTwitchAccept);
+ httpGet.addHeader("Client-ID", mTwitchClientId);
+ httpGet.addHeader("Authorization", "OAuth " + entity.twitch_token);
+
+ try (CloseableHttpResponse resp = mHttpClient.execute(httpGet, HttpClientContext.create());) {
+ retCode = resp.getStatusLine().getStatusCode();
+ }
+
+ httpGet.releaseConnection();
+
+ switch (retCode){
+ case 404:
+ throw new NotFoundException("USER_NOT_SUBSCRIBE");
+
+ case 403:
+ throw new BadAuthenticationException("TOKEN_NOT_ALLOW_TO_CHECK_SUBSCRIPTION");
+
+ case 200:
+ mEvents.updateUserSubscriptionToWinner(mEventId,acc.getTwitchId(),true);
+ return Status.SUCCESS_OK;
+
+ default:
+ throw new BadAuthenticationException("BAD_AUTHENTICATION");
+ }
+
+ } catch (URISyntaxException | IOException e) {
+ Main.LOGGER.log(Level.SEVERE, "Impossible to login", e);
+ throw new InternalServerError("TWITCH_API_ERROR");
+ }
+ }
+
+ private static class LoginBean {
+ public String twitch_token;
+ }
+}
diff --git a/src/main/java/tv/zerator/ffs/api/v1/resources/EventResource.java b/src/main/java/tv/zerator/ffs/api/v1/resources/EventResource.java
index 7b5170d..9ff05f4 100644
--- a/src/main/java/tv/zerator/ffs/api/v1/resources/EventResource.java
+++ b/src/main/java/tv/zerator/ffs/api/v1/resources/EventResource.java
@@ -1,7 +1,17 @@
package tv.zerator.ffs.api.v1.resources;
import java.sql.SQLException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Comparator;
+
+import lombok.RequiredArgsConstructor;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
@@ -21,34 +31,39 @@
public class EventResource extends ServerResource {
@DaoInject
private static EventsDao mEvents;
-
+
private int mEventId;
@Override
protected void doInit() throws ResourceException {
mEventId = Integer.parseInt(getAttribute("EVENT_ID"));
}
-
+
@Get
public EventBean getEvent() throws SQLException {
EventBean event = mEvents.getEvent(mEventId);
if (event == null) throw new NotFoundException("EVENT_NOT_FOUND");
return event;
}
-
+
@Put
public Status updateEvent(UpdateEventEntity entity) throws SQLException {
ValidationUtils.verifyGroup(getRequest(), ApiV1.ADMIN);
ValidationErrors err = new ValidationErrors();
-
+
if (entity == null) throw new BadEntityException("ENTITY_NOT_FOUND");
-
+
err.verifyFieldEmptyness("name", entity.name, 3, 200);
err.verifyFieldEmptyness("description", entity.description, 3, 2048);
-
+
err.checkErrors("EVENT_UPDATE_ERROR");
-
+
EventBean bean = mEvents.getEvent(mEventId);
+
+ if (entity.status == EventBean.Status.ENDED && bean.getStatus() != EventBean.Status.ENDED){
+ rankAllUsers(mEventId);
+ }
+
if (bean == null) throw new NotFoundException("EVENT_NOT_FOUND");
bean.setCurrent(entity.current);
bean.setDescription(entity.description);
@@ -60,16 +75,17 @@ public Status updateEvent(UpdateEventEntity entity) throws SQLException {
bean.setMinimumFollowers(entity.minimum_followers);
bean.setRankingType(entity.ranking_type);
mEvents.update(bean);
+
return Status.SUCCESS_OK;
}
-
+
@Delete
public Status deleteEvent() throws SQLException {
ValidationUtils.verifyGroup(getRequest(), ApiV1.ADMIN);
mEvents.delete(mEventId);
return Status.SUCCESS_OK;
}
-
+
private static class UpdateEventEntity {
public String name, description;
public boolean current, reserved_to_affiliates, reserved_to_partners;
@@ -77,4 +93,69 @@ private static class UpdateEventEntity {
public EventBean.Status status;
public EventBean.RankingType ranking_type;
}
+
+ private void rankAllUsers(int eventId) throws SQLException {
+ EventBean event = mEvents.getEvent(mEventId);
+ List allScores = mEvents.getAllScores(eventId);
+
+ Set lastUsers = new HashSet<>();
+
+ Map map = new HashMap<>();
+
+ for (EventsDao.RoundUserScoreBean rus:
+ allScores) {
+ if (rus.getScore() == 0){
+ lastUsers.add(rus.getId());
+ }
+ if (map.containsKey(rus.getId())){
+ map.put(rus.getId(),map.get(rus.getId()) + rus.getScore());
+ } else {
+ map.put(rus.getId(),rus.getScore());
+ }
+ }
+
+ for (Integer userId:
+ lastUsers) {
+ map.remove(userId);
+ }
+
+ List> list = new ArrayList<>(map.entrySet());
+ Collections.sort(list, new ScoreUserValueComparator(event.getRankingType()));
+
+ int i = 1;
+ int currentRank = 1;
+ Double currentScore = null ;
+ for (Map.Entry entry:
+ list) {
+
+ if (currentScore == null || !currentScore.equals(entry.getValue())){
+ currentRank = i;
+ currentScore = entry.getValue();
+ }
+
+ mEvents.updateUserRank(mEventId, entry.getKey(), currentRank);
+
+ i++;
+ }
+
+ for (Integer userId:
+ lastUsers) {
+ mEvents.updateUserRank(mEventId, userId, i);
+ }
+
+ }
+
+ @RequiredArgsConstructor
+ private static class ScoreUserValueComparator implements Comparator> {
+ private final EventBean.RankingType rankingType;
+
+ @Override
+ public int compare(Map.Entry e1, Map.Entry e2) {
+ if (rankingType.equals(EventBean.RankingType.SCORE_ASC)){
+ return Double.compare(e1.getValue(),e2.getValue());
+ } else {
+ return Double.compare(e2.getValue(),e1.getValue());
+ }
+ }
+ }
}
diff --git a/src/main/java/tv/zerator/ffs/api/v1/resources/EventUsersResource.java b/src/main/java/tv/zerator/ffs/api/v1/resources/EventUsersResource.java
index 8971bcb..63e14a8 100644
--- a/src/main/java/tv/zerator/ffs/api/v1/resources/EventUsersResource.java
+++ b/src/main/java/tv/zerator/ffs/api/v1/resources/EventUsersResource.java
@@ -96,8 +96,8 @@ public List getUsers() throws SQLException {
List users = statusStr != null ? mEvents.getUsers(mEventId, status) : mEvents.getUsers(mEventId);
List ret = new ArrayList<>();
- for (AccountStatusBean ac : users) ret.add(isModerator ? new UserRepresentation(ac.getTwitchId(), ac.getViews(), ac.getFollowers(), ac.getGrade(), ac.getRank(), ac.getUsername(), ac.getEmail(), ac.getUrl(), ac.getLogo(), ac.getBroadcasterType(), ac.getStatus())
- : new UserRepresentation(ac.getTwitchId(), ac.getViews(), ac.getFollowers(), ac.getGrade(), ac.getRank(), ac.getUsername(), null, ac.getUrl(), ac.getLogo(), null, ac.getStatus()));
+ for (AccountStatusBean ac : users) ret.add(isModerator ? new UserRepresentation(ac.getTwitchId(), ac.getViews(), ac.getFollowers(), ac.getGrade(), ac.getRank(), ac.getUsername(), ac.getEmail(), ac.getUrl(), ac.getLogo(), ac.getBroadcasterType(), ac.getStatus(), ac.isSubscribeToWinner())
+ : new UserRepresentation(ac.getTwitchId(), ac.getViews(), ac.getFollowers(), ac.getGrade(), ac.getRank(), ac.getUsername(), null, ac.getUrl(), ac.getLogo(), null, ac.getStatus(), ac.isSubscribeToWinner()));
return ret;
}
@@ -166,6 +166,7 @@ public Status registerUser(RegisterUserEntity entity) throws SQLException {
private final String username, email, url, logo;
private final BroadcasterType broadcasterType;
private final EventsDao.UserStatus status;
+ private final boolean subscribeToWinner;
}
private static class RegisterUserEntity {