From 1120434cd94f43ec1777e2ae117356ee8fd6dace Mon Sep 17 00:00:00 2001 From: eikek Date: Sun, 4 Jul 2021 21:37:34 +0200 Subject: [PATCH] Replace generating preview images with an admin endpoint It doesn't make much sense to have this per collective, because this is triggered by an admin after changing the server config file. So it is now implemented as an admin endpoint that affects all files. --- Changelog.md | 12 +++++ .../scala/docspell/backend/ops/OItem.scala | 18 +++++++ .../src/main/resources/docspell-openapi.yml | 50 ++++++++++--------- .../docspell/restserver/RestServer.scala | 7 +-- .../restserver/routes/AttachmentRoutes.scala | 15 ++++++ .../restserver/routes/CollectiveRoutes.scala | 14 +----- tools/preview/regenerate-previews.sh | 19 ++----- .../content/docs/tools/regenerate-previews.md | 10 ++-- 8 files changed, 85 insertions(+), 60 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9ed82b94..0e40338f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,17 @@ # Changelog +## v0.25.0 + +*Unreleased* + +### Rest API Changes + +- Removed `sec/collective/previews` endpoint, in favor for new + `admin/attachments/generatePreviews` endpoint which is now an admin + task to generate previews for all files. The now removed enpoint did + this only for one collective. + + ## v0.24.0 *Jun 18, 2021* 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 88ad4c7d..135162da 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala @@ -193,6 +193,14 @@ trait OItem[F[_]] { account: AccountId, notifyJoex: Boolean ): F[UpdateResult] + + /** Submits a task that (re)generates the preview images for all + * attachments. + */ + def generateAllPreviews( + storeMode: MakePreviewArgs.StoreMode, + notifyJoex: Boolean + ): F[UpdateResult] } object OItem { @@ -699,6 +707,16 @@ object OItem { _ <- if (notifyJoex) joex.notifyAllNodes else ().pure[F] } yield UpdateResult.success + def generateAllPreviews( + storeMode: MakePreviewArgs.StoreMode, + notifyJoex: Boolean + ): F[UpdateResult] = + for { + job <- JobFactory.allPreviews[F](AllPreviewsArgs(None, storeMode), None) + _ <- queue.insertIfNew(job) + _ <- if (notifyJoex) joex.notifyAllNodes else ().pure[F] + } yield UpdateResult.success + private def onSuccessIgnoreError(update: F[Unit])(ar: UpdateResult): F[Unit] = ar match { case UpdateResult.Success => diff --git a/modules/restapi/src/main/resources/docspell-openapi.yml b/modules/restapi/src/main/resources/docspell-openapi.yml index e871a98d..69314c7c 100644 --- a/modules/restapi/src/main/resources/docspell-openapi.yml +++ b/modules/restapi/src/main/resources/docspell-openapi.yml @@ -1136,30 +1136,6 @@ paths: schema: $ref: "#/components/schemas/BasicResult" - /sec/collective/previews: - post: - operationId: "sec-collective-previews-start-generate" - tags: [ Collective ] - summary: Starts the generate previews task - description: | - Submits a task that re-generates preview images of all - attachments of the current collective. Each existing preview - image will be replaced. - - This can be used after changing the `preview` settings. - - If only preview images of selected attachments should be - regenerated, see the `/sec/attachment/{id}/preview` endpoint. - security: - - authTokenHeader: [] - responses: - 200: - description: Ok - content: - application/json: - schema: - $ref: "#/components/schemas/BasicResult" - /sec/user: get: operationId: "sec-user-get-all" @@ -1348,6 +1324,32 @@ paths: schema: $ref: "#/components/schemas/ResetPasswordResult" + /admin/attachments/generatePreviews: + post: + operationId: "admin-attachments-generate-previews" + tags: [Attachment, Admin] + summary: (Re)generate all preview images + description: | + Submits a task that re-generates preview images of all + attachments. Each existing preview image will be replaced. + + This can be used after changing the `preview` settings. + + If only preview images of selected attachments should be + regenerated, see the `/sec/attachment/{id}/preview` endpoint. + + This is an admin route, you need to specify the secret from + the config file via a http header `Docspell-Admin-Secret`. + security: + - adminHeader: [] + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: "#/components/schemas/BasicResult" + /sec/source: get: operationId: "sec-source-get-all" diff --git a/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala b/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala index e3dd4f7a..60a33b6e 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/RestServer.scala @@ -108,9 +108,10 @@ object RestServer { def adminRoutes[F[_]: Async](cfg: Config, restApp: RestApp[F]): HttpRoutes[F] = Router( - "fts" -> FullTextIndexRoutes.admin(cfg, restApp.backend), - "user" -> UserRoutes.admin(restApp.backend), - "info" -> InfoRoutes.admin(cfg) + "fts" -> FullTextIndexRoutes.admin(cfg, restApp.backend), + "user" -> UserRoutes.admin(restApp.backend), + "info" -> InfoRoutes.admin(cfg), + "attachments" -> AttachmentRoutes.admin(restApp.backend) ) def redirectTo[F[_]: Async](path: String): HttpRoutes[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 57c5e2fb..85b02b42 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/AttachmentRoutes.scala @@ -189,4 +189,19 @@ object AttachmentRoutes { } yield resp } } + + def admin[F[_]: Async](backend: BackendApp[F]): HttpRoutes[F] = { + val dsl = Http4sDsl[F] + import dsl._ + + HttpRoutes.of { case POST -> Root / "generatePreviews" => + for { + res <- backend.item.generateAllPreviews(MakePreviewArgs.StoreMode.Replace, true) + resp <- Ok( + Conversions.basicResult(res, "Generate all previews task submitted.") + ) + } 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 1fd00d7d..3cbb27cd 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/CollectiveRoutes.scala @@ -12,7 +12,7 @@ import cats.implicits._ import docspell.backend.BackendApp import docspell.backend.auth.AuthToken import docspell.backend.ops.OCollective -import docspell.common.{ListType, MakePreviewArgs} +import docspell.common.ListType import docspell.restapi.model._ import docspell.restserver.conv.Conversions import docspell.restserver.http4s._ @@ -101,18 +101,6 @@ object CollectiveRoutes { resp <- Ok(BasicResult(true, "Task submitted")) } yield resp - case POST -> Root / "previews" => - for { - res <- backend.collective.generatePreviews( - MakePreviewArgs.StoreMode.Replace, - user.account, - true - ) - resp <- Ok( - Conversions.basicResult(res, "Generate all previews task submitted.") - ) - } yield resp - case GET -> Root => for { collDb <- backend.collective.find(user.account.collective) diff --git a/tools/preview/regenerate-previews.sh b/tools/preview/regenerate-previews.sh index cc474c66..fdba0c67 100755 --- a/tools/preview/regenerate-previews.sh +++ b/tools/preview/regenerate-previews.sh @@ -11,23 +11,12 @@ JQ_CMD="jq" BASE_URL="${1:-http://localhost:7880}" -LOGIN_URL="$BASE_URL/api/v1/open/auth/login" -TRIGGER_URL="$BASE_URL/api/v1/sec/collective/previews" +TRIGGER_URL="$BASE_URL/api/v1/admin/attachments/generatePreviews" echo "Login to trigger regenerating preview images." echo "Using url: $BASE_URL" -echo -n "Account: " -read USER -echo -n "Password: " -read -s PASS +echo -n "Admin Secret: " +read -s ADMIN_SECRET echo -auth=$("$CURL_CMD" --fail -XPOST --silent --data-binary "{\"account\":\"$USER\", \"password\":\"$PASS\"}" "$LOGIN_URL") - -if [ "$(echo $auth | $JQ_CMD .success)" == "true" ]; then - echo "Login successful" - auth_token=$(echo $auth | "$JQ_CMD" -r .token) - curl --fail -XPOST -H "X-Docspell-Auth: $auth_token" "$TRIGGER_URL" -else - echo "Login failed." -fi +curl --fail -XPOST -H "Docspell-Admin-Secret: $ADMIN_SECRET" "$TRIGGER_URL" diff --git a/website/site/content/docs/tools/regenerate-previews.md b/website/site/content/docs/tools/regenerate-previews.md index 878a56ef..114f1c40 100644 --- a/website/site/content/docs/tools/regenerate-previews.md +++ b/website/site/content/docs/tools/regenerate-previews.md @@ -20,18 +20,18 @@ It is a bash script that additionally needs # Usage ``` -./regenerate-previews.sh [docspell-base-url] +./regenerate-previews.sh [docspell-base-url] [admin-secret] ``` For example, if docspell is at `http://localhost:7880`: ``` -./convert-all-pdfs.sh http://localhost:7880 +./convert-all-pdfs.sh http://localhost:7880 test123 ``` -The script asks for your account name and password. It then logs in -and triggers the said endpoint. After this you should see a few tasks -running. +The script asks for the admin secret if not given to the command. It +then logs in and triggers the said endpoint. After this you should see +a few tasks running. There will be one task per file to convert. All these tasks are submitted with a low priority. So files uploaded through the webapp or