Skip to content

Instantly share code, notes, and snippets.

@tmhedberg
Last active December 17, 2015 08:19
Show Gist options
  • Save tmhedberg/5579391 to your computer and use it in GitHub Desktop.
Save tmhedberg/5579391 to your computer and use it in GitHub Desktop.
Convert PMA commodity/variety spreadsheet from CSV to JSON
#!/usr/bin/runhaskell
{-
- Convert PMA commodity/variety spreadsheet from CSV to JSON
-
- Requires HP + aeson, cassava, utf8-string
-}
import Control.Applicative
import Data.Aeson.Encode.Pretty
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.UTF8 as BSU8
import Data.Char
import Data.Csv
import Data.Function
import Data.List
import qualified Data.Map as M
import qualified Data.Vector as V
data CommodityRec = CommodityRec BSL.ByteString BSL.ByteString
instance FromRecord CommodityRec where
parseRecord rec = liftA2 CommodityRec (rec .! 2) (rec .! 3)
main = BSL.interact convert
convert :: BSL.ByteString -> BSL.ByteString
convert = either (error . ("Failed to parse CSV: "++)) toJSON . decode True
toJSON :: V.Vector CommodityRec -> BSL.ByteString
toJSON = encodePretty' (Config 2 compare)
. tidyVarieties
. compileRecords
. fmap tidyRecord
tidyRecord :: CommodityRec -> CommodityRec
tidyRecord (CommodityRec comm var) = (CommodityRec `on` initialCap) comm var
initialCap :: BSL.ByteString -> BSL.ByteString
initialCap = BSL.fromStrict
. BSU8.fromString
. capitalize
. BSU8.toString
. BSL.toStrict
where capitalize "" = ""
capitalize (c:cs) = toUpper c : map toLower cs
compileRecords :: V.Vector CommodityRec -> M.Map BSL.ByteString [BSL.ByteString]
compileRecords = V.foldl accum M.empty
where
accum acc (CommodityRec comm var) = M.insertWith (++) comm [var] acc
tidyVarieties :: M.Map BSL.ByteString [BSL.ByteString]
-> M.Map BSL.ByteString [BSL.ByteString]
tidyVarieties = M.map $ sort . nub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment