mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-11-04 12:30:12 +00:00 
			
		
		
		
	Add start-now button for train-classifier task
This commit is contained in:
		@@ -53,7 +53,7 @@ object BackendApp {
 | 
			
		||||
      loginImpl      <- Login[F](store)
 | 
			
		||||
      signupImpl     <- OSignup[F](store)
 | 
			
		||||
      joexImpl       <- OJoex(JoexClient(httpClient), store)
 | 
			
		||||
      collImpl       <- OCollective[F](store, utStore, joexImpl)
 | 
			
		||||
      collImpl       <- OCollective[F](store, utStore, queue, joexImpl)
 | 
			
		||||
      sourceImpl     <- OSource[F](store)
 | 
			
		||||
      tagImpl        <- OTag[F](store)
 | 
			
		||||
      equipImpl      <- OEquipment[F](store)
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,13 @@ import docspell.backend.PasswordCrypt
 | 
			
		||||
import docspell.backend.ops.OCollective._
 | 
			
		||||
import docspell.common._
 | 
			
		||||
import docspell.store.queries.QCollective
 | 
			
		||||
import docspell.store.queue.JobQueue
 | 
			
		||||
import docspell.store.records._
 | 
			
		||||
import docspell.store.usertask.UserTask
 | 
			
		||||
import docspell.store.usertask.UserTaskStore
 | 
			
		||||
import docspell.store.{AddResult, Store}
 | 
			
		||||
 | 
			
		||||
import com.github.eikek.calev.CalEvent
 | 
			
		||||
import com.github.eikek.calev._
 | 
			
		||||
 | 
			
		||||
trait OCollective[F[_]] {
 | 
			
		||||
 | 
			
		||||
@@ -49,6 +50,7 @@ trait OCollective[F[_]] {
 | 
			
		||||
 | 
			
		||||
  def findEnabledSource(sourceId: Ident): F[Option[RSource]]
 | 
			
		||||
 | 
			
		||||
  def startLearnClassifier(collective: Ident): F[Unit]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object OCollective {
 | 
			
		||||
@@ -102,6 +104,7 @@ object OCollective {
 | 
			
		||||
  def apply[F[_]: Effect](
 | 
			
		||||
      store: Store[F],
 | 
			
		||||
      uts: UserTaskStore[F],
 | 
			
		||||
      queue: JobQueue[F],
 | 
			
		||||
      joex: OJoex[F]
 | 
			
		||||
  ): Resource[F, OCollective[F]] =
 | 
			
		||||
    Resource.pure[F, OCollective[F]](new OCollective[F] {
 | 
			
		||||
@@ -131,6 +134,21 @@ object OCollective {
 | 
			
		||||
          _ <- joex.notifyAllNodes
 | 
			
		||||
        } yield ()
 | 
			
		||||
 | 
			
		||||
      def startLearnClassifier(collective: Ident): F[Unit] =
 | 
			
		||||
        for {
 | 
			
		||||
          id <- Ident.randomId[F]
 | 
			
		||||
          ut <- UserTask(
 | 
			
		||||
            id,
 | 
			
		||||
            LearnClassifierArgs.taskName,
 | 
			
		||||
            true,
 | 
			
		||||
            CalEvent(WeekdayComponent.All, DateEvent.All, TimeEvent.All),
 | 
			
		||||
            LearnClassifierArgs(collective)
 | 
			
		||||
          ).encode.toPeriodicTask(AccountId(collective, LearnClassifierArgs.taskName))
 | 
			
		||||
          job <- ut.toJob
 | 
			
		||||
          _   <- queue.insert(job)
 | 
			
		||||
          _   <- joex.notifyAllNodes
 | 
			
		||||
        } yield ()
 | 
			
		||||
 | 
			
		||||
      def findSettings(collective: Ident): F[Option[OCollective.Settings]] =
 | 
			
		||||
        store.transact(RCollective.getSettings(collective))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1047,6 +1047,28 @@ paths:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: "#/components/schemas/ContactList"
 | 
			
		||||
 | 
			
		||||
  /sec/collective/classifier/startonce:
 | 
			
		||||
    post:
 | 
			
		||||
      tags: [ Collective ]
 | 
			
		||||
      summary: Starts the learn-classifier task
 | 
			
		||||
      description: |
 | 
			
		||||
        If the collective has classification enabled, this will submit
 | 
			
		||||
        the task for learning a classifier from existing data. This
 | 
			
		||||
        task is usally run periodically as determined by the
 | 
			
		||||
        collective settings.
 | 
			
		||||
 | 
			
		||||
        The request is empty, settings are used from the collective.
 | 
			
		||||
      security:
 | 
			
		||||
        - authTokenHeader: []
 | 
			
		||||
      responses:
 | 
			
		||||
        200:
 | 
			
		||||
          description: Ok
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: "#/components/schemas/BasicResult"
 | 
			
		||||
 | 
			
		||||
  /sec/user:
 | 
			
		||||
    get:
 | 
			
		||||
      tags: [ Collective ]
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,12 @@ object CollectiveRoutes {
 | 
			
		||||
          resp <- Ok(ContactList(res.map(Conversions.mkContact)))
 | 
			
		||||
        } yield resp
 | 
			
		||||
 | 
			
		||||
      case POST -> Root / "classifier" / "startonce" =>
 | 
			
		||||
        for {
 | 
			
		||||
          _    <- backend.collective.startLearnClassifier(user.account.collective)
 | 
			
		||||
          resp <- Ok(BasicResult(true, "Task submitted"))
 | 
			
		||||
        } yield resp
 | 
			
		||||
 | 
			
		||||
      case GET -> Root =>
 | 
			
		||||
        for {
 | 
			
		||||
          collDb <- backend.collective.find(user.account.collective)
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ module Api exposing
 | 
			
		||||
    , setItemNotes
 | 
			
		||||
    , setTags
 | 
			
		||||
    , setUnconfirmed
 | 
			
		||||
    , startClassifier
 | 
			
		||||
    , startOnceNotifyDueItems
 | 
			
		||||
    , startOnceScanMailbox
 | 
			
		||||
    , startReIndex
 | 
			
		||||
@@ -795,6 +796,19 @@ versionInfo flags receive =
 | 
			
		||||
--- Collective
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
startClassifier :
 | 
			
		||||
    Flags
 | 
			
		||||
    -> (Result Http.Error BasicResult -> msg)
 | 
			
		||||
    -> Cmd msg
 | 
			
		||||
startClassifier flags receive =
 | 
			
		||||
    Http2.authPost
 | 
			
		||||
        { url = flags.config.baseUrl ++ "/api/v1/sec/collective/classifier/startonce"
 | 
			
		||||
        , account = getAccount flags
 | 
			
		||||
        , body = Http.emptyBody
 | 
			
		||||
        , expect = Http.expectJson receive Api.Model.BasicResult.decoder
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
getTagCloud : Flags -> (Result Http.Error TagCloud -> msg) -> Cmd msg
 | 
			
		||||
getTagCloud flags receive =
 | 
			
		||||
    Http2.authGet
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ type alias Model =
 | 
			
		||||
    , fullTextConfirmText : String
 | 
			
		||||
    , fullTextReIndexResult : Maybe BasicResult
 | 
			
		||||
    , classifierModel : Comp.ClassifierSettingsForm.Model
 | 
			
		||||
    , startClassifierResult : Maybe BasicResult
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +61,7 @@ init flags settings =
 | 
			
		||||
      , fullTextConfirmText = ""
 | 
			
		||||
      , fullTextReIndexResult = Nothing
 | 
			
		||||
      , classifierModel = cm
 | 
			
		||||
      , startClassifierResult = Nothing
 | 
			
		||||
      }
 | 
			
		||||
    , Cmd.map ClassifierSettingMsg cc
 | 
			
		||||
    )
 | 
			
		||||
@@ -91,6 +93,8 @@ type Msg
 | 
			
		||||
    | TriggerReIndexResult (Result Http.Error BasicResult)
 | 
			
		||||
    | ClassifierSettingMsg Comp.ClassifierSettingsForm.Msg
 | 
			
		||||
    | SaveSettings
 | 
			
		||||
    | StartClassifierTask
 | 
			
		||||
    | StartClassifierResp (Result Http.Error BasicResult)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe CollectiveSettings )
 | 
			
		||||
@@ -169,12 +173,30 @@ update flags msg model =
 | 
			
		||||
                _ ->
 | 
			
		||||
                    ( model, Cmd.none, Nothing )
 | 
			
		||||
 | 
			
		||||
        StartClassifierTask ->
 | 
			
		||||
            ( model, Api.startClassifier flags StartClassifierResp, Nothing )
 | 
			
		||||
 | 
			
		||||
        StartClassifierResp (Ok br) ->
 | 
			
		||||
            ( { model | startClassifierResult = Just br }
 | 
			
		||||
            , Cmd.none
 | 
			
		||||
            , Nothing
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        StartClassifierResp (Err err) ->
 | 
			
		||||
            ( { model
 | 
			
		||||
                | startClassifierResult =
 | 
			
		||||
                    Just (BasicResult False (Util.Http.errorToString err))
 | 
			
		||||
              }
 | 
			
		||||
            , Cmd.none
 | 
			
		||||
            , Nothing
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
view : Flags -> UiSettings -> Model -> Html Msg
 | 
			
		||||
view flags settings model =
 | 
			
		||||
    div
 | 
			
		||||
        [ classList
 | 
			
		||||
            [ ( "ui form", True )
 | 
			
		||||
            [ ( "ui form error success", True )
 | 
			
		||||
            , ( "error", Maybe.map .success model.fullTextReIndexResult == Just False )
 | 
			
		||||
            , ( "success", Maybe.map .success model.fullTextReIndexResult == Just True )
 | 
			
		||||
            ]
 | 
			
		||||
@@ -250,18 +272,7 @@ view flags settings model =
 | 
			
		||||
                [ text "This starts a task that clears the full-text index and re-indexes all your data again."
 | 
			
		||||
                , text "You must type OK before clicking the button to avoid accidental re-indexing."
 | 
			
		||||
                ]
 | 
			
		||||
            , div
 | 
			
		||||
                [ classList
 | 
			
		||||
                    [ ( "ui message", True )
 | 
			
		||||
                    , ( "error", Maybe.map .success model.fullTextReIndexResult == Just False )
 | 
			
		||||
                    , ( "success", Maybe.map .success model.fullTextReIndexResult == Just True )
 | 
			
		||||
                    , ( "hidden invisible", model.fullTextReIndexResult == Nothing )
 | 
			
		||||
                    ]
 | 
			
		||||
                ]
 | 
			
		||||
                [ Maybe.map .message model.fullTextReIndexResult
 | 
			
		||||
                    |> Maybe.withDefault ""
 | 
			
		||||
                    |> text
 | 
			
		||||
                ]
 | 
			
		||||
            , renderResultMessage model.fullTextReIndexResult
 | 
			
		||||
            ]
 | 
			
		||||
        , h3
 | 
			
		||||
            [ classList
 | 
			
		||||
@@ -279,6 +290,19 @@ view flags settings model =
 | 
			
		||||
            ]
 | 
			
		||||
            [ Html.map ClassifierSettingMsg
 | 
			
		||||
                (Comp.ClassifierSettingsForm.view model.classifierModel)
 | 
			
		||||
            , div [ class "ui vertical segment" ]
 | 
			
		||||
                [ button
 | 
			
		||||
                    [ classList
 | 
			
		||||
                        [ ( "ui small secondary basic button", True )
 | 
			
		||||
                        , ( "disabled", not model.classifierModel.enabled )
 | 
			
		||||
                        ]
 | 
			
		||||
                    , title "Starts a task to train a classifier"
 | 
			
		||||
                    , onClick StartClassifierTask
 | 
			
		||||
                    ]
 | 
			
		||||
                    [ text "Start now"
 | 
			
		||||
                    ]
 | 
			
		||||
                , renderResultMessage model.startClassifierResult
 | 
			
		||||
                ]
 | 
			
		||||
            ]
 | 
			
		||||
        , div [ class "ui divider" ] []
 | 
			
		||||
        , button
 | 
			
		||||
@@ -291,3 +315,19 @@ view flags settings model =
 | 
			
		||||
            [ text "Save"
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
renderResultMessage : Maybe BasicResult -> Html msg
 | 
			
		||||
renderResultMessage result =
 | 
			
		||||
    div
 | 
			
		||||
        [ classList
 | 
			
		||||
            [ ( "ui message", True )
 | 
			
		||||
            , ( "error", Maybe.map .success result == Just False )
 | 
			
		||||
            , ( "success", Maybe.map .success result == Just True )
 | 
			
		||||
            , ( "hidden invisible", result == Nothing )
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
        [ Maybe.map .message result
 | 
			
		||||
            |> Maybe.withDefault ""
 | 
			
		||||
            |> text
 | 
			
		||||
        ]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user