-- | Run shell programs
module Cut.Shell
  ( ffmpeg
  , ffmpeg'
  , floatToText
  , youtube_dl
  )
where

import           Data.Text (Text)
import qualified Data.Text as Text
import           Numeric
import           Shelly
import Network.URI(URI)

-- | Wrap ffmpeg for convenience and logging
--  technically supports multiple inputs but for convenice we threw that.
ffmpeg :: Prelude.FilePath -> [Text] -> Sh [Text]
ffmpeg :: FilePath -> [Text] -> Sh [Text]
ffmpeg file :: FilePath
file args :: [Text]
args = [Text] -> Sh [Text]
ffmpeg' ("-y" Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: "-i" Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: FilePath -> Text
Text.pack FilePath
file Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
args)

ffmpeg' :: [Text] -> Sh [Text]
ffmpeg' :: [Text] -> Sh [Text]
ffmpeg' args :: [Text]
args = do
  IO () -> Sh ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Sh ()) -> IO () -> Sh ()
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ()
putStr "Running: "
  IO () -> Sh ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Sh ()) -> IO () -> Sh ()
forall a b. (a -> b) -> a -> b
$ Text -> IO ()
forall a. Show a => a -> IO ()
print (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ "ffmpeg " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
Text.unwords [Text]
args
  FilePath -> [Text] -> Sh ()
run_ "ffmpeg" [Text]
args
  Text -> [Text]
Text.lines (Text -> [Text]) -> Sh Text -> Sh [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sh Text
lastStderr

-- | Format floats for cli
floatToText :: Double -> Text
floatToText :: Double -> Text
floatToText = FilePath -> Text
Text.pack (FilePath -> Text) -> (Double -> FilePath) -> Double -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> FilePath -> FilePath) -> FilePath -> Double -> FilePath
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Maybe Int -> Double -> FilePath -> FilePath
forall a. RealFloat a => Maybe Int -> a -> FilePath -> FilePath
showFFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just 10)) ""

youtube_dl :: URI -> FilePath -> Sh [Text]
youtube_dl :: URI -> FilePath -> Sh [Text]
youtube_dl uri :: URI
uri path' :: FilePath
path' = do
  IO () -> Sh ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Sh ()) -> IO () -> Sh ()
forall a b. (a -> b) -> a -> b
$ Text -> IO ()
forall a. Show a => a -> IO ()
print (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ "running youtube-dl " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
Text.unwords [Text]
args
  FilePath -> [Text] -> Sh ()
run_ "youtube-dl" [Text]
args
  Text -> [Text]
Text.lines (Text -> [Text]) -> Sh Text -> Sh [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sh Text
lastStderr
  where
    args :: [Text]
args = [FilePath -> Text
Text.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ URI -> FilePath
forall a. Show a => a -> FilePath
show URI
uri,
           "-o", FilePath -> Text
Text.pack FilePath
path']