aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Main.hs
blob: 21388f6979a4baf1ba1876b194783eea671a39b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{-

    srem --- Timed reminders as notifications

    Copyright (C) 2015  Sean Whitton

    This file is part of srem.

    srem is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    srem is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with srem.  If not, see <http://www.gnu.org/licenses/>.

-}

import           Control.Applicative    ((<$>), (<*>))
import           Control.Monad          (mapM_)
import           System.Environment     (getArgs)

import           Data.Time.Calendar
import           Data.Time.LocalTime

import           Types.Reminder
import           Types.Reminder.CmdLine
import           Utility.CmdLineRem     (cmdLineReminder)
import           Utility.EventCache
import           Utility.Notify

doCron                  :: IO ()
doCron                  = do
    purgeOldEventCaches
    rems      <- (++) <$> readEmacsEventCache <*> readManualEventCache
    (h, m, _) <- localHMD
    let nowRemsFilter r = getReminderHour r == h
                          && getReminderMinute r == m
        nowRems         = filter nowRemsFilter rems
    sendNotifications nowRems

appendUserReminder   :: Reminder -> IO ()
appendUserReminder r = do
    (h, m, d) <- localHMD
    -- A reminder doesn't know which day the event is on.  So we make
    -- a dummy reminder for right now, and compare to the user's
    -- input.  If their reminder is for a time that's already passed
    -- today, we save the reminder into tomorrow's cache.

    -- This makes it impossible to set a reminder for more than one
    -- day into the future ('cmdLineReminder' is a pure function and
    -- doesn't know what day it is now).  But the only way to express
    -- a reminder for the day after tomorrow in srem's deliberately
    -- simple command line input would be to write something like
    -- @srem 1500m Go out to meet Tina@ which no user would want to
    -- do.

    -- The day after tomorrow is far enough in the future that an
    -- appointment in Emacs Org-mode should be used instead of srem's
    -- manual reminder input.
    let dummyRem = makeReminder' h m (getReminderText r)
    if maybe False (r <=) dummyRem
        then appendManualEventCache r (addDays 1 d)
        else appendManualEventCache r d

main = do
    args <- getArgs
    if length args == 1 && head args == "--cron"
        then doCron
        else if length args == 1 && head args == "--refresh-emacs"
                then refreshEmacsEventCache
             else cmdLineReminder args
                  >>= maybe (error "invalid input") appendUserReminder

localHMD :: IO (Hour, Minute, Day)
localHMD = do
    localTime <- zonedTimeToLocalTime <$> getZonedTime
    let time = localTimeOfDay localTime
        d    = localDay localTime
        h    = todHour time
        m    = todMin  time
    return (h, m, d)