diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-02-18 15:04:19 +0100 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-02-18 15:04:19 +0100 |
commit | a805783f4bb2868e63ba49a911775fff30df5a07 (patch) | |
tree | 130c8ef970f9489876d0667eff25444a0816c41a | |
parent | c88197535f7a4c13b7464a785881a91a67ebd15b (diff) | |
download | thermoprint-a805783f4bb2868e63ba49a911775fff30df5a07.tar thermoprint-a805783f4bb2868e63ba49a911775fff30df5a07.tar.gz thermoprint-a805783f4bb2868e63ba49a911775fff30df5a07.tar.bz2 thermoprint-a805783f4bb2868e63ba49a911775fff30df5a07.tar.xz thermoprint-a805783f4bb2868e63ba49a911775fff30df5a07.zip |
Introduced Range
-rw-r--r-- | client/src/Thermoprint/Client.hs | 7 | ||||
-rw-r--r-- | server/src/Thermoprint/Server/API.hs | 15 | ||||
-rw-r--r-- | spec/src/Thermoprint/API.hs | 34 |
3 files changed, 37 insertions, 19 deletions
diff --git a/client/src/Thermoprint/Client.hs b/client/src/Thermoprint/Client.hs index 80045dd..2b99e7e 100644 --- a/client/src/Thermoprint/Client.hs +++ b/client/src/Thermoprint/Client.hs | |||
@@ -45,10 +45,8 @@ data Client m = Client | |||
45 | { printers :: EitherT ServantError m (Map PrinterId PrinterStatus) | 45 | { printers :: EitherT ServantError m (Map PrinterId PrinterStatus) |
46 | -- ^ List all printers | 46 | -- ^ List all printers |
47 | , jobs :: Maybe PrinterId | 47 | , jobs :: Maybe PrinterId |
48 | -> Maybe JobId | 48 | -> Maybe (Range (JobId)) |
49 | -> Maybe JobId | 49 | -> Maybe (Range (UTCTime)) |
50 | -> Maybe UTCTime | ||
51 | -> Maybe UTCTime | ||
52 | -> EitherT ServantError m (Seq (JobId, UTCTime, JobStatus)) | 50 | -> EitherT ServantError m (Seq (JobId, UTCTime, JobStatus)) |
53 | -- ^ @jobs p minId maxId minTime maxTime@ lists a selection of jobs | 51 | -- ^ @jobs p minId maxId minTime maxTime@ lists a selection of jobs |
54 | , jobCreate :: Maybe PrinterId -> Printout -> EitherT ServantError m JobId | 52 | , jobCreate :: Maybe PrinterId -> Printout -> EitherT ServantError m JobId |
@@ -79,6 +77,7 @@ data Client m = Client | |||
79 | } | 77 | } |
80 | 78 | ||
81 | withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b)) | 79 | withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b)) |
80 | -- ^ Undo factoring of APIs | ||
82 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI | 81 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI |
83 | 82 | ||
84 | mkClient :: (IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can be constructed from 'IO' | 83 | mkClient :: (IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can be constructed from 'IO' |
diff --git a/server/src/Thermoprint/Server/API.hs b/server/src/Thermoprint/Server/API.hs index cd4326e..3f3ab46 100644 --- a/server/src/Thermoprint/Server/API.hs +++ b/server/src/Thermoprint/Server/API.hs | |||
@@ -141,16 +141,13 @@ printerStatus = fmap queueToStatus . queue' . snd <=< lookupPrinter . Just | |||
141 | queueToStatus (Queue _ (Just c) _) = Busy . castId $ jobId c | 141 | queueToStatus (Queue _ (Just c) _) = Busy . castId $ jobId c |
142 | 142 | ||
143 | listJobs :: Maybe PrinterId | 143 | listJobs :: Maybe PrinterId |
144 | -> Maybe API.JobId -> Maybe API.JobId | 144 | -> Maybe (Range API.JobId) -> Maybe (Range UTCTime) |
145 | -> Maybe UTCTime -> Maybe UTCTime | ||
146 | -> Handler (Seq (API.JobId, UTCTime, JobStatus)) | 145 | -> Handler (Seq (API.JobId, UTCTime, JobStatus)) |
147 | listJobs Nothing minId maxId minTime maxTime = fmap mconcat . mapM (\pId -> listJobs (Just pId) minId maxId minTime maxTime) =<< asks (Map.keys . printers) | 146 | listJobs Nothing idR timeR = fmap mconcat . mapM (\pId -> listJobs (Just pId) idR timeR) =<< asks (Map.keys . printers) |
148 | listJobs pId minId maxId minTime maxTime = fmap (filterJobs . extractJobs) . (\(a, b) -> (,) a <$> queue' b) =<< lookupPrinter pId | 147 | listJobs pId idR timeR = fmap (filterJobs . extractJobs) . (\(a, b) -> (,) a <$> queue' b) =<< lookupPrinter pId |
149 | where | 148 | where |
150 | filterJobs = Seq.filter (\(id, time, _) -> and ([ maybe True (<= id ) minId | 149 | filterJobs = Seq.filter (\(id, time, _) -> and ([ maybe True (`contains` id) idR |
151 | , maybe True (>= id ) maxId | 150 | , maybe True (`contains` time) timeR |
152 | , maybe True (<= time) minTime | ||
153 | , maybe True (>= time) maxTime | ||
154 | ] :: [Bool]) | 151 | ] :: [Bool]) |
155 | ) | 152 | ) |
156 | 153 | ||
@@ -158,7 +155,7 @@ getJob :: API.JobId -> Handler Printout | |||
158 | getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool | 155 | getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool |
159 | 156 | ||
160 | jobStatus :: API.JobId -> Handler JobStatus | 157 | jobStatus :: API.JobId -> Handler JobStatus |
161 | jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing Nothing Nothing | 158 | jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing |
162 | 159 | ||
163 | abortJob :: API.JobId -> Handler () | 160 | abortJob :: API.JobId -> Handler () |
164 | abortJob needle = do | 161 | abortJob needle = do |
diff --git a/spec/src/Thermoprint/API.hs b/spec/src/Thermoprint/API.hs index d854e73..5bfe431 100644 --- a/spec/src/Thermoprint/API.hs +++ b/spec/src/Thermoprint/API.hs | |||
@@ -2,6 +2,7 @@ | |||
2 | {-# LANGUAGE TypeOperators, DataKinds #-} | 2 | {-# LANGUAGE TypeOperators, DataKinds #-} |
3 | {-# LANGUAGE StandaloneDeriving #-} | 3 | {-# LANGUAGE StandaloneDeriving #-} |
4 | {-# LANGUAGE OverloadedStrings #-} | 4 | {-# LANGUAGE OverloadedStrings #-} |
5 | {-# LANGUAGE ViewPatterns #-} | ||
5 | 6 | ||
6 | -- | A specification of an API for interacting with a set of printers | 7 | -- | A specification of an API for interacting with a set of printers |
7 | module Thermoprint.API | 8 | module Thermoprint.API |
@@ -9,6 +10,7 @@ module Thermoprint.API | |||
9 | , JobStatus(..) | 10 | , JobStatus(..) |
10 | , PrintingError(..) | 11 | , PrintingError(..) |
11 | , DraftTitle | 12 | , DraftTitle |
13 | , Range(..), contains | ||
12 | , ThermoprintAPI | 14 | , ThermoprintAPI |
13 | , thermoprintAPI | 15 | , thermoprintAPI |
14 | , module Thermoprint.Identifiers | 16 | , module Thermoprint.Identifiers |
@@ -21,6 +23,9 @@ import Thermoprint.Identifiers | |||
21 | import Servant.API | 23 | import Servant.API |
22 | import Data.Aeson | 24 | import Data.Aeson |
23 | 25 | ||
26 | import Data.Monoid | ||
27 | import Data.Maybe | ||
28 | |||
24 | import Data.Set (Set) | 29 | import Data.Set (Set) |
25 | import Data.Map (Map) | 30 | import Data.Map (Map) |
26 | import qualified Data.Map as Map (foldMapWithKey, singleton) | 31 | import qualified Data.Map as Map (foldMapWithKey, singleton) |
@@ -51,7 +56,6 @@ instance (Integral k, Ord k, ToJSON v) => ToJSON (Map k v) where | |||
51 | instance (Enum k, Ord k, FromJSON v) => FromJSON (Map k v) where | 56 | instance (Enum k, Ord k, FromJSON v) => FromJSON (Map k v) where |
52 | parseJSON = fmap (IntMap.foldMapWithKey $ Map.singleton . castId) . parseJSON | 57 | parseJSON = fmap (IntMap.foldMapWithKey $ Map.singleton . castId) . parseJSON |
53 | 58 | ||
54 | |||
55 | data PrinterStatus = Busy JobId | 59 | data PrinterStatus = Busy JobId |
56 | | Available | 60 | | Available |
57 | deriving (Generic, Show, FromJSON, ToJSON) | 61 | deriving (Generic, Show, FromJSON, ToJSON) |
@@ -81,13 +85,31 @@ instance FromText UTCTime where | |||
81 | instance ToText UTCTime where | 85 | instance ToText UTCTime where |
82 | toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q" | 86 | toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q" |
83 | 87 | ||
88 | data Range a = Min a | Max a | Through a a | ||
89 | |||
90 | contains :: Ord a => Range a -> a -> Bool | ||
91 | -- ^ Check if a 'Range' contains a point | ||
92 | contains (Min min) x = min <= x | ||
93 | contains (Max max) x = max >= x | ||
94 | contains (Through min max) x = min <= x && x <= max | ||
95 | |||
96 | instance ToText a => ToText (Range a) where | ||
97 | toText (Min min) = toText min <> "-" | ||
98 | toText (Max max) = "-" <> toText max | ||
99 | toText (Through min max) = toText min <> "-" <> toText max | ||
100 | |||
101 | instance FromText a => FromText (Range a) where | ||
102 | fromText t = listToMaybe $ through <> max <> min | ||
103 | where | ||
104 | through = [ Through min max | ((fromText -> Just min), (T.uncons -> Just ('-', (fromText -> Just max)))) <- zip (T.inits t) (T.tails t) ] | ||
105 | min = [ Min min | (fromText -> Just min) <- T.inits t ] | ||
106 | max = [ Max max | (fromText -> Just max) <- T.tails t ] | ||
107 | |||
84 | type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) | 108 | type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) |
85 | :<|> "jobs" :> ( | 109 | :<|> "jobs" :> ( |
86 | QueryParam "printer" PrinterId -- TODO: this is silly, introduce data Range a = Range { rMin :: a, rMax :: a } | 110 | QueryParam "printer" PrinterId |
87 | :> QueryParam "min" JobId | 111 | :> QueryParam "jobId" (Range JobId) |
88 | :> QueryParam "max" JobId | 112 | :> QueryParam "time" (Range UTCTime) |
89 | :> QueryParam "minTime" UTCTime | ||
90 | :> QueryParam "maxTime" UTCTime | ||
91 | :> Get '[JSON] (Seq (JobId, UTCTime, JobStatus)) | 113 | :> Get '[JSON] (Seq (JobId, UTCTime, JobStatus)) |
92 | :<|> QueryParam "printer" PrinterId :> ReqBody '[JSON] Printout :> Post '[JSON] JobId | 114 | :<|> QueryParam "printer" PrinterId :> ReqBody '[JSON] Printout :> Post '[JSON] JobId |
93 | ) | 115 | ) |