VKHS 1.7.0 → 1.7.1
raw patch · 5 files changed
+219/−7 lines, 5 filesdep +aeson-prettydep +pretty-show
Dependencies added: aeson-pretty, pretty-show
Files
- CHANGELOG.md +22/−0
- README.md +171/−0
- VKHS.cabal +5/−2
- app/vkq/Main.hs +11/−4
- src/Web/VKHS/API/Base.hs +10/−1
+ CHANGELOG.md view
@@ -0,0 +1,22 @@+TODO+----++* Decrypt 'RepeatedForm' errors+* Show capchas to users if required+* Support simplified runhaskell-style scripting+++Version 1.7.1+-------------++* Support setting IDv2 tags for downloaded audio files+* CLI: Fix 'call' command output+* CLI: Fix 'music' command naming+++Version 1.6.0+-------------++* Use coroutine-based engine, offering smooth error handling+* Use pipes-http as network backend+
+ README.md view
@@ -0,0 +1,171 @@+VKHS+====++VKHS provides access to [Vkontakte][1] social network, popular mainly in Russia.+Library can be used to login into the network as a standalone application (OAuth+implicit flow as they call it). Having the access token, it is possible to call+various API methods to query audio files or retrieve wall messages. For now,+vkhs offers limited error detection and no captcha support.++Installing+==========++In order to install VKHS, type:++ $ cabal update+ $ cabal install VKHS++Note, that VKHS uses curlhs and should be linked with libcurl.so. Normally,+cabal handles it without problems.++VKQ+===++VKQ is a command line tool which demonstrates API usage. It can be used for+logging in, downloading music and reading wall messages.+++Log in+------++Here is an example session: Login first++ ]$ vkq login user@mail.org pass123+ d8a41221616ef5ba19537125dc0349bad9d529fa15314ad765911726fe98b15185ac41a7ca2c62f3bf4b9++VKQ returns three values. First is a access token which is required to execute+future API requests. VKQ reads it from VKQ\_ACCESS\_TOKEN environment variable so+we have to set it up++ $ export VKQ_ACCESS_TOKEN=d785932b871f096bd73aac6a35d7a7c469dd788d796463a871e5beb5c61bc6c96788ec2++Download audio+--------------++Now, lets list first 10 audio files I have:++ $ vkq music -l | head -n 10+ 910727_456939044 http://cs1-29v4.vk-cdn.net/p36/d36d0fac4baf0d.mp3 Алёнушка 1989 муз Никиты Богословского - ст Александра Коваленкова+ 910727_456939043 http://cs1-35v4.vk-cdn.net/p7/2629cc1c9e82d7.mp3 Первое апреля+ 910727_456939042 http://cs5078.vk.me/u39450508/audios/b65093a7caea.mp3 Травы травы травы не успели от росы серебрянной согнуться и такие нежные напевы почему-то прямо в сердце льются+ 910727_456939041 http://cs1-35v4.vk-cdn.net/p12/423bca91340edc.mp3 Moving On+ 910727_456939038 http://cs1-37v4.vk-cdn.net/p5/23c658ff1d9a43.mp3 Не для меня придёт весна+ 910727_456939037 http://cs1-17v4.vk-cdn.net/p4/e67571789b026e.mp3 Каждый выбирает для себя+ 910727_456939034 http://cs536114.vk.me/u262757964/audios/8b0e36ee4ad5.mp3 Black Fortress Kings Bounty Dark Side OST+ 910727_456939031 http://cs613118.vk.me/u911727/audios/7bd0a650905e.mp3 Вокализ минус пример+ 910727_456939040 http://cs611628.vk.me/u911727/audios/d5a8eff365aa.mp3 Без названия+ 910727_456939028 http://cs536217.vk.me/u64604046/audios/a4ab2075af94.mp3 The Extasy of Gold++Ok, the link can be used to download the file using wget, but vkq offers+some renaming options, so lets use the latter instead:++ $ vkq music -o . 910727_456939043 910727_456939031+ 910727_456939043+ Polite Dance Song+ ./The Bird And The Bee - Polite Dance Song.mp3+ 910727_456939031+ L'estasi Dell'oro (The Ecstasy Of Gold)+ ./Ennio Morricone - Lestasi Delloro The Ecstasy Of Gold.mp3++Polite dance song and Ecstasy of gold mp3s will appear in the current folder.++Custom API calls+----------------++vkq allows user to call arbitrary API method. The format is as follows:++ Usage: vkq call [--verbose] [--req-per-sec N] [--interactive] [--appid APPID]+ [--user USER] [--pass PASS] [-a ACCESS_TOKEN] METHOD PARAMS+++For example, lets call ausio.search method to get some Beatles records:++ $ vkq call audio.search q=Beatles --pretty++ { "response": [+ 614751,+ {+ "lyrics_id": "6604412",+ "url": "http://cs1-36v4.vk-cdn.net/p16/59674dd8717db2.mp3?extra=k0s2ja3l6pq6aIDOEW5y5XUCs2--JLX9wZpzOT3iuSnZPR-DNhJSF075NUhICB_szMOKKlVJFFlqLlg691q6cKhwiGZgTRU1oAimXzXY396cfNAHnotc8--7w-0xnvoPK6qVoI8",+ "aid": 85031440,+ "title": "Twist and Shout ",+ "genre": 1,+ "owner_id": 9559206,+ "duration": 156,+ "artist": "The Beatles"+ },+ ...+++VKHS library+============++Please, consult the source code of the vkq application.++_Note: Outdated content below_++Following example illustrates basic usage (please fill client\_id, email and+password with correct values):++ import Web.VKHS.Login+ import Web.VKHS.API++ main = do+ let client_id = "111111"+ let e = env client_id "user@example.com" "password" [Photos,Audio,Groups]+ (Right at) <- login e++ let user_of_interest = "222222"+ (Right ans) <- api e at "users.get" [+ ("uids",user_of_interest)+ , ("fields","first_name,last_name,nickname,screen_name")+ , ("name_case","nom")+ ]+ putStrLn ans++client\_id is an application identifier, provided by vk.com. Users receive it+after registering their applications after SMS confirmation. Registration form is+located [here](http://vk.com/editapp?act=create).++Internally, library uses small curl-based HTTP automata and tagsoup for jumping+over relocations and submitting various 'Yes I agree' forms. Curl .so library is+required for vkhs to work. I am using curl-7.26.0 on my system.++Debugging+=========++`RepatedForm` message means that VKHS tries to fill the web form with available+data, but the form appears again. Typically, that means that the password wa+invalid or captcha is required.++_Note: Outdated content below_++To authenticate the user, vkhs acts like a browser: it analyzes html but fills+all forms by itself instead of displaying pages. Of cause, would vk.com change+html design, things stop working.++To deal with that potential problem, Ive included some debugging facilities:+changing:++writing++ (Right at) <- login e { verbose = Debug }++will trigger curl output plus html dumping to the current directory. Please,+mail those .html to me if problem appears.++Limitations+===========+* Implicit-flow authentication, see [documentation in+ Russian](http://vk.com/developers.php?oid=-1&p=Авторизация_клиентских_приложений)+ for details++License+=======++BSD3 license++Copyright (c) 2014, Sergey Mironov <grrwlf@gmail.com>++[1]: http://vk.com+
VKHS.cabal view
@@ -1,6 +1,6 @@ name: VKHS-version: 1.7.0+version: 1.7.1 synopsis: Provides access to Vkontakte social network via public API description: Provides access to Vkontakte API methods. Library requires no interaction@@ -15,6 +15,7 @@ build-type: Simple cabal-version: >=1.6 homepage: http://github.com/grwlf/vkhs+extra-source-files: CHANGELOG.md README.md library hs-source-dirs: src@@ -58,10 +59,12 @@ clock, optparse-applicative, aeson,+ aeson-pretty, vector, filepath, directory,- taglib+ taglib,+ pretty-show executable vkq hs-source-dirs: app/vkq, app/common, src
app/vkq/Main.hs view
@@ -24,6 +24,7 @@ import System.IO import Text.RegexPR import Text.Printf+import Text.Show.Pretty import Web.VKHS import Web.VKHS.Types@@ -43,6 +44,7 @@ data APIOptions = APIOptions { a_method :: String , a_args :: String+ , a_pretty :: Bool } deriving(Show) data LoginOptions = LoginOptions {@@ -92,8 +94,9 @@ api_cmd = (info (API <$> genericOptions <*> (APIOptions <$> argument str (metavar "METHOD" <> help "Method name")- <*> argument str (metavar "PARAMS" <> help "Method arguments, KEY=VALUE[,KEY2=VALUE2[,,,]]")))- ( progDesc "Call VK API method" ))+ <*> argument str (metavar "PARAMS" <> help "Method arguments, KEY=VALUE[,KEY2=VALUE2[,,,]]")+ <*> switch (long "pretty" <> help "Pretty print resulting JSON")))+ ( progDesc "Call VK API method" )) in subparser ( command "login" (info (Login <$> genericOptions_login <*> (LoginOptions@@ -187,11 +190,15 @@ True -> liftIO $ putStrLn $ printf "export %s=%s\n" env_access_token at_access_token False -> liftIO $ putStrLn at_access_token --- API+-- API / CALL cmd (API go APIOptions{..}) = do runAPI go $ do x <- apiJ a_method (map (id *** tpack) $ splitFragments "," "=" a_args)- liftIO $ putStrLn $ show x+ if a_pretty+ then do+ liftIO $ BS.putStrLn $ jsonEncodePretty x+ else+ liftIO $ BS.putStrLn $ jsonEncode x return () cmd (Music go@GenericOptions{..} mo@MusicOptions{..})
src/Web/VKHS/API/Base.hs view
@@ -24,12 +24,13 @@ import qualified Data.Text as Text import Data.ByteString.Char8 (ByteString)-import Data.ByteString.Lazy (fromStrict)+import Data.ByteString.Lazy (fromStrict,toChunks) import qualified Data.ByteString.Char8 as BS import Data.Aeson ((.=), (.:)) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Types as Aeson+import qualified Data.Aeson.Encode.Pretty as Aeson import Text.Printf @@ -121,3 +122,11 @@ api_S :: (Aeson.FromJSON a, MonadAPI m x s) => String -> [(String, String)] -> API m x a api_S m args = api m (map (id *** tpack) args)++-- Encode JSON back to string+jsonEncode :: JSON -> ByteString+jsonEncode JSON{..} = BS.concat $ toChunks $ Aeson.encode js_aeson++jsonEncodePretty :: JSON -> ByteString+jsonEncodePretty JSON{..} = BS.concat $ toChunks $ Aeson.encodePretty js_aeson+