Skip to content

Commit

Permalink
Merge pull request #351 from NDLANO/podcast-friendly-filter
Browse files Browse the repository at this point in the history
Add param to filter podcastfriendly images
  • Loading branch information
gunnarvelle authored Dec 20, 2023
2 parents 8346d3e + de73014 commit f8bdfd3
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ trait BaseImageController {
"ids",
"Return only images that have one of the provided ids. To provide multiple ids, separate by comma (,)."
)
protected val podcastFriendly: Param[Option[Boolean]] =
Param[Option[Boolean]](
"podcast-friendly",
"Filter images that are podcast friendly. Width==heigth and between 1400 and 3000."
)

configureMultipartHandling(MultipartConfig(maxFileSize = Some(MaxImageFileSizeBytes.toLong)))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ trait ImageControllerV2 {
sort: Option[Sort],
pageSize: Option[Int],
page: Option[Int],
podcastFriendly: Option[Boolean],
includeCopyrighted: Boolean,
shouldScroll: Boolean,
modelReleasedStatus: Seq[ModelReleasedStatus.Value],
Expand All @@ -97,6 +98,7 @@ trait ImageControllerV2 {
sort = sort.getOrElse(Sort.ByRelevanceDesc),
page = page,
pageSize = pageSize,
podcastFriendly = podcastFriendly,
includeCopyrighted = includeCopyrighted,
shouldScroll = shouldScroll,
modelReleased = modelReleasedStatus
Expand All @@ -111,6 +113,7 @@ trait ImageControllerV2 {
sort = sort.getOrElse(Sort.ByTitleAsc),
page = page,
pageSize = pageSize,
podcastFriendly = podcastFriendly,
includeCopyrighted = includeCopyrighted,
shouldScroll = shouldScroll,
modelReleased = modelReleasedStatus
Expand Down Expand Up @@ -142,6 +145,7 @@ trait ImageControllerV2 {
asQueryParam(sort),
asQueryParam(pageNo),
asQueryParam(pageSize),
asQueryParam(podcastFriendly),
asQueryParam(scrollId),
asQueryParam(modelReleased)
)
Expand All @@ -159,6 +163,7 @@ trait ImageControllerV2 {
val license = params.get(this.license.paramName)
val pageSize = intOrNone(this.pageSize.paramName)
val page = intOrNone(this.pageNo.paramName)
val podcastFriendly = booleanOrNone(this.podcastFriendly.paramName)
val sort = Sort.valueOf(paramOrDefault(this.sort.paramName, ""))
val includeCopyrighted = booleanOrDefault(this.includeCopyrighted.paramName, default = false)
val shouldScroll = paramOrNone(this.scrollId.paramName).exists(InitialScrollContextKeywords.contains)
Expand All @@ -174,6 +179,7 @@ trait ImageControllerV2 {
sort,
pageSize,
page,
podcastFriendly,
includeCopyrighted,
shouldScroll,
modelReleasedStatus,
Expand Down Expand Up @@ -207,6 +213,7 @@ trait ImageControllerV2 {
val license = searchParams.license
val pageSize = searchParams.pageSize
val page = searchParams.page
val podcastFriendly = searchParams.podcastFriendly
val sort = Sort.valueOf(searchParams.sort)
val includeCopyrighted = searchParams.includeCopyrighted.getOrElse(false)
val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
Expand All @@ -222,6 +229,7 @@ trait ImageControllerV2 {
sort,
pageSize,
page,
podcastFriendly,
includeCopyrighted,
shouldScroll,
modelReleasedStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ trait ImageControllerV3 {
sort: Option[Sort],
pageSize: Option[Int],
page: Option[Int],
podcastFriendly: Option[Boolean],
includeCopyrighted: Boolean,
shouldScroll: Boolean,
modelReleasedStatus: Seq[ModelReleasedStatus.Value],
Expand All @@ -100,6 +101,7 @@ trait ImageControllerV3 {
sort = sort.getOrElse(Sort.ByRelevanceDesc),
page = page,
pageSize = pageSize,
podcastFriendly = podcastFriendly,
includeCopyrighted = includeCopyrighted,
shouldScroll = shouldScroll,
modelReleased = modelReleasedStatus
Expand All @@ -114,6 +116,7 @@ trait ImageControllerV3 {
sort = sort.getOrElse(Sort.ByTitleAsc),
page = page,
pageSize = pageSize,
podcastFriendly = podcastFriendly,
includeCopyrighted = includeCopyrighted,
shouldScroll = shouldScroll,
modelReleased = modelReleasedStatus
Expand Down Expand Up @@ -148,6 +151,7 @@ trait ImageControllerV3 {
asQueryParam(sort),
asQueryParam(pageNo),
asQueryParam(pageSize),
asQueryParam(podcastFriendly),
asQueryParam(scrollId),
asQueryParam(modelReleased)
)
Expand All @@ -166,6 +170,7 @@ trait ImageControllerV3 {
val pageSize = intOrNone(this.pageSize.paramName)
val page = intOrNone(this.pageNo.paramName)
val sort = Sort.valueOf(paramOrDefault(this.sort.paramName, ""))
val podcastFriendly = booleanOrNone(this.podcastFriendly.paramName)
val includeCopyrighted = booleanOrDefault(this.includeCopyrighted.paramName, default = false)
val shouldScroll = paramOrNone(this.scrollId.paramName).exists(InitialScrollContextKeywords.contains)
val modelReleasedStatus =
Expand All @@ -180,6 +185,7 @@ trait ImageControllerV3 {
sort,
pageSize,
page,
podcastFriendly,
includeCopyrighted,
shouldScroll,
modelReleasedStatus,
Expand Down Expand Up @@ -213,6 +219,7 @@ trait ImageControllerV3 {
val license = searchParams.license
val pageSize = searchParams.pageSize
val page = searchParams.page
val podcastFriendly = searchParams.podcastFriendly
val sort = Sort.valueOf(searchParams.sort)
val includeCopyrighted = searchParams.includeCopyrighted.getOrElse(false)
val shouldScroll = searchParams.scrollId.exists(InitialScrollContextKeywords.contains)
Expand All @@ -228,6 +235,7 @@ trait ImageControllerV3 {
sort,
pageSize,
page,
podcastFriendly,
includeCopyrighted,
shouldScroll,
modelReleasedStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ case class SearchParams(
@(ApiModelProperty @field)(description = """The sorting used on results. The following are supported: relevance, -relevance, title, -title, lastUpdated, -lastUpdated, id, -id. Default is by -relevance (desc) when query is set, and title (asc) when query is empty.""") sort: Option[String],
@(ApiModelProperty @field)(description = "The page number of the search hits to display.") page: Option[Int],
@(ApiModelProperty @field)(description = "The number of search hits to display for each page.") pageSize: Option[Int],
@(ApiModelProperty @field)(description = "Only show podcast friendly images.") podcastFriendly: Option[Boolean],
@(ApiModelProperty @field)(description = "A search context retrieved from the response header of a previous search.") scrollId: Option[String],
@(ApiModelProperty @field)(description = "Return only images with one of the provided values for modelReleased.") modelReleased: Option[Seq[String]]
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ case class SearchSettings(
sort: Sort,
page: Option[Int],
pageSize: Option[Int],
podcastFriendly: Option[Boolean],
includeCopyrighted: Boolean,
shouldScroll: Boolean,
modelReleased: Seq[ModelReleasedStatus.Value]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ case class SearchableImage(
modelReleased: Option[String],
editorNotes: Seq[String],
imageFiles: Seq[SearchableImageFile],
podcastFriendly: Boolean,
domainObject: ImageMetaInformation
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ trait ImageIndexService {
keywordField("defaultTitle"),
keywordField("modelReleased"),
textField("editorNotes"),
keywordField("podcastFriendly"),
nestedField("imageFiles").fields(
intField("imageSize"),
textField("previewUrl"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ trait ImageSearchService {
boolQuery().should(settings.modelReleased.map(mrs => termQuery("modelReleased", mrs.toString)))
)

val filters = List(languageFilter, licenseFilter, sizeFilter, modelReleasedFilter)
val podcastFilter = Option.when(settings.podcastFriendly.nonEmpty)(
boolQuery().should(settings.podcastFriendly.map(pf => termQuery("podcastFriendly", pf.toString)))
)

val filters = List(languageFilter, licenseFilter, sizeFilter, modelReleasedFilter, podcastFilter)
val filteredSearch = queryBuilder.filter(filters.flatten)

val (startAt, numResults) = getStartAtAndNumResults(settings.page, settings.pageSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ trait SearchConverterService {
)
)

def asSearchableImageFiles(images: Seq[ImageFileData]): Seq[SearchableImageFile] = {
private def asSearchableImageFiles(images: Seq[ImageFileData]): Seq[SearchableImageFile] = {
images.map(i => {
SearchableImageFile(
imageSize = i.size,
Expand Down Expand Up @@ -89,6 +89,9 @@ trait SearchConverterService {
modelReleased = Some(image.modelReleased.toString),
editorNotes = image.editorNotes.map(_.note),
imageFiles = asSearchableImageFiles(image.images),
podcastFriendly = image.images.exists(i =>
i.dimensions.exists(d => (d.height == d.width) && d.width <= 3000 && d.width >= 1400)
),
domainObject = image
)
}
Expand Down
25 changes: 13 additions & 12 deletions image-api/src/test/scala/no/ndla/imageapi/TestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trait TestData {

def updated(): NDLADate = NDLADate.of(2017, 4, 1, 12, 15, 32)

val ByNcSa = mapping.License.CC_BY_NC_SA.toString
val ByNcSa: String = mapping.License.CC_BY_NC_SA.toString

val elg = new ImageMetaInformation(
id = Some(1),
Expand Down Expand Up @@ -68,7 +68,7 @@ trait TestData {
editorNotes = Seq.empty
)

val apiElg = api.ImageMetaInformationV2(
val apiElg: ImageMetaInformationV2 = api.ImageMetaInformationV2(
"1",
"Elg.jpg",
api.ImageTitle("Elg i busk", "nb"),
Expand Down Expand Up @@ -100,7 +100,7 @@ trait TestData {
None
)

val apiBjorn = ImageMetaInformationV2(
val apiBjorn: ImageMetaInformationV2 = ImageMetaInformationV2(
id = "2",
metaUrl = "",
title = api.ImageTitle("Bjørn i busk", "nb"),
Expand Down Expand Up @@ -167,7 +167,7 @@ trait TestData {
editorNotes = Seq.empty
)

val jerv = new ImageMetaInformation(
val jerv: ImageMetaInformation = new ImageMetaInformation(
id = Some(3),
titles = List(ImageTitle("Jerv på stein", "nb")),
alttexts = List(ImageAltText("Elg i busk", "nb")),
Expand Down Expand Up @@ -272,7 +272,7 @@ trait TestData {
editorNotes = Seq.empty
)

val nonexisting = new ImageMetaInformation(
val nonexisting: ImageMetaInformation = new ImageMetaInformation(
id = Some(6),
titles = List(ImageTitle("Krokodille på krok", "nb")),
alttexts = List(ImageAltText("Elg i busk", "nb")),
Expand Down Expand Up @@ -342,7 +342,7 @@ trait TestData {
editorNotes = Seq.empty
)

val testdata = List(elg, bjorn, jerv, mink, rein)
val testdata: List[ImageMetaInformation] = List(elg, bjorn, jerv, mink, rein)

case class DiskImage(filename: String) extends ImageStream {
override def contentType: String = s"image/$format"
Expand All @@ -351,18 +351,18 @@ trait TestData {
override def fileName: String = filename

override lazy val sourceImage: BufferedImage = ImageIO.read(stream)
lazy val rawBytes = scala.io.Source.fromInputStream(stream).mkString
lazy val rawBytes: String = scala.io.Source.fromInputStream(stream).mkString
}

val NdlaLogoImage = DiskImage("ndla_logo.jpg")
val NdlaLogoGIFImage = DiskImage("ndla_logo.gif")
val CCLogoSvgImage = DiskImage("cc.svg")
val NdlaLogoImage: DiskImage = DiskImage("ndla_logo.jpg")
val NdlaLogoGIFImage: DiskImage = DiskImage("ndla_logo.gif")
val CCLogoSvgImage: DiskImage = DiskImage("cc.svg")

val ChildrensImage = DiskImage(
val ChildrensImage: DiskImage = DiskImage(
"children-drawing-582306_640.jpg"
) // From https://pixabay.com/en/children-drawing-home-tree-meadow-582306/

val searchSettings = SearchSettings(
val searchSettings: SearchSettings = SearchSettings(
query = None,
minimumSize = None,
language = "*",
Expand All @@ -371,6 +371,7 @@ trait TestData {
sort = Sort.ByIdAsc,
page = None,
pageSize = None,
podcastFriendly = None,
includeCopyrighted = false,
shouldScroll = false,
modelReleased = Seq.empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class ImageSearchServiceTest

val largeImage: ImageFileData = ImageFileData(1, "large-full-url", 10000, "jpg", None, "und", 4)
val smallImage: ImageFileData = ImageFileData(2, "small-full-url", 100, "jpg", None, "und", 6)
val podcastImage: ImageFileData =
ImageFileData(3, "podcast-full-url", 100, "jpg", Some(ImageDimensions(width = 1400, height = 1400)), "und", 6)

val byNcSa: Copyright = Copyright(
CC_BY_NC_SA.toString,
Expand Down Expand Up @@ -157,7 +159,7 @@ class ImageSearchServiceTest
ImageTitle("Nynoreg", "nn")
),
alttexts = Seq(ImageAltText("urelatert alttext", "und"), ImageAltText("Nynoreg", "nn")),
images = Seq(smallImage),
images = Seq(podcastImage),
copyright = byNcSa,
tags = Seq(),
captions = Seq(),
Expand Down Expand Up @@ -628,4 +630,16 @@ class ImageSearchServiceTest
searchResult2.results.head.title.title should equal("This is a unrelated photo")
searchResult2.results.head.title.language should equal("en")
}

test("That filtering for podcast-friendly works as expected") {
val Success(searchResult1) = imageSearchService.matchingQuery(
searchSettings.copy(
language = "*",
podcastFriendly = Some(true)
),
None
)

searchResult1.results.map(_.id) should be(Seq("5"))
}
}

0 comments on commit f8bdfd3

Please sign in to comment.