aboutsummaryrefslogtreecommitdiff
path: root/servant
diff options
context:
space:
mode:
Diffstat (limited to 'servant')
-rw-r--r--servant/api/Thermoprint/Api.hs28
-rw-r--r--servant/servant.cabal31
-rw-r--r--servant/servant.nix5
-rw-r--r--servant/src/Main.hs71
4 files changed, 129 insertions, 6 deletions
diff --git a/servant/api/Thermoprint/Api.hs b/servant/api/Thermoprint/Api.hs
new file mode 100644
index 0000000..bd5744b
--- /dev/null
+++ b/servant/api/Thermoprint/Api.hs
@@ -0,0 +1,28 @@
1{-# LANGUAGE DataKinds, TypeOperators, DeriveGeneric #-}
2
3module Thermoprint.Api
4 ( ThermoprintApi
5 ) where
6
7import Thermoprint
8import Data.Aeson
9import Servant.API
10import qualified Data.Text.Lazy as Text
11import qualified Data.ByteString.Lazy.Char8 as ByteString
12import Data.ByteString.Lazy.Char8 (ByteString)
13import GHC.Generics
14
15import Control.Monad
16
17instance ToJSON ByteString where
18 toJSON = toJSON . Text.pack . ByteString.unpack
19instance FromJSON ByteString where
20 parseJSON value = (ByteString.pack . Text.unpack) `liftM` parseJSON value
21
22instance ToJSON c => ToJSON (Inline c)
23instance FromJSON c => FromJSON (Inline c)
24
25instance ToJSON c => ToJSON (Block c)
26instance FromJSON c => FromJSON (Block c)
27
28type ThermoprintApi = "print" :> Capture "printerId" Integer :> ReqBody '[JSON] (Block String) :> Post '[JSON] ()
diff --git a/servant/servant.cabal b/servant/servant.cabal
index b509dbc..b877196 100644
--- a/servant/servant.cabal
+++ b/servant/servant.cabal
@@ -16,11 +16,36 @@ build-type: Simple
16-- extra-source-files: 16-- extra-source-files:
17cabal-version: >=1.10 17cabal-version: >=1.10
18 18
19library
20 exposed-modules: Thermoprint.Api
21 hs-source-dirs: api
22 default-language: Haskell2010
23 other-extensions: DataKinds
24 , TypeOperators
25 , DeriveGeneric
26 build-depends: base >=4.8 && <4.9
27 , thermoprint
28 , aeson >=0.9.0 && <0.10
29 , servant >=0.4.4 && <0.5
30 , text >=1.2.1 && <4.5
31 , bytestring >=0.10.6 && <0.11
32
19executable thermoprint 33executable thermoprint
20 main-is: Main.hs 34 main-is: Main.hs
35 hs-source-dirs: src
36 default-language: Haskell2010
21 -- other-modules: 37 -- other-modules:
22 -- other-extensions: 38 other-extensions: RecordWildCards
39 , OverloadedStrings
23 build-depends: base >=4.8 && <4.9 40 build-depends: base >=4.8 && <4.9
24 , thermoprint 41 , thermoprint
25 hs-source-dirs: src 42 , thermoprint-servant
26 default-language: Haskell2010 \ No newline at end of file 43 , aeson >=0.9.0 && <0.10
44 , wai >=3.0.3 && <3.1
45 , servant-server >=0.4.4 && <0.5
46 , warp >=3.1.3 && <3.2
47 , text >=1.2.1 && <1.3
48 , bytestring >=0.10.6 && <0.11
49 , either >=4.4.1 && <4.5
50 , optparse-applicative >=0.11.0 && <0.12
51 , transformers >=0.4.2 && <0.5 \ No newline at end of file
diff --git a/servant/servant.nix b/servant/servant.nix
index 6c90a4f..a84fc77 100644
--- a/servant/servant.nix
+++ b/servant/servant.nix
@@ -2,16 +2,17 @@
2, stdenv 2, stdenv
3, base 3, base
4, thermoprint 4, thermoprint
5, aeson, wai, servant-server, warp, optparse-applicative
5}: 6}:
6 7
7mkDerivation { 8mkDerivation {
8 pname = "thermoprint-servant"; 9 pname = "thermoprint-servant";
9 version = "0.0.0"; 10 version = "0.0.0";
10 src = ./.; 11 src = ./.;
11 isLibrary = false; 12 isLibrary = true;
12 isExecutable = true; 13 isExecutable = true;
13 executableHaskellDepends = [ 14 executableHaskellDepends = [
14 base thermoprint 15 base thermoprint aeson wai servant-server warp optparse-applicative
15 ]; 16 ];
16 homepage = "git://git.yggdrasil.li/thermoprint"; 17 homepage = "git://git.yggdrasil.li/thermoprint";
17 description = "Server for interfacing to cheap thermoprinters"; 18 description = "Server for interfacing to cheap thermoprinters";
diff --git a/servant/src/Main.hs b/servant/src/Main.hs
index e9e1deb..9d88559 100644
--- a/servant/src/Main.hs
+++ b/servant/src/Main.hs
@@ -1,2 +1,71 @@
1{-# LANGUAGE RecordWildCards, OverloadedStrings #-}
2
3import Thermoprint
4import Thermoprint.Api
5
6import Data.Aeson
7import Network.Wai
8import Network.Wai.Handler.Warp
9import Servant
10import qualified Data.Text.Lazy as Text
11import qualified Data.ByteString.Lazy.Char8 as ByteString
12import Data.ByteString.Lazy.Char8 (ByteString)
13import GHC.Generics
14
15import Control.Monad
16import Control.Monad.IO.Class
17import Control.Monad.Trans.Either
18
19import Options.Applicative
20
21import System.IO
22
23server :: Options -> Integer -> Block String -> EitherT ServantErr IO ()
24server Options{..} printerNo printOut = do
25 printerPath <- case genericIndex printers printerNo of
26 Just path -> return path
27 Nothing -> left $ err404 { errBody = "printerId out of bounds" }
28 liftIO $ withFile printerPath WriteMode doPrint
29 where
30 doPrint handle = do
31 hSetBuffering handle NoBuffering
32 ByteString.hPut handle $ render' printOut
33 genericIndex :: Integral i => [a] -> i -> Maybe a
34 genericIndex (x:_) 0 = Just x
35 genericIndex (_:xs) n
36 | n > 0 = genericIndex xs (n - 1)
37 | otherwise = Nothing
38 genericIndex _ _ = Nothing
39
40data Options = Options
41 { port :: Int
42 , printers :: [FilePath]
43 }
44
45options :: Parser Options
46options = Options
47 <$> option auto (
48 long "port"
49 <> short 'p'
50 <> metavar "PORT"
51 <> help "The port we'll run the server on"
52 <> value 8080
53 <> showDefault
54 )
55 <*> some (strArgument (
56 metavar "PATH [...]"
57 <> help "Path to one of the printers to use"
58 ))
59
60thermoprintApi :: Proxy ThermoprintApi
61thermoprintApi = Proxy
62
1main :: IO () 63main :: IO ()
2main = undefined 64main = do
65 execParser opts >>= main'
66 where
67 opts = info (helper <*> options) (
68 fullDesc
69 <> header "thermoprint-servant - A REST server for interacting with a cheap thermoprinter"
70 )
71 main' args@(Options{..}) = run port $ serve thermoprintApi (server args)