packages feed

VKHS 1.9 → 1.9.1

raw patch · 10 files changed

+41/−68 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Web.VKHS.API.Base: apiD :: (FromJSON a, MonadAPI m x s) => a -> String -> [(String, Text)] -> API m x a
- Web.VKHS.API.Base: apiE :: (FromJSON a, MonadAPI m x s) => String -> [(String, Text)] -> API m x (Either (Response ErrorRecord) a)
- Web.VKHS.API.Base: api_S :: (FromJSON a, MonadAPI m x s) => String -> [(String, String)] -> API m x a
- Web.VKHS.Client: requestUploadPhoto :: (MonadClient m s) => Text -> ByteString -> m (Either Error Request)
+ Web.VKHS.Client: requestUploadPhoto :: (MonadClient m s) => Text -> String -> m (Either Error Request)

Files

CHANGELOG.md view
@@ -1,3 +1,7 @@+Version 1.9.1+-------------+* Fixed user photo uploading using `vkq photo`+ Version 1.9 ----------- 
README.md view
@@ -30,7 +30,7 @@ * Re-implement VK monad as a Free monad special case * Runhaskell: handle some standard command line arguments * Minor issues here and there. Use `git grep FIXME` to find them-* File uploading still not functioning.+* ~~File uploading still not functioning.~~ * Network connection timeout is not handled by the coroutine supervisor. * Enhance the way `vkq` accepts arguments, support multy-line messages. * Grammatical mistakes. Any corrections will be kindly accepted.@@ -162,7 +162,6 @@     {"response":57505}      $ vkq api "groups.search" "q=Haskell"-		$ vkq api "groups.search" "q=Haskell" --pretty     {         "response": [             30,
VKHS.cabal view
@@ -1,6 +1,6 @@  name:                VKHS-version:             1.9+version:             1.9.1 synopsis:            Provides access to Vkontakte social network via public API description:     Provides access to Vkontakte API methods. Library requires no interaction
app/vkq/Main.hs view
@@ -47,6 +47,8 @@ data PhotoOptions = PhotoOptions {     p_listAlbums :: Bool   , p_uploadServer :: Bool+  , p_setUserPhoto :: Bool+  , p_userPhoto :: String   } deriving(Show)  data Options@@ -63,7 +65,7 @@ toMaybe :: (Functor f) => f String -> f (Maybe String) toMaybe = fmap (\s -> if s == "" then Nothing else Just s) --- FIXME support --version flag+--    * FIXME support --version flag optdesc m =   let @@ -160,6 +162,8 @@     <> command "photo" (info ( Photo <$> genericOptions <*> (PhotoOptions       <$> flag False True (long "list-albums" <> help "List Albums")       <*> flag False True (long "upload-server" <> help "Get upload server")+      <*> flag False True (long "set-user-photo" <> help "Set user photo")+      <*> strOption (long "photo" <> help "User photo to set" <> value "")       ))       ( progDesc "Photo-related queries"))     )@@ -251,6 +255,9 @@       _ ->         error "Ivalid album" +  |p_setUserPhoto = do+    user <- getCurrentUser+    setUserPhoto user p_userPhoto+   |otherwise = do     error "invalid command line arguments"-
src/Web/VKHS.hs view
@@ -76,7 +76,7 @@ -- -- See also 'runVK' and 'defaultSupervisor`. ----- * FIXME Re-write using modern 'Monad.Free'+--    * FIXME Re-write using modern 'Monad.Free' newtype VK r a = VK { unVK :: Guts VK (StateT State (ExceptT Text IO)) r a }   deriving(MonadIO, Functor, Applicative, Monad, MonadState State, MonadReader (r -> VK r r) , MonadCont) @@ -96,9 +96,9 @@ -- -- See also 'runVK' ----- * FIXME Store known answers in external DB (in file?) instead of LoginState---   FIXME dictionary--- * FIXME Handle capthas (offer running standalone apps)+--    * FIXME Store known answers in external DB (in file?) instead of LoginState+--      FIXME dictionary+--    * FIXME Handle capthas (offer running standalone apps) defaultSupervisor :: (Show a) => VK (R VK a) (R VK a) -> StateT State (ExceptT Text IO) a defaultSupervisor = go where   go m = do
src/Web/VKHS/API/Base.hs view
@@ -74,7 +74,7 @@  -- | Utility function to parse JSON object ----- * FIXME Don't raise exception, simply return `Left err`+--    * FIXME Don't raise exception, simply return `Left err` decodeJSON :: (MonadAPI m x s)     => ByteString     -> API m x JSON@@ -89,9 +89,9 @@ -- <https://vk.com/dev/methods> -- <https://vk.com/dev/json_schema> ----- * FIXME We currentyl use Text.unpack to encode text into strings. Use encodeUtf8---   FIXME instead.--- * FIXME Split into request builder and request executer+--    * FIXME We currentyl use Text.unpack to encode text into strings. Use encodeUtf8+--      FIXME instead.+--    * FIXME Split into request builder and request executer apiJ :: (MonadAPI m x s)     => String     -- ^ API method name@@ -211,41 +211,6 @@     -> (ErrorRecord -> Maybe a)     -> API m x a apiH m args handler = apiHM m args (\e -> pure (handler e) :: API m x (Maybe a))---- | Invoke the request, return answer as a Haskell datatype or @ErrorRecord@--- object-apiE :: (Aeson.FromJSON a, MonadAPI m x s)-    => String           -- ^ API method name-    -> [(String, Text)] -- ^ API method arguments-    -> API m x (Either (Response ErrorRecord) a)-apiE m args = apiJ m args >>= convert where-  convert j = do-    err <- pure $ parseJSON j-    ans <- pure $ parseJSON j-    case  (ans, err) of-      (Right a, _) -> return (Right a)-      (Left a, Right e) -> return (Left e)-      (Left a, Left e) -> do-        j' <- raise (JSONCovertionFailure-                     (j, "apiE: " <> Text.pack m <> ": expecting either known response or error"))-        convert j'---- | Invoke the request, returns answer or the default value in case of error-apiD :: (Aeson.FromJSON a, MonadAPI m x s)-    => a-    -> String           -- ^ API method name-    -> [(String, Text)] -- ^ API method arguments-    -> API m x a-apiD def m args =-  apiE m args >>= \case-    Left err -> return def-    Right x -> return x---- | String version of @api@--- Deprecated-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 jsonEncodeBS :: JSON -> ByteString
src/Web/VKHS/API/Simple.hs view
@@ -128,15 +128,13 @@       True -> Right (head users)  --- * FIXME fix setUserPhoto, it is not actually working--- * FIXME move low-level upload code to API.Base+--    * FIXME move low-level upload code to API.Base setUserPhoto :: (MonadAPI m x s) => UserRecord -> FilePath -> API m x () setUserPhoto UserRecord{..} photo_path =  do-  photo <- liftIO $ BS.readFile photo_path   OwnerUploadServer{..} <-     resp_data <$> api "photos.getOwnerPhotoUploadServer"       [("owner_id", tshow ur_id)]-  req <- ensure $ requestUploadPhoto ous_upload_url photo+  req <- ensure $ requestUploadPhoto ous_upload_url photo_path   (res, _) <- requestExecute req   j@JSON{..} <- decodeJSON (responseBody res)   liftIO $ BS.putStrLn $ (responseBody res)@@ -150,6 +148,3 @@       ,("photo", upl_photo)]   PhotoSaveResult{..} <- pure resp_data   return ()---
src/Web/VKHS/Client.hs view
@@ -34,6 +34,7 @@ import qualified Data.ByteString.Char8 as BS  import Network.HTTP.Client ()+import qualified Network.HTTP.Client.MultipartFormData as Multipart import Network.HTTP.Client.Internal (setUri) import Network.HTTP.Client.TLS (tlsManagerSettings) import qualified Network.HTTP.Types as Client@@ -118,10 +119,12 @@   deriving(Show) newtype URL_Path = URL_Path { urlpath :: String }   deriving(Show)++-- | URL wrapper newtype URL = URL { uri :: Client.URI }   deriving(Show, Eq) --- * FIXME Pack Text to ByteStrings, not to String+--    * FIXME Pack Text to ByteStrings, not to String buildQuery :: [(String,String)] -> URL_Query buildQuery qis = URL_Query ("?" ++ intercalate "&" (map (\(a,b) -> (esc a) ++ "=" ++ (esc b)) qis)) where   esc x = Client.escapeURIString Client.isAllowedInURI x@@ -136,7 +139,7 @@     Nothing -> Left (ErrorParseURL s "Client.parseURI failed")     Just u -> Right (URL u) --- | * FIXME Convert to ByteString /  Text+-- |    * FIXME Convert to ByteString /  Text splitFragments :: String -> String -> String -> [(String,String)] splitFragments sep eqs =     filter (\(a, b) -> not (null a))@@ -151,7 +154,7 @@         trim = rev (dropWhile (`elem` (" \t\n\r" :: String)))           where rev f = reverse . f . reverse . f --- | * FIXME Convert to ByteString / Text+-- |    * FIXME Convert to ByteString / Text urlFragments :: URL -> [(String,String)] urlFragments URL{..} = splitFragments "&" "=" $  unsharp $ Client.uriFragment uri where   unsharp ('#':x) = x@@ -216,10 +219,10 @@  -- | Upload the bytestring data @bs@ to the server @text_url@ ----- * FIXME This function is not working. Looks like VK requires some other---   FIXME method rather than urlEncodedBody.--- * FIXME Use 'URL' rather than Text-requestUploadPhoto :: (MonadClient m s) => Text -> ByteString -> m (Either Error Request)+--     * FIXME Use 'URL' rather than Text. Think about+--       https://github.com/blamario/network-uri+--+requestUploadPhoto :: (MonadClient m s) => Text -> String -> m (Either Error Request) requestUploadPhoto text_url bs = do   case Client.parseURI (Text.unpack text_url) of     Nothing -> return (Left (ErrorParseURL (Text.unpack text_url) "parseURI failed"))@@ -229,7 +232,8 @@         Left err -> do           return $ Left err         Right Request{..} -> do-          return $ Right $ Request ((Client.urlEncodedBody [("photo", bs)]) req) req_jar+          req' <- Multipart.formDataBody [Multipart.partFile "photo" bs] req+          return $ Right $ Request req' req_jar  data Response = Response {     resp :: Client.Response (Pipes.Producer ByteString IO ())@@ -299,4 +303,3 @@   (Right Request{..}) <- requestCreateGet url (cookiesCreate ())   liftIO $ Pipes.withHTTP req cl_man $ \resp -> do       PP.foldM (\() a -> h a) (return ()) (const (return ())) (Client.responseBody resp)-
src/Web/VKHS/Error.hs view
@@ -31,8 +31,8 @@ -- needs to track two types: the early break @t@ and the current result @a@. -- In order to be runnable (e.g. by 'runVK') both types are need to be the same. ----- * FIXME re-implement the concept using `Monad.Free` library--- * FIMXE clean out of test/unused constructors+--    * FIXME re-implement the concept using `Monad.Free` library+--    * FIMXE clean out of test/unused constructors data Result t a =     Fine a   -- ^ The normal exit of a computation
src/Web/VKHS/Types.hs view
@@ -100,7 +100,7 @@  -- | JSON wrapper. ----- * FIXME  Implement full set of helper functions+--    * FIXME  Implement full set of helper functions data JSON = JSON { js_aeson :: Aeson.Value }   deriving(Show, Data, Typeable) @@ -138,7 +138,7 @@   -- ^ VK user name, (typically, an email). Empty string means no value is given   , l_password :: String   -- ^ VK password. Empty string means no value is given-  -- * FIXME Hide plain-text passwords+  --    * FIXME Hide plain-text passwords   , l_access_token :: String   -- ^ Initial access token, empty means 'not set'. Has higher precedence than   -- l_access_token_file