{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE GADTs #-} module Main where import Data.Aeson import Data.Time import GHC.Generics data ContentType = Movie | Series | Channel | Tv deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype ContentID = ContentID String deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype SubtitleID = SubtitleID String deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype ContentIDPrefix = ContentIDPrefix String deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype Url = Url String deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype BingeGroup = BingeGroup String deriving (Show, Eq, Generic, FromJSON, ToJSON) newtype OpensubtitleHash = OpensubtitleHash String deriving (Show, Eq, Generic, FromJSON, ToJSON) data ImageShape = Square | Poster | Landscape deriving (Show, Eq, Generic, FromJSON, ToJSON) data YearInfo = Single Int | Range Int Int deriving (Show, Eq, Generic, FromJSON, ToJSON) data Language = Language String deriving (Show, Eq, Generic, FromJSON, ToJSON) data Trailer = Trailer String | Clip String deriving (Show, Eq, Generic, FromJSON, ToJSON) data MetaLink = MetaLink { name :: String, category :: [String], url :: Url } deriving (Show, Generic, FromJSON, ToJSON) data StreamDetails = StreamDetails { name :: Maybe String, title :: Maybe String, description :: Maybe String, subtitles :: Maybe [Subtitle], -- we arent doing soruces cuz no torrent for now bingeGroup :: Maybe BingeGroup, vContentIDeoHash :: Maybe OpensubtitleHash, vContentIDeoSize :: Maybe Int, filename :: Maybe String } deriving (Show, Generic, FromJSON, ToJSON) data StreamSource = UrlSource Url | YoutubeSource String | TorrentSource | ExternalSource MetaLink deriving (Show, Generic, FromJSON, ToJSON) data Stream = Stream { details :: StreamDetails, source :: StreamSource } deriving (Show, Generic, FromJSON, ToJSON) data Video = VContentIDeo { id :: ContentID, title :: String, released :: UTCTime, thumbnail :: Maybe Url, streams :: Maybe [Stream], available :: Maybe Bool, -- or maybe just bool is fine episode :: Maybe Int, season :: Maybe Int, trailers :: Maybe [Stream], overview :: Maybe String } deriving (Show, Generic, FromJSON, ToJSON) data Feature = Search { required :: Bool, options :: Maybe [ContentIDPrefix], optionsLimit :: Maybe Int } | Genre { required :: Bool, options :: Maybe [ContentIDPrefix], optionsLimit :: Maybe Int } | Skip deriving (Show, Generic, FromJSON, ToJSON) data Resource a where MetaResource :: { metaTypes :: [ContentType], metaContentIDPrefix :: [ContentIDPrefix] } -> Resource MetaData CatalogResource :: { catalogTypes :: [ContentType], catalogContentIDPrefix :: [ContentIDPrefix], catalogExtra :: [Feature] } -> Resource Catalog StreamResource :: { streamTypes :: [ContentType], streamContentIDPrefix :: [ContentIDPrefix] } -> Resource Stream SubtitleResource :: { subtitleTypes :: [ContentType], subtitleContentIDPrefix :: [ContentIDPrefix] } -> Resource Subtitle data MetaData = Meta { id :: ContentID, contentType :: ContentType, name :: String, genres :: Maybe [String], poster :: Maybe Url, posterShape :: Maybe ImageShape, background :: Maybe Url, logo :: Maybe Url, description :: Maybe String, releaseInfo :: Maybe YearInfo, director :: Maybe [String], cast :: Maybe [String], imdbRating :: Maybe Float, released :: Maybe UTCTime, trailers :: Maybe [Trailer], links :: Maybe [MetaLink], video :: Maybe [Video], runtime :: Maybe String, language :: Maybe String, country :: Maybe String, awards :: Maybe String, website :: Maybe Url } deriving (Show, Generic, FromJSON, ToJSON) data Catalog = Catalog {} deriving (Show, Generic, FromJSON, ToJSON) data Subtitle = Subtitle { id :: SubtitleID, url :: Url, language :: Language } deriving (Show, Generic, FromJSON, ToJSON) main :: IO () main = putStrLn "Hello, Haskell!"