<commit_before>{-# Language QuasiQuotes, OverloadedStrings #-}
{-|
Module      : Client.Hook.Snotice
Description : Hook for sorting some service notices into separate windows.
Copyright   : (c) <NAME> 2019
License     : ISC
Maintainer  : <EMAIL>

These sorting rules are based on the solanum server notices.

-}
module Client.Hook.Snotice
  ( snoticeHook
  ) where

import qualified Data.Text as Text
import           Data.Text (Text)
import           Data.List (find)
import           Text.Regex.TDFA
import           Text.Regex.TDFA.String

import           Client.Hook
import           Irc.Message
import           Irc.Identifier (mkId, Identifier)
import           Irc.UserInfo
import           StrQuote (str)

snoticeHook :: MessageHook
snoticeHook = MessageHook "snotice" True remap

remap ::
  IrcMsg -> MessageResult

remap (Notice (Source (UserInfo u "" "") _) _ msg)
  | Just msg1 <- Text.stripPrefix "*** Notice -- " msg
  , let msg2 = Text.filter (\x -> x /= '\x02' && x /= '\x0f') msg1
  , Just (lvl, cat) <- characterize msg2
  = if lvl < 1 then OmitMessage
               else RemapMessage (Notice (Source (UserInfo u "" "*") "") cat msg1)

remap _ = PassMessage

toPattern :: (Int, String, String) -> (Int, Identifier, Regex)
toPattern (lvl, cat, reStr) =
  case compile co eo reStr of
    Left e  -> error e
    Right r -> (lvl, mkId (Text.pack ('~':cat)), r)
  where
    co = CompOption
      { caseSensitive  = True
      , multiline      = False
      , rightAssoc     = True
      , newSyntax      = True
      , lastStarGreedy = True }
    eo = ExecOption
      { captureGroups  = False }

characterize :: Text -> Maybe (Int, Identifier)
characterize txt =
  do let s = Text.unpack txt
     (lvl, cat, _) <- find (\(_, _, re) -> matchTest re s) patterns
     pure (lvl, cat)

patterns :: [(Int, Identifier, Regex)]
patterns = map toPattern
    [
    -- PATTERN LIST, most common snotes
    -- Client connecting, more complete regex: ^Client connecting: [^ ]+ \([^ ]+@[^ ]+\) \[[^ ]+\] \{[^ ]+\} \[.*\]$
    (1, "c", [str|^Client connecting: |]),
    -- Client exiting, more complete regex: ^Client exiting: [^ ]+ \([^ ]+@[^ ]+\) \[.*\] \[[^ ]+\]$
    (0, "c", [str|^Client exiting: |]),
    -- Nick change
    (0, "c", [str|^Nick change: From |]),
    -- Connection limit, more complete regex: ^Too many user connections for [^ ]+![^ ]+@[^ ]+$
    (1, "u", [str|^Too many user connections for |]),
    -- Join alerts, more complete regex: ^User [^ ]+ \([^ ]+@[^ ]+\) trying to join #[^ ]* is a possible spambot$
    (1, "a", [str|^User [^ ]+ \([^ ]+\) trying to join #[^ ]* is a possible spambot|]),
    -- Kline hitting user
    (1, "k", [str|^K/DLINE active for|]),
    -- Connection limit, more complete regex: ^Too many local connections for [^ ]+![^ ]+@[^ ]+$
    (1, "u", [str|^Too many local connections for |]),
    -- Global kline added, more complete regex: ^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added global [0-9]+ min. K-Line for \[[^ ]+\] \[.*\]$
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. K-Line for |]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. X-Line for |]),
    -- Global kline expiring, more complete regex: ^Propagated ban for \[[^ ]+\] expired$
    (0, "k", [str|^Propagated ban for |]),
    -- Chancreate
    (1, "u", [str|^[^ ]+ is creating new channel #|]),
    -- m_filter
    (0, "u", [str|^FILTER: |]),
    (0, "m", [str|^New filters loaded.$|]),
    (0, "m", [str|^Filtering enabled.$|]),
    -- Failed login
    (0, "f", [str|^Warning: [0-9]+ failed login attempts|]),
    -- Temporary kline added, more complete regex: ^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[.*\]$
    (1, "k", [str|^OperServ![^ ]+\{services\.\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[Joining #|]), -- klinechans
    (1, "k", [str|^OperSyn![^ ]+\{syn\.\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[You've been temporarily|]), -- lethals
    (2, "k", [str|^[^ ]+ added temporary [0-9]+ min. K-Line for |]),
    -- Nick collision
    (1, "m", [str|^Nick collision on|]),
    -- KILLs
    (0, "k", [str|^Received KILL message for [^ ]+\. From NickServ |]),
    (0, "k", [str|^Received KILL message for [^ ]+\. From syn Path: [^ ]+ \(Facility Blocked\)|]),
    (1, "k", [str|^Received KILL message for [^ ]+\. From syn Path: [^ ]+ \(Banned\)|]),
    (2, "k", [str|^Received KILL message|]),
    -- Teporary kline expiring, more complete regex: ^Temporary K-line for \[[^ ]+\] expired$
    (0, "k", [str|^Temporary K-line for |]),

    -- PATTERN LIST, uncommon snotes. regex performance isn't very important beyond this point
    (2, "a", [str|^Possible Flooder|]),
    (0, "a", [str|^New Max Local Clients: [0-9]+$|]),
    (1, "a", [str|^Excessive target change from|]),

    (1, "f", [str|^Failed (OPER|CHALLENGE) attempt - host mismatch|]),
    (3, "f", [str|^Failed (OPER|CHALLENGE) attempt|]), -- ORDER IMPORTANT - catch all failed attempts that aren't host mismatch

    (1, "k", [str|^KLINE active for|]),
    (1, "k", [str|^XLINE active for|]),
    (3, "k", [str|^KLINE over-ruled for |]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. K-Line from [^ ]+![^ ]+@[^ ]+\{[^ ]+\} for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. X-Line from [^ ]+![^ ]+@[^ ]+\{[^ ]+\} for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the global K-Line for: \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the temporary K-Line for: \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added temporary [0-9]+ min. D-Line for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the X-Line for:|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} is removing the X-Line for|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the temporary D-Line for:|]),

    (0, "m", [str|^Received SAVE message for|]),<commit_msg>filter the new rejecting/disconnecting snotes<commit_after>{-# Language QuasiQuotes, OverloadedStrings #-}
{-|
Module      : Client.Hook.Snotice
Description : Hook for sorting some service notices into separate windows.
Copyright   : (c) <NAME> 2019
License     : ISC
Maintainer  : <EMAIL>

These sorting rules are based on the solanum server notices.

-}
module Client.Hook.Snotice
  ( snoticeHook
  ) where

import qualified Data.Text as Text
import           Data.Text (Text)
import           Data.List (find)
import           Text.Regex.TDFA
import           Text.Regex.TDFA.String

import           Client.Hook
import           Irc.Message
import           Irc.Identifier (mkId, Identifier)
import           Irc.UserInfo
import           StrQuote (str)

snoticeHook :: MessageHook
snoticeHook = MessageHook "snotice" True remap

remap ::
  IrcMsg -> MessageResult

remap (Notice (Source (UserInfo u "" "") _) _ msg)
  | Just msg1 <- Text.stripPrefix "*** Notice -- " msg
  , let msg2 = Text.filter (\x -> x /= '\x02' && x /= '\x0f') msg1
  , Just (lvl, cat) <- characterize msg2
  = if lvl < 1 then OmitMessage
               else RemapMessage (Notice (Source (UserInfo u "" "*") "") cat msg1)

remap _ = PassMessage

toPattern :: (Int, String, String) -> (Int, Identifier, Regex)
toPattern (lvl, cat, reStr) =
  case compile co eo reStr of
    Left e  -> error e
    Right r -> (lvl, mkId (Text.pack ('~':cat)), r)
  where
    co = CompOption
      { caseSensitive  = True
      , multiline      = False
      , rightAssoc     = True
      , newSyntax      = True
      , lastStarGreedy = True }
    eo = ExecOption
      { captureGroups  = False }

characterize :: Text -> Maybe (Int, Identifier)
characterize txt =
  do let s = Text.unpack txt
     (lvl, cat, _) <- find (\(_, _, re) -> matchTest re s) patterns
     pure (lvl, cat)

patterns :: [(Int, Identifier, Regex)]
patterns = map toPattern
    [
    -- PATTERN LIST, most common snotes
    -- Client connecting, more complete regex: ^Client connecting: [^ ]+ \([^ ]+@[^ ]+\) \[[^ ]+\] \{[^ ]+\} \[.*\]$
    (1, "c", [str|^Client connecting: |]),
    -- Client exiting, more complete regex: ^Client exiting: [^ ]+ \([^ ]+@[^ ]+\) \[.*\] \[[^ ]+\]$
    (0, "c", [str|^Client exiting: |]),
    -- Nick change
    (0, "c", [str|^Nick change: From |]),
    -- Connection limit, more complete regex: ^Too many user connections for [^ ]+![^ ]+@[^ ]+$
    (1, "u", [str|^Too many user connections for |]),
    -- Join alerts, more complete regex: ^User [^ ]+ \([^ ]+@[^ ]+\) trying to join #[^ ]* is a possible spambot$
    (1, "a", [str|^User [^ ]+ \([^ ]+\) trying to join #[^ ]* is a possible spambot|]),
    -- Kline hitting user
    (1, "k", [str|^K/DLINE active for|]),
    -- Connection limit, more complete regex: ^Too many local connections for [^ ]+![^ ]+@[^ ]+$
    (1, "u", [str|^Too many local connections for |]),
    -- Global kline added, more complete regex: ^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added global [0-9]+ min. K-Line for \[[^ ]+\] \[.*\]$
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. K-Line for |]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. X-Line for |]),
    -- Global kline expiring, more complete regex: ^Propagated ban for \[[^ ]+\] expired$
    (0, "k", [str|^Propagated ban for |]),
    -- Chancreate
    (1, "u", [str|^[^ ]+ is creating new channel #|]),
    -- m_filter
    (0, "u", [str|^FILTER: |]),
    (0, "m", [str|^New filters loaded.$|]),
    (0, "m", [str|^Filtering enabled.$|]),
    -- Failed login
    (0, "f", [str|^Warning: [0-9]+ failed login attempts|]),
    -- Temporary kline added, more complete regex: ^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[.*\]$
    (1, "k", [str|^OperServ![^ ]+\{services\.\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[Joining #|]), -- klinechans
    (1, "k", [str|^OperSyn![^ ]+\{syn\.\} added temporary [0-9]+ min. K-Line for \[[^ ]+\] \[You've been temporarily|]), -- lethals
    (2, "k", [str|^[^ ]+ added temporary [0-9]+ min. K-Line for |]),
    -- Nick collision
    (1, "m", [str|^Nick collision on|]),
    -- KILLs
    (0, "k", [str|^Received KILL message for [^ ]+\. From NickServ |]),
    (0, "k", [str|^Received KILL message for [^ ]+\. From syn Path: [^ ]+ \(Facility Blocked\)|]),
    (1, "k", [str|^Received KILL message for [^ ]+\. From syn Path: [^ ]+ \(Banned\)|]),
    (2, "k", [str|^Received KILL message|]),
    -- Teporary kline expiring, more complete regex: ^Temporary K-line for \[[^ ]+\] expired$
    (0, "k", [str|^Temporary K-line for |]),

    -- PATTERN LIST, uncommon snotes. regex performance isn't very important beyond this point
    (2, "a", [str|^Possible Flooder|]),
    (0, "a", [str|^New Max Local Clients: [0-9]+$|]),
    (1, "a", [str|^Excessive target change from|]),

    (1, "f", [str|^Failed (OPER|CHALLENGE) attempt - host mismatch|]),
    (3, "f", [str|^Failed (OPER|CHALLENGE) attempt|]), -- ORDER IMPORTANT - catch all failed attempts that aren't host mismatch

    (1, "k", [str|^Rejecting [XK]-Lined user|]),
    (1, "k", [str|^Disconnecting [XK]-Lined user|]),
    (1, "k", [str|^KLINE active for|]),
    (1, "k", [str|^XLINE active for|]),
    (3, "k", [str|^KLINE over-ruled for |]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. K-Line from [^ ]+![^ ]+@[^ ]+\{[^ ]+\} for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+ added global [0-9]+ min. X-Line from [^ ]+![^ ]+@[^ ]+\{[^ ]+\} for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the global K-Line for: \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the temporary K-Line for: \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} added temporary [0-9]+ min. D-Line for \[[^ ]+\] \[.*\]$|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the X-Line for:|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} is removing the X-Line for|]),
    (2, "k", [str|^[^ ]+![^ ]+@[^ ]+\{[^ ]+\} has removed the temporary D-Line for:|]),

    (0, "m", [str|^Received SAVE message for|]),
{'fraction_non_alphanumeric': 0.24644351464435146, 'fraction_numerical': 0.013221757322175733, 'mean_word_length': 2.830448717948718, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2854131', 'n_tokens_mistral': 4547, 'n_tokens_neox': 4307, 'n_words': 1239}