commit 12947ba2bd37d750ede244943b45a668616a612c Author: nisstyre56 Date: Fri Jun 26 17:07:50 2015 -0400 First commit Basically bare functionality diff --git a/Main.hs b/Main.hs new file mode 100644 index 0000000..d8881b8 --- /dev/null +++ b/Main.hs @@ -0,0 +1,122 @@ +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) +import Data.Aeson +import qualified Data.ByteString.Lazy.Char8 as BL +import qualified Data.Text as T +import qualified Data.Map as M + +data URL = URL { jurl :: T.Text } + deriving (Show, Eq) + +data VideoID = VideoID { videoID :: T.Text } + deriving (Show, Eq) + +data Thumbnail = Thumbnail { thumbnail :: URL } + deriving (Show, Eq) + +data JSearchResult = JSearchResult { + jvideoID :: VideoID, + snippet :: Snippet +} + deriving (Show, Eq) + +data Snippet = Snippet { + jtitle :: T.Text, + jdescription :: T.Text, + jthumbnails :: Thumbnail +} + deriving (Show, Eq) + +data JItems = JItems [JSearchResult] + deriving (Show) + +data SearchResult = SearchResult { + title :: T.Text, + description :: T.Text, + url :: T.Text, + thumb :: T.Text +} + deriving (Show, Eq) + +instance FromJSON URL where + parseJSON (Object v) = URL <$> v .: "url" + +instance FromJSON Thumbnail where + parseJSON (Object v) = Thumbnail <$> v .: "default" + +instance FromJSON VideoID where + parseJSON (Object v) = VideoID <$> + v .: "videoId" + +instance FromJSON Snippet where + parseJSON (Object v) = Snippet <$> + v .: "title" <*> + v .: "description" <*> + v .: "thumbnails" + +instance FromJSON JSearchResult where + parseJSON (Object v) = JSearchResult <$> + (v .: "id") <*> + (v .: "snippet") + +instance FromJSON JItems where + parseJSON (Object v) = JItems <$> v .: "items" + +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 = "./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 + + + +main = 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) + tokens2 <- refreshTokens client tokens + putStrLn $ "As a test, refreshed token: " ++ show (accessToken tokens2) + writeFile file (show tokens2) + accessTok <- fmap (accessToken . read) (readFile file) + findTracks accessTok "Foo+Fighters" + +findTracks accessTok term = do + response <- simpleHttp $ searchRequest term accessTok + return $ getItems response + +search :: String -> [T.Text] +search term = undefined diff --git a/cabal.sandbox.config b/cabal.sandbox.config new file mode 100644 index 0000000..83df4e6 --- /dev/null +++ b/cabal.sandbox.config @@ -0,0 +1,25 @@ +-- This is a Cabal package environment file. +-- THIS FILE IS AUTO-GENERATED. DO NOT EDIT DIRECTLY. +-- Please create a 'cabal.config' file in the same directory +-- if you want to change the default settings for this sandbox. + + +local-repo: /home/wes/youtube-mpd/.cabal-sandbox/packages +logs-dir: /home/wes/youtube-mpd/.cabal-sandbox/logs +world-file: /home/wes/youtube-mpd/.cabal-sandbox/world +user-install: False +package-db: /home/wes/youtube-mpd/.cabal-sandbox/x86_64-linux-ghc-7.10.1-packages.conf.d +build-summary: /home/wes/youtube-mpd/.cabal-sandbox/logs/build.log + +install-dirs + prefix: /home/wes/youtube-mpd/.cabal-sandbox + bindir: $prefix/bin + libdir: $prefix/lib + libsubdir: $abi/$pkgkey + libexecdir: $prefix/libexec + datadir: $prefix/share + datasubdir: $abi/$pkgid + docdir: $datadir/doc/$abi/$pkgid + htmldir: $docdir/html + haddockdir: $htmldir + sysconfdir: $prefix/etc diff --git a/youtube-mpd.cabal b/youtube-mpd.cabal new file mode 100644 index 0000000..14bc163 --- /dev/null +++ b/youtube-mpd.cabal @@ -0,0 +1,11 @@ +Name: youtube-mpd +Version: 0.1 +Cabal-Version: >= 1.2 +License: GPL-3 +Author: Wesley Kerfoot +Synopsis: play youtube music easier +Build-Type: Simple + +Executable youtube-mpd + Build-Depends: base, handa-gdata, process, directory, http-conduit, bytestring, aeson, containers, text + Main-Is: Main.hs