diff options
author | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-07-17 19:21:56 +0200 |
---|---|---|
committer | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-07-17 19:21:56 +0200 |
commit | 2b9ceaead3f3cd80e973cccecb9a3eebc51154f7 (patch) | |
tree | df2378943480647606b6a06f62c0f4b8b2ab406d | |
parent | ac4cf4a0a494eafe55364f816569c517684fdf32 (diff) | |
download | thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.gz thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.bz2 thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.xz thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.zip |
Fixes for GHC 8.0.1
26 files changed, 214 insertions, 113 deletions
diff --git a/bbcode/bbcode.cabal b/bbcode/bbcode.cabal index 6309fc0..e26dfb7 100644 --- a/bbcode/bbcode.cabal +++ b/bbcode/bbcode.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: bbcode | 4 | name: bbcode |
5 | version: 3.1.0 | 5 | version: 3.1.1 |
6 | synopsis: A parser for bbcode | 6 | synopsis: A parser for bbcode |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -25,7 +25,7 @@ library | |||
25 | , DeriveGeneric | 25 | , DeriveGeneric |
26 | , DeriveAnyClass | 26 | , DeriveAnyClass |
27 | , OverloadedLists | 27 | , OverloadedLists |
28 | build-depends: base >=4.8 && <4.9 | 28 | build-depends: base >=4.8 && <5 |
29 | , attoparsec >=0.13.0 && <1 | 29 | , attoparsec >=0.13.0 && <1 |
30 | , text >=1.2.1 && <2 | 30 | , text >=1.2.1 && <2 |
31 | , containers >=0.4.0 && <1 | 31 | , containers >=0.4.0 && <1 |
diff --git a/client/src/Thermoprint/Client.hs b/client/src/Thermoprint/Client.hs index 7072ad0..448a912 100644 --- a/client/src/Thermoprint/Client.hs +++ b/client/src/Thermoprint/Client.hs | |||
@@ -1,7 +1,10 @@ | |||
1 | {-# LANGUAGE DataKinds #-} | 1 | {-# LANGUAGE DataKinds #-} |
2 | {-# LANGUAGE TypeOperators #-} | 2 | {-# LANGUAGE TypeOperators #-} |
3 | {-# LANGUAGE TypeFamilies #-} | ||
3 | {-# LANGUAGE ViewPatterns #-} | 4 | {-# LANGUAGE ViewPatterns #-} |
4 | {-# LANGUAGE RecordWildCards #-} | 5 | {-# LANGUAGE RecordWildCards #-} |
6 | {-# LANGUAGE FlexibleContexts #-} | ||
7 | {-# LANGUAGE FlexibleInstances #-} | ||
5 | 8 | ||
6 | -- | A client library for 'Thermoprint.API' | 9 | -- | A client library for 'Thermoprint.API' |
7 | module Thermoprint.Client | 10 | module Thermoprint.Client |
@@ -12,8 +15,8 @@ module Thermoprint.Client | |||
12 | , ServantError(..) | 15 | , ServantError(..) |
13 | , module Thermoprint.API | 16 | , module Thermoprint.API |
14 | , module Servant.Common.BaseUrl | 17 | , module Servant.Common.BaseUrl |
15 | , module Control.Monad.Trans.Either | 18 | , module Control.Monad.Except |
16 | , module Servant.Server.Internal.Enter | 19 | , module Servant.Utils.Enter |
17 | ) where | 20 | ) where |
18 | 21 | ||
19 | import Thermoprint.API | 22 | import Thermoprint.API |
@@ -24,19 +27,20 @@ import Data.Time (UTCTime) | |||
24 | import Servant.Client hiding (HasClient(..)) | 27 | import Servant.Client hiding (HasClient(..)) |
25 | import qualified Servant.Client as S | 28 | import qualified Servant.Client as S |
26 | import Servant.Common.BaseUrl | 29 | import Servant.Common.BaseUrl |
30 | import Network.HTTP.Client (Manager, ManagerSettings, newManager, defaultManagerSettings) | ||
27 | import Servant.API | 31 | import Servant.API |
28 | import Servant.Server.Internal.Enter | 32 | import Servant.Utils.Enter |
29 | import Control.Monad.Trans.Either | 33 | import Control.Monad.Except (ExceptT, runExceptT) |
30 | 34 | ||
35 | import Control.Monad.Reader (ReaderT, runReaderT, ask) | ||
31 | import Control.Monad.Catch (Exception, MonadThrow(..)) | 36 | import Control.Monad.Catch (Exception, MonadThrow(..)) |
32 | import Control.Monad.IO.Class (MonadIO(..)) | 37 | import Control.Monad.IO.Class (MonadIO(..)) |
38 | import Control.Monad.Trans (lift) | ||
33 | 39 | ||
34 | import Control.Monad | 40 | import Control.Monad |
35 | import Control.Category | 41 | import Control.Category |
36 | import Prelude hiding (id, (.)) | 42 | import Prelude hiding (id, (.)) |
37 | 43 | ||
38 | instance Exception ServantError | ||
39 | |||
40 | -- | All 'ThermoprintAPI'-functions as a record | 44 | -- | All 'ThermoprintAPI'-functions as a record |
41 | -- | 45 | -- |
42 | -- Use like this: | 46 | -- Use like this: |
@@ -46,7 +50,7 @@ instance Exception ServantError | |||
46 | -- > main :: IO () | 50 | -- > main :: IO () |
47 | -- > -- ^ Display a list of printers with their status | 51 | -- > -- ^ Display a list of printers with their status |
48 | -- > main = print =<< printers | 52 | -- > main = print =<< printers |
49 | -- > where Client{..} = mkClient' $ Http "localhost" 3000 | 53 | -- > where Client{..} = mkClient' defaultManagerSettings $ Http "localhost" 3000 |
50 | data Client m = Client | 54 | data Client m = Client |
51 | { printers :: m (Map PrinterId PrinterStatus) | 55 | { printers :: m (Map PrinterId PrinterStatus) |
52 | -- ^ List all printers | 56 | -- ^ List all printers |
@@ -86,27 +90,55 @@ withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b)) | |||
86 | -- ^ Undo factoring of APIs | 90 | -- ^ Undo factoring of APIs |
87 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI | 91 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI |
88 | 92 | ||
89 | mkClient :: (EitherT ServantError IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can do 'IO' and handle errors | 93 | mkClientS :: Monad m |
90 | -> BaseUrl | 94 | => (ClientM :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can do 'IO' and handle errors |
91 | -> Client m | 95 | -> ManagerSettings |
96 | -> BaseUrl | ||
97 | -> Client m | ||
92 | -- ^ Generate a 'Client' | 98 | -- ^ Generate a 'Client' |
93 | mkClient n url = Client{..} | 99 | mkClientS n mgrS url = Client |
100 | { printers = clientF n printers | ||
101 | , jobs = \a b c -> clientF n $ jobs a b c | ||
102 | , jobCreate = \a b -> clientF n $ jobCreate a b | ||
103 | , job = \a -> clientF n $ job a | ||
104 | , jobStatus = \a -> clientF n $ jobStatus a | ||
105 | , jobDelete = \a -> clientF n $ jobDelete a | ||
106 | , drafts = clientF n drafts | ||
107 | , draftCreate = \a b -> clientF n $ draftCreate a b | ||
108 | , draftReplace = \a b c -> clientF n $ draftReplace a b c | ||
109 | , draft = \a -> clientF n $ draft a | ||
110 | , draftDelete = \a -> clientF n $ draftDelete a | ||
111 | , draftPrint = \a b -> clientF n $ draftPrint a b | ||
112 | } | ||
94 | where | 113 | where |
114 | clientF :: Monad m => (ClientM :~> m) -> (Manager -> BaseUrl -> m a) -> m a | ||
115 | clientF n f = do | ||
116 | mgr <- unNat n $ (liftIO $ newManager mgrS :: ClientM Manager) | ||
117 | f mgr url | ||
95 | printers | 118 | printers |
96 | :<|> (jobs :<|> jobCreate) | 119 | :<|> (jobs :<|> jobCreate) |
97 | :<|> (withArgs -> job :<|> (withArgs -> jobStatus :<|> jobDelete)) | 120 | :<|> (withArgs -> job :<|> (withArgs -> jobStatus :<|> jobDelete)) |
98 | :<|> (drafts :<|> draftCreate) | 121 | :<|> (drafts :<|> draftCreate) |
99 | :<|> (withArgs -> draftReplace :<|> (withArgs -> draft :<|> (withArgs -> draftDelete :<|> draftPrint))) | 122 | :<|> (withArgs -> draftReplace :<|> (withArgs -> draft :<|> (withArgs -> draftDelete :<|> draftPrint))) |
100 | = enter n $ client thermoprintAPI url | 123 | = enter n $ client thermoprintAPI |
101 | 124 | ||
125 | mkClient :: Monad m | ||
126 | => (ClientM :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can do 'IO' and handle errors | ||
127 | -> BaseUrl | ||
128 | -> Client m | ||
129 | mkClient n url = mkClientS n defaultManagerSettings url | ||
130 | |||
102 | mkClient' :: (MonadThrow m, MonadIO m) => BaseUrl -> Client m | 131 | mkClient' :: (MonadThrow m, MonadIO m) => BaseUrl -> Client m |
103 | -- ^ @mkClient' = mkClient $ ioNat . throwNat@ | 132 | -- ^ @mkClient' = mkClient $ ioNat . throwNat@ |
104 | mkClient' = mkClient $ ioNat . throwNat | 133 | mkClient' = mkClient $ ioNat . throwNat |
105 | 134 | ||
106 | throwNat :: (Exception e, MonadThrow m) => EitherT e m :~> m | 135 | throwNat :: (Exception e, MonadThrow m) => ExceptT e m :~> m |
107 | -- ^ Squash a layer of 'EitherT' into the underlying monad supporting 'throwM' | 136 | -- ^ Squash a layer of 'EitherT' into the underlying monad supporting 'throwM' |
108 | throwNat = Nat $ either throwM return <=< runEitherT | 137 | throwNat = Nat $ either throwM return <=< runExceptT |
109 | 138 | ||
110 | ioNat :: MonadIO m => IO :~> m | 139 | ioNat :: MonadIO m => IO :~> m |
111 | -- ^ @ioNat = Nat liftIO@ | 140 | -- ^ @ioNat = Nat liftIO@ |
112 | ioNat = Nat liftIO | 141 | ioNat = Nat liftIO |
142 | |||
143 | readerNat :: a -> ReaderT a m :~> m | ||
144 | readerNat a = Nat $ flip runReaderT a | ||
diff --git a/client/thermoprint-client.cabal b/client/thermoprint-client.cabal index 9567971..9c481e3 100644 --- a/client/thermoprint-client.cabal +++ b/client/thermoprint-client.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: thermoprint-client | 4 | name: thermoprint-client |
5 | version: 0.0.0 | 5 | version: 1.0.0 |
6 | synopsis: Client for thermoprint-spec | 6 | synopsis: Client for thermoprint-spec |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -21,7 +21,7 @@ library | |||
21 | -- other-modules: | 21 | -- other-modules: |
22 | -- other-extensions: | 22 | -- other-extensions: |
23 | build-depends: base >=4.8 && <5 | 23 | build-depends: base >=4.8 && <5 |
24 | , thermoprint-spec ==3.0.* | 24 | , thermoprint-spec ==4.0.* |
25 | , servant >=0.4.4 && <1 | 25 | , servant >=0.4.4 && <1 |
26 | , servant-client >=0.4.4 && <1 | 26 | , servant-client >=0.4.4 && <1 |
27 | , servant-server >=0.4.4 && <1 | 27 | , servant-server >=0.4.4 && <1 |
@@ -30,6 +30,8 @@ library | |||
30 | , time >=1.5.0 && <2 | 30 | , time >=1.5.0 && <2 |
31 | , exceptions >=0.8.2 && <1 | 31 | , exceptions >=0.8.2 && <1 |
32 | , transformers >=0.4.2 && <1 | 32 | , transformers >=0.4.2 && <1 |
33 | , http-client >=0.4.28 && <1 | ||
34 | , mtl >=2.2.1 && <3 | ||
33 | hs-source-dirs: src | 35 | hs-source-dirs: src |
34 | default-language: Haskell2010 | 36 | default-language: Haskell2010 |
35 | ghc-options: -Wall | 37 | ghc-options: -Wall |
diff --git a/default.nix b/default.nix index 7ffadea..0aa8c9e 100644 --- a/default.nix +++ b/default.nix | |||
@@ -1,5 +1,5 @@ | |||
1 | { pkgs ? (import <nixpkgs> {}) | 1 | { pkgs ? (import <nixpkgs> {}) |
2 | , compilerName ? "ghc7103" | 2 | , compilerName ? "ghc801" |
3 | }: | 3 | }: |
4 | 4 | ||
5 | rec { | 5 | rec { |
diff --git a/server/default-conf/Main.hs b/server/default-conf/Main.hs index 7c4bfc7..35088e8 100644 --- a/server/default-conf/Main.hs +++ b/server/default-conf/Main.hs | |||
@@ -20,6 +20,10 @@ main = thermoprintServer True (Nat runSqlite) $ def `withPrinters` printers | |||
20 | runSqlite :: ReaderT ConnectionPool (LoggingT IO) a -> IO a | 20 | runSqlite :: ReaderT ConnectionPool (LoggingT IO) a -> IO a |
21 | runSqlite = runStderrLoggingT . withSqlitePool "thermoprint.sqlite" 1 . runReaderT | 21 | runSqlite = runStderrLoggingT . withSqlitePool "thermoprint.sqlite" 1 . runReaderT |
22 | 22 | ||
23 | printers :: [( ResourceT (ReaderT ConnectionPool (LoggingT IO)) PrinterMethod | ||
24 | , QMConfig (ResourceT (ReaderT ConnectionPool (LoggingT IO))) | ||
25 | ) | ||
26 | ] | ||
23 | printers = [ (pure debugPrint, def) | 27 | printers = [ (pure debugPrint, def) |
24 | , (pure $ delayedDebugPrint (10 * 10^6), def) | 28 | , (pure $ delayedDebugPrint (10 * 10^6), def) |
25 | ] | 29 | ] |
diff --git a/server/src/Thermoprint/Server.hs b/server/src/Thermoprint/Server.hs index 07462da..15fb651 100644 --- a/server/src/Thermoprint/Server.hs +++ b/server/src/Thermoprint/Server.hs | |||
@@ -13,7 +13,7 @@ module Thermoprint.Server | |||
13 | , Config(..), QMConfig(..) | 13 | , Config(..), QMConfig(..) |
14 | , withPrinters | 14 | , withPrinters |
15 | , module Data.Default.Class | 15 | , module Data.Default.Class |
16 | , module Servant.Server.Internal.Enter | 16 | , module Servant.Utils.Enter |
17 | , module Thermoprint.Server.Printer | 17 | , module Thermoprint.Server.Printer |
18 | , module Thermoprint.Server.Queue | 18 | , module Thermoprint.Server.Queue |
19 | , module Thermoprint.Server.Queue.Utils | 19 | , module Thermoprint.Server.Queue.Utils |
@@ -62,7 +62,7 @@ import qualified Network.Wai.Handler.Warp as Warp | |||
62 | import Network.Wai (Application) | 62 | import Network.Wai (Application) |
63 | 63 | ||
64 | import Servant.Server (serve) | 64 | import Servant.Server (serve) |
65 | import Servant.Server.Internal.Enter (enter, (:~>)(..)) | 65 | import Servant.Utils.Enter (enter, (:~>)(..)) |
66 | import Servant.API | 66 | import Servant.API |
67 | import Servant.Utils.Links | 67 | import Servant.Utils.Links |
68 | import Network.URI | 68 | import Network.URI |
@@ -137,16 +137,16 @@ thermoprintServer :: ( MonadLoggerIO m | |||
137 | -> (m :~> IO) -- ^ 'dyre' controls the base of the monad-transformer-stack ('IO') but we let the user specify much of the rest of it (we handle 'ResourceT' ourselves, since we need it to fork properly). Therefore we require a specification of how to collapse the stack. | 137 | -> (m :~> IO) -- ^ 'dyre' controls the base of the monad-transformer-stack ('IO') but we let the user specify much of the rest of it (we handle 'ResourceT' ourselves, since we need it to fork properly). Therefore we require a specification of how to collapse the stack. |
138 | -> ResourceT m (Config (ResourceT m)) -> IO () | 138 | -> ResourceT m (Config (ResourceT m)) -> IO () |
139 | -- ^ Run the server | 139 | -- ^ Run the server |
140 | thermoprintServer dyre io = do | 140 | thermoprintServer dyre io cfg = do |
141 | cfgDir <- lookupEnv "THERMOPRINT_CONFIG" | 141 | cfgDir <- lookupEnv "THERMOPRINT_CONFIG" |
142 | cacheDir <- lookupEnv "THERMOPRINT_CACHE" | 142 | cacheDir <- lookupEnv "THERMOPRINT_CACHE" |
143 | Dyre.wrapMain $ Dyre.defaultParams | 143 | flip Dyre.wrapMain cfg $ Dyre.defaultParams |
144 | { Dyre.projectName = "thermoprint-server" | 144 | { Dyre.projectName = "thermoprint-server" |
145 | , Dyre.realMain = realMain | 145 | , Dyre.realMain = realMain |
146 | , Dyre.showError = flip (\msg -> fmap (\cfg -> cfg { dyreError = Just msg })) | 146 | , Dyre.showError = flip (\msg -> fmap (\cfg -> cfg { dyreError = Just msg })) |
147 | , Dyre.configCheck = dyre | 147 | , Dyre.configCheck = dyre |
148 | , Dyre.configDir = cfgDir | 148 | , Dyre.configDir = return <$> cfgDir |
149 | , Dyre.cacheDir = cacheDir | 149 | , Dyre.cacheDir = return <$> cacheDir |
150 | } | 150 | } |
151 | where | 151 | where |
152 | realMain cfg = unNat (io . Nat runResourceT) $ do | 152 | realMain cfg = unNat (io . Nat runResourceT) $ do |
@@ -164,6 +164,6 @@ thermoprintServer dyre io = do | |||
164 | nChan <- liftIO $ newBroadcastTChanIO | 164 | nChan <- liftIO $ newBroadcastTChanIO |
165 | let | 165 | let |
166 | printerUrl :: API.PrinterId -> URI | 166 | printerUrl :: API.PrinterId -> URI |
167 | printerUrl = safeLink thermoprintAPI (Proxy :: Proxy ("jobs" :> QueryParam "printer" API.PrinterId :> Get '[JSON] (Seq (API.JobId, UTCTime, JobStatus)))) | 167 | printerUrl = safeLink thermoprintAPI (Proxy :: Proxy ("jobs" :> QueryParam "printer" API.PrinterId :> Get '[JSON] (Seq (API.JobId, UTCTime, JobStatus)))) . Just |
168 | mapM_ (fork tMgr . uncurry (notifyOnChange nChan ((==) `on` fromZipper)) . bimap printerUrl queue) $ Map.toList printers | 168 | mapM_ (fork tMgr . uncurry (notifyOnChange nChan ((==) `on` fromZipper)) . bimap printerUrl queue) $ Map.toList printers |
169 | liftIO . Warp.runSettings warpSettings . withPush nChan . serve thermoprintAPI . flip enter API.thermoprintServer =<< handlerNat printers nChan | 169 | liftIO . Warp.runSettings warpSettings . withPush nChan . serve thermoprintAPI . flip enter API.thermoprintServer =<< handlerNat printers nChan |
diff --git a/server/src/Thermoprint/Server/API.hs b/server/src/Thermoprint/Server/API.hs index cbf727c..8e17eb4 100644 --- a/server/src/Thermoprint/Server/API.hs +++ b/server/src/Thermoprint/Server/API.hs | |||
@@ -27,15 +27,15 @@ import qualified Data.Map as Map | |||
27 | 27 | ||
28 | import qualified Data.Text as T | 28 | import qualified Data.Text as T |
29 | 29 | ||
30 | import Servant | 30 | import Servant hiding (Handler) |
31 | import Servant.Server | 31 | import Servant.Server hiding (Handler) |
32 | import Servant.Server.Internal.Enter | 32 | import Servant.Utils.Enter |
33 | import Servant.Utils.Links | 33 | import Servant.Utils.Links |
34 | 34 | ||
35 | import Control.Monad.Logger | 35 | import Control.Monad.Logger |
36 | import Control.Monad.Reader | 36 | import Control.Monad.Reader |
37 | import Control.Monad.Trans.Resource | 37 | import Control.Monad.Trans.Resource |
38 | import Control.Monad.Trans.Either | 38 | import Control.Monad.Except |
39 | import Control.Monad.IO.Class | 39 | import Control.Monad.IO.Class |
40 | 40 | ||
41 | import Control.Concurrent.STM | 41 | import Control.Concurrent.STM |
@@ -65,7 +65,7 @@ import Control.Monad.Catch (handle, catch) | |||
65 | import Data.Time | 65 | import Data.Time |
66 | 66 | ||
67 | type ProtoHandler = ReaderT HandlerInput (LoggingT (ResourceT IO)) | 67 | type ProtoHandler = ReaderT HandlerInput (LoggingT (ResourceT IO)) |
68 | type Handler = EitherT ServantErr ProtoHandler | 68 | type Handler = ExceptT ServantErr ProtoHandler |
69 | 69 | ||
70 | -- ^ Runtime configuration of our handlers | 70 | -- ^ Runtime configuration of our handlers |
71 | data HandlerInput = HandlerInput { sqlPool :: ConnectionPool -- ^ How to interact with 'persistent' storage | 71 | data HandlerInput = HandlerInput { sqlPool :: ConnectionPool -- ^ How to interact with 'persistent' storage |
@@ -73,13 +73,10 @@ data HandlerInput = HandlerInput { sqlPool :: ConnectionPool -- ^ How to intera | |||
73 | , nChan :: TChan Notification | 73 | , nChan :: TChan Notification |
74 | } | 74 | } |
75 | 75 | ||
76 | instance MonadLogger m => MonadLogger (EitherT a m) where | ||
77 | monadLoggerLog loc src lvl = lift . monadLoggerLog loc src lvl | ||
78 | |||
79 | handlerNat :: ( MonadReader ConnectionPool m | 76 | handlerNat :: ( MonadReader ConnectionPool m |
80 | , MonadLoggerIO m | 77 | , MonadLoggerIO m |
81 | ) => Map PrinterId Printer -> TChan Notification -> m (Handler :~> EitherT ServantErr IO) | 78 | ) => Map PrinterId Printer -> TChan Notification -> m (Handler :~> ExceptT ServantErr IO) |
82 | -- ^ Servant requires its handlers to be 'EitherT ServantErr IO' | 79 | -- ^ Servant requires its handlers to be 'ExceptT ServantErr IO' |
83 | -- | 80 | -- |
84 | -- This generates a 'Nat'ural transformation for squashing the monad-transformer-stack we use in our handlers to the monad 'servant-server' wants | 81 | -- This generates a 'Nat'ural transformation for squashing the monad-transformer-stack we use in our handlers to the monad 'servant-server' wants |
85 | handlerNat printerMap nChan = do | 82 | handlerNat printerMap nChan = do |
@@ -116,11 +113,11 @@ lookupPrinter :: Maybe PrinterId -> Handler (PrinterId, Printer) | |||
116 | lookupPrinter pId = asks printers >>= maybePrinter' pId | 113 | lookupPrinter pId = asks printers >>= maybePrinter' pId |
117 | where | 114 | where |
118 | maybePrinter' Nothing printerMap | 115 | maybePrinter' Nothing printerMap |
119 | | Map.null printerMap = left $ err501 { errBody = "No printers available" } | 116 | | Map.null printerMap = throwError $ err501 { errBody = "No printers available" } |
120 | | otherwise = return $ Map.findMin printerMap | 117 | | otherwise = return $ Map.findMin printerMap |
121 | maybePrinter' (Just pId) printerMap | 118 | maybePrinter' (Just pId) printerMap |
122 | | Just printer <- Map.lookup pId printerMap = return (pId, printer) | 119 | | Just printer <- Map.lookup pId printerMap = return (pId, printer) |
123 | | otherwise = left $ err404 { errBody = "No such printer" } | 120 | | otherwise = throwError $ err404 { errBody = "No such printer" } |
124 | 121 | ||
125 | queue' :: MonadIO m => Printer -> m Queue | 122 | queue' :: MonadIO m => Printer -> m Queue |
126 | -- ^ Call 'queue' and handle concurrency | 123 | -- ^ Call 'queue' and handle concurrency |
@@ -160,10 +157,10 @@ listJobs pId idR timeR = fmap (filterJobs . extractJobs) . (\(a, b) -> (,) a | |||
160 | ) | 157 | ) |
161 | 158 | ||
162 | getJob :: API.JobId -> Handler Printout | 159 | getJob :: API.JobId -> Handler Printout |
163 | getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool | 160 | getJob jobId = fmap jobContent . maybe (throwError err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool |
164 | 161 | ||
165 | jobStatus :: API.JobId -> Handler JobStatus | 162 | jobStatus :: API.JobId -> Handler JobStatus |
166 | jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing | 163 | jobStatus jobId = maybe (throwError err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing |
167 | 164 | ||
168 | abortJob :: API.JobId -> Handler () | 165 | abortJob :: API.JobId -> Handler () |
169 | abortJob needle = do | 166 | abortJob needle = do |
@@ -179,7 +176,7 @@ abortJob needle = do | |||
179 | $(logInfo) $ "Removed job #" <> (T.pack $ show (castId needle :: Integer)) <> " from " <> (T.pack . show $ pId') | 176 | $(logInfo) $ "Removed job #" <> (T.pack $ show (castId needle :: Integer)) <> " from " <> (T.pack . show $ pId') |
180 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("jobs" :> Get '[JSON] (Seq (API.JobId, UTCTime, JobStatus)))) | 177 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("jobs" :> Get '[JSON] (Seq (API.JobId, UTCTime, JobStatus)))) |
181 | return found | 178 | return found |
182 | when (not found) $ left err404 | 179 | when (not found) $ throwError err404 |
183 | 180 | ||
184 | listDrafts :: Handler (Map API.DraftId (Maybe DraftTitle)) | 181 | listDrafts :: Handler (Map API.DraftId (Maybe DraftTitle)) |
185 | listDrafts = asks sqlPool >>= runSqlPool (selectSourceRes [] []) >>= flip with toMap | 182 | listDrafts = asks sqlPool >>= runSqlPool (selectSourceRes [] []) >>= flip with toMap |
@@ -194,13 +191,13 @@ addDraft title content = do | |||
194 | return id | 191 | return id |
195 | 192 | ||
196 | updateDraft :: API.DraftId -> Maybe DraftTitle -> Printout -> Handler () | 193 | updateDraft :: API.DraftId -> Maybe DraftTitle -> Printout -> Handler () |
197 | updateDraft draftId title content = handle (\(KeyNotFound _) -> left $ err404) $ do | 194 | updateDraft draftId title content = handle (\(KeyNotFound _) -> throwError $ err404) $ do |
198 | runSqlPool (update (castId draftId) [ DraftTitle =. title, DraftContent =. content ]) =<< asks sqlPool | 195 | runSqlPool (update (castId draftId) [ DraftTitle =. title, DraftContent =. content ]) =<< asks sqlPool |
199 | $(logInfo) $ "Updated draft #" <> (T.pack $ show (castId draftId :: Integer)) | 196 | $(logInfo) $ "Updated draft #" <> (T.pack $ show (castId draftId :: Integer)) |
200 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("draft" :> Capture "draftId" API.DraftId :> Get '[JSON] (Maybe DraftTitle, Printout))) $ draftId | 197 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("draft" :> Capture "draftId" API.DraftId :> Get '[JSON] (Maybe DraftTitle, Printout))) $ draftId |
201 | 198 | ||
202 | getDraft :: API.DraftId -> Handler (Maybe DraftTitle, Printout) | 199 | getDraft :: API.DraftId -> Handler (Maybe DraftTitle, Printout) |
203 | getDraft draftId = fmap (\(Draft title content) -> (title, content)) . maybe (left err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool | 200 | getDraft draftId = fmap (\(Draft title content) -> (title, content)) . maybe (throwError err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool |
204 | 201 | ||
205 | deleteDraft :: API.DraftId -> Handler () | 202 | deleteDraft :: API.DraftId -> Handler () |
206 | deleteDraft draftId = do | 203 | deleteDraft draftId = do |
@@ -209,4 +206,4 @@ deleteDraft draftId = do | |||
209 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("drafts" :> Get '[JSON] (Map API.DraftId (Maybe DraftTitle)))) | 206 | notify $ safeLink thermoprintAPI (Proxy :: Proxy ("drafts" :> Get '[JSON] (Map API.DraftId (Maybe DraftTitle)))) |
210 | 207 | ||
211 | printDraft :: API.DraftId -> Maybe PrinterId -> Handler API.JobId | 208 | printDraft :: API.DraftId -> Maybe PrinterId -> Handler API.JobId |
212 | printDraft draftId printerId = (\(Draft _ content) -> queueJob printerId content) =<< maybe (left err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool | 209 | printDraft draftId printerId = (\(Draft _ content) -> queueJob printerId content) =<< maybe (throwError err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool |
diff --git a/server/src/Thermoprint/Server/Printer/Debug.hs b/server/src/Thermoprint/Server/Printer/Debug.hs index d7ee12a..b8580b8 100644 --- a/server/src/Thermoprint/Server/Printer/Debug.hs +++ b/server/src/Thermoprint/Server/Printer/Debug.hs | |||
@@ -26,7 +26,7 @@ debugPrint :: PrinterMethod | |||
26 | debugPrint = PM $ (>> return Nothing) . $(logDebugS) "Printer.Debug" . T.pack . show . cotext' | 26 | debugPrint = PM $ (>> return Nothing) . $(logDebugS) "Printer.Debug" . T.pack . show . cotext' |
27 | 27 | ||
28 | cotext' :: Printout -> Text | 28 | cotext' :: Printout -> Text |
29 | cotext' = mconcat . intersperse "\n\n" . map (mconcat . map cotext'' . toList) . toList | 29 | cotext' = mconcat . intersperse "\n\n" . map (mconcat . map cotext'' . toList . getChunks) . toList . getParagraphs |
30 | where | 30 | where |
31 | cotext'' (Cooked b) = cotext b | 31 | cotext'' (Cooked b) = cotext b |
32 | cotext'' (Raw _) = "[Raw]" | 32 | cotext'' (Raw _) = "[Raw]" |
diff --git a/server/src/Thermoprint/Server/Printer/Generic.hs b/server/src/Thermoprint/Server/Printer/Generic.hs index df84e06..f431e4f 100644 --- a/server/src/Thermoprint/Server/Printer/Generic.hs +++ b/server/src/Thermoprint/Server/Printer/Generic.hs | |||
@@ -114,10 +114,10 @@ intersperse' :: Monad m => m b -> (a -> m b) -> Seq a -> m () | |||
114 | intersperse' b f = sequence_ . intersperse b f | 114 | intersperse' b f = sequence_ . intersperse b f |
115 | 115 | ||
116 | render :: Printout -> Put | 116 | render :: Printout -> Put |
117 | render = intersperse' (newls' 2) renderPar | 117 | render = intersperse' (newls' 2) renderPar . getParagraphs |
118 | 118 | ||
119 | renderPar :: Paragraph -> Put | 119 | renderPar :: Paragraph -> Put |
120 | renderPar = mapM_ renderChunk | 120 | renderPar = mapM_ renderChunk . getChunks |
121 | where | 121 | where |
122 | renderChunk (Raw bs) = mapM_ pushWord8 $ LBS.unpack bs | 122 | renderChunk (Raw bs) = mapM_ pushWord8 $ LBS.unpack bs |
123 | renderChunk (Cooked block) = renderDoc $ execState (renderBlock block) (initDoc width) | 123 | renderChunk (Cooked block) = renderDoc $ execState (renderBlock block) (initDoc width) |
diff --git a/server/src/Thermoprint/Server/Queue/Utils.hs b/server/src/Thermoprint/Server/Queue/Utils.hs index 86b0162..745053e 100644 --- a/server/src/Thermoprint/Server/Queue/Utils.hs +++ b/server/src/Thermoprint/Server/Queue/Utils.hs | |||
@@ -17,7 +17,7 @@ import Data.Time | |||
17 | import Control.Monad.State | 17 | import Control.Monad.State |
18 | import Control.Monad.IO.Class | 18 | import Control.Monad.IO.Class |
19 | import Control.Monad.Trans.Identity | 19 | import Control.Monad.Trans.Identity |
20 | import Servant.Server.Internal.Enter | 20 | import Servant.Utils.Enter |
21 | 21 | ||
22 | import Thermoprint.Server.Queue | 22 | import Thermoprint.Server.Queue |
23 | 23 | ||
diff --git a/server/test/Thermoprint/ServerSpec.hs b/server/test/Thermoprint/ServerSpec.hs index 028ba2d..8af210d 100644 --- a/server/test/Thermoprint/ServerSpec.hs +++ b/server/test/Thermoprint/ServerSpec.hs | |||
@@ -145,7 +145,7 @@ spec = withSetup $ do | |||
145 | drafts `shouldReturn` [] | 145 | drafts `shouldReturn` [] |
146 | dId <- draftCreate Nothing mempty | 146 | dId <- draftCreate Nothing mempty |
147 | draft dId `shouldReturn` (Nothing, mempty) | 147 | draft dId `shouldReturn` (Nothing, mempty) |
148 | drafts `shouldReturn` [(dId, mempty)] | 148 | drafts `shouldReturn` [(dId, Nothing :: Maybe DraftTitle)] |
149 | p <- generate arbitrary | 149 | p <- generate arbitrary |
150 | draftReplace dId (Just "Title") p | 150 | draftReplace dId (Just "Title") p |
151 | draft dId `shouldReturn` (Just "Title", p) | 151 | draft dId `shouldReturn` (Just "Title", p) |
@@ -154,6 +154,6 @@ spec = withSetup $ do | |||
154 | draftDelete dId | 154 | draftDelete dId |
155 | drafts `shouldReturn` [] | 155 | drafts `shouldReturn` [] |
156 | where | 156 | where |
157 | Client{..} = mkClient' $ BaseUrl Http "localhost" 3000 | 157 | Client{..} = mkClient' $ BaseUrl Http "localhost" 3000 "" |
158 | 158 | ||
159 | 159 | ||
diff --git a/server/thermoprint-server.cabal b/server/thermoprint-server.cabal index 62eb0ca..37cf065 100644 --- a/server/thermoprint-server.cabal +++ b/server/thermoprint-server.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: thermoprint-server | 4 | name: thermoprint-server |
5 | version: 1.1.0 | 5 | version: 2.0.0 |
6 | synopsis: Server for thermoprint-spec | 6 | synopsis: Server for thermoprint-spec |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -50,7 +50,7 @@ library | |||
50 | , servant-server >=0.4.4 && <1 | 50 | , servant-server >=0.4.4 && <1 |
51 | , stm >=2.4.4 && <3 | 51 | , stm >=2.4.4 && <3 |
52 | , text >=1.2.1 && <2 | 52 | , text >=1.2.1 && <2 |
53 | , thermoprint-spec ==3.0.* | 53 | , thermoprint-spec ==4.0.* |
54 | , time >=1.5.0 && <2 | 54 | , time >=1.5.0 && <2 |
55 | , wai >=3.0.4 && <4 | 55 | , wai >=3.0.4 && <4 |
56 | , warp >=3.1.9 && <4 | 56 | , warp >=3.1.9 && <4 |
@@ -75,8 +75,8 @@ Test-Suite tests | |||
75 | hs-source-dirs: test | 75 | hs-source-dirs: test |
76 | main-is: Spec.hs | 76 | main-is: Spec.hs |
77 | build-depends: base >=4.8.1 && <5 | 77 | build-depends: base >=4.8.1 && <5 |
78 | , thermoprint-server ==1.1.* | 78 | , thermoprint-server ==2.0.* |
79 | , thermoprint-client ==0.0.* | 79 | , thermoprint-client ==1.0.* |
80 | , thermoprint-spec -any | 80 | , thermoprint-spec -any |
81 | , hspec >=2.2.1 && <3 | 81 | , hspec >=2.2.1 && <3 |
82 | , QuickCheck >=2.8.1 && <3 | 82 | , QuickCheck >=2.8.1 && <3 |
@@ -6,7 +6,7 @@ let | |||
6 | thermoprintPackages = builtins.attrValues (import ./default.nix {}); | 6 | thermoprintPackages = builtins.attrValues (import ./default.nix {}); |
7 | ghc = haskellPackages.ghcWithPackages | 7 | ghc = haskellPackages.ghcWithPackages |
8 | (ps: thermoprintPackages ++ utilities ps ++ testDeps ps); | 8 | (ps: thermoprintPackages ++ utilities ps ++ testDeps ps); |
9 | utilities = (ps: with ps; [ hlint cabal2nix cabal-install ]); | 9 | utilities = (ps: with ps; [ hlint cabal2nix ]); |
10 | testDeps = (ps: with ps; [ temporary hspec ]); | 10 | testDeps = (ps: with ps; [ temporary hspec ]); |
11 | in | 11 | in |
12 | pkgs.stdenv.mkDerivation rec { | 12 | pkgs.stdenv.mkDerivation rec { |
diff --git a/spec/src/Thermoprint/API.hs b/spec/src/Thermoprint/API.hs index 9e91487..8e98db8 100644 --- a/spec/src/Thermoprint/API.hs +++ b/spec/src/Thermoprint/API.hs | |||
@@ -100,12 +100,6 @@ instance Exception PrintingError | |||
100 | 100 | ||
101 | type DraftTitle = Text | 101 | type DraftTitle = Text |
102 | 102 | ||
103 | instance FromText UTCTime where | ||
104 | fromText = parseTimeM True defaultTimeLocale "%F_%T%Q" . T.unpack | ||
105 | |||
106 | instance ToText UTCTime where | ||
107 | toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q" | ||
108 | |||
109 | data Range a = Min a | Max a | Through a a | 103 | data Range a = Min a | Max a | Through a a |
110 | deriving (Show, Eq, Generic) | 104 | deriving (Show, Eq, Generic) |
111 | 105 | ||
@@ -121,17 +115,19 @@ contains (Min min) x = min <= x | |||
121 | contains (Max max) x = max >= x | 115 | contains (Max max) x = max >= x |
122 | contains (Through min max) x = min <= x && x <= max | 116 | contains (Through min max) x = min <= x && x <= max |
123 | 117 | ||
124 | instance ToText a => ToText (Range a) where | 118 | instance ToHttpApiData a => ToHttpApiData (Range a) where |
125 | toText (Min min) = toText min <> "-" | 119 | toUrlPiece (Min min) = toUrlPiece min <> "-" |
126 | toText (Max max) = "-" <> toText max | 120 | toUrlPiece (Max max) = "-" <> toUrlPiece max |
127 | toText (Through min max) = toText min <> "-" <> toText max | 121 | toUrlPiece (Through min max) = toUrlPiece min <> "-" <> toUrlPiece max |
128 | 122 | ||
129 | instance FromText a => FromText (Range a) where | 123 | instance FromHttpApiData a => FromHttpApiData (Range a) where |
130 | fromText t = listToMaybe $ through <> max <> min | 124 | parseUrlPiece t = listToEither $ through <> max <> min |
131 | where | 125 | where |
132 | through = [ Through min max | ((fromText -> Just min), (T.uncons -> Just ('-', (fromText -> Just max)))) <- zip (T.inits t) (T.tails t) ] | 126 | through = [ Through min max | ((parseUrlPiece -> Right min), (T.uncons -> Just ('-', (parseUrlPiece -> Right max)))) <- zip (T.inits t) (T.tails t) ] |
133 | min = [ Min min | (fromText -> Just min) <- T.inits t ] | 127 | min = [ Min min | (parseUrlPiece -> Right min) <- T.inits t ] |
134 | max = [ Max max | (fromText -> Just max) <- T.tails t ] | 128 | max = [ Max max | (parseUrlPiece -> Right max) <- T.tails t ] |
129 | listToEither [x] = Right x | ||
130 | listToEither _ = Left t | ||
135 | 131 | ||
136 | type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) | 132 | type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) |
137 | :<|> "jobs" :> ( | 133 | :<|> "jobs" :> ( |
@@ -144,16 +140,16 @@ type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) | |||
144 | :<|> "job" :> Capture "jobId" JobId :> ( | 140 | :<|> "job" :> Capture "jobId" JobId :> ( |
145 | Get '[JSON] Printout | 141 | Get '[JSON] Printout |
146 | :<|> "status" :> Get '[JSON] JobStatus | 142 | :<|> "status" :> Get '[JSON] JobStatus |
147 | :<|> Delete '[PlainText] () | 143 | :<|> Delete '[JSON] () |
148 | ) | 144 | ) |
149 | :<|> "drafts" :> ( | 145 | :<|> "drafts" :> ( |
150 | Get '[JSON] (Map DraftId (Maybe DraftTitle)) | 146 | Get '[JSON] (Map DraftId (Maybe DraftTitle)) |
151 | :<|> QueryParam "title" DraftTitle :> ReqBody '[JSON] Printout :> Post '[JSON] DraftId | 147 | :<|> QueryParam "title" DraftTitle :> ReqBody '[JSON] Printout :> Post '[JSON] DraftId |
152 | ) | 148 | ) |
153 | :<|> "draft" :> Capture "draftId" DraftId :> ( | 149 | :<|> "draft" :> Capture "draftId" DraftId :> ( |
154 | QueryParam "title" DraftTitle :> ReqBody '[JSON] Printout :> Put '[PlainText] () | 150 | QueryParam "title" DraftTitle :> ReqBody '[JSON] Printout :> Put '[JSON] () |
155 | :<|> Get '[JSON] (Maybe DraftTitle, Printout) | 151 | :<|> Get '[JSON] (Maybe DraftTitle, Printout) |
156 | :<|> Delete '[PlainText] () | 152 | :<|> Delete '[JSON] () |
157 | :<|> QueryParam "printer" PrinterId :> Post '[JSON] JobId | 153 | :<|> QueryParam "printer" PrinterId :> Post '[JSON] JobId |
158 | ) | 154 | ) |
159 | 155 | ||
diff --git a/spec/src/Thermoprint/Identifiers.hs b/spec/src/Thermoprint/Identifiers.hs index ed8534e..2a07318 100644 --- a/spec/src/Thermoprint/Identifiers.hs +++ b/spec/src/Thermoprint/Identifiers.hs | |||
@@ -12,17 +12,17 @@ import Data.Typeable (Typeable) | |||
12 | import GHC.Generics (Generic) | 12 | import GHC.Generics (Generic) |
13 | import Control.DeepSeq (NFData) | 13 | import Control.DeepSeq (NFData) |
14 | 14 | ||
15 | import Servant.API (ToText, FromText) | 15 | import Servant.API (ToHttpApiData, FromHttpApiData) |
16 | import Data.Aeson (FromJSON, ToJSON) | 16 | import Data.Aeson (FromJSON, ToJSON) |
17 | 17 | ||
18 | newtype PrinterId = PrinterId Integer | 18 | newtype PrinterId = PrinterId Integer |
19 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromText, ToText, FromJSON, ToJSON, Typeable, Generic, NFData) | 19 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromHttpApiData, ToHttpApiData, FromJSON, ToJSON, Typeable, Generic, NFData) |
20 | 20 | ||
21 | newtype JobId = JobId Integer | 21 | newtype JobId = JobId Integer |
22 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromText, ToText, FromJSON, ToJSON, Typeable, Generic, NFData) | 22 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromHttpApiData, ToHttpApiData, FromJSON, ToJSON, Typeable, Generic, NFData) |
23 | 23 | ||
24 | newtype DraftId = DraftId Integer | 24 | newtype DraftId = DraftId Integer |
25 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromText, ToText, FromJSON, ToJSON, Typeable, Generic, NFData) | 25 | deriving (Show, Read, Eq, Ord, Num, Real, Integral, Enum, FromHttpApiData, ToHttpApiData, FromJSON, ToJSON, Typeable, Generic, NFData) |
26 | 26 | ||
27 | castId :: (Integral a, Enum b) => a -> b | 27 | castId :: (Integral a, Enum b) => a -> b |
28 | castId = toEnum . fromInteger . toInteger | 28 | castId = toEnum . fromInteger . toInteger |
diff --git a/spec/src/Thermoprint/Printout.hs b/spec/src/Thermoprint/Printout.hs index 2be0a83..8c33e07 100644 --- a/spec/src/Thermoprint/Printout.hs +++ b/spec/src/Thermoprint/Printout.hs | |||
@@ -1,6 +1,6 @@ | |||
1 | {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} | 1 | {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} |
2 | {-# LANGUAGE OverloadedStrings #-} | 2 | {-# LANGUAGE OverloadedStrings #-} |
3 | {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-} | 3 | {-# LANGUAGE FlexibleInstances, FlexibleContexts, UndecidableInstances #-} |
4 | {-# OPTIONS_HADDOCK show-extensions #-} | 4 | {-# OPTIONS_HADDOCK show-extensions #-} |
5 | 5 | ||
6 | -- | This module contains the definition of the structure -- 'Printout' -- used to represent the content of a job | 6 | -- | This module contains the definition of the structure -- 'Printout' -- used to represent the content of a job |
@@ -63,19 +63,47 @@ import Prelude hiding (fold) | |||
63 | 63 | ||
64 | 64 | ||
65 | -- | A 'Printout' is a sequence of visually seperated 'Paragraph's | 65 | -- | A 'Printout' is a sequence of visually seperated 'Paragraph's |
66 | type Printout = Seq Paragraph | 66 | newtype Printout = Printout { getParagraphs :: Seq Paragraph } |
67 | deriving (Show, Generic, NFData) | ||
68 | |||
69 | instance Eq Paragraph => Eq Printout where | ||
70 | (==) = (==) `on` getParagraphs | ||
71 | |||
72 | instance Monoid Printout where | ||
73 | mempty = Printout mempty | ||
74 | mappend a b = Printout $ (mappend `on` getParagraphs) a b | ||
75 | |||
76 | instance FromJSON Printout where | ||
77 | parseJSON = fmap Printout . parseJSON | ||
78 | |||
79 | instance ToJSON Printout where | ||
80 | toJSON = toJSON . getParagraphs | ||
81 | |||
82 | instance Arbitrary Printout where | ||
83 | arbitrary = Printout <$> arbitrary | ||
67 | 84 | ||
68 | -- | A 'Paragraph' is a non-seperated sequence of 'Chunk's | 85 | -- | A 'Paragraph' is a non-seperated sequence of 'Chunk's |
69 | type Paragraph = Seq Chunk | 86 | newtype Paragraph = Paragraph { getChunks :: Seq Chunk } |
87 | deriving (Show, Generic, NFData) | ||
88 | |||
89 | instance Eq Chunk => Eq Paragraph where | ||
90 | (==) = (==) `on` getChunks | ||
91 | |||
92 | instance Monoid Paragraph where | ||
93 | mempty = Paragraph mempty | ||
94 | mappend a b = Paragraph $ (mappend `on` getChunks) a b | ||
95 | |||
96 | instance Arbitrary Paragraph where | ||
97 | arbitrary = Paragraph <$> arbitrary | ||
70 | 98 | ||
71 | instance FromJSON Paragraph where | 99 | instance FromJSON Paragraph where |
72 | parseJSON o@(Array _) = Seq.fromList <$> parseJSON o | 100 | parseJSON o@(Array _) = Paragraph . Seq.fromList <$> parseJSON o |
73 | parseJSON o@(Object _) = Seq.singleton <$> parseJSON o | 101 | parseJSON o@(Object _) = Paragraph . Seq.singleton <$> parseJSON o |
74 | parseJSON o@(String _) = Seq.singleton <$> parseJSON o | 102 | parseJSON o@(String _) = Paragraph . Seq.singleton <$> parseJSON o |
75 | parseJSON v = typeMismatch "Paragraph" v | 103 | parseJSON v = typeMismatch "Paragraph" v |
76 | 104 | ||
77 | instance ToJSON Paragraph where | 105 | instance ToJSON Paragraph where |
78 | toJSON cs | 106 | toJSON (Paragraph cs) |
79 | | (a :< as) <- viewl cs | 107 | | (a :< as) <- viewl cs |
80 | , Seq.null as = toJSON a | 108 | , Seq.null as = toJSON a |
81 | | otherwise = toJSON $ toList cs | 109 | | otherwise = toJSON $ toList cs |
diff --git a/spec/thermoprint-spec.cabal b/spec/thermoprint-spec.cabal index e236e05..28680fb 100644 --- a/spec/thermoprint-spec.cabal +++ b/spec/thermoprint-spec.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: thermoprint-spec | 4 | name: thermoprint-spec |
5 | version: 3.0.0 | 5 | version: 4.0.0 |
6 | synopsis: A specification of the API and the payload datatypes and associated utilities | 6 | synopsis: A specification of the API and the payload datatypes and associated utilities |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
diff --git a/threepenny.patch b/threepenny.patch index 1feb733..5dbb84f 100644 --- a/threepenny.patch +++ b/threepenny.patch | |||
@@ -1,7 +1,46 @@ | |||
1 | From 480675cba32803ab74ec064e14ed6b2001c8e071 Mon Sep 17 00:00:00 2001 | 1 | From 86574dffb26128252159a6f25a3ea29be965047f Mon Sep 17 00:00:00 2001 |
2 | From: Heinrich Apfelmus <apfelmus@quantentunnel.de> | ||
3 | Date: Fri, 27 May 2016 22:47:04 +0200 | ||
4 | Subject: [PATCH 1/3] Fix #138: Update the use of `GHC.mkWeak#` to GHC 8.0.1 | ||
5 | |||
6 | --- | ||
7 | src/Foreign/RemotePtr.hs | 10 +++++++--- | ||
8 | 1 file changed, 7 insertions(+), 3 deletions(-) | ||
9 | |||
10 | diff --git a/src/Foreign/RemotePtr.hs b/src/Foreign/RemotePtr.hs | ||
11 | index b534b74..fce37bc 100644 | ||
12 | --- a/src/Foreign/RemotePtr.hs | ||
13 | +++ b/src/Foreign/RemotePtr.hs | ||
14 | @@ -33,14 +33,18 @@ import qualified GHC.IORef as GHC | ||
15 | import qualified GHC.STRef as GHC | ||
16 | |||
17 | mkWeakIORefValue :: IORef a -> value -> IO () -> IO (Weak value) | ||
18 | -mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v f = GHC.IO $ \s -> | ||
19 | - case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #) | ||
20 | - | ||
21 | #if CABAL | ||
22 | #if MIN_VERSION_base(4,6,0) | ||
23 | #else | ||
24 | atomicModifyIORef' = atomicModifyIORef | ||
25 | #endif | ||
26 | +#if MIN_VERSION_base(4,9,0) | ||
27 | +mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v (GHC.IO f) = GHC.IO $ \s -> | ||
28 | + case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #) | ||
29 | +#endif | ||
30 | +#else | ||
31 | +mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v f = GHC.IO $ \s -> | ||
32 | + case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #) | ||
33 | #endif | ||
34 | |||
35 | type Map = Map.Map | ||
36 | -- | ||
37 | 2.9.0 | ||
38 | |||
39 | |||
40 | From 0ed2c2ebb64b24fdcded4e273bfda1583763a815 Mon Sep 17 00:00:00 2001 | ||
2 | From: Gregor Kleen <gkleen@yggdrasil.li> | 41 | From: Gregor Kleen <gkleen@yggdrasil.li> |
3 | Date: Tue, 23 Feb 2016 18:14:48 +0000 | 42 | Date: Tue, 23 Feb 2016 18:14:48 +0000 |
4 | Subject: [PATCH 1/2] Switched to using location.host | 43 | Subject: [PATCH 2/3] Switched to using location.host |
5 | 44 | ||
6 | --- | 45 | --- |
7 | js/comm.js | 2 +- | 46 | js/comm.js | 2 +- |
@@ -21,13 +60,13 @@ index 2d24f08..01763ba 100644 | |||
21 | 60 | ||
22 | // Close WebSocket when the browser window is closed. | 61 | // Close WebSocket when the browser window is closed. |
23 | -- | 62 | -- |
24 | 2.7.0 | 63 | 2.9.0 |
25 | 64 | ||
26 | 65 | ||
27 | From 52f45089ccf786c13d185faf1ad7436a63c13002 Mon Sep 17 00:00:00 2001 | 66 | From 4fb9b3304467a48d8ebeec85803464ec1a2aeeb6 Mon Sep 17 00:00:00 2001 |
28 | From: Gregor Kleen <gkleen@yggdrasil.li> | 67 | From: Gregor Kleen <gkleen@yggdrasil.li> |
29 | Date: Tue, 1 Mar 2016 00:22:01 +0100 | 68 | Date: Tue, 1 Mar 2016 00:22:01 +0100 |
30 | Subject: [PATCH 2/2] Now manipulating the location object | 69 | Subject: [PATCH 3/3] Now manipulating the location object |
31 | 70 | ||
32 | --- | 71 | --- |
33 | js/comm.js | 3 +- | 72 | js/comm.js | 3 +- |
@@ -148,5 +187,5 @@ index 0d2a564..ceec6f4 100644 | |||
148 | , [include|js/comm.js|] | 187 | , [include|js/comm.js|] |
149 | , [include|js/ffi.js|] | 188 | , [include|js/ffi.js|] |
150 | -- | 189 | -- |
151 | 2.7.0 | 190 | 2.9.0 |
152 | 191 | ||
diff --git a/tp-bbcode/src/Thermoprint/Printout/BBCode.hs b/tp-bbcode/src/Thermoprint/Printout/BBCode.hs index cbe2618..dd5edb0 100644 --- a/tp-bbcode/src/Thermoprint/Printout/BBCode.hs +++ b/tp-bbcode/src/Thermoprint/Printout/BBCode.hs | |||
@@ -104,7 +104,7 @@ morph :: DomForest -> Either SemanticError Printout | |||
104 | -- ^ Parse a list of paragraphs | 104 | -- ^ Parse a list of paragraphs |
105 | -- | 105 | -- |
106 | -- Since we permit only cooked input via 'Raw' 'Paragraph' is identical to 'Block' | 106 | -- Since we permit only cooked input via 'Raw' 'Paragraph' is identical to 'Block' |
107 | morph = fmap Seq.fromList . mapM (\t -> Seq.singleton . Cooked <$> parse BlockCtx t) | 107 | morph = fmap (Printout . Seq.fromList) . mapM (\t -> Paragraph . Seq.singleton . Cooked <$> parse BlockCtx t) |
108 | 108 | ||
109 | parseDom :: DomTree -> ParseResult | 109 | parseDom :: DomTree -> ParseResult |
110 | -- ^ Invoke 'asLine' and 'asBlock' to parse a single 'DomTree' | 110 | -- ^ Invoke 'asLine' and 'asBlock' to parse a single 'DomTree' |
diff --git a/tp-bbcode/src/Thermoprint/Printout/BBCode/Inverse.hs b/tp-bbcode/src/Thermoprint/Printout/BBCode/Inverse.hs index edd4c5a..8e15417 100644 --- a/tp-bbcode/src/Thermoprint/Printout/BBCode/Inverse.hs +++ b/tp-bbcode/src/Thermoprint/Printout/BBCode/Inverse.hs | |||
@@ -24,10 +24,10 @@ import Data.Monoid | |||
24 | import Thermoprint.Printout | 24 | import Thermoprint.Printout |
25 | 25 | ||
26 | cobbcode :: Printout -> Either UnicodeException Text | 26 | cobbcode :: Printout -> Either UnicodeException Text |
27 | cobbcode (toList -> ps) = mconcat . intersperse "\n\n" <$> mapM handlePar ps | 27 | cobbcode (toList . getParagraphs -> ps) = mconcat . intersperse "\n\n" <$> mapM handlePar ps |
28 | 28 | ||
29 | handlePar :: Seq Chunk -> Either UnicodeException Text | 29 | handlePar :: Paragraph -> Either UnicodeException Text |
30 | handlePar (toList -> cs) = mconcat <$> mapM handleChunk cs | 30 | handlePar (toList . getChunks -> cs) = mconcat <$> mapM handleChunk cs |
31 | 31 | ||
32 | handleChunk :: Chunk -> Either UnicodeException Text | 32 | handleChunk :: Chunk -> Either UnicodeException Text |
33 | handleChunk (Cooked b) = Right $ handleBlock b | 33 | handleChunk (Cooked b) = Right $ handleBlock b |
diff --git a/tp-bbcode/test/Thermoprint/Printout/BBCodeSpec.hs b/tp-bbcode/test/Thermoprint/Printout/BBCodeSpec.hs index 09b3147..7909360 100644 --- a/tp-bbcode/test/Thermoprint/Printout/BBCodeSpec.hs +++ b/tp-bbcode/test/Thermoprint/Printout/BBCodeSpec.hs | |||
@@ -53,7 +53,7 @@ normalize = (!! 3) . iterate normalize' . first (const ()) | |||
53 | join' _ = Left () | 53 | join' _ = Left () |
54 | 54 | ||
55 | pOut :: Seq Block -> Printout | 55 | pOut :: Seq Block -> Printout |
56 | pOut = fmap (pure . Cooked) | 56 | pOut = Printout . fmap (Paragraph . pure . Cooked) |
57 | 57 | ||
58 | examples :: [(Text, Either BBCodeError (Seq Block))] | 58 | examples :: [(Text, Either BBCodeError (Seq Block))] |
59 | examples = [ ("Hello World!" | 59 | examples = [ ("Hello World!" |
diff --git a/tp-bbcode/thermoprint-bbcode.cabal b/tp-bbcode/thermoprint-bbcode.cabal index 8773b89..29855e2 100644 --- a/tp-bbcode/thermoprint-bbcode.cabal +++ b/tp-bbcode/thermoprint-bbcode.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: thermoprint-bbcode | 4 | name: thermoprint-bbcode |
5 | version: 1.0.0 | 5 | version: 2.0.0 |
6 | synopsis: Parse bbcode for use in thermoprint | 6 | synopsis: Parse bbcode for use in thermoprint |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -24,8 +24,8 @@ library | |||
24 | , OverloadedLists | 24 | , OverloadedLists |
25 | -- other-extensions: | 25 | -- other-extensions: |
26 | build-depends: base >=4.8.1 && <5 | 26 | build-depends: base >=4.8.1 && <5 |
27 | , thermoprint-spec ==3.0.* | 27 | , thermoprint-spec ==4.0.* |
28 | , bbcode >=3.0 && <4 | 28 | , bbcode >=3.1.1 && <4 |
29 | , containers -any | 29 | , containers -any |
30 | , text -any | 30 | , text -any |
31 | , case-insensitive -any | 31 | , case-insensitive -any |
@@ -44,7 +44,7 @@ Test-Suite tests | |||
44 | , OverloadedLists | 44 | , OverloadedLists |
45 | build-depends: base >=4.8.1 && <5 | 45 | build-depends: base >=4.8.1 && <5 |
46 | , thermoprint-bbcode -any | 46 | , thermoprint-bbcode -any |
47 | , thermoprint-spec ==3.0.* | 47 | , thermoprint-spec ==4.0.* |
48 | , hspec >=2.2.1 && <3 | 48 | , hspec >=2.2.1 && <3 |
49 | , QuickCheck >=2.8.1 && <3 | 49 | , QuickCheck >=2.8.1 && <3 |
50 | , quickcheck-instances >=0.3.11 && <4 | 50 | , quickcheck-instances >=0.3.11 && <4 |
diff --git a/tprint/src/Options.hs b/tprint/src/Options.hs index 1ad6c47..e146f91 100644 --- a/tprint/src/Options.hs +++ b/tprint/src/Options.hs | |||
@@ -26,6 +26,8 @@ import Instances () | |||
26 | import Paths_tprint (version) | 26 | import Paths_tprint (version) |
27 | import Data.Version (showVersion) | 27 | import Data.Version (showVersion) |
28 | 28 | ||
29 | import Data.Bifunctor (Bifunctor(..)) | ||
30 | |||
29 | data TPrint = TPrint | 31 | data TPrint = TPrint |
30 | { baseUrl :: BaseUrl | 32 | { baseUrl :: BaseUrl |
31 | , dryRun :: Bool | 33 | , dryRun :: Bool |
@@ -148,7 +150,7 @@ pOperation = hsubparser $ mconcat [ command "printers" cmdPrinters | |||
148 | ] | 150 | ] |
149 | 151 | ||
150 | pTPrint :: Parser TPrint | 152 | pTPrint :: Parser TPrint |
151 | pTPrint = TPrint <$> option (eitherReader parseBaseUrl) (metavar "URL" <> long "baseurl" <> short 'u' <> help "Server to interact with" <> value (BaseUrl Http "localhost" 3000) <> showDefaultWith showBaseUrl) | 153 | pTPrint = TPrint <$> option (eitherReader $ first show . parseBaseUrl) (metavar "URL" <> long "baseurl" <> short 'u' <> help "Server to interact with" <> value (BaseUrl Http "localhost" 3000 "") <> showDefaultWith showBaseUrl) |
152 | <*> switch (long "dry-run" <> short 'n' <> help "Don't send any requests that would be expected to change the servers state") | 154 | <*> switch (long "dry-run" <> short 'n' <> help "Don't send any requests that would be expected to change the servers state") |
153 | <*> pOutput | 155 | <*> pOutput |
154 | <*> pOperation | 156 | <*> pOperation |
diff --git a/tprint/tprint.cabal b/tprint/tprint.cabal index d6fc422..5fcd00b 100644 --- a/tprint/tprint.cabal +++ b/tprint/tprint.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: tprint | 4 | name: tprint |
5 | version: 1.0.0 | 5 | version: 2.0.0 |
6 | synopsis: A CLI for thermoprint-client | 6 | synopsis: A CLI for thermoprint-client |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -22,9 +22,9 @@ executable tprint | |||
22 | , Options.Utils | 22 | , Options.Utils |
23 | , Instances | 23 | , Instances |
24 | -- other-extensions: | 24 | -- other-extensions: |
25 | build-depends: base >=4.8 && <4.9 | 25 | build-depends: base >=4.8 && <5 |
26 | , thermoprint-bbcode >=1.0.0 && <2 | 26 | , thermoprint-bbcode >=2.0.0 && <3 |
27 | , thermoprint-client ==0.0.* | 27 | , thermoprint-client ==1.0.* |
28 | , optparse-applicative >=0.12.1 && <1 | 28 | , optparse-applicative >=0.12.1 && <1 |
29 | , containers >=0.5.6 && <1 | 29 | , containers >=0.5.6 && <1 |
30 | , time >=1.5.0 && <2 | 30 | , time >=1.5.0 && <2 |
diff --git a/webgui/src/Main.hs b/webgui/src/Main.hs index a295fd9..252e933 100644 --- a/webgui/src/Main.hs +++ b/webgui/src/Main.hs | |||
@@ -86,6 +86,7 @@ config = do | |||
86 | <*> (BaseUrl Http | 86 | <*> (BaseUrl Http |
87 | <$> Opt.strOption (Opt.long "target-addr" <> Opt.short 'A' <> Opt.metavar "HOST" <> Opt.help "Host to connect to" <> Opt.value "localhost" <> Opt.showDefault) | 87 | <$> Opt.strOption (Opt.long "target-addr" <> Opt.short 'A' <> Opt.metavar "HOST" <> Opt.help "Host to connect to" <> Opt.value "localhost" <> Opt.showDefault) |
88 | <*> Opt.option Opt.auto (Opt.long "target-port" <> Opt.short 'P' <> Opt.metavar "PORT" <> Opt.help "Port to connect to" <> Opt.value 3000 <> Opt.showDefault) | 88 | <*> Opt.option Opt.auto (Opt.long "target-port" <> Opt.short 'P' <> Opt.metavar "PORT" <> Opt.help "Port to connect to" <> Opt.value 3000 <> Opt.showDefault) |
89 | <*> Opt.strOption (Opt.long "target-path" <> Opt.short 'F' <> Opt.metavar "PATH" <> Opt.help "Path we expect to find Thermoprint.Server under" <> Opt.value "" <> Opt.showDefault) | ||
89 | ) | 90 | ) |
90 | where | 91 | where |
91 | port def = Opt.long "port" | 92 | port def = Opt.long "port" |
@@ -151,8 +152,8 @@ setup Config{..} window (split -> (socketErr, dataUpdate)) = void $ do | |||
151 | return (status, triggerStatusChange) | 152 | return (status, triggerStatusChange) |
152 | 153 | ||
153 | Client{..} = mkClient (hoistNat $ Nat liftIO) server | 154 | Client{..} = mkClient (hoistNat $ Nat liftIO) server |
154 | withFatal :: EitherT ServantError UI a -> UI a | 155 | withFatal :: ExceptT ServantError UI a -> UI a |
155 | withFatal a = either (fatal . ("Error while communicating to Thermoprint.Server: " ++) . show) return =<< runEitherT a | 156 | withFatal a = either (fatal . ("Error while communicating to Thermoprint.Server: " ++) . show) return =<< runExceptT a |
156 | 157 | ||
157 | handleEditor selectedPrinter (_, modifyFocusedJobs) = do | 158 | handleEditor selectedPrinter (_, modifyFocusedJobs) = do |
158 | title <- fatal' "Could not find editor title field" =<< getElementById window "editorTitle" | 159 | title <- fatal' "Could not find editor title field" =<< getElementById window "editorTitle" |
@@ -256,7 +257,7 @@ setup Config{..} window (split -> (socketErr, dataUpdate)) = void $ do | |||
256 | 257 | ||
257 | 258 | ||
258 | enactDeletion <- fatal' "Could not find deletion button" =<< getElementById window "enactDeletion" | 259 | enactDeletion <- fatal' "Could not find deletion button" =<< getElementById window "enactDeletion" |
259 | on UI.click enactDeletion . const $ currentValue marking >>= mapM_ (runEitherT . draftDelete) >> updateMarking Set.empty | 260 | on UI.click enactDeletion . const $ currentValue marking >>= mapM_ (runExceptT . draftDelete) >> updateMarking Set.empty |
260 | -- deletion' <- allowDeletion # get UI.checked | 261 | -- deletion' <- allowDeletion # get UI.checked |
261 | let | 262 | let |
262 | updateMarking' = callFunction (mangle <$> ffi getChecked) >>= updateMarking | 263 | updateMarking' = callFunction (mangle <$> ffi getChecked) >>= updateMarking |
@@ -342,7 +343,7 @@ setup Config{..} window (split -> (socketErr, dataUpdate)) = void $ do | |||
342 | (marking, (liftIO .) -> updateMarking) <- stepper' $ Set.empty | 343 | (marking, (liftIO .) -> updateMarking) <- stepper' $ Set.empty |
343 | 344 | ||
344 | enactAbortion <- fatal' "Could not find deletion button" =<< getElementById window "enactAbortion" | 345 | enactAbortion <- fatal' "Could not find deletion button" =<< getElementById window "enactAbortion" |
345 | on UI.click enactAbortion . const $ currentValue marking >>= mapM_ (runEitherT . jobDelete) >> updateMarking Set.empty | 346 | on UI.click enactAbortion . const $ currentValue marking >>= mapM_ (runExceptT . jobDelete) >> updateMarking Set.empty |
346 | 347 | ||
347 | (selectedPrinter, updatePrinter) <- do | 348 | (selectedPrinter, updatePrinter) <- do |
348 | autoselectPrinter <- fatal' "Could not find printer autoselect switch" =<< getElementById window "autoselectPrinter" | 349 | autoselectPrinter <- fatal' "Could not find printer autoselect switch" =<< getElementById window "autoselectPrinter" |
diff --git a/webgui/thermoprint-webgui.cabal b/webgui/thermoprint-webgui.cabal index 024bcf6..03aa9b2 100644 --- a/webgui/thermoprint-webgui.cabal +++ b/webgui/thermoprint-webgui.cabal | |||
@@ -2,7 +2,7 @@ | |||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | 2 | -- documentation, see http://haskell.org/cabal/users-guide/ |
3 | 3 | ||
4 | name: thermoprint-webgui | 4 | name: thermoprint-webgui |
5 | version: 0.0.0 | 5 | version: 1.0.0 |
6 | synopsis: Threepenny interface for thermoprint-spec compliant servers | 6 | synopsis: Threepenny interface for thermoprint-spec compliant servers |
7 | -- description: | 7 | -- description: |
8 | homepage: http://dirty-haskell.org/tags/thermoprint.html | 8 | homepage: http://dirty-haskell.org/tags/thermoprint.html |
@@ -25,9 +25,9 @@ executable thermoprint-webgui | |||
25 | main-is: Main.hs | 25 | main-is: Main.hs |
26 | -- other-modules: | 26 | -- other-modules: |
27 | -- other-extensions: | 27 | -- other-extensions: |
28 | build-depends: base >=4.8 && <4.9 | 28 | build-depends: base >=4.8 && <5 |
29 | , thermoprint-bbcode >=1.0.0 && <2 | 29 | , thermoprint-bbcode >=2.0.0 && <3 |
30 | , thermoprint-client ==0.0.* | 30 | , thermoprint-client ==1.0.* |
31 | , threepenny-gui >=0.6.0 && <1 | 31 | , threepenny-gui >=0.6.0 && <1 |
32 | , optparse-applicative >=0.12.1 && <1 | 32 | , optparse-applicative >=0.12.1 && <1 |
33 | , bytestring >=0.10.6 && <1 | 33 | , bytestring >=0.10.6 && <1 |