packages feed

gopro-plus 0.3.0.1 → 0.3.1.0

raw patch · 3 files changed

+155/−78 lines, 3 filesdep +raw-strings-qqPVP ok

version bump matches the API change (PVP)

Dependencies added: raw-strings-qq

API changes (from Hackage documentation)

+ GoPro.Plus.Media: Moment :: Text -> Maybe Int -> Moment
+ GoPro.Plus.Media: [_moment_id] :: Moment -> Text
+ GoPro.Plus.Media: [_moment_time] :: Moment -> Maybe Int
+ GoPro.Plus.Media: data Moment
+ GoPro.Plus.Media: instance Data.Aeson.Types.FromJSON.FromJSON GoPro.Plus.Media.Moment
+ GoPro.Plus.Media: instance Data.Aeson.Types.FromJSON.FromJSON GoPro.Plus.Media.Moments
+ GoPro.Plus.Media: instance Data.Aeson.Types.ToJSON.ToJSON GoPro.Plus.Media.Moment
+ GoPro.Plus.Media: instance GHC.Classes.Eq GoPro.Plus.Media.PageInfo
+ GoPro.Plus.Media: instance GHC.Generics.Generic GoPro.Plus.Media.Moment
+ GoPro.Plus.Media: instance GHC.Show.Show GoPro.Plus.Media.Moment
+ GoPro.Plus.Media: moment_id :: Lens' Moment Text
+ GoPro.Plus.Media: moment_time :: Lens' Moment (Maybe Int)
+ GoPro.Plus.Media: moments :: (HasGoProAuth m, MonadIO m) => MediumID -> m [Moment]

Files

