foliage/app/Foliage/Pages.hs

157 lines
6.8 KiB
Haskell
Raw Normal View History

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
2022-10-10 10:30:11 +03:00
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
2022-10-21 11:46:50 +03:00
module Foliage.Pages
2022-10-27 06:56:00 +03:00
( allPackagesPageTemplate,
allPackageVersionsPageTemplate,
2022-10-21 11:46:50 +03:00
packageVersionPageTemplate,
2022-10-27 06:56:00 +03:00
makeAllPackagesPage,
makePackageVersionPage,
2022-10-27 06:56:00 +03:00
makeAllPackageVersionsPage,
makeIndexPage,
2022-10-21 11:46:50 +03:00
)
where
2022-10-10 10:30:11 +03:00
import Data.Aeson (KeyValue ((.=)), ToJSON, object)
import Data.Function (on, (&))
2023-03-03 03:23:01 +03:00
import Data.List (sortOn)
import Data.List.NonEmpty qualified as NE
import Data.Maybe (fromMaybe, listToMaybe)
2023-03-03 03:23:01 +03:00
import Data.Ord (Down (Down), comparing)
import Data.Text.Lazy.IO.Utf8 qualified as TL
import Data.Time (UTCTime)
import Data.Time.Clock.POSIX (POSIXTime, utcTimeToPOSIXSeconds)
2022-10-27 06:56:00 +03:00
import Development.Shake (Action, traced)
import Distribution.Aeson (jsonGenericPackageDescription)
import Distribution.Package (PackageIdentifier (pkgName, pkgVersion))
import Distribution.Pretty (prettyShow)
import Foliage.Meta (PackageVersionSource)
import Foliage.Meta.Aeson ()
import Foliage.PreparePackageVersion (PreparedPackageVersion (..))
import Foliage.Shake (readGenericPackageDescription')
import Foliage.Utils.Aeson (MyAesonEncoding (..))
import GHC.Generics (Generic)
import System.Directory qualified as IO
import System.FilePath ((</>))
2022-10-10 10:30:11 +03:00
import Text.Mustache (Template)
import Text.Mustache.Compile.TH (compileMustacheDir)
import Text.Mustache.Render (renderMustache)
2022-10-10 10:30:11 +03:00
2022-10-27 06:56:00 +03:00
makeIndexPage :: FilePath -> Action ()
makeIndexPage outputDir =
traced "webpages / index" $ do
IO.createDirectoryIfMissing True outputDir
TL.writeFile (outputDir </> "index.html") $
renderMustache indexPageTemplate $
object []
data AllPackagesPageEntry = AllPackagesPageEntry
{ allPackagesPageEntryPkgId :: PackageIdentifier,
allPackagesPageEntryTimestamp :: UTCTime,
allPackagesPageEntryTimestampPosix :: POSIXTime,
allPackagesPageEntrySource :: PackageVersionSource,
allPackagesPageEntryLatestRevisionTimestamp :: Maybe UTCTime
}
deriving stock (Generic)
2022-10-27 06:56:00 +03:00
deriving (ToJSON) via MyAesonEncoding AllPackagesPageEntry
makeAllPackagesPage :: UTCTime -> FilePath -> [PreparedPackageVersion] -> Action ()
2022-10-27 06:56:00 +03:00
makeAllPackagesPage currentTime outputDir packageVersions = do
let packages =
packageVersions
2023-03-03 03:23:01 +03:00
& NE.groupBy ((==) `on` (pkgName . pkgId))
& map
( \group ->
group
2023-03-03 03:23:01 +03:00
& NE.sortBy (comparing $ Down . pkgVersion . pkgId)
& NE.head
& ( \(PreparedPackageVersion {pkgId, pkgTimestamp, cabalFileRevisions, pkgVersionSource}) ->
AllPackagesPageEntry
{ allPackagesPageEntryPkgId = pkgId,
allPackagesPageEntryTimestamp = fromMaybe currentTime pkgTimestamp,
allPackagesPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime pkgTimestamp),
allPackagesPageEntrySource = pkgVersionSource,
allPackagesPageEntryLatestRevisionTimestamp = fst <$> listToMaybe cabalFileRevisions
}
)
)
& sortOn allPackagesPageEntryPkgId
2022-10-27 06:56:00 +03:00
traced "webpages / all-packages" $ do
IO.createDirectoryIfMissing True (outputDir </> "all-packages")
TL.writeFile (outputDir </> "all-packages" </> "index.html") $
renderMustache allPackagesPageTemplate $
object ["packages" .= packages]
2022-10-27 06:56:00 +03:00
data AllPackageVersionsPageEntry
= AllPackageVersionsPageEntryPackage
{ allPackageVersionsPageEntryPkgId :: PackageIdentifier,
allPackageVersionsPageEntryTimestamp :: UTCTime,
allPackageVersionsPageEntryTimestampPosix :: POSIXTime,
allPackageVersionsPageEntrySource :: PackageVersionSource
}
2022-10-27 06:56:00 +03:00
| AllPackageVersionsPageEntryRevision
{ allPackageVersionsPageEntryPkgId :: PackageIdentifier,
allPackageVersionsPageEntryTimestamp :: UTCTime,
allPackageVersionsPageEntryTimestampPosix :: POSIXTime
}
deriving stock (Generic)
2022-10-27 06:56:00 +03:00
deriving (ToJSON) via MyAesonEncoding AllPackageVersionsPageEntry
makeAllPackageVersionsPage :: UTCTime -> FilePath -> [PreparedPackageVersion] -> Action ()
2022-10-27 06:56:00 +03:00
makeAllPackageVersionsPage currentTime outputDir packageVersions = do
let entries =
foldMap
( \PreparedPackageVersion {pkgId, pkgTimestamp, pkgVersionSource, cabalFileRevisions} ->
AllPackageVersionsPageEntryPackage
{ allPackageVersionsPageEntryPkgId = pkgId,
allPackageVersionsPageEntryTimestamp = fromMaybe currentTime pkgTimestamp,
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime pkgTimestamp),
allPackageVersionsPageEntrySource = pkgVersionSource
}
: map
( \(revisionTimestamp, _) ->
AllPackageVersionsPageEntryRevision
{ allPackageVersionsPageEntryPkgId = pkgId,
allPackageVersionsPageEntryTimestamp = revisionTimestamp,
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds revisionTimestamp
}
)
cabalFileRevisions
)
packageVersions
& sortOn (Down . allPackageVersionsPageEntryTimestamp)
2022-10-27 06:56:00 +03:00
traced "webpages / all-package-versions" $ do
IO.createDirectoryIfMissing True (outputDir </> "all-package-versions")
TL.writeFile (outputDir </> "all-package-versions" </> "index.html") $
renderMustache allPackageVersionsPageTemplate $
object ["entries" .= entries]
makePackageVersionPage :: FilePath -> PreparedPackageVersion -> Action ()
makePackageVersionPage outputDir PreparedPackageVersion {pkgId, pkgTimestamp, pkgVersionSource, cabalFilePath, cabalFileRevisions} = do
pkgDesc <- readGenericPackageDescription' cabalFilePath
2022-10-27 06:56:00 +03:00
traced ("webpages / package / " ++ prettyShow pkgId) $ do
IO.createDirectoryIfMissing True (outputDir </> "package" </> prettyShow pkgId)
TL.writeFile (outputDir </> "package" </> prettyShow pkgId </> "index.html") $
renderMustache packageVersionPageTemplate $
object
[ "pkgVersionSource" .= pkgVersionSource,
"cabalFileRevisions" .= cabalFileRevisions,
"pkgDesc" .= jsonGenericPackageDescription pkgDesc,
"pkgTimestamp" .= pkgTimestamp
]
2022-10-27 06:56:00 +03:00
indexPageTemplate :: Template
indexPageTemplate = $(compileMustacheDir "index" "templates")
allPackagesPageTemplate :: Template
allPackagesPageTemplate = $(compileMustacheDir "allPackages" "templates")
2022-10-27 06:56:00 +03:00
allPackageVersionsPageTemplate :: Template
allPackageVersionsPageTemplate = $(compileMustacheDir "allPackageVersions" "templates")
2022-10-21 11:46:50 +03:00
2022-10-10 10:30:11 +03:00
packageVersionPageTemplate :: Template
packageVersionPageTemplate = $(compileMustacheDir "packageVersion" "templates")