packages feed

mediawiki 0.2.4 → 0.2.6

raw patch · 41 files changed

+2294/−2256 lines, 41 filesdep +mediawikidep ~basesetup-changednew-component:exe:linksTo

Dependencies added: mediawiki

Dependency ranges changed: base

Files

Main.hs view
@@ -1,83 +1,83 @@-module Main(main) where
-
-import MediaWiki.API
-import MediaWiki.API.Types
-
-import MediaWiki.API.Query.Info
-import MediaWiki.API.Query.Info.Import as I
-import MediaWiki.API.Query.LangLinks
-import MediaWiki.API.Query.LangLinks.Import as LL
-import MediaWiki.API.Query.SiteInfo
-
-import System.Environment
-import Data.List ( isPrefixOf )
-
-mw_api_url :: String
-mw_api_url = "http://en.wikipedia.org/w/"
-
-main :: IO ()
-main = do
-  ls <- getArgs
-  let 
-   (url,pg) =
-    case ls of
-      ("WP":y:_) -> (mw_api_url,y)
-      (x:y:_) -> (x,y)
-      _ -> (mw_api_url, "Main_Page")
-  i <- queryInfo url pg
-  case I.stringXml i of
-    Left x -> putStrLn ("Error getting info for page " ++ pg ++ " error: " ++ show x)
-    Right x -> putStrLn ("Page last touched: " ++ headS (map infTouched (infPages x)))
-  lns <- getAll url pg [] Nothing
-  putStrLn ("The page " ++ pg ++ " is available in other languages:")
-  iwMap <- getIWUrlMap url
-  let 
-   getIWUrl (x,y) = 
-     case filter ((x==).iwPrefix) iwMap of
-        (a:_) -> (x,subst y (iwUrl a))
-	_ -> (x,"<unknown>")
-  let lns1 = map getIWUrl lns
-  putStrLn (' ':' ':unlines (map (\ (a,b) -> a ++ "=> " ++ b) lns1))
- where
-   subst ss x = 
-    case spanUntil ("$1" `isPrefixOf`) x of
-     (as,_:_:bs) -> as ++ ss ++ subst ss bs
-     (as,_) -> as
-
-spanUntil :: ([a] -> Bool) -> [a] -> ([a],[a])
-spanUntil _ [] = ([],[])
-spanUntil p ls@(x:xs)
- | p ls = ([],ls)
- | otherwise = 
-     case spanUntil p xs of
-       (as,bs) -> (x:as,bs)
-
-getAll :: String -> String -> [[(String,String)]] -> Maybe String -> IO [(String,String)]
-getAll url pg acc mbCont = do
---  i <- catch (queryLangPage url pg mbCont) (\ _ -> return "")
-  i <- queryLangPage url pg mbCont
-  case LL.stringXml i of
-   Left{} -> return (concat $ reverse acc)
-   Right ll -> do
-    let lls = map (\ lli -> (langName lli, lTitle lli)) (concat (map snd (llPages ll)))
-    case llContinue ll of
-      Nothing -> return $ concat $ reverse (lls:acc)
-      Just mb -> do
-        getAll url pg (lls:acc) (Just mb)
- where
-  lTitle x =
-    case langTitle x of
-      Nothing -> pg
-      Just "" -> pg
-      Just xs -> xs
-
-getIWUrlMap :: String -> IO [InterwikiEntry]
-getIWUrlMap api_url = do
-  mb <- querySiteIWInfo api_url
-  case mb of
-    Nothing -> return []
-    Just si -> return (siInterwiki si)
-
-headS :: [String] -> String
-headS    [] = ""
-headS (x:_) = x
+module Main(main) where++import MediaWiki.API+import MediaWiki.API.Types++import MediaWiki.API.Query.Info+import MediaWiki.API.Query.Info.Import as I+import MediaWiki.API.Query.LangLinks+import MediaWiki.API.Query.LangLinks.Import as LL+import MediaWiki.API.Query.SiteInfo++import System.Environment+import Data.List ( isPrefixOf )++mw_api_url :: String+mw_api_url = "http://en.wikipedia.org/w/"++main :: IO ()+main = do+  ls <- getArgs+  let+   (url,pg) =+    case ls of+      ("WP":y:_) -> (mw_api_url,y)+      (x:y:_) -> (x,y)+      _ -> (mw_api_url, "Main_Page")+  i <- queryInfo url pg+  case I.stringXml i of+    Left x -> putStrLn ("Error getting info for page " ++ pg ++ " error: " ++ show x)+    Right x -> putStrLn ("Page last touched: " ++ headS (map infTouched (infPages x)))+  lns <- getAll url pg [] Nothing+  putStrLn ("The page " ++ pg ++ " is available in other languages:")+  iwMap <- getIWUrlMap url+  let+   getIWUrl (x,y) =+     case filter ((x==).iwPrefix) iwMap of+        (a:_) -> (x,subst y (iwUrl a))+	_ -> (x,"<unknown>")+  let lns1 = map getIWUrl lns+  putStrLn (' ':' ':unlines (map (\ (a,b) -> a ++ "=> " ++ b) lns1))+ where+   subst ss x =+    case spanUntil ("$1" `isPrefixOf`) x of+     (as,_:_:bs) -> as ++ ss ++ subst ss bs+     (as,_) -> as++spanUntil :: ([a] -> Bool) -> [a] -> ([a],[a])+spanUntil _ [] = ([],[])+spanUntil p ls@(x:xs)+ | p ls = ([],ls)+ | otherwise =+     case spanUntil p xs of+       (as,bs) -> (x:as,bs)++getAll :: String -> String -> [[(String,String)]] -> Maybe String -> IO [(String,String)]+getAll url pg acc mbCont = do+--  i <- catch (queryLangPage url pg mbCont) (\ _ -> return "")+  i <- queryLangPage url pg mbCont+  case LL.stringXml i of+   Left{} -> return (concat $ reverse acc)+   Right ll -> do+    let lls = map (\ lli -> (langName lli, lTitle lli)) (concat (map snd (llPages ll)))+    case llContinue ll of+      Nothing -> return $ concat $ reverse (lls:acc)+      Just mb -> do+        getAll url pg (lls:acc) (Just mb)+ where+  lTitle x =+    case langTitle x of+      Nothing -> pg+      Just "" -> pg+      Just xs -> xs++getIWUrlMap :: String -> IO [InterwikiEntry]+getIWUrlMap api_url = do+  mb <- querySiteIWInfo api_url+  case mb of+    Nothing -> return []+    Just si -> return (siInterwiki si)++headS :: [String] -> String+headS    [] = ""+headS (x:_) = x
MediaWiki/API.hs view
@@ -11,9 +11,9 @@ -- Portability: portable
 --
 -- A Haskell MediaWiki API binding.
--- 
+--
 --------------------------------------------------------------------
-module MediaWiki.API 
+module MediaWiki.API
        ( module MediaWiki.API
        , URLString
        ) where
@@ -25,7 +25,6 @@ import MediaWiki.Util.Fetch as Fetch
 import Codec.MIME.Type
 
-import MediaWiki.API.Query.SiteInfo as SI
 import MediaWiki.API.Query.SiteInfo.Import as SI
 import MediaWiki.API.Action.Login.Import as Login
 
@@ -52,8 +51,8 @@ webPost mbUser url act req = do
   let url_q  = url ++ "api.php?action="++act
   let pload  = showRequest req
