packages feed

antigate 0.5 → 0.6

raw patch · 3 files changed

+100/−34 lines, 3 filesdep +deepseqPVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq

API changes (from Hackage documentation)

+ Text.Recognition.Antigate: instance NFData ApiKey
+ Text.Recognition.Antigate: instance NFData CaptchaConf
+ Text.Recognition.Antigate: instance NFData Phase
+ Text.Recognition.Antigate: instance NFData SolveConf
+ Text.Recognition.Antigate: instance NFData SolveException
+ Text.Recognition.Antigate: instance NFData a => NFData (ApiResult a)

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2012 kudah+Copyright © 2012 kudah  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
Text/Recognition/Antigate.hs view
@@ -85,7 +85,7 @@ import Data.ByteString.Lazy.Char8()  import Network.HTTP.Conduit hiding (httpLbs)-import qualified Network.HTTP.Conduit+import qualified Network.HTTP.Conduit as HC import Network.HTTP.Conduit.MultipartFormData  import Control.Concurrent (threadDelay)@@ -103,23 +103,29 @@ import Safe (readMay) import Text.Printf (printf) +import Control.DeepSeq (NFData(..), deepseq)++__RESPONSE_TIMEOUT :: Int+__RESPONSE_TIMEOUT = 15000000+ decodeUtf8 :: BL.ByteString -> TL.Text decodeUtf8 = TLE.decodeUtf8With TEE.lenientDecode  httpLbs :: Request (ResourceT IO) -> Manager -> ResourceT IO (Response BL.ByteString)-httpLbs r m = Network.HTTP.Conduit.httpLbs r{responseTimeout=Nothing} m+httpLbs r =+        HC.httpLbs r{responseTimeout=Just __RESPONSE_TIMEOUT}  httpGet :: MonadResource m => Manager -> String -> m BL.ByteString httpGet m u = liftResourceT $ do     rq <- parseUrl u     responseBody <$> httpLbs rq m -delimit :: Char -> String -> [String]-delimit _ [] = []-delimit a b =+charDelimit :: Char -> String -> [String]+charDelimit _ [] = []+charDelimit a b =     case break (==a) b of         (c, []) -> [c]-        (c, (_:d)) -> c : delimit a d+        (c, (_:d)) -> c : charDelimit a d  -- | Antigate API access key paired with service provider's host. -- At least these services claim to support Antigate API:@@ -142,6 +148,9 @@             {api_host = "antigate.com"             ,api_key = str} +instance NFData ApiKey where+    rnf (ApiKey h k) = h `deepseq` k `deepseq` ()+ type CaptchaID = Int  -- | Properties of the captcha to be solved. See <http://antigate.com/panel.php?action=api>@@ -201,6 +210,17 @@         ,max_bid = Nothing         } +instance NFData CaptchaConf where+    rnf (CaptchaConf a b c d e f g h) =+        a `deepseq` b `deepseq`+        c `deepseq` d `deepseq`+        e `deepseq` f `deepseq`+        g `deepseq` h `deepseq` ()++instance NFData a => NFData (ApiResult a) where+    rnf (OK a) = a `deepseq` ()+    rnf x = x `seq` ()+ hostExt :: String -> String hostExt host     | "pixodrom.com" `isInfixOf` host = "aspx"@@ -253,24 +273,38 @@  uploadReq :: MonadResource m => Manager -> ApiKey -> CaptchaConf -> Part m (ResourceT IO) -> m (ApiResult CaptchaID) uploadReq m ApiKey{..} conf part = do-    url <- liftIO $ parseUrl $ "http://" ++ api_host ++ "/in." ++ hostExt api_host-    req <- (`formDataBody` url) $-        ([partBS "method" "post"-         ,partBS "key" (fromString api_key)-        ]) ++-        (captchaConfFields conf-        ) ++-        [part]-    liftResourceT $ parseUploadResponse . TL.unpack . decodeUtf8 . responseBody <$> httpLbs req m+    url <- liftIO $+        parseUrl $ "http://" ++ api_host ++ "/in." ++ hostExt api_host+    req <- flip formDataBody url $+        [partBS "method" "post"+        ,partBS "key" $ fromString api_key]+        ++ captchaConfFields conf+        ++ [part]+    liftResourceT $ do+        res <- httpLbs req m+        return $ parseUploadResponse $ TL.unpack $ decodeUtf8 $ responseBody res  -- | upload captcha for recognition -- -- throws 'HttpException' on network errors.-uploadCaptcha :: MonadResource m => ApiKey -> CaptchaConf -> FilePath -> BL.ByteString -> Manager -> m (ApiResult CaptchaID)+uploadCaptcha+    :: MonadResource m+    => ApiKey+    -> CaptchaConf+    -> FilePath+    -> BL.ByteString+    -> Manager+    -> m (ApiResult CaptchaID) uploadCaptcha key sets filename image m = do     uploadReq m key sets $ partFileRequestBody "file" filename $ RequestBodyLBS image -uploadCaptchaFromFile :: MonadResource m => ApiKey -> CaptchaConf -> FilePath -> Manager -> m (ApiResult CaptchaID)+uploadCaptchaFromFile+    :: MonadResource m+    => ApiKey+    -> CaptchaConf+    -> FilePath+    -> Manager+    -> m (ApiResult CaptchaID) uploadCaptchaFromFile key sets filename m = do     uploadReq m key sets $ partFile "file" filename @@ -305,12 +339,17 @@  -- | Parse antigate's multi-check response parseMultiCheckResponses :: String -> [ApiResult String]-parseMultiCheckResponses = map parseMultiCheckResponse . delimit '|'+parseMultiCheckResponses = map parseMultiCheckResponse . charDelimit '|'  -- | retrieve captcha status -- -- throws 'HttpException' on network errors.-checkCaptcha :: MonadResource m => ApiKey -> CaptchaID -> Manager -> m (ApiResult String)+checkCaptcha+    :: MonadResource m+    => ApiKey+    -> CaptchaID+    -> Manager+    -> m (ApiResult String) checkCaptcha ApiKey{..} captchaid m =     fmap (parseCheckResponse . TL.unpack . decodeUtf8) $ httpGet m $         "http://" ++ api_host ++ "/res." ++ hostExt api_host ++ "?key=" ++@@ -319,7 +358,12 @@ -- | retrieve multiple captcha status -- -- throws 'HttpException' on network errors.-checkCaptchas :: MonadResource m => ApiKey -> [CaptchaID] -> Manager -> m [ApiResult String]+checkCaptchas+    :: MonadResource m+    => ApiKey+    -> [CaptchaID]+    -> Manager+    -> m [ApiResult String] checkCaptchas ApiKey{..} captchaids m =     fmap (parseMultiCheckResponses . TL.unpack . decodeUtf8) $ httpGet m $         "http://" ++ api_host ++ "/res." ++ hostExt api_host ++ "?key=" ++@@ -332,9 +376,15 @@  instance Exception SolveException +instance NFData SolveException where+    rnf (SolveExceptionUpload a) = a `deepseq` ()+    rnf (SolveExceptionCheck a b) = a `deepseq` b `deepseq` ()+ data Phase = UploadPhase | CheckPhase   deriving (Show, Read, Eq, Ord, Enum, Bounded) +instance NFData Phase+ data SolveConf = SolveConf     {     -- | how much to sleep while waiting for available slot; in microseconds.@@ -374,17 +424,23 @@                 shows api_check_sleep . showString                     ", api_counter = <Phase -> Int -> IO ()>, api_upload_callback = <CaptchaID -> IO ()>}" +instance NFData SolveConf where+    rnf (SolveConf a b c d) =+        a `deepseq` b `deepseq`+        c `deepseq` d `deepseq` ()+ -- | High level function to solve captcha, blocks until answer is provided (about 2-10 seconds). -- -- throws 'SolveException' or 'HttpException' when something goes wrong.-solveCaptcha :: MonadResource m-             => SolveConf-             -> ApiKey-             -> CaptchaConf-             -> FilePath -- ^ image filename (antigate guesses filetype by file extension)-             -> BL.ByteString -- ^ image contents-             -> Manager -- ^ HTTP connection manager to use-             -> m (CaptchaID, String)+solveCaptcha+    :: MonadResource m+    => SolveConf+    -> ApiKey+    -> CaptchaConf+    -> FilePath -- ^ image filename (antigate guesses filetype by file extension)+    -> BL.ByteString -- ^ image contents+    -> Manager -- ^ HTTP connection manager to use+    -> m (CaptchaID, String) solveCaptcha SolveConf{..} key conf filename image m = do     liftIO $ api_counter UploadPhase 0     captchaid <- goupload 1 api_upload_sleep@@ -414,7 +470,14 @@                 return (captchaid, answer)             ex -> liftIO $ throwIO $ SolveExceptionCheck captchaid $ () <$ ex -solveCaptchaFromFile :: (MonadBaseControl IO m, MonadResource m) => SolveConf -> ApiKey -> CaptchaConf -> FilePath -> Manager -> m (CaptchaID, String)+solveCaptchaFromFile+    :: (MonadBaseControl IO m, MonadResource m)+    => SolveConf+    -> ApiKey+    -> CaptchaConf+    -> FilePath+    -> Manager+    -> m (CaptchaID, String) solveCaptchaFromFile a b c d m = do     s <- liftIO (fromStrict' <$> BS.readFile d)     solveCaptcha a b c d s m
antigate.cabal view
@@ -1,7 +1,9 @@ name: antigate-version: 0.5-synopsis: Haskell interface for antigate.com captcha recognition service and services supporting its API-description: Haskell interface for antigate.com captcha recognition service and other services (e.g. captchabot, decaptcher)+version: 0.6+synopsis: Interface for antigate.com captcha recognition API+description:+    Haskell interface for antigate.com captcha recognition service+    and other services supporting its API (e.g. captchabot, decaptcher) category: Network APIs, CAPTCHA, Text Recognition license: MIT license-file: LICENSE@@ -10,7 +12,7 @@ cabal-version: >= 1.8 stability: experimental build-type: Simple-tested-with: GHC == 7.4.1+tested-with: GHC == 7.4.1, GHC == 7.6.2 homepage: https://github.com/exbb2/antigate  source-repository head@@ -26,6 +28,7 @@                   ,safe                   ,resourcet                   ,transformers+                  ,deepseq      exposed-modules: Text.Recognition.Antigate