1- {-# LANGUAGE DeriveGeneric #-}
2- {-# LANGUAGE OverloadedStrings #-}
1+ {-# LANGUAGE DeriveGeneric #-}
2+ {-# LANGUAGE OverloadedStrings #-}
3+ {-# OPTIONS_GHC -Wno-incomplete-patterns #-}
4+ {-# OPTIONS_GHC -Wno-name-shadowing #-}
5+ {-# LANGUAGE FlexibleInstances #-}
6+ {-# LANGUAGE MultiParamTypeClasses #-}
37
48module Main where
59
610-- Standard library imports
7- import System.Environment (getArgs , lookupEnv )
11+ import System.Environment (getArgs , getProgName , lookupEnv )
812
913-- Third-party library imports
10- import Control.Lens ((^?) )
14+ import Control.Lens (Identity ( runIdentity ), (^?) )
1115import Data.Aeson (FromJSON (parseJSON ), ToJSON ,
1216 Value (Object ), decodeStrict , encode ,
1317 (.:) )
1418import Data.Aeson.Lens (AsNumber (_Integer ), key , nth )
1519import Data.ByteString (ByteString )
1620import qualified Data.ByteString.Char8 as BS
21+ import Data.List as L (intercalate )
22+ import Data.Text as T (unpack )
1723import GHC.Generics (Generic )
1824import Network.HTTP.Simple (Query , getResponseBody , httpBS ,
1925 parseRequest_ , setRequestHeader ,
2026 setRequestQueryString )
27+ import System.FilePath (takeDirectory )
28+ import Text.Ginger (IncludeResolver , SourcePos , Template ,
29+ ToGVal (.. ), dict , easyRender ,
30+ parseGinger )
2131
2232-- Data type definitions
2333data MainRelease = MainRelease {
34+ artists :: [String ],
35+ title :: String ,
36+ year :: Int ,
2437 released :: String ,
2538 imageUrl :: String ,
2639 labels :: [String ],
@@ -29,20 +42,38 @@ data MainRelease = MainRelease {
2942
3043instance ToJSON MainRelease
3144
45+ instance ToGVal m MainRelease where
46+ toGVal release = dict [
47+ (" artists" , toGVal . L. intercalate " , " . artists $ release),
48+ (" title" , toGVal $ title release),
49+ (" year" , toGVal $ year release),
50+ (" released" , toGVal $ released release),
51+ (" imageUrl" , toGVal $ imageUrl release),
52+ (" labels" , toGVal . L. intercalate " , " . labels $ release),
53+ (" uri" , toGVal $ uri release)
54+ ]
55+
56+
3257instance FromJSON MainRelease where
3358 parseJSON (Object v) = do
34- uri <- v .: " uri"
59+ artists <- v .: " artists" >>= traverse (.: " name" )
60+ title <- v .: " title"
61+ year <- v .: " year"
3562 released <- v .: " released"
3663 images <- v .: " images"
3764 imageUrl <- case images of
3865 (img: _) -> img .: " resource_url"
3966 [] -> fail " No images found"
4067 labels <- v .: " labels" >>= traverse (.: " name" )
68+ uri <- v .: " uri"
4169 return MainRelease {
42- uri = uri,
70+ artists = artists,
71+ title = title,
72+ year = year,
4373 released = released,
4474 imageUrl = imageUrl,
45- labels = labels
75+ labels = labels,
76+ uri = uri
4677 }
4778
4879-- Helper functions
@@ -89,6 +120,16 @@ getMainRelease releaseId = do
89120 Just release -> return release
90121 Nothing -> fail " Cannot decode main release"
91122
123+ nullResolver :: IncludeResolver Identity
124+ nullResolver = const $ return Nothing
125+
126+ -- | This is our template. Because 'parseGinger' wants a monad (as loading
127+ -- includes would normally go through some sort of monadic API like 'IO'), we
128+ -- use 'Identity' here.
129+ getTemplate :: String -> Template SourcePos
130+ getTemplate content = either (error . show ) id . runIdentity $
131+ parseGinger nullResolver Nothing content
132+
92133-- Main function
93134main :: IO ()
94135main = do
@@ -99,4 +140,8 @@ main = do
99140 >>= getMainReleaseId
100141 >>= getMainRelease
101142 putStrLn $ BS. unpack $ BS. toStrict $ encode release
143+ content <- getProgName >>= readFile . (++ " /app/templates/post.md" ) . takeDirectory
144+ let template = getTemplate content
145+ let output = T. unpack $ easyRender release template
146+ putStrLn output
102147 _ -> putStrLn " Usage: pull_album_info <artist_name> <album_name>"
0 commit comments