-  (_cookiesOut, hs, p) <- 
-     postContentsURL mbUser 
+  (_cookiesOut, hs, p) <-
+     postContentsURL mbUser
                   url_q
                   [ ("Content-Length", show $ length pload)
 		  , ("Content-Type",   showMIMEType form_mime_ty)
@@ -76,7 +75,7 @@     "" -> return Nothing
     ls -> do
      case p ls of
-      Left (x,errs) -> 
+      Left (x,errs) ->
          case parseError ls of
 	   Right e -> throwMWError e
 	   _ -> putStrLn (x ++ ':':' ':unlines errs) >> return Nothing
@@ -89,7 +88,7 @@ webGetXml p url req = do
   ls <- webGet url req
   case p ls of
-    Left (x,errs) -> 
+    Left (x,errs) ->
          case parseError ls of
 	   Right e -> throwMWError e
 	   _ -> putStrLn (x ++ ':':' ':unlines errs) >> return Nothing
@@ -99,14 +98,14 @@ queryPage pg = emptyQuery{quTitles=[pg]}
 
 mkQueryAction :: APIRequest a => QueryRequest -> a -> Action
-mkQueryAction q qr = 
+mkQueryAction q qr =
   case queryKind qr of
     QProp s -> Query q{quProps=(PropKind s):quProps q} (toReq qr)
     QList s -> Query q{quLists=(ListKind s):quLists q} (toReq qr)
     QMeta s -> Query q{quMetas=(MetaKind s):quMetas q} (toReq qr)
     QGen  s -> Query q{quGenerator=(Just (GeneratorKind s))} (toReq qr)
 
--- | @loginWiki u usr pass@ logs in to MediaWiki install at @url@ as 
+-- | @loginWiki u usr pass@ logs in to MediaWiki install at @url@ as
 -- user @usr@ with password credentials @pass@. Notice that we don't
 -- presently allow HTTP Auth to happen in conjunction with the Wiki
 -- login.
@@ -121,10 +120,10 @@    req = emptyXmlRequest (mkQueryAction (queryPage pgName) infoRequest)
 
 querySiteIWInfo :: URLString -> IO (Maybe SiteInfoResponse)
-querySiteIWInfo url = webGetXml SI.stringXml url req 
+querySiteIWInfo url = webGetXml SI.stringXml url req
  where
-  req = emptyXmlRequest 
-                 (mkQueryAction (queryPage "XP") 
+  req = emptyXmlRequest
+                 (mkQueryAction (queryPage "XP")
 		                siteInfoRequest{siProp=["interwikimap"]})
 
 queryLangPage :: URLString -> PageName -> Maybe String -> IO String
@@ -158,22 +157,21 @@ mwError :: MediaWikiError
 mwError = MediaWikiError{mwErrorCode="",mwErrorInfo=""}
 
-#if defined(EXTENSIBLE_EXCEPTIONS)
-data SomeMWException = forall e . Exception e => SomeMWException e 
-    deriving Typeable 
+data SomeMWException = forall e . Exception e => SomeMWException e
+    deriving Typeable
 
-instance Show SomeMWException where 
-    show (SomeMWException e) = show e 
+instance Show SomeMWException where
+    show (SomeMWException e) = show e
 
-instance Exception SomeMWException 
+instance Exception SomeMWException
 
 mwToException :: Exception e => e -> SomeException
-mwToException = toException . SomeMWException 
+mwToException = toException . SomeMWException
 
-mwFromException :: Exception e => SomeException -> Maybe e 
-mwFromException x = do 
-    SomeMWException a <- fromException x 
-    cast a 
+mwFromException :: Exception e => SomeException -> Maybe e
+mwFromException x = do
+    SomeMWException a <- fromException x
+    cast a
 
 instance Exception MediaWikiError where
   toException = mwToException
@@ -183,18 +181,9 @@ throwMWError e = throwIO e
 
 catchMW :: IO a -> (MediaWikiError -> IO a) -> IO a
-catchMW f hdlr = 
-  CE.catch f
-           (\ e1 -> hdlr e1)
-#else
-throwMWError :: MediaWikiError -> IO a
-throwMWError mw = throwDyn mw
-
-catchMW :: IO a -> (MediaWikiError -> IO a) -> IO a
 catchMW f hdlr =
-  CE.catchDyn f
+  CE.catch f
            (\ e1 -> hdlr e1)
-#endif
 
 handleMW :: (MediaWikiError -> IO a) -> IO a -> IO a
 handleMW h e = catchMW e h
MediaWiki/API/Action/ExpandTemplates.hs view
@@ -1,44 +1,44 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.ExpandTemplates
--- Description : Representing ExpandTemplates requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing ExpandTemplates requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.ExpandTemplates where
-
-import MediaWiki.API.Types
-
-data ExpandTemplatesRequest
- = ExpandTemplatesRequest
-    { etTitle      :: Maybe PageName
-    , etText       :: String
-    , etGenXml     :: Maybe Bool
-    }
-
-emptyExpandTemplatesRequest :: ExpandTemplatesRequest
-emptyExpandTemplatesRequest = ExpandTemplatesRequest
-    { etTitle      = Nothing
-    , etText       = ""
-    , etGenXml     = Nothing
-    }
-
-data ExpandTemplatesResponse
- = ExpandTemplatesResponse
-    { etExpandedText :: String
-    , etExpandedXml  :: Maybe String
-    }
-
-emptyExpandTemplatesResponse :: ExpandTemplatesResponse
-emptyExpandTemplatesResponse = ExpandTemplatesResponse
-    { etExpandedText  = ""
-    , etExpandedXml   = Nothing
-    }
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.ExpandTemplates+-- Description : Representing ExpandTemplates requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing ExpandTemplates requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Action.ExpandTemplates where++import MediaWiki.API.Types++data ExpandTemplatesRequest+ = ExpandTemplatesRequest+    { etTitle      :: Maybe PageName+    , etText       :: String+    , etGenXml     :: Maybe Bool+    }++emptyExpandTemplatesRequest :: ExpandTemplatesRequest+emptyExpandTemplatesRequest = ExpandTemplatesRequest+    { etTitle      = Nothing+    , etText       = ""+    , etGenXml     = Nothing+    }++data ExpandTemplatesResponse+ = ExpandTemplatesResponse+    { etExpandedText :: String+    , etExpandedXml  :: Maybe String+    }++emptyExpandTemplatesResponse :: ExpandTemplatesResponse+emptyExpandTemplatesResponse = ExpandTemplatesResponse+    { etExpandedText  = ""+    , etExpandedXml   = Nothing+    }+
MediaWiki/API/Action/ExpandTemplates/Import.hs view
@@ -10,7 +10,7 @@ -- Portability: portable -- -- Serializing ExpandTemplates requests.--- +-- -------------------------------------------------------------------- module MediaWiki.API.Action.ExpandTemplates.Import where @@ -22,7 +22,6 @@ import Text.XML.Light.Proc   ( strContent )  import Control.Monad-import Data.Maybe  stringXml :: String -> Either (String,[{-Error msg-}String]) ExpandTemplatesResponse stringXml s = parseDoc xml s
MediaWiki/API/Action/FeedWatchlist.hs view
@@ -1,49 +1,49 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.FeedWatchlist
--- Description : Representing FeedWatchList requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing FeedWatchList requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.FeedWatchlist where
-
-import MediaWiki.API.Types
-
-data FeedWatchListRequest
- = FeedWatchListRequest
-    { feAsAtom    :: Bool  -- False => rss
-    , feHours     :: Maybe Int
-    , feAllRev    :: Bool
-    }
-
-emptyFeedWatchListRequest :: FeedWatchListRequest
-emptyFeedWatchListRequest = FeedWatchListRequest
-    { feAsAtom    = False
-    , feHours     = Nothing
-    , feAllRev    = False
-    }
-
-data FeedWatchListResponse
- = FeedWatchListResponse
-    { fwFeedFormat  :: String
-    , fwFeedRaw     :: String
-    , fwFeedItems   :: [FeedItem]
-    }
-
-data FeedItem
- = FeedItem
-    { fiTitle     :: String
-    , fiUrl       :: URLString
-    , fiComment   :: String
-    , fiTimestamp :: String
-    , fiUser      :: String
-    , fiText      :: String
-    }
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.FeedWatchlist+-- Description : Representing FeedWatchList requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing FeedWatchList requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Action.FeedWatchlist where++import MediaWiki.API.Types++data FeedWatchListRequest+ = FeedWatchListRequest+    { feAsAtom    :: Bool  -- False => rss+    , feHours     :: Maybe Int+    , feAllRev    :: Bool+    }++emptyFeedWatchListRequest :: FeedWatchListRequest+emptyFeedWatchListRequest = FeedWatchListRequest+    { feAsAtom    = False+    , feHours     = Nothing+    , feAllRev    = False+    }++data FeedWatchListResponse+ = FeedWatchListResponse+    { fwFeedFormat  :: String+    , fwFeedRaw     :: String+    , fwFeedItems   :: [FeedItem]+    }++data FeedItem+ = FeedItem+    { fiTitle     :: String+    , fiUrl       :: URLString+    , fiComment   :: String+    , fiTimestamp :: String+    , fiUser      :: String+    , fiText      :: String+    }+
MediaWiki/API/Action/Login.hs view
@@ -1,67 +1,67 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.Login
--- Description : Representing Login requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing Login requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.Login where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Utils
-
-data LoginRequest
- = LoginRequest
-     { lgName     :: User
-     , lgPassword :: Password
-     , lgDomain   :: Maybe String
-     }
-
-instance APIRequest LoginRequest where
-  isPostable _ = True
-  showReq r =
-   [ opt "lgname" (lgName r)
-   , opt "lgpassword" (lgPassword r)
-   , mbOpt "lgdomain" id (lgDomain r)
-   ]
-
-emptyLogin :: User -> Password -> LoginRequest
-emptyLogin u p 
- = LoginRequest
-    { lgName     = u
-    , lgPassword = p
-    , lgDomain   = Nothing
-    }
-
-data LoginResponse
-    -- error responses, all together:
- = LoginError
-    { lgSuccess  :: Bool
-    , lgeError   :: String -- NeedToWait/NoName/Illegal/WrongPluginPass/NotExists/WrongPass/EmptyPass/future ones.
-        -- (resist the temptation(?) to encode errors via a separate type, keep it loose for now in a String.
-    , lgeDetails :: Maybe String
-    , lgeWait    :: String
-    }
-    -- Successfully logged in, bundle up the result in a separate record so as to ease
-    -- the carrying around of a user session. 
-    --
-    -- Notice the use of a shared boolean field betw. the constructors; eases the processing of
-    -- responses in code where conds/guards are more convenient:
-    --
-    --    x <- submitLoginRequest lgReq
-    --    when (not $ lgSuccess x) (handleError x)
-    --    let sess = lgSession x
-    --    ...
-    --
- | LoginResponse
-    { lgSuccess :: Bool
-    , lgSession :: UserSession
-    } 
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.Login+-- Description : Representing Login requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing Login requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Action.Login where++import MediaWiki.API.Types+import MediaWiki.API.Utils++data LoginRequest+ = LoginRequest+     { lgName     :: User+     , lgPassword :: Password+     , lgDomain   :: Maybe String+     }++instance APIRequest LoginRequest where+  isPostable _ = True+  showReq r =+   [ opt "lgname" (lgName r)+   , opt "lgpassword" (lgPassword r)+   , mbOpt "lgdomain" id (lgDomain r)+   ]++emptyLogin :: User -> Password -> LoginRequest+emptyLogin u p + = LoginRequest+    { lgName     = u+    , lgPassword = p+    , lgDomain   = Nothing+    }++data LoginResponse+    -- error responses, all together:+ = LoginError+    { lgSuccess  :: Bool+    , lgeError   :: String -- NeedToWait/NoName/Illegal/WrongPluginPass/NotExists/WrongPass/EmptyPass/future ones.+        -- (resist the temptation(?) to encode errors via a separate type, keep it loose for now in a String.+    , lgeDetails :: Maybe String+    , lgeWait    :: String+    }+    -- Successfully logged in, bundle up the result in a separate record so as to ease+    -- the carrying around of a user session. +    --+    -- Notice the use of a shared boolean field betw. the constructors; eases the processing of+    -- responses in code where conds/guards are more convenient:+    --+    --    x <- submitLoginRequest lgReq+    --    when (not $ lgSuccess x) (handleError x)+    --    let sess = lgSession x+    --    ...+    --+ | LoginResponse+    { lgSuccess :: Bool+    , lgSession :: UserSession+    } +
MediaWiki/API/Action/Login/Import.hs view
@@ -10,7 +10,7 @@ -- Portability: portable -- -- Serializing Login requests.--- +-- -------------------------------------------------------------------- module MediaWiki.API.Action.Login.Import where @@ -21,7 +21,6 @@ import Text.XML.Light.Types  import Control.Monad-import Data.Maybe  stringXml :: String -> Either (String,[{-Error msg-}String]) LoginResponse stringXml s = parseDoc xml s@@ -39,7 +38,7 @@   let ses = pAttr "sessionid" p   case res of     Nothing -> fail "missing 'result' api attribute"-    Just "Success" -> +    Just "Success" ->        return LoginResponse{ lgSuccess=True                            , lgSession=UserSession 			                 { sessUserId    = fromMaybe "" uid@@ -58,4 +57,4 @@ 		, lgeDetails = det 		, lgeWait   = fromMaybe "" wai 		}-		+
MediaWiki/API/Action/OpenSearch.hs view
@@ -1,44 +1,42 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.OpenSearch
--- Description : Representing OpenSearch requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing OpenSearch requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.OpenSearch where
-
-import MediaWiki.API.Types
-
-data OpenSearchRequest
- = OpenSearchRequest
-    { osSearch     :: String
-    , osLimit      :: Maybe Int
-    , osNamespaces :: Maybe [Int]
-    }
-
-emptyOpenSearchRequest :: String -> OpenSearchRequest
-emptyOpenSearchRequest tit 
- = OpenSearchRequest
-    { osSearch     = tit
-    , osLimit      = Nothing
-    , osNamespaces = Nothing
-    }
-
-data OpenSearchResponse
- = OpenSearchResponse
-      { osHits :: [OpenSearchHit]
-      }
-
-data OpenSearchHit
- = OpenSearchHit
-      { oshTitle   :: String
-      , oshMatches :: [String]
-      }
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.OpenSearch+-- Description : Representing OpenSearch requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing OpenSearch requests.+--+--------------------------------------------------------------------+module MediaWiki.API.Action.OpenSearch where++data OpenSearchRequest+ = OpenSearchRequest+    { osSearch     :: String+    , osLimit      :: Maybe Int+    , osNamespaces :: Maybe [Int]+    }++emptyOpenSearchRequest :: String -> OpenSearchRequest+emptyOpenSearchRequest tit+ = OpenSearchRequest+    { osSearch     = tit+    , osLimit      = Nothing+    , osNamespaces = Nothing+    }++data OpenSearchResponse+ = OpenSearchResponse+      { osHits :: [OpenSearchHit]+      }++data OpenSearchHit+ = OpenSearchHit+      { oshTitle   :: String+      , oshMatches :: [String]+      }+
MediaWiki/API/Action/ParamInfo.hs view
@@ -1,59 +1,57 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.ParamInfo
--- Description : Representing ParamInfo requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing ParamInfo requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.ParamInfo where
-
-import MediaWiki.API.Types
-
-data ParamInfoRequest
- = ParamInfoRequest
-    { paModules      :: [String]
-    , paQueryModules :: [String]
-    }
-
-emptyParamInfoRequest :: ParamInfoRequest
-emptyParamInfoRequest = ParamInfoRequest
-    { paModules      = []
-    , paQueryModules = []
-    }
-
-data ParamInfoResponse
- = ParamInfoResponse
-    { parModules :: [APIModule]
-    }
-
-data APIModule
- = APIModule
-    { modName        :: String
-    , modClass       :: String
-    , modDescription :: String
-    , modParams      :: [ModuleParam]
-    }
-
-data ModuleParam
- = ModuleParam
-    { modParamName        :: String
-    , modParamDefault     :: String
-    , modParamDescription :: String
-    , modParamPrefix      :: String
-    , modParamType        :: ParamType
-    }
-
-data ParamType
- = TypeBool
- | TypeString
- | TypeInteger
- | TypeTimestamp
- | TypeName String
- | TypeEnum [String]
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.ParamInfo+-- Description : Representing ParamInfo requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing ParamInfo requests.+--+--------------------------------------------------------------------+module MediaWiki.API.Action.ParamInfo where++data ParamInfoRequest+ = ParamInfoRequest+    { paModules      :: [String]+    , paQueryModules :: [String]+    }++emptyParamInfoRequest :: ParamInfoRequest+emptyParamInfoRequest = ParamInfoRequest+    { paModules      = []+    , paQueryModules = []+    }++data ParamInfoResponse+ = ParamInfoResponse+    { parModules :: [APIModule]+    }++data APIModule+ = APIModule+    { modName        :: String+    , modClass       :: String+    , modDescription :: String+    , modParams      :: [ModuleParam]+    }++data ModuleParam+ = ModuleParam+    { modParamName        :: String+    , modParamDefault     :: String+    , modParamDescription :: String+    , modParamPrefix      :: String+    , modParamType        :: ParamType+    }++data ParamType+ = TypeBool+ | TypeString+ | TypeInteger+ | TypeTimestamp+ | TypeName String+ | TypeEnum [String]
MediaWiki/API/Action/Parse.hs view
@@ -1,89 +1,89 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.Parse
--- Description : Representing Parse requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing Parse requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.Parse where
-
-import MediaWiki.API.Types
-
-data ParseRequest
- = ParseRequest
-    { paTitle     :: Maybe PageName
-    , paText      :: String
-    , paPage      :: Maybe PageName
-    , paOldId     :: Maybe RevID
-    , paProp      :: [String]
-    }
-
-emptyParseRequest :: String -> ParseRequest
-emptyParseRequest txt = ParseRequest
-    { paTitle     = Nothing
-    , paText      = txt
-    , paPage      = Nothing
-    , paOldId     = Nothing
-    , paProp      = []
-    }
-
-data ParseResponse
- = ParseResponse
-    { parText          :: String
-    , parRevId         :: Maybe RevID
-    , parLangLinks     :: Maybe [LanguageLink]
-    , parCategories    :: Maybe [CategoryLink]
-    , parLinks         :: Maybe [Link]
-    , parTemplates     :: Maybe [Link]
-    , parImages        :: Maybe [String]
-    , parExternalLinks :: Maybe [URLString]
-    , parSections      :: Maybe [TOCSection]
-    }
-
-emptyParseResponse :: ParseResponse
-emptyParseResponse  = ParseResponse
-    { parText          = ""
-    , parRevId         = Nothing
-    , parLangLinks     = Nothing
-    , parCategories    = Nothing
-    , parLinks         = Nothing
-    , parTemplates     = Nothing
-    , parImages        = Nothing
-    , parExternalLinks = Nothing
-    , parSections      = Nothing
-    }
-
-data LanguageLink
- = LanguageLink
-    { laLang  :: String
-    , laLink  :: String
-    }
-
-data CategoryLink
- = CategoryLink
-    { caSortKey :: String
-    , caLink    :: String
-    }
-
-data Link
- = Link
-    { liNamespace :: String
-    , liExists    :: Bool
-    , liLink      :: String
-    }
-
-data TOCSection
- = TOCSection
-    { tocTocLevel :: Int
-    , tocLevel    :: Int
-    , tocLine     :: String
-    , tocNumber   :: String
-    }
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.Parse+-- Description : Representing Parse requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing Parse requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Action.Parse where++import MediaWiki.API.Types++data ParseRequest+ = ParseRequest+    { paTitle     :: Maybe PageName+    , paText      :: String+    , paPage      :: Maybe PageName+    , paOldId     :: Maybe RevID+    , paProp      :: [String]+    }++emptyParseRequest :: String -> ParseRequest+emptyParseRequest txt = ParseRequest+    { paTitle     = Nothing+    , paText      = txt+    , paPage      = Nothing+    , paOldId     = Nothing+    , paProp      = []+    }++data ParseResponse+ = ParseResponse+    { parText          :: String+    , parRevId         :: Maybe RevID+    , parLangLinks     :: Maybe [LanguageLink]+    , parCategories    :: Maybe [CategoryLink]+    , parLinks         :: Maybe [Link]+    , parTemplates     :: Maybe [Link]+    , parImages        :: Maybe [String]+    , parExternalLinks :: Maybe [URLString]+    , parSections      :: Maybe [TOCSection]+    }++emptyParseResponse :: ParseResponse+emptyParseResponse  = ParseResponse+    { parText          = ""+    , parRevId         = Nothing+    , parLangLinks     = Nothing+    , parCategories    = Nothing+    , parLinks         = Nothing+    , parTemplates     = Nothing+    , parImages        = Nothing+    , parExternalLinks = Nothing+    , parSections      = Nothing+    }++data LanguageLink+ = LanguageLink+    { laLang  :: String+    , laLink  :: String+    }++data CategoryLink+ = CategoryLink+    { caSortKey :: String+    , caLink    :: String+    }++data Link+ = Link+    { liNamespace :: String+    , liExists    :: Bool+    , liLink      :: String+    }++data TOCSection+ = TOCSection+    { tocTocLevel :: Int+    , tocLevel    :: Int+    , tocLine     :: String+    , tocNumber   :: String+    }+
MediaWiki/API/Action/Sitematrix.hs view
@@ -1,48 +1,48 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Action.Sitematrix
--- Description : Representing Sitematrix requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing Sitematrix requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Action.Sitematrix where
-
-import MediaWiki.API.Types
-
--- 1.12+ and later
-data SitematrixRequest
- = SitematrixRequest
-
-emptySitematrixRequest :: SitematrixRequest
-emptySitematrixRequest = SitematrixRequest
-
-data SitematrixResponse
- = SitematrixResponse
-     { smCount     :: Int
-     , smSpecials  :: [SiteSpecialInfo]
-     , smLanguages :: [LanguageInfo]
-     }
-
-data SiteSpecialInfo
- = SiteSpecialInfo
-     { siCode :: String
-     , siUrl  :: URLString
-     }
-
-data LanguageInfo
- = LanguageInfo
-     { liCode  :: String
-     , liName  :: String
-     , liSites :: [SiteInfos]
-     }
-
-data SiteInfos
- = SiteInfos
-     { siInfo :: String }
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Action.Sitematrix+-- Description : Representing Sitematrix requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing Sitematrix requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Action.Sitematrix where++import MediaWiki.API.Types++-- 1.12+ and later+data SitematrixRequest+ = SitematrixRequest++emptySitematrixRequest :: SitematrixRequest+emptySitematrixRequest = SitematrixRequest++data SitematrixResponse+ = SitematrixResponse+     { smCount     :: Int+     , smSpecials  :: [SiteSpecialInfo]+     , smLanguages :: [LanguageInfo]+     }++data SiteSpecialInfo+ = SiteSpecialInfo+     { siCode :: String+     , siUrl  :: URLString+     }++data LanguageInfo+ = LanguageInfo+     { liCode  :: String+     , liName  :: String+     , liSites :: [SiteInfos]+     }++data SiteInfos+ = SiteInfos+     { siInfo :: String }
MediaWiki/API/Base.hs view
@@ -1,329 +1,329 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Base
--- Description : Collector module of types used by the MediaWiki API
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Collector module of types used by the MediaWiki API
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Base 
-	( module MediaWiki.API.Base
-	, module MediaWiki.API.Query.AllCategories
-	, module MediaWiki.API.Query.AllImages
-	, module MediaWiki.API.Query.AllLinks
-	, module MediaWiki.API.Query.AllMessages
-	, module MediaWiki.API.Query.AllPages
-	, module MediaWiki.API.Query.AllUsers
-	, module MediaWiki.API.Query.BackLinks
-	, module MediaWiki.API.Query.Blocks
-	, module MediaWiki.API.Query.Categories
-	, module MediaWiki.API.Query.CategoryInfo
-	, module MediaWiki.API.Query.CategoryMembers
-	, module MediaWiki.API.Query.DeletedRevisions
-	, module MediaWiki.API.Query.EmbeddedIn
-	, module MediaWiki.API.Query.ExternalLinks
-	, module MediaWiki.API.Query.ExternalURLUsage
-	, module MediaWiki.API.Query.ImageInfo
-	, module MediaWiki.API.Query.Images
-	, module MediaWiki.API.Query.ImageUsage
-	, module MediaWiki.API.Query.Info
-	, module MediaWiki.API.Query.LangLinks
-	, module MediaWiki.API.Query.LogEvents
-	, module MediaWiki.API.Query.Random
-	, module MediaWiki.API.Query.RecentChanges
-	, module MediaWiki.API.Query.Revisions
-	, module MediaWiki.API.Query.Search
-	, module MediaWiki.API.Query.SiteInfo
-	, module MediaWiki.API.Query.Templates
-	, module MediaWiki.API.Query.UserContribs
-	, module MediaWiki.API.Query.UserInfo
-	, module MediaWiki.API.Query.Users
-	, module MediaWiki.API.Query.WatchList
-
-	, module MediaWiki.API.Action.Login
-	, module MediaWiki.API.Action.ParamInfo
-	, module MediaWiki.API.Action.Parse
-	, module MediaWiki.API.Action.OpenSearch
-	, module MediaWiki.API.Action.FeedWatchlist
-	, module MediaWiki.API.Action.ExpandTemplates
-        , module MediaWiki.API.Action.Sitematrix
-        , module MediaWiki.API.Action.Unblock
-        , module MediaWiki.API.Action.Watch
-        , module MediaWiki.API.Action.EmailUser
-        , module MediaWiki.API.Action.Edit
-        , module MediaWiki.API.Action.Move
-        , module MediaWiki.API.Action.Block
-        , module MediaWiki.API.Action.Protect
-        , module MediaWiki.API.Action.Undelete
-        , module MediaWiki.API.Action.Delete
-        , module MediaWiki.API.Action.Rollback
-
-	) where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Query.AllCategories
-import MediaWiki.API.Query.AllImages
-import MediaWiki.API.Query.AllLinks
-import MediaWiki.API.Query.AllMessages
-import MediaWiki.API.Query.AllPages
-import MediaWiki.API.Query.AllUsers
-import MediaWiki.API.Query.BackLinks
-import MediaWiki.API.Query.Blocks
-import MediaWiki.API.Query.Categories
-import MediaWiki.API.Query.CategoryInfo
-import MediaWiki.API.Query.CategoryMembers
-import MediaWiki.API.Query.DeletedRevisions
-import MediaWiki.API.Query.EmbeddedIn
-import MediaWiki.API.Query.ExternalLinks
-import MediaWiki.API.Query.ExternalURLUsage
-import MediaWiki.API.Query.ImageInfo
-import MediaWiki.API.Query.Images
-import MediaWiki.API.Query.ImageUsage
-import MediaWiki.API.Query.Info
-import MediaWiki.API.Query.LangLinks
-import MediaWiki.API.Query.Links
-import MediaWiki.API.Query.LogEvents
-import MediaWiki.API.Query.Random
-import MediaWiki.API.Query.RecentChanges
-import MediaWiki.API.Query.Revisions
-import MediaWiki.API.Query.Search
-import MediaWiki.API.Query.SiteInfo
-import MediaWiki.API.Query.Templates
-import MediaWiki.API.Query.UserContribs
-import MediaWiki.API.Query.UserInfo
-import MediaWiki.API.Query.Users
-import MediaWiki.API.Query.WatchList
-
-import MediaWiki.API.Action.Login
-import MediaWiki.API.Action.ParamInfo
-import MediaWiki.API.Action.Parse
-import MediaWiki.API.Action.OpenSearch
-import MediaWiki.API.Action.FeedWatchlist
-import MediaWiki.API.Action.ExpandTemplates
-import MediaWiki.API.Action.Sitematrix
-import MediaWiki.API.Action.Unblock
-import MediaWiki.API.Action.Watch
-import MediaWiki.API.Action.EmailUser
-import MediaWiki.API.Action.Edit
-import MediaWiki.API.Action.Move
-import MediaWiki.API.Action.Block
-import MediaWiki.API.Action.Protect
-import MediaWiki.API.Action.Undelete
-import MediaWiki.API.Action.Delete
-import MediaWiki.API.Action.Rollback
-
--- | Type collecting together the main parts of a MediaWiki API request.
-data Request
- = Request
-    { reqAction :: Action
-    , reqFormat :: Format
-    , reqMaxLag :: Maybe Int
-    }
-
-emptyRequest :: Action -> Format -> Request
-emptyRequest a f 
- = Request
-    { reqAction = a
-    , reqFormat = f
-    , reqMaxLag = Nothing
-    }
-
-emptyXmlRequest :: Action -> Request
-emptyXmlRequest a = emptyRequest a xmlFormat
-
-data Action
- = Sitematrix
- | Login           LoginRequest
- | Logout
- | Query           QueryRequest [String]
- | ExpandTemplates ExpandTemplatesRequest
- | Parse           ParseRequest
- | OpenSearch      OpenSearchRequest
- | FeedWatch       FeedWatchListRequest
- | Help            HelpRequest
- | ParamInfo       ParamInfoRequest
- | Unblock         UnblockRequest
- | Watch           WatchRequest
- | EmailUser       EmailUserRequest
- | Edit            EditRequest
- | Move            MoveRequest
- | Block           BlockRequest
- | Protect         ProtectRequest
- | Undelete        UndeleteRequest
- | Delete          DeleteRequest
- | Rollback        RollbackRequest
- | OtherAction     String [ValueName]
-
-
-infoRequest :: InfoRequest
-infoRequest = emptyInfoRequest
-
-revisionRequest :: RevisionRequest
-revisionRequest  = emptyRevisionRequest
-
-linksRequest :: LinksRequest
-linksRequest = emptyLinksRequest
-
-langLinksRequest :: LangLinksRequest
-langLinksRequest  = emptyLangLinksRequest
-
-imagesRequest :: ImagesRequest
-imagesRequest = emptyImagesRequest
-
-imageInfoRequest :: ImageInfoRequest
-imageInfoRequest = emptyImageInfoRequest
-
-templatesRequest :: TemplatesRequest
-templatesRequest = emptyTemplatesRequest
-
-categoriesRequest :: CategoriesRequest
-categoriesRequest = emptyCategoriesRequest
-
-allCategoriesRequest :: AllCategoriesRequest
-allCategoriesRequest = emptyAllCategoriesRequest
-
-allImagesRequest :: AllImagesRequest
-allImagesRequest = emptyAllImagesRequest
-
-allLinksRequest :: AllLinksRequest
-allLinksRequest  = emptyAllLinksRequest
-
-allMessagesRequest :: AllMessagesRequest
-allMessagesRequest = emptyAllMessagesRequest
-
-allPagesRequest :: AllPagesRequest
-allPagesRequest = emptyAllPagesRequest
-
-allUsersRequest :: AllUsersRequest
-allUsersRequest = emptyAllUsersRequest
-
-backLinksRequest :: BackLinksRequest
-backLinksRequest = emptyBackLinksRequest
-
-embeddedInRequest :: EmbeddedInRequest
-embeddedInRequest = emptyEmbeddedInRequest
-
-imageUsageRequest :: ImageUsageRequest
-imageUsageRequest = emptyImageUsageRequest
-
-categoryInfoRequest :: CategoryInfoRequest
-categoryInfoRequest = emptyCategoryInfoRequest
-
-categoryMembersRequest :: CategoryMembersRequest
-categoryMembersRequest = emptyCategoryMembersRequest
-
-externalLinksRequest :: ExternalLinksRequest
-externalLinksRequest = emptyExternalLinksRequest
-
-externalURLUsageRequest :: ExternalURLUsageRequest
-externalURLUsageRequest = emptyExternalURLUsageRequest
-
-logEventsRequest :: LogEventsRequest
-logEventsRequest = emptyLogEventsRequest
-
-recentChangesRequest :: RecentChangesRequest
-recentChangesRequest = emptyRecentChangesRequest
-
-searchRequest :: String -> SearchRequest
-searchRequest = emptySearchRequest
-
-siteInfoRequest :: SiteInfoRequest
-siteInfoRequest = emptySiteInfoRequest
-
-userContribsRequest :: UserContribsRequest
-userContribsRequest = emptyUserContribsRequest
-
-userInfoRequest :: UserInfoRequest
-userInfoRequest = emptyUserInfoRequest
-
-watchListRequest :: WatchListRequest
-watchListRequest = emptyWatchListRequest
-
-blocksRequest :: BlocksRequest
-blocksRequest = emptyBlocksRequest
-
-deletedRevisionsRequest :: DeletedRevisionsRequest
-deletedRevisionsRequest = emptyDeletedRevisionsRequest
-
-usersRequest :: UsersRequest
-usersRequest = emptyUsersRequest
-
-randomPagesRequest :: RandomPagesRequest
-randomPagesRequest = emptyRandomPagesRequest
-
-data QueryRequestKind
- = InfoProp          InfoRequest
- | RevisionsProp     RevisionRequest
- | LinksPropProp     LinksRequest
- | LangLinksProp     LangLinksRequest
- | ImagesProp        ImagesRequest
- | ImageInfoProp     ImageInfoRequest
- | TemplatesProp     TemplatesRequest
- | CategoriesProp    CategoriesRequest
- | AllCategoriesProp AllCategoriesRequest
- | AllImagesProp     AllImagesRequest
- | AllLinksProp      AllLinksRequest
- | AllMessagesProp   AllMessagesRequest
- | AllPagesProp      AllPagesRequest
- | AllUsersProp      AllUsersRequest
- | BacklinksProp     BackLinksRequest
- | EmbeddedInProp    EmbeddedInRequest
- | ImageUsageProp    ImageUsageRequest
- | CategoryInfoProp  CategoryInfoRequest
- | CategoryMembersProp  CategoryMembersRequest
- | ExternalLinksProp    ExternalLinksRequest
- | ExternalURLUsageProp ExternalURLUsageRequest
- | LogEventsProp        LogEventsRequest
- | RecentChangesProp    RecentChangesRequest
- | SearchProp           SearchRequest
- | SiteInfoProp         SiteInfoRequest
- | UserContribsProp     UserContribsRequest
- | UserInfoProp         UserInfoRequest
- | WatchListProp        WatchListRequest
- | BlocksProp           BlocksRequest
- | DeletedRevsProp      DeletedRevisionsRequest
- | UsersProp            UsersRequest
- | RandomProp           RandomPagesRequest
-
-qKind :: QueryRequestKind -> QueryKind
-qKind q = 
- case q of
-   InfoProp k -> queryKind k
-   RevisionsProp k -> queryKind k
-   LinksPropProp k -> queryKind k
-   LangLinksProp k -> queryKind k
-   ImagesProp    k -> queryKind k
-   ImageInfoProp k -> queryKind k
-   TemplatesProp k -> queryKind k
-   CategoriesProp k -> queryKind k
-   AllCategoriesProp k -> queryKind k
-   AllImagesProp     k -> queryKind k
-   AllLinksProp      k -> queryKind k
-   AllMessagesProp   k -> queryKind k
-   AllPagesProp      k -> queryKind k
-   AllUsersProp      k -> queryKind k
-   BacklinksProp     k -> queryKind k
-   EmbeddedInProp    k -> queryKind k
-   ImageUsageProp    k -> queryKind k
-   CategoryInfoProp  k -> queryKind k
-   CategoryMembersProp k -> queryKind k
-   ExternalLinksProp   k -> queryKind k
-   ExternalURLUsageProp k -> queryKind k
-   LogEventsProp        k -> queryKind k
-   RecentChangesProp    k -> queryKind k
-   SearchProp           k -> queryKind k
-   SiteInfoProp         k -> queryKind k
-   UserContribsProp     k -> queryKind k
-   UserInfoProp         k -> queryKind k
-   WatchListProp        k -> queryKind k
-   BlocksProp           k -> queryKind k
-   DeletedRevsProp      k -> queryKind k
-   UsersProp            k -> queryKind k
-   RandomProp           k -> queryKind k
- 
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Base+-- Description : Collector module of types used by the MediaWiki API+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Collector module of types used by the MediaWiki API+-- +--------------------------------------------------------------------+module MediaWiki.API.Base +	( module MediaWiki.API.Base+	, module MediaWiki.API.Query.AllCategories+	, module MediaWiki.API.Query.AllImages+	, module MediaWiki.API.Query.AllLinks+	, module MediaWiki.API.Query.AllMessages+	, module MediaWiki.API.Query.AllPages+	, module MediaWiki.API.Query.AllUsers+	, module MediaWiki.API.Query.BackLinks+	, module MediaWiki.API.Query.Blocks+	, module MediaWiki.API.Query.Categories+	, module MediaWiki.API.Query.CategoryInfo+	, module MediaWiki.API.Query.CategoryMembers+	, module MediaWiki.API.Query.DeletedRevisions+	, module MediaWiki.API.Query.EmbeddedIn+	, module MediaWiki.API.Query.ExternalLinks+	, module MediaWiki.API.Query.ExternalURLUsage+	, module MediaWiki.API.Query.ImageInfo+	, module MediaWiki.API.Query.Images+	, module MediaWiki.API.Query.ImageUsage+	, module MediaWiki.API.Query.Info+	, module MediaWiki.API.Query.LangLinks+	, module MediaWiki.API.Query.LogEvents+	, module MediaWiki.API.Query.Random+	, module MediaWiki.API.Query.RecentChanges+	, module MediaWiki.API.Query.Revisions+	, module MediaWiki.API.Query.Search+	, module MediaWiki.API.Query.SiteInfo+	, module MediaWiki.API.Query.Templates+	, module MediaWiki.API.Query.UserContribs+	, module MediaWiki.API.Query.UserInfo+	, module MediaWiki.API.Query.Users+	, module MediaWiki.API.Query.WatchList++	, module MediaWiki.API.Action.Login+	, module MediaWiki.API.Action.ParamInfo+	, module MediaWiki.API.Action.Parse+	, module MediaWiki.API.Action.OpenSearch+	, module MediaWiki.API.Action.FeedWatchlist+	, module MediaWiki.API.Action.ExpandTemplates+        , module MediaWiki.API.Action.Sitematrix+        , module MediaWiki.API.Action.Unblock+        , module MediaWiki.API.Action.Watch+        , module MediaWiki.API.Action.EmailUser+        , module MediaWiki.API.Action.Edit+        , module MediaWiki.API.Action.Move+        , module MediaWiki.API.Action.Block+        , module MediaWiki.API.Action.Protect+        , module MediaWiki.API.Action.Undelete+        , module MediaWiki.API.Action.Delete+        , module MediaWiki.API.Action.Rollback++	) where++import MediaWiki.API.Types+import MediaWiki.API.Query.AllCategories+import MediaWiki.API.Query.AllImages+import MediaWiki.API.Query.AllLinks+import MediaWiki.API.Query.AllMessages+import MediaWiki.API.Query.AllPages+import MediaWiki.API.Query.AllUsers+import MediaWiki.API.Query.BackLinks+import MediaWiki.API.Query.Blocks+import MediaWiki.API.Query.Categories+import MediaWiki.API.Query.CategoryInfo+import MediaWiki.API.Query.CategoryMembers+import MediaWiki.API.Query.DeletedRevisions+import MediaWiki.API.Query.EmbeddedIn+import MediaWiki.API.Query.ExternalLinks+import MediaWiki.API.Query.ExternalURLUsage+import MediaWiki.API.Query.ImageInfo+import MediaWiki.API.Query.Images+import MediaWiki.API.Query.ImageUsage+import MediaWiki.API.Query.Info+import MediaWiki.API.Query.LangLinks+import MediaWiki.API.Query.Links+import MediaWiki.API.Query.LogEvents+import MediaWiki.API.Query.Random+import MediaWiki.API.Query.RecentChanges+import MediaWiki.API.Query.Revisions+import MediaWiki.API.Query.Search+import MediaWiki.API.Query.SiteInfo+import MediaWiki.API.Query.Templates+import MediaWiki.API.Query.UserContribs+import MediaWiki.API.Query.UserInfo+import MediaWiki.API.Query.Users+import MediaWiki.API.Query.WatchList++import MediaWiki.API.Action.Login+import MediaWiki.API.Action.ParamInfo+import MediaWiki.API.Action.Parse+import MediaWiki.API.Action.OpenSearch+import MediaWiki.API.Action.FeedWatchlist+import MediaWiki.API.Action.ExpandTemplates+import MediaWiki.API.Action.Sitematrix+import MediaWiki.API.Action.Unblock+import MediaWiki.API.Action.Watch+import MediaWiki.API.Action.EmailUser+import MediaWiki.API.Action.Edit+import MediaWiki.API.Action.Move+import MediaWiki.API.Action.Block+import MediaWiki.API.Action.Protect+import MediaWiki.API.Action.Undelete+import MediaWiki.API.Action.Delete+import MediaWiki.API.Action.Rollback++-- | Type collecting together the main parts of a MediaWiki API request.+data Request+ = Request+    { reqAction :: Action+    , reqFormat :: Format+    , reqMaxLag :: Maybe Int+    }++emptyRequest :: Action -> Format -> Request+emptyRequest a f + = Request+    { reqAction = a+    , reqFormat = f+    , reqMaxLag = Nothing+    }++emptyXmlRequest :: Action -> Request+emptyXmlRequest a = emptyRequest a xmlFormat++data Action+ = Sitematrix+ | Login           LoginRequest+ | Logout+ | Query           QueryRequest [String]+ | ExpandTemplates ExpandTemplatesRequest+ | Parse           ParseRequest+ | OpenSearch      OpenSearchRequest+ | FeedWatch       FeedWatchListRequest+ | Help            HelpRequest+ | ParamInfo       ParamInfoRequest+ | Unblock         UnblockRequest+ | Watch           WatchRequest+ | EmailUser       EmailUserRequest+ | Edit            EditRequest+ | Move            MoveRequest+ | Block           BlockRequest+ | Protect         ProtectRequest+ | Undelete        UndeleteRequest+ | Delete          DeleteRequest+ | Rollback        RollbackRequest+ | OtherAction     String [ValueName]+++infoRequest :: InfoRequest+infoRequest = emptyInfoRequest++revisionRequest :: RevisionRequest+revisionRequest  = emptyRevisionRequest++linksRequest :: LinksRequest+linksRequest = emptyLinksRequest++langLinksRequest :: LangLinksRequest+langLinksRequest  = emptyLangLinksRequest++imagesRequest :: ImagesRequest+imagesRequest = emptyImagesRequest++imageInfoRequest :: ImageInfoRequest+imageInfoRequest = emptyImageInfoRequest++templatesRequest :: TemplatesRequest+templatesRequest = emptyTemplatesRequest++categoriesRequest :: CategoriesRequest+categoriesRequest = emptyCategoriesRequest++allCategoriesRequest :: AllCategoriesRequest+allCategoriesRequest = emptyAllCategoriesRequest++allImagesRequest :: AllImagesRequest+allImagesRequest = emptyAllImagesRequest++allLinksRequest :: AllLinksRequest+allLinksRequest  = emptyAllLinksRequest++allMessagesRequest :: AllMessagesRequest+allMessagesRequest = emptyAllMessagesRequest++allPagesRequest :: AllPagesRequest+allPagesRequest = emptyAllPagesRequest++allUsersRequest :: AllUsersRequest+allUsersRequest = emptyAllUsersRequest++backLinksRequest :: BackLinksRequest+backLinksRequest = emptyBackLinksRequest++embeddedInRequest :: EmbeddedInRequest+embeddedInRequest = emptyEmbeddedInRequest++imageUsageRequest :: ImageUsageRequest+imageUsageRequest = emptyImageUsageRequest++categoryInfoRequest :: CategoryInfoRequest+categoryInfoRequest = emptyCategoryInfoRequest++categoryMembersRequest :: CategoryMembersRequest+categoryMembersRequest = emptyCategoryMembersRequest++externalLinksRequest :: ExternalLinksRequest+externalLinksRequest = emptyExternalLinksRequest++externalURLUsageRequest :: ExternalURLUsageRequest+externalURLUsageRequest = emptyExternalURLUsageRequest++logEventsRequest :: LogEventsRequest+logEventsRequest = emptyLogEventsRequest++recentChangesRequest :: RecentChangesRequest+recentChangesRequest = emptyRecentChangesRequest++searchRequest :: String -> SearchRequest+searchRequest = emptySearchRequest++siteInfoRequest :: SiteInfoRequest+siteInfoRequest = emptySiteInfoRequest++userContribsRequest :: UserContribsRequest+userContribsRequest = emptyUserContribsRequest++userInfoRequest :: UserInfoRequest+userInfoRequest = emptyUserInfoRequest++watchListRequest :: WatchListRequest+watchListRequest = emptyWatchListRequest++blocksRequest :: BlocksRequest+blocksRequest = emptyBlocksRequest++deletedRevisionsRequest :: DeletedRevisionsRequest+deletedRevisionsRequest = emptyDeletedRevisionsRequest++usersRequest :: UsersRequest+usersRequest = emptyUsersRequest++randomPagesRequest :: RandomPagesRequest+randomPagesRequest = emptyRandomPagesRequest++data QueryRequestKind+ = InfoProp          InfoRequest+ | RevisionsProp     RevisionRequest+ | LinksPropProp     LinksRequest+ | LangLinksProp     LangLinksRequest+ | ImagesProp        ImagesRequest+ | ImageInfoProp     ImageInfoRequest+ | TemplatesProp     TemplatesRequest+ | CategoriesProp    CategoriesRequest+ | AllCategoriesProp AllCategoriesRequest+ | AllImagesProp     AllImagesRequest+ | AllLinksProp      AllLinksRequest+ | AllMessagesProp   AllMessagesRequest+ | AllPagesProp      AllPagesRequest+ | AllUsersProp      AllUsersRequest+ | BacklinksProp     BackLinksRequest+ | EmbeddedInProp    EmbeddedInRequest+ | ImageUsageProp    ImageUsageRequest+ | CategoryInfoProp  CategoryInfoRequest+ | CategoryMembersProp  CategoryMembersRequest+ | ExternalLinksProp    ExternalLinksRequest+ | ExternalURLUsageProp ExternalURLUsageRequest+ | LogEventsProp        LogEventsRequest+ | RecentChangesProp    RecentChangesRequest+ | SearchProp           SearchRequest+ | SiteInfoProp         SiteInfoRequest+ | UserContribsProp     UserContribsRequest+ | UserInfoProp         UserInfoRequest+ | WatchListProp        WatchListRequest+ | BlocksProp           BlocksRequest+ | DeletedRevsProp      DeletedRevisionsRequest+ | UsersProp            UsersRequest+ | RandomProp           RandomPagesRequest++qKind :: QueryRequestKind -> QueryKind+qKind q = + case q of+   InfoProp k -> queryKind k+   RevisionsProp k -> queryKind k+   LinksPropProp k -> queryKind k+   LangLinksProp k -> queryKind k+   ImagesProp    k -> queryKind k+   ImageInfoProp k -> queryKind k+   TemplatesProp k -> queryKind k+   CategoriesProp k -> queryKind k+   AllCategoriesProp k -> queryKind k+   AllImagesProp     k -> queryKind k+   AllLinksProp      k -> queryKind k+   AllMessagesProp   k -> queryKind k+   AllPagesProp      k -> queryKind k+   AllUsersProp      k -> queryKind k+   BacklinksProp     k -> queryKind k+   EmbeddedInProp    k -> queryKind k+   ImageUsageProp    k -> queryKind k+   CategoryInfoProp  k -> queryKind k+   CategoryMembersProp k -> queryKind k+   ExternalLinksProp   k -> queryKind k+   ExternalURLUsageProp k -> queryKind k+   LogEventsProp        k -> queryKind k+   RecentChangesProp    k -> queryKind k+   SearchProp           k -> queryKind k+   SiteInfoProp         k -> queryKind k+   UserContribsProp     k -> queryKind k+   UserInfoProp         k -> queryKind k+   WatchListProp        k -> queryKind k+   BlocksProp           k -> queryKind k+   DeletedRevsProp      k -> queryKind k+   UsersProp            k -> queryKind k+   RandomProp           k -> queryKind k+ 
MediaWiki/API/Output.hs view
@@ -1,212 +1,212 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Output
--- Description : Serializing MediaWiki API types
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Serializing MediaWiki API types
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Output where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Base
-
-import MediaWiki.Util.Codec.Percent
-
-import Data.List
-import Data.Maybe
-
-showRequest :: Request -> String
-showRequest req = 
-  join (showAction (reqAction req) : showMaxLag (reqMaxLag req) (showFormat (reqFormat req)))
-
-showMaxLag :: Maybe Int -> String -> [String]
-showMaxLag Nothing  rs = [rs]
-showMaxLag (Just l) rs = [field "maxlag" (show l), rs]
-
-showFormat :: Format -> String
-showFormat f = field "format" $ isFormatted (formatFormatted f) $
- case formatKind f of
-   FormatJSON -> "json"
-   FormatPHP  -> "php"
-   FormatWDDX -> "wddx"
-   FormatXML  -> "xml"
-   FormatYAML -> "yaml"
-   FormatTxt  -> "txt"
-   FormatDbg  -> "dbg"
- where
-  isFormatted False xs = xs
-  isFormatted _     xs = xs++"fm"
-  
-toReq :: APIRequest a => a -> [String]
-toReq x =
- case catMaybes $ showReq x of
-   [] -> []
-   xs -> map showP xs
- where
-  showP (a,b) = a ++ '=':b
-
-showQueryRequestKind :: QueryRequestKind -> [String]
-showQueryRequestKind r = 
- case r of
-   InfoProp p -> toReq p
-   RevisionsProp p -> toReq p
-   LinksPropProp p -> toReq p
-   LangLinksProp p -> toReq p
-   ImagesProp    p -> toReq p
-   ImageInfoProp p -> toReq p
-   TemplatesProp p -> toReq p
-   CategoriesProp p -> toReq p
-   AllCategoriesProp p -> toReq p
-   AllImagesProp     p -> toReq p
-   AllLinksProp      p -> toReq p
-   AllMessagesProp   p -> toReq p
-   AllPagesProp      p -> toReq p
-   AllUsersProp      p -> toReq p
-   BacklinksProp     p -> toReq p
-   EmbeddedInProp    p -> toReq p
-   ImageUsageProp    p -> toReq p
-   CategoryInfoProp  p -> toReq p
-   CategoryMembersProp p -> toReq p
-   ExternalLinksProp    p -> toReq p
-   ExternalURLUsageProp p -> toReq p
-   LogEventsProp        p -> toReq p
-   RecentChangesProp    p -> toReq p
-   SearchProp           p -> toReq p
-   SiteInfoProp         p -> toReq p
-   UserContribsProp     p -> toReq p
-   UserInfoProp         p -> toReq p
-   WatchListProp        p -> toReq p
-   BlocksProp           p -> toReq p
-   DeletedRevsProp      p -> toReq p
-   UsersProp            p -> toReq p
-   RandomProp           p -> toReq p
- 
-
-showAction :: Action -> String
-showAction act = join $
-  case act of
-    Sitematrix -> [field "action" "sitematrix"]
-    Login l    -> (field "action" "login"): (toReq l)
-    Logout     -> [field "action" "logout"]
-    Query q qr -> (field "action" "query") : (showQuery q) ++ qr
-    ExpandTemplates et -> (field "action" "expandtemplates") : (showExpandTemplates et)
-    Parse pt -> (field "action" "parse") : (showParseRequest pt)
-    OpenSearch os ->  (field "action" "opensearch") : (showOpenSearch os)
-    FeedWatch f -> (field "action" "feedwatchlist") : (showFeedWatch f)
-    Help h -> (field "action" "help") : (showHelpRequest h)
-    ParamInfo pin ->  (field "action" "paraminfo") : (showParamInfoRequest pin)
-    Unblock r -> (field "action" "unblock") : toReq r
-    Watch   r -> (field "action" "watch") : toReq r
-    EmailUser r -> (field "action" "emailuser") : toReq r
-    Edit      r -> (field "action" "edit") : toReq r
-    Move      r -> (field "action" "move") : toReq r
-    Block     r -> (field "action" "block") : toReq r
-    Protect   r -> (field "action" "protect") : toReq r
-    Undelete  r -> (field "action" "undelete") : toReq r
-    Delete    r -> (field "action" "delete") : toReq r
-    Rollback  r -> (field "action" "rollback") : toReq r
-    OtherAction  at vs -> (field "action" at) : (map showValueName vs)
-
-{-
-showLoginRequest :: LoginRequest -> [String]
-showLoginRequest l = catMaybes 
-  [ Just $ field "name" (lgName l)
-  , Just $ field "password" (lgPassword l)
-  , fieldMb "version" id (lgDomain l)
-  ]
--}
-
-showHelpRequest :: HelpRequest -> [String]
-showHelpRequest h = 
-  maybeToList (fieldMb "version" showBool (helpVersion h))
-
-showQuery :: QueryRequest -> [String]
-showQuery q = catMaybes
-  [ fList    "titles"  (quTitles q)
-  , fList    "pageids" (quPageIds q)
-  , fList    "revids"  (quRevIds q)
-  , fList    "prop"    (map showPropKind $ quProps q)
-  , fList    "list"    (map showListKind $ quLists q)
-  , fList    "meta"    (map showMetaKind $ quMetas q)
-  , fieldMb  "generator"    showGeneratorKind  (quGenerator q)
-  , fieldMb  "redirects"    showBool           (quFollowRedirects q)
-  , fieldMb  "indexpageids" showBool           (quIndexPageIds q)
-  ]
- where
-  fList t ls = fieldList t "|" ls
-
-showExpandTemplates :: ExpandTemplatesRequest -> [String]
-showExpandTemplates et = catMaybes
-  [ fieldMb "title" id (etTitle et)
-  , Just $ field "text" (etText et)
-  ]
-  
-showPropKind :: PropKind -> String
-showPropKind pk = prKind pk
-
-showListKind :: ListKind -> String
-showListKind lk = liKind lk
-
-showMetaKind :: MetaKind -> String
-showMetaKind mk = meKind mk
-
-showParseRequest :: ParseRequest -> [String]
-showParseRequest p = catMaybes
-  [ fieldMb "title" id (paTitle p)
-  , Just $ field "text" (paText p)
-  , fieldMb "page" id (paPage p)
-  , fieldList "prop" "|" (paProp p)
-  ]
-  
-showOpenSearch :: OpenSearchRequest -> [String]
-showOpenSearch o = catMaybes
-  [ Just $ field "search" (osSearch o)
-  , fieldMb "limit" show (osLimit o)
-  ]
-  
-showFeedWatch :: FeedWatchListRequest -> [String]
-showFeedWatch f = catMaybes
- [ Just $ field "feedformat" (if feAsAtom f then "atom" else "rss")
- , fieldMb "hours" show (feHours f)
- , if feAllRev f then (Just $ field  "allrev" "") else Nothing
- ]
- 
-showParamInfoRequest :: ParamInfoRequest -> [String]
-showParamInfoRequest p = catMaybes
- [ fieldList "modules" "," (paModules p)
- , fieldList "querymodules" "|" (paQueryModules p)
- ]
- 
-showGeneratorKind :: GeneratorKind -> String
-showGeneratorKind gk = genKind gk
-
-showValueName :: ValueName -> String
-showValueName (n,v) = field n v
-
-showBool :: Bool -> String
-showBool True = "true"
-showBool _    = "false"
-
-join :: [String] -> String
-join [] = ""
-join xs = concat (intersperse "&" xs)
-
-field :: String -> String -> String
-field a b = a ++ '=':b
-
-fieldMb :: String -> (a -> String) -> Maybe a -> Maybe String
-fieldMb _ _ Nothing = Nothing
-fieldMb n f (Just x) = Just (field n (f x))
-
-fieldList :: String -> String -> [String] -> Maybe String
-fieldList _ _ [] = Nothing
-fieldList n s xs = Just (field n (intercalate (getEncodedString s) xs))
-
-
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Output+-- Description : Serializing MediaWiki API types+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Serializing MediaWiki API types+-- +--------------------------------------------------------------------+module MediaWiki.API.Output where++import MediaWiki.API.Types+import MediaWiki.API.Base++import MediaWiki.Util.Codec.Percent++import Data.List+import Data.Maybe++showRequest :: Request -> String+showRequest req = +  join (showAction (reqAction req) : showMaxLag (reqMaxLag req) (showFormat (reqFormat req)))++showMaxLag :: Maybe Int -> String -> [String]+showMaxLag Nothing  rs = [rs]+showMaxLag (Just l) rs = [field "maxlag" (show l), rs]++showFormat :: Format -> String+showFormat f = field "format" $ isFormatted (formatFormatted f) $+ case formatKind f of+   FormatJSON -> "json"+   FormatPHP  -> "php"+   FormatWDDX -> "wddx"+   FormatXML  -> "xml"+   FormatYAML -> "yaml"+   FormatTxt  -> "txt"+   FormatDbg  -> "dbg"+ where+  isFormatted False xs = xs+  isFormatted _     xs = xs++"fm"+  +toReq :: APIRequest a => a -> [String]+toReq x =+ case catMaybes $ showReq x of+   [] -> []+   xs -> map showP xs+ where+  showP (a,b) = a ++ '=':b++showQueryRequestKind :: QueryRequestKind -> [String]+showQueryRequestKind r = + case r of+   InfoProp p -> toReq p+   RevisionsProp p -> toReq p+   LinksPropProp p -> toReq p+   LangLinksProp p -> toReq p+   ImagesProp    p -> toReq p+   ImageInfoProp p -> toReq p+   TemplatesProp p -> toReq p+   CategoriesProp p -> toReq p+   AllCategoriesProp p -> toReq p+   AllImagesProp     p -> toReq p+   AllLinksProp      p -> toReq p+   AllMessagesProp   p -> toReq p+   AllPagesProp      p -> toReq p+   AllUsersProp      p -> toReq p+   BacklinksProp     p -> toReq p+   EmbeddedInProp    p -> toReq p+   ImageUsageProp    p -> toReq p+   CategoryInfoProp  p -> toReq p+   CategoryMembersProp p -> toReq p+   ExternalLinksProp    p -> toReq p+   ExternalURLUsageProp p -> toReq p+   LogEventsProp        p -> toReq p+   RecentChangesProp    p -> toReq p+   SearchProp           p -> toReq p+   SiteInfoProp         p -> toReq p+   UserContribsProp     p -> toReq p+   UserInfoProp         p -> toReq p+   WatchListProp        p -> toReq p+   BlocksProp           p -> toReq p+   DeletedRevsProp      p -> toReq p+   UsersProp            p -> toReq p+   RandomProp           p -> toReq p+ ++showAction :: Action -> String+showAction act = join $+  case act of+    Sitematrix -> [field "action" "sitematrix"]+    Login l    -> (field "action" "login"): (toReq l)+    Logout     -> [field "action" "logout"]+    Query q qr -> (field "action" "query") : (showQuery q) ++ qr+    ExpandTemplates et -> (field "action" "expandtemplates") : (showExpandTemplates et)+    Parse pt -> (field "action" "parse") : (showParseRequest pt)+    OpenSearch os ->  (field "action" "opensearch") : (showOpenSearch os)+    FeedWatch f -> (field "action" "feedwatchlist") : (showFeedWatch f)+    Help h -> (field "action" "help") : (showHelpRequest h)+    ParamInfo pin ->  (field "action" "paraminfo") : (showParamInfoRequest pin)+    Unblock r -> (field "action" "unblock") : toReq r+    Watch   r -> (field "action" "watch") : toReq r+    EmailUser r -> (field "action" "emailuser") : toReq r+    Edit      r -> (field "action" "edit") : toReq r+    Move      r -> (field "action" "move") : toReq r+    Block     r -> (field "action" "block") : toReq r+    Protect   r -> (field "action" "protect") : toReq r+    Undelete  r -> (field "action" "undelete") : toReq r+    Delete    r -> (field "action" "delete") : toReq r+    Rollback  r -> (field "action" "rollback") : toReq r+    OtherAction  at vs -> (field "action" at) : (map showValueName vs)++{-+showLoginRequest :: LoginRequest -> [String]+showLoginRequest l = catMaybes +  [ Just $ field "name" (lgName l)+  , Just $ field "password" (lgPassword l)+  , fieldMb "version" id (lgDomain l)+  ]+-}++showHelpRequest :: HelpRequest -> [String]+showHelpRequest h = +  maybeToList (fieldMb "version" showBool (helpVersion h))++showQuery :: QueryRequest -> [String]+showQuery q = catMaybes+  [ fList    "titles"  (quTitles q)+  , fList    "pageids" (quPageIds q)+  , fList    "revids"  (quRevIds q)+  , fList    "prop"    (map showPropKind $ quProps q)+  , fList    "list"    (map showListKind $ quLists q)+  , fList    "meta"    (map showMetaKind $ quMetas q)+  , fieldMb  "generator"    showGeneratorKind  (quGenerator q)+  , fieldMb  "redirects"    showBool           (quFollowRedirects q)+  , fieldMb  "indexpageids" showBool           (quIndexPageIds q)+  ]+ where+  fList t ls = fieldList t "|" ls++showExpandTemplates :: ExpandTemplatesRequest -> [String]+showExpandTemplates et = catMaybes+  [ fieldMb "title" id (etTitle et)+  , Just $ field "text" (etText et)+  ]+  +showPropKind :: PropKind -> String+showPropKind pk = prKind pk++showListKind :: ListKind -> String+showListKind lk = liKind lk++showMetaKind :: MetaKind -> String+showMetaKind mk = meKind mk++showParseRequest :: ParseRequest -> [String]+showParseRequest p = catMaybes+  [ fieldMb "title" id (paTitle p)+  , Just $ field "text" (paText p)+  , fieldMb "page" id (paPage p)+  , fieldList "prop" "|" (paProp p)+  ]+  +showOpenSearch :: OpenSearchRequest -> [String]+showOpenSearch o = catMaybes+  [ Just $ field "search" (osSearch o)+  , fieldMb "limit" show (osLimit o)+  ]+  +showFeedWatch :: FeedWatchListRequest -> [String]+showFeedWatch f = catMaybes+ [ Just $ field "feedformat" (if feAsAtom f then "atom" else "rss")+ , fieldMb "hours" show (feHours f)+ , if feAllRev f then (Just $ field  "allrev" "") else Nothing+ ]+ +showParamInfoRequest :: ParamInfoRequest -> [String]+showParamInfoRequest p = catMaybes+ [ fieldList "modules" "," (paModules p)+ , fieldList "querymodules" "|" (paQueryModules p)+ ]+ +showGeneratorKind :: GeneratorKind -> String+showGeneratorKind gk = genKind gk++showValueName :: ValueName -> String+showValueName (n,v) = field n v++showBool :: Bool -> String+showBool True = "true"+showBool _    = "false"++join :: [String] -> String+join [] = ""+join xs = concat (intersperse "&" xs)++field :: String -> String -> String+field a b = a ++ '=':b++fieldMb :: String -> (a -> String) -> Maybe a -> Maybe String+fieldMb _ _ Nothing = Nothing+fieldMb n f (Just x) = Just (field n (f x))++fieldList :: String -> String -> [String] -> Maybe String+fieldList _ _ [] = Nothing+fieldList n s xs = Just (field n (intercalate (getEncodedString s) xs))++
MediaWiki/API/Query/AllImages/Import.hs view
@@ -1,12 +1,10 @@ module MediaWiki.API.Query.AllImages.Import where -import MediaWiki.API.Types import MediaWiki.API.Utils import MediaWiki.API.Query.AllImages import MediaWiki.API.Query.ImageInfo.Import ( xmlII )  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/AllPages/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.AllPages  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/AllUsers/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.AllUsers  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/Blocks/Import.hs view
@@ -1,11 +1,9 @@ module MediaWiki.API.Query.Blocks.Import where -import MediaWiki.API.Types import MediaWiki.API.Utils import MediaWiki.API.Query.Blocks  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/Categories/Import.hs view
@@ -16,8 +16,8 @@ xml e = do   guard (elName e == nsName "api")   let es1 = children e-  p  <- pNode "query" es1-  let es2 = children p+  q  <- pNode "query" es1+  let es2 = children q   p  <- pNode "pages" es2   let ps0 = pNodes "page" $ children p   let ps1 = catMaybes (map xmlPage ps0)@@ -32,7 +32,7 @@      -- depending on being 'prop'-constrained, a 'page'      -- may have a 'categories' child. (Or the page may not belong      -- to a category at all, I suppose..)-   let cs = +   let cs =         maybe []               (\ c -> catMaybes (map xmlCL (pNodes "cl" $ children c)))               (pNode "categories" es)
MediaWiki/API/Query/CategoryMembers/Import.hs view
@@ -28,5 +28,4 @@    let ns     = fromMaybe "0" $ pAttr "ns" e    let tit    = fromMaybe ""  $ pAttr "title" e    let mbpid  = pAttr "pageid" e-   let ts     = pAttr "timestamp" e-   return emptyPageTitle{pgNS=ns,pgTitle=tit,pgMbId=mbpid}+   return emptyPageTitle{pgNS = ns,pgTitle = tit,pgMbId = mbpid}
MediaWiki/API/Query/ExternalURLUsage/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.ExternalURLUsage  import Text.XML.Light.Types-import Text.XML.Light.Proc ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/ImageInfo/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.ImageInfo  import Text.XML.Light.Types-import Text.XML.Light.Proc ( strContent )  import Control.Monad import Data.Maybe@@ -39,7 +38,7 @@  xmlII :: String -> Element -> Maybe ImageInfo xmlII tg p = do-   guard (elName p == nsName tg) +   guard (elName p == nsName tg)    let ts = fromMaybe nullTimestamp (pAttr "timestamp" p)    let us = fromMaybe nullUser (pAttr "user" p)    let wi = pAttr "width" p >>= readI@@ -65,11 +64,11 @@     , iiMime      = mi     } -   + readI :: String -> Maybe Int-readI s = +readI s =   case reads s of     ((v,_):_) -> Just v     _ -> Nothing-    + 
MediaWiki/API/Query/Info.hs view
@@ -1,90 +1,90 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Query.Info
--- Description : Representing 'info' requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing 'info' requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Query.Info where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Utils
-
-data InfoRequest
- = InfoRequest
-     { inProps  :: [String]
-     , inTokens :: [String]
-     }
-
-instance APIRequest InfoRequest where
-  queryKind _ = QProp "info"
-  showReq r = 
-   [ opt1 "inprop" (inProps r)
-   , opt1 "intoken" (inTokens r)
-   ]
-
-emptyInfoRequest :: InfoRequest
-emptyInfoRequest = InfoRequest
-     { inProps  = []
-     , inTokens = []
-     }
-
-data InfoResponse
- = InfoResponse
-     { infPages :: [InfoPage]
-     }
-     
-data InfoPage
- = InfoPage
-     { infPage       :: PageTitle
-     , infTouched    :: TimeString
-     , infLastRevId  :: RevID
-     , infCounter    :: Integer
-     , infLength     :: Integer
-     , infIsRedirect :: Bool
-     , infIsNew      :: Bool
-     , infEditTok    :: Maybe Token
-     , infDeleteTok  :: Maybe Token
-     , infProtectTok :: Maybe Token
-     , infMoveTok    :: Maybe Token
-     , infProtection :: [PageRestriction]
-     }
-
-emptyInfoResponse :: InfoResponse
-emptyInfoResponse =
-   InfoResponse{ infPages= []
-               }
-
-emptyInfoPage :: InfoPage
-emptyInfoPage =
-   InfoPage
-     { infPage       = emptyPageTitle
-     , infTouched    = ""
-     , infLastRevId  = ""
-     , infCounter    = 0
-     , infLength     = 0
-     , infIsRedirect = False
-     , infIsNew      = False
-     , infEditTok    = Nothing
-     , infDeleteTok  = Nothing
-     , infProtectTok = Nothing
-     , infMoveTok    = Nothing
-     , infProtection = []
-     }
-
-data PageRestriction
- = PageRestriction
-     { prPageId  :: PageID
-     , prSource  :: PageName
-     , prType    :: String
-     , prLevel   :: Integer
-     , prExpiry  :: TimeString
-     , prCascade :: Bool
-     }
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Query.Info+-- Description : Representing 'info' requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing 'info' requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Query.Info where++import MediaWiki.API.Types+import MediaWiki.API.Utils++data InfoRequest+ = InfoRequest+     { inProps  :: [String]+     , inTokens :: [String]+     }++instance APIRequest InfoRequest where+  queryKind _ = QProp "info"+  showReq r = +   [ opt1 "inprop" (inProps r)+   , opt1 "intoken" (inTokens r)+   ]++emptyInfoRequest :: InfoRequest+emptyInfoRequest = InfoRequest+     { inProps  = []+     , inTokens = []+     }++data InfoResponse+ = InfoResponse+     { infPages :: [InfoPage]+     }+     +data InfoPage+ = InfoPage+     { infPage       :: PageTitle+     , infTouched    :: TimeString+     , infLastRevId  :: RevID+     , infCounter    :: Integer+     , infLength     :: Integer+     , infIsRedirect :: Bool+     , infIsNew      :: Bool+     , infEditTok    :: Maybe Token+     , infDeleteTok  :: Maybe Token+     , infProtectTok :: Maybe Token+     , infMoveTok    :: Maybe Token+     , infProtection :: [PageRestriction]+     }++emptyInfoResponse :: InfoResponse+emptyInfoResponse =+   InfoResponse{ infPages= []+               }++emptyInfoPage :: InfoPage+emptyInfoPage =+   InfoPage+     { infPage       = emptyPageTitle+     , infTouched    = ""+     , infLastRevId  = ""+     , infCounter    = 0+     , infLength     = 0+     , infIsRedirect = False+     , infIsNew      = False+     , infEditTok    = Nothing+     , infDeleteTok  = Nothing+     , infProtectTok = Nothing+     , infMoveTok    = Nothing+     , infProtection = []+     }++data PageRestriction+ = PageRestriction+     { prPageId  :: PageID+     , prSource  :: PageName+     , prType    :: String+     , prLevel   :: Integer+     , prExpiry  :: TimeString+     , prCascade :: Bool+     }
MediaWiki/API/Query/Info/Import.hs view
@@ -1,54 +1,54 @@-module MediaWiki.API.Query.Info.Import where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Utils
-import MediaWiki.API.Query.Info
-
-import Text.XML.Light.Types
-
-import Control.Monad
-import Data.Maybe
-
-stringXml :: String -> Either (String,[{-Error msg-}String]) InfoResponse
-stringXml s = parseDoc xml s
-
-xml :: Element -> Maybe InfoResponse
-xml e = do
-  guard (elName e == nsName "api")
-  let es1 = children e
-  p  <- pNode "query" es1
-  let es = children p
-  ps <- fmap (mapMaybe xmlPage) (fmap children $ pNode "pages" es)
-  return emptyInfoResponse{infPages=ps}
-
-xmlPage :: Element -> Maybe InfoPage
-xmlPage e = do
-  guard (elName e == nsName "page")
-  let touched = fromMaybe "" $ pAttr "touched" e
-  let rvid    = fromMaybe "0"  $ pAttr "lastrevid" e
-  let cnt     = fromMaybe 0  $ (pAttr "counter" e >>= readMb)
-  let len     = fromMaybe 0  $ (pAttr "length" e  >>= readMb)
-  let ns      = fromMaybe "0" $ pAttr "ns" e
-  let tit     = fromMaybe ""  $ pAttr "title" e
-  let pid     = pAttr "pageid" e
-  let miss    = fromMaybe False  $ fmap (const True) $ pAttr "missing" e
-  let red     = fromMaybe False  $ fmap (const True) $ pAttr "redirect" e
-  let new     = fromMaybe False  $ fmap (const True) $ pAttr "new" e
-  let edTok   = pAttr "edittoken" e
-  let deTok   = pAttr "deletetoken" e
-  let prTok   = pAttr "protecttoken" e
-  let moTok   = pAttr "movetoken" e
-  return emptyInfoPage
-    { infPage = emptyPageTitle{pgNS=ns,pgTitle=tit,pgMbId=pid,pgMissing=miss}
-    , infTouched   = touched
-    , infLastRevId = rvid
-    , infCounter   = cnt
-    , infLength    = len
-    , infIsRedirect = red
-    , infIsNew      = new
-    , infEditTok    = edTok
-    , infDeleteTok  = deTok
-    , infProtectTok  = prTok
-    , infMoveTok     = moTok
-    , infProtection  = []
-    }
+module MediaWiki.API.Query.Info.Import where++import MediaWiki.API.Types+import MediaWiki.API.Utils+import MediaWiki.API.Query.Info++import Text.XML.Light.Types++import Control.Monad+import Data.Maybe++stringXml :: String -> Either (String,[{-Error msg-}String]) InfoResponse+stringXml s = parseDoc xml s++xml :: Element -> Maybe InfoResponse+xml e = do+  guard (elName e == nsName "api")+  let es1 = children e+  p  <- pNode "query" es1+  let es = children p+  ps <- fmap (mapMaybe xmlPage) (fmap children $ pNode "pages" es)+  return emptyInfoResponse{infPages=ps}++xmlPage :: Element -> Maybe InfoPage+xmlPage e = do+  guard (elName e == nsName "page")+  let touched = fromMaybe "" $ pAttr "touched" e+  let rvid    = fromMaybe "0"  $ pAttr "lastrevid" e+  let cnt     = fromMaybe 0  $ (pAttr "counter" e >>= readMb)+  let len     = fromMaybe 0  $ (pAttr "length" e  >>= readMb)+  let ns      = fromMaybe "0" $ pAttr "ns" e+  let tit     = fromMaybe ""  $ pAttr "title" e+  let pid     = pAttr "pageid" e+  let miss    = fromMaybe False  $ fmap (const True) $ pAttr "missing" e+  let red     = fromMaybe False  $ fmap (const True) $ pAttr "redirect" e+  let new     = fromMaybe False  $ fmap (const True) $ pAttr "new" e+  let edTok   = pAttr "edittoken" e+  let deTok   = pAttr "deletetoken" e+  let prTok   = pAttr "protecttoken" e+  let moTok   = pAttr "movetoken" e+  return emptyInfoPage+    { infPage = emptyPageTitle{pgNS=ns,pgTitle=tit,pgMbId=pid,pgMissing=miss}+    , infTouched   = touched+    , infLastRevId = rvid+    , infCounter   = cnt+    , infLength    = len+    , infIsRedirect = red+    , infIsNew      = new+    , infEditTok    = edTok+    , infDeleteTok  = deTok+    , infProtectTok  = prTok+    , infMoveTok     = moTok+    , infProtection  = []+    }
MediaWiki/API/Query/Links.hs view
@@ -1,55 +1,55 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Query.Links
--- Description : Representing 'links' requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing 'links' requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Query.Links where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Utils
-
-data LinksRequest
- = LinksRequest
-    { plNamespaces   :: [NamespaceID]
-    , plLimit        :: Maybe Int
-    , plContinueFrom :: Maybe String
-    }
-
-instance APIRequest LinksRequest where
-  queryKind _ = QProp "links"
-  showReq r
-   = [ opt1 "plnamespace" (plNamespaces r)
-     , mbOpt "pllimit" show (plLimit r)
-     , mbOpt "plcontinue" id (plContinueFrom r)
-     ]
-
-
-emptyLinksRequest :: LinksRequest
-emptyLinksRequest 
- = LinksRequest
-    { plNamespaces   = []
-    , plLimit        = Nothing
-    , plContinueFrom = Nothing
-    }
-
-data LinksResponse
- = LinksResponse
-    { plPages    :: [(PageTitle,[PageTitle])]
-    , plContinue :: Maybe String
-    }
-
-emptyLinksResponse :: LinksResponse
-emptyLinksResponse = LinksResponse
-    { plPages = []
-    , plContinue = Nothing
-    }
-    
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Query.Links+-- Description : Representing 'links' requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing 'links' requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Query.Links where++import MediaWiki.API.Types+import MediaWiki.API.Utils++data LinksRequest+ = LinksRequest+    { plNamespaces   :: [NamespaceID]+    , plLimit        :: Maybe Int+    , plContinueFrom :: Maybe String+    }++instance APIRequest LinksRequest where+  queryKind _ = QProp "links"+  showReq r+   = [ opt1 "plnamespace" (plNamespaces r)+     , mbOpt "pllimit" show (plLimit r)+     , mbOpt "plcontinue" id (plContinueFrom r)+     ]+++emptyLinksRequest :: LinksRequest+emptyLinksRequest + = LinksRequest+    { plNamespaces   = []+    , plLimit        = Nothing+    , plContinueFrom = Nothing+    }++data LinksResponse+ = LinksResponse+    { plPages    :: [(PageTitle,[PageTitle])]+    , plContinue :: Maybe String+    }++emptyLinksResponse :: LinksResponse+emptyLinksResponse = LinksResponse+    { plPages = []+    , plContinue = Nothing+    }+    
MediaWiki/API/Query/Random/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.Random  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/RecentChanges/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.RecentChanges  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe@@ -36,8 +35,8 @@   let ns_t = pAttr "new_ns" e   let tit_t = pAttr "new_title" e   let pid_t = pAttr "new_pageid" e-  let pg_to -       | any isJust [ns_t,tit_t,pid_t] +  let pg_to+       | any isJust [ns_t,tit_t,pid_t]        = Just           emptyPageTitle{ pgNS=fromMaybe mainNamespace ns_t                         , pgTitle=fromMaybe "" tit_t@@ -73,8 +72,3 @@ 	   , rchTimestamp = ts 	   , rchComment = co 	   }-	   --  -  -
MediaWiki/API/Query/Revisions.hs view
@@ -1,110 +1,110 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Query.Revisions
--- Description : Representing 'revisions' requests.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Representing 'revisions' requests.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Query.Revisions where
-
-import MediaWiki.API.Types
-import MediaWiki.API.Utils
-
-data RevisionRequest
- = RevisionRequest
-    { rvProp            :: [String]
-    , rvLimit           :: Maybe Int
-    , rvStartID         :: Maybe RevID
-    , rvEndID           :: Maybe RevID
-    , rvStart           :: Maybe TimeString
-    , rvEnd             :: Maybe TimeString
-    , rvDir             :: Maybe Direction
-    , rvUser            :: Maybe UserName
-    , rvExcludeUser     :: Maybe UserName
-    , rvExpandTemplates :: Maybe Bool
-    , rvSection         :: Maybe String
-    , rvTokens          :: [String]
-    }
-
-instance APIRequest RevisionRequest where
-  queryKind _ = QProp "revisions"
-  showReq r =
-    [ opt1 "rvprop" (rvProp r)
-    , mbOpt "rvlimit" show (rvLimit r)
-    , mbOpt "rvstartid" id (rvStartID r)
-    , mbOpt "rvendid" id (rvEndID r)
-    , mbOpt "rvstart" id (rvStart r)
-    , mbOpt "rvend"   id (rvEnd r)
-    , mbOpt "rvdir" (\ x -> if x == Up then "ascending" else "descending")
-                    (rvDir r)
-    , mbOpt "rvuser" id (rvUser r)
-    , mbOpt "rvexcludeuser" id (rvExcludeUser r)
-    , optB  "rvexpandtemplates" (fromMaybe False (rvExpandTemplates r))
-    , mbOpt "rvsection" id (rvSection r)
-    , opt1  "rvtoken"  (rvTokens r)
-    ]
-
-
-emptyRevisionRequest :: RevisionRequest
-emptyRevisionRequest = RevisionRequest
-    { rvProp            = []
-    , rvLimit           = Nothing
-    , rvStartID         = Nothing
-    , rvEndID           = Nothing
-    , rvStart           = Nothing
-    , rvEnd             = Nothing
-    , rvDir             = Nothing
-    , rvUser            = Nothing
-    , rvExcludeUser     = Nothing
-    , rvExpandTemplates = Nothing
-    , rvTokens          = []
-    , rvSection         = Nothing
-    }
-
-data RevisionsResponse
- = RevisionsResponse
-    { rvPages    :: [(PageTitle,[Revision])]
-    , rvContinue :: Maybe String
-    }
-    
-emptyRevisionsResponse :: RevisionsResponse
-emptyRevisionsResponse 
- = RevisionsResponse
-    { rvPages    = []
-    , rvContinue = Nothing
-    }
-
-data Revision
- = Revision
-    { revPage          :: PageTitle
-    , revRevId         :: RevID
-    , revIsMinor       :: Bool
-    , revUser          :: String
-    , revIsAnon        :: Bool
-    , revTimestamp     :: TimeString
-    , revSize          :: Integer
-    , revComment       :: Maybe String
---    , revRollbackToken :: Maybe Token
-    , revContent       :: Maybe String
-    }
-
-emptyRevision :: PageTitle -> Revision
-emptyRevision pg
- = Revision
-    { revPage          = pg
-    , revRevId         = nullRevId
-    , revIsMinor       = False
-    , revUser          = nullUser
-    , revIsAnon        = False
-    , revTimestamp     = nullTimestamp
-    , revSize          = 0
-    , revComment       = Nothing
-    , revContent       = Nothing
-    }
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Query.Revisions+-- Description : Representing 'revisions' requests.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Representing 'revisions' requests.+-- +--------------------------------------------------------------------+module MediaWiki.API.Query.Revisions where++import MediaWiki.API.Types+import MediaWiki.API.Utils++data RevisionRequest+ = RevisionRequest+    { rvProp            :: [String]+    , rvLimit           :: Maybe Int+    , rvStartID         :: Maybe RevID+    , rvEndID           :: Maybe RevID+    , rvStart           :: Maybe TimeString+    , rvEnd             :: Maybe TimeString+    , rvDir             :: Maybe Direction+    , rvUser            :: Maybe UserName+    , rvExcludeUser     :: Maybe UserName+    , rvExpandTemplates :: Maybe Bool+    , rvSection         :: Maybe String+    , rvTokens          :: [String]+    }++instance APIRequest RevisionRequest where+  queryKind _ = QProp "revisions"+  showReq r =+    [ opt1 "rvprop" (rvProp r)+    , mbOpt "rvlimit" show (rvLimit r)+    , mbOpt "rvstartid" id (rvStartID r)+    , mbOpt "rvendid" id (rvEndID r)+    , mbOpt "rvstart" id (rvStart r)+    , mbOpt "rvend"   id (rvEnd r)+    , mbOpt "rvdir" (\ x -> if x == Up then "ascending" else "descending")+                    (rvDir r)+    , mbOpt "rvuser" id (rvUser r)+    , mbOpt "rvexcludeuser" id (rvExcludeUser r)+    , optB  "rvexpandtemplates" (fromMaybe False (rvExpandTemplates r))+    , mbOpt "rvsection" id (rvSection r)+    , opt1  "rvtoken"  (rvTokens r)+    ]+++emptyRevisionRequest :: RevisionRequest+emptyRevisionRequest = RevisionRequest+    { rvProp            = []+    , rvLimit           = Nothing+    , rvStartID         = Nothing+    , rvEndID           = Nothing+    , rvStart           = Nothing+    , rvEnd             = Nothing+    , rvDir             = Nothing+    , rvUser            = Nothing+    , rvExcludeUser     = Nothing+    , rvExpandTemplates = Nothing+    , rvTokens          = []+    , rvSection         = Nothing+    }++data RevisionsResponse+ = RevisionsResponse+    { rvPages    :: [(PageTitle,[Revision])]+    , rvContinue :: Maybe String+    }+    +emptyRevisionsResponse :: RevisionsResponse+emptyRevisionsResponse + = RevisionsResponse+    { rvPages    = []+    , rvContinue = Nothing+    }++data Revision+ = Revision+    { revPage          :: PageTitle+    , revRevId         :: RevID+    , revIsMinor       :: Bool+    , revUser          :: String+    , revIsAnon        :: Bool+    , revTimestamp     :: TimeString+    , revSize          :: Integer+    , revComment       :: Maybe String+--    , revRollbackToken :: Maybe Token+    , revContent       :: Maybe String+    }++emptyRevision :: PageTitle -> Revision+emptyRevision pg+ = Revision+    { revPage          = pg+    , revRevId         = nullRevId+    , revIsMinor       = False+    , revUser          = nullUser+    , revIsAnon        = False+    , revTimestamp     = nullTimestamp+    , revSize          = 0+    , revComment       = Nothing+    , revContent       = Nothing+    }
MediaWiki/API/Query/Revisions/Import.hs view
@@ -5,8 +5,7 @@ import MediaWiki.API.Query.Revisions  import Text.XML.Light.Types-import Text.XML.Light.Input ( parseXMLDoc )-import Text.XML.Light.Proc  ( strContent )+import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe@@ -33,17 +32,17 @@   let ns      = fromMaybe mainNamespace $ pAttr "ns" e   let tit     = fromMaybe "" $ pAttr "title" e   let pid     = pAttr "pageid" e-  let es = children e  +  let es = children e   p  <- pNode "revisions" es   let pg = emptyPageTitle{pgNS = ns, pgTitle=tit, pgMbId = pid}-  rs <- fmap (mapMaybe (xmlRevision pg)) (fmap children $ pNode "rev" es)+  rs <- fmap (mapMaybe (xmlRevision pg)) (fmap children $ pNode "rev" (children p))   return (pg, rs)  xmlRevision :: PageTitle -> Element -> Maybe Revision xmlRevision pg e = do   guard (elName e == nsName "page")   let rid  = fromMaybe "" $ pAttr "revid" e-  let min  = isJust (pAttr "minor" e)+  let mino = isJust (pAttr "minor" e)   let usr  = fromMaybe "" $ pAttr "user" e   let anon = isJust (pAttr "anon" e)   let ts   = fromMaybe "" $ pAttr "timestamp" e@@ -52,7 +51,7 @@   let con  = case strContent e of { "" -> Nothing ; xs -> Just xs}   return (emptyRevision pg)              { revRevId = rid-	     , revIsMinor = min+	     , revIsMinor = mino 	     , revUser = usr 	     , revIsAnon = anon 	     , revTimestamp = ts
MediaWiki/API/Query/Search/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.Search  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/Templates/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.Templates  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe
MediaWiki/API/Query/Users/Import.hs view
@@ -1,6 +1,5 @@ module MediaWiki.API.Query.Users.Import where -import MediaWiki.API.Types import MediaWiki.API.Utils import MediaWiki.API.Query.Users @@ -43,5 +42,5 @@    xmlG p = do      guard (elName p == nsName "g")      return (strContent p)-	    + 
MediaWiki/API/Query/WatchList/Import.hs view
@@ -5,7 +5,6 @@ import MediaWiki.API.Query.WatchList  import Text.XML.Light.Types-import Text.XML.Light.Proc   ( strContent )  import Control.Monad import Data.Maybe@@ -53,4 +52,4 @@     , wlOldLength = leno     , wlComment = co     }-   +
MediaWiki/API/Types.hs view
@@ -1,241 +1,241 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Types
--- Description : Basic MediaWiki API types
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- Basic MediaWiki API types
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Types where
-
--- base types
-type UserName = String
-type NamespaceID = String
-type TimeString = String
-data Direction = Up | Down deriving ( Eq )
-type RevID = String
-type PageName = String
-type UserID = String
-data TimeArrow = Earlier | Later deriving ( Eq )
-type Timestamp = String
-type Redirect = String
-type SortKind = String
-type CatName = String
-type GroupName = String
-type FilterLang = String
-type WithRedirects = String
-type URLString = String
-type Token = String
-type LangName = String
-
-nullRevId :: RevID
-nullRevId = "0"
-
-nullTimestamp :: Timestamp
-nullTimestamp = ""
-
-nullUser :: UserName
-nullUser = ""
-
-data PageTitle 
- = PageTitle { pgNS    :: NamespaceID
-             , pgTitle :: Title 
-	     , pgMbId  :: Maybe PageID
-	     , pgMissing :: Bool
-	     }
-
-emptyPageTitle :: PageTitle
-emptyPageTitle
- = PageTitle { pgNS    = mainNamespace
-             , pgTitle = ""
-	     , pgMbId  = Nothing
-	     , pgMissing = False
-	     }
-
-mainNamespace :: NamespaceID
-mainNamespace  = "0"
-
-ns_MAIN :: NamespaceID
-ns_MAIN = mainNamespace
-
-ns_IMAGE :: NamespaceID
-ns_IMAGE = "6"
-
-data Format
- = Format 
-     { formatKind      :: FormatKind
-     , formatFormatted :: Bool
-     }
-
-emptyFormat :: Format
-emptyFormat = Format{formatKind=FormatXML, formatFormatted=True}
-
-xmlFormat :: Format
-xmlFormat = emptyFormat{formatKind=FormatXML, formatFormatted=False}
-
-data FormatKind
- = FormatJSON
- | FormatPHP 
- | FormatWDDX
- | FormatXML
- | FormatYAML
- | FormatTxt
- | FormatDbg
-
-type User     = String
-type Password = String
-type LoginToken = String
-type SessionID = String
-type SessionToken = String
-type ValueName = (String,String)
-
-data UserInfo
- = UserInfo
-    { uiName      :: UserName
-    , uiId        :: UserID
-    , uiIsAnon    :: Bool
-    , uiHasMessage :: Bool
-    , uiBlocked   :: Maybe (UserName,String)
-    , uiGroups    :: [String]
-    , uiRights    :: [String]
-    , uiOptions   :: [(String,String)]
-    , uiRateLimits :: [RateLimit]
-    , uiEditCount  :: Maybe Int
-    }
-
-emptyUserInfo :: UserInfo
-emptyUserInfo = UserInfo
-    { uiName      = nullUser
-    , uiId        = "0"
-    , uiIsAnon    = True
-    , uiHasMessage = False
-    , uiBlocked   = Nothing
-    , uiGroups    = []
-    , uiRights    = []
-    , uiOptions   = []
-    , uiRateLimits = []
-    , uiEditCount  = Nothing
-    }
-
-data RateLimit
- = RateLimit
-    { rlName    :: String
-    , rlHits    :: Int
-    , rlSeconds :: Int
-    }
-
-
-data NamespaceInfo
- = NamespaceInfo
-      { nsId       :: String
-      , nsTitle    :: String
-      , nsSubpages :: Bool
-      }
-
-data InterwikiEntry
- = InterwikiEntry
-      { iwPrefix        :: String
-      , iwLocal         :: Bool
-      , iwTranscludable :: Maybe Bool
-      , iwUrl           :: String
-      , iwLanguage      :: Maybe String
-      }
-
-data UserSession
- = UserSession
-    { sessUserId    :: UserID
-    , sessUserName  :: UserName
-    , sessPassword  :: Maybe Password  -- not sure; could leave out.
-    , sessCookiePrefix :: Maybe String
-    , sessSessionId :: Maybe SessionID
-    , sessToken     :: LoginToken
-    }
-
-data HelpRequest
- = HelpRequest
-    { helpVersion :: Maybe Bool
-    }
-
-type Title  = String   -- Q: what kind of encoding/escaping can be assumed here?
-type PageID = String   -- numeric ID, so arguably wrong Haskell type.
-type RevisionID = String -- ditto.
-
-newtype PropKind 
- = PropKind { prKind :: String }
-    {- Not deemed worthy to try to enumerate them all.
-    -- Three major reasons: 
-    --    - supportd properties are likely to evolve with MW API.
-    --    - fields support subsets of the type, so using a union type
-    --      for these is imprecise.
-    --    - development of queries are driven by reading the API documentation
-    --      from the MW API help page, so transliterations ought to be
-    --      accommodated.
-    --    - being too lazy to write them out is not a reason; did
-    --      have such an enum type defined at one point :-)
-    -}
-
-newtype MetaKind
- = MetaKind { meKind :: String } -- likely values: siteinfo, userinfo, allmessages
-
-newtype ListKind
- = ListKind { liKind :: String }
-
-newtype GeneratorKind
- = GeneratorKind { genKind :: String }
-
-class APIRequest a where
-  showReq    :: a -> [Maybe (String,String)]
-  isPostable :: a -> Bool
-  isPostable _ = False
-  
-  queryKind :: a -> QueryKind
-  queryKind _ = QProp ""
-
-
-data QueryKind 
- = QProp String | QMeta String | QList String | QGen String
-   deriving ( Eq )
-
-data QueryRequest
- = QueryRequest
-     { quTitles          :: [Title]
-     , quPageIds         :: [PageID]
-     , quRevIds          :: [RevisionID]
-     , quProps           :: [PropKind]
-     , quLists           :: [ListKind]
-     , quMetas           :: [MetaKind]
-     , quGenerator       :: Maybe GeneratorKind
-     , quFollowRedirects :: Maybe Bool
-     , quIndexPageIds    :: Maybe Bool
-     }
-
-emptyQuery :: QueryRequest
-emptyQuery = QueryRequest
-     { quTitles          = []
-     , quPageIds         = []
-     , quRevIds          = []
-     , quProps           = []
-     , quLists           = []
-     , quMetas           = []
-     , quGenerator       = Nothing
-     , quFollowRedirects = Nothing
-     , quIndexPageIds    = Nothing
-     }
-{-
-data MetaKindProp
- = SiteInfoProp
- | UserInfoProp
- | AllMessagesProp
- | ExpandTemplatesProp
- | ParseProp
- | OpenSearchProp
- | FeedWatchlistProp
- | HelpProp
- | ParamInfoProp
- -}
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Types+-- Description : Basic MediaWiki API types+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- Basic MediaWiki API types+-- +--------------------------------------------------------------------+module MediaWiki.API.Types where++-- base types+type UserName = String+type NamespaceID = String+type TimeString = String+data Direction = Up | Down deriving ( Eq )+type RevID = String+type PageName = String+type UserID = String+data TimeArrow = Earlier | Later deriving ( Eq )+type Timestamp = String+type Redirect = String+type SortKind = String+type CatName = String+type GroupName = String+type FilterLang = String+type WithRedirects = String+type URLString = String+type Token = String+type LangName = String++nullRevId :: RevID+nullRevId = "0"++nullTimestamp :: Timestamp+nullTimestamp = ""++nullUser :: UserName+nullUser = ""++data PageTitle + = PageTitle { pgNS    :: NamespaceID+             , pgTitle :: Title +	     , pgMbId  :: Maybe PageID+	     , pgMissing :: Bool+	     }++emptyPageTitle :: PageTitle+emptyPageTitle+ = PageTitle { pgNS    = mainNamespace+             , pgTitle = ""+	     , pgMbId  = Nothing+	     , pgMissing = False+	     }++mainNamespace :: NamespaceID+mainNamespace  = "0"++ns_MAIN :: NamespaceID+ns_MAIN = mainNamespace++ns_IMAGE :: NamespaceID+ns_IMAGE = "6"++data Format+ = Format +     { formatKind      :: FormatKind+     , formatFormatted :: Bool+     }++emptyFormat :: Format+emptyFormat = Format{formatKind=FormatXML, formatFormatted=True}++xmlFormat :: Format+xmlFormat = emptyFormat{formatKind=FormatXML, formatFormatted=False}++data FormatKind+ = FormatJSON+ | FormatPHP + | FormatWDDX+ | FormatXML+ | FormatYAML+ | FormatTxt+ | FormatDbg++type User     = String+type Password = String+type LoginToken = String+type SessionID = String+type SessionToken = String+type ValueName = (String,String)++data UserInfo+ = UserInfo+    { uiName      :: UserName+    , uiId        :: UserID+    , uiIsAnon    :: Bool+    , uiHasMessage :: Bool+    , uiBlocked   :: Maybe (UserName,String)+    , uiGroups    :: [String]+    , uiRights    :: [String]+    , uiOptions   :: [(String,String)]+    , uiRateLimits :: [RateLimit]+    , uiEditCount  :: Maybe Int+    }++emptyUserInfo :: UserInfo+emptyUserInfo = UserInfo+    { uiName      = nullUser+    , uiId        = "0"+    , uiIsAnon    = True+    , uiHasMessage = False+    , uiBlocked   = Nothing+    , uiGroups    = []+    , uiRights    = []+    , uiOptions   = []+    , uiRateLimits = []+    , uiEditCount  = Nothing+    }++data RateLimit+ = RateLimit+    { rlName    :: String+    , rlHits    :: Int+    , rlSeconds :: Int+    }+++data NamespaceInfo+ = NamespaceInfo+      { nsId       :: String+      , nsTitle    :: String+      , nsSubpages :: Bool+      }++data InterwikiEntry+ = InterwikiEntry+      { iwPrefix        :: String+      , iwLocal         :: Bool+      , iwTranscludable :: Maybe Bool+      , iwUrl           :: String+      , iwLanguage      :: Maybe String+      }++data UserSession+ = UserSession+    { sessUserId    :: UserID+    , sessUserName  :: UserName+    , sessPassword  :: Maybe Password  -- not sure; could leave out.+    , sessCookiePrefix :: Maybe String+    , sessSessionId :: Maybe SessionID+    , sessToken     :: LoginToken+    }++data HelpRequest+ = HelpRequest+    { helpVersion :: Maybe Bool+    }++type Title  = String   -- Q: what kind of encoding/escaping can be assumed here?+type PageID = String   -- numeric ID, so arguably wrong Haskell type.+type RevisionID = String -- ditto.++newtype PropKind + = PropKind { prKind :: String }+    {- Not deemed worthy to try to enumerate them all.+    -- Three major reasons: +    --    - supportd properties are likely to evolve with MW API.+    --    - fields support subsets of the type, so using a union type+    --      for these is imprecise.+    --    - development of queries are driven by reading the API documentation+    --      from the MW API help page, so transliterations ought to be+    --      accommodated.+    --    - being too lazy to write them out is not a reason; did+    --      have such an enum type defined at one point :-)+    -}++newtype MetaKind+ = MetaKind { meKind :: String } -- likely values: siteinfo, userinfo, allmessages++newtype ListKind+ = ListKind { liKind :: String }++newtype GeneratorKind+ = GeneratorKind { genKind :: String }++class APIRequest a where+  showReq    :: a -> [Maybe (String,String)]+  isPostable :: a -> Bool+  isPostable _ = False+  +  queryKind :: a -> QueryKind+  queryKind _ = QProp ""+++data QueryKind + = QProp String | QMeta String | QList String | QGen String+   deriving ( Eq )++data QueryRequest+ = QueryRequest+     { quTitles          :: [Title]+     , quPageIds         :: [PageID]+     , quRevIds          :: [RevisionID]+     , quProps           :: [PropKind]+     , quLists           :: [ListKind]+     , quMetas           :: [MetaKind]+     , quGenerator       :: Maybe GeneratorKind+     , quFollowRedirects :: Maybe Bool+     , quIndexPageIds    :: Maybe Bool+     }++emptyQuery :: QueryRequest+emptyQuery = QueryRequest+     { quTitles          = []+     , quPageIds         = []+     , quRevIds          = []+     , quProps           = []+     , quLists           = []+     , quMetas           = []+     , quGenerator       = Nothing+     , quFollowRedirects = Nothing+     , quIndexPageIds    = Nothing+     }+{-+data MetaKindProp+ = SiteInfoProp+ | UserInfoProp+ | AllMessagesProp+ | ExpandTemplatesProp+ | ParseProp+ | OpenSearchProp+ | FeedWatchlistProp+ | HelpProp+ | ParamInfoProp+ -}
MediaWiki/API/Utils.hs view
@@ -1,94 +1,94 @@---------------------------------------------------------------------
--- |
--- Module      : MediaWiki.API.Utils
--- Description : MediaWiki API internal utility functions.
--- Copyright   : (c) Sigbjorn Finne, 2008
--- License     : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: portable
---
--- MediaWiki API internal utility functions.
--- 
---------------------------------------------------------------------
-module MediaWiki.API.Utils 
-       ( module MediaWiki.API.Utils
-       , fromMaybe
-       ) where
-
-import Text.XML.Light as XML
-import Data.Maybe
-import Data.List
-import Control.Monad
-
-import MediaWiki.Util.Codec.URLEncoder ( encodeString )
-
-pNodes       :: String -> [XML.Element] -> [XML.Element]
-pNodes x es   = filter ((nsName x ==) . elName) es
-
-pNode        :: String -> [XML.Element] -> Maybe XML.Element
-pNode x es    = listToMaybe (pNodes x es)
-
-pLeaf        :: String -> [XML.Element] -> Maybe String
-pLeaf x es    = strContent `fmap` pNode x es
-
-pAttr        :: String -> XML.Element -> Maybe String
-pAttr x e     = lookup (nsName x) [ (k,v) | Attr k v <- elAttribs e ]
-
-pMany        :: String -> (XML.Element -> Maybe a) -> [XML.Element] -> [a]
-pMany p f es  = mapMaybe f (pNodes p es)
-
-children     :: XML.Element -> [XML.Element]
-children e    = onlyElems (elContent e)
-
-nsName :: String -> QName
-nsName x = QName{qName=x,qURI=Nothing,qPrefix=Nothing}
-
-without :: [String] -> [XML.Attr] -> [XML.Attr]
-without xs as = filter (\ a -> not (attrKey a `elem` qxs)) as
- where
-  qxs = map nsName xs
-
-parseDoc :: (Element -> Maybe a) -> String -> Either (String,[{-error msg-}String]) a
-parseDoc f s = 
-  case parseXMLDoc s of
-    Nothing -> Left (s, ["not valid XML content"])
-    Just d  ->
-      case f d of
-        Nothing -> Left (s,["unexpected XML response"])
-	Just x  -> Right x
-
-xmlContinue :: String -> String -> Element -> Maybe String
-xmlContinue tgName atName e = do
-  guard (elName e == nsName "query-continue")
-  let es1 = children e
-  p  <- pNode tgName es1
-  pAttr atName p
-
-mbDef :: a -> Maybe a -> Maybe a
-mbDef x Nothing = Just x
-mbDef _ v = v
-
-readMb :: Read a => String -> Maybe a
-readMb x = case reads x of
-             ((v,_):_) -> Just v
-	     _ -> Nothing
-
-piped :: [String] -> String
-piped xs = intercalate "|" xs
-
-opt :: String -> String -> Maybe (String,String)
-opt a b = Just (a, encodeString b)
-
-optB :: String -> Bool -> Maybe (String,String)
-optB _ False = Nothing
-optB a _ = Just (a,"")
-
-opt1 :: String -> [String] -> Maybe (String,String)
-opt1 _ [] = Nothing
-opt1 a b = Just (a,encodeString $ piped b)
-
-mbOpt :: String -> (a -> String) -> Maybe a -> Maybe (String,String)
-mbOpt  _ _ Nothing = Nothing
-mbOpt tg f (Just x) = Just (tg,encodeString $ f x)
+--------------------------------------------------------------------+-- |+-- Module      : MediaWiki.API.Utils+-- Description : MediaWiki API internal utility functions.+-- Copyright   : (c) Sigbjorn Finne, 2008+-- License     : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: portable+--+-- MediaWiki API internal utility functions.+-- +--------------------------------------------------------------------+module MediaWiki.API.Utils +       ( module MediaWiki.API.Utils+       , fromMaybe+       ) where++import Text.XML.Light as XML+import Data.Maybe+import Data.List+import Control.Monad++import MediaWiki.Util.Codec.URLEncoder ( encodeString )++pNodes       :: String -> [XML.Element] -> [XML.Element]+pNodes x es   = filter ((nsName x ==) . elName) es++pNode        :: String -> [XML.Element] -> Maybe XML.Element+pNode x es    = listToMaybe (pNodes x es)++pLeaf        :: String -> [XML.Element] -> Maybe String+pLeaf x es    = strContent `fmap` pNode x es++pAttr        :: String -> XML.Element -> Maybe String+pAttr x e     = lookup (nsName x) [ (k,v) | Attr k v <- elAttribs e ]++pMany        :: String -> (XML.Element -> Maybe a) -> [XML.Element] -> [a]+pMany p f es  = mapMaybe f (pNodes p es)++children     :: XML.Element -> [XML.Element]+children e    = onlyElems (elContent e)++nsName :: String -> QName+nsName x = QName{qName=x,qURI=Nothing,qPrefix=Nothing}++without :: [String] -> [XML.Attr] -> [XML.Attr]+without xs as = filter (\ a -> not (attrKey a `elem` qxs)) as+ where+  qxs = map nsName xs++parseDoc :: (Element -> Maybe a) -> String -> Either (String,[{-error msg-}String]) a+parseDoc f s = +  case parseXMLDoc s of+    Nothing -> Left (s, ["not valid XML content"])+    Just d  ->+      case f d of+        Nothing -> Left (s,["unexpected XML response"])+	Just x  -> Right x++xmlContinue :: String -> String -> Element -> Maybe String+xmlContinue tgName atName e = do+  guard (elName e == nsName "query-continue")+  let es1 = children e+  p  <- pNode tgName es1+  pAttr atName p++mbDef :: a -> Maybe a -> Maybe a+mbDef x Nothing = Just x+mbDef _ v = v++readMb :: Read a => String -> Maybe a+readMb x = case reads x of+             ((v,_):_) -> Just v+	     _ -> Nothing++piped :: [String] -> String+piped xs = intercalate "|" xs++opt :: String -> String -> Maybe (String,String)+opt a b = Just (a, encodeString b)++optB :: String -> Bool -> Maybe (String,String)+optB _ False = Nothing+optB a _ = Just (a,"")++opt1 :: String -> [String] -> Maybe (String,String)+opt1 _ [] = Nothing+opt1 a b = Just (a,encodeString $ piped b)++mbOpt :: String -> (a -> String) -> Maybe a -> Maybe (String,String)+mbOpt  _ _ Nothing = Nothing+mbOpt tg f (Just x) = Just (tg,encodeString $ f x)
MediaWiki/Util/Codec/Percent.hs view
@@ -16,7 +16,7 @@ -} module MediaWiki.Util.Codec.Percent where -import Data.Char ( chr, isAlphaNum )+import Data.Char ( chr, isAlphaNum, isAscii ) import Numeric   ( readHex, showHex )  getEncodedString :: String -> String@@ -35,7 +35,7 @@  getEncodedChar :: Char -> Maybe String getEncodedChar x- | isAlphaNum x || + | (isAlphaNum x && isAscii x) ||     x `elem` "-_.~" = Nothing  | xi < 0xff       = Just ('%':showHex (xi `div` 16) (showHex (xi `mod` 16) ""))  | otherwise       = -- ToDo: import utf8 lib
MediaWiki/Util/Fetch.hs view
@@ -1,182 +1,182 @@---------------------------------------------------------------------
--- |
--- Module    : MediaWiki.Util.Fetch
--- Copyright : (c) Sigbjorn Finne, 2008
--- License   : BSD3
---
--- Maintainer: Sigbjorn Finne <sof@forkIO.com>
--- Stability : provisional
--- Portability: so-so
--- 
--- Simple GET\/de-ref of URLs; abstracting out networking backend\/package.
---
-module MediaWiki.Util.Fetch 
-       ( readContentsURL
-       , readUserContentsURL
-       
-       , postContentsURL
-
---       , URLString
-       , AuthUser(..)
-       , nullAuthUser
-       , Cookie
-       ) where
-       
---import Network.Curl
-import Network.Browser
-import Network.HTTP
-import Network.URI
-
-type URLString = String
-
-data AuthUser
- = AuthUser 
-     { authUserName :: String
-     , authUserPass :: String
-     }
-
-nullAuthUser :: AuthUser
-nullAuthUser = AuthUser
-            { authUserName = ""
-	    , authUserPass = ""
-	    }
-
-readContentsURL :: URLString -> IO String
-readContentsURL u = do
-  req <- 
-    case parseURI u of
-      Nothing -> fail ("ill-formed URL: " ++ u)
-      Just ur -> return (defaultGETRequest ur)
-    -- don't like doing this, but HTTP is awfully chatty re: cookie handling..
-  let nullHandler _ = return ()
-  (_u, resp) <- browse $ setOutHandler nullHandler >> request req
-  case rspCode resp of
-    (2,_,_) -> return (rspBody resp)
-    _ -> fail ("Failed reading URL " ++ show u ++ " code: " ++ show (rspCode resp))
-
-{- Curl version:
-readContentsURL :: URLString -> IO String
-readContentsURL u = do
-  let opts = [ CurlFollowLocation True
-	     ]
-  (_,xs) <- curlGetString u opts
-  return xs
--}
-
-readUserContentsURL :: Maybe AuthUser -> Bool -> Bool -> URLString -> [(String,String)] -> IO ([(String,String)], String)
-readUserContentsURL mbU doRedir isHead us hdrs = do -- readContentsURL u
-  let hs = 
-       case parseHeaders $ map (\ (x,y) -> x++": " ++ y) (addDefaultHeaders 0 hdrs) of
-         Left{} -> []
-	 Right xs -> xs
-  req0 <- 
-    case parseURI us of
-      Nothing -> fail ("ill-formed URL: " ++ us)
-      Just ur -> return (defaultGETRequest ur)
-    -- don't like doing this, but HTTP is awfully chatty re: cookie handling..
-  let req = insertHeaderIfMissing HdrHost (authority (rqURI req0)) $
-              req0{ rqMethod=if isHead then HEAD else GET
-	          , rqHeaders= hs
-		  , rqURI = (rqURI req0){uriScheme="",uriAuthority=Nothing}
-	          }
-  let nullHandler _ = return ()
-  (u, resp) <- browse $ do 
-     setOutHandler nullHandler
-     case mbU of
-       Nothing -> return ()
-       Just usr -> do
-         setAllowRedirects doRedir
-         setAllowBasicAuth True
-         setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))
-
---                  setAllowBasicAuth True
---		  setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))
-{-
-                  addAuthority AuthBasic{ auUsername = userName usr
-                                        , auPassword = userPass usr
-                                        , auRealm    = ""
-                                        , auSite     = nullURI{uriPath="/"}
-                                        }
--}
-     request req
-  case rspCode resp of
-    (2,_,_) -> return (map toP (rspHeaders resp), rspBody resp)
-    (3,_,_) | not doRedir -> return (map toP (rspHeaders resp), rspBody resp)
-    _ -> fail ("Failed reading URL " ++ show u ++ " code: " ++ show (rspCode resp))
-
-
-postContentsURL :: Maybe AuthUser
-                -> URLString
-		-> [(String,String)]
-		-> [Cookie]
-		-> String
-		-> IO ([Cookie],[(String,String)], String)
-postContentsURL mbU u hdrs csIn body = do
-  let hs = 
-       case parseHeaders $ map (\ (x,y) -> x++": " ++ y) (addDefaultHeaders  (length body) hdrs) of
-         Left{} -> []
-	 Right xs -> xs
-  req0 <- 
-    case parseURI u of
-      Nothing -> fail ("ill-formed URL: " ++ u)
-      Just ur -> return (defaultGETRequest ur)
-  let req = insertHeaderIfMissing HdrHost (authority (rqURI req0)) $
-              req0{ rqMethod=POST
-                  , rqBody=body
-		  , rqHeaders= hs
-		  , rqURI = (rqURI req0){uriScheme="",uriAuthority=Nothing}
-	          }
---  print req -- ,body)
-  let nullHandler _ = return ()
-  ((_,rsp),cs) <- browse $ do
-     setOutHandler nullHandler
-     setAllowRedirects True
-     setCookies csIn
-     case mbU of
-       Nothing -> return ()
-       Just usr -> do
-         setAllowBasicAuth True
-         setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))
-		   
-     v <- request req
-     ls <- getCookies
-     return (v,ls)
-  case rspCode rsp of
-    (2,_,_) -> return (cs,map toP (rspHeaders rsp), rspBody rsp)
-    x -> fail ("POST failed - code: " ++ show x ++ ", URL: " ++ u ++ show (rspBody rsp))
-
-toP :: Header -> (String, String)
-toP (Header k v) = (show k, v)
-
-addDefaultHeaders :: Int -> [(String,String)] -> [(String,String)]
-addDefaultHeaders clen hs = 
-  addIfMiss "User-Agent" "hs-twitter" $
-  addIfMiss "Content-Length"  (show clen) hs
- where
-  addIfMiss f v xs = maybe ((f,v):xs) (const xs) (lookup f xs)
-
-{- Curl versions:
-readUserContentsURL :: User -> URLString -> IO String
-readUserContentsURL u url = do
-  let opts = [ CurlHttpAuth [HttpAuthAny]
-             , CurlUserPwd (authUserName u ++ 
-	                    case authUserPass u of {"" -> ""; p -> ':':p })
-             , CurlFollowLocation True
-	     ] 
-  (_,xs) <- curlGetString url opts
-  return xs
-     
-postContentsURL :: URLString -> [(String,String)] -> String -> IO String
-postContentsURL u hdrs body = do
-  let opts = [ CurlCustomRequest "POST"
-             , CurlFollowLocation True
-	     , CurlPost True
-	     , CurlPostFields [body]
-	     , CurlHttpTransferDecoding False
-	     ] ++ [CurlHttpHeaders (map ( \ (x,y) -> (x ++ ':':y)) hdrs)]
-  rsp <- curlGetResponse u opts
-  case respStatus rsp `div` 100 of
-    2 -> return (respBody rsp)
-    x -> fail ("POST failed - code: " ++ show x ++ ", URL: " ++ u)
-
--}
+--------------------------------------------------------------------+-- |+-- Module    : MediaWiki.Util.Fetch+-- Copyright : (c) Sigbjorn Finne, 2008+-- License   : BSD3+--+-- Maintainer: Sigbjorn Finne <sof@forkIO.com>+-- Stability : provisional+-- Portability: so-so+-- +-- Simple GET\/de-ref of URLs; abstracting out networking backend\/package.+--+module MediaWiki.Util.Fetch +       ( readContentsURL+       , readUserContentsURL+       +       , postContentsURL++--       , URLString+       , AuthUser(..)+       , nullAuthUser+       , Cookie+       ) where+       +--import Network.Curl+import Network.Browser+import Network.HTTP+import Network.URI++type URLString = String++data AuthUser+ = AuthUser +     { authUserName :: String+     , authUserPass :: String+     }++nullAuthUser :: AuthUser+nullAuthUser = AuthUser+            { authUserName = ""+	    , authUserPass = ""+	    }++readContentsURL :: URLString -> IO String+readContentsURL u = do+  req <- +    case parseURI u of+      Nothing -> fail ("ill-formed URL: " ++ u)+      Just ur -> return (defaultGETRequest ur)+    -- don't like doing this, but HTTP is awfully chatty re: cookie handling..+  let nullHandler _ = return ()+  (_u, resp) <- browse $ setOutHandler nullHandler >> request req+  case rspCode resp of+    (2,_,_) -> return (rspBody resp)+    _ -> fail ("Failed reading URL " ++ show u ++ " code: " ++ show (rspCode resp))++{- Curl version:+readContentsURL :: URLString -> IO String+readContentsURL u = do+  let opts = [ CurlFollowLocation True+	     ]+  (_,xs) <- curlGetString u opts+  return xs+-}++readUserContentsURL :: Maybe AuthUser -> Bool -> Bool -> URLString -> [(String,String)] -> IO ([(String,String)], String)+readUserContentsURL mbU doRedir isHead us hdrs = do -- readContentsURL u+  let hs = +       case parseHeaders $ map (\ (x,y) -> x++": " ++ y) (addDefaultHeaders 0 hdrs) of+         Left{} -> []+	 Right xs -> xs+  req0 <- +    case parseURI us of+      Nothing -> fail ("ill-formed URL: " ++ us)+      Just ur -> return (defaultGETRequest ur)+    -- don't like doing this, but HTTP is awfully chatty re: cookie handling..+  let req = insertHeaderIfMissing HdrHost (authority (rqURI req0)) $+              req0{ rqMethod=if isHead then HEAD else GET+	          , rqHeaders= hs+		  , rqURI = (rqURI req0){uriScheme="",uriAuthority=Nothing}+	          }+  let nullHandler _ = return ()+  (u, resp) <- browse $ do +     setOutHandler nullHandler+     case mbU of+       Nothing -> return ()+       Just usr -> do+         setAllowRedirects doRedir+         setAllowBasicAuth True+         setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))++--                  setAllowBasicAuth True+--		  setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))+{-+                  addAuthority AuthBasic{ auUsername = userName usr+                                        , auPassword = userPass usr+                                        , auRealm    = ""+                                        , auSite     = nullURI{uriPath="/"}+                                        }+-}+     request req+  case rspCode resp of+    (2,_,_) -> return (map toP (rspHeaders resp), rspBody resp)+    (3,_,_) | not doRedir -> return (map toP (rspHeaders resp), rspBody resp)+    _ -> fail ("Failed reading URL " ++ show u ++ " code: " ++ show (rspCode resp))+++postContentsURL :: Maybe AuthUser+                -> URLString+		-> [(String,String)]+		-> [Cookie]+		-> String+		-> IO ([Cookie],[(String,String)], String)+postContentsURL mbU u hdrs csIn body = do+  let hs = +       case parseHeaders $ map (\ (x,y) -> x++": " ++ y) (addDefaultHeaders  (length body) hdrs) of+         Left{} -> []+	 Right xs -> xs+  req0 <- +    case parseURI u of+      Nothing -> fail ("ill-formed URL: " ++ u)+      Just ur -> return (defaultGETRequest ur)+  let req = insertHeaderIfMissing HdrHost (authority (rqURI req0)) $+              req0{ rqMethod=POST+                  , rqBody=body+		  , rqHeaders= hs+		  , rqURI = (rqURI req0){uriScheme="",uriAuthority=Nothing}+	          }+--  print req -- ,body)+  let nullHandler _ = return ()+  ((_,rsp),cs) <- browse $ do+     setOutHandler nullHandler+     setAllowRedirects True+     setCookies csIn+     case mbU of+       Nothing -> return ()+       Just usr -> do+         setAllowBasicAuth True+         setAuthorityGen (\ _ _ -> return (Just (authUserName usr,authUserPass usr)))+		   +     v <- request req+     ls <- getCookies+     return (v,ls)+  case rspCode rsp of+    (2,_,_) -> return (cs,map toP (rspHeaders rsp), rspBody rsp)+    x -> fail ("POST failed - code: " ++ show x ++ ", URL: " ++ u ++ show (rspBody rsp))++toP :: Header -> (String, String)+toP (Header k v) = (show k, v)++addDefaultHeaders :: Int -> [(String,String)] -> [(String,String)]+addDefaultHeaders clen hs = +  addIfMiss "User-Agent" "hs-twitter" $+  addIfMiss "Content-Length"  (show clen) hs+ where+  addIfMiss f v xs = maybe ((f,v):xs) (const xs) (lookup f xs)++{- Curl versions:+readUserContentsURL :: User -> URLString -> IO String+readUserContentsURL u url = do+  let opts = [ CurlHttpAuth [HttpAuthAny]+             , CurlUserPwd (authUserName u ++ +	                    case authUserPass u of {"" -> ""; p -> ':':p })+             , CurlFollowLocation True+	     ] +  (_,xs) <- curlGetString url opts+  return xs+     +postContentsURL :: URLString -> [(String,String)] -> String -> IO String+postContentsURL u hdrs body = do+  let opts = [ CurlCustomRequest "POST"+             , CurlFollowLocation True+	     , CurlPost True+	     , CurlPostFields [body]+	     , CurlHttpTransferDecoding False+	     ] ++ [CurlHttpHeaders (map ( \ (x,y) -> (x ++ ':':y)) hdrs)]+  rsp <- curlGetResponse u opts+  case respStatus rsp `div` 100 of+    2 -> return (respBody rsp)+    x -> fail ("POST failed - code: " ++ show x ++ ", URL: " ++ u)++-}
Setup.hs view
@@ -1,7 +1,7 @@-module Main where
-
-import Distribution.Simple
-
-
-main :: IO ()
-main = defaultMain
+module Main where++import Distribution.Simple+++main :: IO ()+main = defaultMain
+ examples/LinksTo.hs view
@@ -0,0 +1,85 @@+{-+  Querying for back/in links to a given page.++  foo$ path/to/linksTo "Haskell"+  ...+  foo$+-}+module Main(main) where++import MediaWiki.API.Base+import MediaWiki.API.Types ( PageTitle(..) )+import MediaWiki.API++import MediaWiki.API.Query.BackLinks.Import as Back++import Util.GetOpts++-- begin option handling+data Options+ = Options+    { optWiki :: String+    , optUser :: Maybe String+    , optPass :: Maybe String+    , optPage :: Maybe String+    }++nullOptions :: Options+nullOptions = Options+    { optWiki  = "http://en.wikipedia.org/w/"+    , optUser  = Nothing+    , optPass  = Nothing+    , optPage  = Nothing+    }++option_descr :: [OptDescr (Options -> Options)]+option_descr =+  [ Option ['u'] ["user"]+           (ReqArg (\ x o -> o{optUser=Just x}) "USER")+	   "Wiki user name to login as"+  , Option ['p'] ["pass"]+           (ReqArg (\ x o -> o{optPass=Just x}) "PASSWORD")+	   "user's password credentials to supply if logging in"+  , Option ['w'] ["wiki"]+           (ReqArg (\ x o -> o{optWiki=x}) "WIKI")+	   "the Wiki to access"+  , Option ['P'] ["page"]+           (ReqArg (\ x o -> o{optPage=Just x}) "PAGE")+	   "the page title to list category pages for"+  ]++-- end option handling++queryPageInLinks :: URLString -> String -> IO [PageTitle]+queryPageInLinks url pgName = queryInLinks emptyBackLinksRequest{blTitle=Just pgName} []+ where+  queryInLinks bReq acc = do+    let req = emptyXmlRequest (mkQueryAction (queryPage pgName) bReq)+    mb <- webGetXml Back.stringXml url req+    case mb of+      Nothing -> fail ("Failed to fetch page" ++ pgName ++ " from " ++ url)+      Just c  -> do+        let acc' = acc ++ blLinks c+        case blContinue c of+          Nothing -> return acc'+	  Just x  -> queryInLinks bReq{blContinueFrom=Just x} acc'++main :: IO ()+main = do+  (opts, fs) <- processOptions option_descr nullOptions+  let url = optWiki opts+  case mbCons (optPage opts) fs of+    [] -> return ()+    xs -> mapM_ (linksToPage url) xs++linksToPage :: URLString -> String -> IO ()+linksToPage url pgName = do+  ps <- queryPageInLinks url pgName+  putStrLn ("Page " ++ show pgName ++ " has the following backlinks: ")+  mapM_ (putStrLn.toTitle) ps+ where+  toTitle pg = ' ':pgTitle pg++mbCons :: Maybe a -> [a] -> [a]+mbCons Nothing xs = xs+mbCons (Just x) xs = x:xs
examples/ListCat.hs view
@@ -1,161 +1,139 @@-{-
-  Example of how to query for category members, demonstrating
-  the modules, types and steps used to interact with the API:
-  
-  foo$ listCat "Functional programming"
-  ...
-  foo$ 
--}
-module Main(main) where
-
-import MediaWiki.API.Base
-import MediaWiki.API.Types ( PageTitle(..) )
-import MediaWiki.API
-import MediaWiki.API.Query.CategoryMembers as CatMem
-import MediaWiki.API.Query.CategoryMembers.Import as CatMem
-
-import MediaWiki.API.Query.Categories as Cats
-import MediaWiki.API.Query.Categories.Import as Cats
-
-import Util.GetOpts
-import System.IO
-import System.Environment
-import System.Exit
-
-import Control.Monad
---import Data.Maybe ( fromMaybe )
-import Data.List
-
--- begin option handling
-data Options
- = Options
-    { optWiki    :: String
-    , optUser    :: Maybe String
-    , optPass    :: Maybe String
-    , optCat     :: Maybe String
-    , optPage    :: Maybe String
-    }
-
-nullOptions :: Options
-nullOptions = Options
-    { optWiki    = "http://en.wikipedia.org/w/"
-    , optUser    = Nothing
-    , optPass    = Nothing
-    , optCat     = Nothing
-    , optPage    = Nothing
-    }
-
-option_descr :: [OptDescr (Options -> Options)]
-option_descr = 
-  [ Option ['u'] ["user"]
-           (ReqArg (\ x o -> o{optUser=Just x}) "USER")
-	   "Wiki user name to login as"
-  , Option ['p'] ["pass"]
-           (ReqArg (\ x o -> o{optPass=Just x}) "PASSWORD")
-	   "user's password credentials to supply if logging in"
-  , Option ['w'] ["wiki"]
-           (ReqArg (\ x o -> o{optWiki=x}) "WIKI")
-	   "the Wiki to access"
-  , Option ['c'] ["cat"]
-           (ReqArg (\ x o -> o{optCat=Just x}) "CAT")
-	   "the Wiki category to query for"
-  , Option ['P'] ["page"]
-           (ReqArg (\ x o -> o{optPage=Just x}) "PAGE")
-	   "the page title to list category pages for"
-  ]
-
-
-parseOptions :: [String] -> (Options, [String], [String])
-parseOptions argv = getOpt2 Permute option_descr argv nullOptions
-
-processOptions :: IO (Options, [String])
-processOptions = do
-  ls <- getArgs
-  let (opts, ws, es) = parseOptions ls
-  when (not $ null es) $ do
-    hPutStrLn stderr (unlines es)
-    hPutStrLn stderr ("(try '--help' for list of options supported.)")
-    exitFailure
-  return (opts, ws)
-
--- end option handling
-
-queryCat :: URLString -> String -> IO [PageTitle]
-queryCat url catName = queryCat' url catName' req []
- where 
-  catName'
-    | "Category:" `isPrefixOf` catName = wikify catName
-    | otherwise = "Category:"++wikify catName
-
-  req = categoryMembersRequest{cmTitle=Just catName'}
-
-  wikify "" = ""
-  wikify (' ':xs) = '_':wikify xs
-  wikify (x:xs) = x : wikify xs
-
-
-queryCat' :: URLString -> String -> CategoryMembersRequest -> [PageTitle] -> IO [PageTitle]
-queryCat' url catName cReq acc = do
-  let req = emptyXmlRequest (mkQueryAction (queryPage catName) cReq)
-  mb <- webGetXml CatMem.stringXml url req
-  case mb of
-    Nothing -> fail ("Failed to fetch pages for category " ++ catName ++ " from " ++ url)
-    Just c  -> do
-      let acc' = (acc ++ cmPages c)
-      case cmContinue c of
-        Nothing -> return acc'
-	Just x  -> queryCat' url catName cReq{cmContinueFrom=Just x} acc'
-
-queryPageCats :: URLString -> String -> IO [PageTitle]
-queryPageCats url pgName = queryPageCats' emptyCategoriesRequest []
- where
-  queryPageCats' cReq acc = do
-    let req = emptyXmlRequest (mkQueryAction (queryPage pgName) cReq)
-    mb <- webGetXml Cats.stringXml url req
-    case mb of
-      Nothing -> fail ("Failed to fetch page" ++ pgName ++ " from " ++ url)
-      Just c  -> do
-        let acc' = (acc ++ clPages c)
-        case clContinue c of
-          Nothing -> return (concatMap snd acc')
-	  Just x  -> queryPageCats' cReq{clContinueFrom=Just x} acc'
-
-main :: IO ()
-main = do
-  (opts, fs) <- processOptions
-  let url = optWiki opts
-    -- not needed here, but left in to show how to login to a Wiki.
-  case (optUser opts, optPass opts) of
-    (Just u, Just p) -> do
-       x <- loginWiki url u p
-       case x of
-         Nothing -> putStrLn ("Unable to login to: " ++ url)
-         Just lg -> print (lgSuccess lg)
-    _ -> return ()
-  case mbCons (optCat opts) fs of
-    [] -> putStrLn "No categories specified."
-    xs -> mapM_ (showCat url) xs
-  case mbCons (optPage opts) fs of
-    [] -> return ()
-    xs -> mapM_ (showPages url) xs
-
-showCat :: URLString -> String -> IO ()
-showCat url cat = do
-  ps <- queryCat url cat
-  putStrLn ("Members of category `" ++ cat ++ "'")
-  mapM_ (putStrLn.toTitle) ps
- where
-  toTitle pg = ' ':pgTitle pg
-
-showPages :: URLString -> String -> IO ()
-showPages url pgName = do
-  ps <- queryPageCats url pgName
-  putStrLn ("Page " ++ show pgName ++ " is a member of the following categories: ")
-  mapM_ (putStrLn.toTitle) ps
- where
-  toTitle pg = ' ':pgTitle pg
-
-mbCons :: Maybe a -> [a] -> [a]
-mbCons Nothing xs = xs
-mbCons (Just x) xs = x:xs
-
+{-+  Example of how to query for category members, demonstrating+  the modules, types and steps used to interact with the API:++  foo$ listCat "Functional programming"+  ...+  foo$+-}+module Main(main) where++import MediaWiki.API.Base+import MediaWiki.API.Types ( PageTitle(..) )+import MediaWiki.API+import MediaWiki.API.Query.CategoryMembers.Import as CatMem++import MediaWiki.API.Query.Categories.Import as Cats++import Util.GetOpts+import Data.List++-- begin option handling+data Options+ = Options+    { optWiki    :: String+    , optUser    :: Maybe String+    , optPass    :: Maybe String+    , optCat     :: Maybe String+    , optPage    :: Maybe String+    }++nullOptions :: Options+nullOptions = Options+    { optWiki    = "http://en.wikipedia.org/w/"+    , optUser    = Nothing+    , optPass    = Nothing+    , optCat     = Nothing+    , optPage    = Nothing+    }++option_descr :: [OptDescr (Options -> Options)]+option_descr =+  [ Option ['u'] ["user"]+           (ReqArg (\ x o -> o{optUser=Just x}) "USER")+	   "Wiki user name to login as"+  , Option ['p'] ["pass"]+           (ReqArg (\ x o -> o{optPass=Just x}) "PASSWORD")+	   "user's password credentials to supply if logging in"+  , Option ['w'] ["wiki"]+           (ReqArg (\ x o -> o{optWiki=x}) "WIKI")+	   "the Wiki to access"+  , Option ['c'] ["cat"]+           (ReqArg (\ x o -> o{optCat=Just x}) "CAT")+	   "the Wiki category to query for"+  , Option ['P'] ["page"]+           (ReqArg (\ x o -> o{optPage=Just x}) "PAGE")+	   "the page title to list category pages for"+  ]++-- end option handling++queryCat :: URLString -> String -> IO [PageTitle]+queryCat url catName = queryCat' url catName' req []+ where+  catName'+    | "Category:" `isPrefixOf` catName = wikify catName+    | otherwise = "Category:"++wikify catName++  req = categoryMembersRequest{cmTitle=Just catName'}++  wikify "" = ""+  wikify (' ':xs) = '_':wikify xs+  wikify (x:xs) = x : wikify xs+++queryCat' :: URLString -> String -> CategoryMembersRequest -> [PageTitle] -> IO [PageTitle]+queryCat' url catName cReq acc = do+  let req = emptyXmlRequest (mkQueryAction (queryPage catName) cReq)+  mb <- webGetXml CatMem.stringXml url req+  case mb of+    Nothing -> fail ("Failed to fetch pages for category " ++ catName ++ " from " ++ url)+    Just c  -> do+      let acc' = (acc ++ cmPages c)+      case cmContinue c of+        Nothing -> return acc'+	Just x  -> queryCat' url catName cReq{cmContinueFrom=Just x} acc'++queryPageCats :: URLString -> String -> IO [PageTitle]+queryPageCats url pgName = queryPageCats' emptyCategoriesRequest []+ where+  queryPageCats' cReq acc = do+    let req = emptyXmlRequest (mkQueryAction (queryPage pgName) cReq)+    mb <- webGetXml Cats.stringXml url req+    case mb of+      Nothing -> fail ("Failed to fetch page" ++ pgName ++ " from " ++ url)+      Just c  -> do+        let acc' = (acc ++ clPages c)+        case clContinue c of+          Nothing -> return (concatMap snd acc')+	  Just x  -> queryPageCats' cReq{clContinueFrom=Just x} acc'++main :: IO ()+main = do+  (opts, fs) <- processOptions option_descr nullOptions+  let url = optWiki opts+    -- not needed here, but left in to show how to login to a Wiki.+  case (optUser opts, optPass opts) of+    (Just u, Just p) -> do+       x <- loginWiki url u p+       case x of+         Nothing -> putStrLn ("Unable to login to: " ++ url)+         Just lg -> print (lgSuccess lg)+    _ -> return ()+  case mbCons (optCat opts) fs of+    [] -> putStrLn "No categories specified."+    xs -> mapM_ (showCat url) xs+  case mbCons (optPage opts) fs of+    [] -> return ()+    xs -> mapM_ (showPages url) xs++showCat :: URLString -> String -> IO ()+showCat url cat = do+  ps <- queryCat url cat+  putStrLn ("Members of category `" ++ cat ++ "'")+  mapM_ (putStrLn.toTitle) ps+ where+  toTitle pg = ' ':pgTitle pg++showPages :: URLString -> String -> IO ()+showPages url pgName = do+  ps <- queryPageCats url pgName+  putStrLn ("Page " ++ show pgName ++ " is a member of the following categories: ")+  mapM_ (putStrLn.toTitle) ps+ where+  toTitle pg = ' ':pgTitle pg++mbCons :: Maybe a -> [a] -> [a]+mbCons Nothing xs = xs+mbCons (Just x) xs = x:xs+
examples/Util/GetOpts.hs view
@@ -12,34 +12,62 @@ -- -- So, to correctly attribute the source of the bulk of the functionality -- provided, here's its module header:--- +-- -- Module      :  System.Console.GetOpt -- Copyright   :  (c) Sven Panne Oct. 1996 (small changes Dec. 1997) -- License     :  BSD-style (see the file libraries\/core\/LICENSE)--- +-- -- Maintainer  :  libraries@haskell.org -- Stability   :  experimental -- Portability :  portable ----- A Haskell port of GNU's getopt library +-- A Haskell port of GNU's getopt library --  module Util.GetOpts     ( module System.Console.GetOpt-    , getOpt2           -- :: ArgOrder (a->a) +    , getOpt2           -- :: ArgOrder (a->a)                         -- -> [OptDescr (a->a)]                         -- -> [String]                         -- -> a                         -- -> (a,[String],[String])     , usageInfo2        -- :: String -> [OptDescr a] -> String++    , parseOptions      -- :: [OptDescr (a -> a)]+                        -- :: a+			-- -> [String]+			-- -> (a, [String], [String])+    , processOptions    -- :: [OptDescr (a -> a)]+                        -- -> a+	                -- -> IO (a, [String])     ) where  import Prelude import Data.List        ( isPrefixOf ) import Text.PrettyPrint---import Util.Pretty import System.Console.GetOpt +import System.IO+import System.Environment+import System.Exit++import Control.Monad ( when )++processOptions :: [OptDescr (a -> a)]+               -> a+	       -> IO (a, [String])+processOptions descriptors nullVal = do+  ls <- getArgs+  let (opts, ws, es) = parseOptions descriptors nullVal ls+  when (not $ null es) $ do+    hPutStrLn stderr (unlines es)+    hPutStrLn stderr ("(try '--help' for list of options supported.)")+    exitFailure+  return (opts, ws)++parseOptions :: [OptDescr (a -> a)] -> a -> [String] -> (a, [String], [String])+parseOptions descriptors nullVal argv = getOpt2 Permute descriptors argv nullVal+ {- |  The @getOpt@ provided @System.Console.GetOpt@ returns a list of  values representing the options found present in an @argv@-vector.@@ -51,7 +79,7 @@  to be quite a bit less cumbersome to work with, leaving you at  the end with a single value (the record) packaging up all the  options setting.- +  With @getOpt@, you normally end up (essentially) having to  write a sub parser of the list of values returned, which just  adds even more bulk to your code, for very little benefit.@@ -75,7 +103,7 @@          (opt,rest)  = getNext arg args optDescr          (st',xs,es) = getOpt2 ordering optDescr rest st --- getOpt2 supporting code - copied verbatim from System.Console.GetOpt +-- getOpt2 supporting code - copied verbatim from System.Console.GetOpt -- as it isn't exported.  data OptKind a                -- kind of cmd line arg (internal use only):@@ -155,7 +183,7 @@ usageInfo2 header optDescr = render $ vcat $ text header : table   where     (ss, ls, descs) = unzip3 $ map fmtOpt optDescr-    table           = +    table           =         let (c1, ssd) = sameLen ss             (c2, lsd) = sameLen ls         in@@ -188,11 +216,11 @@ -- | Simple line formatting of a paragraph, introducing line breaks -- whenever length exceeds that of the first argument. fitText :: Int -> String -> Doc-fitText width s = +fitText width s =    vcat $ map (hsep . (map text))               (fit 0 [] (words s))   where-     -- fill up lines left-to-right, introducing line breaks +     -- fill up lines left-to-right, introducing line breaks      -- whenever line length exceeds 'width'.     fit :: Int -> [String] -> [String] -> [[String]]     fit _ acc [] = [reverse acc]
mediawiki.cabal view
@@ -1,149 +1,134 @@-Name:               mediawiki
-Version:            0.2.4
-License:            BSD3
-License-file:       LICENSE
-Category:           Web
-Synopsis:           Interfacing with the MediaWiki API
-Description:        
-  A complete Haskell binding to the MediaWiki API letting you
-  programmatically access (read and write) MediaWiki content.
-  .
-  See <http://www.mediawiki.org/wiki/API> and <http://haskell.forkio.com/>
-  for more.
-Author:             Sigbjorn Finne <sof@forkIO.com>
-Maintainer:         Sigbjorn Finne <sof@forkIO.com>
-Cabal-version:   >= 1.2
-build-type: Simple
-extra-source-files: README
-                    examples/ListCat.hs
-                    examples/Util/GetOpts.hs
-
-flag old-base
-  description: Old, monolithic base
-  default: False
-  
-library
-    Exposed-Modules: MediaWiki.API.Types,
-                     MediaWiki.API.Output,
-                     MediaWiki.API, 
-                     MediaWiki.API.Base, 
-                     MediaWiki.API.Utils, 
-                     MediaWiki.API.Query.AllCategories,
-                     MediaWiki.API.Query.AllCategories.Import,
-                     MediaWiki.API.Query.AllImages,
-                     MediaWiki.API.Query.AllImages.Import,
-                     MediaWiki.API.Query.AllLinks,
-                     MediaWiki.API.Query.AllLinks.Import,
-                     MediaWiki.API.Query.AllMessages,
-                     MediaWiki.API.Query.AllMessages.Import,
-                     MediaWiki.API.Query.AllPages,
-                     MediaWiki.API.Query.AllPages.Import,
-                     MediaWiki.API.Query.AllUsers,
-                     MediaWiki.API.Query.AllUsers.Import,
-                     MediaWiki.API.Query.BackLinks,
-                     MediaWiki.API.Query.BackLinks.Import,
-                     MediaWiki.API.Query.Blocks,
-                     MediaWiki.API.Query.Blocks.Import,
-                     MediaWiki.API.Query.Categories,
-                     MediaWiki.API.Query.Categories.Import,
-                     MediaWiki.API.Query.CategoryInfo,
-                     MediaWiki.API.Query.CategoryInfo.Import,
-                     MediaWiki.API.Query.CategoryMembers,
-                     MediaWiki.API.Query.CategoryMembers.Import,
-                     MediaWiki.API.Query.DeletedRevisions,
-                     MediaWiki.API.Query.DeletedRevisions.Import,
-                     MediaWiki.API.Query.EmbeddedIn,
-                     MediaWiki.API.Query.EmbeddedIn.Import,
-                     MediaWiki.API.Query.ExternalLinks
-                     MediaWiki.API.Query.ExternalLinks.Import,
-                     MediaWiki.API.Query.ExternalURLUsage
-                     MediaWiki.API.Query.ExternalURLUsage.Import,
-                     MediaWiki.API.Query.ImageInfo,
-                     MediaWiki.API.Query.ImageInfo.Import,
-                     MediaWiki.API.Query.Images,
-                     MediaWiki.API.Query.Images.Import,
-                     MediaWiki.API.Query.ImageUsage,
-                     MediaWiki.API.Query.ImageUsage.Import,
-                     MediaWiki.API.Query.Info,
-                     MediaWiki.API.Query.Info.Import,
-                     MediaWiki.API.Query.LangLinks,
-                     MediaWiki.API.Query.LangLinks.Import,
-                     MediaWiki.API.Query.Links,
-                     MediaWiki.API.Query.Links.Import,
-                     MediaWiki.API.Query.LogEvents,
-                     MediaWiki.API.Query.LogEvents.Import,
-                     MediaWiki.API.Query.Random,
-                     MediaWiki.API.Query.Random.Import,
-                     MediaWiki.API.Query.RecentChanges,
-                     MediaWiki.API.Query.RecentChanges.Import,
-                     MediaWiki.API.Query.Revisions,
-                     MediaWiki.API.Query.Revisions.Import,
-                     MediaWiki.API.Query.Search,
-                     MediaWiki.API.Query.Search.Import,
-                     MediaWiki.API.Query.SiteInfo,
-                     MediaWiki.API.Query.SiteInfo.Import,
-                     MediaWiki.API.Query.Templates,
-                     MediaWiki.API.Query.Templates.Import,
-                     MediaWiki.API.Query.UserContribs,
-                     MediaWiki.API.Query.UserContribs.Import,
-                     MediaWiki.API.Query.UserInfo,
-                     MediaWiki.API.Query.UserInfo.Import,
-                     MediaWiki.API.Query.Users,
-                     MediaWiki.API.Query.Users.Import,
-                     MediaWiki.API.Query.WatchList,
-                     MediaWiki.API.Query.WatchList.Import,
-                     MediaWiki.API.Action.Sitematrix,
-                     MediaWiki.API.Action.Login,
-                     MediaWiki.API.Action.Login.Import,
-                     MediaWiki.API.Action.ParamInfo,
-                     MediaWiki.API.Action.Parse,
-                     MediaWiki.API.Action.Parse.Import,
-                     MediaWiki.API.Action.Rollback,
-                     MediaWiki.API.Action.Delete,
-                     MediaWiki.API.Action.Undelete,
-                     MediaWiki.API.Action.Protect,
-                     MediaWiki.API.Action.Block,
-                     MediaWiki.API.Action.Unblock,
-                     MediaWiki.API.Action.Move,
-                     MediaWiki.API.Action.Edit,
-                     MediaWiki.API.Action.EmailUser,
-                     MediaWiki.API.Action.Watch,
-                     MediaWiki.API.Action.OpenSearch,
-                     MediaWiki.API.Action.FeedWatchlist,
-                     MediaWiki.API.Action.ExpandTemplates,
-                     MediaWiki.API.Action.ExpandTemplates.Import,
-                     MediaWiki.Util.Fetch,
-                     MediaWiki.Util.Codec.Percent,
-                     MediaWiki.Util.Codec.URLEncoder
-    Ghc-Options:     -Wall -O2 
-    Build-Depends:   xml, HTTP >= 3001, network, mime, utf8-string
- if flag(old-base)
-   Build-Depends: base < 3
- else
-   Build-Depends: base >= 4
-
- if impl(ghc >= 6.10)
-    cpp-options:     -DEXTENSIBLE_EXCEPTIONS
-
-executable main {
-  if flag(old-base)
-   Build-Depends: base < 3
-  else
-   Build-Depends: base >= 4
-  main-is:              Main.hs
-  ghc-options:          -Wall -fglasgow-exts
-  if impl(ghc >= 6.10)
-    cpp-options:     -DEXTENSIBLE_EXCEPTIONS
-}
-
-executable listCat {
-  build-depends:        pretty
-  if flag(old-base)
-   Build-Depends: base < 3
-  else
-   Build-Depends: base >= 4
-  main-is:              examples/ListCat.hs
-  ghc-options:          -Wall -fglasgow-exts -iexamples
-  if impl(ghc >= 6.10)
-    CPP-options:     -DEXTENSIBLE_EXCEPTIONS
-}
+Name:               mediawiki+Version:            0.2.6+License:            BSD3+License-file:       LICENSE+Category:           Web+Synopsis:           Interfacing with the MediaWiki API+Description:+  A complete Haskell binding to the MediaWiki API letting you+  programmatically access (read and write) MediaWiki content.+  .+  See <http://www.mediawiki.org/wiki/API> and <http://haskell.forkio.com/>+  for more.+Author:             Sigbjorn Finne <sof@forkIO.com>+Maintainer:         Sigbjorn Finne <sof@forkIO.com>+Cabal-version:   >= 1.8+build-type: Simple+extra-source-files: README+                    examples/ListCat.hs+                    examples/LinksTo.hs+                    examples/Util/GetOpts.hs++library+    Exposed-Modules: MediaWiki.API.Types,+                     MediaWiki.API.Output,+                     MediaWiki.API,+                     MediaWiki.API.Base,+                     MediaWiki.API.Utils,+                     MediaWiki.API.Query.AllCategories,+                     MediaWiki.API.Query.AllCategories.Import,+                     MediaWiki.API.Query.AllImages,+                     MediaWiki.API.Query.AllImages.Import,+                     MediaWiki.API.Query.AllLinks,+                     MediaWiki.API.Query.AllLinks.Import,+                     MediaWiki.API.Query.AllMessages,+                     MediaWiki.API.Query.AllMessages.Import,+                     MediaWiki.API.Query.AllPages,+                     MediaWiki.API.Query.AllPages.Import,+                     MediaWiki.API.Query.AllUsers,+                     MediaWiki.API.Query.AllUsers.Import,+                     MediaWiki.API.Query.BackLinks,+                     MediaWiki.API.Query.BackLinks.Import,+                     MediaWiki.API.Query.Blocks,+                     MediaWiki.API.Query.Blocks.Import,+                     MediaWiki.API.Query.Categories,+                     MediaWiki.API.Query.Categories.Import,+                     MediaWiki.API.Query.CategoryInfo,+                     MediaWiki.API.Query.CategoryInfo.Import,+                     MediaWiki.API.Query.CategoryMembers,+                     MediaWiki.API.Query.CategoryMembers.Import,+                     MediaWiki.API.Query.DeletedRevisions,+                     MediaWiki.API.Query.DeletedRevisions.Import,+                     MediaWiki.API.Query.EmbeddedIn,+                     MediaWiki.API.Query.EmbeddedIn.Import,+                     MediaWiki.API.Query.ExternalLinks+                     MediaWiki.API.Query.ExternalLinks.Import,+                     MediaWiki.API.Query.ExternalURLUsage+                     MediaWiki.API.Query.ExternalURLUsage.Import,+                     MediaWiki.API.Query.ImageInfo,+                     MediaWiki.API.Query.ImageInfo.Import,+                     MediaWiki.API.Query.Images,+                     MediaWiki.API.Query.Images.Import,+                     MediaWiki.API.Query.ImageUsage,+                     MediaWiki.API.Query.ImageUsage.Import,+                     MediaWiki.API.Query.Info,+                     MediaWiki.API.Query.Info.Import,+                     MediaWiki.API.Query.LangLinks,+                     MediaWiki.API.Query.LangLinks.Import,+                     MediaWiki.API.Query.Links,+                     MediaWiki.API.Query.Links.Import,+                     MediaWiki.API.Query.LogEvents,+                     MediaWiki.API.Query.LogEvents.Import,+                     MediaWiki.API.Query.Random,+                     MediaWiki.API.Query.Random.Import,+                     MediaWiki.API.Query.RecentChanges,+                     MediaWiki.API.Query.RecentChanges.Import,+                     MediaWiki.API.Query.Revisions,+                     MediaWiki.API.Query.Revisions.Import,+                     MediaWiki.API.Query.Search,+                     MediaWiki.API.Query.Search.Import,+                     MediaWiki.API.Query.SiteInfo,+                     MediaWiki.API.Query.SiteInfo.Import,+                     MediaWiki.API.Query.Templates,+                     MediaWiki.API.Query.Templates.Import,+                     MediaWiki.API.Query.UserContribs,+                     MediaWiki.API.Query.UserContribs.Import,+                     MediaWiki.API.Query.UserInfo,+                     MediaWiki.API.Query.UserInfo.Import,+                     MediaWiki.API.Query.Users,+                     MediaWiki.API.Query.Users.Import,+                     MediaWiki.API.Query.WatchList,+                     MediaWiki.API.Query.WatchList.Import,+                     MediaWiki.API.Action.Sitematrix,+                     MediaWiki.API.Action.Login,+                     MediaWiki.API.Action.Login.Import,+                     MediaWiki.API.Action.ParamInfo,+                     MediaWiki.API.Action.Parse,+                     MediaWiki.API.Action.Parse.Import,+                     MediaWiki.API.Action.Rollback,+                     MediaWiki.API.Action.Delete,+                     MediaWiki.API.Action.Undelete,+                     MediaWiki.API.Action.Protect,+                     MediaWiki.API.Action.Block,+                     MediaWiki.API.Action.Unblock,+                     MediaWiki.API.Action.Move,+                     MediaWiki.API.Action.Edit,+                     MediaWiki.API.Action.EmailUser,+                     MediaWiki.API.Action.Watch,+                     MediaWiki.API.Action.OpenSearch,+                     MediaWiki.API.Action.FeedWatchlist,+                     MediaWiki.API.Action.ExpandTemplates,+                     MediaWiki.API.Action.ExpandTemplates.Import,+                     MediaWiki.Util.Fetch,+                     MediaWiki.Util.Codec.Percent,+                     MediaWiki.Util.Codec.URLEncoder+   Ghc-Options:    -Wall -O2+   Build-Depends:  base >= 3 && < 5, xml, HTTP >= 3001, network, mime, utf8-string++executable main {+  Build-Depends:   mediawiki, base >= 3 && < 5, xml, HTTP >= 3001, network, mime, utf8-string+  Main-is:         Main.hs+  Ghc-options:     -Wall+}++executable listCat {+  Build-Depends:   mediawiki, base >= 3 && < 5, xml, HTTP >= 3001, network, mime, utf8-string, pretty+  Main-is:         examples/ListCat.hs+  Ghc-options:     -Wall -iexamples+}++executable linksTo {+  Build-Depends:   mediawiki, base >= 4, xml, HTTP >= 3001, network, mime, utf8-string, pretty+  Main-is:         examples/LinksTo.hs+  Ghc-options:     -Wall -iexamples+}