module Vimeta.UI.CommandLine.TV
( Options,
optionsParser,
run,
)
where
import Network.API.TheMovieDB
import Options.Applicative
import Vimeta.Core
import Vimeta.UI.CommandLine.Common
import Vimeta.UI.Common.TV
import Vimeta.UI.Term.TV
data Options = Options
{ Options -> Maybe ItemID
optsTVID :: Maybe ItemID,
Options -> Maybe ItemID
optsStartSeason :: Maybe Int,
Options -> Maybe ItemID
optsStartEpisode :: Maybe Int,
Options -> Maybe FilePath
optsMappingFile :: Maybe FilePath,
Options -> [FilePath]
optsFiles :: [FilePath],
Options -> CommonOptions
optsCommon :: CommonOptions
}
optionsParser :: Parser Options
optionsParser :: Parser Options
optionsParser =
Maybe ItemID
-> Maybe ItemID
-> Maybe ItemID
-> Maybe FilePath
-> [FilePath]
-> CommonOptions
-> Options
Options (Maybe ItemID
-> Maybe ItemID
-> Maybe ItemID
-> Maybe FilePath
-> [FilePath]
-> CommonOptions
-> Options)
-> Parser (Maybe ItemID)
-> Parser
(Maybe ItemID
-> Maybe ItemID
-> Maybe FilePath
-> [FilePath]
-> CommonOptions
-> Options)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ItemID -> Parser (Maybe ItemID)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ReadM ItemID -> Mod OptionFields ItemID -> Parser ItemID
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM ItemID
forall a. Read a => ReadM a
auto Mod OptionFields ItemID
forall a. Mod OptionFields a
infoTVID)
Parser
(Maybe ItemID
-> Maybe ItemID
-> Maybe FilePath
-> [FilePath]
-> CommonOptions
-> Options)
-> Parser (Maybe ItemID)
-> Parser
(Maybe ItemID
-> Maybe FilePath -> [FilePath] -> CommonOptions -> Options)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ItemID -> Parser (Maybe ItemID)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ReadM ItemID -> Mod OptionFields ItemID -> Parser ItemID
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM ItemID
forall a. Read a => ReadM a
auto Mod OptionFields ItemID
forall a. Mod OptionFields a
infoStartSeason)
Parser
(Maybe ItemID
-> Maybe FilePath -> [FilePath] -> CommonOptions -> Options)
-> Parser (Maybe ItemID)
-> Parser
(Maybe FilePath -> [FilePath] -> CommonOptions -> Options)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ItemID -> Parser (Maybe ItemID)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ReadM ItemID -> Mod OptionFields ItemID -> Parser ItemID
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM ItemID
forall a. Read a => ReadM a
auto Mod OptionFields ItemID
forall a. Mod OptionFields a
infoStartEpisode)
Parser (Maybe FilePath -> [FilePath] -> CommonOptions -> Options)
-> Parser (Maybe FilePath)
-> Parser ([FilePath] -> CommonOptions -> Options)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption Mod OptionFields FilePath
forall a. Mod OptionFields a
infoMappingFile)
Parser ([FilePath] -> CommonOptions -> Options)
-> Parser [FilePath] -> Parser (CommonOptions -> Options)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath -> Parser [FilePath]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (ReadM FilePath -> Mod ArgumentFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod ArgumentFields a -> Parser a
argument ReadM FilePath
forall s. IsString s => ReadM s
str (FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"[FILE...]"))
Parser (CommonOptions -> Options)
-> Parser CommonOptions -> Parser Options
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser CommonOptions
commonOptions
where
infoTVID :: Mod OptionFields a
infoTVID =
Char -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'i' Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"id" Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"ID"
Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Series ID assigned by TheMovieDB.org"
infoStartSeason :: Mod OptionFields a
infoStartSeason =
Char -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
's' Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"season" Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"NUM"
Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Starting season number"
infoStartEpisode :: Mod OptionFields a
infoStartEpisode =
Char -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'e' Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"episode" Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"NUM"
Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Starting episode number"
infoMappingFile :: Mod OptionFields a
infoMappingFile =
Char -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'm' Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"map" Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILE"
Mod OptionFields a -> Mod OptionFields a -> Mod OptionFields a
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields a
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"File to map files to seasons/episodes"
run :: Options -> IO (Either String ())
run :: Options -> IO (Either FilePath ())
run Options
opts = (Config -> Config) -> Vimeta IO () -> IO (Either FilePath ())
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
(Config -> Config) -> Vimeta m a -> m (Either FilePath a)
execVimeta (CommonOptions -> Config -> Config
updateConfig (CommonOptions -> Config -> Config)
-> CommonOptions -> Config -> Config
forall a b. (a -> b) -> a -> b
$ Options -> CommonOptions
optsCommon Options
opts) (Vimeta IO () -> IO (Either FilePath ()))
-> Vimeta IO () -> IO (Either FilePath ())
forall a b. (a -> b) -> a -> b
$ do
TV
tv <- case Options -> Maybe ItemID
optsTVID Options
opts of
Maybe ItemID
Nothing -> Vimeta IO TV
forall (m :: * -> *). MonadIO m => Vimeta m TV
tvSearch
Just ItemID
n -> TheMovieDB TV -> Vimeta IO TV
forall (m :: * -> *) a. MonadIO m => TheMovieDB a -> Vimeta m a
tmdb (ItemID -> TheMovieDB TV
fetchFullTVSeries ItemID
n)
case Options -> Maybe FilePath
optsMappingFile Options
opts of
Maybe FilePath
Nothing -> Options -> TV -> Vimeta IO ()
forall (m :: * -> *). MonadIO m => Options -> TV -> Vimeta m ()
fromFiles Options
opts TV
tv
Just FilePath
fn -> Options -> TV -> FilePath -> Vimeta IO ()
forall (m :: * -> *).
MonadIO m =>
Options -> TV -> FilePath -> Vimeta m ()
fromMappingFile Options
opts TV
tv FilePath
fn
fromFiles :: (MonadIO m) => Options -> TV -> Vimeta m ()
fromFiles :: Options -> TV -> Vimeta m ()
fromFiles Options
opts TV
tv = case (Options -> Maybe ItemID
optsStartSeason Options
opts, Options -> Maybe ItemID
optsStartEpisode Options
opts) of
(Just ItemID
s, Maybe ItemID
Nothing) -> TV -> EpisodeSpec -> [FilePath] -> Vimeta m ()
forall (m :: * -> *).
MonadIO m =>
TV -> EpisodeSpec -> [FilePath] -> Vimeta m ()
tagWithFileOrder TV
tv (ItemID -> ItemID -> EpisodeSpec
EpisodeSpec ItemID
s ItemID
1) (Options -> [FilePath]
optsFiles Options
opts)
(Just ItemID
s, Just ItemID
e) -> TV -> EpisodeSpec -> [FilePath] -> Vimeta m ()
forall (m :: * -> *).
MonadIO m =>
TV -> EpisodeSpec -> [FilePath] -> Vimeta m ()
tagWithFileOrder TV
tv (ItemID -> ItemID -> EpisodeSpec
EpisodeSpec ItemID
s ItemID
e) (Options -> [FilePath]
optsFiles Options
opts)
(Maybe ItemID
_, Maybe ItemID
_) -> FilePath -> Vimeta m ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError FilePath
"please use the --season option"
fromMappingFile :: (MonadIO m) => Options -> TV -> FilePath -> Vimeta m ()
fromMappingFile :: Options -> TV -> FilePath -> Vimeta m ()
fromMappingFile Options
opts TV
tv FilePath
filename = do
Bool -> Vimeta m () -> Vimeta m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([FilePath] -> Bool) -> [FilePath] -> Bool
forall a b. (a -> b) -> a -> b
$ Options -> [FilePath]
optsFiles Options
opts) (Vimeta m () -> Vimeta m ()) -> Vimeta m () -> Vimeta m ()
forall a b. (a -> b) -> a -> b
$
FilePath -> Vimeta m ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError FilePath
"don't give file arguments when using a mapping file"
TV -> FilePath -> Vimeta m ()
forall (m :: * -> *). MonadIO m => TV -> FilePath -> Vimeta m ()
tagWithMappingFile TV
tv FilePath
filename