aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <pngwjpgh@users.noreply.github.com>2016-07-17 19:21:56 +0200
committerGregor Kleen <pngwjpgh@users.noreply.github.com>2016-07-17 19:21:56 +0200
commit2b9ceaead3f3cd80e973cccecb9a3eebc51154f7 (patch)
treedf2378943480647606b6a06f62c0f4b8b2ab406d
parentac4cf4a0a494eafe55364f816569c517684fdf32 (diff)
downloadthermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar
thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.gz
thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.bz2
thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.tar.xz
thermoprint-2b9ceaead3f3cd80e973cccecb9a3eebc51154f7.zip
Fixes for GHC 8.0.1
-rw-r--r--bbcode/bbcode.cabal4
-rw-r--r--client/src/Thermoprint/Client.hs60
-rw-r--r--client/thermoprint-client.cabal6
-rw-r--r--default.nix2
-rw-r--r--server/default-conf/Main.hs4
-rw-r--r--server/src/Thermoprint/Server.hs14
-rw-r--r--server/src/Thermoprint/Server/API.hs33
-rw-r--r--server/src/Thermoprint/Server/Printer/Debug.hs2
-rw-r--r--server/src/Thermoprint/Server/Printer/Generic.hs4
-rw-r--r--server/src/Thermoprint/Server/Queue/Utils.hs2
-rw-r--r--server/test/Thermoprint/ServerSpec.hs4
-rw-r--r--server/thermoprint-server.cabal8
-rw-r--r--shell.nix2
-rw-r--r--spec/src/Thermoprint/API.hs32
-rw-r--r--spec/src/Thermoprint/Identifiers.hs8
-rw-r--r--spec/src/Thermoprint/Printout.hs42
-rw-r--r--spec/thermoprint-spec.cabal2
-rw-r--r--threepenny.patch51
-rw-r--r--tp-bbcode/src/Thermoprint/Printout/BBCode.hs2
-rw-r--r--tp-bbcode/src/Thermoprint/Printout/BBCode/Inverse.hs6
-rw-r--r--tp-bbcode/test/Thermoprint/Printout/BBCodeSpec.hs2
-rw-r--r--tp-bbcode/thermoprint-bbcode.cabal8
-rw-r--r--tprint/src/Options.hs4
-rw-r--r--tprint/tprint.cabal8
-rw-r--r--webgui/src/Main.hs9
-rw-r--r--webgui/thermoprint-webgui.cabal8
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
4name: bbcode 4name: bbcode
5version: 3.1.0 5version: 3.1.1
6synopsis: A parser for bbcode 6synopsis: A parser for bbcode
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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'
7module Thermoprint.Client 10module 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
19import Thermoprint.API 22import Thermoprint.API
@@ -24,19 +27,20 @@ import Data.Time (UTCTime)
24import Servant.Client hiding (HasClient(..)) 27import Servant.Client hiding (HasClient(..))
25import qualified Servant.Client as S 28import qualified Servant.Client as S
26import Servant.Common.BaseUrl 29import Servant.Common.BaseUrl
30import Network.HTTP.Client (Manager, ManagerSettings, newManager, defaultManagerSettings)
27import Servant.API 31import Servant.API
28import Servant.Server.Internal.Enter 32import Servant.Utils.Enter
29import Control.Monad.Trans.Either 33import Control.Monad.Except (ExceptT, runExceptT)
30 34
35import Control.Monad.Reader (ReaderT, runReaderT, ask)
31import Control.Monad.Catch (Exception, MonadThrow(..)) 36import Control.Monad.Catch (Exception, MonadThrow(..))
32import Control.Monad.IO.Class (MonadIO(..)) 37import Control.Monad.IO.Class (MonadIO(..))
38import Control.Monad.Trans (lift)
33 39
34import Control.Monad 40import Control.Monad
35import Control.Category 41import Control.Category
36import Prelude hiding (id, (.)) 42import Prelude hiding (id, (.))
37 43
38instance 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
50data Client m = Client 54data 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
87withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI 91withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI
88 92
89mkClient :: (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 93mkClientS :: 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'
93mkClient n url = Client{..} 99mkClientS 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
125mkClient :: 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
129mkClient n url = mkClientS n defaultManagerSettings url
130
102mkClient' :: (MonadThrow m, MonadIO m) => BaseUrl -> Client m 131mkClient' :: (MonadThrow m, MonadIO m) => BaseUrl -> Client m
103-- ^ @mkClient' = mkClient $ ioNat . throwNat@ 132-- ^ @mkClient' = mkClient $ ioNat . throwNat@
104mkClient' = mkClient $ ioNat . throwNat 133mkClient' = mkClient $ ioNat . throwNat
105 134
106throwNat :: (Exception e, MonadThrow m) => EitherT e m :~> m 135throwNat :: (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'
108throwNat = Nat $ either throwM return <=< runEitherT 137throwNat = Nat $ either throwM return <=< runExceptT
109 138
110ioNat :: MonadIO m => IO :~> m 139ioNat :: MonadIO m => IO :~> m
111-- ^ @ioNat = Nat liftIO@ 140-- ^ @ioNat = Nat liftIO@
112ioNat = Nat liftIO 141ioNat = Nat liftIO
142
143readerNat :: a -> ReaderT a m :~> m
144readerNat 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
4name: thermoprint-client 4name: thermoprint-client
5version: 0.0.0 5version: 1.0.0
6synopsis: Client for thermoprint-spec 6synopsis: Client for thermoprint-spec
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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
5rec { 5rec {
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
62import Network.Wai (Application) 62import Network.Wai (Application)
63 63
64import Servant.Server (serve) 64import Servant.Server (serve)
65import Servant.Server.Internal.Enter (enter, (:~>)(..)) 65import Servant.Utils.Enter (enter, (:~>)(..))
66import Servant.API 66import Servant.API
67import Servant.Utils.Links 67import Servant.Utils.Links
68import Network.URI 68import 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
140thermoprintServer dyre io = do 140thermoprintServer 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
28import qualified Data.Text as T 28import qualified Data.Text as T
29 29
30import Servant 30import Servant hiding (Handler)
31import Servant.Server 31import Servant.Server hiding (Handler)
32import Servant.Server.Internal.Enter 32import Servant.Utils.Enter
33import Servant.Utils.Links 33import Servant.Utils.Links
34 34
35import Control.Monad.Logger 35import Control.Monad.Logger
36import Control.Monad.Reader 36import Control.Monad.Reader
37import Control.Monad.Trans.Resource 37import Control.Monad.Trans.Resource
38import Control.Monad.Trans.Either 38import Control.Monad.Except
39import Control.Monad.IO.Class 39import Control.Monad.IO.Class
40 40
41import Control.Concurrent.STM 41import Control.Concurrent.STM
@@ -65,7 +65,7 @@ import Control.Monad.Catch (handle, catch)
65import Data.Time 65import Data.Time
66 66
67type ProtoHandler = ReaderT HandlerInput (LoggingT (ResourceT IO)) 67type ProtoHandler = ReaderT HandlerInput (LoggingT (ResourceT IO))
68type Handler = EitherT ServantErr ProtoHandler 68type Handler = ExceptT ServantErr ProtoHandler
69 69
70-- ^ Runtime configuration of our handlers 70-- ^ Runtime configuration of our handlers
71data HandlerInput = HandlerInput { sqlPool :: ConnectionPool -- ^ How to interact with 'persistent' storage 71data 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
76instance MonadLogger m => MonadLogger (EitherT a m) where
77 monadLoggerLog loc src lvl = lift . monadLoggerLog loc src lvl
78
79handlerNat :: ( MonadReader ConnectionPool m 76handlerNat :: ( 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
85handlerNat printerMap nChan = do 82handlerNat printerMap nChan = do
@@ -116,11 +113,11 @@ lookupPrinter :: Maybe PrinterId -> Handler (PrinterId, Printer)
116lookupPrinter pId = asks printers >>= maybePrinter' pId 113lookupPrinter 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
125queue' :: MonadIO m => Printer -> m Queue 122queue' :: 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
162getJob :: API.JobId -> Handler Printout 159getJob :: API.JobId -> Handler Printout
163getJob jobId = fmap jobContent . maybe (left err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool 160getJob jobId = fmap jobContent . maybe (throwError err404) return =<< runSqlPool (get $ castId jobId) =<< asks sqlPool
164 161
165jobStatus :: API.JobId -> Handler JobStatus 162jobStatus :: API.JobId -> Handler JobStatus
166jobStatus jobId = maybe (left err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing 163jobStatus jobId = maybe (throwError err404) return . lookup jobId . map (\(id, _, st) -> (id, st)) . toList =<< listJobs Nothing Nothing Nothing
167 164
168abortJob :: API.JobId -> Handler () 165abortJob :: API.JobId -> Handler ()
169abortJob needle = do 166abortJob 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
184listDrafts :: Handler (Map API.DraftId (Maybe DraftTitle)) 181listDrafts :: Handler (Map API.DraftId (Maybe DraftTitle))
185listDrafts = asks sqlPool >>= runSqlPool (selectSourceRes [] []) >>= flip with toMap 182listDrafts = asks sqlPool >>= runSqlPool (selectSourceRes [] []) >>= flip with toMap
@@ -194,13 +191,13 @@ addDraft title content = do
194 return id 191 return id
195 192
196updateDraft :: API.DraftId -> Maybe DraftTitle -> Printout -> Handler () 193updateDraft :: API.DraftId -> Maybe DraftTitle -> Printout -> Handler ()
197updateDraft draftId title content = handle (\(KeyNotFound _) -> left $ err404) $ do 194updateDraft 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
202getDraft :: API.DraftId -> Handler (Maybe DraftTitle, Printout) 199getDraft :: API.DraftId -> Handler (Maybe DraftTitle, Printout)
203getDraft draftId = fmap (\(Draft title content) -> (title, content)) . maybe (left err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool 200getDraft draftId = fmap (\(Draft title content) -> (title, content)) . maybe (throwError err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool
204 201
205deleteDraft :: API.DraftId -> Handler () 202deleteDraft :: API.DraftId -> Handler ()
206deleteDraft draftId = do 203deleteDraft 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
211printDraft :: API.DraftId -> Maybe PrinterId -> Handler API.JobId 208printDraft :: API.DraftId -> Maybe PrinterId -> Handler API.JobId
212printDraft draftId printerId = (\(Draft _ content) -> queueJob printerId content) =<< maybe (left err404) return =<< runSqlPool (get $ castId draftId) =<< asks sqlPool 209printDraft 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
26debugPrint = PM $ (>> return Nothing) . $(logDebugS) "Printer.Debug" . T.pack . show . cotext' 26debugPrint = PM $ (>> return Nothing) . $(logDebugS) "Printer.Debug" . T.pack . show . cotext'
27 27
28cotext' :: Printout -> Text 28cotext' :: Printout -> Text
29cotext' = mconcat . intersperse "\n\n" . map (mconcat . map cotext'' . toList) . toList 29cotext' = 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 ()
114intersperse' b f = sequence_ . intersperse b f 114intersperse' b f = sequence_ . intersperse b f
115 115
116render :: Printout -> Put 116render :: Printout -> Put
117render = intersperse' (newls' 2) renderPar 117render = intersperse' (newls' 2) renderPar . getParagraphs
118 118
119renderPar :: Paragraph -> Put 119renderPar :: Paragraph -> Put
120renderPar = mapM_ renderChunk 120renderPar = 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
17import Control.Monad.State 17import Control.Monad.State
18import Control.Monad.IO.Class 18import Control.Monad.IO.Class
19import Control.Monad.Trans.Identity 19import Control.Monad.Trans.Identity
20import Servant.Server.Internal.Enter 20import Servant.Utils.Enter
21 21
22import Thermoprint.Server.Queue 22import 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
4name: thermoprint-server 4name: thermoprint-server
5version: 1.1.0 5version: 2.0.0
6synopsis: Server for thermoprint-spec 6synopsis: Server for thermoprint-spec
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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
diff --git a/shell.nix b/shell.nix
index 638a9df..f0a69b4 100644
--- a/shell.nix
+++ b/shell.nix
@@ -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 ]);
11in 11in
12pkgs.stdenv.mkDerivation rec { 12pkgs.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
101type DraftTitle = Text 101type DraftTitle = Text
102 102
103instance FromText UTCTime where
104 fromText = parseTimeM True defaultTimeLocale "%F_%T%Q" . T.unpack
105
106instance ToText UTCTime where
107 toText = T.pack . formatTime defaultTimeLocale "%F_%T%Q"
108
109data Range a = Min a | Max a | Through a a 103data 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
121contains (Max max) x = max >= x 115contains (Max max) x = max >= x
122contains (Through min max) x = min <= x && x <= max 116contains (Through min max) x = min <= x && x <= max
123 117
124instance ToText a => ToText (Range a) where 118instance 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
129instance FromText a => FromText (Range a) where 123instance 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
136type ThermoprintAPI = "printers" :> Get '[JSON] (Map PrinterId PrinterStatus) 132type 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)
12import GHC.Generics (Generic) 12import GHC.Generics (Generic)
13import Control.DeepSeq (NFData) 13import Control.DeepSeq (NFData)
14 14
15import Servant.API (ToText, FromText) 15import Servant.API (ToHttpApiData, FromHttpApiData)
16import Data.Aeson (FromJSON, ToJSON) 16import Data.Aeson (FromJSON, ToJSON)
17 17
18newtype PrinterId = PrinterId Integer 18newtype 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
21newtype JobId = JobId Integer 21newtype 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
24newtype DraftId = DraftId Integer 24newtype 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
27castId :: (Integral a, Enum b) => a -> b 27castId :: (Integral a, Enum b) => a -> b
28castId = toEnum . fromInteger . toInteger 28castId = 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
66type Printout = Seq Paragraph 66newtype Printout = Printout { getParagraphs :: Seq Paragraph }
67 deriving (Show, Generic, NFData)
68
69instance Eq Paragraph => Eq Printout where
70 (==) = (==) `on` getParagraphs
71
72instance Monoid Printout where
73 mempty = Printout mempty
74 mappend a b = Printout $ (mappend `on` getParagraphs) a b
75
76instance FromJSON Printout where
77 parseJSON = fmap Printout . parseJSON
78
79instance ToJSON Printout where
80 toJSON = toJSON . getParagraphs
81
82instance 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
69type Paragraph = Seq Chunk 86newtype Paragraph = Paragraph { getChunks :: Seq Chunk }
87 deriving (Show, Generic, NFData)
88
89instance Eq Chunk => Eq Paragraph where
90 (==) = (==) `on` getChunks
91
92instance Monoid Paragraph where
93 mempty = Paragraph mempty
94 mappend a b = Paragraph $ (mappend `on` getChunks) a b
95
96instance Arbitrary Paragraph where
97 arbitrary = Paragraph <$> arbitrary
70 98
71instance FromJSON Paragraph where 99instance 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
77instance ToJSON Paragraph where 105instance 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
4name: thermoprint-spec 4name: thermoprint-spec
5version: 3.0.0 5version: 4.0.0
6synopsis: A specification of the API and the payload datatypes and associated utilities 6synopsis: A specification of the API and the payload datatypes and associated utilities
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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 @@
1From 480675cba32803ab74ec064e14ed6b2001c8e071 Mon Sep 17 00:00:00 2001 1From 86574dffb26128252159a6f25a3ea29be965047f Mon Sep 17 00:00:00 2001
2From: Heinrich Apfelmus <apfelmus@quantentunnel.de>
3Date: Fri, 27 May 2016 22:47:04 +0200
4Subject: [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
10diff --git a/src/Foreign/RemotePtr.hs b/src/Foreign/RemotePtr.hs
11index 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--
372.9.0
38
39
40From 0ed2c2ebb64b24fdcded4e273bfda1583763a815 Mon Sep 17 00:00:00 2001
2From: Gregor Kleen <gkleen@yggdrasil.li> 41From: Gregor Kleen <gkleen@yggdrasil.li>
3Date: Tue, 23 Feb 2016 18:14:48 +0000 42Date: Tue, 23 Feb 2016 18:14:48 +0000
4Subject: [PATCH 1/2] Switched to using location.host 43Subject: [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--
242.7.0 632.9.0
25 64
26 65
27From 52f45089ccf786c13d185faf1ad7436a63c13002 Mon Sep 17 00:00:00 2001 66From 4fb9b3304467a48d8ebeec85803464ec1a2aeeb6 Mon Sep 17 00:00:00 2001
28From: Gregor Kleen <gkleen@yggdrasil.li> 67From: Gregor Kleen <gkleen@yggdrasil.li>
29Date: Tue, 1 Mar 2016 00:22:01 +0100 68Date: Tue, 1 Mar 2016 00:22:01 +0100
30Subject: [PATCH 2/2] Now manipulating the location object 69Subject: [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--
1512.7.0 1902.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'
107morph = fmap Seq.fromList . mapM (\t -> Seq.singleton . Cooked <$> parse BlockCtx t) 107morph = fmap (Printout . Seq.fromList) . mapM (\t -> Paragraph . Seq.singleton . Cooked <$> parse BlockCtx t)
108 108
109parseDom :: DomTree -> ParseResult 109parseDom :: 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
24import Thermoprint.Printout 24import Thermoprint.Printout
25 25
26cobbcode :: Printout -> Either UnicodeException Text 26cobbcode :: Printout -> Either UnicodeException Text
27cobbcode (toList -> ps) = mconcat . intersperse "\n\n" <$> mapM handlePar ps 27cobbcode (toList . getParagraphs -> ps) = mconcat . intersperse "\n\n" <$> mapM handlePar ps
28 28
29handlePar :: Seq Chunk -> Either UnicodeException Text 29handlePar :: Paragraph -> Either UnicodeException Text
30handlePar (toList -> cs) = mconcat <$> mapM handleChunk cs 30handlePar (toList . getChunks -> cs) = mconcat <$> mapM handleChunk cs
31 31
32handleChunk :: Chunk -> Either UnicodeException Text 32handleChunk :: Chunk -> Either UnicodeException Text
33handleChunk (Cooked b) = Right $ handleBlock b 33handleChunk (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
55pOut :: Seq Block -> Printout 55pOut :: Seq Block -> Printout
56pOut = fmap (pure . Cooked) 56pOut = Printout . fmap (Paragraph . pure . Cooked)
57 57
58examples :: [(Text, Either BBCodeError (Seq Block))] 58examples :: [(Text, Either BBCodeError (Seq Block))]
59examples = [ ("Hello World!" 59examples = [ ("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
4name: thermoprint-bbcode 4name: thermoprint-bbcode
5version: 1.0.0 5version: 2.0.0
6synopsis: Parse bbcode for use in thermoprint 6synopsis: Parse bbcode for use in thermoprint
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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 ()
26import Paths_tprint (version) 26import Paths_tprint (version)
27import Data.Version (showVersion) 27import Data.Version (showVersion)
28 28
29import Data.Bifunctor (Bifunctor(..))
30
29data TPrint = TPrint 31data 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
150pTPrint :: Parser TPrint 152pTPrint :: Parser TPrint
151pTPrint = TPrint <$> option (eitherReader parseBaseUrl) (metavar "URL" <> long "baseurl" <> short 'u' <> help "Server to interact with" <> value (BaseUrl Http "localhost" 3000) <> showDefaultWith showBaseUrl) 153pTPrint = 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
4name: tprint 4name: tprint
5version: 1.0.0 5version: 2.0.0
6synopsis: A CLI for thermoprint-client 6synopsis: A CLI for thermoprint-client
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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
4name: thermoprint-webgui 4name: thermoprint-webgui
5version: 0.0.0 5version: 1.0.0
6synopsis: Threepenny interface for thermoprint-spec compliant servers 6synopsis: Threepenny interface for thermoprint-spec compliant servers
7-- description: 7-- description:
8homepage: http://dirty-haskell.org/tags/thermoprint.html 8homepage: 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