From a5a66419e88ef4f8b97b1c1dfbba5adb23fea4fe Mon Sep 17 00:00:00 2001 From: Malte Brandy Date: Sat, 11 Apr 2020 01:42:01 +0200 Subject: [PATCH] Add mail-sorting-setup --- common/secret/default.nix | Bin 12738 -> 16218 bytes home/modules/mail.nix | 117 ++++++++++++++++++++++++++++++++++++-- lib/default.nix | 26 ++++++--- 3 files changed, 130 insertions(+), 13 deletions(-) diff --git a/common/secret/default.nix b/common/secret/default.nix index 46af7b390ed304b49377d430e9817dfeb398b1a3..c173e418a7a0318acfa3efa79bcd19a447e8998d 100644 GIT binary patch literal 16218 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 literal 12738 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 IWMQA1uaGg-Y5)KL diff --git a/home/modules/mail.nix b/home/modules/mail.nix index 200d53ad..6087fad8 100644 --- a/home/modules/mail.nix +++ b/home/modules/mail.nix @@ -1,9 +1,114 @@ { lib, config, pkgs, ... }: with lib; let + inherit (import ../../lib) writeHaskellScript; mail = config.m-0.mail; inherit (config.m-0.private) sendmail me; + inherit (config.m-0.private.mail_filters) sortLists stupidLists notifications; maildir = config.accounts.email.maildirBasePath; + # mhdr -h List-ID -d Maildir/hera/Archiv/unsortiert | sort | sed 's/^.*<\(.*\)>$/\1/' | uniq | xargs -I '{}' sh -c "notmuch count List:{} | sed 's/$/: {}/'" | sort + # To find candidates + archiveSuffix = "hera/Archiv"; + unsortedSuffix = "${archiveSuffix}/unsortiert"; + unsorted = "${maildir}/${unsortedSuffix}"; + archive = "${maildir}/${archiveSuffix}"; + filter = rec { + mailToFolder = name: + toFolder (lib.concatStringsSep "." (splitString "@" name)); + toFolder = name: + lib.concatStringsSep "/" (lib.reverseList (lib.splitString "." name)); + simple = filter: target: { inherit filter target; }; + notifications = notify: + simple "from:${notify}" "notifications/${mailToFolder notify}"; + stupidList = list: simple "to:${list}" "list/${mailToFolder list}"; + simpleSortList = listName: + simple "List:${listName}" "list/${toFolder listName}"; + }; + myFilters = builtins.map filter.simpleSortList sortLists + ++ builtins.map filter.stupidList stupidLists + ++ builtins.map filter.notifications notifications; + sortMail = writeHaskellScript { + name = "sort-mail-archive"; + bins = [ pkgs.notmuch pkgs.coreutils pkgs.mblaze pkgs.findutils ]; + libraries = [ pkgs.haskellPackages.megaparsec ]; + imports = [ + "Text.Megaparsec" + "Text.Megaparsec.Char" + "Text.Megaparsec.Char.Lexer" + "qualified Data.List.NonEmpty as NE" + "qualified Data.Text as T" + "System.Environment (setEnv)" + ]; + } '' + reScan = notmuch "new" + + findFilterMail :: (Text,Text) -> IO (Maybe (LByteString, Text, Text)) + findFilterMail (filter, target) = do + files <- notmuch "search" "--output" "files" (toString filter) "folder:${unsortedSuffix}" |> capture + pure $ if (LBS.length files > 0) then Just (files, filter, target) else Nothing + + executeFilterMail :: (LByteString, Text, Text) -> IO () + executeFilterMail (files, filter, target) = do + putTextLn [i|Sorting "#{filter}" into #{target}|] + writeOutput files |> mscan + mmkdir ([i|${archive}/#{target}|] :: String) + writeOutput files |> mrefile ([i|${archive}/#{target}|] :: String) + + myFilters :: [(Text,Text)] + myFilters = [${ + lib.concatStringsSep "," + (builtins.map ({ filter, target }: ''("${filter}","${target}")'') + myFilters) + }] + + filtersFromTo :: Text -> Maybe (Text,Text) + filtersFromTo = filtersFromField "to" [toToName] + toToName :: Text -> Maybe Text + toToName (T.splitOn "@" -> [name, "maralorn.de"]) + | not (T.isInfixOf "randy" name) = Just . ("to/" <>) . T.intercalate "_" . T.splitOn "." $ name + toToName _ = Nothing + filtersFromField :: Text -> [Text-> Maybe Text] -> Text -> Maybe (Text,Text) + filtersFromField field filters text = fmap ([i|#{field}:#{text}|],) . viaNonEmpty Relude.head . mapMaybe ($ text) $ filters + filtersFromListIDs :: Text -> Maybe (Text,Text) + filtersFromListIDs = filtersFromField "List" [githubNameFolderFromId, gitlabNameFolderFromId] + githubNameFolderFromId :: Text -> Maybe Text + githubNameFolderFromId (reverse . T.splitOn "." -> ("com":"github":org:name)) = Just [i|github/#{org}/#{T.intercalate "_" $ reverse name}|] + githubNameFolderFromId _ = Nothing + gitlabNameFolderFromId :: Text -> Maybe Text + gitlabNameFolderFromId (reverse . T.splitOn "." -> ("de":"ccc":"darmstadt":"git":org:name1:name)) = Just [i|cda-gitlab/#{org}/#{T.intercalate "_" . toList . Relude.tail $ NE.reverse (name1:|name)}|] + gitlabNameFolderFromId _ = Nothing + + type Parser = Parsec Text Text + listId :: Parser Text + listId = manyTill anySingle (char '<') *> (toText <$> manyTill anySingle (char '>')) + + mySearch :: [String] -> IO [Text] + mySearch param = lines . decodeUtf8 <$> (Main.find ("${archive}":param) |> captureTrim) + + main :: IO () + main = do + setEnv "MBLAZE_PAGER" "cat" + setEnv "NOTMUCH_CONFIG" "${config.home.sessionVariables.NOTMUCH_CONFIG}" + reScan + (listIDs,tos) <- concurrently (mhdr "-h" "List-ID" "-d" "${unsorted}" |> capture) (mhdr "-h" "To" "-d" "${unsorted}" "-A" |> capture) + let listFilters = mapMaybe filtersFromListIDs . sortNub . mapMaybe (parseMaybe listId) . lines . decodeUtf8 $ listIDs + toFilters = mapMaybe filtersFromTo . sortNub . fmap (\x -> maybe x Relude.id $ parseMaybe listId x) . lines . decodeUtf8 $ tos + applicableFilters <- catMaybes <$> forConcurrently (listFilters <> myFilters <> toFilters) findFilterMail + for_ applicableFilters executeFilterMail + reScan + syncStates <- mySearch ["-name", ".mbsyncstate"] + dbFiles <- mySearch ["-name", ".isyncuidmap.db"] + dirs <- mySearch ["-type", "d"] + maildirs <- sortNub <$> (lines . decodeUtf8 =<<) <$> forM dirs (\dir -> mdirs (toString dir) |> captureTrim) + emptyMaildirs <- filterM (\dir -> (== 0) . LBS.length <$> (mlist (toString dir) |> captureTrim)) maildirs + forM_ emptyMaildirs $ \dir -> rmdir ([[i|#{dir}/cur|],[i|#{dir}/new|],[i|#{dir}/tmp|]] :: [String]) + let nonMaildirs = filter (`notElem` maildirs) dirs + delSyncs = filter (`elem` syncStates) $ (\x -> [i|#{x}/.mbsyncstate|]) <$> nonMaildirs + delDbs = filter (`elem` dbFiles) $ (\x -> [i|#{x}/.isyncuidmap.db|]) <$> nonMaildirs + whenNotNull (delSyncs ++ delDbs) $ rm . fmap toString . toList + emptyDirs <- Main.find "${archive}" "-type" "d" "-empty" "!" "-name" "cur" "!" "-name" "tmp" "!" "-name" "new" "-print0" |> capture + when (LBS.length emptyDirs > 0) $ writeOutput emptyDirs |> xargs "-0" "rmdir" + ''; in { options.m-0.mail.enable = mkEnableOption "private-mail"; @@ -15,8 +120,7 @@ in { enable = true; frequency = "*:0/30"; verbose = false; - postExec = - "${pkgs.notmuch}/bin/notmuch --config=${config.home.sessionVariables.NOTMUCH_CONFIG} new"; + postExec = "${sortMail}/bin/sort-mail-archive"; }; accounts.email.accounts = config.m-0.mail.accounts; @@ -75,8 +179,9 @@ in { }; maildir.synchronizeFlags = true; }; + home = { - packages = with pkgs; [ neomutt ]; + packages = [ pkgs.neomutt sortMail ]; file = let mutt_alternates = "@maralorn.de " + (builtins.concatStringsSep " " me.alternates); @@ -166,9 +271,9 @@ in { source "${hide-sidebar}" macro index "source ${hide-sidebar}" macro index "source ${show-sidebar}" - set sidebar_folder_indent=yes - set sidebar_short_path=yes - set sidebar_width=40 + set sidebar_folder_indent=no + set sidebar_short_path=no + set sidebar_width=60 set sidebar_sort_method="alpha" set sidebar_indent_string=" " color sidebar_indicator black white diff --git a/lib/default.nix b/lib/default.nix index 0163834e..9f151479 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -45,13 +45,22 @@ rec { writeHaskellScript = { name ? "haskell-script", bins ? [ ], libraries ? [ ], imports ? [ ] }: code: - pkgs.writers.writeHaskellBin name { - libraries = libraries ++ [ - shh - pkgs.haskellPackages.string-interpolate - pkgs.haskellPackages.relude - ]; - } '' + pkgs.writers.makeBinWriter { + compileScript = '' + cp $contentPath ${name}.hs + ${ + pkgs.ghc.withPackages (_: + libraries ++ [ + shh + pkgs.haskellPackages.string-interpolate + pkgs.haskellPackages.relude + pkgs.haskellPackages.async + ]) + }/bin/ghc ${name}.hs -threaded + mv ${name} $out + ${pkgs.binutils-unwrapped}/bin/strip --strip-unneeded "$out" + ''; + } "/bin/${name}" '' {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE QuasiQuotes #-} @@ -62,15 +71,18 @@ rec { {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NoImplicitPrelude #-} + {-# LANGUAGE TupleSections #-} import Shh import Relude import qualified Relude.Unsafe as Unsafe + import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString as BS import qualified Data.Text as Text import System.Environment (getArgs) import Control.Exception (bracket, try) import Data.String.Interpolate (i) + import Control.Concurrent.Async ${builtins.concatStringsSep "\n" (map (x: "import ${x}") imports)} -- Load binaries from Nix packages. The dependencies will be captured