Skip to content
This repository has been archived by the owner on Aug 16, 2024. It is now read-only.

Commit

Permalink
Merge pull request #5 from Dasiu/slick-update
Browse files Browse the repository at this point in the history
Made articles list filters independent
  • Loading branch information
Dasiu authored Jan 19, 2020
2 parents dedd1b9 + f076b74 commit 754a9b4
Show file tree
Hide file tree
Showing 26 changed files with 576 additions and 695 deletions.
21 changes: 4 additions & 17 deletions app/articles/ArticleComponents.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.softwaremill.macwire.wire
import commons.config.{WithControllerComponents, WithExecutionContextComponents}
import commons.models._
import articles.controllers.{ArticleController, CommentController, TagController}
import articles.models.{ArticleMetaModel, CommentId, MainFeedPageRequest, UserFeedPageRequest}
import articles.models._
import articles.repositories._
import articles.services._
import commons.CommonsComponents
Expand All @@ -19,9 +19,6 @@ trait ArticleComponents
with CommonsComponents
with WithExecutionContextComponents {

private lazy val defaultOffset = 0L
private lazy val defaultLimit = 20L

def authenticatedAction: AuthenticatedActionBuilder

lazy val articleController: ArticleController = wire[ArticleController]
Expand All @@ -48,21 +45,11 @@ trait ArticleComponents
q_o"offset=${long(maybeOffset)}" &
q_o"tag=$maybeTag" &
q_o"author=$maybeAuthor" &
q_o"favorited=$maybeFavorited") =>

val limit = maybeLimit.getOrElse(defaultLimit)
val offset = maybeOffset.getOrElse(defaultOffset)
val maybeAuthorUsername = maybeAuthor.map(Username(_))
val maybeFavoritedUsername = maybeFavorited.map(Username(_))
q_o"favorited =$maybeFavorited") =>

articleController.findAll(MainFeedPageRequest(maybeTag, maybeAuthorUsername, maybeFavoritedUsername, limit, offset,
List(Ordering(ArticleMetaModel.createdAt, Descending))))
articleController.findAll(maybeTag, maybeAuthor, maybeFavorited, maybeLimit, maybeOffset)
case GET(p"/articles/feed" ? q_o"limit=${long(limit)}" & q_o"offset=${long(offset)}") =>
val theLimit = limit.getOrElse(defaultLimit)
val theOffset = offset.getOrElse(defaultOffset)

articleController.findFeed(UserFeedPageRequest(theLimit, theOffset,
List(Ordering(ArticleMetaModel.createdAt, Descending))))
articleController.findFeed(limit, offset)
case GET(p"/articles/$slug") =>
articleController.findBySlug(slug)
case POST(p"/articles") =>
Expand Down
55 changes: 49 additions & 6 deletions app/articles/controllers/ArticleController.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package articles.controllers

import commons.exceptions.MissingModelException
import commons.services.ActionRunner
import articles.controllers.ArticleController.{defaultLimit, defaultOffset}
import articles.exceptions.AuthorMismatchException
import articles.models._
import articles.services.{ArticleReadService, ArticleWriteService}
import commons.controllers.RealWorldAbstractController
import commons.exceptions.MissingModelException
import commons.models.{Descending, Ordering, Username}
import commons.services.ActionRunner
import org.apache.commons.lang3.StringUtils
import play.api.libs.json._
import play.api.mvc.{Action, AnyContent, ControllerComponents}
Expand Down Expand Up @@ -58,26 +60,62 @@ class ArticleController(authenticatedAction: AuthenticatedActionBuilder,
})
}

