Skip to content

Commit

Permalink
Introduce /api/rules/csv-import endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyford committed Jul 23, 2024
1 parent 3ac5799 commit 707581a
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
20 changes: 20 additions & 0 deletions apps/rule-manager/app/controllers/RulesController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,24 @@ class RulesController(
case Left(error) => BadRequest(s"Invalid request: $error")
}
}

def csvImport() = Action { implicit request =>
val rules = for {
formData <- request.body.asMultipartFormData.toRight("No form data found in request")
file <- formData.file("file").toRight("No file found in request")
tag = formData.dataParts.get("tag") match {
case Some(tag) => tag.head
case None => ""
}
} yield RuleManager.csvImport(
file.ref.path.toFile,
tag,
bucketRuleResource
)

rules match {
case Right(int) => Ok(Json.toJson(int))
case Left(message) => BadRequest(message)
}
}
}
2 changes: 1 addition & 1 deletion apps/rule-manager/app/db/DbRuleDraft.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ case class DbRuleDraft(
id match {
case None =>
throw new Exception(
s"Attempted to make live rule for rule with externalId $externalId, but the rule did not have an id"
s"Attempted to make live rule for rule with externalId ${externalId}, but the rule did not have an id"
)
case Some(_) =>
DbRuleLive(
Expand Down
45 changes: 45 additions & 0 deletions apps/rule-manager/app/service/RuleManager.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import model.{DictionaryForm, LTRuleCoreForm, LTRuleXMLForm, PaginatedResponse,
import play.api.data.FormError
import play.api.libs.json.{Json, OWrites}
import scalikejdbc.DBSession
import com.github.tototoshi.csv.CSVReader
import java.io.File

object AllRuleData {
implicit val writes: OWrites[AllRuleData] = Json.writes[AllRuleData]
Expand All @@ -32,6 +34,49 @@ case class AllRuleData(
)

object RuleManager extends Loggable {
def csvImport(toFile: File, tagName: String, bucketRuleResource: BucketRuleResource) = {
val reader = CSVReader.open(toFile)
val rules = reader.all()

val initialRuleOrder = DbRuleDraft.getLatestRuleOrder() + 1

val draftRules = rules.zipWithIndex.map { case (rule, index) =>
val pattern = rule(0)
val replacement = rule(1)
val description = rule(2)

DbRuleDraft.withUser(
id = None,
ruleType = RuleType.regex,
pattern = Some(pattern),
category = Some("Imported from CSV"),
description = Some(description),
ignore = false,
replacement = Some(replacement),
user = "CSV Import",
ruleOrder = initialRuleOrder + index
)
}
val ruleIds = DbRuleDraft.batchInsert(draftRules, true)

// Apply tag
val allTags = Tags.findAll()
allTags.find(tag => tag.name == tagName).map(_.id) match {
case Some(tagId) =>
RuleTagDraft.batchInsert(ruleIds.map(id => RuleTagDraft(id, tagId.getOrElse(-1))))
case None => log.error(s"Tag $tagName not found")
}

val rulesWithIds = DbRuleDraft.findRules(ruleIds)
val liveRulesWithIds = rulesWithIds.map(_.toLive("Imported from CSV", true))

DbRuleLive.batchInsert(liveRulesWithIds)

publishLiveRules(bucketRuleResource)

liveRulesWithIds.size
}

object RuleType {
val regex = "regex"
val languageToolXML = "languageToolXML"
Expand Down
2 changes: 2 additions & 0 deletions apps/rule-manager/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ GET /api/rules/batch/:ids controllers.RulesController.getRules(ids
+nocsrf
POST /api/rules/batch controllers.RulesController.batchUpdate()
+nocsrf
POST /api/rules/csv-import controllers.RulesController.csvImport()
+nocsrf
GET /api/rules/:id controllers.RulesController.get(id: Int)
+nocsrf
POST /api/rules/:id controllers.RulesController.update(id: Int)
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ val ruleManager = playProject(
"org.scalikejdbc" %% "scalikejdbc-test" % scalikejdbcVersion % Test,
"org.scalikejdbc" %% "scalikejdbc-syntax-support-macro" % scalikejdbcVersion,
"com.gu" %% "editorial-permissions-client" % "2.14",
"com.github.tototoshi" %% "scala-csv" % "2.0.0",
),
libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
)
Expand Down

0 comments on commit 707581a

Please sign in to comment.