package controllers; import java.io.IOException; import java.io.InputStream; import java.sql.Array; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeCreator; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import play.*; import play.db.DB; import play.libs.WS; import play.libs.WS.Response; import play.mvc.*; import play.mvc.Http.RequestBody; import views.html.*; public class EventManager extends Controller{ public static final String EVENT_GET_SQL_UNRESTRICTED = "select distinct Event.id as id, Event.name as name, Event.location as location, UNIX_TIMESTAMP(Event.time) as time, Event.description as description, Event.visibility as visibility, Event.view_count as view_count, Event_has_User.rsvp as rsvp from Event inner join Event_has_Tags on Event.id = Event_has_Tags.Event_id inner join Tags on Event_has_Tags.Tags_id = Tags.id inner join Event_has_User on Event.id = Event_has_User.event_id"; public static final String EVENT_GET_SQL = "select distinct Event.id as id, Event.name as name, Event.location as location, UNIX_TIMESTAMP(Event.time) as time, Event.description as description, Event.visibility as visibility, Event.view_count as view_count, Event_has_User.rsvp as rsvp from Event inner join Event_has_Tags on Event.id = Event_has_Tags.Event_id inner join Tags on Event_has_Tags.Tags_id = Tags.id inner join Event_has_User on Event.id = Event_has_User.event_id WHERE (Event.visibility = 1 OR (Event_has_User.user_id = ? AND (Event_has_User.rsvp != -1 or Event_has_User.is_admin != 0)))"; public static ArrayNode buildEventResults(Connection conn, ResultSet rs, long userId) throws SQLException { ArrayNode arr = JsonNodeFactory.instance.arrayNode(); while(rs.next()) { ObjectNode eventRes = createEventJson(rs); try(PreparedStatement stmtTag = conn.prepareStatement("select Tags.tag from Tags INNER JOIN Event_has_Tags ON Tags.id = Event_has_Tags.Tags_id INNER JOIN Event ON Event.id = Event_has_Tags.Event_id WHERE Event.id = ?")) { stmtTag.setLong(1, rs.getLong("id")); stmtTag.execute(); ResultSet rsTag = stmtTag.getResultSet(); addCategoriesToEventJson(eventRes, rsTag); } try(PreparedStatement stmtAdmin = conn.prepareStatement("select is_admin, rsvp from Event_has_User where event_id = ? and user_id = ?")) { stmtAdmin.setLong(1, rs.getLong("id")); stmtAdmin.setLong(2, userId); stmtAdmin.execute(); ResultSet rsAdmin = stmtAdmin.getResultSet(); if(rsAdmin.next()) { eventRes.put("is_admin", rsAdmin.getInt("is_admin")); eventRes.put("rsvp", rsAdmin.getInt("rsvp")); } else { eventRes.put("is_admin", 0); eventRes.put("rsvp", "-1"); } rsAdmin.close(); } try(PreparedStatement stmtCreator = conn.prepareStatement("select user_id from Event_has_User where event_id = ? and is_admin != 0")) { stmtCreator.setLong(1, rs.getLong("id")); stmtCreator.execute(); ResultSet rsCreator = stmtCreator.getResultSet(); if(rsCreator.next()) { try(PreparedStatement stmtCreatorInfo = conn.prepareStatement("select first_name, last_name from User where id = ?")) { stmtCreatorInfo.setLong(1, rsCreator.getLong("user_id")); stmtCreatorInfo.execute(); ResultSet rsCreatorInfo = stmtCreatorInfo.getResultSet(); if(rsCreatorInfo.next()) { eventRes.put("creator", JsonNodeFactory.instance.objectNode() .put("first_name", rsCreatorInfo.getString("first_name")) .put("last_name", rsCreatorInfo.getString("last_name")) ); } rsCreatorInfo.close(); } } rsCreator.close(); } arr.add(eventRes); } return arr; } public static Result create() { /* OAuth*/ JsonNode request = request().body().asJson(); try { Application.checkReqValid(request); } catch(AuthorizationException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } catch(SQLException e) { e.printStackTrace(); return ok(); } String title, desc, location; long timestamp; int visibility; ArrayNode categories; try { title = request.get("title").textValue(); desc = request.get("desc").textValue(); location = request.get("location").textValue(); timestamp = request.get("date_time").asLong(); visibility = request.get("visibility").intValue(); if(request.has("categories")) { categories = (ArrayNode) request.get("categories"); } else { throw new Exception("categories"); } } catch(Exception e) { return ok(JsonNodeFactory.instance.objectNode() .put("error", "Parameters: title (string), desc(string), location(string), date_time(long), visibility(int), categories(array)")); } // convert time to date java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(timestamp); Connection conn = DB.getConnection(); try { conn.setAutoCommit(false); PreparedStatement stmt = conn.prepareStatement("INSERT INTO CampusFeed.Event (name,location,time,description,visibility) VALUES (?,?,?,?,?)",Statement.RETURN_GENERATED_KEYS); stmt.setString(1, title); stmt.setString(2, location); stmt.setTimestamp(3, sqlTimestamp); stmt.setString(4, desc); stmt.setInt(5, visibility); stmt.executeUpdate(); ResultSet rs = stmt.getGeneratedKeys(); // get the generated primary key if(rs.next()) { long event_id = rs.getLong(1); long user_id =Application.getUserId(request); stmt = conn.prepareStatement("INSERT INTO CampusFeed.Event_has_User (event_id,user_id,is_admin) VALUES (?,?,?)"); stmt.setLong(1, event_id); stmt.setLong(2, user_id); stmt.setInt(3, 1); stmt.executeUpdate(); String[] categoriesStr = new String[categories.size()]; for(int i = 0; i < categories.size(); ++i) { categoriesStr[i] = categories.get(i).textValue(); } addTags(conn, event_id, categoriesStr); conn.commit(); conn.close(); return ok(JsonNodeFactory.instance.objectNode().put("event_id", event_id)); } else { throw new SQLException(); } } catch(SQLException e) { e.printStackTrace(); try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } return ok(); } } public static int createFromScrapedPage(JsonNode request) { /* OAuth*/ String title, desc, location; long timestamp; int visibility; ArrayNode categories; try { title = request.get("title").textValue(); desc = request.get("desc").textValue(); location = request.get("location").textValue(); timestamp = request.get("date_time").asLong(); visibility = request.get("visibility").intValue(); if(request.has("categories")) { categories = (ArrayNode) request.get("categories"); } else { throw new Exception("categories"); } } catch(Exception e) { return -1; } // convert time to date java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(timestamp); Connection conn = DB.getConnection(); try { conn.setAutoCommit(false); PreparedStatement stmt = conn.prepareStatement("INSERT INTO CampusFeed.Event (name,location,time,description,visibility) VALUES (?,?,?,?,?)",Statement.RETURN_GENERATED_KEYS); stmt.setString(1, title); stmt.setString(2, location); stmt.setTimestamp(3, sqlTimestamp); stmt.setString(4, desc); stmt.setInt(5, visibility); stmt.executeUpdate(); ResultSet rs = stmt.getGeneratedKeys(); // get the generated primary key if(rs.next()) { long event_id = rs.getLong(1); long user_id =Application.getUserId(request); stmt = conn.prepareStatement("INSERT INTO CampusFeed.Event_has_User (event_id,user_id,is_admin) VALUES (?,?,?)"); stmt.setLong(1, event_id); stmt.setLong(2, ScraperHandler.SCRAPER_ID); stmt.setInt(3, 1); stmt.executeUpdate(); String[] categoriesStr = new String[categories.size()]; for(int i = 0; i < categories.size(); ++i) { categoriesStr[i] = categories.get(i).textValue(); } addTags(conn, event_id, categoriesStr); conn.commit(); conn.close(); return 1; } else { throw new SQLException(); } } catch(SQLException e) { e.printStackTrace(); try { conn.rollback(); return 1; } catch (SQLException e1) { e1.printStackTrace(); return -1; } } } public static Result rsvp_to_event() { /* OAuth*/ JsonNode request = request().body().asJson(); if(request==null) { return ok(); } try { Application.checkReqValid(request); } catch(AuthorizationException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } catch(SQLException e) { e.printStackTrace(); return ok(); } // add user to rsvp // get the user id long user_id =Application.getUserId(request); // main thing, only need event_id long event_id; int rsvp_status; try { event_id = request.get("event_id").longValue(); rsvp_status = request.get("rsvp_status").intValue(); } catch(Exception ex) { return ok(JsonNodeFactory.instance.objectNode().put("error", "usage: event_id, rsvp_status")); } try(Connection conn = DB.getConnection()) { PreparedStatement stmt = conn.prepareStatement("SELECT rsvp FROM CampusFeed.Event_has_User WHERE user_id=? AND event_id=?"); stmt.setLong(1, user_id); stmt.setLong(2, event_id); stmt.execute(); ResultSet rs = stmt.getResultSet(); if(rs.next()) { PreparedStatement update = conn.prepareStatement("update Event_has_User set rsvp = ? where user_id = ? and event_id = ?"); update.setInt(1, rsvp_status); update.setLong(2, user_id); update.setLong(3, event_id); update.execute(); } else { PreparedStatement insert = conn.prepareStatement("insert into Event_has_User (rsvp, event_id, user_id) values (?, ?, ?)"); insert.setInt(1, rsvp_status); insert.setLong(2, event_id); insert.setLong(3, user_id); insert.execute(); } } catch(Exception e) { e.printStackTrace(); return ok(JsonNodeFactory.instance.objectNode().put("error", e.toString())); } return ok(JsonNodeFactory.instance.objectNode().put("ok", "ok")); } /** * Helper function to create event json from results * @param rs result set from query on a valid event row * @return the json event * @throws SQLException */ private static ObjectNode createEventJson(ResultSet rs) throws SQLException { ObjectNode searchResult = JsonNodeFactory.instance.objectNode(); searchResult.put("id", rs.getString("id")); searchResult.put("name", rs.getString("name")); searchResult.put("location", rs.getString("location")); searchResult.put("time", rs.getInt("time")); searchResult.put("description", rs.getString("description")); //searchResult.put("category", rs.getString("category")); searchResult.put("visibility", rs.getInt("visibility")); searchResult.put("view_count", rs.getInt("view_count")); searchResult.put("rsvp", rs.getInt("rsvp")); return searchResult; } /** * Helper function to add categories to event json * @param event * @param rs * @throws SQLException */ private static void addCategoriesToEventJson(ObjectNode event, ResultSet rs) throws SQLException { ArrayNode categories = JsonNodeFactory.instance.arrayNode(); while(rs.next()) { categories.add(rs.getString("tag")); } event.put("categories", categories); } public static Result advSearch() { JsonNode request = request().body().asJson(); try { Application.checkReqValid(request); } catch(AuthorizationException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } catch(SQLException e) { e.printStackTrace(); return ok(); } // get the user id long user_id =Application.getUserId(request); //check params if(!request.has("name") && !(request.has("start_date") && request.has("end_date")) && !request.has("desc") && !request.has("tags")){ return ok(JsonNodeFactory.instance.objectNode().put("error", "usage: name (text) or (start_date (date) and end_date (date)) or desc (text) or tags (array)")); } try(Connection conn = DB.getConnection()) { PreparedStatement stmt = null; List<Object> params = new ArrayList<Object>(); params.add(user_id); String sql = EVENT_GET_SQL; if(request.has("name")) { if(params.size() != 0) { sql += " AND "; } sql += "name like ?"; params.add("%" + request.get("name").textValue() + "%"); } if(request.has("start_date") && request.has("end_date")) { if(params.size() != 0) { sql += " AND "; } sql += "UNIX_TIMESTAMP(time) BETWEEN ? AND ?"; params.add(request.get("start_date").asLong()); params.add(request.get("end_date").asLong()); } if(request.has("desc")) { if(params.size() != 0) { sql += " AND "; } sql += "description like ?"; params.add("%" + request.get("desc").textValue() + "%"); } if(request.has("tags")) { ArrayNode tags = (ArrayNode) request.get("tags"); if(params.size() != 0) { sql += " AND ("; } for(int i = 0; i < tags.size(); ++i) { sql += "Tags.tag = ?"; params.add(tags.get(i).textValue()); if(i < tags.size() - 1) { sql += " OR "; } } sql += ")"; } stmt = conn.prepareStatement(sql+" ORDER BY Event.view_count DESC"); for(int i = 0; i < params.size(); ++i) { stmt.setObject(i + 1, params.get(i)); } stmt.execute(); ResultSet rs = stmt.executeQuery(); return ok(buildEventResults(conn, rs, user_id)); } catch(Exception e) { e.printStackTrace(); return ok(); } } public static Result listEvent() { JsonNode request = request().body().asJson(); try { Application.checkReqValid(request); } catch(AuthorizationException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } catch(SQLException e) { e.printStackTrace(); return ok(); } // get the user id long user_id =Application.getUserId(request); //check params int page; try { page = request.get("page").intValue(); } catch(Exception e) { return ok(JsonNodeFactory.instance.objectNode().put("error", "usage: page (int)")); } try(Connection conn = DB.getConnection()) { try(PreparedStatement stmt = conn.prepareStatement(EVENT_GET_SQL + "ORDER BY Event.view_count DESC LIMIT 25 OFFSET ?")) { stmt.setLong(1, user_id); stmt.setInt(2, page * 25); ResultSet rs = stmt.executeQuery(); return ok(buildEventResults(conn, rs, user_id)); } } catch(SQLException e) { e.printStackTrace(); return ok(); } } private static void addTags(Connection conn, long eventId, String[] tags) throws SQLException{ PreparedStatement lookupTag = conn.prepareStatement("SELECT id FROM Tags WHERE tag = ?"); PreparedStatement addTag = conn.prepareStatement("INSERT INTO Tags (tag) VALUES (?)", Statement.RETURN_GENERATED_KEYS); PreparedStatement linkTag = conn.prepareStatement("INSERT INTO Event_has_Tags (Event_id, Tags_id) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS); for(String tag : tags) { lookupTag.setString(1, tag); lookupTag.execute(); ResultSet rs; long tag_id = -1; if((rs = lookupTag.getResultSet()).next()) { tag_id = rs.getLong(1); } else { addTag.setString(1, tag); addTag.execute(); if((rs = addTag.getGeneratedKeys()).next()) { tag_id = rs.getLong(1); } } linkTag.setLong(1, eventId); linkTag.setLong(2, tag_id); linkTag.execute(); } lookupTag.close(); addTag.close(); linkTag.close(); } public static Result updateEvent() { /* OAuth*/ JsonNode request = request().body().asJson(); try { Application.checkReqValid(request); } catch(AuthorizationException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } catch(SQLException e) { e.printStackTrace(); return ok(); } String title, desc, location; long timestamp, id; int visibility; ArrayNode categories; try { title = request.get("title").textValue(); desc = request.get("desc").textValue(); location = request.get("location").textValue(); timestamp = request.get("date_time").asLong(); visibility = request.get("visibility").intValue(); id = request.get("id").longValue(); categories = (ArrayNode) request.get("categories"); if(categories == null) { throw new Exception("categories"); } } catch(Exception e) { e.printStackTrace(); return ok(JsonNodeFactory.instance.objectNode() .put("error", "Parameters: title (string), desc(string), location(string), date_time(long), visibility(int), categories(array)")); } long userId = Application.getUserId(request); Connection conn = DB.getConnection(); try { conn.setAutoCommit(false); PreparedStatement isAdminQuery = conn.prepareStatement("select is_admin from CampusFeed.Event_has_User where event_id = ? and user_id = ?"); isAdminQuery.setLong(1, id); isAdminQuery.setLong(2, userId); isAdminQuery.execute(); boolean isAdmin = false; ResultSet rs = isAdminQuery.getResultSet(); if(rs.next()) { isAdmin = rs.getInt("is_admin") != 0; } isAdminQuery.close(); if(!isAdmin) { conn.close(); return ok(JsonNodeFactory.instance.objectNode().put("no", "not admin")); } PreparedStatement stmt2 = conn.prepareStatement("UPDATE `CampusFeed`.`Event` SET name=?, location=?,description=?,time=?,visibility=? WHERE `Event`.`id` = ?"); stmt2.setString(1, title); stmt2.setString(2, location); stmt2.setString(3, desc); stmt2.setTimestamp(4, new Timestamp(timestamp)); stmt2.setInt(5, visibility); stmt2.setLong(6, id); stmt2.executeUpdate(); stmt2 = conn.prepareStatement("DELETE Event_has_Tags FROM Event_has_Tags INNER JOIN Event ON Event_has_Tags.Event_id = Event.id WHERE (Event.id = ?)"); stmt2.setLong(1, id); stmt2.executeUpdate(); String[] categoriesStr = new String[categories.size()]; for(int i = 0; i < categories.size(); ++i) { categoriesStr[i] = categories.get(i).textValue(); } addTags(conn, id, categoriesStr); conn.commit(); conn.close(); // send messages to all users GCMHandler.sendMessage(get_user_ids(),id); // end messaging. return ok(JsonNodeFactory.instance.objectNode().put("ok", "ok")); } catch(SQLException e) { e.printStackTrace(); return ok("err", e.getMessage()); } } public static ArrayList<String> get_user_ids() { try(Connection conn = DB.getConnection()) { PreparedStatement stmt = conn.prepareStatement("SELECT * FROM `User` WHERE gcm_id IS NOT NULL"); ResultSet s =stmt.executeQuery(); ArrayList<String> user_ids = new ArrayList<String>(); while(s.next()) { String gcm_id = s.getString("gcm_id"); user_ids.add(gcm_id); System.out.println(gcm_id+"\n"); } s.close(); return user_ids; }catch(Exception e) { return null; } } public static Result allTags() { try(Connection conn = DB.getConnection()) { PreparedStatement stmt = conn.prepareStatement("SELECT * FROM Tags"); ResultSet s =stmt.executeQuery(); ArrayList<String> tags = new ArrayList<String>(); while(s.next()) { tags.add(s.getString("tag")); } s.close(); JsonNode tags_json= JsonNodeFactory.instance.objectNode().put("tags", tags.toString()); return ok(tags_json); }catch(Exception e) { return ok(); } } public static Result top5() { JsonNode request = request().body().asJson(); String category; try { category = request.get("category").textValue(); } catch(Exception e) { e.printStackTrace(); return ok(JsonNodeFactory.instance.objectNode() .put("error", "Parameters: category (text)")); } try(Connection conn = DB.getConnection()) { PreparedStatement stmt = conn.prepareStatement(EVENT_GET_SQL_UNRESTRICTED + " WHERE Tags.tag = ? ORDER BY Event.view_count DESC LIMIT 5"); stmt.setString(1, category); ResultSet rs = stmt.executeQuery(); return ok(buildEventResults(conn, rs, Application.getUserId(request))); } catch(SQLException e) { return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } } public static Result getEvent() { JsonNode request = request().body().asJson(); long event_id; try { event_id = request.get("event_id").longValue(); } catch(Exception e) { return ok(JsonNodeFactory.instance.objectNode().put("error", "usage: event_id (long)")); } long user_id; user_id = Application.getUserId(request); try(Connection conn = DB.getConnection()) { if(user_id != -1) { PreparedStatement stmt = conn.prepareStatement(EVENT_GET_SQL_UNRESTRICTED + " WHERE Event.id = ?"); stmt.setLong(1, event_id); ResultSet rs = stmt.executeQuery(); return ok(buildEventResults(conn, rs, Application.getUserId(request)).get(0)); } else { PreparedStatement stmt = conn.prepareStatement(EVENT_GET_SQL_UNRESTRICTED + " WHERE Event.id = ?"); stmt.setLong(1, event_id); ResultSet rs = stmt.executeQuery(); return ok(buildEventResults(conn, rs, Application.getUserId(request)).get(0)); } } catch(Exception e) { e.printStackTrace(); return ok(JsonNodeFactory.instance.objectNode().put("error", e.getMessage())); } } public static Result getEventAttendees() { JsonNode request = request().body().asJson(); // get all members for event. long event_id=request.get("event_id").longValue(); try{ Connection conn = DB.getConnection(); PreparedStatement stmt = conn.prepareStatement("SELECT User.first_name, User.last_name from User INNER JOIN Event_has_User ON User.id=Event_has_User.user_id WHERE Event_has_User.event_id = ? "); stmt.setLong(1, event_id); ResultSet rs = stmt.executeQuery(); ArrayList<String> names = new ArrayList<String>(); JSONObject obj = new JSONObject(); JSONArray json_array = new JSONArray(); while(rs.next()) { String first = rs.getString(1); if(!first.equals("Scraper")){ json_array.put(first +" "+ rs.getString(2)); } } obj.put("names", json_array); return ok(obj.toString()); } catch(Exception e) { return ok(e.toString()); } } public static Result incrementViewCount() { JsonNode request = request().body().asJson(); int event_id = request.get("event_id").asInt(); try{ Connection conn = DB.getConnection(); PreparedStatement stmt = conn.prepareStatement("UPDATE Event SET view_count = view_count +1 WHERE id = ?"); stmt.setInt(1, event_id); stmt.executeUpdate(); JSONObject json = new JSONObject(); json.put("response", "done"); return ok(json.toString()); } catch(Exception e) { return ok(e.toString()); } } }