Skip to content

Commit

Permalink
Merge pull request #568 from NDLANO/set-hide-byline-for-images
Browse files Browse the repository at this point in the history
Sett hidebyline på bilder i artikler som ikkje er copyrighta
  • Loading branch information
gunnarvelle authored Jan 2, 2025
2 parents 0c48c7e + decb497 commit f3f6a4c
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import no.ndla.articleapi.db.migrationwithdependencies.{
V20__UpdateH5PDomainForFF,
V22__UpdateH5PDomainForFFVisualElement,
V33__ConvertLanguageUnknown,
V55__SetHideBylineForImagesNotCopyrighted,
V8__CopyrightFormatUpdated,
V9__TranslateUntranslatedAuthors
}
Expand Down Expand Up @@ -65,7 +66,9 @@ class ComponentRegistry(properties: ArticleApiProperties)
with DBArticle
with DBMigrator
with SwaggerDocControllerConfig
with FrontpageApiClient {
with FrontpageApiClient
with ImageApiClient
with V55__SetHideBylineForImagesNotCopyrighted {
override val props: ArticleApiProperties = properties
override val migrator: DBMigrator = DBMigrator(
new R__SetArticleLanguageFromTaxonomy(props),
Expand All @@ -74,7 +77,8 @@ class ComponentRegistry(properties: ArticleApiProperties)
new V9__TranslateUntranslatedAuthors,
new V20__UpdateH5PDomainForFF,
new V22__UpdateH5PDomainForFFVisualElement,
new V33__ConvertLanguageUnknown(props)
new V33__ConvertLanguageUnknown(props),
new V55__SetHideBylineForImagesNotCopyrighted
)

override val dataSource: HikariDataSource = DataSource.getHikariDataSource
Expand Down Expand Up @@ -102,6 +106,7 @@ class ComponentRegistry(properties: ArticleApiProperties)
lazy val myndlaApiClient = new MyNDLAApiClient
lazy val redisClient = new RedisClient(props.RedisHost, props.RedisPort)
lazy val frontpageApiClient = new FrontpageApiClient
lazy val imageApiClient = new ImageApiClient

lazy val clock = new SystemClock

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package no.ndla.articleapi.db.migrationwithdependencies

import no.ndla.articleapi.Props
import no.ndla.articleapi.db.HtmlMigration
import no.ndla.articleapi.integration.ImageApiClient
import no.ndla.network.NdlaClient
import org.jsoup.nodes.Element

trait V55__SetHideBylineForImagesNotCopyrighted {
this: ImageApiClient & NdlaClient & Props =>

class V55__SetHideBylineForImagesNotCopyrighted extends HtmlMigration {
override val tableName: String = "contentdata"
override val columnName: String = "document"

/** Method to override that manipulates the content string */
override def convertHtml(doc: Element, language: String): Element = {
val ids = List.newBuilder[String]
doc
.select("ndlaembed[data-resource='image']")
.forEach(embed => {
val noHideByline = !embed.hasAttr("data-hide-byline")
if (noHideByline) {
ids += embed.attr("data-resource_id")
}
})
if (ids.result().isEmpty) {
return doc
}
val images = imageApiClient.getImagesWithIds(ids.result()).getOrElse(List.empty)
doc
.select("ndlaembed[data-resource='image']")
.forEach(embed => {
val imageId = embed.attr("data-resource_id")
val image = images.find(i => i.id == imageId)
embed
.attr("data-hide-byline", s"${image.exists(i => !i.copyright.license.license.equals("COPYRIGHTED"))}"): Unit
})
doc
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Part of NDLA article-api
* Copyright (C) 2018 NDLA
*
* See LICENSE
*/

package no.ndla.articleapi.integration

import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.articleapi.Props
import no.ndla.articleapi.service.ConverterService
import no.ndla.common.model.api.CopyrightDTO
import no.ndla.network.NdlaClient
import sttp.client3.quick.*

import scala.util.Try

trait ImageApiClient {
this: NdlaClient & ConverterService & Props =>
val imageApiClient: ImageApiClient

class ImageApiClient {
private val Endpoint = s"http://${props.ImageApiHost}/image-api/v3/images"

def getImagesWithIds(ids: Seq[String]): Try[Seq[ImageWithCopyright]] = {
val idsParam = ids.mkString(",")
get[Seq[ImageWithCopyright]](s"$Endpoint/ids", "ids" -> idsParam)
}

private def get[A: Decoder](endpointUrl: String, params: (String, String)*): Try[A] = {
val request = quickRequest.get(uri"$endpointUrl".withParams(params*))
ndlaClient.fetch[A](request)
}

}
}
case class ImageWithCopyright(id: String, copyright: CopyrightDTO)

object ImageWithCopyright {
implicit val encoder: Encoder[ImageWithCopyright] = deriveEncoder
implicit val decoder: Decoder[ImageWithCopyright] = deriveDecoder
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ trait TestEnvironment
with Props
with TestData
with DBMigrator
with FrontpageApiClient {
with FrontpageApiClient
with ImageApiClient {
val props: ArticleApiProperties = new ArticleApiProperties {
override def InlineHtmlTags: Set[String] = Set("code", "em", "span", "strong", "sub", "sup")
override def IntroductionHtmlTags: Set[String] = InlineHtmlTags ++ Set("br", "p")
Expand Down Expand Up @@ -88,6 +89,7 @@ trait TestEnvironment
val feideApiClient: FeideApiClient = mock[FeideApiClient]
val redisClient: RedisClient = mock[RedisClient]
val frontpageApiClient: FrontpageApiClient = mock[FrontpageApiClient]
val imageApiClient: ImageApiClient = mock[ImageApiClient]

val clock: SystemClock = mock[SystemClock]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import no.ndla.draftapi.db.migrationwithdependencies.{
V20__UpdateH5PDomainForFF,
V23__UpdateH5PDomainForFFVisualElement,
V33__ConvertLanguageUnknown,
V57__MigrateSavedSearch
V57__MigrateSavedSearch,
V66__SetHideBylineForImagesNotCopyrighted
}
import no.ndla.draftapi.integration.*
import no.ndla.draftapi.model.api.ErrorHandling
Expand Down Expand Up @@ -73,12 +74,14 @@ class ComponentRegistry(properties: DraftApiProperties)
with ArticleApiClient
with SearchApiClient
with H5PApiClient
with ImageApiClient
with UserDataController
with Props
with DBMigrator
with ErrorHandling
with SwaggerDocControllerConfig
with V57__MigrateSavedSearch {
with V57__MigrateSavedSearch
with V66__SetHideBylineForImagesNotCopyrighted {
override val props: DraftApiProperties = properties
override val migrator: DBMigrator = DBMigrator(
new R__RemoveEmptyStringLanguageFields(props),
Expand All @@ -88,7 +91,8 @@ class ComponentRegistry(properties: DraftApiProperties)
new V20__UpdateH5PDomainForFF,
new V23__UpdateH5PDomainForFFVisualElement,
new V33__ConvertLanguageUnknown(props),
new V57__MigrateSavedSearch
new V57__MigrateSavedSearch,
new V66__SetHideBylineForImagesNotCopyrighted
)
override val dataSource: HikariDataSource = DataSource.getHikariDataSource
DataSource.connectToDatabase()
Expand Down Expand Up @@ -128,6 +132,7 @@ class ComponentRegistry(properties: DraftApiProperties)
lazy val taxonomyApiClient = new TaxonomyApiClient
lazy val learningpathApiClient = new LearningpathApiClient
lazy val h5pApiClient = new H5PApiClient
lazy val imageApiClient = new ImageApiClient

lazy val internController = new InternController
lazy val draftController = new DraftController
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Part of NDLA draft-api
* Copyright (C) 2024 NDLA
*
* See LICENSE
*/

package no.ndla.draftapi.db.migrationwithdependencies

import no.ndla.draftapi.Props
import no.ndla.draftapi.db.HtmlMigration
import no.ndla.draftapi.integration.ImageApiClient
import no.ndla.network.NdlaClient
import org.jsoup.nodes.Element
import scalikejdbc.{SQLSyntax, scalikejdbcSQLInterpolationImplicitDef}

trait V66__SetHideBylineForImagesNotCopyrighted {
this: ImageApiClient & NdlaClient & Props =>

class V66__SetHideBylineForImagesNotCopyrighted extends HtmlMigration {
override val tableName: String = "articledata a"
override val columnName: String = "document"
private lazy val columnNameSQL: SQLSyntax = SQLSyntax.createUnsafely(columnName)

override lazy val whereClause: SQLSyntax =
sqls"$columnNameSQL is not null and $columnNameSQL -> 'status' ->> 'current' != 'ARCHIVED' and $columnNameSQL -> 'status' ->> 'current' != 'UNPUBLISHED' and revision = (select max(revision) from articledata a2 where a2.article_id = a.article_id)"

/** Method to override that manipulates the content string */
override def convertHtml(doc: Element, language: String): Element = {
val ids = List.newBuilder[String]
doc
.select("ndlaembed[data-resource='image']")
.forEach(embed => {
val noHideByline = !embed.hasAttr("data-hide-byline")
if (noHideByline) {
ids += embed.attr("data-resource_id")
}
})
if (ids.result().isEmpty) {
return doc
}
val images = imageApiClient.getImagesWithIds(ids.result()).getOrElse(List.empty)
doc
.select("ndlaembed[data-resource='image']")
.forEach(embed => {
val imageId = embed.attr("data-resource_id")
val image = images.find(i => i.id == imageId)
embed
.attr("data-hide-byline", s"${image.exists(i => !i.copyright.license.license.equals("COPYRIGHTED"))}"): Unit
})
doc
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Part of NDLA draft-api
* Copyright (C) 2018 NDLA
*
* See LICENSE
*/

package no.ndla.draftapi.integration

import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}
import no.ndla.common.model.api.CopyrightDTO
import no.ndla.draftapi.Props
import no.ndla.draftapi.service.ConverterService
import no.ndla.network.NdlaClient
import sttp.client3.quick.*

import scala.util.Try

trait ImageApiClient {
this: NdlaClient & ConverterService & Props =>
val imageApiClient: ImageApiClient

class ImageApiClient {
private val Endpoint = s"http://${props.ImageApiHost}/image-api/v3/images"

def getImagesWithIds(ids: Seq[String]): Try[Seq[ImageWithCopyright]] = {
val idsParam = ids.mkString(",")
get[Seq[ImageWithCopyright]](s"$Endpoint/ids", "ids" -> idsParam)
}

private def get[A: Decoder](endpointUrl: String, params: (String, String)*): Try[A] = {
val request = quickRequest.get(uri"$endpointUrl".withParams(params*))
ndlaClient.fetch[A](request)
}

}
}
case class ImageWithCopyright(id: String, copyright: CopyrightDTO)

object ImageWithCopyright {
implicit val encoder: Encoder[ImageWithCopyright] = deriveEncoder
implicit val decoder: Decoder[ImageWithCopyright] = deriveDecoder
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ trait TestEnvironment
val searchApiClient: SearchApiClient = mock[SearchApiClient]
val taxonomyApiClient: TaxonomyApiClient = mock[TaxonomyApiClient]
val h5pApiClient: H5PApiClient = mock[H5PApiClient]
val imageApiClient: ImageApiClient = mock[ImageApiClient]

def services: List[TapirController] = List.empty
}

0 comments on commit f3f6a4c

Please sign in to comment.