Newer
Older
package controllers
import javax.inject._
import play.api.mvc._
import play.api.libs.json.{JsValue, JsLookupResult}
import models.actions.{AuthenticatedUserAction, AuthenticationRequest}
import models.exceptions.{ConflictException, NotFoundException, InvalidRequestBodyException, InvalidQueryParameterException}
import scala.concurrent.TimeoutException
import org.bson.types.ObjectId
/**
* This controller handles all the Daily endpoints.
*/
@Singleton
class DailyController @Inject()(val controllerComponents: ControllerComponents, authenticatedUserAction: AuthenticatedUserAction)
extends BaseController {
/**
* Create an Action to fetch all the Dailies in the DB.
*/
def getAll() = authenticatedUserAction {
println("DailyController:getAll")
try {
val result: Seq[Daily] = Daily.getAllDailiesAsync()
val jsonResult: JsValue = Daily.toJson(result)
case _: TimeoutException => BadRequest("Request timed out")
case _: Throwable => BadRequest("Exception raised")
/**
* Create an Action to fetch the user's Dailies in the DB.
*
* @param userId The ID of the user to get the dailies for.
def getUserDailies(userId: String) = authenticatedUserAction {
println("DailyController:getUserDailies")
try {
if (!ObjectId.isValid(userId)) throw new InvalidQueryParameterException("Invalid query parameter ID format: userId")
val result: Seq[Daily] = Daily.getUserDailiesAsync(new ObjectId(userId))
val jsonResult: JsValue = Daily.toJson(result)
Ok(jsonResult)
} catch {
case _: TimeoutException => BadRequest("Request timed out")
case ex: InvalidQueryParameterException => BadRequest(ex.getMessage())
case _: Throwable => BadRequest("Exception raised")
/**
* Create an Action to fetch the user's Feed.
*
* @param userId The ID of the user to get the feed for.
def getUserFeed(userId: String, questionId: String) = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
println("DailyController:getUserFeed")
try {
if (!ObjectId.isValid(userId)) throw new InvalidRequestBodyException("Invalid query parameter ID format: userId")
val result: Seq[Daily] = Daily.getUserFeedAsync(new ObjectId(userId), new ObjectId(questionId), request.jwt)
val jsonResult: JsValue = Daily.toJson(result)
case _: TimeoutException => BadRequest("Request timed out")
case ex: InvalidQueryParameterException => BadRequest(ex.getMessage())
case _: Throwable => BadRequest("Exception raised")
/**
* Create an Action to create a Daily.
*/
def create() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
println("DailyController:create")
try {
val (userId, questionId, content) = fetchCreateRequestBody(request.body)
val result: Daily = Daily.createDailyAsync(userId, questionId, content)
val jsonResult: JsValue = Daily.toJson(result)
case _: TimeoutException => BadRequest("Request timed out")
case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
case _: Throwable => BadRequest("Exception raised")
/**
* Create an Action to like a Daily.
*/
def like() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
println("DailyController:like")
try {
val (dailyId, likerId) = fetchLikeRequestBody(request.body)
Daily.likeAsync(dailyId, likerId, request.jwt)
case _: TimeoutException => BadRequest("Request timed out")
case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
case ex: ConflictException => BadRequest(ex.getMessage())
case ex: NotFoundException => BadRequest(ex.getMessage())
case _: Throwable => BadRequest("Exception raised")
/**
* Create an Action to unlike a Daily.
*/
def unlike() = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] =>
println("DailyController:unlike")
try {
val (dailyId, likerId) = fetchLikeRequestBody(request.body)
Daily.unlikeAsync(dailyId, likerId, request.jwt)
} catch {
case _: TimeoutException => BadRequest("Request timed out")
case ex: InvalidRequestBodyException => BadRequest(ex.getMessage())
case ex: ConflictException => BadRequest(ex.getMessage())
case ex: NotFoundException => BadRequest(ex.getMessage())
case _: Throwable => BadRequest("Exception raised")
}
}
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/**
* Fetch the needed values from the request body for the creating a Daily endpoint.
*
* @param requestBody The request's body.
*/
def fetchCreateRequestBody(requestBody: AnyContent): (ObjectId, ObjectId, String) = {
if (!requestBody.asJson.isDefined) throw new InvalidRequestBodyException("Request body must be in JSON format.")
val bodyJson = requestBody.asJson.get
val userId: ObjectId = fetchJsonBodyObjectId(bodyJson, "userId")
val questionId: ObjectId = fetchJsonBodyObjectId(bodyJson, "questionId")
val content: String = fetchJsonBodyString(bodyJson, "content")
(userId, questionId, content)
}
/**
* Fetch the needed values from the request body for the liking/unliking a Daily endpoint.
*
* @param requestBody The request's body.
*/
def fetchLikeRequestBody(requestBody: AnyContent): (ObjectId, ObjectId) = {
if (!requestBody.asJson.isDefined) throw new InvalidRequestBodyException("Request body must be in JSON format.")
val bodyJson = requestBody.asJson.get
val dailyId: ObjectId = fetchJsonBodyObjectId(bodyJson, "dailyId")
val likerId: ObjectId = fetchJsonBodyObjectId(bodyJson, "likerId")
(dailyId, likerId)
}
/**
* Fetch the value of the given field name from the JSON.
*
* @param bodyJson The JSON.
* @param fieldName The field name.
*/
def fetchJsonBodyValue(bodyJson: JsValue, fieldName: String): JsValue = {
val value: JsLookupResult = (bodyJson \ fieldName)
if (!value.isDefined) throw new InvalidRequestBodyException("Missing parameter: " + fieldName)
value.get
}
/**
* Fetch the String value of the field name from the JSON.
*
* @param bodyJson The JSON.
* @param fieldName The field name.
*/
def fetchJsonBodyString(bodyJson: JsValue, fieldName: String): String = {
fetchJsonBodyValue(bodyJson, fieldName).as[String]
}
/**
* Fetch the ObjectId value of the field name from the JSON.
*
* @param bodyJson The JSON.
* @param fieldName The field name.
*
* @throws InvalidRequestBodyException if the value is not a valid ID.
*/
def fetchJsonBodyObjectId(bodyJson: JsValue, fieldName: String): ObjectId = {
val value: String = fetchJsonBodyValue(bodyJson, fieldName).as[String]
if (!ObjectId.isValid(value)) throw new InvalidRequestBodyException("Invalid ID format: " + fieldName)
new ObjectId(value)
}