Merge pull request #439 from eikek/mail-subject-filter

Mail subject filter
This commit is contained in:
mergify[bot] 2020-11-13 23:07:12 +00:00 committed by GitHub
commit b0bd7e417f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 46 deletions

View File

@ -33,7 +33,9 @@ case class ScanMailboxArgs(
// set a filter for files when importing archives
fileFilter: Option[Glob],
// set a list of tags to apply to new item
tags: Option[List[String]]
tags: Option[List[String]],
// a glob filter for the mail subject
subjectFilter: Option[Glob]
)
object ScanMailboxArgs {

View File

@ -142,7 +142,7 @@ object ScanMailboxTask {
_ <- Kleisli.liftF(ctx.logger.info(s"Processing folder $name"))
folder <- requireFolder(a)(name)
search <- searchMails(a)(folder)
headers <- Kleisli.liftF(filterMessageIds(search.mails))
headers <- Kleisli.liftF(filterSubjects(search.mails).flatMap(filterMessageIds))
_ <- headers.traverse(handleOne(ctx.args, a, upload))
} yield ScanResult(name, search.mails.size, search.count - search.mails.size)
@ -178,6 +178,26 @@ object ScanMailboxTask {
} yield mails
}
def filterSubjects(headers: Vector[MailHeader]): F[Vector[MailHeader]] =
ctx.args.subjectFilter match {
case Some(sf) =>
def check(mh: MailHeader): F[Option[MailHeader]] =
if (sf.matches(mh.subject))
ctx.logger.debug(
s"Including mail '${mh.subject}', it matches the filter."
) *> Option(mh).pure[F]
else
ctx.logger.debug(
s"Excluding mail '${mh.subject}', it doesn't match the filter."
) *> (None: Option[MailHeader]).pure[F]
ctx.logger.info(
s"Filtering mails on subject using filter: ${sf.asString}"
) *> headers.traverseFilter(check)
case None =>
ctx.logger.debug("Not matching on subjects. No filter given") *> headers.pure[F]
}
def filterMessageIds(headers: Vector[MailHeader]): F[Vector[MailHeader]] =
NonEmptyList.fromFoldable(headers.flatMap(_.messageId)) match {
case Some(nl) =>

View File

@ -3503,7 +3503,12 @@ components:
$ref: "#/components/schemas/StringList"
fileFilter:
description: |
A glob to filter attachments to import.
A glob to filter attachments to import by file name.
type: string
format: glob
subjectFilter:
description: |
A glob to filter attachments to import by subject.
type: string
format: glob

View File

@ -115,7 +115,8 @@ object ScanMailboxRoutes {
settings.direction,
settings.itemFolder,
settings.fileFilter,
settings.tags.map(_.items)
settings.tags.map(_.items),
settings.subjectFilter
)
)
)
@ -137,7 +138,7 @@ object ScanMailboxRoutes {
task.id,
task.enabled,
conn.getOrElse(Ident.unsafe("")),
task.args.folders, //folders
task.args.folders,
task.timer,
task.args.receivedSince.map(_.hours.toInt),
task.args.targetFolder,
@ -145,6 +146,7 @@ object ScanMailboxRoutes {
task.args.direction,
task.args.itemFolder,
task.args.tags.map(StringList.apply),
task.args.fileFilter
task.args.fileFilter,
task.args.subjectFilter
)
}

View File

