diff --git a/src/Handler/Eos/V0/Latest.hs b/src/Handler/Eos/V0/Latest.hs index 371f04d..097e1c7 100644 --- a/src/Handler/Eos/V0/Latest.hs +++ b/src/Handler/Eos/V0/Latest.hs @@ -12,15 +12,18 @@ import Database.Esqueleto.Experimental ( orderBy, select, table, + where_, + val, (^.), + (==.) ) import Foundation (Handler, RegistryCtx (appSettings)) import Handler.Package.V0.ReleaseNotes (ReleaseNotes (..)) -import Handler.Util (queryParamAs, tickleMAU) +import Handler.Util (queryParamAs, tickleMAU, getArchQuery) import Lib.Types.Emver (Version, parseVersion) import Model (EntityField (..), OsVersion (..)) import Orphans.Emver () -import Startlude (Bool (..), Down (..), Eq, Generic, Maybe (..), Ord ((<)), Show, Text, const, filter, fst, head, maybe, pure, sortOn, ($), (&&&), (.), (<$>), (<&>), (<=)) +import Startlude (Bool (..), Down (..), Eq, Generic, Maybe (..), Ord ((<)), Show, Text, const, filter, fst, head, maybe, pure, sortOn, ($), (&&&), (.), (<$>), (<&>), (<=), (>>=)) import Yesod (ToContent (toContent), ToTypedContent (..), YesodPersist (runDB), getsYesod, sendResponseStatus) import Yesod.Core.Types (JSONResponse (..)) import Settings (AppSettings(maxEosVersion)) @@ -46,32 +49,36 @@ instance ToTypedContent EosRes where getEosVersionR :: Handler (JSONResponse (Maybe EosRes)) getEosVersionR = do currentEosVersion <- queryParamAs "eos-version" parseVersion - case currentEosVersion of - Nothing -> sendResponseStatus status400 (InvalidParamsE "Param is required" "eos-version") - Just currentEosVersion' -> do - maxVersion <- getsYesod $ maxEosVersion . appSettings - allEosVersions <- runDB $ - select $ do - vers <- from $ table @OsVersion - orderBy [desc (vers ^. OsVersionNumber)] - pure vers - let osV = determineMaxEosVersionAvailable maxVersion currentEosVersion' $ entityVal <$> allEosVersions - let mLatest = head osV - let mappedVersions = - ReleaseNotes $ - HM.fromList $ - sortOn (Down . fst) $ - filter (maybe (const True) (<) currentEosVersion . fst) $ - ((osVersionNumber &&& osVersionReleaseNotes)) - <$> osV - tickleMAU - pure . JSONResponse $ - mLatest <&> \latest -> - EosRes - { eosResVersion = osVersionNumber latest - , eosResHeadline = osVersionHeadline latest - , eosResReleaseNotes = mappedVersions - } + getArchQuery >>= \case + Nothing -> sendResponseStatus status400 (InvalidParamsE "Param is required" "arch") + Just arch -> do + case currentEosVersion of + Nothing -> sendResponseStatus status400 (InvalidParamsE "Param is required" "eos-version") + Just currentEosVersion' -> do + maxVersion <- getsYesod $ maxEosVersion . appSettings + allEosVersions <- runDB $ + select $ do + vers <- from $ table @OsVersion + where_ (vers ^. OsVersionArch ==. val (Just arch)) + orderBy [desc (vers ^. OsVersionNumber)] + pure vers + let osV = determineMaxEosVersionAvailable maxVersion currentEosVersion' $ entityVal <$> allEosVersions + let mLatest = head osV + let mappedVersions = + ReleaseNotes $ + HM.fromList $ + sortOn (Down . fst) $ + filter (maybe (const True) (<) currentEosVersion . fst) $ + ((osVersionNumber &&& osVersionReleaseNotes)) + <$> osV + tickleMAU + pure . JSONResponse $ + mLatest <&> \latest -> + EosRes + { eosResVersion = osVersionNumber latest + , eosResHeadline = osVersionHeadline latest + , eosResReleaseNotes = mappedVersions + } determineMaxEosVersionAvailable :: Version -> Version -> [OsVersion] -> [OsVersion] determineMaxEosVersionAvailable maxEosVersion currentEosVersion versions = do diff --git a/src/Handler/Util.hs b/src/Handler/Util.hs index 06ae547..18fc6e6 100644 --- a/src/Handler/Util.hs +++ b/src/Handler/Util.hs @@ -23,7 +23,7 @@ import Lib.PkgRepository ( PkgRepo, getHash, ) -import Lib.Types.Core (PkgId) +import Lib.Types.Core (PkgId, OsArch) import Lib.Types.Emver ( Version, VersionRange, @@ -177,5 +177,5 @@ fetchCompatiblePkgVersions osVersion pkg = do Nothing -> const True Just v -> flip satisfies v -getArchQuery :: Handler (Maybe Text) +getArchQuery :: Handler (Maybe OsArch) getArchQuery = parseQueryParam "arch" ((flip $ note . mappend "Invalid 'arch': ") =<< readMaybe) \ No newline at end of file diff --git a/src/Lib/Types/Core.hs b/src/Lib/Types/Core.hs index fe563fa..7cc7451 100644 --- a/src/Lib/Types/Core.hs +++ b/src/Lib/Types/Core.hs @@ -57,6 +57,7 @@ import Web.HttpApiData ( ToHttpApiData, ) import Yesod (PathPiece (..)) +import Prelude (read) newtype PkgId = PkgId {unPkgId :: Text} @@ -88,6 +89,23 @@ instance PathPiece PkgId where fromPathPiece = fmap PkgId . fromPathPiece toPathPiece = unPkgId +data OsArch = X86_64 | AARCH64 | RASPBERRYPI + deriving (Eq, Ord) +instance Show OsArch where + show X86_64 = "x86_64" + show AARCH64 = "aarch64" + show RASPBERRYPI = "raspberrypi" +instance Read OsArch where + readsPrec _ "x86_64" = [(X86_64, "")] + readsPrec _ "aarch64" = [(AARCH64, "")] + readsPrec _ "raspberrypi" = [(RASPBERRYPI, "")] + readsPrec _ _ = [] +instance PersistField OsArch where + toPersistValue = PersistText . show + fromPersistValue (PersistText t) = Right $ read $ toS t + fromPersistValue other = Left [i|Invalid OsArch: #{other}|] +instance PersistFieldSql OsArch where + sqlType _ = SqlString newtype Extension (a :: Symbol) = Extension String deriving (Eq) type S9PK = Extension "s9pk" diff --git a/src/Model.hs b/src/Model.hs index 0d7e4a5..68f78ef 100644 --- a/src/Model.hs +++ b/src/Model.hs @@ -22,7 +22,7 @@ import Database.Persist.TH ( share, sqlSettings, ) -import Lib.Types.Core (PkgId (PkgId)) +import Lib.Types.Core (PkgId (PkgId), OsArch) import Lib.Types.Emver ( Version, VersionRange, @@ -71,6 +71,7 @@ OsVersion number Version headline Text releaseNotes Text + arch OsArch Maybe deriving Eq deriving Show @@ -129,7 +130,7 @@ UserActivity createdAt UTCTime serverId Text osVersion Version - arch Text + arch OsArch Admin Id Text