aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-02-18 15:04:19 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2016-02-18 15:04:19 +0100
commita805783f4bb2868e63ba49a911775fff30df5a07 (patch)
tree130c8ef970f9489876d0667eff25444a0816c41a
parentc88197535f7a4c13b7464a785881a91a67ebd15b (diff)
downloadthermoprint-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.hs7
-rw-r--r--server/src/Thermoprint/Server/API.hs15
-rw-r--r--spec/src/Thermoprint/API.hs34
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
81withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b)) 79withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b))
80-- ^ Undo factoring of APIs
82withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI 81withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI
83 82
84mkClient :: (IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can be constructed from 'IO' 83mkClient :: (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
143listJobs :: Maybe PrinterId 143listJobs :: 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))
147listJobs Nothing minId maxId minTime maxTime = fmap mconcat . mapM (\pId -> listJobs (Just pId) minId maxId minTime maxTime) =<< asks (Map.keys . printers) 146listJobs Nothing idR timeR = fmap mconcat . mapM (\pId -> listJobs (Just pId) idR timeR) =<< asks (Map.keys . printers)
148listJobs pId minId maxId minTime maxTime = fmap (filterJobs . extractJobs) . (\(a, b) -> (,) a <$> queue' b) =<< lookupPrinter pId 147listJobs 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
158getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool 155getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool
159 156
160jobStatus :: API.JobId -> Handler JobStatus 157jobStatus :: API.JobId -> Handler JobStatus
161jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing Nothing Nothing 158jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing
162 159
163abortJob :: API.JobId -> Handler () 160abortJob :: API.JobId -> Handler ()
164abortJob needle = do 161abortJob 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
7module Thermoprint.API 8module 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
21import Servant.API 23import Servant.API
22import Data.Aeson 24import Data.Aeson
23 25
26import Data.Monoid
27import Data.Maybe
28
24import Data.Set (Set) 29import Data.Set (Set)
25import Data.Map (Map) 30import Data.Map (Map)
26import qualified Data.Map as Map (foldMapWithKey, singleton) 31import qualified Data.Map as Map (foldMapWithKey, singleton)
@@ -51,7 +56,6 @@ instance (Integral k, Ord k, ToJSON v) => ToJSON (Map k v) where
51instance (Enum k, Ord k, FromJSON v) => FromJSON (Map k v) where 56instance (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
55data PrinterStatus = Busy JobId 59data 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
81instance ToText UTCTime where 85instance ToText UTCTime where
82 toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q" 86 toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q"
83 87
88data Range a = Min a | Max a | Through a a
89
90contains :: Ord a => Range a -> a -> Bool
91-- ^ Check if a 'Range' contains a point
92contains (Min min) x = min <= x
93contains (Max max) x = max >= x
94contains (Through min max) x = min <= x && x <= max
95
96instance 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
101instance 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
84type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) 108type 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 )