{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Blog.Skin (
      Skin(..)
    , build
  ) where

import Arguments (Arguments)
import qualified Arguments (bannerPath, favicon, cardImage, headPath, previewArticlesCount, previewLinesCount)
import Control.Monad (filterM)
import Data.Aeson (ToJSON(..), (.=), pairs)
import Data.Maybe (listToMaybe)
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid ((<>))
#endif
import Files (absoluteLink)
import GHC.Generics (Generic)
import Prelude hiding (head)
import System.Directory (doesFileExist)
import System.FilePath ((</>), (<.>))

data Skin = Skin {
       :: Maybe String
    , Skin -> Maybe String
cardImage :: Maybe FilePath
    , Skin -> Maybe String
favicon :: Maybe FilePath
    , Skin -> Maybe String
head :: Maybe String
    , Skin -> Int
previewArticlesCount :: Int
    , Skin -> Int
previewLinesCount :: Int
  } deriving (forall x. Skin -> Rep Skin x)
-> (forall x. Rep Skin x -> Skin) -> Generic Skin
forall x. Rep Skin x -> Skin
forall x. Skin -> Rep Skin x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Skin x -> Skin
$cfrom :: forall x. Skin -> Rep Skin x
Generic

instance ToJSON Skin where
  toEncoding :: Skin -> Encoding
toEncoding (Skin {Int
previewArticlesCount :: Int
previewArticlesCount :: Skin -> Int
previewArticlesCount, Int
previewLinesCount :: Int
previewLinesCount :: Skin -> Int
previewLinesCount}) = Series -> Encoding
pairs (
        Text
"previewArticlesCount" Text -> Int -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
previewArticlesCount
      Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> Text
"previewLinesCount" Text -> Int -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
previewLinesCount
    )

findImage :: String -> Maybe FilePath -> IO (Maybe FilePath)
findImage :: String -> Maybe String -> IO (Maybe String)
findImage String
_ (Just String
path) = Maybe String -> IO (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe String -> IO (Maybe String))
-> (String -> Maybe String) -> String -> IO (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String
forall a. a -> Maybe a
Just (String -> IO (Maybe String)) -> String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ String -> String
absoluteLink String
path
findImage String
name Maybe String
Nothing =
  [String] -> Maybe String
forall a. [a] -> Maybe a
listToMaybe ([String] -> Maybe String) -> IO [String] -> IO (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> IO Bool) -> [String] -> IO [String]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM String -> IO Bool
doesFileExist [String]
pathsToCheck
  where
    directories :: [String]
directories = [String
".", String
"image", String
"images", String
"pictures", String
"skin", String
"static"]
    extensions :: [String]
extensions = [String
"ico", String
"gif", String
"jpeg", String
"jpg", String
"png", String
"svg"]
    pathsToCheck :: [String]
pathsToCheck = [ String
dir String -> String -> String
</> String
name String -> String -> String
<.> String
ext | String
dir <- [String]
directories, String
ext <- [String]
extensions ]

build :: String -> Arguments -> IO Skin
build :: String -> Arguments -> IO Skin
build String
blogName Arguments
arguments = do
  Maybe String
banner <- (String -> IO String) -> Maybe String -> IO (Maybe String)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM String -> IO String
readFile (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ Arguments -> Maybe String
Arguments.bannerPath Arguments
arguments
  Maybe String
cardImage <- String -> Maybe String -> IO (Maybe String)
findImage String
blogName (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ Arguments -> Maybe String
Arguments.cardImage Arguments
arguments
  Maybe String
favicon <- String -> Maybe String -> IO (Maybe String)
findImage String
"favicon" (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ Arguments -> Maybe String
Arguments.favicon Arguments
arguments
  Maybe String
head <- (String -> IO String) -> Maybe String -> IO (Maybe String)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM String -> IO String
readFile (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ Arguments -> Maybe String
Arguments.headPath Arguments
arguments
  Skin -> IO Skin
forall (m :: * -> *) a. Monad m => a -> m a
return (Skin -> IO Skin) -> Skin -> IO Skin
forall a b. (a -> b) -> a -> b
$ Skin :: Maybe String
-> Maybe String
-> Maybe String
-> Maybe String
-> Int
-> Int
-> Skin
Skin {
        Maybe String
banner :: Maybe String
banner :: Maybe String
banner
      , Maybe String
cardImage :: Maybe String
cardImage :: Maybe String
cardImage
      , Maybe String
favicon :: Maybe String
favicon :: Maybe String
favicon
      , Maybe String
head :: Maybe String
head :: Maybe String
head
      , previewArticlesCount :: Int
previewArticlesCount = Arguments -> Int
Arguments.previewArticlesCount Arguments
arguments
      , previewLinesCount :: Int
previewLinesCount = Arguments -> Int
Arguments.previewLinesCount Arguments
arguments
    }