Showing posts with label haskell. Show all posts
Showing posts with label haskell. Show all posts

Tuesday, December 31, 2019

Validated Hamlet Textarea Form Field

Here is my custom textarea field that validates correct hamlet content

in the Form:
...
  (hamletHtmlResult, hamletHtmlView) <- mreq validatedHamletTextareaField
...

the field:

validatedHamletTextareaField :: Field (HandlerFor App) Textarea
validatedHamletTextareaField = checkM isValidHamlet textareaField
  where
    isValidHamlet :: Textarea -> Handler (Either AppMessage Textarea)
    isValidHamlet textarea@(Textarea text) = do
      eitherParsedTemplate <- tryParse text
      return $
        case eitherParsedTemplate of
          Left _ -> Left MsgGlobalInvalidHamlet
          Right _ -> Right $ Textarea text
      where
        tryParse :: Text -> Handler (Either SomeException HamletTemplate)
        tryParse text = try $ parseHamletTemplate defaultHamletSettings $ unpack text

Thursday, September 12, 2019

haskell LDAP TLS

import Ldap.Client as Ldap
import qualified Ldap.Client.Bind as Ldap

ldapTest :: App -> IO Text
ldapTest app = do
  let ldapHost = .....
  let ldapPort = .....
  let ldapBindDn = .....
  let ldapBindPassword = .....
  let tlsSettings = if .....
                    then Ldap.defaultTlsSettings
                    else Ldap.insecureTlsSettings
  res <- Ldap.with (Ldap.Tls ldapHost tlsSettings) (fromInteger ldapPort) $ \l -> do
    Ldap.bind l
      (Dn ldapBindDn)
      (Password $ encodeUtf8 ldapBindPassword)
    Ldap.search l
      (Dn "dc=.....")
      (typesOnly False)
      (And [ Attr "objectCategory" := "Person"
           , Attr "objectClass" := "user"
           , Attr "sAMAccountName" := encodeUtf8 "xyzuser"
           ])
      []
  case res of
    Left  e -> return $ pack $ "ERROR: " ++ show e
    Right t -> return $ pack $ "OK: " ++ show t

Saturday, December 22, 2018

CommandBuilder-Monad as EDSL (sort of WriterMonad)


