diff --git a/src/main/java/shef/data/Recipe.java b/src/main/java/shef/data/Recipe.java index 1d1527f..5a8cf81 100644 --- a/src/main/java/shef/data/Recipe.java +++ b/src/main/java/shef/data/Recipe.java @@ -23,6 +23,7 @@ import java.util.Iterator; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.EmbeddedEntity; +import com.google.appengine.api.datastore.KeyFactory; /** Stores a recipe's data. */ public class Recipe { @@ -38,6 +39,7 @@ public class Recipe { private List steps; private Set spinOffs; private long timestamp; + private boolean hasLiveStream; /** * Copy constructor called when creating spin-offs. @@ -65,11 +67,14 @@ public Recipe(String name, String description, Set tags, Set ing /** Creates a Recipe from a Datastore entity. */ public Recipe(Entity recipeEntity) { + this.key = KeyFactory.keyToString(recipeEntity.getKey()); this.name = (String) recipeEntity.getProperty("name"); + this.user = (String) recipeEntity.getProperty("user"); this.description = (String) recipeEntity.getProperty("description"); this.tags = getTagsFromEntity((Collection) recipeEntity.getProperty("tags")); this.ingredients = getIngredientsFromEntity((Collection) recipeEntity.getProperty("ingredients")); this.steps = getStepsFromEntity((Collection) recipeEntity.getProperty("steps")); + this.hasLiveStream = (boolean) recipeEntity.getProperty("has-live-stream"); this.timestamp = (long) recipeEntity.getProperty("timestamp"); } diff --git a/src/main/java/shef/servlets/DisplayRecipesServlet.java b/src/main/java/shef/servlets/DisplayRecipesServlet.java index 1a47c9d..24aca87 100644 --- a/src/main/java/shef/servlets/DisplayRecipesServlet.java +++ b/src/main/java/shef/servlets/DisplayRecipesServlet.java @@ -53,7 +53,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro List recipes = new ArrayList<>(); for (Entity entity : results.asIterable()) { - recipes.add(entityToRecipe(entity)); + recipes.add(new Recipe(entity)); } Gson gson = new Gson(); @@ -61,27 +61,4 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro response.setContentType("application/json;"); response.getWriter().println(gson.toJson(recipes)); } - - /** Converts a Datastore entity into a Recipe. */ - public Recipe entityToRecipe(Entity recipeEntity) { - String key = KeyFactory.keyToString(recipeEntity.getKey()); - String user = (String) recipeEntity.getProperty("user"); - String name = (String) recipeEntity.getProperty("name"); - String description = (String) recipeEntity.getProperty("description"); - LinkedHashSet tags = new LinkedHashSet<>((LinkedList) (LinkedList) getDataAsList(recipeEntity.getProperty("tags"), "tag")); - LinkedHashSet ingredients = new LinkedHashSet<>((LinkedList) (LinkedList) getDataAsList(recipeEntity.getProperty("ingredients"), "ingredient")); - LinkedList steps = (LinkedList) (LinkedList) getDataAsList(recipeEntity.getProperty("steps"), "step"); - long timestamp = (long) recipeEntity.getProperty("timestamp"); - return new Recipe(key, name, user, description, tags, ingredients, steps, timestamp); - } - - /** Gets a list of Recipe parameters from a Datastore property. */ - public Collection getDataAsList(Object propertiesObject, String field) { - Collection properties = (Collection) propertiesObject; - Collection dataAsList = new LinkedList<>(); - for (EmbeddedEntity property : properties) { - dataAsList.add(property.getProperty(field)); - } - return dataAsList; - } } diff --git a/src/main/java/shef/servlets/NewLiveStreamServlet.java b/src/main/java/shef/servlets/NewLiveStreamServlet.java index d30b279..5630d8e 100644 --- a/src/main/java/shef/servlets/NewLiveStreamServlet.java +++ b/src/main/java/shef/servlets/NewLiveStreamServlet.java @@ -20,6 +20,13 @@ import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.DatastoreServiceFactory; import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.PreparedQuery; +import com.google.appengine.api.datastore.Query; import java.io.IOException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -53,6 +60,25 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); datastore.put(liveStreamEntity); + /* Get the recipe that the user wishes to associate the live stream + with. If the recipe already has an associated live stream, throw an error. + Else, set the recipe's hasLiveStream field to true. hasLiveStream is used + to determine whether and how the recipe shows on the recipe and live stream feeds. */ + Query query = new Query("Recipe"); + Key recipeKey = KeyFactory.stringToKey(request.getParameter("recipe-key")); + Filter recipeKeyFilter = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, recipeKey); + query.setFilter(recipeKeyFilter); + PreparedQuery results = datastore.prepare(query); + for (Entity entity : results.asIterable()) { + boolean hasLiveStream = (boolean) entity.getProperty("has-live-stream"); + if (hasLiveStream) { + System.err.println("This event already has a live stream associated with it. Each recipe can only be associated with one live stream."); + } else { + entity.setProperty("has-live-stream", true); + datastore.put(entity); + } + } + response.sendRedirect("/create-live-stream.html"); } } diff --git a/src/main/java/shef/servlets/NewRecipeServlet.java b/src/main/java/shef/servlets/NewRecipeServlet.java index 2251e78..0449516 100644 --- a/src/main/java/shef/servlets/NewRecipeServlet.java +++ b/src/main/java/shef/servlets/NewRecipeServlet.java @@ -26,6 +26,8 @@ import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.users.UserService; +import com.google.appengine.api.users.UserServiceFactory; import com.google.gson.Gson; import java.util.Collection; import java.util.List; @@ -40,6 +42,7 @@ public class NewRecipeServlet extends HttpServlet { private DatastoreService datastore; + private UserService userService; private final String TAG = "tag"; private final String INGREDIENT = "ingredient"; private final String STEP = "step"; @@ -47,6 +50,7 @@ public class NewRecipeServlet extends HttpServlet { @Override public void init() { datastore = DatastoreServiceFactory.getDatastoreService(); + userService = UserServiceFactory.getUserService(); } /** When a spin-off is created, this GET request gets the original recipe's data. */ @@ -75,7 +79,12 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr Collection tags = getParameters(request, TAG, searchStrings); Collection ingredients = getParameters(request, INGREDIENT, searchStrings); Collection steps = getParameters(request, STEP, null); - int likes = Integer.parseInt(request.getParameter("likes")); + int likes; + try { + likes = Integer.parseInt(request.getParameter("likes")); + } catch (NumberFormatException e) { + likes = 0; + } long timestamp = System.currentTimeMillis(); Entity recipe = new Entity("Recipe"); @@ -85,6 +94,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr recipe.setProperty("ingredients", ingredients); recipe.setProperty("steps", steps); recipe.setProperty("search-strings", new ArrayList(searchStrings)); + recipe.setProperty("has-live-stream", false); // A newly created recipe does not have an associated live stream. recipe.setProperty("timestamp", timestamp); // Temporary if statement, can be removed once user service is fully integrated with recipe creation. // Without this if statement for the time being, the servlet crashes. @@ -95,9 +105,17 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr recipe.setProperty("user", userKeyString); } recipe.setProperty("likes", likes); + + // Add property for the key string of the current user. + if (userService != null && userService.getCurrentUser() != null) { + String id = userService.getCurrentUser().getUserId(); + Key userKey = KeyFactory.createKey("User", id); + String userKeyString = KeyFactory.keyToString(userKey); + recipe.setProperty("user", userKeyString); + } datastore.put(recipe); - response.sendRedirect("/edit-recipe.html"); + response.sendRedirect("/recipe.html"); } /** diff --git a/src/main/webapp/browse-recipes.html b/src/main/webapp/browse-recipes.html index f957534..deca6cb 100644 --- a/src/main/webapp/browse-recipes.html +++ b/src/main/webapp/browse-recipes.html @@ -25,7 +25,7 @@

Browse Recipes

-
+
diff --git a/src/main/webapp/create-recipe-blank.html b/src/main/webapp/create-recipe-blank.html index 8f3de8d..4de8237 100644 --- a/src/main/webapp/create-recipe-blank.html +++ b/src/main/webapp/create-recipe-blank.html @@ -37,6 +37,25 @@ + + + + diff --git a/src/main/webapp/css/style.css b/src/main/webapp/css/style.css index 852b922..4fd6920 100644 --- a/src/main/webapp/css/style.css +++ b/src/main/webapp/css/style.css @@ -11484,6 +11484,12 @@ p { font-size: 1.25rem; } +parameter-input { + display: inline-block; + vertical-align: middle; + margin: 0 0 15px 0; +} + .display-4 { font-weight: bold; } diff --git a/src/main/webapp/recipe.html b/src/main/webapp/recipe.html index 71ce5ce..c26fd18 100644 --- a/src/main/webapp/recipe.html +++ b/src/main/webapp/recipe.html @@ -47,12 +47,27 @@ }); - -

-    
-    
-    
-    
+    
+