summaryrefslogtreecommitdiff
path: root/Utility/Scheduled.hs
blob: 90d3462800133134e8900aa36018c1b332da0a23 (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
{- scheduled activities
 - 
 - Copyright 2013 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Utility.Scheduled (
	Schedule(..),
	Recurrance(..),
	TimeOfDay(..),
	fromSchedule,
	toSchedule
) where

import Common

{- Some sort of scheduled event. -}
data Schedule = Schedule Recurrance TimeOfDay Duration
  deriving (Show)

data Recurrance
	= Daily
	| Weekly WeekDay
	| Monthly MonthDay
	| Yearly YearDay
	-- Divisible 3 Daily is every day of the year evenly divisible by 3
	| Divisable Int Recurrance
  deriving (Show)

type WeekDay = Int
type MonthDay = Int
type YearDay = Int

data TimeOfDay
	= AnyTime
	| Hour Int
  deriving (Show)

data Duration = MinutesDuration Int
  deriving (Show)

fromRecurrance :: Recurrance -> String
fromRecurrance (Divisable n r) =
	fromRecurrance' (++ "s divisible by " ++ show n) r
fromRecurrance r = fromRecurrance' ("every " ++) r

fromRecurrance' :: (String -> String) -> Recurrance -> String
fromRecurrance' a Daily = a "day"
fromRecurrance' a (Weekly n) = onday n (a "week")
fromRecurrance' a (Monthly n) = onday n (a "month")
fromRecurrance' a (Yearly n) = onday n (a "year")
fromRecurrance' a (Divisable _n r) = fromRecurrance' a r -- not used

onday :: Int -> String -> String
onday n s = s ++ " on day " ++ show n

toRecurrance :: String -> Maybe Recurrance
toRecurrance s = case words s of
	("every":something:l) -> parse something l
	(something:"divisible":"by":sn:l) -> do
		r <- parse something l
		n <- readish sn
		if n > 0
			then Just $ Divisable n r
			else Nothing
	_ -> Nothing
  where
	parse "day" [] = Just Daily
	parse "week" l = withday Weekly l
	parse "month" l = withday Monthly l
	parse "year" l = withday Yearly l
	parse v l
		| "s" `isSuffixOf` v = parse (reverse $ drop 1 $ reverse v) l
		| otherwise = Nothing
	withday a ("on":"day":n:[]) = a <$> readish n
	withday _ _ = Nothing

fromTimeOfDay :: TimeOfDay -> String
fromTimeOfDay AnyTime = "any time"
fromTimeOfDay (Hour n) = "hour " ++ show n

toTimeOfDay :: String -> Maybe TimeOfDay
toTimeOfDay s = case words s of
	("any":"time":[]) -> Just AnyTime
	("hour":n:[]) -> Hour <$> readish n
	_ -> Nothing

fromDuration :: Duration -> String
fromDuration (MinutesDuration n) = show n ++ " minutes"

toDuration :: String -> Maybe Duration
toDuration s = case words s of
	(n:"minutes":[]) -> MinutesDuration <$> readish n
	(n:"minute":[]) -> MinutesDuration <$> readish n
	_ -> Nothing

fromSchedule :: Schedule -> String
fromSchedule (Schedule recurrance timeofday duration) = unwords
	[ fromRecurrance recurrance
	, "at"
	, fromTimeOfDay timeofday
	, "for"
	, fromDuration duration
	]

toSchedule :: String -> Maybe Schedule
toSchedule s = Schedule
	<$> toRecurrance (unwords recurrance)
	<*> toTimeOfDay (unwords timeofday)
	<*> toDuration (unwords duration)
  where
  	ws = words s
	(recurrance, ws') = separate (== "at") ws
	(timeofday, duration) = separate (== "for") ws'