module Villefort.Todo where import Villefort.Database import Villefort.Time import Control.Monad.IO.Class import Data.List.Split import Paths_Villefort import Database.HDBC data Row = Row { rid :: Int, title :: String, description :: String, due :: String, subject :: String, time :: Int, pred :: Double } deriving (Show) toRow :: [String] -> Row toRow x = Row (read (x !! 0) :: Int) (x !! 1) (x !! 2) (x !! 3)( x !! 4) (read ( x !! 5) :: Int) (read (x !! 6) :: Double) qetTasks' :: IO [Row] qetTasks' = do x <- makeQuery' "select id, Title, Description, Due, Subject, sum(time),pred from todo where state=1 group by id order by id" return (map toRow x) convRow' :: [[SqlValue]] -> [[String]] convRow' dat = Prelude.map (\x -> Prelude.map (\y -> conv' y ) x) dat --conv h:: SqlValue -> String conv' :: SqlValue -> String conv' x = case fromSql x of Just y -> fromSql y :: String Nothing -> "0" --makeQuery :: Query -> IO [[String]] makeQuery' :: String -> IO [[String]] makeQuery' query = do conn <- getDb taskRaw <- quickQuery' conn query [] disconnect conn return (convRow' taskRaw) merge :: [a] -> [a] -> [a] merge [] ys = ys merge (x:xs) ys = x:merge ys xs genModal' :: Row -> IO String genModal' row = if rid row == 1 then return (" ") else do let f = due row modal <- getModal days <- daysUntil f let da = [daysToColor' days , show $ rid row, (convTitle $ title row) ++ "Due in " ++ show days, show $ rid row, title row, description row, show $ time row, show $ Villefort.Todo.pred row, "/delete", show $ rid row ] return $ mconcat $ merge modal da --genModal row = daysToColor' :: (Num a, Ord a) => a -> String daysToColor' x = if x < 1 then "btn-due0" else if x == 1 then "btn-due1" else if x == 2 then "btn-due2" else if x == 3 then "btn-due3" else if x == 4 then "btn-due4" else if x == 5 then "btn-due5" else if x == 6 then "btn-due6" else "btn-due7" convTitle :: String -> String convTitle longTitle | length s1 > 30 = s1 | length s2 > 30 = s2 | length s3 > 30 = s3 | length s4 > 30 = s4 | otherwise = longTitle where splits = (Data.List.Split.splitOn "." longTitle) s1 = (splits !! 0) s2 = mconcat (take 2 splits) s3 = mconcat (take 3 splits) s4 = mconcat (take 4 splits) getModal :: IO [[Char]] --getModal = path >>= \path -> readFile (path ++ "templates/modal.ts") >>= \rawModal -> return (Data.List.Split.splitOn "}" rawModal) getModal = getDataFileName "templates/modal.ts" >>= \path -> readFile path>>= \rawModal -> return (Data.List.Split.splitOn "}" rawModal) -- | Returns html from todos getTodos :: IO String getTodos = do tasks <- qetTasks' --do liftIO $ putStrLn $ show tasks modals <- sequence $ genModal' <$> tasks header <- getHeader let body = Prelude.concat modals return (header ++ body) getHeader :: IO String getHeader = do headerPath <-getDataFileName "templates/header" header <- liftIO $ readFile headerPath return header -- | Delete a done task from database sets state = 0 but it's record is still maintained in the database for the stats page. deleteTodo :: (Show t, MonadIO m) => t -> m () deleteTodo raw = do let da = Data.List.Split.splitOn "&" (show raw) let rawid = Data.List.Split.splitOn "=" $ (Prelude.init (da !! 1)) let sqlId = read (rawid!! 1) :: Int let rawtime = Data.List.Split.splitOn "=" $ (da !! 0) let integerTime = read (rawtime !! 1) :: Int if integerTime /= 0 then do liftIO $ updateTask sqlId integerTime -- update task time liftIO $ delTask sqlId -- then remove from database else do liftIO $ delTask sqlId -- otherwise just remove from database return () delTask :: Int -> IO () delTask sqlId = execQuery "update todo set state = 0 where id = ?" [sqlId] updateTask :: Int -> Int -> IO () updateTask sqlId timeTaken = execQuery "insert into todo (id,Description,Title,Entered,Due,state,time,Subject) select id,Description,Title,Entered,datetime('now', 'localtime'),0,?,Subject from todo where id = ? limit 1" [ timeTaken, sqlId] addTask :: String -> String -> String -> String -> IO () addTask todoTitle todoSummary date todoSubject = do nextSqlId <- getNextId execQuery "insert into todo (id,Description,Title,Entered,Due,State,time,Subject) Values (?,?,?,datetime('now', 'localtime'),?,1,0,?)" [show nextSqlId, todoTitle, todoSummary, date, todoSubject] return ()