def findAll(pageRequest: MainFeedPageRequest): Action[AnyContent] = optionallyAuthenticatedActionBuilder.async { request =>
require(pageRequest != null)
def findAll(maybeTag: Option[String],
maybeAuthor: Option[String],
maybeFavorited: Option[String],
maybeLimit: Option[Long],
maybeOffset: Option[Long]): Action[AnyContent] = optionallyAuthenticatedActionBuilder.async { request =>
validateNoMoreThanOneFilterIsGiven(maybeTag, maybeAuthor, maybeFavorited)

val pageRequest = buildPageRequest(maybeTag, maybeAuthor, maybeFavorited, maybeLimit, maybeOffset)
val maybeUserId = request.authenticatedUserOption.map(_.userId)
actionRunner.runTransactionally(articleReadService.findAll(pageRequest, maybeUserId))
.map(page => ArticlePage(page.models, page.count))
.map(Json.toJson(_))
.map(Ok(_))
}

def findFeed(pageRequest: UserFeedPageRequest): Action[AnyContent] = authenticatedAction.async { request =>
require(pageRequest != null)
private def buildPageRequest(maybeTag: Option[String], maybeAuthor: Option[String],
maybeFavorited: Option[String], maybeLimit: Option[Long],
maybeOffset: Option[Long]) = {
val limit = maybeLimit.getOrElse(defaultLimit)
val offset = maybeOffset.getOrElse(defaultOffset)
if (maybeTag.isDefined) {
ArticlesByTag(maybeTag.get, limit, offset)
} else if (maybeAuthor.isDefined) {
ArticlesByAuthor(maybeAuthor.map(Username(_)).get, limit, offset)
} else if (maybeFavorited.isDefined) {
ArticlesByFavorited(maybeFavorited.map(Username(_)).get, limit, offset)
} else {
ArticlesAll(limit, offset)
}
}

private def validateNoMoreThanOneFilterIsGiven(maybeTag: Option[String], maybeAuthor: Option[String], maybeFavorited: Option[String]) = {
val possibleFilters = List(maybeTag, maybeAuthor, maybeFavorited)
val filtersCount = possibleFilters.count(_.isDefined)
if (filtersCount >= 2) {
BadRequest("Can not use more than one filter at the time")
}
}

def findFeed(maybeLimit: Option[Long], maybeOffset: Option[Long]): Action[AnyContent] = authenticatedAction.async { request =>
val pageRequest: UserFeedPageRequest = buildPageRequest(maybeLimit, maybeOffset)
val userId = request.user.userId
actionRunner.runTransactionally(articleReadService.findFeed(pageRequest, userId))
.map(page => ArticlePage(page.models, page.count))
.map(Json.toJson(_))
.map(Ok(_))
}

private def buildPageRequest(maybeLimit: Option[Long], maybeOffset: Option[Long]) = {
val limit = maybeLimit.getOrElse(20L)
val offset = maybeOffset.getOrElse(0L)
val pageRequest = UserFeedPageRequest(limit, offset,
List(Ordering(ArticleMetaModel.createdAt, Descending)))
pageRequest
}

def create: Action[NewArticleWrapper] = authenticatedAction.async(validateJson[NewArticleWrapper]) { request =>
val article = request.body.article
val userId = request.user.userId
Expand Down Expand Up @@ -115,3 +153,8 @@ class ArticleController(authenticatedAction: AuthenticatedActionBuilder,
}

}

object ArticleController {
private lazy val defaultOffset = 0L
private lazy val defaultLimit = 20L
}
13 changes: 13 additions & 0 deletions app/articles/models/ArticlesPageRequest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package articles.models

import commons.models.Username

sealed trait ArticlesPageRequest {
def limit: Long
def offset: Long
}

case class ArticlesAll(limit: Long, offset: Long) extends ArticlesPageRequest
case class ArticlesByTag(tag: String, limit: Long, offset: Long) extends ArticlesPageRequest
case class ArticlesByAuthor(author: Username, limit: Long, offset: Long) extends ArticlesPageRequest
case class ArticlesByFavorited(favoritedBy: Username, limit: Long, offset: Long) extends ArticlesPageRequest
10 changes: 0 additions & 10 deletions app/articles/models/MainFeedPageRequest.scala

This file was deleted.

Loading

0 comments on commit 754a9b4

Please sign in to comment.