aboutsummaryrefslogtreecommitdiff
path: root/tprint
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-03-01 06:25:23 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2016-03-01 06:25:23 +0100
commitfc83a7241e27574ef2bb81de206c59a9a854efe6 (patch)
treea6bd70a3560012b408128c2df947f3f49c7f57e0 /tprint
parentc5758391f793fc3d7d177bdacf79aac72da979d5 (diff)
downloadthermoprint-fc83a7241e27574ef2bb81de206c59a9a854efe6.tar
thermoprint-fc83a7241e27574ef2bb81de206c59a9a854efe6.tar.gz
thermoprint-fc83a7241e27574ef2bb81de206c59a9a854efe6.tar.bz2
thermoprint-fc83a7241e27574ef2bb81de206c59a9a854efe6.tar.xz
thermoprint-fc83a7241e27574ef2bb81de206c59a9a854efe6.zip
First work on argument parsing
Diffstat (limited to 'tprint')
-rw-r--r--tprint/src/Main.hs164
-rw-r--r--tprint/tprint.cabal4
-rw-r--r--tprint/tprint.nix7
3 files changed, 171 insertions, 4 deletions
diff --git a/tprint/src/Main.hs b/tprint/src/Main.hs
index e9e1deb..e8d4670 100644
--- a/tprint/src/Main.hs
+++ b/tprint/src/Main.hs
@@ -1,2 +1,164 @@
1{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE StandaloneDeriving #-}
3{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
4
5import Data.Map (Map)
6import qualified Data.Map as Map
7import Data.Sequence (Seq)
8import qualified Data.Sequence as Seq
9import Data.Text (Text)
10import qualified Data.Text as T
11import Data.Time
12
13import Data.Foldable
14import Data.Char
15import Text.Read
16import Data.Maybe
17import Data.List
18
19import GHC.Generics (Generic)
20
21import Text.Show.Pretty (Value, PrettyVal(..), dumpStr)
22import qualified Text.Show.Pretty as PShow (Value(..))
23
24import Thermoprint.Client
25import Options.Applicative
26
27import Debug.Trace
28
29instance PrettyVal Scheme
30instance PrettyVal BaseUrl
31instance PrettyVal PrinterId
32instance PrettyVal JobId
33instance PrettyVal DraftId
34instance PrettyVal a => PrettyVal (Range a)
35
36instance PrettyVal UTCTime where
37 prettyVal = PShow.String . formatTime defaultTimeLocale "%Z %F %X"
38
39instance PrettyVal Text where
40 prettyVal = prettyVal . T.unpack
41
42data TPrint = TPrint
43 { baseUrl :: BaseUrl
44 , dryRun :: Bool
45 , output :: Output
46 , operation :: Operation
47 }
48 deriving (Show, Generic, PrettyVal)
49
50data Operation
51 = Printers
52 | Jobs
53 { printer :: Maybe PrinterId
54 , jobRange :: Maybe (Range JobId)
55 , timeRange :: Maybe (Range UTCTime)
56 }
57 | JobCreate
58 { printer :: Maybe PrinterId
59 , input :: Input
60 }
61 | Job { jobId :: JobId }
62 | JobStatus { jobId :: JobId }
63 | JobDelete { jobId :: JobId }
64 | Drafts
65 | DraftCreate
66 { draftTitle :: Maybe DraftTitle
67 , input :: Input
68 }
69 | DraftReplace
70 { draftId :: DraftId
71 , draftTitle :: Maybe DraftTitle
72 , input :: Input
73 }
74 | Draft { draftId :: DraftId }
75 | DraftDelete { draftId :: DraftId }
76 | DraftPrint
77 { draftId :: DraftId
78 , printer :: Maybe PrinterId
79 }
80 deriving (Show, Generic, PrettyVal)
81
82type Input = (Format, Source)
83type Output = (Format, Sink )
84
85data Format = Human | BBCode | Internal | JSON
86 deriving (Enum, Bounded, Show, Read, Generic, PrettyVal)
87
88data Source = Stdin | ReadFile FilePath
89 deriving (Show, Generic, PrettyVal)
90
91data Sink = Stdout | WriteFile FilePath
92 deriving (Show, Generic, PrettyVal)
93
94cmdPrinters :: ParserInfo Operation
95cmdPrinters = info cmdPrinters' $ mconcat [ header "List all available printers"
96 ]
97 where cmdPrinters' = pure Printers
98
99cmdJobs :: ParserInfo Operation
100cmdJobs = info cmdJobs' $ mconcat [ header "List printjobs"
101 ]
102 where
103 cmdJobs' = Jobs
104 <$> optional (option (PrinterId <$> auto) $ metavar "PRINTER" <> long "printer" <> short 'p' <> help "List only jobs associated with printer #PRINTER")
105 <*> pRange (JobId <$> auto) (metavar "JOB") (long "min-job" <> short 'j' <> help "List only jobs with id greater than or equal to JOB") (long "max-job" <> short 'J' <> help "List only jobs with id less than or equal to JOB")
106 <*> pRange rTime (metavar "TIME") (long "min-time" <> short 't' <> help "List only jobs created after or at TIME") (long "max-time" <> short 'T' <> help "List only jobs created before or at TIME")
107
108pOperation :: Parser Operation
109pOperation = hsubparser $ mconcat [ command "printers" cmdPrinters
110 , command "jobs" cmdJobs
111 ]
112
113pTPrint :: Parser TPrint
114pTPrint = TPrint <$> option (eitherReader parseBaseUrl) (metavar "URL" <> long "baseurl" <> short 'u' <> help "Server to interact with" <> value (BaseUrl Http "localhost" 3000) <> showDefaultWith showBaseUrl)
115 <*> switch (long "dry-run" <> short 'n' <> help "Don't send any requests that would be expected to change the servers state" <> showDefault)
116 <*> pOutput
117 <*> pOperation
118
119pOutput :: Parser Output
120pOutput = (,) <$> pOutputFormat <*> pSink
121 where
122 pOutputFormat = option ciAuto $ metavar "FORMAT" <> long "output-format" <> short 'O' <> help ("Format to use for all output (possible values: " ++ show ([minBound..maxBound] :: [Format]) ++ ")") <> value Human <> showDefault
123 pSink = option rSink $ metavar "PATH" <> long "output" <> short 'o' <> help "Send output to PATH (`-' means stdout)" <> value Stdout <> showDefault
124 rSink = rSink' <$> str
125 where
126 rSink' "-" = Stdout
127 rSink' x = WriteFile x
128
129ciAuto :: (Read a, Show a) => ReadM a
130ciAuto = eitherReader rRep'
131 where
132 rRep' str = case mapMaybe readMaybe $ cases str of
133 [] -> Left $ "Could not parse `" ++ str ++ "'"
134 [x] -> Right x
135 xs -> Left $ "Ambiguous parse for `" ++ str ++ "': " ++ show xs
136 cases [] = []
137 cases (c:cs) = [(c':cs') | c' <- [toLower c, toUpper c], cs' <- cases cs]
138
139rTime :: ReadM UTCTime
140rTime = eitherReader rTime'
141 where
142 rTime' str = maybe (Left $ "Could not parse `" ++ str ++ "' as a specification of time -- try the output of `date -u +'%Y-%m-%d %H:%M:%S' \"" ++ str ++ "\"`") Right
143 . foldr (<|>) Nothing
144 $ map (flip (parseTimeM True defaultTimeLocale) str) ( "%c" : "%s" : perms' [ [time, date, timezone] | time <- ["%T", "%X", "%I:%M:%S", "%r", "%X%Q", "%I:%M:%S%Q %p"], date <- ["%x", "%F"], timezone <- ["%z", "%Z"]] )
145 perms' :: [[String]] -> [String]
146 perms' = map unwords . concatMap subsequences . concatMap permutations
147
148pRange :: ReadM a
149 -> Mod OptionFields a -- ^ Modifiers applied to both min & max
150 -> Mod OptionFields a -- ^ Modifiers for minimum
151 -> Mod OptionFields a -- ^ Modifiers for maximum
152 -> Parser (Maybe (Range a))
153pRange r both min max = toRange <$> optional (option r (both <> min)) <*> optional (option r (both <> max))
154 where
155 toRange Nothing Nothing = Nothing
156 toRange (Just min) Nothing = Just $ Min min
157 toRange Nothing (Just max) = Just $ Max max
158 toRange (Just min) (Just max) = Just $ min `Through` max
159
1main :: IO () 160main :: IO ()
2main = undefined 161main = customExecParser (prefs $ showHelpOnError) (info pTPrint $ header "tprint - A cli interface to Thermoprint.Client") >>= tprint
162
163tprint :: TPrint -> IO ()
164tprint = putStrLn . dumpStr -- *DEBUG*
diff --git a/tprint/tprint.cabal b/tprint/tprint.cabal
index e7a5797..d61ea01 100644
--- a/tprint/tprint.cabal
+++ b/tprint/tprint.cabal
@@ -24,6 +24,10 @@ executable tprint
24 , thermoprint-bbcode >=1.0.0 && <2 24 , thermoprint-bbcode >=1.0.0 && <2
25 , thermoprint-client ==0.0.* 25 , thermoprint-client ==0.0.*
26 , optparse-applicative >=0.12.1 && <1 26 , optparse-applicative >=0.12.1 && <1
27 , containers >=0.5.6 && <1
28 , time >=1.5.0 && <2
29 , pretty-show >=1.6.9 && <2
30 , text -any
27 hs-source-dirs: src 31 hs-source-dirs: src
28 default-language: Haskell2010 32 default-language: Haskell2010
29 ghc-options: -Wall \ No newline at end of file 33 ghc-options: -Wall \ No newline at end of file
diff --git a/tprint/tprint.nix b/tprint/tprint.nix
index 413774a..9954b02 100644
--- a/tprint/tprint.nix
+++ b/tprint/tprint.nix
@@ -1,5 +1,5 @@
1{ mkDerivation, base, optparse-applicative, stdenv 1{ mkDerivation, base, containers, optparse-applicative, pretty-show
2, thermoprint-bbcode, thermoprint-client 2, stdenv, thermoprint-bbcode, thermoprint-client, time
3}: 3}:
4mkDerivation { 4mkDerivation {
5 pname = "tprint"; 5 pname = "tprint";
@@ -8,7 +8,8 @@ mkDerivation {
8 isLibrary = false; 8 isLibrary = false;
9 isExecutable = true; 9 isExecutable = true;
10 executableHaskellDepends = [ 10 executableHaskellDepends = [
11 base optparse-applicative thermoprint-bbcode thermoprint-client 11 base containers optparse-applicative pretty-show thermoprint-bbcode
12 thermoprint-client time
12 ]; 13 ];
13 homepage = "http://dirty-haskell.org/tags/thermoprint.html"; 14 homepage = "http://dirty-haskell.org/tags/thermoprint.html";
14 description = "A CLI for thermoprint-client"; 15 description = "A CLI for thermoprint-client";