feat(owothia): Add owothia
Add owothia, an irc bot that picks a random verb out of a random subset of messages and replies with a message of the form "<verb> me owo". it's incredibly messy, full of warnings, includes a *number* of harcoded things, but also is hilarious. Change-Id: I73cacd533bbbff9e753d1e542308da25247a7034 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1063 Tested-by: BuildkiteCI Reviewed-by: lukegb <lukegb@tvl.fyi>
This commit is contained in:
parent
7e0b2cd3f3
commit
2eb90cbca1
12 changed files with 290 additions and 0 deletions
|
@ -102,5 +102,6 @@ in lib.fix (self: {
|
||||||
(systemFor system.system.chupacabra)
|
(systemFor system.system.chupacabra)
|
||||||
xanthous
|
xanthous
|
||||||
keyboard.layout
|
keyboard.layout
|
||||||
|
owothia
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
1
users/glittershark/owothia/.envrc
Normal file
1
users/glittershark/owothia/.envrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
eval "$(lorri direnv)"
|
29
users/glittershark/owothia/.gitignore
vendored
Normal file
29
users/glittershark/owothia/.gitignore
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
dist
|
||||||
|
dist-*
|
||||||
|
cabal-dev
|
||||||
|
*.o
|
||||||
|
*.hi
|
||||||
|
*.hie
|
||||||
|
*.chi
|
||||||
|
*.chs.h
|
||||||
|
*.dyn_o
|
||||||
|
*.dyn_hi
|
||||||
|
.hpc
|
||||||
|
.hsenv
|
||||||
|
.cabal-sandbox/
|
||||||
|
cabal.sandbox.config
|
||||||
|
*.prof
|
||||||
|
*.aux
|
||||||
|
*.hp
|
||||||
|
*.eventlog
|
||||||
|
.stack-work/
|
||||||
|
cabal.project.local
|
||||||
|
cabal.project.local~
|
||||||
|
.HTF/
|
||||||
|
.ghc.environment.*
|
||||||
|
|
||||||
|
# from nix-build
|
||||||
|
result
|
||||||
|
|
||||||
|
# grr
|
||||||
|
*_flymake.hs
|
19
users/glittershark/owothia/chatter.patch
Normal file
19
users/glittershark/owothia/chatter.patch
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
diff --git a/src/NLP/POS/LiteralTagger.hs b/src/NLP/POS/LiteralTagger.hs
|
||||||
|
index 913bee8..3c2f71d 100644
|
||||||
|
--- a/src/NLP/POS/LiteralTagger.hs
|
||||||
|
+++ b/src/NLP/POS/LiteralTagger.hs
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
+{-# LANGUAGE OverloadedStrings, PackageImports #-}
|
||||||
|
module NLP.POS.LiteralTagger
|
||||||
|
( tag
|
||||||
|
, tagSentence
|
||||||
|
@@ -27,7 +27,7 @@ import NLP.FullStop (segment)
|
||||||
|
import NLP.Types ( tagUNK, Sentence, TaggedSentence(..), applyTags
|
||||||
|
, Tag, POSTagger(..), CaseSensitive(..), tokens, showTok)
|
||||||
|
import Text.Regex.TDFA
|
||||||
|
-import Text.Regex.TDFA.Text (compile)
|
||||||
|
+import "regex-tdfa" Text.Regex.TDFA.Text (compile)
|
||||||
|
|
||||||
|
taggerID :: ByteString
|
||||||
|
taggerID = pack "NLP.POS.LiteralTagger"
|
6
users/glittershark/owothia/default.nix
Normal file
6
users/glittershark/owothia/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{ pkgs ? (import ../../../. {}).third_party
|
||||||
|
, lib ? pkgs.lib
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
(import ./packageSet.nix {}).callPackage (import ./pkg.nix { inherit pkgs; }) {}
|
4
users/glittershark/owothia/hie.yaml
Normal file
4
users/glittershark/owothia/hie.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
cradle:
|
||||||
|
cabal:
|
||||||
|
- path: './app'
|
||||||
|
component: 'exe:owothia'
|
53
users/glittershark/owothia/owothia.cabal
Normal file
53
users/glittershark/owothia/owothia.cabal
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
cabal-version: 2.2
|
||||||
|
name: owothia
|
||||||
|
version: 0.0.1.0
|
||||||
|
|
||||||
|
executable owothia
|
||||||
|
main-is: Main.hs
|
||||||
|
build-depends: base
|
||||||
|
, relude ^>= 0.6.0.0
|
||||||
|
, irc-client
|
||||||
|
, lens
|
||||||
|
, chatter
|
||||||
|
, containers
|
||||||
|
, text
|
||||||
|
, bytestring
|
||||||
|
, random
|
||||||
|
, envy
|
||||||
|
|
||||||
|
mixins: base hiding (Prelude)
|
||||||
|
, relude (Relude as Prelude)
|
||||||
|
|
||||||
|
hs-source-dirs:
|
||||||
|
src
|
||||||
|
|
||||||
|
default-extensions:
|
||||||
|
BlockArguments
|
||||||
|
ConstraintKinds
|
||||||
|
DataKinds
|
||||||
|
DeriveAnyClass
|
||||||
|
DeriveGeneric
|
||||||
|
DerivingStrategies
|
||||||
|
DerivingVia
|
||||||
|
FlexibleContexts
|
||||||
|
FlexibleInstances
|
||||||
|
FunctionalDependencies
|
||||||
|
GADTSyntax
|
||||||
|
GeneralizedNewtypeDeriving
|
||||||
|
KindSignatures
|
||||||
|
LambdaCase
|
||||||
|
MultiWayIf
|
||||||
|
NoStarIsType
|
||||||
|
OverloadedStrings
|
||||||
|
PolyKinds
|
||||||
|
RankNTypes
|
||||||
|
ScopedTypeVariables
|
||||||
|
TupleSections
|
||||||
|
TypeApplications
|
||||||
|
TypeFamilies
|
||||||
|
TypeOperators
|
||||||
|
ViewPatterns
|
||||||
|
|
||||||
|
ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -O2
|
||||||
|
|
||||||
|
default-language: Haskell2010
|
20
users/glittershark/owothia/packageSet.nix
Normal file
20
users/glittershark/owothia/packageSet.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs ? (import ../../../. {}).third_party, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
hlib = pkgs.haskell.lib;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
pkgs.haskellPackages.extend (self: super: {
|
||||||
|
regex-tdfa-text = hlib.doJailbreak
|
||||||
|
(hlib.appendPatch
|
||||||
|
super.regex-tdfa-text
|
||||||
|
./regex-tdfa-text.patch
|
||||||
|
);
|
||||||
|
|
||||||
|
fullstop = hlib.dontCheck super.fullstop;
|
||||||
|
|
||||||
|
chatter = hlib.doJailbreak
|
||||||
|
(hlib.dontCheck (hlib.appendPatch super.chatter ./chatter.patch));
|
||||||
|
})
|
6
users/glittershark/owothia/pkg.nix
Normal file
6
users/glittershark/owothia/pkg.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
args@{ pkgs ? (import ../../../. {}).third_party }:
|
||||||
|
|
||||||
|
import ((import ./packageSet.nix args).haskellSrc2nix {
|
||||||
|
name = "owothia";
|
||||||
|
src = pkgs.gitignoreSource ./.;
|
||||||
|
})
|
40
users/glittershark/owothia/regex-tdfa-text.patch
Normal file
40
users/glittershark/owothia/regex-tdfa-text.patch
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
diff --git a/Text/Regex/TDFA/Text.hs b/Text/Regex/TDFA/Text.hs
|
||||||
|
index c4ef9db..9299272 100644
|
||||||
|
--- a/Text/Regex/TDFA/Text.hs
|
||||||
|
+++ b/Text/Regex/TDFA/Text.hs
|
||||||
|
@@ -38,13 +38,6 @@ import Text.Regex.TDFA.NewDFA.Uncons(Uncons(uncons))
|
||||||
|
import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)
|
||||||
|
import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)
|
||||||
|
|
||||||
|
-instance Extract T.Text where
|
||||||
|
- before = T.take; after = T.drop; empty = T.empty
|
||||||
|
-
|
||||||
|
-instance Uncons T.Text where
|
||||||
|
- {- INLINE uncons #-}
|
||||||
|
- uncons = T.uncons
|
||||||
|
-
|
||||||
|
instance RegexContext Regex T.Text T.Text where
|
||||||
|
match = polymatch
|
||||||
|
matchM = polymatchM
|
||||||
|
diff --git a/Text/Regex/TDFA/Text/Lazy.hs b/Text/Regex/TDFA/Text/Lazy.hs
|
||||||
|
index 73ca4a0..52958fb 100644
|
||||||
|
--- a/Text/Regex/TDFA/Text/Lazy.hs
|
||||||
|
+++ b/Text/Regex/TDFA/Text/Lazy.hs
|
||||||
|
@@ -38,17 +38,10 @@ import Text.Regex.TDFA.NewDFA.Uncons(Uncons(uncons))
|
||||||
|
import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)
|
||||||
|
import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)
|
||||||
|
|
||||||
|
-instance Extract L.Text where
|
||||||
|
- before = L.take . toEnum; after = L.drop . toEnum; empty = L.empty
|
||||||
|
-
|
||||||
|
instance RegexContext Regex L.Text L.Text where
|
||||||
|
match = polymatch
|
||||||
|
matchM = polymatchM
|
||||||
|
|
||||||
|
-instance Uncons L.Text where
|
||||||
|
- {- INLINE uncons #-}
|
||||||
|
- uncons = L.uncons
|
||||||
|
-
|
||||||
|
instance RegexMaker Regex CompOption ExecOption L.Text where
|
||||||
|
makeRegexOptsM c e source = makeRegexOptsM c e (L.unpack source)
|
||||||
|
|
14
users/glittershark/owothia/shell.nix
Normal file
14
users/glittershark/owothia/shell.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
args@{ pkgs ? (import ../../../. {}).third_party, ... }:
|
||||||
|
|
||||||
|
((import ./packageSet.nix args).extend (pkgs.haskell.lib.packageSourceOverrides {
|
||||||
|
owothia = pkgs.gitignoreSource ./.;
|
||||||
|
})).shellFor {
|
||||||
|
packages = p: [p.owothia];
|
||||||
|
withHoogle = true;
|
||||||
|
doBenchmark = true;
|
||||||
|
buildInputs = with pkgs.haskellPackages; [
|
||||||
|
cabal-install
|
||||||
|
hlint
|
||||||
|
pkgs.haskell-language-server.ghc883
|
||||||
|
];
|
||||||
|
}
|
97
users/glittershark/owothia/src/Main.hs
Normal file
97
users/glittershark/owothia/src/Main.hs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
import Network.IRC.Client
|
||||||
|
import Control.Lens
|
||||||
|
import NLP.POS
|
||||||
|
import NLP.Types (POSTagger)
|
||||||
|
import NLP.Types.Tree
|
||||||
|
import qualified NLP.Types.Tree
|
||||||
|
import qualified NLP.Corpora.Conll as Conll
|
||||||
|
import NLP.Corpora.Conll (Tag)
|
||||||
|
import qualified Data.ByteString as BS
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import System.Random
|
||||||
|
import System.Envy
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
data Config = Config
|
||||||
|
{ _nickservPassword :: Text
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (FromEnv)
|
||||||
|
makeLenses ''Config
|
||||||
|
|
||||||
|
verbs :: POSTagger Tag -> Text -> [Text]
|
||||||
|
verbs tagger s = mapMaybe pickVerb $ tag tagger s >>= \(TaggedSent ps) -> ps
|
||||||
|
where
|
||||||
|
pickVerb (POS Conll.VB (Token verb)) = Just verb
|
||||||
|
pickVerb (POS Conll.VBD (Token verb)) = Just verb
|
||||||
|
pickVerb (POS Conll.VBG (Token verb)) = Just verb
|
||||||
|
pickVerb (POS Conll.VBN (Token verb)) = Just verb
|
||||||
|
pickVerb (POS Conll.VBZ (Token verb)) = Just verb
|
||||||
|
pickVerb _ = Nothing
|
||||||
|
|
||||||
|
randomVerb :: POSTagger Tag -> Text -> IO (Maybe Text)
|
||||||
|
randomVerb tagger txt = do
|
||||||
|
let vs = verbs tagger txt
|
||||||
|
i <- randomRIO (0, length vs - 1)
|
||||||
|
pure $ vs ^? ix i
|
||||||
|
|
||||||
|
owo :: Text -> Text
|
||||||
|
owo = (<> " me owo")
|
||||||
|
|
||||||
|
owoChance = 10
|
||||||
|
|
||||||
|
doOwo :: MonadIO m => m Bool
|
||||||
|
doOwo = do
|
||||||
|
n <- liftIO (randomRIO @Int (0, owoChance))
|
||||||
|
liftIO $ putStrLn $ "rolled " <> show n
|
||||||
|
pure $ n == 0
|
||||||
|
|
||||||
|
owothiaHandler :: Config -> IORef Bool -> POSTagger Tag -> EventHandler s
|
||||||
|
owothiaHandler conf state tagger = EventHandler Just $ \src ev -> do
|
||||||
|
hasIdentified <- readIORef state
|
||||||
|
when (not hasIdentified) $ do
|
||||||
|
nickservAuth
|
||||||
|
send $ Join "##tvl"
|
||||||
|
writeIORef state True
|
||||||
|
|
||||||
|
when ("You are now identified" `BS.isInfixOf` (ev ^. raw)) $
|
||||||
|
send $ Join "##tvl"
|
||||||
|
|
||||||
|
case (src, ev ^. message) of
|
||||||
|
(Channel "##tvl" nick, Privmsg _ (Right m)) -> do
|
||||||
|
willOwo <- doOwo
|
||||||
|
when willOwo $ owoMessage m
|
||||||
|
_ -> pure ()
|
||||||
|
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
where
|
||||||
|
owoMessage m = do
|
||||||
|
mVerb <- liftIO $ randomVerb tagger m
|
||||||
|
for_ mVerb $ \verb -> send $ Privmsg "##tvl" $ Right $ owo verb
|
||||||
|
nickservAuthMsg = "IDENTIFY " <> myNick <> " " <> conf ^. nickservPassword
|
||||||
|
nickservAuth = send $ Privmsg "NickServ" $ Right nickservAuthMsg
|
||||||
|
|
||||||
|
myNick :: Text
|
||||||
|
myNick = "owothia"
|
||||||
|
|
||||||
|
run :: ByteString -> Int -> IO ()
|
||||||
|
run host port = do
|
||||||
|
Right conf <- decodeEnv
|
||||||
|
tagger <- defaultTagger
|
||||||
|
state <- newIORef False
|
||||||
|
let conn =
|
||||||
|
plainConnection host port
|
||||||
|
& logfunc .~ stdoutLogger
|
||||||
|
cfg =
|
||||||
|
defaultInstanceConfig myNick
|
||||||
|
& channels .~ ["##tvl"]
|
||||||
|
& handlers %~ (owothiaHandler conf state tagger : )
|
||||||
|
runClient conn cfg ()
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
run "irc.freenode.net" 6667
|
Loading…
Reference in a new issue