diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-20 19:57:15 +0000 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-20 19:57:15 +0000 |
commit | d27690786ed2056d64c882ac72825755110d4870 (patch) | |
tree | 513f2fda510e38e1a1c9bd90dd43bdba7f83bfea /server | |
parent | 47e346cdea8fdb158cd2942c614609c041936c9e (diff) | |
download | thermoprint-d27690786ed2056d64c882ac72825755110d4870.tar thermoprint-d27690786ed2056d64c882ac72825755110d4870.tar.gz thermoprint-d27690786ed2056d64c882ac72825755110d4870.tar.bz2 thermoprint-d27690786ed2056d64c882ac72825755110d4870.tar.xz thermoprint-d27690786ed2056d64c882ac72825755110d4870.zip |
Nonfunctional API framework for server
Diffstat (limited to 'server')
-rw-r--r-- | server/default-conf/Main.hs | 17 | ||||
-rw-r--r-- | server/src/Main.hs | 6 | ||||
-rw-r--r-- | server/src/Thermoprint/Server.hs | 166 | ||||
-rw-r--r-- | server/thermoprint-server.cabal | 25 | ||||
-rw-r--r-- | server/thermoprint-server.nix | 16 |
5 files changed, 198 insertions, 32 deletions
diff --git a/server/default-conf/Main.hs b/server/default-conf/Main.hs new file mode 100644 index 0000000..0aa7d91 --- /dev/null +++ b/server/default-conf/Main.hs | |||
@@ -0,0 +1,17 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
2 | |||
3 | module Main (main) where | ||
4 | |||
5 | import Thermoprint.Server | ||
6 | |||
7 | import Control.Monad.Trans.Resource | ||
8 | import Control.Monad.Logger | ||
9 | import Control.Monad.Reader | ||
10 | |||
11 | import Database.Persist.Sqlite | ||
12 | |||
13 | main :: IO () | ||
14 | main = thermoprintServer (Nat runSqlite) def | ||
15 | where | ||
16 | runSqlite :: ReaderT ConnectionPool (LoggingT (ResourceT IO)) a -> IO a | ||
17 | runSqlite = runResourceT . runStderrLoggingT . withSqlitePool ":memory:" 1 . runReaderT | ||
diff --git a/server/src/Main.hs b/server/src/Main.hs deleted file mode 100644 index e392fe1..0000000 --- a/server/src/Main.hs +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | module Main (main) where | ||
2 | |||
3 | import Thermoprint.Server | ||
4 | |||
5 | main :: IO () | ||
6 | main = thermoprintServer def | ||
diff --git a/server/src/Thermoprint/Server.hs b/server/src/Thermoprint/Server.hs index 9b8d719..4018d17 100644 --- a/server/src/Thermoprint/Server.hs +++ b/server/src/Thermoprint/Server.hs | |||
@@ -1,8 +1,20 @@ | |||
1 | {-# LANGUAGE RecordWildCards #-} | 1 | {-# LANGUAGE RecordWildCards #-} |
2 | {-# LANGUAGE EmptyDataDecls #-} | ||
3 | {-# LANGUAGE FlexibleContexts #-} | ||
4 | {-# LANGUAGE GADTs #-} | ||
5 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
6 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
7 | {-# LANGUAGE OverloadedStrings #-} | ||
8 | {-# LANGUAGE QuasiQuotes #-} | ||
9 | {-# LANGUAGE TemplateHaskell #-} | ||
10 | {-# LANGUAGE TypeFamilies #-} | ||
11 | {-# LANGUAGE OverloadedStrings #-} | ||
12 | {-# LANGUAGE TypeOperators #-} | ||
2 | 13 | ||
3 | module Thermoprint.Server | 14 | module Thermoprint.Server |
4 | ( thermoprintServer | 15 | ( thermoprintServer |
5 | , module Data.Default.Class | 16 | , module Data.Default.Class |
17 | , module Servant.Server.Internal.Enter | ||
6 | ) where | 18 | ) where |
7 | 19 | ||
8 | import Data.Default.Class | 20 | import Data.Default.Class |
@@ -11,42 +23,160 @@ import qualified Config.Dyre as Dyre | |||
11 | import System.IO (hPutStrLn, stderr) | 23 | import System.IO (hPutStrLn, stderr) |
12 | import System.Exit (exitFailure) | 24 | import System.Exit (exitFailure) |
13 | 25 | ||
14 | import Control.Monad ((<=<)) | 26 | import Control.Monad ((<=<), mapM_, liftM2) |
27 | import Prelude hiding ((.), id) | ||
28 | import Control.Category | ||
29 | |||
30 | import Control.Monad.Logger | ||
31 | import Control.Monad.Reader | ||
32 | import Control.Monad.Trans.Resource | ||
33 | import Control.Monad.Trans.Either | ||
34 | import Control.Monad.IO.Class | ||
35 | |||
36 | import Data.Functor.Compose | ||
37 | |||
38 | import Thermoprint.API hiding (JobId(..), DraftId(..)) | ||
39 | import qualified Thermoprint.API as API (JobId(..), DraftId(..)) | ||
40 | import Data.Set (Set) | ||
41 | import qualified Data.Set as Set | ||
42 | import Data.Sequence (Seq) | ||
43 | import qualified Data.Sequence as Seq | ||
15 | 44 | ||
16 | import qualified Network.Wai.Handler.Warp as Warp | 45 | import qualified Network.Wai.Handler.Warp as Warp |
17 | import Network.Wai (Application) | 46 | import Network.Wai (Application) |
18 | 47 | ||
48 | import Servant | ||
19 | import Servant.Server | 49 | import Servant.Server |
50 | import Servant.Server.Internal.Enter | ||
20 | 51 | ||
21 | import Thermoprint.API | 52 | import Database.Persist |
53 | import Database.Persist.Sql | ||
54 | import Database.Persist.TH | ||
22 | 55 | ||
23 | data Config = Config { dyreError :: Maybe String | 56 | data Config = Config { dyreError :: Maybe String |
24 | , warpSettings :: Warp.Settings | 57 | , warpSettings :: Warp.Settings |
25 | } | 58 | } |
26 | 59 | ||
27 | instance Default Config where | 60 | instance Default Config where |
28 | def = Config { dyreError = Nothing | 61 | def = Config { dyreError = Nothing |
29 | , warpSettings = Warp.defaultSettings | 62 | , warpSettings = Warp.defaultSettings |
30 | } | 63 | } |
31 | 64 | ||
32 | thermoprintServer :: Config -> IO () | 65 | |
33 | thermoprintServer = Dyre.wrapMain $ Dyre.defaultParams | 66 | share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| |
67 | Job | ||
68 | content Printout | ||
69 | Draft | ||
70 | content Printout | ||
71 | |] | ||
72 | |||
73 | |||
74 | thermoprintServer :: ( MonadLogger m | ||
75 | , MonadIO m | ||
76 | , MonadBaseControl IO m | ||
77 | , MonadReader ConnectionPool m | ||
78 | ) => (m :~> IO) -> Config -> IO () | ||
79 | thermoprintServer io = Dyre.wrapMain $ Dyre.defaultParams | ||
34 | { Dyre.projectName = "thermoprint-server" | 80 | { Dyre.projectName = "thermoprint-server" |
35 | , Dyre.realMain = realMain <=< handleDyreErrors | 81 | , Dyre.realMain = realMain <=< handleDyreErrors |
36 | , Dyre.showError = (\cfg msg -> cfg { dyreError = Just msg }) | 82 | , Dyre.showError = (\cfg msg -> cfg { dyreError = Just msg }) |
37 | } | 83 | } |
84 | where | ||
85 | handleDyreErrors cfg@(Config{..}) | ||
86 | | Just msg <- dyreError = do | ||
87 | hPutStrLn stderr msg | ||
88 | exitFailure | ||
89 | undefined | ||
90 | | otherwise = return cfg | ||
91 | |||
92 | realMain (Config{..}) = enter io $ do | ||
93 | runSqlPool' (runMigrationSilent migrateAll) >>= mapM_ $(logWarn) | ||
94 | liftIO . Warp.runSettings warpSettings . serve thermoprintAPI $ enter (hoistNat io) thermoprintServer' | ||
95 | |||
96 | |||
97 | runSqlPool' :: ( MonadBaseControl IO m | ||
98 | , MonadReader ConnectionPool m | ||
99 | ) => SqlPersistT m a -> m a | ||
100 | runSqlPool' a = runSqlPool a =<< ask | ||
101 | |||
102 | (<||>) :: Monad m => m a -> m b -> m (a :<|> b) | ||
103 | (<||>) = liftM2 (:<|>) | ||
104 | infixr 9 <||> | ||
105 | |||
106 | |||
107 | thermoprintServer' :: ( Monad m | ||
108 | ) => ServerT ThermoprintAPI (EitherT ServantErr m) | ||
109 | thermoprintServer' = listPrinters | ||
110 | :<|> queueJob <||> printerStatus | ||
111 | :<|> listJobs | ||
112 | :<|> getJob <||> jobStatus <||> getJobPrinter <||> deleteJob | ||
113 | :<|> (listDrafts :<|> addDraft) | ||
114 | :<|> updateDraft <||> getDraft <||> deleteDraft | ||
115 | |||
116 | |||
117 | listPrinters :: ( Monad m | ||
118 | ) => EitherT ServantErr m (Set PrinterId) | ||
119 | listPrinters = return Set.empty | ||
120 | |||
121 | queueJob :: ( Monad m | ||
122 | ) => PrinterId | ||
123 | -> Printout | ||
124 | -> EitherT ServantErr m API.JobId | ||
125 | queueJob = return undefined | ||
126 | |||
127 | printerStatus :: ( Monad m | ||
128 | ) => PrinterId | ||
129 | -> EitherT ServantErr m PrinterStatus | ||
130 | printerStatus = return undefined | ||
131 | |||
132 | listJobs :: ( Monad m | ||
133 | ) => Maybe PrinterId | ||
134 | -> Maybe API.JobId | ||
135 | -> Maybe API.JobId | ||
136 | -> EitherT ServantErr m (Seq API.JobId) | ||
137 | listJobs = return undefined | ||
138 | |||
139 | getJob :: ( Monad m | ||
140 | ) => API.JobId | ||
141 | -> EitherT ServantErr m Printout | ||
142 | getJob = return undefined | ||
143 | |||
144 | jobStatus :: ( Monad m | ||
145 | ) => API.JobId | ||
146 | -> EitherT ServantErr m JobStatus | ||
147 | jobStatus = return undefined | ||
148 | |||
149 | getJobPrinter :: ( Monad m | ||
150 | ) => API.JobId | ||
151 | -> EitherT ServantErr m PrinterId | ||
152 | getJobPrinter = return undefined | ||
153 | |||
154 | deleteJob :: ( Monad m | ||
155 | ) => API.JobId | ||
156 | -> EitherT ServantErr m () | ||
157 | deleteJob = return undefined | ||
158 | |||
159 | listDrafts :: ( Monad m | ||
160 | ) => EitherT ServantErr m (Set API.DraftId) | ||
161 | listDrafts = return undefined | ||
162 | |||
163 | addDraft :: ( Monad m | ||
164 | ) => Printout | ||
165 | -> EitherT ServantErr m API.DraftId | ||
166 | addDraft = return undefined | ||
38 | 167 | ||
39 | handleDyreErrors :: Config -> IO Config | 168 | updateDraft :: ( Monad m |
40 | handleDyreErrors cfg | 169 | ) => API.DraftId |
41 | | Just msg <- dyreError cfg = do | 170 | -> Printout |
42 | hPutStrLn stderr msg | 171 | -> EitherT ServantErr m () |
43 | exitFailure | 172 | updateDraft = return undefined |
44 | return undefined | ||
45 | | otherwise = return cfg | ||
46 | |||
47 | 173 | ||
48 | realMain :: Config -> IO () | 174 | getDraft :: ( Monad m |
49 | realMain cfg@(Config{..}) = Warp.runSettings warpSettings $ serve thermoprintAPI thermoprintServer' | 175 | ) => API.DraftId |
176 | -> EitherT ServantErr m Printout | ||
177 | getDraft = return undefined | ||
50 | 178 | ||
51 | thermoprintServer :: Server ThermoprintAPI | 179 | deleteDraft :: ( Monad m |
52 | thermoprintServer = undefined | 180 | ) => API.DraftId |
181 | -> EitherT ServantErr m () | ||
182 | deleteDraft = return undefined | ||
diff --git a/server/thermoprint-server.cabal b/server/thermoprint-server.cabal index c8586ae..0aa1870 100644 --- a/server/thermoprint-server.cabal +++ b/server/thermoprint-server.cabal | |||
@@ -16,16 +16,35 @@ build-type: Simple | |||
16 | -- extra-source-files: | 16 | -- extra-source-files: |
17 | cabal-version: >=1.10 | 17 | cabal-version: >=1.10 |
18 | 18 | ||
19 | executable thermoprint-server | 19 | library |
20 | main-is: Main.hs | 20 | exposed-modules: Thermoprint.Server |
21 | -- other-modules: | 21 | -- other-modules: |
22 | -- other-extensions: | 22 | -- other-extensions: |
23 | build-depends: base >=4.8 && <4.9 | 23 | build-depends: base >=4.8 && <5 |
24 | , thermoprint-spec ==3.0.* | 24 | , thermoprint-spec ==3.0.* |
25 | , dyre >=0.8.12 && <1 | 25 | , dyre >=0.8.12 && <1 |
26 | , data-default-class >=0.0.1 && <1 | 26 | , data-default-class >=0.0.1 && <1 |
27 | , wai >=3.0.4 && <4 | 27 | , wai >=3.0.4 && <4 |
28 | , servant-server >=0.4.4 && <1 | 28 | , servant-server >=0.4.4 && <1 |
29 | , warp >=3.1.9 && <4 | 29 | , warp >=3.1.9 && <4 |
30 | , persistent >=2.2 && <3 | ||
31 | , persistent-template >=2.1.4 && <3 | ||
32 | , transformers >=0.3.0 && <1 | ||
33 | , mtl >=2.2.1 && <3 | ||
34 | , resourcet >=1.1.7 && <2 | ||
35 | , monad-logger >=0.3.13 && <1 | ||
36 | , containers >=0.5.6 && <1 | ||
37 | , either >=4.4.1 && <5 | ||
30 | hs-source-dirs: src | 38 | hs-source-dirs: src |
39 | default-language: Haskell2010 | ||
40 | |||
41 | executable thermoprint-server | ||
42 | main-is: Main.hs | ||
43 | build-depends: base >=4.8 && <5 | ||
44 | , thermoprint-server -any | ||
45 | , persistent-sqlite >=2.2 && <3 | ||
46 | , mtl >=2.2.1 && <3 | ||
47 | , resourcet >=1.1.7 && <2 | ||
48 | , monad-logger >=0.3.13 && <1 | ||
49 | hs-source-dirs: default-conf | ||
31 | default-language: Haskell2010 \ No newline at end of file | 50 | default-language: Haskell2010 \ No newline at end of file |
diff --git a/server/thermoprint-server.nix b/server/thermoprint-server.nix index 7154dc3..c6a6224 100644 --- a/server/thermoprint-server.nix +++ b/server/thermoprint-server.nix | |||
@@ -1,15 +1,21 @@ | |||
1 | { mkDerivation, base, data-default-class, dyre, servant-server | 1 | { mkDerivation, base, containers, data-default-class, dyre, either |
2 | , stdenv, thermoprint-spec, wai, warp | 2 | , monad-logger, mtl, persistent, persistent-sqlite |
3 | , persistent-template, resourcet, servant-server, stdenv | ||
4 | , thermoprint-spec, transformers, wai, warp | ||
3 | }: | 5 | }: |
4 | mkDerivation { | 6 | mkDerivation { |
5 | pname = "thermoprint-server"; | 7 | pname = "thermoprint-server"; |
6 | version = "0.0.0"; | 8 | version = "0.0.0"; |
7 | src = ./.; | 9 | src = ./.; |
8 | isLibrary = false; | 10 | isLibrary = true; |
9 | isExecutable = true; | 11 | isExecutable = true; |
12 | libraryHaskellDepends = [ | ||
13 | base containers data-default-class dyre either monad-logger mtl | ||
14 | persistent persistent-template resourcet servant-server | ||
15 | thermoprint-spec transformers wai warp | ||
16 | ]; | ||
10 | executableHaskellDepends = [ | 17 | executableHaskellDepends = [ |
11 | base data-default-class dyre servant-server thermoprint-spec wai | 18 | base monad-logger mtl persistent-sqlite resourcet |
12 | warp | ||
13 | ]; | 19 | ]; |
14 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; | 20 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; |
15 | description = "Server for thermoprint-spec"; | 21 | description = "Server for thermoprint-spec"; |