{-# LANGUAGE OverloadedStrings #-}
module Main where

import Control.Applicative
import Control.Monad
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.List as L

main :: IO ()
main = do
  putStrLn "build actions"
  let actions = do
        fooAction
        barAction "aaa"
        barAction "bbb"
        do
          fooAction
          barAction "ccc"
          barAction "ddd"
        fooAction
        barAction "eee"
        barAction "fff"
  putStrLn "execute actions"                                                                                                 
  let results = execute actions
  forM_ results T.putStrLn

fooAction :: Builder
fooAction = build $ Action "foo action"

barAction :: Text -> Builder
barAction text = build $ Action $ T.concat ["bar action (", text, ")"]                                                       


build :: Action -> Builder
build action = BuilderM () [action]

execute :: Builder -> [Text]
execute (BuilderM _ actions) = L.map actionText actions

actionText :: Action -> Text
actionText (Action text) = text

data Action = Action Text
  deriving Show

data BuilderM a = BuilderM a [Action]
  deriving Show

type Builder = BuilderM ()

instance Functor BuilderM where
  fmap = liftM

instance Applicative BuilderM where
  pure  = return
  (<*>) = ap

instance Monad BuilderM where
  return a            = BuilderM a []
  BuilderM a xs >>= f = let BuilderM b ys = f a
                        in  BuilderM b (xs++ys)


$ stack build && stack exec ...                                                       
build actions
execute actions
foo action
bar action (aaa)
bar action (bbb)
foo action
bar action (ccc)
bar action (ddd)
foo action
bar action (eee)
bar action (fff)

Friday, May 18, 2018

nixos haskell yesod package with overrides

create a new file my-stack-project.nix:

let
  pkgs = import  {};
  pkg = pkgs.haskellPackages.callCabal2nix "my-stack-project" ./. {};
in
  pkgs.haskell.lib.overrideCabal pkg (_: {
    doHaddock = false;
    postInstall = ''
      cp -r ./static $out/bin
      cp -r ./config $out/bin
    '';
  })

nixos haskell package without default.nix

create a new file my-stack-project.nix:

let
  pkgs = import  {};
in
  pkgs.haskellPackages.callCabal2nix "my-stack-project" ./. {}

nixos haskell package with default.nix

generate the default.nix with

cd my-stack-project
cabal2nix . > default.nix

create a new file my-stack-project.nix:

let
  pkgs = import  {};
in
  pkgs.haskellPackages.callPackage ./default.nix {}

Tuesday, October 17, 2017

haskell set file modes


import System.Posix.Files (setFileMode, groupReadMode)
import System.Directory (getDirectoryContents)

tmpFilePaths <- liftIO $ getDirectoryContents staticDir
forM_ tmpFilePaths (\path -> do
                               liftIO $ setFileMode path groupReadMode
                   )

Tuesday, September 26, 2017

Yesod embed json in html


getPersonListR :: Handler Html
getPersonListR = do
  urlRender <- getUrlRender
  personEnts <- runDB $ selectList [] [Asc PersonId]
  let jData = map (\(Entity personId person) ->
                      JPerson { jPersonPerson = person
                              , jPersonEditFormUrl = urlRender $ PersonEditFormR personId }
                  ) personEnts
  jsonData <- returnJson jData >>= return . toJsonText
  defaultLayout $ do
    toWidgetBody [julius|var data = #{rawJS jsonData}|]
    $(widgetFile "person_list")

data JPerson = JPerson
  { jPersonPerson :: Person
  , jPersonEditFormUrl :: Text
  }

Thursday, May 12, 2016

Wednesday, December 30, 2015

haskell yesod curl POST request ... handling CSRF


get the cookie with token in it:

$ curl -c cookie.txt http://localhost:3000/

$ cat cookie.txt 
# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_localhost FALSE / FALSE 1451524550 _SESSION gxV1yVNefLhiS7K3/ukfWWi5GXfD7wXfwJFYDXk3fz/HvyPqcSIcU7BBIKdOrj0jrpcU9DroL0+ioD3rr8cbvCSy+A+jPDpt/8kkiSPjYE86cGyTiueVo2cOGWcc8=
localhost FALSE / FALSE 0 XSRF-TOKEN seQLdve8GY


use token:

$ curl -v \
    --cookie cookie.txt \
    -c cookie.txt \
    -H "x-xsrf-token: seQLdve8GY" \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -X POST \
    -d '{"foo":"bar", ...}' \
    http://localhost:3000/updateDruckprodukt

Saturday, August 08, 2015

yesod persistent enum type

State.hs
{-# LANGUAGE TemplateHaskell #-}
module State where

import Database.Persist.TH
import Prelude

data State = New | Released
    deriving (Show, Read, Eq)
derivePersistField "State"
models
MyModel json
    state S.State
    createdAt UTCTime default=CURRENT_TIME
Model.hs
import qualified State as S

instance ToJSON S.State where
    toJSON S.New = String "New"
    toJSON S.Released = String "Released"

instance FromJSON S.State where
    parseJSON (String "New") = pure S.New
    parseJSON (String "Released") = pure S.Released

Thursday, June 18, 2015

runhaskell in cabal sandbox

mkdir foo
cd foo
cabal sandbox init
cabal install ...
cabal exec runhaskell hello.hs

Monday, February 16, 2015

haskell Writer IO monad transformer sample

module Main where

import Control.Monad.Writer (WriterT, tell, runWriterT)

main :: IO ()
main = do
  result <- runWriterT main'
  print result
  return ()

main' :: WriterT [String] IO ()
main' = do
  x <- foo
  y <- bar
  tell [show x ++ show y]
  return ()

foo :: WriterT [String] IO Int
foo = do
  tell ["foo"]
  return 42

bar :: WriterT [String] IO Int
bar = do
  tell ["bar"]
  return 43

Monday, January 26, 2015

haskell Data.Text.Format example

{-# LANGUAGE OverloadedStrings #-}

import Data.Text
import qualified Data.Text.Format as TF

main :: IO ()
main = do
     print $ TF.format "foo {}" $ TF.Only ("bar" :: Text)

     let str = "world" :: Text
     print $ TF.format strf $ TF.Only str

     let num = 123 :: Integer
     print $ TF.format multif (str, num)

strf :: TF.Format                                                                         
strf = "hello {}"                                                                         

multif :: TF.Format                                                                       
multif = "hello {} {}"

Friday, November 28, 2014

haskell shellac skeleton sample

module ShellacTest where

import System.Console.Shell
import System.Console.Shell.ShellMonad
import System.Console.Shell.Backend.Basic

react :: String -> Sh () ()
react s = shellPutStrLn $ "exec command: " ++ s

main :: IO ()
main = do
  runShell shellDescr' basicBackend ()
  where shellDescr = mkShellDescription shellCommands react
        shellDescr' = shellDescr {greetingText = Just "welcome to shellac\n  type \"quit\" or \"exit\" to quit\n  or \"?\" for help\n",
                                  prompt = \_ -> return "prompt> ",
                                  commandStyle = OnlyCommands,
                                  shellCommands = shellCommands
                                 }
        shellCommands = [exitCommand "quit", exitCommand "exit",
                         helpCommand "?"]