diff --git a/README.md b/README.md index 8f8616b..7958ab1 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,7 @@ The goal is to provide a minimalistic and fast todo list that is self hostable. - [ ] write a minimal step by step guide to install with nix, - [ ] add some css to make it look nicer - [ ] add htmx to make more agreable without making js manadatory - - [x] make api to allow usage with native app (a way to get every list that has been modified since date $date belonging from the user in a json or similar format) - - [ ] document api to help create clients + - [ ] make api to allow usage with native app (a way to get every list that has been modified since date $date belonging from the user in a json or similar format) ## Version 0.0.3 Simple todo list webapp. Features : diff --git a/client_session_key.aes b/client_session_key.aes deleted file mode 100644 index 70e3c9c..0000000 --- a/client_session_key.aes +++ /dev/null @@ -1 +0,0 @@ -:M^O2I蚑4,pe8ķ,CI(q7/gGuL'(ɜwq1I#pYW)2L{2;v_i[ʳY \ No newline at end of file diff --git a/config/models.persistentmodels b/config/models.persistentmodels index d9a31b5..bb9d354 100644 --- a/config/models.persistentmodels +++ b/config/models.persistentmodels @@ -8,15 +8,12 @@ TodolistItem Todolist groupId GroupId OnDeleteCascade title Text - lastModified UTCTime UniqueListPair groupId title - deriving Show User name Text UniqueName name Group group Text - lastModified UTCTime GroupUser user UserId groupId GroupId OnDeleteCascade \ No newline at end of file diff --git a/config/routes.yesodroutes b/config/routes.yesodroutes index b310a04..9d7e398 100644 --- a/config/routes.yesodroutes +++ b/config/routes.yesodroutes @@ -26,4 +26,3 @@ /delete DeleteGroupR POST /delete/group/#GroupId DeleteTodolistR POST -/api/#Int ApiR GET diff --git a/src/Application.hs b/src/Application.hs index 7be018c..fd6e107 100644 --- a/src/Application.hs +++ b/src/Application.hs @@ -47,7 +47,6 @@ import Handler.Common import Handler.Group import Handler.Todolist import Handler.TodolistItem -import Handler.Api -- This line actually creates our YesodDispatch instance. It is the second half -- of the call to mkYesodData which occurs in Foundation.hs. Please see the diff --git a/src/Foundation.hs b/src/Foundation.hs index bdd1015..d031441 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -12,7 +12,7 @@ module Foundation where import Import.NoFoundation import Data.Kind (Type) -import Database.Persist.Sql (ConnectionPool, runSqlPool, rawSql) +import Database.Persist.Sql (ConnectionPool, runSqlPool) import Text.Hamlet (hamletFile) import Text.Jasmine (minifym) import Control.Monad.Logger (LogSource) @@ -208,9 +208,4 @@ dbIfAuth groupId action = do user <- getUserId result <- runDB $ selectFirst [GroupUserUser ==. user, GroupUserGroupId ==. groupId] [] if isNothing result then permissionDenied "you are not logged in or you dont have access to this group" - else runDB action - -getGroups :: Key User -> Handler [Entity Group] -getGroups userId = - let sql = "SELECT ?? FROM \"group\" JOIN group_user gu ON \"group\".id = gu.group_id WHERE gu.user = ?" in - runDB $ rawSql sql [toPersistValue userId] \ No newline at end of file + else runDB action \ No newline at end of file diff --git a/src/Handler/Api.hs b/src/Handler/Api.hs deleted file mode 100644 index f429a0e..0000000 --- a/src/Handler/Api.hs +++ /dev/null @@ -1,52 +0,0 @@ -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE OverloadedStrings #-} - -module Handler.Api where - -import Import -import Database.Persist.Sql (rawSql) -import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds) -import qualified Data.Text as Text -getApiR :: Int -> Handler TypedContent -getApiR time = do - -- TODO: use only one runDB - userId <- getUserId - -- We get all groups no matter what, since else we can't know which groups have been deleted - groups <- getGroups userId - let utcTime = posixSecondsToUTCTime (fromIntegral time) - let sqlLists = "select ?? from todolist join group_user on todolist.group_id = group_user.group_id and group_user.user = ? join \"group\" on todolist.group_id = \"group\".id and \"group\".last_modified > ?;" - lists <- runDB $ rawSql sqlLists [toPersistValue userId, toPersistValue utcTime] - let a = lists :: [Entity Todolist] - let sqlItems = "select ?? from todolist join group_user on todolist.group_id = group_user.group_id and group_user.user = ? join \"group\" on todolist.group_id = \"group\".id and \"group\".last_modified > ? join todolist_item on todolist_item.todolist_id = todolist.id;" - items <- runDB $ rawSql sqlItems [toPersistValue userId, toPersistValue utcTime] - let t = unlines $ map groupToCSV groups <> map todolistToCSV lists <> map todolistItemToCSV items - return $ TypedContent typePlain $ toContent t - -todolistItemToCSV :: Entity TodolistItem -> Text -todolistItemToCSV item = "i," <> fieldToText item -todolistToCSV :: Entity Todolist -> Text -todolistToCSV list = "l," <> fieldToText list -groupToCSV :: Entity Group -> Text -groupToCSV group = "g," <> fieldToText group - --- TODO: error management ? (maybe use Either Text Text and then propagate left to handler and send error ?) -fieldToText :: PersistEntity record => Entity record -> Text -fieldToText field = Text.intercalate "," (map persistValueToText $ entityValues field) - -persistValueToText :: PersistValue -> Text -persistValueToText (PersistText s) = s -persistValueToText (PersistInt64 i) = Text.pack $ show i -persistValueToText (PersistUTCTime d) = Text.pack $ show $ floor (utcTimeToPOSIXSeconds d) -persistValueToText (PersistBool b) = if b then "T" else "F" -persistValueToText _ = error "Wrong input type" - -getText :: Text -getText = do - -- GET EVERY GROUP THAT HAS BEEN MODIFIED SINCE TIMESTAMP FROM USER - - -- GET EVERY TODOLIST THAT HAS BEEN MODIFIED SINCE TIMESTAMP - -- GET EVERY ITEM FROM THESE TODOLISTS - -- ENCODE ALL OF THEM IN THE TEXTFILE - -- SEND IT ! - -- DONE :) - error "not done yet" \ No newline at end of file diff --git a/src/Handler/Group.hs b/src/Handler/Group.hs index eb15bea..16fc7c1 100644 --- a/src/Handler/Group.hs +++ b/src/Handler/Group.hs @@ -11,7 +11,7 @@ module Handler.Group where import Import import Text.Read -import Database.Persist.Sql (fromSqlKey, toSqlKey) +import Database.Persist.Sql (fromSqlKey, toSqlKey, rawSql) getGroupR :: Handler Html getGroupR = do userId <- getUserId @@ -25,8 +25,7 @@ postAddGroupR = do -- TODO: in a newer version, put insertUnique_ user <- getUserId _ <- runDB $ do - currentTime <- liftIO getCurrentTime - gId <- insert $ Group g currentTime + gId <- insert $ Group g success <- insertUnique $ GroupUser user gId when (isNothing success) $ delete gId redirect GroupR @@ -55,4 +54,9 @@ postDeleteGroupR = do let ids = map toSqlKey ints :: [GroupId] -- TODO: make sure the user has access to it aswell (this only works now for single user), and handle group owned by many runDB $ deleteWhere [GroupId <-. ids] - redirect EditGroupR \ No newline at end of file + redirect EditGroupR + +getGroups :: Key User -> Handler [Entity Group] +getGroups userId = + let sql = "SELECT ?? FROM \"group\" JOIN group_user gu ON \"group\".id = gu.group_id WHERE gu.user = ?" in + runDB $ rawSql sql [toPersistValue userId] \ No newline at end of file diff --git a/src/Handler/Todolist.hs b/src/Handler/Todolist.hs index 1520130..7dcfbeb 100644 --- a/src/Handler/Todolist.hs +++ b/src/Handler/Todolist.hs @@ -16,8 +16,7 @@ postAddTodolistR :: GroupId -> Handler Html postAddTodolistR groupId = do list <- runInputPost $ ireq textField "list" -- TODO: in a newer version, put insertUnique_ - currentTime <- liftIO getCurrentTime - _ <- dbIfAuth groupId (insertUnique $ Todolist groupId list currentTime) + _ <- dbIfAuth groupId (insertUnique $ Todolist groupId list) redirect $ TodolistR groupId -- TODO: move this to a new handler file