Przeglądaj źródła

Food routes added + Parameterized Units

Food routes are linked up and a few examples added.  Added some
serialization handling to Measure to accomplish this.

I realized the only distinguishing features between each of the units
were the conversion and measure, both of which could be loaded at run
time with no penalty.  Considering this, I decided to parameterize it
to make it a bit more flexible.
Thomas Flucke 7 lat temu
rodzic
commit
9236f87e2c

+ 20 - 7
app/controllers/FoodController.scala

@@ -1,12 +1,25 @@
 package controllers
 
-import models.Food
+import models.{Food,Unit,Mass,Measure}
 import play.api.mvc._
+import play.api.libs.json._
 
-object FoodController extends Controller {
-  def put(id: Int): Result = null
-  def update(): Result = null
-  def get(id: Int): Result = null
-  def query(query: String = ""): Result = null
-  def delete(query: String = ""): Result = null
+class FoodController extends Controller {
+  private def expFood() = new Food("Example",
+    false, false, false,
+    Map.empty,
+    "Tom Flucke",
+    Seq("Poultry", "Southern"),
+    Mass,
+    2, 30, 1237,
+    Nil
+  )
+
+  def put(): Action[Food] = null
+  def update(id: Int): Action[Food] = null
+  def get(id: Int): Action[Food] = null
+  def query(query: String = ""): Action[AnyContent] = Action {
+    Ok(Json.toJson(expFood))
+  }
+  def delete(id: Int): Action[Food] = null
 }

+ 21 - 14
app/models/Food.scala

@@ -1,17 +1,24 @@
 package models
 
-class Food(
-  name: String,
-  glutenFree: Boolean = false,
-  vegitarian: Boolean = false,
-  vegan: Boolean = false,
-  nutrients: Map[Nutrient, Float],
-  source: String,
-  catagory: Seq[String],
-  primaryMeasure: Measure,
-  density: Float,
-  mass_p_u: Float,
-  price: Int,
-  alternatives: Seq[Food] = Nil
-  //picture: Image
+import play.api.libs.json._
+
+case class Food(
+  val name: String,
+  val glutenFree: Boolean = false,
+  val vegitarian: Boolean = false,
+  val vegan: Boolean = false,
+  val nutrients: Map[String, Float],
+  val source: String,
+  val category: Seq[String],
+  val primaryMeasure: Measure,
+  val density: Float,
+  val mass_p_u: Float,
+  val price: Int,
+  val alternatives: Seq[Food] = Nil
+    //val picture: Image
 )
+
+object Food {
+  import play.api.libs.json.Json
+  implicit val foodFormats = Json.format[Food]
+}

+ 29 - 10
app/models/Measure.scala

@@ -3,20 +3,39 @@ package models
 sealed trait Measure {
   def productPrefix: String
   def name: String = this.productPrefix.split("\\.").last
-  def primaryUnit: Unit
+  //  def primaryUnit: Uni
 }
 
-case object Mass extends Measure
-{
-  val primaryUnit = Gram
+object Measure {
+  import play.api.libs.json._
+
+  implicit val measureFormat = new Format[Measure] {
+    def writes(m: Measure): JsValue = Json.toJson(m.name.toLowerCase)
+
+    def reads(jsValue: JsValue): JsResult[Measure] =
+      jsValue.validate[String] match {
+        case s: JsSuccess[String] => s.get match {
+          case "mass" => JsSuccess(Mass)
+          case "volume" => JsSuccess(Volume)
+          case "number" => JsSuccess(Number)
+        }
+        case e: JsError => e
+      }
+  }
 }
 
+case object Mass extends Measure
+// {
+//   val primaryUnit = Gram
+// }
+
 case object Volume extends Measure
-{
-  val primaryUnit = Liter
-}
+// {
+//   val primaryUnit = Liter
+// }
 
 case object Number extends Measure
-{
-  val primaryUnit = Count
-}
+// {
+//   val primaryUnit = Count
+// }
+

+ 7 - 1
app/models/Nutrient.scala

@@ -1,3 +1,9 @@
 package models
 
-class Nutrient(id: Int, name: String, unit: Unit, description: String)
+import play.api.libs.json._
+
+class Nutrient(
+  val id: Int,
+  val name: String,
+  val unit: Unit,
+  val description: String)

+ 8 - 6
app/models/Unit.scala

@@ -3,12 +3,12 @@ package models
 class ConversionException(from: Unit, to: Unit) extends
     RuntimeException(s"Cannot convert from $from to $to.", null)
 
-sealed trait Unit {
-  def productPrefix: String
-  protected def conversion: Float
-  def name: String = this.productPrefix.split("\\.").last
-  protected def abreviation: String
-  def measure: Measure
+class Unit(
+  val name: String,
+  abreviation: String,
+  conversion: Float,
+  val measure: Measure
+) {
   def convertToPrimary(v: Float): Float = v/conversion
   def convertFromPrimary(v: Float): Float = v*conversion
   def convertTo(v: Float, other: Unit) = {
@@ -19,6 +19,7 @@ sealed trait Unit {
   }
 }
 
+/*
 case object Gram extends Unit
 {
   protected val conversion: Float = 1f
@@ -95,3 +96,4 @@ case object Count extends Unit
   val measure: Measure = Number
   val abreviation: String = ""
 }
+ */

+ 8 - 0
conf/routes

@@ -6,6 +6,14 @@
 # An example controller showing a sample home page
 GET     /                           controllers.HomeController.index
 
+# Food Manager
+GET     /food                       controllers.FoodController.query(term: String ?= "")
+GET     /food/:id                   controllers.FoodController.get(id: Int)
+PUT     /food                       controllers.FoodController.put()
+POST    /food/:id                   controllers.FoodController.update(id: Int)
+DELETE  /food/:id                   controllers.FoodController.delete(id: Int)
+
+# Ingredient Manager
 GET     /ingredients                controllers.IngredientController.editorPage
 
 # Map static resources from the /public folder to the /assets URL path