gopro-plus.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.33.0. -- -- see: https://github.com/sol/hpack ----- hash: aad6d39dfff268773a2546434545e5c4ef4a88e542724369091bd0a343e5f2e6+-- hash: 127fa4201fe98756bd46ca02b48f05168aac1d43f403d89bac1e8c5997f147a5  name:           gopro-plus-version:        0.3.0.1+version:        0.3.1.0 synopsis:       GoPro Plus Client API. description:    Please see the README on GitHub at <https://github.com/dustin/gopro-plus#readme> category:       Web@@ -86,6 +86,7 @@     , lens-aeson     , mtl     , random+    , raw-strings-qq     , retry     , tasty     , tasty-hunit
src/GoPro/Plus/Media.hs view
@@ -36,6 +36,7 @@   FileStuff(..), files, variations, sprites, sidecar_files,   FileInfo(..), fileStuff, filename,   Error(..), error_reason, error_code, error_description, error_id,+  Moment(..), moment_id, moment_time, moments,   -- * Low-level Junk   putMedium   ) where@@ -66,12 +67,13 @@ import           GoPro.Plus.Internal.AuthHTTP import           GoPro.Plus.Internal.HTTP -data PageInfo = PageInfo {-  _current_page :: Int,-  _per_page     :: Int,-  _total_items  :: Int,-  _total_pages  :: Int-  } deriving (Generic, Show)+data PageInfo = PageInfo+    { _current_page :: Int+    , _per_page     :: Int+    , _total_items  :: Int+    , _total_pages  :: Int+    }+    deriving (Generic, Show, Eq)  makeLenses ''PageInfo @@ -80,8 +82,12 @@  type MediumID = T.Text -data MediumType = Photo | Video | TimeLapse | TimeLapseVideo | Burst-  deriving (Show, Read, Eq)+data MediumType = Photo+    | Video+    | TimeLapse+    | TimeLapseVideo+    | Burst+    deriving (Show, Read, Eq)  instance ToJSON MediumType where   toJSON = J.String . T.pack . show@@ -90,9 +96,14 @@   parseJSON (J.String x) = pure . read . T.unpack $ x   parseJSON invalid      = typeMismatch "Response" invalid -data ReadyToViewType = ViewReady | ViewFailure | ViewLoading-                     | ViewRegistered | ViewTranscoding | ViewProcessing | ViewUploading-  deriving (Show, Read, Eq)+data ReadyToViewType = ViewReady+    | ViewFailure+    | ViewLoading+    | ViewRegistered+    | ViewTranscoding+    | ViewProcessing+    | ViewUploading+    deriving (Show, Read, Eq)  instance ToJSON ReadyToViewType where   toJSON = J.String . T.pack . fmap toLower . drop 4 . show@@ -103,20 +114,21 @@           trans []     = error "empty ready to view type"   parseJSON invalid      = typeMismatch "Response" invalid -data Medium = Medium {-  _medium_id              :: MediumID,-  _medium_camera_model    :: Maybe String,-  _medium_captured_at     :: UTCTime,-  _medium_created_at      :: UTCTime,-  _medium_file_size       :: Maybe Int,-  _medium_moments_count   :: Int,-  _medium_ready_to_view   :: ReadyToViewType,-  _medium_source_duration :: Maybe String,-  _medium_type            :: MediumType,-  _medium_token           :: String,-  _medium_width           :: Maybe Int,-  _medium_height          :: Maybe Int-  } deriving (Generic, Show)+data Medium = Medium+    { _medium_id              :: MediumID+    , _medium_camera_model    :: Maybe String+    , _medium_captured_at     :: UTCTime+    , _medium_created_at      :: UTCTime+    , _medium_file_size       :: Maybe Int+    , _medium_moments_count   :: Int+    , _medium_ready_to_view   :: ReadyToViewType+    , _medium_source_duration :: Maybe String+    , _medium_type            :: MediumType+    , _medium_token           :: String+    , _medium_width           :: Maybe Int+    , _medium_height          :: Maybe Int+    }+    deriving (Generic, Show)  makeLenses ''Medium @@ -143,10 +155,11 @@   n <- liftIO $ getStdRandom (randomR (1,4))   proxyAuth (thumbnailURL n m) -data Listing = Listing {-  _media :: [Medium],-  _pages :: PageInfo-  } deriving (Generic, Show)+data Listing = Listing+    { _media :: [Medium]+    , _pages :: PageInfo+    }+    deriving (Generic, Show)  makeLenses ''Listing @@ -181,14 +194,15 @@           else pure m'  -data File = File {-  _file_camera_position :: String,-  _file_height          :: Int,-  _file_width           :: Int,-  _file_item_number     :: Int,-  _file_orientation     :: Int,-  _file_url             :: String-  } deriving (Generic, Show)+data File = File+    { _file_camera_position :: String+    , _file_height          :: Int+    , _file_width           :: Int+    , _file_item_number     :: Int+    , _file_orientation     :: Int+    , _file_url             :: String+    }+    deriving (Generic, Show)  makeLenses  ''File @@ -197,14 +211,15 @@     fieldLabelModifier = dropPrefix "_file_"     } -data Variation = Variation {-  _var_height  :: Int,-  _var_width   :: Int,-  _var_label   :: String,-  _var_quality :: String,-  _var_type    :: String,-  _var_url     :: String-  } deriving(Generic, Show)+data Variation = Variation+    { _var_height  :: Int+    , _var_width   :: Int+    , _var_label   :: String+    , _var_quality :: String+    , _var_type    :: String+    , _var_url     :: String+    }+    deriving (Generic, Show)  makeLenses ''Variation @@ -213,11 +228,12 @@   fieldLabelModifier = dropPrefix "_var_"   } -data SpriteFrame = SpriteFrame {-  _frame_count  :: Int,-  _frame_height :: Int,-  _frame_width  :: Int-  } deriving(Generic, Show)+data SpriteFrame = SpriteFrame+    { _frame_count  :: Int+    , _frame_height :: Int+    , _frame_width  :: Int+    }+    deriving (Generic, Show)  makeLenses ''SpriteFrame @@ -226,14 +242,15 @@     fieldLabelModifier = dropPrefix "_frame_"   } -data Sprite = Sprite {-  _sprite_fps    :: Double,-  _sprite_frame  :: SpriteFrame,-  _sprite_height :: Int,-  _sprite_width  :: Int,-  _sprite_type   :: String,-  _sprite_urls   :: [String]-  } deriving (Generic, Show)+data Sprite = Sprite+    { _sprite_fps    :: Double+    , _sprite_frame  :: SpriteFrame+    , _sprite_height :: Int+    , _sprite_width  :: Int+    , _sprite_type   :: String+    , _sprite_urls   :: [String]+    }+    deriving (Generic, Show)  makeLenses ''Sprite @@ -242,22 +259,24 @@     fieldLabelModifier = dropPrefix "_sprite_"   } -data FileStuff = FileStuff {-  _files         :: [File],-  _variations    :: [Variation],-  _sprites       :: [Sprite],-  _sidecar_files :: [Value]-  } deriving (Generic, Show)+data FileStuff = FileStuff+    { _files         :: [File]+    , _variations    :: [Variation]+    , _sprites       :: [Sprite]+    , _sidecar_files :: [Value]+    }+    deriving (Generic, Show)  makeLenses ''FileStuff  instance FromJSON FileStuff where   parseJSON = genericParseJSON jsonOpts -data FileInfo = FileInfo {-  _fileStuff :: FileStuff,-  _filename  :: String-  } deriving (Generic, Show)+data FileInfo = FileInfo+    { _fileStuff :: FileStuff+    , _filename  :: String+    }+    deriving (Generic, Show)  makeLenses ''FileInfo @@ -277,12 +296,13 @@ retrieve :: (HasGoProAuth m, FromJSON j, MonadIO m) => MediumID -> m j retrieve k = jgetAuth (dlURL k) -data Error = Error {-  _error_reason      :: String,-  _error_code        :: Int,-  _error_description :: String,-  _error_id          :: String-  } deriving (Generic, Show)+data Error = Error+    { _error_reason      :: String+    , _error_code        :: Int+    , _error_description :: String+    , _error_id          :: String+    }+    deriving (Generic, Show)  makeLenses ''Error @@ -321,3 +341,35 @@   where     v :: Value -> ()     v = const ()++-- | A moment of interestingness in a Medium.+data Moment = Moment+    { _moment_id   :: T.Text+    , _moment_time :: Maybe Int+    }+    deriving (Show, Generic)++makeLenses ''Moment++instance FromJSON Moment where+  parseJSON = genericParseJSON defaultOptions {+    fieldLabelModifier = dropPrefix "_moment_"+  }++instance ToJSON Moment where+  toEncoding = genericToEncoding jsonOpts{ fieldLabelModifier = dropPrefix "_moment_" }+  toJSON = genericToJSON jsonOpts{ fieldLabelModifier = dropPrefix "_moment_" }++newtype Moments = Moments { unMoments :: [Moment] }++instance FromJSON Moments where+  parseJSON (Object v) = do+    o <- v .: "_embedded"+    m <- o .: "moments"+    Moments <$> traverse parseJSON (V.toList m)++  parseJSON invalid    = typeMismatch "Response" invalid++-- | Get the moments for the given medium.+moments :: (HasGoProAuth m, MonadIO m) => MediumID -> m [Moment]+moments mid = unMoments <$> jgetAuth ("https://api.gopro.com/media/" <> T.unpack mid <> "/moments?fields=time")
test/Spec.hs view
@@ -1,10 +1,34 @@+{-# LANGUAGE QuasiQuotes #-}++import           Control.Lens+import qualified Data.Aeson            as J+import qualified Data.ByteString.Lazy  as BL+import           Text.RawString.QQ     (r)+ import           Test.Tasty import           Test.Tasty.HUnit import           Test.Tasty.QuickCheck as QC +import           GoPro.Plus.Media++exampleMedia :: BL.ByteString+exampleMedia = [r|+{"_pages":{"current_page":1,"per_page":100,"total_items":2169,"total_pages":22},+"_embedded":{"errors":[],"media":[+{"captured_at":"2020-04-06T15:51:32Z","content_title":"GOPR1991.MP4","content_type":null,"created_at":"2020-04-07T03:35:27Z","gopro_user_id":"uid","file_size":412808724,"height":1080,"fov":null,"id":"62NzWRrpPXm7o","moments_count":0,"on_public_profile":false,"orientation":1,"play_as":"video","ready_to_edit":true,"ready_to_view":"ready","resolution":"1080p","source_duration":"109710","token":"token1","type":"Video","width":1920},+{"captured_at":"2020-04-06T00:33:22Z","content_title":null,"content_type":null,"created_at":"2020-04-06T01:39:39Z","gopro_user_id":"uid","file_size":7930021,"height":3000,"fov":null,"id":"EDavpqr4GVe8O","moments_count":0,"on_public_profile":false,"orientation":1,"play_as":"photo","ready_to_edit":true,"ready_to_view":"ready","resolution":"12000000","source_duration":"0","token":"token2","type":"Photo","width":4000}]}}+|]++testSearchParser :: Assertion+testSearchParser = do+  let l = J.decode exampleMedia :: Maybe Listing+  assertEqual (show l) (Just (PageInfo 1 100 2169 22)) (l ^? _Just . pages)+  assertEqual (show l) [Video, Photo] (l ^.. _Just . media . folded . medium_type)+  assertEqual (show l) ["62NzWRrpPXm7o", "EDavpqr4GVe8O"] (l ^.. _Just . media . folded . medium_id)+ tests :: [TestTree] tests = [-    testProperty "a test property" (\x -> (x::Int) == id x)+    testCase "Parsing" testSearchParser     ]  main :: IO ()