initial commit
This commit is contained in:
commit
6f1e9df2af
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
dist-newstyle
|
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Revision history for kino
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
13
LICENSE
Normal file
13
LICENSE
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Copyright (c) 2021 depsterr
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
6
app/Main.hs
Normal file
6
app/Main.hs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
import Request
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print =<< testFunc
|
46
kino.cabal
Normal file
46
kino.cabal
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
cabal-version: 2.4
|
||||||
|
name: kino
|
||||||
|
version: 0.1.0.0
|
||||||
|
synopsis: A terminal interface to the yts.mx api
|
||||||
|
-- description:
|
||||||
|
homepage:
|
||||||
|
-- bug-reports:
|
||||||
|
license: ISC
|
||||||
|
license-file: LICENSE
|
||||||
|
author: depsterr
|
||||||
|
maintainer: depsterr@protonmail.com
|
||||||
|
-- copyright:
|
||||||
|
category: Movie
|
||||||
|
extra-source-files: CHANGELOG.md
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules: Request
|
||||||
|
, JSONTypes
|
||||||
|
other-modules:
|
||||||
|
-- other-extensions:
|
||||||
|
build-depends: base ^>=4.14.1.0
|
||||||
|
, wreq
|
||||||
|
, aeson
|
||||||
|
, lens-aeson
|
||||||
|
, lens
|
||||||
|
, bytestring
|
||||||
|
, text
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
executable kino
|
||||||
|
main-is: Main.hs
|
||||||
|
-- other-modules:
|
||||||
|
-- other-extensions:
|
||||||
|
build-depends:
|
||||||
|
base ^>=4.14.1.0,
|
||||||
|
kino
|
||||||
|
hs-source-dirs: app
|
||||||
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
test-suite kino-test
|
||||||
|
default-language: Haskell2010
|
||||||
|
type: exitcode-stdio-1.0
|
||||||
|
hs-source-dirs: test
|
||||||
|
main-is: MyLibTest.hs
|
||||||
|
build-depends: base ^>=4.14.1.0
|
103
src/JSONTypes.hs
Normal file
103
src/JSONTypes.hs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module JSONTypes where
|
||||||
|
|
||||||
|
import Data.Aeson
|
||||||
|
import Data.Aeson.Types
|
||||||
|
import Data.Text as T
|
||||||
|
import Data.Aeson.Lens (key, nth)
|
||||||
|
import qualified Data.ByteString.Lazy.Internal as BL
|
||||||
|
|
||||||
|
data JSONResponse d = JSONResponse
|
||||||
|
{ resp_status :: T.Text
|
||||||
|
, resp_message :: T.Text
|
||||||
|
, response_data :: d
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
instance (FromJSON d) => FromJSON (JSONResponse d) where
|
||||||
|
parseJSON (Object v) = JSONResponse
|
||||||
|
<$> v .: "status"
|
||||||
|
<*> v .: "status_message"
|
||||||
|
<*> v .: "data"
|
||||||
|
parseJSON invalid =
|
||||||
|
prependFailure "parsing JSONResponse failed, "
|
||||||
|
(typeMismatch "Object" invalid)
|
||||||
|
|
||||||
|
data JSONListMovies = JSONListMovies
|
||||||
|
{ movies_count :: Int
|
||||||
|
, movies_limit :: Int
|
||||||
|
, page_number :: Int
|
||||||
|
, movies :: [JSONMovie]
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
instance FromJSON JSONListMovies where
|
||||||
|
parseJSON (Object v) = JSONListMovies
|
||||||
|
<$> v .: "movie_count"
|
||||||
|
<*> v .: "limit"
|
||||||
|
<*> v .: "page_number"
|
||||||
|
<*> v .: "movies"
|
||||||
|
parseJSON invalid =
|
||||||
|
prependFailure "parsing JSONListMovies failed, "
|
||||||
|
(typeMismatch "Object" invalid)
|
||||||
|
|
||||||
|
data JSONMovie = JSONMovie
|
||||||
|
{ movie_id :: Int
|
||||||
|
, movie_url :: T.Text
|
||||||
|
, imdb_code :: T.Text
|
||||||
|
, movie_title :: T.Text
|
||||||
|
, movie_year :: Int
|
||||||
|
, movie_rating :: Double
|
||||||
|
, movie_runtime :: Int
|
||||||
|
, movie_genres :: [T.Text]
|
||||||
|
, movie_summary :: T.Text
|
||||||
|
, movie_language :: T.Text
|
||||||
|
, movie_state :: T.Text
|
||||||
|
, movie_torrents :: [JSONTorrent]
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
instance FromJSON JSONMovie where
|
||||||
|
parseJSON (Object v) = JSONMovie
|
||||||
|
<$> v .: "id"
|
||||||
|
<*> v .: "url"
|
||||||
|
<*> v .: "imdb_code"
|
||||||
|
<*> v .: "title"
|
||||||
|
<*> v .: "year"
|
||||||
|
<*> v .: "rating"
|
||||||
|
<*> v .: "runtime"
|
||||||
|
<*> v .: "genres"
|
||||||
|
<*> v .: "summary"
|
||||||
|
<*> v .: "language"
|
||||||
|
<*> v .: "state"
|
||||||
|
<*> v .: "torrents"
|
||||||
|
parseJSON invalid =
|
||||||
|
prependFailure "parsing JSONMovie failed, "
|
||||||
|
(typeMismatch "Object" invalid)
|
||||||
|
|
||||||
|
data JSONTorrent = JSONTorrent
|
||||||
|
{ torrent_url :: T.Text
|
||||||
|
, torrent_hash :: T.Text
|
||||||
|
, torrent_quality :: T.Text
|
||||||
|
, torrent_type :: T.Text
|
||||||
|
, torrent_seeds :: Int
|
||||||
|
, torrent_peers :: Int
|
||||||
|
, torrent_size :: T.Text
|
||||||
|
, torrent_bytes :: Int
|
||||||
|
, torrent_uploaded :: T.Text
|
||||||
|
, torrent_uploaded_unix :: Int -- TODO: better date type?
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
instance FromJSON JSONTorrent where
|
||||||
|
parseJSON (Object v) = JSONTorrent
|
||||||
|
<$> v .: "url"
|
||||||
|
<*> v .: "hash"
|
||||||
|
<*> v .: "quality"
|
||||||
|
<*> v .: "type"
|
||||||
|
<*> v .: "seeds"
|
||||||
|
<*> v .: "peers"
|
||||||
|
<*> v .: "size"
|
||||||
|
<*> v .: "size_bytes"
|
||||||
|
<*> v .: "date_uploaded"
|
||||||
|
<*> v .: "date_uploaded_unix"
|
||||||
|
parseJSON invalid =
|
||||||
|
prependFailure "parsing JSONTorrent failed, "
|
||||||
|
(typeMismatch "Object" invalid)
|
24
src/Request.hs
Normal file
24
src/Request.hs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module Request where
|
||||||
|
|
||||||
|
import JSONTypes
|
||||||
|
|
||||||
|
import Network.Wreq
|
||||||
|
import Control.Lens
|
||||||
|
import Data.Aeson
|
||||||
|
import Data.Text as T
|
||||||
|
import Data.Aeson.Lens (key, nth)
|
||||||
|
import qualified Data.ByteString.Lazy.Internal as BL
|
||||||
|
|
||||||
|
testFunc :: IO (JSONResponse JSONListMovies)
|
||||||
|
testFunc = do
|
||||||
|
r <- asJSON =<< get "https://yts.mx/api/v2/list_movies.json"
|
||||||
|
pure $ r ^. responseBody
|
||||||
|
|
||||||
|
getMovies :: IO (Either T.Text JSONListMovies)
|
||||||
|
getMovies = do
|
||||||
|
r <- asJSON =<< get "https://yts.mx/api/v2/list_movies.json"
|
||||||
|
pure $ case (r ^. responseBody) of
|
||||||
|
(JSONResponse "ok" _ d) -> Right d
|
||||||
|
(JSONResponse _ m _) -> Left m
|
4
test/MyLibTest.hs
Normal file
4
test/MyLibTest.hs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = putStrLn "Test suite not yet implemented."
|
Loading…
Reference in New Issue
Block a user