qr-imager 1.0.1.8 → 2.0.0.0
raw patch · 8 files changed
+36/−180 lines, 8 filesdep +binarydep −aesondep −optparse-applicativedep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: binary
Dependencies removed: aeson, optparse-applicative
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.QRCodes.Exe: Input :: Com
- Data.QRCodes.Exe: Output :: Com
- Data.QRCodes.Exe: Prog :: Com -> Bool -> Bool -> String -> Prog
- Data.QRCodes.Exe: [cmd] :: Prog -> Com
- Data.QRCodes.Exe: [file] :: Prog -> String
- Data.QRCodes.Exe: [secured] :: Prog -> Bool
- Data.QRCodes.Exe: [verify] :: Prog -> Bool
- Data.QRCodes.Exe: act :: Prog -> IO ()
- Data.QRCodes.Exe: data Com
- Data.QRCodes.Exe: data Prog
- Data.QRCodes.Exe: exec :: IO ()
- Data.QRCodes.Exe: program :: Parser Prog
- Data.QRCodes: createQRCode :: (ToJSON a) => a -> FilePath -> IO ()
+ Data.QRCodes: createQRCode :: (Binary a) => a -> FilePath -> IO ()
- Data.QRCodes: createSecureQRCode :: (ToJSON a) => a -> FilePath -> FilePath -> IO ()
+ Data.QRCodes: createSecureQRCode :: (Binary a) => a -> FilePath -> FilePath -> IO ()
- Data.QRCodes: createSecureQRCode' :: (ToJSON a) => a -> (PublicKey, PrivateKey) -> FilePath -> IO ()
+ Data.QRCodes: createSecureQRCode' :: (Binary a) => a -> (PublicKey, PrivateKey) -> FilePath -> IO ()
- Data.QRCodes: readQRStrSec :: (FromJSON a) => FilePath -> FilePath -> IO a
+ Data.QRCodes: readQRStrSec :: (Binary a) => FilePath -> FilePath -> IO a
- Data.QRCodes: readQRStrSec' :: (FromJSON a) => FilePath -> (PublicKey, PrivateKey) -> IO a
+ Data.QRCodes: readQRStrSec' :: (Binary a) => FilePath -> (PublicKey, PrivateKey) -> IO a
- Data.QRCodes.Image: objToImg :: (ToJSON a) => a -> IO (Image Word8)
+ Data.QRCodes.Image: objToImg :: (Binary a) => a -> IO (Image Word8)
- Data.QRCodes.Image: objToImgSec :: (ToJSON a) => a -> FilePath -> IO (Image Word8)
+ Data.QRCodes.Image: objToImgSec :: (Binary a) => a -> FilePath -> IO (Image Word8)
- Data.QRCodes.Image: objToImgSec' :: (ToJSON a) => a -> (PublicKey, PrivateKey) -> IO (Image Word8)
+ Data.QRCodes.Image: objToImgSec' :: (Binary a) => a -> (PublicKey, PrivateKey) -> IO (Image Word8)
Files
- README.md +2/−12
- cabal.project.local +3/−0
- qr-imager.cabal +9/−10
- src/Data/QRCodes.hs +8/−8
- src/Data/QRCodes/Exe.hs +0/−66
- src/Data/QRCodes/Image.hs +9/−8
- src/Data/QRCodes/Utils.hs +2/−2
- stack.yaml +3/−74
README.md view
@@ -1,26 +1,16 @@ # QR Imager Library+ [](https://travis-ci.org/vmchale/QR-writer) This is a library to generate `.png` files from QR codes. ## Dependencies-The library depends on the C library [libqrencode](https://github.com/fukuchi/libqrencode) which you will need to install separately, as well as the C library `Zbar` from [here](https://github.com/ZBar/ZBar). You should also be able to get them from your distro. +The library depends on the C library [libqrencode](https://github.com/fukuchi/libqrencode) which you will need to install separately, as well as the command-line tool `Zbar` from [here](https://github.com/ZBar/ZBar). You should also be able to get them from your distro. ## Library The library can be used via the exported functions `createQRCode`, `byteStringToQR` and `readQRString`, plus their signed counterparts. The first two export to ".png" while the third can be used on any image format `Zbar` supports. The functions `bsToImg` and `objToImg` output JuicyPixels images for your further manipulation.--## Executable--### Installation-For building haskell, the best tool is currently [http://haskellstack.org](stack). Install it, and then type--```-stack install --install-ghc-```--in the appropriate directory, and it will be installed to your path. ### Use
+ cabal.project.local view
@@ -0,0 +1,3 @@+-- constraints: qr-imager +development+tests: true+documentation: true
qr-imager.cabal view
@@ -1,6 +1,6 @@-cabal-version: >=1.10+cabal-version: 1.18 name: qr-imager-version: 1.0.1.8+version: 2.0.0.0 license: BSD3 license-file: LICENSE copyright: Copyright: (c) 2016-2018 Vanessa McHale@@ -8,14 +8,15 @@ author: Vanessa McHale stability: stable homepage: https://github.com/vmchale/QRImager#readme-synopsis: Library to generate QR codes from bytestrings and objects+synopsis: Library to generate images. description:- Please see README.md-category: Data+ Library for generating images containing QR codes, from bytestrings and objects.+category: Data, QR, Image build-type: Simple extra-source-files:- README.md stack.yaml+ cabal.project.local+extra-doc-files: README.md source-repository head type: git@@ -24,7 +25,6 @@ library exposed-modules: Data.QRCodes- Data.QRCodes.Exe Data.QRCodes.Image Data.QRCodes.Signature pkgconfig-depends: libqrencode -any@@ -33,8 +33,8 @@ Data.QRCodes.Utils default-language: Haskell2010 build-depends:- base >=4.9 && <5,- aeson -any,+ base >=4.8 && <5,+ binary -any, JuicyPixels -any, vector -any, bytestring -any,@@ -44,7 +44,6 @@ directory -any, haskell-qrencode -any, process -any,- optparse-applicative -any, split -any test-suite test-lib
src/Data/QRCodes.hs view
@@ -17,7 +17,7 @@ import Codec.Picture.Png (writePng) import Control.Applicative ((<$>)) import Crypto.PubKey.RSA-import Data.Aeson+import Data.Binary import qualified Data.ByteString.Char8 as BS import Data.ByteString.Lazy (toStrict) import qualified Data.ByteString.Lazy.Char8 as BSL@@ -47,17 +47,17 @@ byteStringToQRSec' string key filepath = flip byteStringToQR filepath =<< (fmap preserveUpper . flip mkSig key) string -- | Creates a signed QR code from an object that is part of the ToJSON class-createSecureQRCode :: (ToJSON a) => a -> FilePath -> FilePath -> IO ()+createSecureQRCode :: (Binary a) => a -> FilePath -> FilePath -> IO () createSecureQRCode object = byteStringToQRSec (toStrict $ encode object) -- | Creates a signed QR code from an object that is part of the ToJSON class-createSecureQRCode' :: (ToJSON a) => a -> (PublicKey, PrivateKey) -> FilePath -> IO ()+createSecureQRCode' :: (Binary a) => a -> (PublicKey, PrivateKey) -> FilePath -> IO () createSecureQRCode' object = byteStringToQRSec' (toStrict $ encode object) -- | Creates a QR code from an object that is part of the ToJSON class -- -- > createQRCode userRecord "user-231.png"-createQRCode :: (ToJSON a) => a -> FilePath -> IO ()+createQRCode :: (Binary a) => a -> FilePath -> IO () createQRCode object filepath = let input = toStrict $ encode object in byteStringToQR input filepath -- | Create a QR code, writing an image to the given 'FilePath'@@ -73,13 +73,13 @@ -- | given a filepath pointing to a QR code, get the contents & verify signature with the keyfile -- -- > readQRStrSec "output.png" ".key.hk"-readQRStrSec :: (FromJSON a) => FilePath -> FilePath -> IO a-readQRStrSec filepath keyfile = fromJust . decode . BSL.pack <$> do+readQRStrSec :: (Binary a) => FilePath -> FilePath -> IO a+readQRStrSec filepath keyfile = decode . BSL.pack <$> do enc <- map toLower . init . drop 8 . view _2 <$> readCreateProcessWithExitCode (shell $ "zbarimg " ++ filepath) "" fmap (liftEither BS.unpack) . flip checkSigFile keyfile . resolveUpper $ BS.pack enc -- | Read an image containing a QR code, decode and verify the signature using the given key.-readQRStrSec' :: (FromJSON a) => FilePath -> (PublicKey, PrivateKey) -> IO a-readQRStrSec' filepath key = fromJust . decode . BSL.pack <$> do+readQRStrSec' :: (Binary a) => FilePath -> (PublicKey, PrivateKey) -> IO a+readQRStrSec' filepath key = decode . BSL.pack <$> do enc <- map toLower . init . drop 8 . view _2 <$> readCreateProcessWithExitCode (shell $ "zbarimg " ++ filepath) "" fmap (liftEither BS.unpack) . flip checkSig key . resolveUpper $ BS.pack enc
− src/Data/QRCodes/Exe.hs
@@ -1,66 +0,0 @@--- | Parse options applicatively and read or write secure or non-secure QR codes.-module Data.QRCodes.Exe where--import Data.Aeson-import qualified Data.ByteString as B-import Data.QRCodes-import Data.Semigroup-import Options.Applicative-import System.Environment (getArgs)---- | Data type for the executable comprising the command, whether to sign, whether to verify it worked, and the output filename-data Prog = Prog { cmd :: Com- , secured :: Bool- , verify :: Bool- , file :: String}---- | Command is either read or write-data Com = Input | Output---- | main exec function-exec :: IO ()-exec = execParser full >>= act- where- full = info (helper <*> program)- ( fullDesc- <> progDesc "Read/Write QR Codes with files"- <> header "qrpipe - QR utilities made in Haskell" )---- | Takes a `Prog` and returns the appropriate IO action-act :: Prog -> IO ()-act (Prog Output True True filepath) = do- pipeIn <- getContents- createSecureQRCode pipeIn ".key.hk" filepath- (readQRStrSec filepath ".key.hk" :: IO String) >>= print-act (Prog Output False True filepath) = do- pipeIn <- B.getContents- byteStringToQR pipeIn filepath- readQRString filepath >>= print-act (Prog Output True False filepath) = do- pipeIn <- getContents- createSecureQRCode pipeIn ".key.hk" filepath-act (Prog Output False False filepath) = do- pipeIn <- B.getContents- byteStringToQR pipeIn filepath-act (Prog Input True _ filepath) =- (readQRStrSec filepath ".key.hk" :: IO String) >>= print-act (Prog Input False _ filepath) =- readQRString filepath >>= print---- | Parser for the command line-program :: Parser Prog-program = Prog- <$> subparser- ( command "write" (info (pure Output)- ( progDesc "Create a QR Code from stdin" ))- <> command "read" (info (pure Input)- ( progDesc "Read a QR code from file" )))- <*> switch- ( long "signed"- <> short 's'- <> help "Whether to sign the QR code" )- <*> switch- ( long "verify"- <> short 'v'- <> help "Attempt to read the resultant file?" )- <*> argument str (metavar "FILE")
src/Data/QRCodes/Image.hs view
@@ -1,6 +1,6 @@ -- | A few functions to deal with the image itself-module Data.QRCodes.Image (-- * Functions to convert to JuicyPixels `Image`- bsToImg+module Data.QRCodes.Image ( -- * Functions to convert to JuicyPixels `Image`+ bsToImg , objToImg -- * Functions to sign and convert to `Image` , bsToImgSec@@ -11,8 +11,9 @@ ) where import Codec.Picture.Types as T+import Control.Monad import Crypto.PubKey.RSA-import Data.Aeson+import Data.Binary import qualified Data.ByteString as BS import Data.ByteString.Lazy (toStrict) import Data.QRCode@@ -36,11 +37,11 @@ bsToImgSec' string key = bsToImg =<< (fmap preserveUpper . flip mkSig key) string -- | Encode an object as a JuicyPixels `Image` with a key in a given file.-objToImgSec :: (ToJSON a) => a -> FilePath -> IO (T.Image Word8)+objToImgSec :: (Binary a) => a -> FilePath -> IO (T.Image Word8) objToImgSec obj = bsToImgSec (toStrict $ encode obj) -- | Encode an object as a JuicyPixels `Image` with a key.-objToImgSec' :: (ToJSON a) => a -> (PublicKey, PrivateKey) -> IO (T.Image Word8)+objToImgSec' :: (Binary a) => a -> (PublicKey, PrivateKey) -> IO (T.Image Word8) objToImgSec' obj = bsToImgSec' (toStrict $ encode obj) -- | Create a JuicyPixels `Image` from a `ByteString`@@ -51,14 +52,14 @@ pure $ encodePng qrMatrix -- | Encode an object as a JuicyPixels `Image`-objToImg :: (ToJSON a) => a -> IO (T.Image Word8)+objToImg :: (Binary a) => a -> IO (T.Image Word8) objToImg obj = let input = toStrict $ encode obj in bsToImg input -- | Encode a JuicyPixels `Image` given a matrix encodePng :: [[Word8]] -> T.Image Word8 encodePng matrix = Image dim dim vector where dim = P.length matrix- vector = V.map ((*255) . swapWord) $ V.fromList $ P.concat matrix+ vector = V.map ((*255) . swapWord) $ V.fromList $ join matrix -- | To help scale the image up, e.g. --@@ -66,4 +67,4 @@ -- -- to scale @smallMatrix :: [[Word8]]@ by a factor of 8 fattenList :: Int -> [a] -> [a]-fattenList i l = P.concat $ P.foldr ((:) . P.replicate i) [] l+fattenList = (=<<) . replicate
src/Data/QRCodes/Utils.hs view
@@ -1,5 +1,5 @@ -- | Miscellaneous helper functions that don't fit anywhere else-module Data.QRCodes.Utils where+module Data.QRCodes.Utils (preserveUpper, resolveUpper, swapWord, liftEither) where import qualified Data.ByteString.Char8 as BS import Data.Char (toLower, toUpper)@@ -24,7 +24,7 @@ lift :: (String -> String) -> (BS.ByteString -> BS.ByteString) lift f = BS.pack . f . BS.unpack --- | helper function to life Either values to IO in our case+-- | helper function to lift Either values to IO in our case liftEither :: (Show b, Monad m) => (t -> m a) -> Either b t -> m a liftEither = either (error . show)
stack.yaml view
@@ -1,75 +1,4 @@-# This file was automatically generated by 'stack init'-#-# Some commonly used options have been documented as comments in this file.-# For advanced use and comprehensive documentation of the format, please see:-# http://docs.haskellstack.org/en/stable/yaml_configuration/--# A warning or info to be displayed to the user on config load.-user-message: ! 'Warning (added by new or init): Specified resolver could not satisfy- all dependencies. Some external packages have been added as dependencies.-- You can suppress this message by removing it from stack.yaml--'--# Resolver to choose a 'specific' stackage snapshot or a compiler version.-# A snapshot resolver dictates the compiler version and the set of packages-# to be used for project dependencies. For example:-#-# resolver: lts-3.5-# resolver: nightly-2015-09-21-# resolver: ghc-7.10.2-# resolver: ghcjs-0.1.0_ghc-7.10.2-# resolver:-# name: custom-snapshot-# location: "./custom-snapshot.yaml"-resolver: lts-8.15--# User packages to be built.-# Various formats can be used as shown in the example below.-#-# packages:-# - some-directory-# - https://example.com/foo/bar/baz-0.0.2.tar.gz-# - location:-# git: https://github.com/commercialhaskell/stack.git-# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a-# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a-# extra-dep: true-# subdirs:-# - auto-update-# - wai-#-# A package marked 'extra-dep: true' will only be built if demanded by a-# non-dependency (i.e. a user package), and its test suites and benchmarks-# will not be run. This is useful for tweaking upstream packages.-packages:-- '.'-# Dependency packages to be pulled from upstream that are not in the resolver-# (e.g., acme-missiles-0.3)+---+resolver: lts-11.4 extra-deps:-- haskell-qrencode-1.0.4--# Override default flag values for local packages and extra-deps-flags: {}--# Extra package databases containing global packages-extra-package-dbs: []--# Control whether we use the GHC we find on the path-# system-ghc: true-#-# Require a specific version of stack, using version ranges-# require-stack-version: -any # Default-# require-stack-version: ">=1.4"-#-# Override the architecture used by stack, especially useful on Windows-# arch: i386-# arch: x86_64-#-# Extra directories used by stack for building-# extra-include-dirs: [/path/to/dir]-# extra-lib-dirs: [/path/to/dir]-#-# Allow a newer minor version of GHC than the snapshot specifies-# compiler-check: newer-minor+ - haskell-qrencode-1.0.4