{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | The Nation API. -- -- This module should be imported qualified, to prevent name clashes: -- -- @ -- import NationStates -- import qualified NationStates.Nation as Nation -- @ -- -- In general, this module follows the terminology used in the -- , -- except when it clashes with Haskell keywords. For instance, the -- @type@ shard has been renamed to 'type_'. -- -- Here's a short example: -- -- @ -- import NationStates -- import qualified NationStates.Nation as Nation -- import Text.Printf -- -- main = do -- c <- 'NationStates.newContext' "ExampleBot/2000" -- (name, motto) <- Nation.'run' "Montesardo-East Adanzi" -- ((,) \<$\> Nation.'name' \<*\> Nation.'motto') c -- printf "%s has the motto: %s\\n" name motto -- @ module NationStates.Nation ( -- * Running queries Nation(..), run, -- * Shards name, fullname, type_, motto, category, wa, endorsements, gavote, scvote, freedom, region, population, tax, animal, animaltrait, currency, flag, banner, banners, -- majorindustry, -- crime, -- sensibilities, -- govtpriority, -- govt, -- govtdesc, -- industrydesc, -- notable, -- admirable, -- founded, -- firstlogin, -- lastlogin, -- lastactivity, -- influence, -- freedomscores, -- publicsector, -- deaths, -- leader, -- capital, -- religion, -- customleader, -- customcapital, -- customreligion, -- rcensus, -- wcensus, censusscore, censusscore', -- legislation, -- happenings, -- demonym, -- demonym2, -- demonym2plural, -- factbooks, -- factbooklist, -- dispatches, -- dispatchlist, ) where import Control.Applicative import Data.Maybe import qualified Data.Map as Map import qualified Data.MultiSet as MultiSet import Text.XML.Light import Prelude -- GHC 7.10 import NationStates.Core -- | A request to the Nation API. newtype Nation a = Nation { unNation :: NS a } deriving (Functor, Applicative) -- | Perform a request to the Nation API. run :: String -- ^ Nation name -> Nation a -- ^ Requested shards -> Context -- ^ Connection manager -> IO a run nation = requestNS (Just ("nation", nation)) . unNation -- | Short name. -- -- > "Testlandia" name :: Nation String name = Nation $ makeNS "name" "NAME" -- | Full name, including pre-title. -- -- > "The Republic of Testlandia" fullname :: Nation String fullname = Nation $ makeNS "fullname" "FULLNAME" -- | Nation type. -- -- > "Republic" type_ :: Nation String type_ = Nation $ makeNS "type" "TYPE" -- | Motto. -- -- > "It's a feature!" motto :: Nation String motto = Nation $ makeNS "motto" "MOTTO" -- | Nation category. -- -- > InoffensiveCentristDemocracy category :: Nation WACategory category = Nation . fmap (expect "category" <*> readWACategory) $ makeNS "category" "CATEGORY" -- | Whether the nation is in the World Assembly. -- -- > True wa :: Nation Bool wa = Nation . fmap (expect "WA status" <*> readWAStatus) $ makeNS "wa" "UNSTATUS" -- | List of endorsements received. -- -- > ["jlink","translenia","the_vines"] endorsements :: Nation [String] endorsements = Nation . fmap (wordsBy (== ',')) $ makeNS "endorsements" "ENDORSEMENTS" -- | General assembly vote. -- -- > Just True gavote :: Nation (Maybe WAVote) gavote = Nation . fmap (expect "General Assembly vote" <*> readWAVote') $ makeNS "gavote" "GAVOTE" -- | Security council vote. -- -- > Nothing scvote :: Nation (Maybe WAVote) scvote = Nation . fmap (expect "Security Council vote" <*> readWAVote') $ makeNS "scvote" "SCVOTE" -- | Description of civil rights, economy, and political freedoms. -- -- > ("Excellent","Strong","Very Good") freedom :: Nation (String, String, String) freedom = Nation $ makeNS' (shard "freedom") parse where parse _ root | Just parent <- findChild (unqual "FREEDOM") root , [c, e, p] <- map strContent $ elChildren parent = (c, e, p) | otherwise = error "could not find freedom descriptors" -- | Resident region. -- -- > "Testregionia" region :: Nation String region = Nation $ makeNS "region" "REGION" -- | Population, in millions. -- -- > 25764 population :: Nation Integer population = Nation . fmap (expect "population" <*> readMaybe) $ makeNS "population" "POPULATION" -- | Income tax, percent. -- -- > 83.6 tax :: Nation Double tax = Nation . fmap (expect "tax" <*> readMaybe) $ makeNS "tax" "TAX" -- | National animal. -- -- > "sea-snake" animal :: Nation String animal = Nation $ makeNS "animal" "ANIMAL" -- | A short phrase describing the animal. -- -- > "is also the nation's favorite main course" animaltrait :: Nation String animaltrait = Nation $ makeNS "animaltrait" "ANIMALTRAIT" -- | Currency. -- -- > "☆star☆" currency :: Nation String currency = Nation $ makeNS "currency" "CURRENCY" -- | Flag URL. -- -- > "http://www.nationstates.net/images/flags/Switzerland.png" flag :: Nation String flag = Nation $ makeNS "flag" "FLAG" -- | A suitable banner for this nation. -- -- > "v1" banner :: Nation String banner = Nation $ makeNS "banner" "BANNER" -- | A list of suitable banners for this nation. -- -- > ["v1","o4","b14","t23","m3"] banners :: Nation [String] banners = Nation $ makeNS' (shard "banners") parse where parse _ root | Just parent <- findChild (unqual "BANNERS") root = map strContent $ elChildren parent | otherwise = error "could not find banner codes" -- | Query today's census. -- -- Returns the current census ID, along with its value. -- -- > (24,6.0) censusscore :: Nation (Integer, Double) censusscore = Nation $ makeNS' (shard "censusscore") parse where parse q root | Just (i, _) <- MultiSet.minView $ MultiSet.difference response request , Just x <- lookup i censusScores = (i, x) | otherwise = error "could not find census score" where censusScores = extractCensusScores root request = MultiSet.mapMaybe id . MultiSet.fromSet $ queryShards q Map.! "censusscore" response = MultiSet.fromList $ map fst censusScores -- | Query a census by its census ID. -- -- > 94.0 censusscore' :: Integer -> Nation Double censusscore' i = Nation $ makeNS' (shard' "censusscore" i) parse where parse _ = fromMaybe (error $ "could not find census " ++ show i) . lookup i . extractCensusScores extractCensusScores :: Element -> [(Integer, Double)] extractCensusScores root = catMaybes [ (,) <$> maybeId <*> maybeValue | Elem e <- elContent root, elName e == unqual "CENSUSSCORE", let maybeId = readMaybe =<< findAttr (unqual "id") e, let maybeValue = readMaybe $ strContent e ]