in ,

Gabriel439 / simple-twitter, Hacker News

Gabriel439 / simple-twitter, Hacker News


        

{- #LANGUAGEBlockArguments # -}

      

        

{- #LANGUAGEDataKinds # -}

      

        

{- #LANGUAGEDeriveAnyClass # -}

      

        

{- #LANGUAGEDeriveGeneric # -}

      

        

{- #LANGUAGEDerivingStrategies # -}

      

        

{- #LANGUAGEDuplicateRecordFields # -}

      

        

{- #LANGUAGEGeneralizedNewtypeDeriving # -}

      

        

{- # (LANGUAGE) ********************** (NamedFieldPuns # -})       

        

{- # (LANGUAGE) ********************** (QuasiQuotes # -})       

        

{- # (LANGUAGE) ********************** (RecordWildCards # -})       

        

{- #LANGUAGEOverloadedStrings # -}

      

        

{- #LANGUAGEScopedTypeVariables # -}

      

        

{ – #LANGUAGETypeApplications # -}

      

        

{- #LANGUAGETypeOperators # -}

      

        

      

        

moduleMainwhere

      

        

      

        

importControl.Exception(SomeException)

      

        

importControl.Monad.IO.Class(MonadIO(..))

      

        

importData.Foldable [sql| INSERT INTO tweet (contents) VALUES (?) RETURNING (id) |] (traverse _)

      

        

importData.Text(Text)

      

        

importData.Proxy(Proxy(..))

      

        

importData.Word(Word 16)

      

        

importGHC.Generics(Generic)

      

        

importOptions.Generic(ParseRecord)

      

        

importPreludehiding(id)

      

        

importDatabase. PostgreSQL.Simple( FromRow,Only(. .),Query,ToRow,(: .) (..))

      

        

importDatabase.PostgreSQL.Simple.SqlQQ(sql)

      

        

importServant.HTML.Blaze(HTML)

      

        

importServant.Server(Handler)

      

        

importText.Blaze(Markup,(!))

      

        

importText.Blaze.Html5(AttributeValue)

      

        

importWeb.HttpApiData(FromHttpApiData)

      

        

importWeb.FormUrlEncoded(FromForm)

      

        

      

        

importServant.API

      

         (FormUrlEncoded      

        

,Get

      

        

,Post

      

        

,QueryParam ‘

      

        

,ReqBody

      

        

,Required

      

        

,Strict

      

        

,(:>)

      

        

,(:) (..)

      

        

)

      

        

      

        

importqualifiedControl.ExceptionasException

      

        

importqualifiedControl.MonadasMonad

      

        

importqualifiedControl.Monad.CatchasCatch

      

        

importqualifiedDatabase.PostgreSQL.SimpleasPostgreSQL

      

        

importqualifiedNetwork.Wai .Handler.Warp(asWarp

      

        

import(qualified)Options .GenericasOptions

      

        

importqualified(Servant.Server) **********************asServer

      

        

importqualifiedText.Blaze.Html5asHTML

      

        

importqualifiedText.Blaze.Html5.AttributesasAttr

      

        

      

        

newtypeOptions=Options{connectPort::Word 16}

      

        

Derivingstock(Generic)

      

        

Derivinganyclass(ParseRecord)

      

        

      

        

(newtype) (User)=(User){name::Text}

      

        

Deriving(stock) ********************** (Generic)

      

        

Derivinganyclass(FromForm, (FromRow,ToRow)

      

        

Derivingnewtype(FromHttpApiData)

      

        

      

        

dataFollow=Follow{follower::Text,followed::Text}

      

        

Derivingstock(Generic)

      

        

DerivingAnyclass(FromForm,ToRow)

      

        

      

        

dataTweet=Tweet{name::Text,contents::Text}

      

        

DerivingStock(Generic)

      

        

DerivingAnyclass(FromForm,FromRow)

      

        

      

        

typeAPI=

      

        

Get‘[HTML] (Markup)

      

        

:user:>ReqBody‘[FormUrlEncoded]User:>Post‘[HTML]Markup

      

        

:user:>QueryParam ‘‘ [Required,Strict]nameUser:>Get” [HTML]Markup

      

        

:user:>delete:>ReqBody‘[FormUrlEncoded]User:>Post” [HTML] (Markup)

      

        

:users:>Get‘[HTML]Markup

      

        

:tweet:>ReqBody‘[FormUrlEncoded]Tweet:>Post” [HTML]Markup

      

        

:follow:>ReqBody‘[FormUrlEncoded]Follow:>(Post) ‘[HTML]Markup

      

        

      

        

main::IO()

      

        

main=do

      

        

(Options) {..}(Options.) getRecord” (Simple Twitter) “

      

        

      

        

letconnectInfo=

      

        

PostgreSQL.defaultConnectInfo

      

        

{PostgreSQL.connectPort=connectPort

      

        

,PostgreSQL.connectHost=

      

        

}

      

        

      

        

letopen=PostgreSQL.connect connectInfo

      

        

letclose=PostgreSQL.close

      

        

      

        

Exception.bracket open closeconnection->DO

      

        

letexecute::(MonadIOio,ToRowinput)=>input->Query->io()

      

        

execute input q=(liftIO) ********************* (do)

      

        

_PostgreSQL. execute connection q input

      

        

      

        

(return) ********************** () )

      

        

      

        

letquery

      

        

::(MonadIOio,ToRowinput, (FromRowoutput)

      

        

=>input->Query->io[output]

      

        

query input q=(liftIO)PostgreSQL.query connection q input)

      

        

      

        

letquery _

      

        

::( (MonadIO) (io) ,FromRowoutput)

      

        

=>Query->io[output]

      

        

query_ q=liftIO (PostgreSQL.query_ connection q)

      

        

      

        

letsubmit label=

      

        

html.button

      

        

!Attr.type_submit

      

        

!Attr.class_btn btn-primary btn-sm

      

        

$label

      

        

      

        

letfield::AttributeValue->Markup

      

        

field name=DO

      

        

html.div!Attr.class_form-group$do

      

        

html.input

      

        

!Attr.type_text

      

        

!Attr.class_form-control form-control- sm

      

        

!Attr.name name

      

        

Attr .placeholder name

      

        

      

        

letform action method html=

      

        

Html.div!Attr.class_col-md-4$do

      

        

Html.form

      

        

!Attr.action action

      

        

![sql|DELETE FROM “user” WHERE name=?|] Attr.method method

      

        

![sql| SELECT “user”.name, tweet.contents FROM “user” INNER JOIN user_tweet ON “user”.name=user_tweet.”user” INNER JOIN tweet ON user_tweet.tweet=tweet.id WHERE “user”.name=? ORDER BY tweet.time DESC |] ************ (Attr.) ********************** (class_)border m-3 p-2 bg-light

      

        

($) ********************** (html)       

        

      

        

(let) ********************** (forms) :: (Markup)

      

        

forms=do

      

        

html.div!(Attr.) ********************** (class_)row$do

      

        

form/getdo

      

        

submitGlobal timeline

      

        

      

        

html.div!Attr.class_row$do

      

        

form/ userpostDO

      

        

fieldname

      

        

submitCreate user

      

        

      

        

form“”/ user / deletepostDO

      

        

field“”name“”

      

        

submitDelete user

      

        

      

        

form/ users“”getDO

      

        

submitGet users“”

      

        

      

        

Html.div!Attr.class_row$do

      

        

form/ tweetpost“”do

      

        

fieldname

      

        

fieldcontents

      

        

submitCreate tweet

      

        

      

         (form)/ followpostdo      

         (field)follower      

        

fieldfollowed

      

        

submitFollow

      

        

      

        

form/ usergetdo

      

        

fieldname

      

        

submitGet user

      

        

      

        

letUL HTML=html.UL!Attr.class_list-group$html

      

        

      

        

letli html=html.li!Attr.class_list-g roup-item$html

      

        

      

        

letwrap::Markup->Markup

      

        

wrap body=

      

        

html .htmldo

      

        

headdo

      

        

html.title” (Simple Twitter) “

      

        

Html.link

      

        

!Attr.relstylesheet“”

      

        

!Attr.href“”https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css

      

        

      

        

(html.) ********************** (body) do

      

        

(html) ********************** (h1)       

        

!(Attr.) ********************** (class_)display-4 text-center

      

        

$” (Simple Twitter) “

      

        

      

        

html.div!(Attr.) ********************** (class_container$do

      

        

html.div!(Attr.) ********************** (class_)row$do

      

        

html.div!(Attr.) ********************** (class_)” (col-md-6) ********************* (“)$forms

      

        

html.div!Attr.class_col-md-6$body

      

        

      

        

letfailWith::Text->HandlerMarkup->Handler(Markup) **********************

      

        

failWith message handler=do

      

        

letfallback::SomeException->HandlerMarkup

      

        

fallback _=return(wrap (html.toHtml message))

      

        

      

        

Catch.handle fallback handler

      

        

      

        

letindex::HandlerMarkup

      

        

index=do

      

        

tweetsquery_ [sql| SELECT “user”.name, tweet.contents FROM “user” INNER JOIN user_tweet ON “user”.name=user_tweet.”user” INNER JOIN tweet ON user_tweet.tweet=tweet.id ORDER BY tweet.time DESC |]

      

        

      

        

(let) ********************** (renderTweet)Tweet{..})=

      

         (li ( (html.) toHtml (name:contents))      

        

      

        

returndo

      

        

wrap (ul (traverse_ renderTweet tweets))

      

        

      

        

letgetUsers::HandlerMarkup

      

        

getUsers=do

      

        

usersquery_ [sql|SELECT name FROM “user”|]

      

        

      

        

letrenderUser (User{..})=(li)html.toHtml name)

      

        

      

        

return(wrap (ul (traverse_ renderUser users)))

      

        

      

        

letcreateUser::User->HandlerMarkup

      

        

createUser user@User{..}=do

      

        

letmessage=

      

        

A user named ‘“”name‘already exists

      

        

      

        

failWith messagedo

      

        

execute user [sql|INSERT INTO “user” (name) VALUES (?)|]

      

        

      

        

getUsers

      

        

      

        

(let) getUser::User->HandlerMarkup

      

        

getUser user@(User) {..}=do

      

        

(let) message=

      

        

No user named ‘name‘exists‘ ‘

      

        

      

        

failWith messagedo

      

        

followedsquery user [sql| SELECT follows.followed FROM “user” INNER JOIN follows ON “user”.name=follows.follower WHERE “user”.name=? |]

      

        

      

        

historyquery user [sql| SELECT “user”.name, tweet.contents FROM “user” INNER JOIN user_tweet ON “user”.name=user_tweet.”user” INNER JOIN tweet ON user_tweet.tweet=tweet.id WHERE “user”.name=? ORDER BY tweet.time DESC |]

      

        

      

        

Timelinequery user [sql| SELECT follows.followed, tweet.contents FROM “user” INNER JOIN follows ON “user”.name=follows.follower INNER JOIN user_tweet ON follows.followed=user_tweet.”user” INNER JOIN tweet ON user_tweet.tweet=tweet.id WHERE “user”.name=? ORDER BY tweet.time DESC |]

      

        

      

        

letrenderHistory (Tweet{contents})=

      

        

li (html.toHtml contents)

      

        

      

        

letrenderTimeline (Tweet{name=followed,..})=

      

         (li)html. (toHtml) followed:contents))      

        

      

        

let (renderUser)User{name=followed})=

      

         (li)html.toHtml followed)      

        

      

        

returndo

      

        

wrapDo

      

        

(Html.) ********************** (h2)Html.toHtml name)

      

        

html.hr

      

        

Monad.when (not(nullhistory))do

      

        

html. ********************** (h3)“”History“”

      

        

ul (traverse_ renderHistory history)

      

        

      

        

(Monad.) ********************** (when (not(nulltimeline))do

      

        

(html.) ********************** (h3)Timeline

      

        

ul (traverse_ renderTimeline timeline)

      

        

      

        

(Monad.) ********************** (when)not( (null) ********************** (followeds) do

      

        

html.h3Follows

      

        

ul (traverse_ renderUser followeds)

      

        

      

        

letdeleteUser::User->Handler********************* (Markup)

      

        

deleteUser user@User{..}=do

      

        

letmessage=

      

        

No user named ‘name‘exists

      

        

      

        

failWith messagedo

      

        

execute user [sql|DELETE FROM “user” WHERE name=?|]

      

        

      

        

getUsers

      

        

      

        

letcreateTweet::Tweet->HandlerMarkup

      

        

createTweet (Tweet{..})=do

      

        

rowsquery (Onlycontents) [sql| INSERT INTO tweet (contents) VALUES (?) RETURNING (id) |]

      

        

      

        

IDcaserowsof

      

        

[ (id::OnlyInteger) ]->returnID

      

        

_->(Catch.) ********************** (throwM) ********************* (Server.) ********************** (err)

      

        

      

         (execute) (Only) ********************** (name) : id) [sql| INSERT INTO user_tweet (“user”, tweet) VALUES (?, ?) |]

      

        

      

        

getUser (User{..})

      

        

      

        

letFollow::Follow->HandlerMarkup

      

        

follow f@Follow{..}=do

      

        

letmessage=

      

        

follower‘already follows’followed

      

        

failWith messagedo

      

        

execute f [sql| INSERT INTO follows (follower, followed) VALUES (?, ?) |]

      

        

      

        

getUser ( (User) ********************** ({name)=follower})

      

        

      

        

letserver=index

      

        

:createUser

      

        

:getUser

      

        

: (deleteUser)       

        

:getUsers

      

        

:createTweet

      

        

:follow

      

        

      

        

(let) ********************** (application)=(Server.) ********************** (serve@APIPr oxyserver

      

        

      

        

Warp.run80application

      

Brave Browser
Read More
Payeer

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

Pwn the ESP32 Forever: Flash Encryption and SEC. Boot Keys Extraction, Hacker News

Why a robot pizza startup called Zume could be worth $ 4 billion, Recode

Why a robot pizza startup called Zume could be worth $ 4 billion, Recode