New paste Repaste Download
fastTimeParser :: Data.Attoparsec.Text.Parser UTCTime
fastTimeParser = do
  y <- decimal; char '-'; m <- decimal; char '-'; d <- decimal; char ' '
  h <- decimal; char ':'; n <- decimal; char ':'; s <- decimal
  pure $ UTCTime (fromGregorian y m d)
                 (fromIntegral (h * 3600 + n * 60 + s))
fastParseTime :: T.Text -> Maybe UTCTime
fastParseTime t = either (const Nothing) Just $ parseOnly fastTimeParser t where
parseWeechatLog          :: T.Text -> T.Text -> (M.HashMap T.Text T.Text, V.Vector (UTCTime, WeechatLogEntry))
parseWeechatLog chan log = either (const $ (M.empty, V.empty)) id . (flip parseOnly $ log) $ execute M.empty V.empty
  where opGlyphs = S.fromList "+%@&~"
        execute hostmasks acc = do
          done <- atEnd
          if done then return (hostmasks, acc)
          else do
            ts <- weechatTimestampParser
            (hostmasks', result) <- choice [ Data.Attoparsec.Text.string "--\t" >> takeTill isEndOfLine >> char '\n' >> return (hostmasks, Nothing)
                                           , Data.Attoparsec.Text.string "<--\t" >> weechatPartMsgParser chan hostmasks
                                           , Data.Attoparsec.Text.string "<--\t" >> weechatKickMsgParser chan hostmasks
                                           , Data.Attoparsec.Text.string "<--\t" >> weechatQuitMsgParser hostmasks
                                           , Data.Attoparsec.Text.string "Welcome\t" >> takeTill isEndOfLine >> char '\n' >> return (hostmasks, Nothing)
                                           , Data.Attoparsec.Text.string "-->\t" >> weechatJoinMsgParser chan hostmasks
                                           , parseWeechatPrivMsg chan hostmasks
                                           ]
            end <- atEnd
            case result of
              Just entry -> if end then return $ (hostmasks', V.snoc acc $ (ts, entry))
                                   else execute hostmasks' . V.snoc acc $ (ts, entry)
              Nothing          -> execute hostmasks acc
        weechatTimestampParser :: Data.Attoparsec.Text.Parser UTCTime
        weechatTimestampParser = do
          t <- fastTimeParser
          Data.Attoparsec.Text.take 1
          return t
        weechatJoinMsgParser :: T.Text -> M.HashMap T.Text T.Text -> Data.Attoparsec.Text.Parser (M.HashMap T.Text T.Text, Maybe WeechatLogEntry)
        weechatJoinMsgParser chan hostmasks = do
          n <- takeTill isHorizontalSpace
          Data.Attoparsec.Text.take 2
          h <- takeTill (== ')')
          takeTill isEndOfLine
          (char '\n' >> return ()) <|> pure ()
          let hostmasks' = M.insert n h hostmasks
          return (hostmasks', Just (WeechatJoinMsg n h chan))
        weechatPartMsgParser           :: T.Text -> M.HashMap T.Text T.Text -> Data.Attoparsec.Text.Parser (M.HashMap T.Text T.Text, Maybe WeechatLogEntry)
        weechatPartMsgParser chan hostmasks = do
          n <- takeTill isHorizontalSpace
          Data.Attoparsec.Text.take 2
          h <- takeTill (== ')')
          Data.Attoparsec.Text.string ") has left "
          takeTill (== '(')
          Data.Attoparsec.Text.take 1
          m <- takeTill isEndOfLine
          (char '\n' >> return ()) <|> pure ()
          let hostmasks' = M.insert n h hostmasks
          return (hostmasks', Just (WeechatPartMsg n h chan (T.dropEnd 1 m)))
        weechatKickMsgParser :: T.Text -> M.HashMap T.Text T.Text -> Data.Attoparsec.Text.Parser (M.HashMap T.Text T.Text, Maybe WeechatLogEntry)
        weechatKickMsgParser chan hostmasks = do
          n <- takeTill isHorizontalSpace
          Data.Attoparsec.Text.take 1
          string "has kicked "
          p <- takeTill isHorizontalSpace
          Data.Attoparsec.Text.take 2
          m <- takeTill isEndOfLine
          (char '\n' >> return ()) <|> pure ()
          let host = M.lookup n hostmasks
          return (hostmasks, Just (WeechatKickMsg n host p chan (T.dropEnd 1 m)))
        weechatQuitMsgParser :: M.HashMap T.Text T.Text -> Data.Attoparsec.Text.Parser (M.HashMap T.Text T.Text, Maybe WeechatLogEntry)
        weechatQuitMsgParser hostmasks = do
          n <- takeTill isHorizontalSpace
          Data.Attoparsec.Text.take 2
          h <- takeTill (== ')')
          takeTill (== '(')
          Data.Attoparsec.Text.take 1
          m <- takeTill isEndOfLine
          (char '\n' >> return ()) <|> pure ()
          let hostmasks' = M.insert n h hostmasks
          return (hostmasks', Just (WeechatQuitMsg n h (T.dropEnd 1 m)))
        parseWeechatPrivMsg :: T.Text -> M.HashMap T.Text T.Text -> Data.Attoparsec.Text.Parser (M.HashMap T.Text T.Text, Maybe WeechatLogEntry)
        parseWeechatPrivMsg chan hostmasks = do
          n <- takeTill (== '\t')
          Data.Attoparsec.Text.take 1
          m <- takeTill isEndOfLine
          (char '\n' >> return ()) <|> pure ()
          let host = M.lookup n hostmasks
          return (hostmasks, Just (WeechatPrivMsg (T.filter (not . (`elem` opGlyphs)) n) host chan m))
Filename: /tmp/parse.hs. Size: 5kb. View raw, , hex, or download this file.

This paste expires on 2026-07-07 01:47:10.219768+00:00. Pasted through v1-api.