@ -63,6 +63,7 @@ type alias Model =
, tagModel : Comp.Dropdown.Model Tag
, existingTags : List String
, fileFilter : Maybe String
, subjectFilter : Maybe String
}
@ -94,6 +95,7 @@ type Msg
| GetTagResp (Result Http.Error TagList)
| TagDropdownMsg (Comp.Dropdown.Msg Tag)
| SetFileFilter String
| SetSubjectFilter String
initWith : Flags -> ScanMailboxSettings -> ( Model, Cmd Msg )
@ -135,6 +137,7 @@ initWith flags s =
Maybe.map .items s.tags
|> Maybe.withDefault []
, fileFilter = s.fileFilter
, subjectFilter = s.subjectFilter
}
, Cmd.batch
[ Api.getImapSettings flags "" ConnResp
@ -184,6 +187,7 @@ init flags =
, tagModel = Util.Tag.makeDropdownModel
, existingTags = []
, fileFilter = Nothing
, subjectFilter = Nothing
}
, Cmd.batch
[ Api.getImapSettings flags "" ConnResp
@ -228,6 +232,7 @@ makeSettings model =
, schedule = Data.CalEvent.makeEvent timer
, itemFolder = model.itemFolderId
, fileFilter = model.fileFilter
, subjectFilter = model.subjectFilter
, tags =
case Comp.Dropdown.getSelected model.tagModel of
[] ->
@ -586,6 +591,12 @@ update flags msg model =
, Cmd.none
)
SetSubjectFilter str ->
( { model | subjectFilter = Util.Maybe.fromString str }
, NoAction
, Cmd.none
)
--- View
@ -653,13 +664,6 @@ view extraClasses settings model =
[ text "The folders to go through"
]
]
, Html.map ReceivedHoursMsg
(Comp.IntField.viewWithInfo
"Select mails newer than `now - receivedHours`"
model.receivedHours
"field"
model.receivedHoursModel
)
, div [ class "field" ]
[ label [] [ text "Target folder" ]
, input
@ -688,6 +692,74 @@ view extraClasses settings model =
, text " is not set."
]
]
, div [ class "ui dividing header" ]
[ text "Filter"
]
, Html.map ReceivedHoursMsg
(Comp.IntField.viewWithInfo
"Select mails newer than `now - receivedHours`"
model.receivedHours
"field"
model.receivedHoursModel
)
, div
[ class "field"
]
[ label [] [ text "File Filter" ]
, input
[ type_ "text"
, onInput SetFileFilter
, placeholder "File Filter"
, model.fileFilter
|> Maybe.withDefault ""
|> value
]
[]
, div [ class "small-info" ]
[ text "Specify a file glob to filter attachments. For example, to only extract pdf files: "
, code []
[ text "*.pdf"
]
, text ". If you want to include the mail body, allow html files or "
, code []
[ text "mail.html"
]
, text ". Globs can be combined via OR, like this: "
, code []
[ text "*.pdf|mail.html"
]
, text ". No file filter defaults to "
, code []
[ text "*"
]
, text " that includes all"
]
]
, div
[ class "field"
]
[ label [] [ text "Subject Filter" ]
, input
[ type_ "text"
, onInput SetSubjectFilter
, placeholder "Subject Filter"
, model.subjectFilter
|> Maybe.withDefault ""
|> value
]
[]
, div [ class "small-info" ]
[ text "Specify a file glob to filter mails by subject. For example: "
, code []
[ text "*Scanned Document*"
]
, text ". No file filter defaults to "
, code []
[ text "*"
]
, text " that includes all"
]
]
, div [ class "ui dividing header" ]
[ text "Metadata"
]
@ -763,39 +835,6 @@ disappear then.
[ text "Choose tags that should be applied to items."
]
]
, div
[ class "field"
]
[ label [] [ text "File Filter" ]
, input
[ type_ "text"
, onInput SetFileFilter
, placeholder "File Filter"
, model.fileFilter
|> Maybe.withDefault ""
|> value
]
[]
, div [ class "small-info" ]
[ text "Specify a file glob to filter attachments. For example, to only extract pdf files: "
, code []
[ text "*.pdf"
]
, text ". If you want to include the mail body, allow html files or "
, code []
[ text "mail.html"
]
, text ". Globs can be combined via OR, like this: "
, code []
[ text "*.pdf|mail.html"
]
, text "No file filter defaults to "
, code []
[ text "*"
]
, text " that includes all"
]
]
, div [ class "ui dividing header" ]
[ text "Schedule"
]