dbri.hs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. -- the comments are all outta wack too.
  2. --important, reminder, Digit ! This is stage4 type, not stage 3 type.
  3. -- therefor, mind your pastes from type 3 to type 4 need the " h" taken out of equations
  4. -- This is the BedrockLinux info version of daskeb (digit's haskell bot).
  5. -- ____ __
  6. -- ___/ / /_______/_/
  7. -- / _ / _ / __/ /
  8. -- /____/_____/_/ /_/
  9. --
  10. -- digit's bedrock
  11. -- info bot, dbri
  12. import Data.List
  13. import Network
  14. import System.IO
  15. import System.Exit
  16. import Control.Arrow
  17. import Control.Monad.Reader
  18. import Control.Exception
  19. import Text.Printf
  20. import System.Random -- import random, it said, surely they meant import Random, trying System.Random
  21. --server = "irc.freenode.org"
  22. server = "irc.libera.chat"
  23. port = 6667
  24. chan = "##bedrock-treehouse"
  25. nick = "dbri"
  26. -- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state.
  27. type Net = ReaderT Bot IO
  28. data Bot = Bot { socket :: Handle }
  29. -- Set up actions to run on start and end, and run the main loop
  30. main :: IO ()
  31. main = bracket connect disconnect loop
  32. where
  33. disconnect = hClose . socket
  34. loop st = runReaderT run st
  35. -- Connect to the server and return the initial bot state
  36. connect :: IO Bot
  37. connect = notify $ do
  38. h <- connectTo server (PortNumber (fromIntegral port))
  39. hSetBuffering h NoBuffering
  40. return (Bot h)
  41. where
  42. notify a = bracket_
  43. (printf "Connecting to %s ... " server >> hFlush stdout)
  44. (putStrLn "done.")
  45. a
  46. -- We're in the Net monad now, so we've connected successfully
  47. -- Join a channel, and start processing commands
  48. run :: Net ()
  49. run = do
  50. write "NICK" nick
  51. write "USER" (nick++" 0 * :DigitsHaskellBot")
  52. write "JOIN" chan
  53. asks socket >>= listen
  54. -- Process each line from the server
  55. listen :: Handle -> Net ()
  56. listen h = forever $ do
  57. s <- init `fmap` io (hGetLine h)
  58. io (putStrLn s)
  59. if ping s then pong s else eval (clean s)
  60. where
  61. forever a = a >> forever a
  62. clean = drop 1 . dropWhile (/= ':') . drop 1
  63. ping x = "PING :" `isPrefixOf` x
  64. pong x = write "PONG" (':' : drop 6 x)
  65. -- Dispatch a command
  66. eval :: String -> Net ()
  67. -- -- extra features
  68. -- list of exit commands, in case of annoyance/abuse.
  69. riddances = ["exit", "quit", "stop", "mute", "stfu", "shut up", "go away", "be quiet", "stop that", "enough", "!!", "rage", "please stop", "Hush", "hush", "HUSH", "quiet you", "Quiet you", "QUIET", "please segfault", "segfault please", "fuckoff", "feckoff", "fuck off", "feck off", "fek off", "fekoff", "gtf", "please leave", "leave", "annoying", "anoying"]
  70. -- -- features in dev
  71. -- for dbribot, can haz tuples
  72. --interrogatives = ["bipity", "bopity"] --for testing purposes only.
  73. interrogatives = ["what", "who", "how", "why", "where", "when", "which", " or ", "What", "Who", "How", "Why", "Where", "When", "Which", "Or ", "WHAT", "WHO", "HOW", "WHY", "WHERE", "WHEN", "WHICH", " OR "]
  74. --eval x | "?" `isSuffixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
  75. -- idea for dbribot is a list of commands to call forth basic
  76. --eval x | "~" `isPrefixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "here i'd execute the relevant command/tuple for $interrogatives" else "idk about that yet")
  77. --eval x | "?" `isSuffixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
  78. --
  79. -- -------------------------------------------------------------------------------------------
  80. -- another way of grouping multiple commands... (needs work so can neatly have all commands contained in one eval, following the command character, e.g. "~")
  81. -- from -- --eval x | "!bedrock" `isInfixOf` x = privmsg (if "FatherJack:" `isPrefixOf` x then "glug glug glug" else "DRINK!")
  82. --
  83. -- homepage = ["bedrock", "website"]
  84. ------eval x | homepage `isPrefixOf` x = privmsg "https://bedrocklinux.org/"
  85. -------eval x | homepage `isPrefixOf` x = privmsg (if any (`isInfixOf` x) homepage then "https://bedrocklinux.org/" else "idk about that yet")
  86. -- eval x | "~" `isPrefixOf` x = privmsg (if any (`isInfixOf` x) homepage then "https://bedrocklinux.org/" else "idk about that yet")
  87. -- -------------------------------------------------------------------------------------------
  88. -- -------------------------------------------------------------------------------------------
  89. --
  90. --------------------------------------
  91. ----------------------------------------------------------------------------
  92. ------------------------------------------------------------------------------------------------------------------
  93. --------------------------------------------------------------------------------------------------------------------------------------------
  94. --------------------------------------------------------------------------------------------------------------------------------------------
  95. --------------------------------------------------------------------------------------------------------------------------------------------
  96. --------------------------------------------------------------------------------------------------------------------------------------------
  97. -- ---------------------------------------------------------------------------------------- -----\\\\\\\\\\\\-------------------------------
  98. -- ------\\\ \\\------------------------------
  99. -- ____ ** ------------------------------------------------------------------------ ** ____ -------\\\ \\\-----------------------------
  100. -- __** -- **__ --------\\\ \\\\\\\\\\\\\\\\\--------------
  101. -- _** -- _____ ____ _____ _ _ _ _____ ____ _____ **_ ---------\\\ \\\-------------
  102. -- _** -- |___\ \ / /\ \ / /___| __| | |__ _ _(_) |___\ \ / /\ \ / /___| **_ ----------\\\ \\\------------
  103. -- _** -- \ \ | | | | / / / _` | '_ \ '_| | \ \ | | | | / / **_ -----------\\\ ______ \\\-----------
  104. -- _** -- \_\_| | | |_/_/ \__,_|_.__/_| |_| \_\_| | | |_/_/ **_ ------------\\\ ///-----------
  105. -- _** -- |___\_\/_/___| GPL digit's bedrock info bot. |___\_\/_/___| **_ -------------\\\ ///------------
  106. -- _** -- **_ --------------\\\ ///-------------
  107. -- __** -- **__ ---------------\\\////////////////--------------
  108. -- ____ ** ------------------------------------------------ ----------------- ** ____ -- __ __ __ ---------
  109. -- ---- ---- -- \ \_________\ \____________\ \___ ---------
  110. -- ------------------------------------------------------------ ------------------------- \ _ \ _\ _ \ _\ __ \ __\ / ---------
  111. -- -------------------------------------------------------------- ----------------------- \___/\__/\__/ \_\ \___/\__/\_\_\ ---------
  112. -- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- for 0.7 ( poki ) BedrockLinux ---------
  113. -- -----------------------------------------------------------------------------------------------------------------------------------------
  114. --------------------------------------------------------------------------------------------------------------------------------------------
  115. --------------------------------------------------------------------------------------------------------------------------------------------
  116. --------------------------------------------------------------------------------------------------------------------------------------------
  117. -- dbri
  118. -- INDEX/HELP/CONTENTS/COMMANDSLIST
  119. eval x | "!help" `isPrefixOf` x = privmsg "!bedrock !intro !faq !releaseoverview !install !basic !distrocompatibility !featurecompatibility !issues !commands !advanced !debug !addfetch !addpm !addo !beta !version !v | (+!more)"
  120. eval x | "!more" `isPrefixOf` x = privmsg "(in-dev...) terminology/faq: !base !main !tute !concepts !init | bot housekeeping: !leave !version !dbri !about | etc: !search | temp issues: !grub !btrfs !zfs !grub+btrfs !fonts"
  121. eval x | "!concepts" `isPrefixOf` x = privmsg "!concepts : !basic : !local !global " -- !misconcepts: !base&!main ? or rephrase as a !nobase ?
  122. -- INFO FEATURE
  123. -- INFO PAGES
  124. --eval x | "~" `isPrefixOf` x = privmsg (if any (`isInfixOf` x) homepage then "https://bedrocklinux.org/")
  125. -- BEDROCK
  126. eval x | "!bedrock" `isPrefixOf` x = privmsg "https://bedrocklinux.org/"
  127. -- INTRODUCTORY MATERIAL
  128. eval x | "!intro" `isPrefixOf` x = privmsg "https://bedrocklinux.org/introduction.html"
  129. eval x | "!faq" `isPrefixOf` x = privmsg "https://bedrocklinux.org/faq.html"
  130. -- 0.7
  131. --
  132. eval x | "!0.7" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/index.html"
  133. eval x | "!releaseoverview" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/index.html"
  134. eval x | "!install" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/installation-instructions.html"
  135. eval x | "!basic" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/basic-usage.html" -- + see:"-- FURTHER BASIC INFO (subsections ..."
  136. ---- LIMITATIONS
  137. eval x | "!distrocompatibility" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/distro-compatibility.html"
  138. eval x | "!featurecompatibility" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/feature-compatibility.html"
  139. eval x | "!issues" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/known-issues.html grub&btrfs: https://bedrocklinux.org/0.7/feature-compatibility.html#grub-btrfs-zfs "
  140. eval x | "!grub+btrfs" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/feature-compatibility.html#grub-btrfs-zfs This will cause boot failures. Until this is resolved, it is strongly recommended not to use Bedrock, GRUB, and BTRFS/ZFS."
  141. eval x | "!commands" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/commands.html"
  142. -- commands
  143. --
  144. eval x | "!configuration" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/configuration.html"
  145. eval x | "!advanced" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/workflows.html"
  146. --eval x | "!workflows" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/workflows.html"
  147. -- advanced workflows
  148. --
  149. eval x | "!debug" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/debugging.html"
  150. -- extending
  151. eval x | "!addfetch" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/extending.html#brl-fetch-new-distros"
  152. eval x | "!addpm" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/extending.html#pmm-new-package-managers"
  153. eval x | "!addo" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/extending.html#pmm-new-operations"
  154. -- version
  155. eval x | "!beta" `isPrefixOf` x = privmsg "https://bedrocklinux.org/0.7/beta-channel.html"
  156. eval x | "!v" `isPrefixOf` x = privmsg "0.7"
  157. -- FURTHER BASIC INFO (subsections of !basic https://bedrocklinux.org/0.7/basic-usage.html
  158. -- !concepts
  159. --eval x | "!concepts" `isPrefixOf` x = privmsg "!concepts" --
  160. -- global & local
  161. eval x | "!global" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/basic-usage.html#global-file-paths "
  162. eval x | "!local" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/basic-usage.html#local-file-paths "
  163. eval x | "!init" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/basic-usage.html#special-strata https://bedrocklinux.org/0.7/basic-usage.html#removing-strata "
  164. -- /0.7
  165. -- FURTHER INFO ADDITIONS (!more)
  166. -- !tute
  167. eval x | "!tute" `isPrefixOf` x = privmsg "Bedrock has an interactive tutorial you can go thorugh via `brl tutorial basics`. Consider giving that a go. It may clarify questions like this."
  168. eval x | "!tutorial" `isPrefixOf` x = privmsg "Bedrock has an interactive tutorial you can go thorugh via `brl tutorial basics`. Consider giving that a go. It may clarify questions like this."
  169. -- base stratum / main stratum
  170. eval x | "!base" `isPrefixOf` x = privmsg "there is no base distro but bedrock. the stratum used for install (and defaults to being init stratum), is much like any other strata, and can be removed, or other strata can be switched to init. think of each strata like equal players on bedrock."
  171. eval x | "!main" `isPrefixOf` x = privmsg "see !base. similarly, while you're free to think of any of your strata as your main, there's nothing in bedrock insistently making it so."
  172. -- temp issues
  173. -- !grub + !btrfs
  174. eval x | "!grub" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/feature-compatibility.html#grub-btrfs-zfs "
  175. eval x | "!btrfs" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/feature-compatibility.html#grub-btrfs-zfs "
  176. eval x | "!zfs" `isPrefixOf` x = privmsg " https://bedrocklinux.org/0.7/feature-compatibility.html#grub-btrfs-zfs "
  177. eval x | "!fonts" `isPrefixOf` x = privmsg " fonts across strata are supposed to just-work, but there's an issue with caching that sadly won't be fixed until 0.8. For now, manually run `strat <stratum> fc-cache -fv` to update the cache. You may need to do this both as root and non-root. "
  178. ---------------------------------------------
  179. ---------------------------------------------
  180. ---------------------------------------------
  181. ---------------------------------------------
  182. -------------------------------------------
  183. -----------------------------------
  184. ---------------------------
  185. -------------------
  186. -------------
  187. -----
  188. --
  189. -- // BOT HOUSEKEEPING
  190. eval x | "!version" `isPrefixOf` x = privmsg "This version of Digits BedRock Info bot is for 0.7 https://bedrocklinux.org/0.7/index.html" -- see !v for bedrock version
  191. eval x | "!dbri" `isPrefixOf` x = privmsg "This version of Digits BedRock Info bot is for 0.7 https://bedrocklinux.org/0.7/index.html"
  192. eval x | "!about" `isPrefixOf` x = privmsg "This version of Digits BedRock Info bot is for 0.7 https://bedrocklinux.org/0.7/index.html"
  193. eval x | "!source" `isPrefixOf` x = privmsg "https://notabug.org/Digit/dbls/src/master/bots/dbri.hs"
  194. -- EXIT FEATURE
  195. --old basic leave, straight n clean, for reference:
  196. eval "!leave" = write "QUIT" ":Exiting" >> io (exitWith ExitSuccess)
  197. -- RIDDANCE FEATURE
  198. -- issues any of the exit commands if dbri is mentioned with them, in case of annoyance/abuse.
  199. --disabled while fatherjack feature is addressing dbri directly. -- need get this into the one "eval x | "dbri" for when being spoken to, to fathom the if/thens. ... fuckit... disable the riddances for now. keep directaddressingfatherjackmode on for testing/dev purposes.
  200. eval x | "dbri" `isInfixOf` x = (if any (`isInfixOf` x) riddances then write "QUIT" ":Exiting" >> io (exitWith ExitSuccess) else return())
  201. --
  202. -- WEBSEARCH FEATURE
  203. eval x | "!search " `isPrefixOf` x = privmsg ("https://lmddgtfy.net/?q=" ++ (drop 8 x) ++ " ok?") -- added this back in to be useful.
  204. -- PARROT FEATURE
  205. eval x | "!repeat " `isPrefixOf` x = privmsg (drop 8 x) -- comment out to minimise a11buse
  206. -- FATHERJACK FEATURE -- as currently is at time of writing, can only have one eval x | dbri. jack or exit... your choice.
  207. --(... is that a case of simply needing use something other than x?, ~(izata calda "scope colision" or summin?))
  208. -- ... shud be able to suss how to ifif or something to mend that... when brain switched on. for goodness sake, dont commit with this bilge still here...
  209. -- or, i need be savvy and move this into the one "eval x | "dbri" for when being spoken to, to fathom the if/thens. ... fuckit... disable the riddances for now. keep this for testing/dev purposes. --- noh, leave the riddances, on. " riddances more important than jack feature. leaving as is (with commenting). until i suss a way to get them merged into one.... like the if statements not already clunky, heh."
  210. --eval x | "dbri:" `isPrefixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
  211. eval _ = return () -- ignore everything else
  212. -- Send a privmsg to the current chan + server
  213. privmsg :: String -> Net ()
  214. privmsg s = write "PRIVMSG" (chan ++ " :" ++ s)
  215. -- Send a message out to the server we're currently connected to
  216. write :: String -> String -> Net ()
  217. write s t = do
  218. h <- asks socket
  219. io $ hPrintf h "%s %s\r\n" s t
  220. io $ printf "> %s %s\n" s t
  221. -- Convenience.
  222. io :: IO a -> Net a
  223. io = liftIO