pixiv-0.1.0: src/Web/Pixiv/Utils.hs
-- | Copyright: (c) 2021 The closed eye of love
-- SPDX-License-Identifier: BSD-3-Clause
-- Maintainer: Poscat <poscat@mail.poscat.moe>, berberman <berberman@yandex.com>
-- Stability: alpha
-- Portability: portable
-- Miscellaneous utilities.
module Web.Pixiv.Utils
( isSinglePageIllust,
extractHighestQualityImageUrl,
extractImageUrlsFromIllust,
unzipArchive,
ugoiraMetadataToFFConcat,
)
where
import qualified Codec.Archive.Zip as Zip
import Control.Applicative ((<|>))
import Control.Lens
import Control.Monad (join)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Numeric (showFFloat)
import Web.Pixiv.Types
import Web.Pixiv.Types.Lens
-----------------------------------------------------------------------------
-- | Judges if an illustration has only one image.
isSinglePageIllust :: Illust -> Bool
isSinglePageIllust i = null $ i ^. metaPages
-- | Extracts the url of the highest quality image.
extractHighestQualityImageUrl :: ImageUrls -> Maybe Text
extractHighestQualityImageUrl x =
x ^. original
<|> x ^. large
<|> x ^. medium
<|> x ^. squareMedium
-- | Extracts all urls from an illustration, using 'extractHighestQualityImageUrl'.
extractImageUrlsFromIllust :: Illust -> [Text]
extractImageUrlsFromIllust i
| isSinglePageIllust i = (single <|> (multi ^? _head)) ^.. each
| otherwise = multi
where
single = join $ (i ^. metaSinglePage) & each %~ (^. originalImageUrl)
multi = (i ^. metaPages ^.. each . imageUrls <&> extractHighestQualityImageUrl) ^.. each . _Just
-----------------------------------------------------------------------------
-- | Unzip a zip archive represented in 'LBS.ByteString' to a directory.
unzipArchive ::
-- | destination directory
FilePath ->
-- | zip archive
LBS.ByteString ->
IO ()
unzipArchive dir bs = do
let archive = Zip.toArchive bs
option = [Zip.OptDestination dir]
Zip.extractFilesFromArchive option archive
-- | Generates ffconcat meta file of an ugoira.
ugoiraMetadataToFFConcat :: UgoiraMetadata -> BS.ByteString
ugoiraMetadataToFFConcat meta =
encodeUtf8 . T.unlines $
"ffconcat version 1.0" :
[ T.unlines
[ "file " <> frame ^. ugoiraFile,
"duration "
<> T.pack
( frame ^. ugoiraDelay
& fromIntegral
& (/ 1000)
& flip (showFFloat @Double Nothing) ""
)
]
| frame <- meta ^. frames
]