2016-05-25 06:48:21 +09:00
|
|
|
|
{- This file is part of Vervis.
|
|
|
|
|
-
|
2019-02-15 07:13:58 +09:00
|
|
|
|
- Written in 2016, 2019 by fr33domlover <fr33domlover@riseup.net>.
|
2016-05-25 06:48:21 +09:00
|
|
|
|
-
|
|
|
|
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
|
|
|
|
-
|
|
|
|
|
- The author(s) have dedicated all copyright and related and neighboring
|
|
|
|
|
- rights to this software to the public domain worldwide. This software is
|
|
|
|
|
- distributed without any warranty.
|
|
|
|
|
-
|
|
|
|
|
- You should have received a copy of the CC0 Public Domain Dedication along
|
|
|
|
|
- with this software. If not, see
|
|
|
|
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Vervis.Handler.Group
|
|
|
|
|
( getGroupsR
|
|
|
|
|
, postGroupsR
|
|
|
|
|
, getGroupNewR
|
2019-02-15 07:13:58 +09:00
|
|
|
|
, getGroup
|
2016-05-26 01:03:58 +09:00
|
|
|
|
, getGroupMembersR
|
2016-05-26 02:48:17 +09:00
|
|
|
|
, postGroupMembersR
|
|
|
|
|
, getGroupMemberNewR
|
|
|
|
|
, getGroupMemberR
|
|
|
|
|
, deleteGroupMemberR
|
|
|
|
|
, postGroupMemberR
|
2016-05-25 06:48:21 +09:00
|
|
|
|
)
|
|
|
|
|
where
|
|
|
|
|
|
|
|
|
|
import Prelude
|
|
|
|
|
|
|
|
|
|
import Control.Monad.IO.Class (liftIO)
|
2016-05-25 16:24:34 +09:00
|
|
|
|
import Data.Maybe (fromMaybe)
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Data.Time.Clock (getCurrentTime)
|
2016-06-02 07:01:01 +09:00
|
|
|
|
import Database.Esqueleto hiding ((==.), (!=.), delete)
|
|
|
|
|
import Database.Persist
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Text.Blaze.Html (Html)
|
2016-05-26 00:52:15 +09:00
|
|
|
|
import Yesod.Auth (requireAuthId)
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Yesod.Core (defaultLayout, setMessage)
|
2019-02-15 07:13:58 +09:00
|
|
|
|
import Yesod.Core.Content (TypedContent)
|
|
|
|
|
import Yesod.Core.Handler
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Yesod.Form.Functions (runFormPost)
|
|
|
|
|
import Yesod.Form.Types (FormResult (..))
|
|
|
|
|
import Yesod.Persist.Core (runDB, getBy404)
|
|
|
|
|
|
2016-06-02 07:01:01 +09:00
|
|
|
|
import qualified Database.Esqueleto as E
|
|
|
|
|
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Vervis.Form.Group
|
|
|
|
|
import Vervis.Foundation
|
|
|
|
|
import Vervis.Model
|
2016-05-26 00:52:15 +09:00
|
|
|
|
import Vervis.Model.Group
|
2016-05-25 16:24:34 +09:00
|
|
|
|
import Vervis.Model.Ident (ShrIdent, shr2text)
|
2016-05-25 06:48:21 +09:00
|
|
|
|
import Vervis.Settings (widgetFile)
|
2016-05-25 16:50:10 +09:00
|
|
|
|
import Vervis.Time (showDate)
|
2019-06-07 13:26:32 +09:00
|
|
|
|
import Vervis.Widget.Sharer
|
2016-05-25 06:48:21 +09:00
|
|
|
|
|
|
|
|
|
getGroupsR :: Handler Html
|
|
|
|
|
getGroupsR = do
|
|
|
|
|
groups <- runDB $ select $ from $ \ (sharer, group) -> do
|
2016-06-02 07:01:01 +09:00
|
|
|
|
where_ $ sharer ^. SharerId E.==. group ^. GroupIdent
|
2016-05-25 06:48:21 +09:00
|
|
|
|
orderBy [asc $ sharer ^. SharerIdent]
|
|
|
|
|
return sharer
|
|
|
|
|
defaultLayout $(widgetFile "group/list")
|
|
|
|
|
|
|
|
|
|
postGroupsR :: Handler Html
|
|
|
|
|
postGroupsR = do
|
|
|
|
|
((result, widget), enctype) <- runFormPost newGroupForm
|
|
|
|
|
case result of
|
|
|
|
|
FormSuccess ng -> do
|
|
|
|
|
now <- liftIO getCurrentTime
|
2016-05-26 00:52:15 +09:00
|
|
|
|
pid <- requireAuthId
|
2016-05-25 06:48:21 +09:00
|
|
|
|
runDB $ do
|
|
|
|
|
let sharer = Sharer
|
|
|
|
|
{ sharerIdent = ngIdent ng
|
|
|
|
|
, sharerName = ngName ng
|
|
|
|
|
, sharerCreated = now
|
|
|
|
|
}
|
|
|
|
|
sid <- insert sharer
|
|
|
|
|
let group = Group
|
|
|
|
|
{ groupIdent = sid
|
|
|
|
|
}
|
2016-05-26 00:52:15 +09:00
|
|
|
|
gid <- insert group
|
|
|
|
|
let member = GroupMember
|
|
|
|
|
{ groupMemberPerson = pid
|
|
|
|
|
, groupMemberGroup = gid
|
|
|
|
|
, groupMemberRole = GRAdmin
|
2016-05-27 01:25:23 +09:00
|
|
|
|
, groupMemberJoined = now
|
2016-05-26 00:52:15 +09:00
|
|
|
|
}
|
|
|
|
|
insert_ member
|
2019-02-15 07:13:58 +09:00
|
|
|
|
redirect $ SharerR $ ngIdent ng
|
2016-05-25 06:48:21 +09:00
|
|
|
|
FormMissing -> do
|
|
|
|
|
setMessage "Field(s) missing"
|
|
|
|
|
defaultLayout $(widgetFile "group/new")
|
|
|
|
|
FormFailure _l -> do
|
|
|
|
|
setMessage "Group creation failed, see errors below"
|
|
|
|
|
defaultLayout $(widgetFile "group/new")
|
|
|
|
|
|
|
|
|
|
getGroupNewR :: Handler Html
|
|
|
|
|
getGroupNewR = do
|
|
|
|
|
((_result, widget), enctype) <- runFormPost newGroupForm
|
|
|
|
|
defaultLayout $(widgetFile "group/new")
|
|
|
|
|
|
2019-02-15 07:13:58 +09:00
|
|
|
|
getGroup :: ShrIdent -> Group -> Handler TypedContent
|
|
|
|
|
getGroup shar group = selectRep $ provideRep $
|
2016-06-06 23:13:33 +09:00
|
|
|
|
defaultLayout $(widgetFile "group/one")
|
2016-05-26 01:03:58 +09:00
|
|
|
|
|
|
|
|
|
getGroupMembersR :: ShrIdent -> Handler Html
|
|
|
|
|
getGroupMembersR shar = do
|
2016-05-25 16:24:34 +09:00
|
|
|
|
(group, members) <- runDB $ do
|
|
|
|
|
Entity sid s <- getBy404 $ UniqueSharer shar
|
|
|
|
|
Entity gid _g <- getBy404 $ UniqueGroup sid
|
|
|
|
|
ms <- select $ from $ \ (member, person, sharer) -> do
|
|
|
|
|
where_ $
|
2016-06-02 07:01:01 +09:00
|
|
|
|
member ^. GroupMemberGroup E.==. val gid &&.
|
|
|
|
|
member ^. GroupMemberPerson E.==. person ^. PersonId &&.
|
|
|
|
|
person ^. PersonIdent E.==. sharer ^. SharerId
|
2016-05-26 00:52:15 +09:00
|
|
|
|
orderBy
|
|
|
|
|
[ asc $ member ^. GroupMemberRole
|
|
|
|
|
, asc $ sharer ^. SharerIdent
|
|
|
|
|
]
|
2016-05-25 16:24:34 +09:00
|
|
|
|
return sharer
|
|
|
|
|
return (s, ms)
|
2016-05-27 01:25:23 +09:00
|
|
|
|
defaultLayout $(widgetFile "group/member/list")
|
|
|
|
|
|
|
|
|
|
getgid :: ShrIdent -> AppDB GroupId
|
|
|
|
|
getgid shar = do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer shar
|
|
|
|
|
Entity g _ <- getBy404 $ UniqueGroup s
|
|
|
|
|
return g
|
2016-05-26 02:48:17 +09:00
|
|
|
|
|
|
|
|
|
postGroupMembersR :: ShrIdent -> Handler Html
|
2016-05-27 01:25:23 +09:00
|
|
|
|
postGroupMembersR shar = do
|
|
|
|
|
((result, widget), enctype) <-
|
|
|
|
|
runFormPost $ newGroupMemberForm $ getgid shar
|
|
|
|
|
case result of
|
|
|
|
|
FormSuccess ngm -> do
|
|
|
|
|
now <- liftIO getCurrentTime
|
|
|
|
|
runDB $ do
|
|
|
|
|
gid <- getgid shar
|
|
|
|
|
pid <- do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer $ ngmIdent ngm
|
|
|
|
|
Entity p _ <- getBy404 $ UniquePersonIdent s
|
|
|
|
|
return p
|
|
|
|
|
let member = GroupMember
|
|
|
|
|
{ groupMemberPerson = pid
|
|
|
|
|
, groupMemberGroup = gid
|
|
|
|
|
, groupMemberRole = ngmRole ngm
|
|
|
|
|
, groupMemberJoined = now
|
|
|
|
|
}
|
|
|
|
|
insert_ member
|
|
|
|
|
redirect $ GroupMemberR shar $ ngmIdent ngm
|
|
|
|
|
FormMissing -> do
|
|
|
|
|
setMessage "Field(s) missing"
|
|
|
|
|
defaultLayout $(widgetFile "group/member/new")
|
|
|
|
|
FormFailure _l -> do
|
|
|
|
|
setMessage "Member insertion failed, see errors below"
|
|
|
|
|
defaultLayout $(widgetFile "group/member/new")
|
2016-05-26 02:48:17 +09:00
|
|
|
|
|
|
|
|
|
getGroupMemberNewR :: ShrIdent -> Handler Html
|
2016-05-27 01:25:23 +09:00
|
|
|
|
getGroupMemberNewR shar = do
|
|
|
|
|
((_result, widget), enctype) <-
|
|
|
|
|
runFormPost $ newGroupMemberForm $ getgid shar
|
|
|
|
|
defaultLayout $(widgetFile "group/member/new")
|
2016-05-26 02:48:17 +09:00
|
|
|
|
|
|
|
|
|
getGroupMemberR :: ShrIdent -> ShrIdent -> Handler Html
|
2016-06-02 07:01:01 +09:00
|
|
|
|
getGroupMemberR grp memb = do
|
|
|
|
|
member <- runDB $ do
|
|
|
|
|
gid <- do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer grp
|
|
|
|
|
Entity g _ <- getBy404 $ UniqueGroup s
|
|
|
|
|
return g
|
|
|
|
|
pid <- do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer memb
|
|
|
|
|
Entity p _ <- getBy404 $ UniquePersonIdent s
|
|
|
|
|
return p
|
|
|
|
|
Entity _mid m <- getBy404 $ UniqueGroupMember pid gid
|
|
|
|
|
return m
|
|
|
|
|
defaultLayout $(widgetFile "group/member/one")
|
2016-05-26 02:48:17 +09:00
|
|
|
|
|
|
|
|
|
deleteGroupMemberR :: ShrIdent -> ShrIdent -> Handler Html
|
2016-06-02 07:01:01 +09:00
|
|
|
|
deleteGroupMemberR grp memb = do
|
|
|
|
|
succ <- runDB $ do
|
|
|
|
|
gid <- do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer grp
|
|
|
|
|
Entity g _ <- getBy404 $ UniqueGroup s
|
|
|
|
|
return g
|
|
|
|
|
pid <- do
|
|
|
|
|
Entity s _ <- getBy404 $ UniqueSharer memb
|
|
|
|
|
Entity p _ <- getBy404 $ UniquePersonIdent s
|
|
|
|
|
return p
|
|
|
|
|
mm <-
|
|
|
|
|
selectFirst
|
|
|
|
|
[ GroupMemberGroup ==. gid
|
|
|
|
|
, GroupMemberPerson !=. pid
|
|
|
|
|
, GroupMemberRole ==. GRAdmin
|
|
|
|
|
]
|
|
|
|
|
[]
|
|
|
|
|
case mm of
|
|
|
|
|
Nothing -> return False
|
|
|
|
|
Just _ -> do
|
|
|
|
|
Entity mid _m <- getBy404 $ UniqueGroupMember pid gid
|
|
|
|
|
delete mid
|
|
|
|
|
return True
|
|
|
|
|
setMessage $
|
|
|
|
|
if succ
|
|
|
|
|
then "Group member removed."
|
|
|
|
|
else "Can’t leave a group without an admin."
|
|
|
|
|
redirect $ GroupMembersR grp
|
2016-05-26 02:48:17 +09:00
|
|
|
|
|
|
|
|
|
postGroupMemberR :: ShrIdent -> ShrIdent -> Handler Html
|
|
|
|
|
postGroupMemberR grp memb = do
|
|
|
|
|
mmethod <- lookupPostParam "_method"
|
|
|
|
|
case mmethod of
|
|
|
|
|
Just "DELETE" -> deleteGroupMemberR grp memb
|
|
|
|
|
_ -> notFound
|