packages feed

roku-api (empty) → 0.1.0.0

raw patch · 7 files changed

+290/−0 lines, 7 filesdep +basedep +bytestringdep +http-clientsetup-changed

Dependencies added: base, bytestring, http-client, network, text, xml, xml-extractors

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Brian McKenna++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Brian McKenna nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Network/Roku.hs view
@@ -0,0 +1,10 @@+module Network.Roku+  ( module Network.Roku.App+  , module Network.Roku.Keys+  , module Network.Roku.Request+  )+where++import Network.Roku.App+import Network.Roku.Keys+import Network.Roku.Request
+ Network/Roku/App.hs view
@@ -0,0 +1,62 @@+module Network.Roku.App where++import Control.Applicative+import Data.Text+import Text.XML.Light.Extractors++newtype AppId+  = AppId Text+  deriving Show++data AppType+  = Appl+  | Ssvr+  deriving Show++newtype AppVersion+  = AppVersion Text+  deriving Show++newtype AppName+  = AppName Text+  deriving Show++data App+  = App AppId AppType AppVersion AppName+  deriving Show++data AppOrHomescreen+  = NormalApp App+  | Homescreen+  deriving Show++data Screensaver+  = Screensaver App+  deriving Show++data ActiveAppResponse+  = ActiveAppResponse AppOrHomescreen (Maybe Screensaver)+  deriving Show++appBodyParser :: ElementExtractor App+appBodyParser = do+  let p = Right . pack+  i <- attribAs "id" p+  let t' "appl" = Right Appl+      t' "ssvr" = Right Ssvr+      t' t = Left t+  t <- attribAs "type" t'+  v <- attribAs "version" p+  n <- contents $ textAs p+  return $ App (AppId i) t (AppVersion v) (AppName n)++appsParser :: ContentsExtractor [App]+appsParser =+  element "apps" . children . many $ element "app" appBodyParser++activeAppParser :: ContentsExtractor ActiveAppResponse+activeAppParser =+  element "active-app" . children $ do+    app <- optional $ element "app" appBodyParser+    ssvr <- optional $ element "screensaver" appBodyParser+    return $ ActiveAppResponse (maybe Homescreen NormalApp app) $ Screensaver <$> ssvr
+ Network/Roku/Keys.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE OverloadedStrings #-}+module Network.Roku.Keys where++import Prelude hiding (Either(..))+import Data.ByteString.Char8++data Key+  = Home+  | Rev+  | Fwd+  | Play+  | Select+  | Left+  | Right+  | Down+  | Up+  | Back+  | InstantReplay+  | Info+  | Backspace+  | Search+  | Enter+  | Lit Char+  deriving Show++keyValue :: Key -> ByteString+keyValue Home =+  "Home"+keyValue Rev =+  "Rev"+keyValue Fwd =+  "Fwd"+keyValue Play =+  "Play"+keyValue Select =+  "Select"+keyValue Left =+  "Left"+keyValue Right =+  "Right"+keyValue Down =+  "Down"+keyValue Up =+  "Up"+keyValue Back =+  "Back"+keyValue InstantReplay =+  "InstantReplay"+keyValue Info =+  "Info"+keyValue Backspace =+  "Backspace"+keyValue Search =+  "Search"+keyValue Enter =+  "Enter"+keyValue (Lit c) =+  snoc "Lit_" c
+ Network/Roku/Request.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE OverloadedStrings #-}+module Network.Roku.Request+  ( Query(..)+  , Method(..)+  , Request(..)+  , Resource(..)+  , request+  , resource+  , QueryError(..)+  , queryActiveApp+  , queryApps+  )+where++import Data.ByteString+import Data.Semigroup+import Data.Text.Encoding+import Data.Bifunctor+import Network.Roku.App+import Text.XML.Light.Extractors+import Text.XML.Light.Input+import qualified Data.ByteString.Lazy as LBS+import qualified Network.HTTP.Client as HTTP+import qualified Network.Roku.Keys as Keys++data Query+  = Apps+  | ActiveApp+  | Icon AppId+  deriving Show++data Method+  = Get+  | Post+  deriving Show++data Request+  = Query Query+  | Keyup Keys.Key+  | Keydown Keys.Key+  | Keypress Keys.Key+  | Launch AppId+  | Install AppId+  deriving Show++data Resource+  = Resource Method ByteString+  deriving Show++resource :: Request -> Resource+resource (Query query) =+  Resource Get $ "query/" <> path+  where path = case query of+          Apps -> "apps"+          ActiveApp -> "active-app"+          Icon (AppId appId) -> "icon/" <> encodeUtf8 appId+resource (Keyup key) =+  Resource Post $ "keyup/" <> Keys.keyValue key+resource (Keydown key) =+  Resource Post $ "keydown/" <> Keys.keyValue key+resource (Keypress key) =+  Resource Post $ "keypress/" <> Keys.keyValue key+resource (Launch (AppId appId)) =+  Resource Post $ "launch/" <> encodeUtf8 appId+resource (Install (AppId appId)) =+  Resource Post $ "install/" <> encodeUtf8 appId++data QueryError+  = QueryInvalidXML LBS.ByteString+  | QueryExtractionErr ExtractionErr+  deriving Show++request :: Request -> ByteString -> HTTP.Request+request r host =+  HTTP.defaultRequest { HTTP.host = host+                      , HTTP.method = method'+                      , HTTP.path = path+                      , HTTP.port = 8060+                      }+  where Resource method path = resource r+        method' = case method of+          Post -> "POST"+          Get -> "GET"++runQuery :: Query -> ContentsExtractor a -> ByteString -> HTTP.Manager -> IO (Either QueryError a)+runQuery q p host manager = do+  r <- HTTP.httpLbs (request (Query q) host) manager+  let body = HTTP.responseBody r+  return $ do+    doc <- maybe (Left $ QueryInvalidXML body) Right $ parseXMLDoc body+    first QueryExtractionErr $ extractDocContents p doc++queryActiveApp :: ByteString -> HTTP.Manager -> IO (Either QueryError ActiveAppResponse)+queryActiveApp = do+  runQuery ActiveApp activeAppParser++queryApps :: ByteString -> HTTP.Manager -> IO (Either QueryError [App])+queryApps = do+  runQuery Apps appsParser
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ roku-api.cabal view
@@ -0,0 +1,29 @@+name:                roku-api+version:             0.1.0.0+synopsis:            Bindings to Roku's External Control API+description:         Bindings to Roku's External Control API.+license:             BSD3+license-file:        LICENSE+author:              Brian McKenna+maintainer:          brian@brianmckenna.org+category:            Network+build-type:          Simple+cabal-version:       >=1.10++library+  exposed-modules:     Network.Roku+                     , Network.Roku.App+                     , Network.Roku.Keys+                     , Network.Roku.Request+  build-depends:       base >=4.9 && <4.10+                     , bytestring+                     , http-client+                     , network+                     , text+                     , xml+                     , xml-extractors+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/puffnfresh/roku-api