From c1e76643ec0e10d5c3eeaafb15c0fbc5dd519f46 Mon Sep 17 00:00:00 2001 From: Adrian Sieber Date: Fri, 3 May 2024 11:03:41 +0000 Subject: [PATCH] Fix typos, auto-format code --- archive/tasklite-server/source-old/Helpers.hs | 62 ++- archive/tasklite-server/source-old/Main.hs | 363 ++++++++++-------- docs-source/differences_taskwarrior.md | 2 +- docs-source/usage/haskell_api.md | 2 +- tasklite-airsequel-app/src/Main.elm | 4 +- tasklite-core/source/Migrations.hs | 2 +- tasklite-core/source/Task.hs | 63 +-- tasklite-core/source/Utils.hs | 2 +- 8 files changed, 272 insertions(+), 228 deletions(-) diff --git a/archive/tasklite-server/source-old/Helpers.hs b/archive/tasklite-server/source-old/Helpers.hs index 57b0f41..ad5fdc3 100644 --- a/archive/tasklite-server/source-old/Helpers.hs +++ b/archive/tasklite-server/source-old/Helpers.hs @@ -4,15 +4,15 @@ module Helpers where import Protolude as P hiding (get, put) +import Control.Lens +import Crypto.BCrypt import Crypto.JOSE.JWS (CompactJWS) import Crypto.JWT as Crypto hiding (param) -import Crypto.BCrypt -import Control.Lens -import Data.Aeson as Aeson (Value(..), toJSON, decode, object) +import Data.Aeson as Aeson (Value (..), decode, object, toJSON) +import Data.HashMap.Lazy (lookup) import Data.Text.Encoding as T import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL -import Data.HashMap.Lazy (lookup) import Data.Acid as Acid import Data.Time @@ -20,8 +20,8 @@ import Network.HTTP.Types.Status import Web.Scotty as Scotty import Database -import DbUser import DbIdea +import DbUser import PostIdea import Types @@ -48,22 +48,24 @@ loginToPartialDbUser (LoginUser email password) = credentialsToDbUser "" email password -credentialsToDbUser :: Text -> Text -> Text -> IO DbUser +credentialsToDbUser :: Text -> Text -> Text -> IO DbUser credentialsToDbUser name email password = do - newHash <- hashPasswordUsingPolicy - HashingPolicy - { preferredHashCost = 10 - , preferredHashAlgorithm = "$2b$" - } - (T.encodeUtf8 password) + newHash <- + hashPasswordUsingPolicy + HashingPolicy + { preferredHashCost = 10 + , preferredHashAlgorithm = "$2b$" + } + (T.encodeUtf8 password) refresh_token <- getRefreshToken - pure $ DbUser - { password_hash = T.decodeUtf8 $ fromMaybe "" newHash - , refresh_token = Just refresh_token - , .. - } + pure $ + DbUser + { password_hash = T.decodeUtf8 $ fromMaybe "" newHash + , refresh_token = Just refresh_token + , .. + } getAudienceFromJWT :: TL.Text -> Either Text Text @@ -81,20 +83,19 @@ getAudienceFromJWT jwtBS = strToMaybe = \case (Just (String s)) -> Just s - _ -> Nothing + _ -> Nothing payloadMaybe = (strToMaybe stringValMaybe) - <&> P.encodeUtf8 - >>= preview base64url - >>= Aeson.decode + <&> P.encodeUtf8 + >>= preview base64url + >>= Aeson.decode in case payloadMaybe of Just (Object payloadObj) -> let emailMaybe = strToMaybe $ lookup "aud" payloadObj - in note "Payload does not contain an audience" emailMaybe + in note "Payload does not contain an audience" emailMaybe _ -> Left $ "JWT does not contain a payload" - _ -> Left "JWT payload is not an object" @@ -150,11 +151,9 @@ validateAndAddIdea database emailAddress claimsResult ideaResult = (Left error, _) -> do status status400 json $ toJsonError $ show error - (_, Left error) -> do status status400 json $ toJsonError error - (Right _, Right verifiedIdea) -> do newId <- liftIO getId now <- liftIO getCurrentTime @@ -181,24 +180,23 @@ validateAndReplaceIdea database emailAddress id claimsResult ideaResult = (Left error, _) -> do status status400 json $ toJsonError $ show error - (_, Left error) -> do status status400 json $ toJsonError error - (Right _, Right verifiedIdea) -> do now <- liftIO getCurrentTime let newDbIdea = PostIdea.toDbIdea id emailAddress now verifiedIdea - updateResult <- liftIO - $ update database $ UpdateIdeaIfBy emailAddress id newDbIdea + updateResult <- + liftIO $ + update database $ + UpdateIdeaIfBy emailAddress id newDbIdea case updateResult of - Left (statusCode, errorMesage) -> do + Left (statusCode, errorMessage) -> do status statusCode - json $ toJsonError errorMesage + json $ toJsonError errorMessage Right _ -> do status ok200 json $ DbIdea.toIdea newDbIdea - diff --git a/archive/tasklite-server/source-old/Main.hs b/archive/tasklite-server/source-old/Main.hs index f99e426..ae39cb7 100644 --- a/archive/tasklite-server/source-old/Main.hs +++ b/archive/tasklite-server/source-old/Main.hs @@ -1,43 +1,44 @@ -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE TypeFamilies #-} module Main where import Protolude as P hiding (get, put) -import Crypto.JWT as Crypto hiding (param) import Control.Lens +import Crypto.JWT as Crypto hiding (param) import Data.Acid as Acid -import Data.Aeson as Aeson (Value(..), object, eitherDecode) +import Data.Aeson as Aeson (Value (..), eitherDecode, object) import Data.List.Extra as List (chunksOf) import Data.String (fromString) import Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL import Data.Time -import Network.HTTP.Types.Status import Network.Gravatar +import Network.HTTP.Types.Status import System.Environment (getEnv) import Web.Scotty as Scotty import AccessToken import Database -import DbUser import DbIdea +import DbUser +import Helpers import PostIdea import SignupUser import Types -import Helpers makeClaims :: DbUser -> IO ClaimsSet makeClaims user = do now <- getCurrentTime - pure $ emptyClaimsSet - & (claimIss ?~ fromString "tasklite-server") - & (claimAud ?~ Audience [fromString $ T.unpack $ DbUser.email user]) - & (claimIat ?~ NumericDate now) - & (claimExp ?~ (NumericDate $ (fromRational 600 {-sec-}) `addUTCTime` now)) + pure $ + emptyClaimsSet + & (claimIss ?~ fromString "tasklite-server") + & (claimAud ?~ Audience [fromString $ T.unpack $ DbUser.email user]) + & (claimIat ?~ NumericDate now) + & (claimExp ?~ (NumericDate $ (fromRational 600 {-sec-}) `addUTCTime` now)) doJwtSign :: JWK -> ClaimsSet -> IO (Either JWTError SignedJWT) @@ -50,8 +51,9 @@ doJwtSign jwkValue claims = runExceptT $ do doJwtVerify :: Text -> JWK -> SignedJWT -> IO (Either JWTError ClaimsSet) doJwtVerify audEmailAddress jwkValue jwt = runExceptT $ do let - config = defaultJWTValidationSettings - (== (fromString $ T.unpack audEmailAddress)) + config = + defaultJWTValidationSettings + (== (fromString $ T.unpack audEmailAddress)) verifyClaims config jwkValue jwt @@ -66,7 +68,7 @@ refreshTokenToWebToken dbUser refreshToken = do Left error -> liftIO $ die $ show error Right jwt -> do status created201 - json $ WebToken { jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt } + json $ WebToken{jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt} refreshTokenToAccessToken :: DbUser -> RefreshToken -> ActionM () @@ -79,16 +81,18 @@ refreshTokenToAccessToken dbUser refreshToken = do Left error -> liftIO $ die $ show error Right jwt -> do status created201 - json $ AccessToken - { jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt - , refresh_token = refreshToken - } + json $ + AccessToken + { jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt + , refresh_token = refreshToken + } app :: AcidState Database -> ScottyM () app database = do - defaultHandler (\error -> do - json $ toJsonError $ toStrict $ error + defaultHandler + ( \error -> do + json $ toJsonError $ toStrict $ error ) -- Refresh JWT @@ -104,7 +108,6 @@ app database = do Left errorMessage -> notFoundAction errorMessage Right dbUser -> refreshTokenToWebToken dbUser refreshToken - -- User Login post "/access-tokens" $ do fullBody <- body @@ -113,57 +116,66 @@ app database = do Left errorMessage -> badRequest errorMessage Right loginUser -> do newToken <- liftIO getRefreshToken - loginResult <- liftIO $ update database $ LogUserIn - (Types.email loginUser) - (Types.password loginUser) - newToken + loginResult <- + liftIO $ + update database $ + LogUserIn + (Types.email loginUser) + (Types.password loginUser) + newToken case loginResult of Left (statusCode, errorMessage) -> do status statusCode json $ toJsonError errorMessage - Right dbUser -> do - (DbUser.refresh_token dbUser) - <&> refreshTokenToAccessToken dbUser - & fromMaybe (status internalServerError500) - + Right dbUser -> + do + (DbUser.refresh_token dbUser) + <&> refreshTokenToAccessToken dbUser + & fromMaybe (status internalServerError500) -- User Logout delete "/access-tokens" $ do jwtBSMaybe <- Scotty.header "x-access-token" - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - - case claimsResult of - Left error -> badRequest $ show error - Right _ -> do - fullBody <- body - - case (eitherDecode fullBody & over _Left T.pack) of - Left errorMessage -> badRequest errorMessage - Right refreshToken -> do - userResult <- liftIO $ query database - $ GetUserByToken refreshToken - - case userResult of - Left errorMessage -> notFoundAction errorMessage - Right _ -> do - logoutResult <- liftIO $ update database - $ LogoutByEmailAndToken emailAddress refreshToken - - case logoutResult of - Left (statusCode, errorMessage) -> do - status statusCode - json $ toJsonError errorMessage - Right _ -> do - status noContent204 - json $ Object mempty + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + + case claimsResult of + Left error -> badRequest $ show error + Right _ -> do + fullBody <- body + + case (eitherDecode fullBody & over _Left T.pack) of + Left errorMessage -> badRequest errorMessage + Right refreshToken -> do + userResult <- + liftIO $ + query database $ + GetUserByToken refreshToken + + case userResult of + Left errorMessage -> notFoundAction errorMessage + Right _ -> do + logoutResult <- + liftIO $ + update database $ + LogoutByEmailAndToken emailAddress refreshToken + + case logoutResult of + Left (statusCode, errorMessage) -> do + status statusCode + json $ toJsonError errorMessage + Right _ -> do + status noContent204 + json $ Object mempty ) - -- User Signup post "/users" $ do fullBody <- body @@ -173,9 +185,10 @@ app database = do Right signupUser -> do let minPasswordLength = 6 - checkPassword pwd = if T.length pwd < minPasswordLength - then Left (badRequest400, "Password is too short") - else Right () + checkPassword pwd = + if T.length pwd < minPasswordLength + then Left (badRequest400, "Password is too short") + else Right () dbUser <- liftIO $ toDbUser signupUser additionResult <- liftIO $ update database $ AddUser dbUser @@ -183,16 +196,17 @@ app database = do let validationResult = (checkPassword $ SignupUser.password signupUser) - >>= (\_ -> additionResult) + >>= (\_ -> additionResult) case validationResult of - Left (statusCode, errorMesage) -> do + Left (statusCode, errorMessage) -> do status statusCode - json $ toJsonError errorMesage + json $ toJsonError errorMessage Right _ -> do let - refreshToken = fromMaybe (RefreshToken "Not possible") - $ DbUser.refresh_token dbUser + refreshToken = + fromMaybe (RefreshToken "Not possible") $ + DbUser.refresh_token dbUser jwkValue = refreshTokenToJwk refreshToken claims <- liftIO $ makeClaims dbUser @@ -202,145 +216,174 @@ app database = do Left error -> liftIO $ die $ show error Right jwt -> do status created201 - json $ AccessToken - { jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt - , refresh_token = refreshToken - } - + json $ + AccessToken + { jwt = TL.toStrict $ TL.decodeUtf8 $ encodeCompact jwt + , refresh_token = refreshToken + } -- Get All Registered Users -- get "/admin/users" $ do -- users <- liftIO $ query database GetUsers -- json users - -- Get Current User's Info get "/me" $ do jwtBSMaybe <- Scotty.header "x-access-token" - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - - case claimsResult of - Left error -> badRequest $ show error - Right _ -> do - userMaybe <- liftIO $ query database $ GetUserByEmail emailAddress - json $ userMaybe <&> (\user -> object - [ ("email", String $ DbUser.email user) - , ("name", String $ DbUser.name user) - , ("avatar_url", String $ T.pack $ - gravatar (def :: GravatarOptions) $ DbUser.email user) - ] - ) + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + + case claimsResult of + Left error -> badRequest $ show error + Right _ -> do + userMaybe <- liftIO $ query database $ GetUserByEmail emailAddress + json $ + userMaybe + <&> ( \user -> + object + [ ("email", String $ DbUser.email user) + , ("name", String $ DbUser.name user) + , + ( "avatar_url" + , String $ + T.pack $ + gravatar (def :: GravatarOptions) $ + DbUser.email user + ) + ] + ) ) - -- Add Idea post "/ideas" $ do jwtBSMaybe <- Scotty.header "x-access-token" fullBody <- body let postIdeaResult = eitherDecode fullBody & over _Left T.pack - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - let verifiedIdea = postIdeaResult >>= verifyIdea - validateAndAddIdea - database - emailAddress - claimsResult - verifiedIdea + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + let verifiedIdea = postIdeaResult >>= verifyIdea + validateAndAddIdea + database + emailAddress + claimsResult + verifiedIdea ) - -- Get all Ideas -- get "/admin/ideas" $ do -- ideas <- liftIO $ query database GetIdeas -- json ideas - -- Get all ideas of current user get "/ideas" $ do jwtBSMaybe <- Scotty.header "x-access-token" (page :: Int) <- (param "page" `rescue` (\_ -> pure 1)) - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - - case claimsResult of - Left error -> badRequest $ show error - Right _ -> do - ideas <- liftIO $ - query database $ GetIdeasByEmail emailAddress - let - ideasPerPage = 10 - ideasByScoreDesc = ideas & sortBy - (\a b -> compare - (DbIdea.average_score b) - (DbIdea.average_score a)) - - if page < 1 - then badRequest "Page number must be > 0" - else do - json $ fromMaybe [] $ - (List.chunksOf ideasPerPage ideasByScoreDesc) - ^? element (page - 1) - <&> (<&> DbIdea.toIdea) + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + + case claimsResult of + Left error -> badRequest $ show error + Right _ -> do + ideas <- + liftIO $ + query database $ + GetIdeasByEmail emailAddress + let + ideasPerPage = 10 + ideasByScoreDesc = + ideas + & sortBy + ( \a b -> + compare + (DbIdea.average_score b) + (DbIdea.average_score a) + ) + + if page < 1 + then badRequest "Page number must be > 0" + else do + json $ + fromMaybe [] $ + (List.chunksOf ideasPerPage ideasByScoreDesc) + ^? element (page - 1) + <&> (<&> DbIdea.toIdea) ) - -- Update Idea put "/ideas/:id" $ do jwtBSMaybe <- Scotty.header "x-access-token" id <- param "id" - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - fullBody <- body - - case (eitherDecode fullBody & over _Left T.pack) of - Left errorMessage -> badRequest errorMessage - Right postIdea -> do - let verifiedIdea = verifyIdea postIdea - validateAndReplaceIdea - database emailAddress id claimsResult verifiedIdea + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + fullBody <- body + + case (eitherDecode fullBody & over _Left T.pack) of + Left errorMessage -> badRequest errorMessage + Right postIdea -> do + let verifiedIdea = verifyIdea postIdea + validateAndReplaceIdea + database + emailAddress + id + claimsResult + verifiedIdea ) - -- Delete an Idea delete "/ideas/:id" $ do jwtBSMaybe <- Scotty.header "x-access-token" id <- param "id" - runIfRegisteredUser database jwtBSMaybe - (\emailAddress jwkValue jwtValue -> do - claimsResult <- liftIO $ - doJwtVerify emailAddress jwkValue jwtValue - case claimsResult of - Left error -> badRequest $ show error - Right _ -> do - deletionResult <- liftIO $ update database - $ DeleteIdeaIfBy emailAddress id - case deletionResult of - Left (statusCode, errorMesage) -> do - status statusCode - json $ toJsonError errorMesage - Right _ -> do - status noContent204 - json $ Object mempty + runIfRegisteredUser + database + jwtBSMaybe + ( \emailAddress jwkValue jwtValue -> do + claimsResult <- + liftIO $ + doJwtVerify emailAddress jwkValue jwtValue + case claimsResult of + Left error -> badRequest $ show error + Right _ -> do + deletionResult <- + liftIO $ + update database $ + DeleteIdeaIfBy emailAddress id + case deletionResult of + Left (statusCode, errorMessage) -> do + status statusCode + json $ toJsonError errorMessage + Right _ -> do + status noContent204 + json $ Object mempty ) - notFound $ - json $ toJsonError "This endpoint does not exist" - + json $ + toJsonError "This endpoint does not exist" main :: IO () diff --git a/docs-source/differences_taskwarrior.md b/docs-source/differences_taskwarrior.md index 4dd8190..778efe6 100644 --- a/docs-source/differences_taskwarrior.md +++ b/docs-source/differences_taskwarrior.md @@ -125,7 +125,7 @@ uuids | - | Filtered list of UUIDs \_aliases | - | List of active aliases \_columns | - | List of supported columns \_commands | - | List of supported commands -\_config | - | List of confguration setting names +\_config | - | List of configuration setting names \_context | - | List of defined context names [\_get] | - | DOM accessor \_ids | - | Filtered list of task IDs diff --git a/docs-source/usage/haskell_api.md b/docs-source/usage/haskell_api.md index f2ea5e2..3d96120 100644 --- a/docs-source/usage/haskell_api.md +++ b/docs-source/usage/haskell_api.md @@ -1,7 +1,7 @@ # Haskell API for Programmatic Usage While TaskLite is primarily a tool to manage your personal tasks, -it can also be used as a dependency of other programms. +it can also be used as a dependency of other programs. For example as a queue for processing tasks or a backend for a bookmarking service. diff --git a/tasklite-airsequel-app/src/Main.elm b/tasklite-airsequel-app/src/Main.elm index e5a1239..6934136 100644 --- a/tasklite-airsequel-app/src/Main.elm +++ b/tasklite-airsequel-app/src/Main.elm @@ -238,7 +238,7 @@ viewTodo now todo = ] , ifDisabledElse (title <| - "Currenly not supported.\n" + "Currently not supported.\n" ++ "Please use the CLI to complete this task." ) (\_ -> css []) @@ -627,7 +627,7 @@ setTodoCompleted closedUtc ulid = (\c -> { c | eq = Present ulid }) -- TODO: Add when Airsequel supports - -- several filters simulatenously + -- several filters simultaneously -- recurrence_duration = -- Present <| -- buildStringComparison diff --git a/tasklite-core/source/Migrations.hs b/tasklite-core/source/Migrations.hs index f6558c3..c015aa1 100644 --- a/tasklite-core/source/Migrations.hs +++ b/tasklite-core/source/Migrations.hs @@ -551,7 +551,7 @@ runMigrations _ connection = do migrationsUpLinted = do currentVersion <- maybeToEither - "`PRAGMA user_verison` does not return current version" + "`PRAGMA user_version` does not return current version" (P.head currentVersionList) -- Check if duplicate user versions are defined diff --git a/tasklite-core/source/Task.hs b/tasklite-core/source/Task.hs index ab24116..f0732c6 100644 --- a/tasklite-core/source/Task.hs +++ b/tasklite-core/source/Task.hs @@ -1,4 +1,7 @@ {-# LANGUAGE QuasiQuotes #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Use uncurry" #-} {-| Datatype to represent a task as stored in the `tasks` table @@ -169,10 +172,10 @@ instance Arbitrary DerivedState where | detailed explanation of the different states | and how they relate to each other -} -type StateHierachy = (DerivedState, DerivedState) +type StateHierarchy = (DerivedState, DerivedState) -instance {-# OVERLAPS #-} Pretty StateHierachy where +instance {-# OVERLAPS #-} Pretty StateHierarchy where pretty stateH = ( if fst stateH == snd stateH then show $ fst stateH @@ -231,36 +234,36 @@ derivedStateToQuery = \case IsBlocked -> "" -- TODO -getStateHierarchy :: DateTime -> Task -> StateHierachy -getStateHierarchy now task = +getStateHierarchy :: DateTime -> Task -> StateHierarchy +getStateHierarchy now task = do let nowTxt = pack $ timePrint (utcFormat defaultConfig) now - in - case Task.state task of - Just Done -> (IsClosed, IsDone) - Just Obsolete -> (IsClosed, IsObsolete) - Just Deletable -> (IsClosed, IsDeletable) - Nothing -> case closed_utc task of - Just _ -> (IsClosed, IsClosed) - Nothing -> case review_utc task of - Just val -> - if val > nowTxt - then (IsOpen, IsWaiting) - else (IsOpen, IsReview) - Nothing -> case waiting_utc task of - Just _ -> (IsOpen, IsWaiting) - Nothing -> case (ready_utc task, awake_utc task) of - (Just readyUtc, Just awakeUtc) -> - if readyUtc < nowTxt && awakeUtc < nowTxt - then (IsOpen, IsReady) - else - if readyUtc > nowTxt && awakeUtc < nowTxt - then (IsOpen, IsAwake) - else (IsOpen, IsAsleep) - (Just readyUtc, Nothing) | readyUtc < nowTxt -> (IsOpen, IsReady) - (Nothing, Just awakeUtc) | awakeUtc < nowTxt -> (IsOpen, IsAwake) - (Nothing, Just awakeUtc) | awakeUtc > nowTxt -> (IsOpen, IsAsleep) - _ -> (IsOpen, IsOpen) + + case Task.state task of + Just Done -> (IsClosed, IsDone) + Just Obsolete -> (IsClosed, IsObsolete) + Just Deletable -> (IsClosed, IsDeletable) + Nothing -> case closed_utc task of + Just _ -> (IsClosed, IsClosed) + Nothing -> case review_utc task of + Just val -> + if val > nowTxt + then (IsOpen, IsWaiting) + else (IsOpen, IsReview) + Nothing -> case waiting_utc task of + Just _ -> (IsOpen, IsWaiting) + Nothing -> case (ready_utc task, awake_utc task) of + (Just readyUtc, Just awakeUtc) -> + if readyUtc < nowTxt && awakeUtc < nowTxt + then (IsOpen, IsReady) + else + if readyUtc > nowTxt && awakeUtc < nowTxt + then (IsOpen, IsAwake) + else (IsOpen, IsAsleep) + (Just readyUtc, Nothing) | readyUtc < nowTxt -> (IsOpen, IsReady) + (Nothing, Just awakeUtc) | awakeUtc < nowTxt -> (IsOpen, IsAwake) + (Nothing, Just awakeUtc) | awakeUtc > nowTxt -> (IsOpen, IsAsleep) + _ -> (IsOpen, IsOpen) newtype Ulid = Ulid Text diff --git a/tasklite-core/source/Utils.hs b/tasklite-core/source/Utils.hs index f4c9692..f69c66b 100644 --- a/tasklite-core/source/Utils.hs +++ b/tasklite-core/source/Utils.hs @@ -157,7 +157,7 @@ parseUtc utcText = let utcString = unpack $ T.toLower utcText - -- TOOD: Remove after https://github.com/vincenthz/hs-hourglass/issues/50 + -- TODO: Remove after https://github.com/vincenthz/hs-hourglass/issues/50 addSpaceAfter10 = T.intercalate " " . T.chunksOf 10 addSpaceAfter13 = T.intercalate " " . T.chunksOf 13 unixMicro = "EPOCH ms us" :: [Char]