module Web.Data.Yahoo.Request where import Data.List (intercalate) import Data.Maybe (catMaybes) import Data.Time.Calendar (Day, fromGregorian) import Text.Printf (printf) import Web.Data.Yahoo.Utils (dayAsEpoch) data Ticker = Ticker String class YahooParam a where key :: a -> String symbol :: a -> String paramToString :: YahooParam a => a -> String paramToString :: forall a. YahooParam a => a -> [Char] paramToString a p = forall r. PrintfType r => [Char] -> r printf [Char] "%s=%s" (forall a. YahooParam a => a -> [Char] key a p) (forall a. YahooParam a => a -> [Char] symbol a p) data Interval = Daily | Weekly | Monthly deriving (Int -> Interval -> [Char] -> [Char] [Interval] -> [Char] -> [Char] Interval -> [Char] forall a. (Int -> a -> [Char] -> [Char]) -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a showList :: [Interval] -> [Char] -> [Char] $cshowList :: [Interval] -> [Char] -> [Char] show :: Interval -> [Char] $cshow :: Interval -> [Char] showsPrec :: Int -> Interval -> [Char] -> [Char] $cshowsPrec :: Int -> Interval -> [Char] -> [Char] Show, Interval -> Interval -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Interval -> Interval -> Bool $c/= :: Interval -> Interval -> Bool == :: Interval -> Interval -> Bool $c== :: Interval -> Interval -> Bool Eq) instance YahooParam Interval where key :: Interval -> [Char] key Interval _ = [Char] "interval" symbol :: Interval -> [Char] symbol Interval Daily = [Char] "1d" symbol Interval Weekly = [Char] "1wk" symbol Interval Monthly = [Char] "1mo" data Events = HistoricalPrices | Dividends | Splits instance YahooParam Events where key :: Events -> [Char] key Events _ = [Char] "events" symbol :: Events -> [Char] symbol Events HistoricalPrices = [Char] "history" symbol Events Dividends = [Char] "div" symbol Events Splits = [Char] "split" data FromEndpoint = FromEndpoint Day instance YahooParam FromEndpoint where key :: FromEndpoint -> [Char] key FromEndpoint _ = [Char] "period1" symbol :: FromEndpoint -> [Char] symbol (FromEndpoint Day day) = forall a. Show a => a -> [Char] show forall a b. (a -> b) -> a -> b $ Day -> Integer dayAsEpoch Day day data ToEndpoint = ToEndpoint Day instance YahooParam ToEndpoint where key :: ToEndpoint -> [Char] key ToEndpoint _ = [Char] "period2" symbol :: ToEndpoint -> [Char] symbol (ToEndpoint Day day) = forall a. Show a => a -> [Char] show forall a b. (a -> b) -> a -> b $ Day -> Integer dayAsEpoch Day day data TimeRange = After Day | Before Day | Range Day Day timeRangeToEndpoints :: TimeRange -> (FromEndpoint, ToEndpoint) timeRangeToEndpoints :: TimeRange -> (FromEndpoint, ToEndpoint) timeRangeToEndpoints (After Day day) = (Day -> FromEndpoint FromEndpoint Day day, Day -> ToEndpoint ToEndpoint forall a b. (a -> b) -> a -> b $ Integer -> Int -> Int -> Day fromGregorian Integer 2050 Int 12 Int 31) timeRangeToEndpoints (Before Day day) = (Day -> FromEndpoint FromEndpoint forall a b. (a -> b) -> a -> b $ Integer -> Int -> Int -> Day fromGregorian Integer 1970 Int 1 Int 1, Day -> ToEndpoint ToEndpoint Day day) timeRangeToEndpoints (Range Day from Day to) = (Day -> FromEndpoint FromEndpoint Day from, Day -> ToEndpoint ToEndpoint Day to) data YahooRequest = YahooRequest { YahooRequest -> Ticker ticker :: Ticker, YahooRequest -> Maybe Interval interval :: Maybe Interval, YahooRequest -> Maybe TimeRange period :: Maybe TimeRange } requestUrl :: YahooRequest -> String requestUrl :: YahooRequest -> [Char] requestUrl (YahooRequest { ticker :: YahooRequest -> Ticker ticker = (Ticker [Char] t), interval :: YahooRequest -> Maybe Interval interval = Maybe Interval i, period :: YahooRequest -> Maybe TimeRange period = Maybe TimeRange p }) = forall r. PrintfType r => [Char] -> r printf [Char] "%s/%s%s" [Char] baseUrl [Char] t ([[Char]] -> [Char] queryString [[Char]] queryParams) where baseUrl :: String baseUrl :: [Char] baseUrl = [Char] "http://query1.finance.yahoo.com/v7/finance/download" rangeEndpoints :: Maybe (FromEndpoint, ToEndpoint) rangeEndpoints :: Maybe (FromEndpoint, ToEndpoint) rangeEndpoints = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap TimeRange -> (FromEndpoint, ToEndpoint) timeRangeToEndpoints Maybe TimeRange p fromEndpoint :: Maybe FromEndpoint fromEndpoint :: Maybe FromEndpoint fromEndpoint = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a b. (a, b) -> a fst Maybe (FromEndpoint, ToEndpoint) rangeEndpoints toEndpoint :: Maybe ToEndpoint toEndpoint :: Maybe ToEndpoint toEndpoint = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a b. (a, b) -> b snd Maybe (FromEndpoint, ToEndpoint) rangeEndpoints queryParams :: [String] queryParams :: [[Char]] queryParams = forall a. [Maybe a] -> [a] catMaybes forall a b. (a -> b) -> a -> b $ [ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a. YahooParam a => a -> [Char] paramToString Maybe Interval i, forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a. YahooParam a => a -> [Char] paramToString Maybe FromEndpoint fromEndpoint, forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a. YahooParam a => a -> [Char] paramToString Maybe ToEndpoint toEndpoint ] queryString :: [String] -> String queryString :: [[Char]] -> [Char] queryString [] = [Char] "" queryString [[Char]] ps = forall r. PrintfType r => [Char] -> r printf [Char] "?%s" (forall a. [a] -> [[a]] -> [a] intercalate [Char] "&" [[Char]] ps)