From c41cdeefec654c631ca6fcab8440b38c4329cf68 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Mon, 4 May 2020 23:52:53 +0200 Subject: [PATCH] Update scalafmt to 2.5.1 + scalafmtAll --- .scalafmt.conf | 5 +- .../docspell/analysis/TextAnalyser.scala | 7 +- .../scala/docspell/backend/auth/Login.scala | 5 +- .../docspell/backend/ops/OCollective.scala | 9 ++- .../scala/docspell/backend/ops/OItem.scala | 12 ++-- .../scala/docspell/backend/ops/OUpload.scala | 25 ++++--- .../docspell/backend/ops/OUserTask.scala | 8 +-- .../docspell/backend/signup/OSignup.scala | 27 ++++---- .../backend/signup/SignupResult.scala | 11 ++-- .../main/scala/docspell/common/Binary.scala | 12 ++-- .../docspell/common/CollectiveState.scala | 13 ++-- .../src/main/scala/docspell/common/File.scala | 47 +++++++------- .../main/scala/docspell/common/Ident.scala | 13 ++-- .../scala/docspell/common/LenientUri.scala | 32 ++++----- .../main/scala/docspell/common/Logger.scala | 29 +++++---- .../scala/docspell/common/SystemCommand.scala | 23 ++++--- .../scala/docspell/common/UserState.scala | 9 +-- .../docspell/common/syntax/EitherSyntax.scala | 18 ++--- .../docspell/common/syntax/StreamSyntax.scala | 7 +- .../scala/docspell/convert/Conversion.scala | 5 +- .../docspell/convert/extern/ExternConv.scala | 5 +- .../convert/extern/ExternConvTest.scala | 9 +-- .../scala/docspell/extract/Extraction.scala | 5 +- .../scala/docspell/extract/PdfExtract.scala | 9 ++- .../scala/docspell/files/TikaMimetype.scala | 15 +++-- .../test/scala/docspell/files/Playing.scala | 32 ++++----- .../main/scala/docspell/joex/JoexServer.scala | 5 +- .../src/main/scala/docspell/joex/Main.scala | 3 +- .../docspell/joex/hk/CleanupInvitesTask.scala | 5 +- .../docspell/joex/hk/CleanupJobsTask.scala | 5 +- .../joex/notify/NotifyDueItemsTask.scala | 21 +++--- .../docspell/joex/process/CreateItem.scala | 24 +++---- .../docspell/joex/process/EvalProposals.scala | 6 +- .../docspell/joex/process/FindProposal.scala | 10 +-- .../docspell/joex/process/TextAnalysis.scala | 7 +- .../docspell/joex/scheduler/JobTask.scala | 4 +- .../joex/scheduler/SchedulerImpl.scala | 24 +++---- .../scala/docspell/joex/scheduler/Task.scala | 4 +- .../main/scala/docspell/restserver/Main.scala | 3 +- .../docspell/restserver/RestServer.scala | 5 +- .../docspell/restserver/auth/CookieData.scala | 7 +- .../restserver/conv/Conversions.scala | 53 ++++++++------- .../restserver/http4s/ResponseGenerator.scala | 4 +- .../restserver/routes/AttachmentRoutes.scala | 65 ++++++++++--------- .../restserver/routes/CollectiveRoutes.scala | 16 +++-- .../restserver/routes/ItemRoutes.scala | 7 +- .../restserver/routes/MailSendRoutes.scala | 5 +- .../routes/NotifyDueItemsRoutes.scala | 29 +++++---- .../routes/OrganizationRoutes.scala | 5 +- .../restserver/routes/PersonRoutes.scala | 5 +- .../restserver/routes/RegisterRoutes.scala | 44 +++++++------ .../restserver/webapp/TemplateRoutes.scala | 12 ++-- .../scala/docspell/store/impl/Column.scala | 9 +-- .../store/migrate/FlywayMigrate.scala | 47 +++++++------- .../docspell/store/queries/QAttachment.scala | 37 ++++++----- .../docspell/store/queries/QCollective.scala | 4 +- .../scala/docspell/store/queries/QItem.scala | 4 +- .../scala/docspell/store/queries/QJob.scala | 12 ++-- .../store/queue/PeriodicTaskStore.scala | 13 ++-- .../docspell/store/records/RAttachment.scala | 6 +- .../store/records/RAttachmentArchive.scala | 6 +- .../store/records/RAttachmentMeta.scala | 6 +- .../docspell/store/records/RJobLog.scala | 6 +- .../scala/docspell/store/records/RNode.scala | 6 +- .../store/usertask/UserTaskStore.scala | 28 ++++---- 65 files changed, 523 insertions(+), 431 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index ccaa37ac..0f646238 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,7 +1,6 @@ -version = "2.4.2" +version = "2.5.1" -align = more -#align.arrowEnumeratorGenerator = true +preset = defaultWithAlign maxColumn = 90 diff --git a/modules/analysis/src/main/scala/docspell/analysis/TextAnalyser.scala b/modules/analysis/src/main/scala/docspell/analysis/TextAnalyser.scala index 881dbe23..53e14235 100644 --- a/modules/analysis/src/main/scala/docspell/analysis/TextAnalyser.scala +++ b/modules/analysis/src/main/scala/docspell/analysis/TextAnalyser.scala @@ -49,9 +49,10 @@ object TextAnalyser { StanfordNerClassifier.nerAnnotate(lang)(text) } - private def contactNer(text: String): F[Vector[NerLabel]] = Sync[F].delay { - Contact.annotate(text) - } + private def contactNer(text: String): F[Vector[NerLabel]] = + Sync[F].delay { + Contact.annotate(text) + } private def dateNer(lang: Language, text: String): F[Vector[NerDateLabel]] = Sync[F].delay { diff --git a/modules/backend/src/main/scala/docspell/backend/auth/Login.scala b/modules/backend/src/main/scala/docspell/backend/auth/Login.scala index 5415346d..38fd4ada 100644 --- a/modules/backend/src/main/scala/docspell/backend/auth/Login.scala +++ b/modules/backend/src/main/scala/docspell/backend/auth/Login.scala @@ -71,8 +71,9 @@ object Login { for { data <- store.transact(QLogin.findUser(acc)) _ <- Sync[F].delay(logger.trace(s"Account lookup: $data")) - res <- if (data.exists(check(up.pass))) okResult - else Result.invalidAuth.pure[F] + res <- + if (data.exists(check(up.pass))) okResult + else Result.invalidAuth.pure[F] } yield res case Left(_) => Result.invalidAuth.pure[F] diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OCollective.scala b/modules/backend/src/main/scala/docspell/backend/ops/OCollective.scala index a77151d9..1e41db96 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OCollective.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OCollective.scala @@ -117,9 +117,12 @@ object OCollective { val q = for { optUser <- RUser.findByAccount(accountId) check = optUser.map(_.password).map(p => PasswordCrypt.check(current, p)) - n <- check - .filter(identity) - .traverse(_ => RUser.updatePassword(accountId, PasswordCrypt.crypt(newPass))) + n <- + check + .filter(identity) + .traverse(_ => + RUser.updatePassword(accountId, PasswordCrypt.crypt(newPass)) + ) res = check match { case Some(true) => if (n.getOrElse(0) > 0) PassChangeResult.success diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala b/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala index 5361fb5f..3668e778 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala @@ -199,11 +199,13 @@ object OItem { def setTags(item: Ident, tagIds: List[Ident], collective: Ident): F[AddResult] = { val db = for { cid <- RItem.getCollective(item) - nd <- if (cid.contains(collective)) RTagItem.deleteItemTags(item) - else 0.pure[ConnectionIO] - ni <- if (tagIds.nonEmpty && cid.contains(collective)) - RTagItem.insertItemTags(item, tagIds) - else 0.pure[ConnectionIO] + nd <- + if (cid.contains(collective)) RTagItem.deleteItemTags(item) + else 0.pure[ConnectionIO] + ni <- + if (tagIds.nonEmpty && cid.contains(collective)) + RTagItem.insertItemTags(item, tagIds) + else 0.pure[ConnectionIO] } yield nd + ni store.transact(db).attempt.map(AddResult.fromUpdate) diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OUpload.scala b/modules/backend/src/main/scala/docspell/backend/ops/OUpload.scala index 71671d63..a99fd305 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OUpload.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OUpload.scala @@ -72,8 +72,9 @@ object OUpload { data.meta.sourceAbbrev, data.meta.validFileTypes ) - args = if (data.multiple) files.map(f => ProcessItemArgs(meta, List(f))) - else Vector(ProcessItemArgs(meta, files.toList)) + args = + if (data.multiple) files.map(f => ProcessItemArgs(meta, List(f))) + else Vector(ProcessItemArgs(meta, files.toList)) job <- pred.traverse(_ => makeJobs(args, account, data.priority, data.tracker)) _ <- logger.fdebug(s"Storing jobs: $job") res <- job.traverse(submitJobs) @@ -84,9 +85,10 @@ object OUpload { def submit(data: OUpload.UploadData[F], sourceId: Ident): F[OUpload.UploadResult] = for { - sOpt <- store - .transact(RSource.find(sourceId)) - .map(_.toRight(UploadResult.NoSource)) + sOpt <- + store + .transact(RSource.find(sourceId)) + .map(_.toRight(UploadResult.NoSource)) abbrev = sOpt.map(_.abbrev).toOption.getOrElse(data.meta.sourceAbbrev) updata = data.copy(meta = data.meta.copy(sourceAbbrev = abbrev)) accId = sOpt.map(source => AccountId(source.cid, source.sid)) @@ -108,10 +110,15 @@ object OUpload { .lastOrError .map(fm => Ident.unsafe(fm.id)) .attempt - .map(_.fold(ex => { - logger.warn(ex)(s"Could not store file for processing!") - None - }, id => Some(ProcessItemArgs.File(file.name, id)))) + .map( + _.fold( + ex => { + logger.warn(ex)(s"Could not store file for processing!") + None + }, + id => Some(ProcessItemArgs.File(file.name, id)) + ) + ) private def checkFileList( files: Seq[ProcessItemArgs.File] diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OUserTask.scala b/modules/backend/src/main/scala/docspell/backend/ops/OUserTask.scala index dc8917d8..d002d654 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OUserTask.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OUserTask.scala @@ -27,8 +27,8 @@ trait OUserTask[F[_]] { * executor's queue. It will not update the corresponding periodic * task. */ - def executeNow[A](account: AccountId, task: UserTask[A])( - implicit E: Encoder[A] + def executeNow[A](account: AccountId, task: UserTask[A])(implicit + E: Encoder[A] ): F[Unit] } @@ -41,8 +41,8 @@ object OUserTask { ): Resource[F, OUserTask[F]] = Resource.pure[F, OUserTask[F]](new OUserTask[F] { - def executeNow[A](account: AccountId, task: UserTask[A])( - implicit E: Encoder[A] + def executeNow[A](account: AccountId, task: UserTask[A])(implicit + E: Encoder[A] ): F[Unit] = for { ptask <- task.encode.toPeriodicTask(account) diff --git a/modules/backend/src/main/scala/docspell/backend/signup/OSignup.scala b/modules/backend/src/main/scala/docspell/backend/signup/OSignup.scala index 4f9037b6..4b09318d 100644 --- a/modules/backend/src/main/scala/docspell/backend/signup/OSignup.scala +++ b/modules/backend/src/main/scala/docspell/backend/signup/OSignup.scala @@ -25,16 +25,15 @@ object OSignup { Resource.pure[F, OSignup[F]](new OSignup[F] { def newInvite(cfg: Config)(password: Password): F[NewInviteResult] = - if (cfg.mode == Config.Mode.Invite) { + if (cfg.mode == Config.Mode.Invite) if (cfg.newInvitePassword.isEmpty || cfg.newInvitePassword != password) NewInviteResult.passwordMismatch.pure[F] else store .transact(RInvitation.insertNew) .map(ri => NewInviteResult.success(ri.id)) - } else { + else Effect[F].pure(NewInviteResult.invitationClosed) - } def register(cfg: Config)(data: RegisterData): F[SignupResult] = cfg.mode match { @@ -51,15 +50,19 @@ object OSignup { now <- Timestamp.current[F] min = now.minus(cfg.inviteTime) ok <- store.transact(RInvitation.useInvite(inv, min)) - res <- if (ok) addUser(data).map(SignupResult.fromAddResult) - else SignupResult.invalidInvitationKey.pure[F] - _ <- if (retryInvite(res)) - logger - .fdebug(s"Adding account failed ($res). Allow retry with invite.") *> store - .transact( - RInvitation.insert(RInvitation(inv, now)) - ) - else 0.pure[F] + res <- + if (ok) addUser(data).map(SignupResult.fromAddResult) + else SignupResult.invalidInvitationKey.pure[F] + _ <- + if (retryInvite(res)) + logger + .fdebug( + s"Adding account failed ($res). Allow retry with invite." + ) *> store + .transact( + RInvitation.insert(RInvitation(inv, now)) + ) + else 0.pure[F] } yield res case None => SignupResult.invalidInvitationKey.pure[F] diff --git a/modules/backend/src/main/scala/docspell/backend/signup/SignupResult.scala b/modules/backend/src/main/scala/docspell/backend/signup/SignupResult.scala index 15782324..585cf296 100644 --- a/modules/backend/src/main/scala/docspell/backend/signup/SignupResult.scala +++ b/modules/backend/src/main/scala/docspell/backend/signup/SignupResult.scala @@ -18,9 +18,10 @@ object SignupResult { def failure(ex: Throwable): SignupResult = Failure(ex) def success: SignupResult = Success - def fromAddResult(ar: AddResult): SignupResult = ar match { - case AddResult.Success => Success - case AddResult.Failure(ex) => Failure(ex) - case AddResult.EntityExists(_) => CollectiveExists - } + def fromAddResult(ar: AddResult): SignupResult = + ar match { + case AddResult.Success => Success + case AddResult.Failure(ex) => Failure(ex) + case AddResult.EntityExists(_) => CollectiveExists + } } diff --git a/modules/common/src/main/scala/docspell/common/Binary.scala b/modules/common/src/main/scala/docspell/common/Binary.scala index 14237a1c..f45c28a2 100644 --- a/modules/common/src/main/scala/docspell/common/Binary.scala +++ b/modules/common/src/main/scala/docspell/common/Binary.scala @@ -37,11 +37,10 @@ object Binary { Binary(name, MimeType.html.withCharset(cs), Stream.chunk(Chunk.byteVector(content))) def decode[F[_]](cs: Charset): Pipe[F, Byte, String] = - if (cs == StandardCharsets.UTF_8) { + if (cs == StandardCharsets.UTF_8) fs2.text.utf8Decode - } else { + else util.decode[F](cs) - } def loadAllBytes[F[_]: Sync](data: Stream[F, Byte]): F[ByteVector] = data.chunks.map(_.toByteVector).compile.fold(ByteVector.empty)((r, e) => r ++ e) @@ -78,17 +77,16 @@ object Binary { decoder.decode(byteBuffer, charBuffer, false) val nextStream = stream.consChunk(Chunk.byteBuffer(byteBuffer.slice())) Pull.output1(charBuffer.flip().toString).as(Some(nextStream)) - } else { + } else Pull.output(Chunk.empty[String]).as(Some(stream)) - } } } } private def skipByteOrderMark[F[_]](chunk: Chunk[Byte]): Chunk[Byte] = - if (chunk.size >= 3 && chunk.take(3) == utf8Bom) { + if (chunk.size >= 3 && chunk.take(3) == utf8Bom) chunk.drop(3) - } else chunk + else chunk } } diff --git a/modules/common/src/main/scala/docspell/common/CollectiveState.scala b/modules/common/src/main/scala/docspell/common/CollectiveState.scala index 35dfa40e..a6e6e006 100644 --- a/modules/common/src/main/scala/docspell/common/CollectiveState.scala +++ b/modules/common/src/main/scala/docspell/common/CollectiveState.scala @@ -33,12 +33,13 @@ object CollectiveState { def unsafe(str: String): CollectiveState = fromString(str).fold(sys.error, identity) - def asString(state: CollectiveState): String = state match { - case Active => "active" - case Blocked => "blocked" - case Closed => "closed" - case ReadOnly => "readonly" - } + def asString(state: CollectiveState): String = + state match { + case Active => "active" + case Blocked => "blocked" + case Closed => "closed" + case ReadOnly => "readonly" + } implicit val collectiveStateEncoder: Encoder[CollectiveState] = Encoder.encodeString.contramap(CollectiveState.asString) diff --git a/modules/common/src/main/scala/docspell/common/File.scala b/modules/common/src/main/scala/docspell/common/File.scala index 5772c897..c20f35ef 100644 --- a/modules/common/src/main/scala/docspell/common/File.scala +++ b/modules/common/src/main/scala/docspell/common/File.scala @@ -25,30 +25,31 @@ object File { ): F[Path] = mkDir(parent).map(p => Files.createTempFile(p, prefix, suffix.orNull)) - def deleteDirectory[F[_]: Sync](dir: Path): F[Int] = Sync[F].delay { - val count = new AtomicInteger(0) - Files.walkFileTree( - dir, - new SimpleFileVisitor[Path]() { - override def visitFile( - file: Path, - attrs: BasicFileAttributes - ): FileVisitResult = { - Files.deleteIfExists(file) - count.incrementAndGet() - FileVisitResult.CONTINUE - } - override def postVisitDirectory(dir: Path, e: IOException): FileVisitResult = - Option(e) match { - case Some(ex) => throw ex - case None => - Files.deleteIfExists(dir) - FileVisitResult.CONTINUE + def deleteDirectory[F[_]: Sync](dir: Path): F[Int] = + Sync[F].delay { + val count = new AtomicInteger(0) + Files.walkFileTree( + dir, + new SimpleFileVisitor[Path]() { + override def visitFile( + file: Path, + attrs: BasicFileAttributes + ): FileVisitResult = { + Files.deleteIfExists(file) + count.incrementAndGet() + FileVisitResult.CONTINUE } - } - ) - count.get - } + override def postVisitDirectory(dir: Path, e: IOException): FileVisitResult = + Option(e) match { + case Some(ex) => throw ex + case None => + Files.deleteIfExists(dir) + FileVisitResult.CONTINUE + } + } + ) + count.get + } def exists[F[_]: Sync](file: Path): F[Boolean] = Sync[F].delay(Files.exists(file)) diff --git a/modules/common/src/main/scala/docspell/common/Ident.scala b/modules/common/src/main/scala/docspell/common/Ident.scala index 6314dffc..49577fac 100644 --- a/modules/common/src/main/scala/docspell/common/Ident.scala +++ b/modules/common/src/main/scala/docspell/common/Ident.scala @@ -20,12 +20,13 @@ object Ident { def randomUUID[F[_]: Sync]: F[Ident] = Sync[F].delay(unsafe(UUID.randomUUID.toString)) - def randomId[F[_]: Sync]: F[Ident] = Sync[F].delay { - val random = new SecureRandom() - val buffer = new Array[Byte](32) - random.nextBytes(buffer) - unsafe(ByteVector.view(buffer).toBase58.grouped(11).mkString("-")) - } + def randomId[F[_]: Sync]: F[Ident] = + Sync[F].delay { + val random = new SecureRandom() + val buffer = new Array[Byte](32) + random.nextBytes(buffer) + unsafe(ByteVector.view(buffer).toBase58.grouped(11).mkString("-")) + } def apply(str: String): Either[String, Ident] = fromString(str) diff --git a/modules/common/src/main/scala/docspell/common/LenientUri.scala b/modules/common/src/main/scala/docspell/common/LenientUri.scala index fac6cf2f..f010764b 100644 --- a/modules/common/src/main/scala/docspell/common/LenientUri.scala +++ b/modules/common/src/main/scala/docspell/common/LenientUri.scala @@ -122,11 +122,12 @@ object LenientUri { val isRoot = false def /(seg: String): Path = copy(segs = segs.append(seg)) - def asString = segs.head match { - case "." => segments.map(percentEncode).mkString("/") - case ".." => segments.map(percentEncode).mkString("/") - case _ => "/" + segments.map(percentEncode).mkString("/") - } + def asString = + segs.head match { + case "." => segments.map(percentEncode).mkString("/") + case ".." => segments.map(percentEncode).mkString("/") + case _ => "/" + segments.map(percentEncode).mkString("/") + } } def unsafe(str: String): LenientUri = @@ -136,16 +137,17 @@ object LenientUri { unsafe(u.toExternalForm) def parse(str: String): Either[String, LenientUri] = { - def makePath(str: String): Path = str.trim match { - case "/" => RootPath - case "" => EmptyPath - case _ => - NonEmptyList - .fromList(stripLeading(str, '/').split('/').toList.map(percentDecode)) match { - case Some(nl) => NonEmptyPath(nl) - case None => sys.error(s"Invalid url: $str") - } - } + def makePath(str: String): Path = + str.trim match { + case "/" => RootPath + case "" => EmptyPath + case _ => + NonEmptyList + .fromList(stripLeading(str, '/').split('/').toList.map(percentDecode)) match { + case Some(nl) => NonEmptyPath(nl) + case None => sys.error(s"Invalid url: $str") + } + } def makeNonEmpty(str: String): Option[String] = Option(str).filter(_.nonEmpty) diff --git a/modules/common/src/main/scala/docspell/common/Logger.scala b/modules/common/src/main/scala/docspell/common/Logger.scala index 7de684d2..2472f2e1 100644 --- a/modules/common/src/main/scala/docspell/common/Logger.scala +++ b/modules/common/src/main/scala/docspell/common/Logger.scala @@ -17,24 +17,25 @@ trait Logger[F[_]] { object Logger { - def log4s[F[_]: Sync](log: Log4sLogger): Logger[F] = new Logger[F] { - def trace(msg: => String): F[Unit] = - log.ftrace(msg) + def log4s[F[_]: Sync](log: Log4sLogger): Logger[F] = + new Logger[F] { + def trace(msg: => String): F[Unit] = + log.ftrace(msg) - def debug(msg: => String): F[Unit] = - log.fdebug(msg) + def debug(msg: => String): F[Unit] = + log.fdebug(msg) - def info(msg: => String): F[Unit] = - log.finfo(msg) + def info(msg: => String): F[Unit] = + log.finfo(msg) - def warn(msg: => String): F[Unit] = - log.fwarn(msg) + def warn(msg: => String): F[Unit] = + log.fwarn(msg) - def error(ex: Throwable)(msg: => String): F[Unit] = - log.ferror(ex)(msg) + def error(ex: Throwable)(msg: => String): F[Unit] = + log.ferror(ex)(msg) - def error(msg: => String): F[Unit] = - log.ferror(msg) - } + def error(msg: => String): F[Unit] = + log.ferror(msg) + } } diff --git a/modules/common/src/main/scala/docspell/common/SystemCommand.scala b/modules/common/src/main/scala/docspell/common/SystemCommand.scala index 6c9b0ca1..ddff8dc0 100644 --- a/modules/common/src/main/scala/docspell/common/SystemCommand.scala +++ b/modules/common/src/main/scala/docspell/common/SystemCommand.scala @@ -47,17 +47,20 @@ object SystemCommand { for { _ <- writeToProcess(stdin, proc, blocker) term <- Sync[F].delay(proc.waitFor(cmd.timeout.seconds, TimeUnit.SECONDS)) - _ <- if (term) - logger.debug(s"Command `${cmd.cmdString}` finished: ${proc.exitValue}") - else - logger.warn( - s"Command `${cmd.cmdString}` did not finish in ${cmd.timeout.formatExact}!" - ) + _ <- + if (term) + logger.debug(s"Command `${cmd.cmdString}` finished: ${proc.exitValue}") + else + logger.warn( + s"Command `${cmd.cmdString}` did not finish in ${cmd.timeout.formatExact}!" + ) _ <- if (!term) timeoutError(proc, cmd) else Sync[F].pure(()) - out <- if (term) inputStreamToString(proc.getInputStream, blocker) - else Sync[F].pure("") - err <- if (term) inputStreamToString(proc.getErrorStream, blocker) - else Sync[F].pure("") + out <- + if (term) inputStreamToString(proc.getInputStream, blocker) + else Sync[F].pure("") + err <- + if (term) inputStreamToString(proc.getErrorStream, blocker) + else Sync[F].pure("") } yield Result(proc.exitValue, out, err) } } diff --git a/modules/common/src/main/scala/docspell/common/UserState.scala b/modules/common/src/main/scala/docspell/common/UserState.scala index 81e6b4cb..d0a579c7 100644 --- a/modules/common/src/main/scala/docspell/common/UserState.scala +++ b/modules/common/src/main/scala/docspell/common/UserState.scala @@ -22,10 +22,11 @@ object UserState { def unsafe(str: String): UserState = fromString(str).fold(sys.error, identity) - def asString(s: UserState): String = s match { - case Active => "active" - case Disabled => "disabled" - } + def asString(s: UserState): String = + s match { + case Active => "active" + case Disabled => "disabled" + } implicit val userStateEncoder: Encoder[UserState] = Encoder.encodeString.contramap(UserState.asString) diff --git a/modules/common/src/main/scala/docspell/common/syntax/EitherSyntax.scala b/modules/common/src/main/scala/docspell/common/syntax/EitherSyntax.scala index fff6e7d8..169c5740 100644 --- a/modules/common/src/main/scala/docspell/common/syntax/EitherSyntax.scala +++ b/modules/common/src/main/scala/docspell/common/syntax/EitherSyntax.scala @@ -3,17 +3,19 @@ package docspell.common.syntax trait EitherSyntax { implicit final class LeftStringEitherOps[A](e: Either[String, A]) { - def throwLeft: A = e match { - case Right(a) => a - case Left(err) => sys.error(err) - } + def throwLeft: A = + e match { + case Right(a) => a + case Left(err) => sys.error(err) + } } implicit final class ThrowableLeftEitherOps[A](e: Either[Throwable, A]) { - def throwLeft: A = e match { - case Right(a) => a - case Left(err) => throw err - } + def throwLeft: A = + e match { + case Right(a) => a + case Left(err) => throw err + } } } diff --git a/modules/common/src/main/scala/docspell/common/syntax/StreamSyntax.scala b/modules/common/src/main/scala/docspell/common/syntax/StreamSyntax.scala index 761412fb..88098648 100644 --- a/modules/common/src/main/scala/docspell/common/syntax/StreamSyntax.scala +++ b/modules/common/src/main/scala/docspell/common/syntax/StreamSyntax.scala @@ -16,9 +16,10 @@ trait StreamSyntax { .last .map(optStr => for { - str <- optStr - .map(_.trim) - .toRight(new Exception("Empty string cannot be parsed into a value")) + str <- + optStr + .map(_.trim) + .toRight(new Exception("Empty string cannot be parsed into a value")) json <- parse(str).leftMap(_.underlying) value <- json.as[A] } yield value diff --git a/modules/convert/src/main/scala/docspell/convert/Conversion.scala b/modules/convert/src/main/scala/docspell/convert/Conversion.scala index 1b53513c..819910b1 100644 --- a/modules/convert/src/main/scala/docspell/convert/Conversion.scala +++ b/modules/convert/src/main/scala/docspell/convert/Conversion.scala @@ -63,7 +63,7 @@ object Conversion { case Images(mt) => ImageSize.get(in).flatMap { case Some(dim) => - if (dim.product > cfg.maxImageSize) { + if (dim.product > cfg.maxImageSize) logger .info( s"Image size (${dim.product}) is too large (max ${cfg.maxImageSize})." @@ -74,12 +74,11 @@ object Conversion { s"Image size (${dim.width}x${dim.height}) is too large (max ${cfg.maxImageSize})." ) ) - } else { + else Tesseract.toPDF(cfg.tesseract, lang, cfg.chunkSize, blocker, logger)( in, handler ) - } case None => logger.info( diff --git a/modules/convert/src/main/scala/docspell/convert/extern/ExternConv.scala b/modules/convert/src/main/scala/docspell/convert/extern/ExternConv.scala index 966832f3..7e9a2a28 100644 --- a/modules/convert/src/main/scala/docspell/convert/extern/ExternConv.scala +++ b/modules/convert/src/main/scala/docspell/convert/extern/ExternConv.scala @@ -90,13 +90,12 @@ private[extern] object ExternConv { val outTxt = out.resolveSibling(s"$outPrefix.txt") File.exists(outTxt).flatMap { txtExists => val pdfData = File.readAll(out, blocker, chunkSize) - if (result.rc == 0) { + if (result.rc == 0) if (txtExists) successPdfTxt(pdfData, File.readText(outTxt, blocker)).pure[F] else successPdf(pdfData).pure[F] - } else { + else logger.warn(s"Command not successful (rc=${result.rc}), but file exists.") *> successPdf(pdfData).pure[F] - } } case false => diff --git a/modules/convert/src/test/scala/docspell/convert/extern/ExternConvTest.scala b/modules/convert/src/test/scala/docspell/convert/extern/ExternConvTest.scala index f60d82e3..ff3eefac 100644 --- a/modules/convert/src/test/scala/docspell/convert/extern/ExternConvTest.scala +++ b/modules/convert/src/test/scala/docspell/convert/extern/ExternConvTest.scala @@ -24,7 +24,7 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { ) if (!commandExists(cfg.program)) ignore(s"Command ${cfg.program} not found") - else { + else File .withTempDir[IO](target, "wkhtmltopdf") .use(dir => @@ -42,7 +42,6 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { } ) .unsafeRunSync - } } test("convert office to pdf") { @@ -53,7 +52,7 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { ) if (!commandExists(cfg.program)) ignore(s"Command ${cfg.program} not found") - else { + else File .withTempDir[IO](target, "unoconv") .use(dir => @@ -71,7 +70,6 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { } ) .unsafeRunSync - } } test("convert image to pdf") { @@ -82,7 +80,7 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { ) if (!commandExists(cfg.program)) ignore(s"Command ${cfg.program} not found") - else { + else File .withTempDir[IO](target, "tesseract") .use(dir => @@ -101,7 +99,6 @@ object ExternConvTest extends SimpleTestSuite with FileChecks { } ) .unsafeRunSync - } } } diff --git a/modules/extract/src/main/scala/docspell/extract/Extraction.scala b/modules/extract/src/main/scala/docspell/extract/Extraction.scala index 56c37fdc..ade88cdb 100644 --- a/modules/extract/src/main/scala/docspell/extract/Extraction.scala +++ b/modules/extract/src/main/scala/docspell/extract/Extraction.scala @@ -60,7 +60,7 @@ object Extraction { ImageSize.get(data).flatMap { case Some(dim) => - if (dim.product > cfg.ocr.maxImageSize) { + if (dim.product > cfg.ocr.maxImageSize) logger.info( s"Image size (${dim.product}) is too large (max ${cfg.ocr.maxImageSize})." ) *> @@ -71,9 +71,8 @@ object Extraction { ) ) .pure[F] - } else { + else doExtract - } case None => logger.info( s"Cannot read image data from ${mt.asString}. Extracting anyways." diff --git a/modules/extract/src/main/scala/docspell/extract/PdfExtract.scala b/modules/extract/src/main/scala/docspell/extract/PdfExtract.scala index cb5e4162..5eaad5f1 100644 --- a/modules/extract/src/main/scala/docspell/extract/PdfExtract.scala +++ b/modules/extract/src/main/scala/docspell/extract/PdfExtract.scala @@ -33,8 +33,9 @@ object PdfExtract { //maybe better: inspect the pdf and decide whether ocr or not for { - pdfboxRes <- logger.debug("Trying to strip text from pdf using pdfbox.") *> PdfboxExtract - .get[F](in) + pdfboxRes <- + logger.debug("Trying to strip text from pdf using pdfbox.") *> PdfboxExtract + .get[F](in) res <- pdfboxRes.fold( ex => logger.info( @@ -44,7 +45,9 @@ object PdfExtract { if (str.length >= stripMinLen) str.pure[F].attempt else logger - .info(s"Stripped text from PDF is small (${str.length}). Trying with OCR.") *> + .info( + s"Stripped text from PDF is small (${str.length}). Trying with OCR." + ) *> runOcr.flatMap(ocrStr => chooseResult(ocrStr, str)).attempt ) } yield res diff --git a/modules/files/src/main/scala/docspell/files/TikaMimetype.scala b/modules/files/src/main/scala/docspell/files/TikaMimetype.scala index a9e594e6..55ccc51d 100644 --- a/modules/files/src/main/scala/docspell/files/TikaMimetype.scala +++ b/modules/files/src/main/scala/docspell/files/TikaMimetype.scala @@ -36,24 +36,25 @@ object TikaMimetype { md } - private def normalize(in: MimeType): MimeType = in match { - case MimeType(_, sub, p) if sub contains "xhtml" => - MimeType.html.copy(params = p) - case _ => in - } + private def normalize(in: MimeType): MimeType = + in match { + case MimeType(_, sub, p) if sub contains "xhtml" => + MimeType.html.copy(params = p) + case _ => in + } private def fromBytes(bv: Array[Byte], hint: MimeTypeHint): MimeType = { val mt = convert( tika.detect(new java.io.ByteArrayInputStream(bv), makeMetadata(hint)) ) - if (mt.primary == "text") { + if (mt.primary == "text") charsetFromBytes(bv, hint) match { case Some(cs) => mt.withCharset(cs) case None => mt } - } else mt + else mt } private def charsetFromBytes(bv: Array[Byte], hint: MimeTypeHint): Option[Charset] = diff --git a/modules/files/src/test/scala/docspell/files/Playing.scala b/modules/files/src/test/scala/docspell/files/Playing.scala index c0b800f5..0f4f2423 100644 --- a/modules/files/src/test/scala/docspell/files/Playing.scala +++ b/modules/files/src/test/scala/docspell/files/Playing.scala @@ -8,20 +8,22 @@ import scala.concurrent.ExecutionContext object Playing extends IOApp { val blocker = Blocker.liftExecutionContext(ExecutionContext.global) - def run(args: List[String]): IO[ExitCode] = IO { - //val ods = ExampleFiles.examples_sample_ods.readURL[IO](8192, blocker) - //val odt = ExampleFiles.examples_sample_odt.readURL[IO](8192, blocker) - val rtf = ExampleFiles.examples_sample_rtf.readURL[IO](8192, blocker) + def run(args: List[String]): IO[ExitCode] = + IO { + //val ods = ExampleFiles.examples_sample_ods.readURL[IO](8192, blocker) + //val odt = ExampleFiles.examples_sample_odt.readURL[IO](8192, blocker) + val rtf = ExampleFiles.examples_sample_rtf.readURL[IO](8192, blocker) - val x = for { - odsm1 <- TikaMimetype - .detect( - rtf, - MimeTypeHint.filename(ExampleFiles.examples_sample_rtf.path.segments.last) - ) - odsm2 <- TikaMimetype.detect(rtf, MimeTypeHint.none) - } yield (odsm1, odsm2) - println(x.unsafeRunSync()) - ExitCode.Success - } + val x = for { + odsm1 <- + TikaMimetype + .detect( + rtf, + MimeTypeHint.filename(ExampleFiles.examples_sample_rtf.path.segments.last) + ) + odsm2 <- TikaMimetype.detect(rtf, MimeTypeHint.none) + } yield (odsm1, odsm2) + println(x.unsafeRunSync()) + ExitCode.Success + } } diff --git a/modules/joex/src/main/scala/docspell/joex/JoexServer.scala b/modules/joex/src/main/scala/docspell/joex/JoexServer.scala index 58884c9e..065360db 100644 --- a/modules/joex/src/main/scala/docspell/joex/JoexServer.scala +++ b/modules/joex/src/main/scala/docspell/joex/JoexServer.scala @@ -28,8 +28,9 @@ object JoexServer { val app = for { signal <- Resource.liftF(SignallingRef[F, Boolean](false)) exitCode <- Resource.liftF(Ref[F].of(ExitCode.Success)) - joexApp <- JoexAppImpl - .create[F](cfg, signal, pools.connectEC, pools.httpClientEC, pools.blocker) + joexApp <- + JoexAppImpl + .create[F](cfg, signal, pools.connectEC, pools.httpClientEC, pools.blocker) httpApp = Router( "/api/info" -> InfoRoutes(), diff --git a/modules/joex/src/main/scala/docspell/joex/Main.scala b/modules/joex/src/main/scala/docspell/joex/Main.scala index 2a324a3d..bc984815 100644 --- a/modules/joex/src/main/scala/docspell/joex/Main.scala +++ b/modules/joex/src/main/scala/docspell/joex/Main.scala @@ -31,9 +31,8 @@ object Main extends IOApp { if (!Files.exists(path)) { logger.info(s"Not using config file '$f' because it doesn't exist") System.clearProperty("config.file") - } else { + } else logger.info(s"Using config file from system properties: $f") - } case _ => } } diff --git a/modules/joex/src/main/scala/docspell/joex/hk/CleanupInvitesTask.scala b/modules/joex/src/main/scala/docspell/joex/hk/CleanupInvitesTask.scala index 345d488d..8a717864 100644 --- a/modules/joex/src/main/scala/docspell/joex/hk/CleanupInvitesTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/hk/CleanupInvitesTask.scala @@ -11,7 +11,7 @@ object CleanupInvitesTask { def apply[F[_]: Sync](cfg: HouseKeepingConfig.CleanupInvites): Task[F, Unit, Unit] = Task { ctx => - if (cfg.enabled) { + if (cfg.enabled) for { now <- Timestamp.current[F] ts = now - cfg.olderThan @@ -19,8 +19,7 @@ object CleanupInvitesTask { n <- ctx.store.transact(RInvitation.deleteOlderThan(ts)) _ <- ctx.logger.info(s"Removed $n invitations") } yield () - } else { + else ctx.logger.info("CleanupInvites task is disabled in the configuration") - } } } diff --git a/modules/joex/src/main/scala/docspell/joex/hk/CleanupJobsTask.scala b/modules/joex/src/main/scala/docspell/joex/hk/CleanupJobsTask.scala index 43105814..16baeb5f 100644 --- a/modules/joex/src/main/scala/docspell/joex/hk/CleanupJobsTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/hk/CleanupJobsTask.scala @@ -13,7 +13,7 @@ object CleanupJobsTask { def apply[F[_]: Sync](cfg: HouseKeepingConfig.CleanupJobs): Task[F, Unit, Unit] = Task { ctx => - if (cfg.enabled) { + if (cfg.enabled) for { now <- Timestamp.current[F] ts = now - cfg.olderThan @@ -21,9 +21,8 @@ object CleanupJobsTask { n <- deleteDoneJobs(ctx.store, ts, cfg.deleteBatch) _ <- ctx.logger.info(s"Removed $n jobs") } yield () - } else { + else ctx.logger.info("CleanupJobs task is disabled in the configuration") - } } def deleteDoneJobs[F[_]: Sync](store: Store[F], ts: Timestamp, batch: Int): F[Int] = diff --git a/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala b/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala index 2f6eb196..57f26984 100644 --- a/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala @@ -69,16 +69,17 @@ object NotifyDueItemsTask { def findItems[F[_]: Sync](ctx: Context[F, Args]): F[Vector[QItem.ListItem]] = for { now <- Timestamp.current[F] - q = QItem.Query - .empty(ctx.args.account.collective) - .copy( - states = ItemState.validStates, - tagsInclude = ctx.args.tagsInclude, - tagsExclude = ctx.args.tagsExclude, - dueDateFrom = ctx.args.daysBack.map(back => now - Duration.days(back.toLong)), - dueDateTo = Some(now + Duration.days(ctx.args.remindDays.toLong)), - orderAsc = Some(_.dueDate) - ) + q = + QItem.Query + .empty(ctx.args.account.collective) + .copy( + states = ItemState.validStates, + tagsInclude = ctx.args.tagsInclude, + tagsExclude = ctx.args.tagsExclude, + dueDateFrom = ctx.args.daysBack.map(back => now - Duration.days(back.toLong)), + dueDateTo = Some(now + Duration.days(ctx.args.remindDays.toLong)), + orderAsc = Some(_.dueDate) + ) res <- ctx.store.transact(QItem.findItems(q).take(maxItems)).compile.toVector } yield res diff --git a/modules/joex/src/main/scala/docspell/joex/process/CreateItem.scala b/modules/joex/src/main/scala/docspell/joex/process/CreateItem.scala index 17cee1db..798fb6f5 100644 --- a/modules/joex/src/main/scala/docspell/joex/process/CreateItem.scala +++ b/modules/joex/src/main/scala/docspell/joex/process/CreateItem.scala @@ -89,12 +89,14 @@ object CreateItem { Task { ctx => for { cand <- ctx.store.transact(QItem.findByFileIds(ctx.args.files.map(_.fileMetaId))) - _ <- if (cand.nonEmpty) ctx.logger.warn("Found existing item with these files.") - else ().pure[F] + _ <- + if (cand.nonEmpty) ctx.logger.warn("Found existing item with these files.") + else ().pure[F] ht <- cand.drop(1).traverse(ri => QItem.delete(ctx.store)(ri.id, ri.cid)) - _ <- if (ht.sum > 0) - ctx.logger.warn(s"Removed ${ht.sum} items with same attachments") - else ().pure[F] + _ <- + if (ht.sum > 0) + ctx.logger.warn(s"Removed ${ht.sum} items with same attachments") + else ().pure[F] rms <- OptionT( cand.headOption.traverse(ri => ctx.store.transact(RAttachment.findByItemAndCollective(ri.id, ri.cid)) @@ -103,9 +105,10 @@ object CreateItem { orig <- rms.traverse(a => ctx.store.transact(RAttachmentSource.findById(a.id)).map(s => (a, s)) ) - origMap = orig - .map(originFileTuple) - .toMap + origMap = + orig + .map(originFileTuple) + .toMap } yield cand.headOption.map(ri => ItemData(ri, rms, Vector.empty, Vector.empty, origMap) ) @@ -116,13 +119,12 @@ object CreateItem { saved: Vector[RAttachment], saveCount: Int ): F[Unit] = - if (ctx.args.files.size != saved.size) { + if (ctx.args.files.size != saved.size) ctx.logger.warn( s"Not all given files (${ctx.args.files.size}) have been stored. Files retained: ${saved.size}; saveCount=$saveCount" ) - } else { + else ().pure[F] - } private def storeItemError[F[_]: Sync](ctx: Context[F, ProcessItemArgs]): F[Unit] = { val msg = "Inserting item failed. DB returned 0 update count!" diff --git a/modules/joex/src/main/scala/docspell/joex/process/EvalProposals.scala b/modules/joex/src/main/scala/docspell/joex/process/EvalProposals.scala index 799b8b6c..6e492a07 100644 --- a/modules/joex/src/main/scala/docspell/joex/process/EvalProposals.scala +++ b/modules/joex/src/main/scala/docspell/joex/process/EvalProposals.scala @@ -79,8 +79,10 @@ object EvalProposals { if (mt == MetaProposalType.CorrOrg) 0.8 else 1.0 case NerTag.Person => - if (mt == MetaProposalType.CorrPerson || - mt == MetaProposalType.ConcPerson) 0.8 + if ( + mt == MetaProposalType.CorrPerson || + mt == MetaProposalType.ConcPerson + ) 0.8 else 1.0 case NerTag.Website => 0.5 } diff --git a/modules/joex/src/main/scala/docspell/joex/process/FindProposal.scala b/modules/joex/src/main/scala/docspell/joex/process/FindProposal.scala index b4eaf0f7..1f7e66b9 100644 --- a/modules/joex/src/main/scala/docspell/joex/process/FindProposal.scala +++ b/modules/joex/src/main/scala/docspell/joex/process/FindProposal.scala @@ -103,7 +103,8 @@ object FindProposal { } def nextWhenEmpty(f: Finder[F], mt0: MetaProposalType, mts: MetaProposalType*)( - implicit F: FlatMap[F], + implicit + F: FlatMap[F], F2: Applicative[F] ): Finder[F] = flatMap { res0 => @@ -139,11 +140,11 @@ object FindProposal { val minLength = if (exact) 2 else 5 - if (value.length < minLength) { + if (value.length < minLength) ctx.logger .debug(s"Skipping too small value '$value' (original '${nt.label}').") .map(_ => MetaProposalList.empty) - } else + else nt.tag match { case NerTag.Organization => ctx.logger.debug(s"Looking for organizations: $value") *> @@ -191,9 +192,8 @@ object FindProposal { .map(s => s"%$s%") .getOrElse(value) searchContact(nt, ContactKind.Website, searchString, ctx) - } else { + } else searchContact(nt, ContactKind.Website, value, ctx) - } case NerTag.Date => // There is no database search required for this tag diff --git a/modules/joex/src/main/scala/docspell/joex/process/TextAnalysis.scala b/modules/joex/src/main/scala/docspell/joex/process/TextAnalysis.scala index 554d1f40..e369421b 100644 --- a/modules/joex/src/main/scala/docspell/joex/process/TextAnalysis.scala +++ b/modules/joex/src/main/scala/docspell/joex/process/TextAnalysis.scala @@ -18,8 +18,11 @@ object TextAnalysis { for { _ <- ctx.logger.info("Starting text analysis") s <- Duration.stopTime[F] - t <- item.metas.toList - .traverse(annotateAttachment[F](ctx.args.meta.language, ctx.logger, analyser)) + t <- + item.metas.toList + .traverse( + annotateAttachment[F](ctx.args.meta.language, ctx.logger, analyser) + ) _ <- ctx.logger.debug(s"Storing tags: ${t.map(_._1.copy(content = None))}") _ <- t.traverse(m => ctx.store.transact(RAttachmentMeta.updateLabels(m._1.id, m._1.nerlabels)) diff --git a/modules/joex/src/main/scala/docspell/joex/scheduler/JobTask.scala b/modules/joex/src/main/scala/docspell/joex/scheduler/JobTask.scala index f5348417..891636c3 100644 --- a/modules/joex/src/main/scala/docspell/joex/scheduler/JobTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/scheduler/JobTask.scala @@ -28,8 +28,8 @@ object JobTask { name: Ident, task: Task[F, A, Unit], onCancel: Task[F, A, Unit] - )( - implicit D: Decoder[A] + )(implicit + D: Decoder[A] ): JobTask[F] = { val convert: String => F[A] = str => diff --git a/modules/joex/src/main/scala/docspell/joex/scheduler/SchedulerImpl.scala b/modules/joex/src/main/scala/docspell/joex/scheduler/SchedulerImpl.scala index 37189f3e..9fb6d160 100644 --- a/modules/joex/src/main/scala/docspell/joex/scheduler/SchedulerImpl.scala +++ b/modules/joex/src/main/scala/docspell/joex/scheduler/SchedulerImpl.scala @@ -96,14 +96,15 @@ final class SchedulerImpl[F[_]: ConcurrentEffect: ContextShift]( _ <- permits.acquire _ <- logger.fdebug("New permit acquired") down <- state.get.map(_.shutdownRequest) - rjob <- if (down) - logger.finfo("") *> permits.release *> (None: Option[RJob]).pure[F] - else - queue.nextJob( - group => state.modify(_.nextPrio(group, config.countingScheme)), - config.name, - config.retryDelay - ) + rjob <- + if (down) + logger.finfo("") *> permits.release *> (None: Option[RJob]).pure[F] + else + queue.nextJob( + group => state.modify(_.nextPrio(group, config.countingScheme)), + config.name, + config.retryDelay + ) _ <- logger.fdebug(s"Next job found: ${rjob.map(_.info)}") _ <- rjob.map(execute).getOrElse(permits.release) } yield rjob.isDefined @@ -128,9 +129,10 @@ final class SchedulerImpl[F[_]: ConcurrentEffect: ContextShift]( def execute(job: RJob): F[Unit] = { val task = for { - jobtask <- tasks - .find(job.task) - .toRight(s"This executor cannot run tasks with name: ${job.task}") + jobtask <- + tasks + .find(job.task) + .toRight(s"This executor cannot run tasks with name: ${job.task}") } yield jobtask task match { diff --git a/modules/joex/src/main/scala/docspell/joex/scheduler/Task.scala b/modules/joex/src/main/scala/docspell/joex/scheduler/Task.scala index 85874177..7c5f7616 100644 --- a/modules/joex/src/main/scala/docspell/joex/scheduler/Task.scala +++ b/modules/joex/src/main/scala/docspell/joex/scheduler/Task.scala @@ -25,8 +25,8 @@ trait Task[F[_], A, B] { def mapF[C](f: F[B] => F[C]): Task[F, A, C] = Task(Task.toKleisli(this).mapF(f)) - def attempt( - implicit F: ApplicativeError[F, Throwable] + def attempt(implicit + F: ApplicativeError[F, Throwable] ): Task[F, A, Either[Throwable, B]] = mapF(_.attempt) diff --git a/modules/restserver/src/main/scala/docspell/restserver/Main.scala b/modules/restserver/src/main/scala/docspell/restserver/Main.scala index eceeba3e..47fadcfa 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/Main.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/Main.scala @@ -31,9 +31,8 @@ object Main extends IOApp { if (!Files.exists(path)) { logger.info(s"Not using config file '$f' because it doesn't exist") System.clearProperty("config.file") - } else { + } else logger.info(s"Using config file from system properties: $f") - } case _ => } } diff --git a/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala b/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala index 2abbf53d..1a9266de 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala @@ -23,8 +23,9 @@ object RestServer { val templates = TemplateRoutes[F](pools.blocker, cfg) val app = for { - restApp <- RestAppImpl - .create[F](cfg, pools.connectEC, pools.httpClientEC, pools.blocker) + restApp <- + RestAppImpl + .create[F](cfg, pools.connectEC, pools.httpClientEC, pools.blocker) httpApp = Router( "/api/info" -> routes.InfoRoutes(), "/api/v1/open/" -> openRoutes(cfg, restApp), diff --git a/modules/restserver/src/main/scala/docspell/restserver/auth/CookieData.scala b/modules/restserver/src/main/scala/docspell/restserver/auth/CookieData.scala index 52c51e94..ae15d434 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/auth/CookieData.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/auth/CookieData.scala @@ -34,9 +34,10 @@ object CookieData { def fromCookie[F[_]](req: Request[F]): Either[String, String] = for { header <- headers.Cookie.from(req.headers).toRight("Cookie parsing error") - cookie <- header.values.toList - .find(_.name == cookieName) - .toRight("Couldn't find the authcookie") + cookie <- + header.values.toList + .find(_.name == cookieName) + .toRight("Couldn't find the authcookie") } yield cookie.content def fromHeader[F[_]](req: Request[F]): Either[String, String] = diff --git a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala index dd2f01f5..ea262bce 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala @@ -199,10 +199,15 @@ trait Conversions { body .through(fs2.text.utf8Decode) .parseJsonAs[ItemUploadMeta] - .map(_.fold(ex => { - logger.error(ex)("Reading upload metadata failed.") - throw ex - }, identity)) + .map( + _.fold( + ex => { + logger.error(ex)("Reading upload metadata failed.") + throw ex + }, + identity + ) + ) val meta: F[(Boolean, UploadMeta)] = mp.parts .find(_.name.exists(_.equalsIgnoreCase("meta"))) @@ -452,26 +457,30 @@ trait Conversions { BasicResult(true, "The job has been removed from the queue.") } - def basicResult(ar: AddResult, successMsg: String): BasicResult = ar match { - case AddResult.Success => BasicResult(true, successMsg) - case AddResult.EntityExists(msg) => BasicResult(false, msg) - case AddResult.Failure(ex) => BasicResult(false, s"Internal error: ${ex.getMessage}") - } + def basicResult(ar: AddResult, successMsg: String): BasicResult = + ar match { + case AddResult.Success => BasicResult(true, successMsg) + case AddResult.EntityExists(msg) => BasicResult(false, msg) + case AddResult.Failure(ex) => + BasicResult(false, s"Internal error: ${ex.getMessage}") + } - def basicResult(ur: OUpload.UploadResult): BasicResult = ur match { - case UploadResult.Success => BasicResult(true, "Files submitted.") - case UploadResult.NoFiles => BasicResult(false, "There were no files to submit.") - case UploadResult.NoSource => BasicResult(false, "The source id is not valid.") - } + def basicResult(ur: OUpload.UploadResult): BasicResult = + ur match { + case UploadResult.Success => BasicResult(true, "Files submitted.") + case UploadResult.NoFiles => BasicResult(false, "There were no files to submit.") + case UploadResult.NoSource => BasicResult(false, "The source id is not valid.") + } - def basicResult(cr: PassChangeResult): BasicResult = cr match { - case PassChangeResult.Success => BasicResult(true, "Password changed.") - case PassChangeResult.UpdateFailed => - BasicResult(false, "The database update failed.") - case PassChangeResult.PasswordMismatch => - BasicResult(false, "The current password is incorrect.") - case PassChangeResult.UserNotFound => BasicResult(false, "User not found.") - } + def basicResult(cr: PassChangeResult): BasicResult = + cr match { + case PassChangeResult.Success => BasicResult(true, "Password changed.") + case PassChangeResult.UpdateFailed => + BasicResult(false, "The database update failed.") + case PassChangeResult.PasswordMismatch => + BasicResult(false, "The current password is incorrect.") + case PassChangeResult.UserNotFound => BasicResult(false, "User not found.") + } def basicResult(e: Either[Throwable, _], successMsg: String): BasicResult = e match { diff --git a/modules/restserver/src/main/scala/docspell/restserver/http4s/ResponseGenerator.scala b/modules/restserver/src/main/scala/docspell/restserver/http4s/ResponseGenerator.scala index 3a349760..7ee3519a 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/http4s/ResponseGenerator.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/http4s/ResponseGenerator.scala @@ -9,8 +9,8 @@ trait ResponseGenerator[F[_]] { self: Http4sDsl[F] => implicit final class EitherResponses[A, B](e: Either[A, B]) { - def toResponse(headers: Header*)( - implicit F: Applicative[F], + def toResponse(headers: Header*)(implicit + F: Applicative[F], w0: EntityEncoder[F, A], w1: EntityEncoder[F, B] ): F[Response[F]] = diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala index d02375a9..37079630 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala @@ -46,9 +46,10 @@ object AttachmentRoutes { case HEAD -> Root / Ident(id) => for { fileData <- backend.item.findAttachment(id, user.account.collective) - resp <- fileData - .map(data => withResponseHeaders(Ok())(data)) - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map(data => withResponseHeaders(Ok())(data)) + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case req @ GET -> Root / Ident(id) => @@ -56,20 +57,22 @@ object AttachmentRoutes { fileData <- backend.item.findAttachment(id, user.account.collective) inm = req.headers.get(`If-None-Match`).flatMap(_.tags) matches = matchETag(fileData.map(_.meta), inm) - resp <- fileData - .map { data => - if (matches) withResponseHeaders(NotModified())(data) - else makeByteResp(data) - } - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map { data => + if (matches) withResponseHeaders(NotModified())(data) + else makeByteResp(data) + } + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case HEAD -> Root / Ident(id) / "original" => for { fileData <- backend.item.findAttachmentSource(id, user.account.collective) - resp <- fileData - .map(data => withResponseHeaders(Ok())(data)) - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map(data => withResponseHeaders(Ok())(data)) + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case req @ GET -> Root / Ident(id) / "original" => @@ -77,20 +80,22 @@ object AttachmentRoutes { fileData <- backend.item.findAttachmentSource(id, user.account.collective) inm = req.headers.get(`If-None-Match`).flatMap(_.tags) matches = matchETag(fileData.map(_.meta), inm) - resp <- fileData - .map { data => - if (matches) withResponseHeaders(NotModified())(data) - else makeByteResp(data) - } - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map { data => + if (matches) withResponseHeaders(NotModified())(data) + else makeByteResp(data) + } + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case HEAD -> Root / Ident(id) / "archive" => for { fileData <- backend.item.findAttachmentArchive(id, user.account.collective) - resp <- fileData - .map(data => withResponseHeaders(Ok())(data)) - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map(data => withResponseHeaders(Ok())(data)) + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case req @ GET -> Root / Ident(id) / "archive" => @@ -98,12 +103,13 @@ object AttachmentRoutes { fileData <- backend.item.findAttachmentArchive(id, user.account.collective) inm = req.headers.get(`If-None-Match`).flatMap(_.tags) matches = matchETag(fileData.map(_.meta), inm) - resp <- fileData - .map { data => - if (matches) withResponseHeaders(NotModified())(data) - else makeByteResp(data) - } - .getOrElse(NotFound(BasicResult(false, "Not found"))) + resp <- + fileData + .map { data => + if (matches) withResponseHeaders(NotModified())(data) + else makeByteResp(data) + } + .getOrElse(NotFound(BasicResult(false, "Not found"))) } yield resp case GET -> Root / Ident(id) / "view" => @@ -123,8 +129,9 @@ object AttachmentRoutes { case DELETE -> Root / Ident(id) => for { n <- backend.item.deleteAttachment(id, user.account.collective) - res = if (n == 0) BasicResult(false, "Attachment not found") - else BasicResult(true, "Attachment deleted.") + res = + if (n == 0) BasicResult(false, "Attachment not found") + else BasicResult(true, "Attachment deleted.") resp <- Ok(res) } yield resp } diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala index 2d779b6c..a5163e88 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala @@ -28,8 +28,9 @@ object CollectiveRoutes { case req @ POST -> Root / "settings" => for { settings <- req.as[CollectiveSettings] - res <- backend.collective - .updateLanguage(user.account.collective, settings.language) + res <- + backend.collective + .updateLanguage(user.account.collective, settings.language) resp <- Ok(Conversions.basicResult(res, "Language updated.")) } yield resp @@ -43,11 +44,12 @@ object CollectiveRoutes { case GET -> Root / "contacts" :? QueryParam.QueryOpt(q) +& QueryParam .ContactKindOpt(kind) => for { - res <- backend.collective - .getContacts(user.account.collective, q.map(_.q), kind) - .take(50) - .compile - .toList + res <- + backend.collective + .getContacts(user.account.collective, q.map(_.q), kind) + .take(50) + .compile + .toList resp <- Ok(ContactList(res.map(Conversions.mkContact))) } yield resp diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/ItemRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/ItemRoutes.scala index 881b5129..389c79de 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/ItemRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/ItemRoutes.scala @@ -36,9 +36,10 @@ object ItemRoutes { for { item <- backend.item.findItem(id, user.account.collective) result = item.map(Conversions.mkItemDetail) - resp <- result - .map(r => Ok(r)) - .getOrElse(NotFound(BasicResult(false, "Not found."))) + resp <- + result + .map(r => Ok(r)) + .getOrElse(NotFound(BasicResult(false, "Not found."))) } yield resp case POST -> Root / Ident(id) / "confirm" => diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/MailSendRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/MailSendRoutes.scala index 88c7bae1..58dd98b8 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/MailSendRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/MailSendRoutes.scala @@ -40,8 +40,9 @@ object MailSendRoutes { for { rec <- s.recipients.traverse(MailAddress.parse) fileIds <- s.attachmentIds.traverse(Ident.fromString) - sel = if (s.addAllAttachments) AttachSelection.All - else AttachSelection.Selected(fileIds) + sel = + if (s.addAllAttachments) AttachSelection.All + else AttachSelection.Selected(fileIds) } yield ItemMail(item, s.subject, rec, s.body, sel) def convertOut(res: SendResult): BasicResult = diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/NotifyDueItemsRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/NotifyDueItemsRoutes.scala index 1d4927f4..069346d4 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/NotifyDueItemsRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/NotifyDueItemsRoutes.scala @@ -31,10 +31,10 @@ object NotifyDueItemsRoutes { for { data <- req.as[NotificationSettings] task = makeTask(cfg, user.account, data) - res <- ut - .executeNow(user.account, task) - .attempt - .map(Conversions.basicResult(_, "Submitted successfully.")) + res <- + ut.executeNow(user.account, task) + .attempt + .map(Conversions.basicResult(_, "Submitted successfully.")) resp <- Ok(res) } yield resp @@ -49,10 +49,10 @@ object NotifyDueItemsRoutes { for { data <- req.as[NotificationSettings] task = makeTask(cfg, user.account, data) - res <- ut - .submitNotifyDueItems(user.account, task) - .attempt - .map(Conversions.basicResult(_, "Saved successfully.")) + res <- + ut.submitNotifyDueItems(user.account, task) + .attempt + .map(Conversions.basicResult(_, "Saved successfully.")) resp <- Ok(res) } yield resp } @@ -89,12 +89,13 @@ object NotifyDueItemsRoutes { for { tinc <- backend.tag.loadAll(task.args.tagsInclude) texc <- backend.tag.loadAll(task.args.tagsExclude) - conn <- backend.mail - .getSettings(account, None) - .map( - _.find(_.name == task.args.smtpConnection) - .map(_.name) - ) + conn <- + backend.mail + .getSettings(account, None) + .map( + _.find(_.name == task.args.smtpConnection) + .map(_.name) + ) } yield NotificationSettings( task.id, task.enabled, diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/OrganizationRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/OrganizationRoutes.scala index 98362f7d..00f54fca 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/OrganizationRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/OrganizationRoutes.scala @@ -21,17 +21,16 @@ object OrganizationRoutes { HttpRoutes.of { case GET -> Root :? QueryParam.FullOpt(full) +& QueryParam.QueryOpt(q) => - if (full.getOrElse(false)) { + if (full.getOrElse(false)) for { data <- backend.organization.findAllOrg(user.account, q.map(_.q)) resp <- Ok(OrganizationList(data.map(mkOrg).toList)) } yield resp - } else { + else for { data <- backend.organization.findAllOrgRefs(user.account, q.map(_.q)) resp <- Ok(ReferenceList(data.map(mkIdName).toList)) } yield resp - } case req @ POST -> Root => for { diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/PersonRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/PersonRoutes.scala index d0c438ae..e2d97696 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/PersonRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/PersonRoutes.scala @@ -24,17 +24,16 @@ object PersonRoutes { HttpRoutes.of { case GET -> Root :? QueryParam.FullOpt(full) +& QueryParam.QueryOpt(q) => - if (full.getOrElse(false)) { + if (full.getOrElse(false)) for { data <- backend.organization.findAllPerson(user.account, q.map(_.q)) resp <- Ok(PersonList(data.map(mkPerson).toList)) } yield resp - } else { + else for { data <- backend.organization.findAllPersonRefs(user.account, q.map(_.q)) resp <- Ok(ReferenceList(data.map(mkIdName).toList)) } yield resp - } case req @ POST -> Root => for { diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/RegisterRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/RegisterRoutes.scala index 29424eb4..15b57319 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/RegisterRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/RegisterRoutes.scala @@ -38,28 +38,30 @@ object RegisterRoutes { } } - def convert(r: NewInviteResult): InviteResult = r match { - case NewInviteResult.Success(id) => - InviteResult(true, "New invitation created.", Some(id)) - case NewInviteResult.InvitationDisabled => - InviteResult(false, "Signing up is not enabled for invitations.", None) - case NewInviteResult.PasswordMismatch => - InviteResult(false, "Password is invalid.", None) - } + def convert(r: NewInviteResult): InviteResult = + r match { + case NewInviteResult.Success(id) => + InviteResult(true, "New invitation created.", Some(id)) + case NewInviteResult.InvitationDisabled => + InviteResult(false, "Signing up is not enabled for invitations.", None) + case NewInviteResult.PasswordMismatch => + InviteResult(false, "Password is invalid.", None) + } - def convert(r: SignupResult): BasicResult = r match { - case SignupResult.CollectiveExists => - BasicResult(false, "A collective with this name already exists.") - case SignupResult.InvalidInvitationKey => - BasicResult(false, "Invalid invitation key.") - case SignupResult.SignupClosed => - BasicResult(false, "Sorry, registration is closed.") - case SignupResult.Failure(ex) => - logger.error(ex)("Error signing up") - BasicResult(false, s"Internal error: ${ex.getMessage}") - case SignupResult.Success => - BasicResult(true, "Signup successful") - } + def convert(r: SignupResult): BasicResult = + r match { + case SignupResult.CollectiveExists => + BasicResult(false, "A collective with this name already exists.") + case SignupResult.InvalidInvitationKey => + BasicResult(false, "Invalid invitation key.") + case SignupResult.SignupClosed => + BasicResult(false, "Sorry, registration is closed.") + case SignupResult.Failure(ex) => + logger.error(ex)("Error signing up") + BasicResult(false, s"Internal error: ${ex.getMessage}") + case SignupResult.Success => + BasicResult(true, "Signup successful") + } def convert(r: Registration): RegisterData = RegisterData(r.collectiveName, r.login, r.password, r.invite) diff --git a/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala index 47c0782e..70976688 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala @@ -26,8 +26,8 @@ object TemplateRoutes { def app: HttpRoutes[F] } - def apply[F[_]: Effect](blocker: Blocker, cfg: Config)( - implicit C: ContextShift[F] + def apply[F[_]: Effect](blocker: Blocker, cfg: Config)(implicit + C: ContextShift[F] ): InnerRoutes[F] = { val indexTemplate = memo( loadResource("/index.html").flatMap(loadTemplate(_, blocker)) @@ -64,8 +64,8 @@ object TemplateRoutes { r.pure[F] } - def loadUrl[F[_]: Sync](url: URL, blocker: Blocker)( - implicit C: ContextShift[F] + def loadUrl[F[_]: Sync](url: URL, blocker: Blocker)(implicit + C: ContextShift[F] ): F[String] = Stream .bracket(Sync[F].delay(url.openStream))(in => Sync[F].delay(in.close())) @@ -82,8 +82,8 @@ object TemplateRoutes { } } - def loadTemplate[F[_]: Sync](url: URL, blocker: Blocker)( - implicit C: ContextShift[F] + def loadTemplate[F[_]: Sync](url: URL, blocker: Blocker)(implicit + C: ContextShift[F] ): F[Template] = loadUrl[F](url, blocker).flatMap(s => parseTemplate(s)).map { t => logger.info(s"Compiled template $url") diff --git a/modules/store/src/main/scala/docspell/store/impl/Column.scala b/modules/store/src/main/scala/docspell/store/impl/Column.scala index 5f47a4db..c2f19abd 100644 --- a/modules/store/src/main/scala/docspell/store/impl/Column.scala +++ b/modules/store/src/main/scala/docspell/store/impl/Column.scala @@ -22,10 +22,11 @@ case class Column(name: String, ns: String = "", alias: String = "") { def is[A: Put](value: A): Fragment = f ++ fr" = $value" - def is[A: Put](ov: Option[A]): Fragment = ov match { - case Some(v) => f ++ fr" = $v" - case None => fr"is null" - } + def is[A: Put](ov: Option[A]): Fragment = + ov match { + case Some(v) => f ++ fr" = $v" + case None => fr"is null" + } def is(c: Column): Fragment = f ++ fr"=" ++ c.f diff --git a/modules/store/src/main/scala/docspell/store/migrate/FlywayMigrate.scala b/modules/store/src/main/scala/docspell/store/migrate/FlywayMigrate.scala index 29eced76..138ea485 100644 --- a/modules/store/src/main/scala/docspell/store/migrate/FlywayMigrate.scala +++ b/modules/store/src/main/scala/docspell/store/migrate/FlywayMigrate.scala @@ -8,28 +8,29 @@ import org.log4s._ object FlywayMigrate { private[this] val logger = getLogger - def run[F[_]: Sync](jdbc: JdbcConfig): F[Int] = Sync[F].delay { - logger.info("Running db migrations...") - val locations = jdbc.dbmsName match { - case Some(dbtype) => - val name = if (dbtype == "h2") "postgresql" else dbtype - List(s"classpath:db/migration/${name}") - case None => - logger.warn( - s"Cannot read database name from jdbc url: ${jdbc.url}. Go with PostgreSQL" - ) - List("classpath:db/postgresql") + def run[F[_]: Sync](jdbc: JdbcConfig): F[Int] = + Sync[F].delay { + logger.info("Running db migrations...") + val locations = jdbc.dbmsName match { + case Some(dbtype) => + val name = if (dbtype == "h2") "postgresql" else dbtype + List(s"classpath:db/migration/${name}") + case None => + logger.warn( + s"Cannot read database name from jdbc url: ${jdbc.url}. Go with PostgreSQL" + ) + List("classpath:db/postgresql") + } + + logger.info(s"Using migration locations: $locations") + val fw = Flyway + .configure() + .cleanDisabled(true) + .dataSource(jdbc.url.asString, jdbc.user, jdbc.password) + .locations(locations: _*) + .load() + + fw.repair() + fw.migrate() } - - logger.info(s"Using migration locations: $locations") - val fw = Flyway - .configure() - .cleanDisabled(true) - .dataSource(jdbc.url.asString, jdbc.user, jdbc.password) - .locations(locations: _*) - .load() - - fw.repair() - fw.migrate() - } } diff --git a/modules/store/src/main/scala/docspell/store/queries/QAttachment.scala b/modules/store/src/main/scala/docspell/store/queries/QAttachment.scala index 9f4a78b3..56b2fffe 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QAttachment.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QAttachment.scala @@ -30,16 +30,18 @@ object QAttachment { for { files <- store.transact(loadFiles) - k <- if (files._3 == 1) deleteArchive(store)(attachId) - else store.transact(RAttachmentArchive.delete(attachId)) + k <- + if (files._3 == 1) deleteArchive(store)(attachId) + else store.transact(RAttachmentArchive.delete(attachId)) n <- store.transact(RAttachment.delete(attachId)) - f <- Stream - .emits(files._1.toSeq ++ files._2.toSeq) - .map(_.id) - .flatMap(store.bitpeace.delete) - .map(flag => if (flag) 1 else 0) - .compile - .foldMonoid + f <- + Stream + .emits(files._1.toSeq ++ files._2.toSeq) + .map(_.id) + .flatMap(store.bitpeace.delete) + .map(flag => if (flag) 1 else 0) + .compile + .foldMonoid } yield n + k + f } @@ -55,12 +57,13 @@ object QAttachment { _ <- logger.fdebug[F]( s"Deleted $n meta records (source, meta, archive). Deleting binaries now." ) - f <- Stream - .emits(ra.fileId.id +: (s.map(_.fileId.id).toSeq)) - .flatMap(store.bitpeace.delete) - .map(flag => if (flag) 1 else 0) - .compile - .foldMonoid + f <- + Stream + .emits(ra.fileId.id +: (s.map(_.fileId.id).toSeq)) + .flatMap(store.bitpeace.delete) + .map(flag => if (flag) 1 else 0) + .compile + .foldMonoid } yield n + f def deleteArchive[F[_]: Sync](store: Store[F])(attachId: Ident): F[Int] = @@ -119,7 +122,9 @@ object QAttachment { val IC = RItem.Columns val q = - fr"SELECT" ++ commas(MC.all.map(_.prefix("m").f)) ++ fr"FROM" ++ RItem.table ++ fr"i" ++ + fr"SELECT" ++ commas( + MC.all.map(_.prefix("m").f) + ) ++ fr"FROM" ++ RItem.table ++ fr"i" ++ fr"INNER JOIN" ++ RAttachment.table ++ fr"a ON" ++ IC.id .prefix("i") .is(AC.itemId.prefix("a")) ++ diff --git a/modules/store/src/main/scala/docspell/store/queries/QCollective.scala b/modules/store/src/main/scala/docspell/store/queries/QCollective.scala index 81bdd889..8f9f4067 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QCollective.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QCollective.scala @@ -96,7 +96,9 @@ object QCollective { RC.Columns.all, RC.table, and( - Seq(or(RC.Columns.orgId.isIn(orgCond), RC.Columns.personId.isIn(persCond))) ++ queryCond ++ kindCond + Seq( + or(RC.Columns.orgId.isIn(orgCond), RC.Columns.personId.isIn(persCond)) + ) ++ queryCond ++ kindCond ) ) ++ orderBy(RC.Columns.value.f) diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala index 5d77cf95..452015eb 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala @@ -291,7 +291,9 @@ object QItem { val IC = RItem.Columns val AC = RAttachment.Columns val q = - fr"SELECT DISTINCT" ++ commas(IC.all.map(_.prefix("i").f)) ++ fr"FROM" ++ RItem.table ++ fr"i" ++ + fr"SELECT DISTINCT" ++ commas( + IC.all.map(_.prefix("i").f) + ) ++ fr"FROM" ++ RItem.table ++ fr"i" ++ fr"INNER JOIN" ++ RAttachment.table ++ fr"a ON" ++ AC.itemId .prefix("a") .is(IC.id.prefix("i")) ++ diff --git a/modules/store/src/main/scala/docspell/store/queries/QJob.scala b/modules/store/src/main/scala/docspell/store/queries/QJob.scala index ded3e2e6..852f1ade 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QJob.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QJob.scala @@ -55,8 +55,9 @@ object QJob { def markJob(job: RJob): F[Either[Unit, RJob]] = store.transact(for { n <- RJob.setScheduled(job.id, worker) - _ <- if (n == 1) RJobGroupUse.setGroup(RJobGroupUse(worker, job.group)) - else 0.pure[ConnectionIO] + _ <- + if (n == 1) RJobGroupUse.setGroup(RJobGroupUse(worker, job.group)) + else 0.pure[ConnectionIO] } yield if (n == 1) Right(job) else Left(())) for { @@ -68,9 +69,10 @@ object QJob { _ <- logger.ftrace[F](s"Choose group ${group.map(_.id)}") prio <- group.map(priority).getOrElse((Priority.Low: Priority).pure[F]) _ <- logger.ftrace[F](s"Looking for job of prio $prio") - job <- group - .map(g => store.transact(selectNextJob(g, prio, retryPause, now))) - .getOrElse((None: Option[RJob]).pure[F]) + job <- + group + .map(g => store.transact(selectNextJob(g, prio, retryPause, now))) + .getOrElse((None: Option[RJob]).pure[F]) _ <- logger.ftrace[F](s"Found job: ${job.map(_.info)}") res <- job.traverse(j => markJob(j)) } yield res.map(_.map(_.some)).getOrElse { diff --git a/modules/store/src/main/scala/docspell/store/queue/PeriodicTaskStore.scala b/modules/store/src/main/scala/docspell/store/queue/PeriodicTaskStore.scala index e1730182..c94458bb 100644 --- a/modules/store/src/main/scala/docspell/store/queue/PeriodicTaskStore.scala +++ b/modules/store/src/main/scala/docspell/store/queue/PeriodicTaskStore.scala @@ -81,12 +81,13 @@ object PeriodicTaskStore { def unmark(job: RPeriodicTask): F[Unit] = for { now <- Timestamp.current[F] - nextRun <- CalevFs2 - .nextElapses[F](now.atUTC)(job.timer) - .take(1) - .compile - .last - .map(_.map(Timestamp.from)) + nextRun <- + CalevFs2 + .nextElapses[F](now.atUTC)(job.timer) + .take(1) + .compile + .last + .map(_.map(Timestamp.from)) _ <- store.transact(QPeriodicTask.unsetWorker(job.id, nextRun)) } yield () diff --git a/modules/store/src/main/scala/docspell/store/records/RAttachment.scala b/modules/store/src/main/scala/docspell/store/records/RAttachment.scala index d79fa439..a63dd4d5 100644 --- a/modules/store/src/main/scala/docspell/store/records/RAttachment.scala +++ b/modules/store/src/main/scala/docspell/store/records/RAttachment.scala @@ -43,7 +43,11 @@ object RAttachment { fId: Ident, fname: Option[String] ): ConnectionIO[Int] = - updateRow(table, id.is(attachId), commas(fileId.setTo(fId), name.setTo(fname))).update.run + updateRow( + table, + id.is(attachId), + commas(fileId.setTo(fId), name.setTo(fname)) + ).update.run def updatePosition(attachId: Ident, pos: Int): ConnectionIO[Int] = updateRow(table, id.is(attachId), position.setTo(pos)).update.run diff --git a/modules/store/src/main/scala/docspell/store/records/RAttachmentArchive.scala b/modules/store/src/main/scala/docspell/store/records/RAttachmentArchive.scala index 2d1b34e0..04dd38b0 100644 --- a/modules/store/src/main/scala/docspell/store/records/RAttachmentArchive.scala +++ b/modules/store/src/main/scala/docspell/store/records/RAttachmentArchive.scala @@ -38,7 +38,11 @@ object RAttachmentArchive { RAttachmentArchive(ra.id, ra.fileId, ra.name, mId, ra.created) def insert(v: RAttachmentArchive): ConnectionIO[Int] = - insertRow(table, all, fr"${v.id},${v.fileId},${v.name},${v.messageId},${v.created}").update.run + insertRow( + table, + all, + fr"${v.id},${v.fileId},${v.name},${v.messageId},${v.created}" + ).update.run def findById(attachId: Ident): ConnectionIO[Option[RAttachmentArchive]] = selectSimple(all, table, id.is(attachId)).query[RAttachmentArchive].option diff --git a/modules/store/src/main/scala/docspell/store/records/RAttachmentMeta.scala b/modules/store/src/main/scala/docspell/store/records/RAttachmentMeta.scala index 9eedd0e2..eeb598fa 100644 --- a/modules/store/src/main/scala/docspell/store/records/RAttachmentMeta.scala +++ b/modules/store/src/main/scala/docspell/store/records/RAttachmentMeta.scala @@ -35,7 +35,11 @@ object RAttachmentMeta { import Columns._ def insert(v: RAttachmentMeta): ConnectionIO[Int] = - insertRow(table, all, fr"${v.id},${v.content},${v.nerlabels},${v.proposals}").update.run + insertRow( + table, + all, + fr"${v.id},${v.content},${v.nerlabels},${v.proposals}" + ).update.run def exists(attachId: Ident): ConnectionIO[Boolean] = selectCount(id, table, id.is(attachId)).query[Int].unique.map(_ > 0) diff --git a/modules/store/src/main/scala/docspell/store/records/RJobLog.scala b/modules/store/src/main/scala/docspell/store/records/RJobLog.scala index 0761f5dd..cbc81183 100644 --- a/modules/store/src/main/scala/docspell/store/records/RJobLog.scala +++ b/modules/store/src/main/scala/docspell/store/records/RJobLog.scala @@ -29,7 +29,11 @@ object RJobLog { import Columns._ def insert(v: RJobLog): ConnectionIO[Int] = - insertRow(table, all, fr"${v.id},${v.jobId},${v.level},${v.created},${v.message}").update.run + insertRow( + table, + all, + fr"${v.id},${v.jobId},${v.level},${v.created},${v.message}" + ).update.run def findLogs(id: Ident): ConnectionIO[Vector[RJobLog]] = (selectSimple(all, table, jobId.is(id)) ++ orderBy(created.asc)) diff --git a/modules/store/src/main/scala/docspell/store/records/RNode.scala b/modules/store/src/main/scala/docspell/store/records/RNode.scala index 51c6e51e..ca6f970e 100644 --- a/modules/store/src/main/scala/docspell/store/records/RNode.scala +++ b/modules/store/src/main/scala/docspell/store/records/RNode.scala @@ -34,7 +34,11 @@ object RNode { import Columns._ def insert(v: RNode): ConnectionIO[Int] = - insertRow(table, all, fr"${v.id},${v.nodeType},${v.url},${v.updated},${v.created}").update.run + insertRow( + table, + all, + fr"${v.id},${v.nodeType},${v.url},${v.updated},${v.created}" + ).update.run def update(v: RNode): ConnectionIO[Int] = updateRow( diff --git a/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala b/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala index 86f47d8f..3287c5ec 100644 --- a/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala +++ b/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala @@ -38,8 +38,8 @@ trait UserTaskStore[F[_]] { /** Return all tasks of the given name and user. The task's arguments * are decoded using the given json decoder. */ - def getByName[A](account: AccountId, name: Ident)( - implicit D: Decoder[A] + def getByName[A](account: AccountId, name: Ident)(implicit + D: Decoder[A] ): Stream[F, UserTask[A]] /** Updates or inserts the given task. @@ -65,8 +65,8 @@ trait UserTaskStore[F[_]] { * error is returned. The task's arguments are decoded using the * given json decoder. */ - def getOneByName[A](account: AccountId, name: Ident)( - implicit D: Decoder[A] + def getOneByName[A](account: AccountId, name: Ident)(implicit + D: Decoder[A] ): OptionT[F, UserTask[A]] /** Updates or inserts the given task. @@ -80,8 +80,8 @@ trait UserTaskStore[F[_]] { * the user `account`, they will all be removed and the given task * inserted! */ - def updateOneTask[A](account: AccountId, ut: UserTask[A])( - implicit E: Encoder[A] + def updateOneTask[A](account: AccountId, ut: UserTask[A])(implicit + E: Encoder[A] ): F[UserTask[String]] /** Delete all tasks of the given user that have name `name'. @@ -100,16 +100,16 @@ object UserTaskStore { def getByNameRaw(account: AccountId, name: Ident): Stream[F, UserTask[String]] = store.transact(QUserTask.findByName(account, name)) - def getByName[A](account: AccountId, name: Ident)( - implicit D: Decoder[A] + def getByName[A](account: AccountId, name: Ident)(implicit + D: Decoder[A] ): Stream[F, UserTask[A]] = getByNameRaw(account, name).flatMap(_.decode match { case Right(ua) => Stream.emit(ua) case Left(err) => Stream.raiseError[F](new Exception(err)) }) - def updateTask[A](account: AccountId, ut: UserTask[A])( - implicit E: Encoder[A] + def updateTask[A](account: AccountId, ut: UserTask[A])(implicit + E: Encoder[A] ): F[Int] = { val exists = QUserTask.exists(ut.id) val insert = QUserTask.insert(account, ut.encode) @@ -142,8 +142,8 @@ object UserTaskStore { } ) - def getOneByName[A](account: AccountId, name: Ident)( - implicit D: Decoder[A] + def getOneByName[A](account: AccountId, name: Ident)(implicit + D: Decoder[A] ): OptionT[F, UserTask[A]] = getOneByNameRaw(account, name) .semiflatMap(_.decode match { @@ -151,8 +151,8 @@ object UserTaskStore { case Left(err) => Effect[F].raiseError(new Exception(err)) }) - def updateOneTask[A](account: AccountId, ut: UserTask[A])( - implicit E: Encoder[A] + def updateOneTask[A](account: AccountId, ut: UserTask[A])(implicit + E: Encoder[A] ): F[UserTask[String]] = getByNameRaw(account, ut.name).compile.toList.flatMap { case a :: rest =>