module Search where import Control.Monad (unless) import System.Info (os) import System.Process (system, rawSystem) import System.Exit (ExitCode(..)) import System.Directory (doesFileExist) import Network.Google.OAuth2 (formUrl, exchangeCode, refreshTokens, OAuth2Client(..), OAuth2Tokens(..)) import Network.Google (makeRequest, doRequest) import Network.HTTP.Conduit (simpleHttp, HttpException) import Data.Aeson (decode) import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.Text as T import Control.Exception import Network.HTTP.Base (urlEncode, urlDecode) import Types makeURL :: T.Text -> T.Text makeURL vid = "https://youtube.com/watch?v=" `T.append` vid getItems :: BL.ByteString -> [SearchResult] getItems str = let parsed = decode str :: Maybe JItems in maybe [] getResults parsed where getResults (JItems xs) = map getResult xs getResult x = SearchResult (jtitle . snippet $ x) (jdescription . snippet $ x) (makeURL . videoID . jvideoID $ x) (jurl . thumbnail . jthumbnails . snippet $ x) cid = "571126085022-7ash7a48cdao0tesqe66ghtime34cfvo.apps.googleusercontent.com" secret = "FjgeOtSZoJgU87FbuwJf2vwj" file = "/home/wes/.config/youtube-tokens.txt" baseURI = "https://www.googleapis.com/youtube/v3/" searchRequest :: String -> String -> String searchRequest keyword accessTok = baseURI ++ "search?part=snippet&q=" ++ keyword ++ "&type=video&access_token=" ++ accessTok getNewTokens :: OAuth2Client -> IO OAuth2Tokens getNewTokens client = do tokens <- read <$> readFile file newTokens <- refreshTokens client tokens writeFile file (show newTokens) return newTokens findTracks :: OAuth2Client -> String -> String -> IO [SearchResult] findTracks client accessTok term = do response <- (try $ simpleHttp $ searchRequest term accessTok) :: IO (Either HttpException BL.ByteString) case response of (Left _) -> do tokens <- getNewTokens client findTracks client (accessToken tokens) term (Right resp) -> return $ getItems resp search :: String -> IO [SearchResult] search term = do let client = OAuth2Client { clientId = cid, clientSecret = secret } permissionUrl = formUrl client ["https://www.googleapis.com/auth/youtube"] b <- doesFileExist file unless b $ do putStrLn $ "Load this URL: " ++ show permissionUrl putStrLn "Please paste the verification code: " authcode <- getLine tokens <- exchangeCode client authcode putStrLn $ "Received access token: " ++ show (accessToken tokens) writeFile file (show tokens) accessTok <- fmap (accessToken . read) (readFile file) findTracks client accessTok (urlEncode term)