packages feed

mdapi-1: src/Fedora/Mdapi/Types.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
-----------------------------------------------------------------------------
-- |
-- Module : Fedora.Mdapi.Types
-- Copyright : (C) 2015 Red hat, Inc.
-- License : BSD2 (see LICENSE file)
-- Maintainer : Ricky Elrod <relrod@redhat.com>
-- Stability : experimental
-- Portability : ghc (lens)
--
-- Types for Mdapi
----------------------------------------------------------------------------
module Fedora.Mdapi.Types where

import Control.Lens
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Data.Aeson
--import Data.Aeson.Lens (key, nth)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.Default
import Data.List (dropWhileEnd)
import Data.Maybe (fromMaybe)
import Data.Monoid
import qualified Data.Text as T
import Network.Wreq
import Network.Wreq.Types (Postable)

-- | Our 'MdapiT' type which is really a 'ReaderT' with 'IO' as its base. For
-- now, at least.
type MdapiT a = ReaderT MdapiConfig IO a

-- | Run the whole transformer stack.
runMdapiT :: MdapiT a -> MdapiConfig -> IO a
runMdapiT = runReaderT

-- | Describes how to connect to the mdapi instance.
data MdapiConfig = MdapiConfig {
    _baseUrl :: String
  } deriving (Eq, Show)

-- | Default to <https://apps.fedoraproject.org/mdapi/>.
instance Default MdapiConfig where
  def = MdapiConfig "https://apps.fedoraproject.org/mdapi/"

data Branch =
    Dist6Epel
  | F23
  | Rawhide
  | F22
  | Koji
  | Dist5Epel
  | Dist6
  | Dist5
  | Epel7
  | F21

branchToBranchName :: Branch -> String
branchToBranchName Dist6Epel = "dist-6E-epel"
branchToBranchName F23       = "f23"
branchToBranchName Rawhide   = "rawhide"
branchToBranchName F22       = "f22"
branchToBranchName Koji      = "koji"
branchToBranchName Dist5Epel = "dist-5E-epel"
branchToBranchName Dist6     = "dist-6E"
branchToBranchName Dist5     = "dist-5E"
branchToBranchName Epel7     = "epel7"
branchToBranchName F21       = "f21"

--------------------------------------------------------------------------------
-- Package
--------------------------------------------------------------------------------

data NEVR =
  NEVR { _name    :: Maybe T.Text
       , _epoch   :: Maybe T.Text
       , _version :: Maybe T.Text
       , _release :: Maybe T.Text
       } deriving (Eq, Show)

makeLenses ''NEVR

instance FromJSON NEVR where
  parseJSON (Object v) = NEVR <$>
                         v .: "name" <*>
                         v .: "epoch" <*>
                         v .: "version" <*>
                         v .: "release"
  parseJSON _          = mempty

data PackageResponse =
  PackageResponse { _arch :: T.Text
                  , _basename :: T.Text
                  , _copackages :: [T.Text]
                  , _conflicts :: [NEVR]
                  , _description :: T.Text
                  , _enhances :: [NEVR] -- Sometimes null, sometimes []?
                  , _pkgEpoch :: T.Text
                  , _obsoletes :: [NEVR]
                  , _provides :: [NEVR]
                  , _recommends :: [NEVR]
                  , _pkgRelease :: T.Text
                  , _pkgRepo :: T.Text
                  , _requires :: [NEVR]
                  , _suggests :: [NEVR]
                  , _summary :: T.Text
                  , _supplements :: [NEVR]
                  , _pkgVersion :: T.Text
                  } deriving (Eq, Show)

makeLenses ''PackageResponse

instance FromJSON PackageResponse where
  parseJSON (Object v) = PackageResponse <$>
                         v .: "arch" <*>
                         v .: "basename" <*>
                         v .: "co-packages" <*>
                         v .: "conflicts" <*>
                         v .: "description" <*>
                         fmap fixNull (v .: "enhances") <*>
                         v .: "epoch" <*>
                         v .: "obsoletes" <*>
                         v .: "provides" <*>
                         fmap fixNull (v .: "recommends") <*>
                         v .: "release" <*>
                         v .: "repo" <*>
                         v .: "requires" <*>
                         fmap fixNull (v .: "suggests") <*>
                         v .: "summary" <*>
                         fmap fixNull (v .: "supplements") <*>
                         v .: "version"
    where
      fixNull = fromMaybe []
  parseJSON _          = mempty


--------------------------------------------------------------------------------
-- Changelog
--------------------------------------------------------------------------------

data ChangelogEntry =
  ChangelogEntry { _author :: T.Text
                 , _log :: T.Text
                 , _date :: Integer
                 } deriving (Eq, Show)

makeLenses ''ChangelogEntry

instance FromJSON ChangelogEntry where
  parseJSON (Object v) = ChangelogEntry <$>
                         v .: "author" <*>
                         v .: "changelog" <*>
                         v .: "date"
  parseJSON _          = mempty

data ChangelogResponse =
  ChangelogResponse { _changelogResponseEntries :: [ChangelogEntry]
                      -- ^ Why is this called 'files' upstream?
                    , _changelogResponseRepo :: String
                    } deriving (Eq, Show)

makeLenses ''ChangelogResponse

instance FromJSON ChangelogResponse where
  parseJSON (Object v) = ChangelogResponse <$>
                         v .: "files" <*>
                         v .: "repo"
  parseJSON _          = mempty

--------------------------------------------------------------------------------
-- Files
--------------------------------------------------------------------------------

data FileEntry =
  FileEntry { _dirname :: T.Text
            , _filenames :: T.Text
            , _filetypes :: T.Text
            } deriving (Eq, Show)

makeLenses ''FileEntry

instance FromJSON FileEntry where
  parseJSON (Object v) = FileEntry <$>
                         v .: "dirname" <*>
                         v .: "filenames" <*>
                         v .: "filetypes"
  parseJSON _          = mempty

data FilesResponse =
  FilesResponse { _filesResponseEntries :: [FileEntry]
                , _filesResponseRepo :: String
                } deriving (Eq, Show)

makeLenses ''FilesResponse

instance FromJSON FilesResponse where
  parseJSON (Object v) = FilesResponse <$>
                         v .: "files" <*>
                         v .: "repo"
  parseJSON _          = mempty