Unfortunately we don't have any consistency guarantee on that "action" field: it could be anything. And it could change. And sometimes a log entry will mention more than one nation (or region).
Ditto for pasting it as raw HTML: it seems problematic, given that the HTML may change in the future.
I think the best option is to tag nations and regions in plaintext... somehow.
You might see some oddities, such as embedded URLs linking to RMB posts... I'm not sure what is easiest for you to process, so let me know and I'm happy to tweak it.
Posted: Wed Jan 18, 2012 12:57 am
by Charlotte Ryberg
Hi,
I am creating a local API for comparing major issue effects: is there a way to call up just the most recent new legislation (or the last phrase in the "legislation" shard)?
Posted: Wed Jan 18, 2012 1:41 pm
by Letoilenoir
Sorry to appear naive, but doesn't the LAW and HAPPENINGS shards constitute duplication?
I can understand that they have subtle differences, but enough to take up valuable virtual estate?
The Legislation shard gives the effects of the last 4 laws passed, as also provided on the nation page. The Happenings shard provides the last 10 items of the national happenings. These may be all 'was endorsed by', 'relocated to X', 'altered national flag', etc... items without mentioning the effects of laws. They may be mentioned there too though.
Either way, the game is better off storing them separately anyway. Trying to combine these things would severely complicate programming and barely save any storage space, so I'm guessing that wasn't done.
Ballotonia
Posted: Wed Jan 18, 2012 2:47 pm
by [violet]
Charlotte Ryberg wrote:I am creating a local API for comparing major issue effects: is there a way to call up just the most recent new legislation (or the last phrase in the "legislation" shard)?
No, you'll need to just pick out the last one in your own script.
Relatedly, I would love to be able to add some script examples to our API doc -- e.g. some basic Perl, Python, and PHP to show scripting newbies how to get started. Any script authors willing to provide this?
Posted: Wed Jan 18, 2012 2:50 pm
by Letoilenoir
Ballotonia I bow to your superior experience in these matters, just thought paring down the core data might have sped things up at least for the API
Charlotte Ryberg wrote:I am creating a local API for comparing major issue effects: is there a way to call up just the most recent new legislation (or the last phrase in the "legislation" shard)?
No, you'll need to just pick out the last one in your own script.
Relatedly, I would love to be able to add some script examples to our API doc -- e.g. some basic Perl, Python, and PHP to show scripting newbies how to get started. Any script authors willing to provide this?
Please somebody step forward, if only to hint at what can be done!
Posted: Wed Jan 18, 2012 3:16 pm
by New South Hell
[violet] wrote: Relatedly, I would love to be able to add some script examples to our API doc -- e.g. some basic Perl, Python, and PHP to show scripting newbies how to get started. Any script authors willing to provide this?
I'll volunteer to do some Python - though it may take awhile for me to get the free time.
use strict; use warnings; use LWP::Simple; use XML::Simple;
#This perl script, designed by Unibot will show you a basic method to grab an entry from the shards and an entry from the Standard API. I will comment after each step.
my $nation_to_search = <STDIN>; chomp ($nation_to_search);
#This allows you to type in which nation that you'd like to search.
$_ = lc($nation_to_search); tr/ /_/; my $nation_searched = $_;
#This substitutes the spaces in any input for underscores, which is important because "the south pacific" does not equal "the_south_pacific", for example. You need all the spaces in the input to be underscores for your script to find the information you want to find.
my $desired_shard = "http://www.nationstates.net/cgi-bin/api.cgi?nation="."$nation_searched"."&q=population";
#Since I want to grab a nation's population from the appropriate shard, I need to make a string with the url to this shard.
my $XML_population = XMLin( get($desired_shard)); my $population = $XML_population->{'POPULATION'};
#This grabs the requested nation's population from the appropriate shard.
my $standard_api = "http://www.nationstates.net/cgi-bin/api.cgi/nation="."$nation_searched";
#Next I want to use the Standard API to grab the nation's "freedom score" for Civil Rights. So I have to make a link again, but this time for the Standard API.
my $xml_civil_rights = XMLin( get($standard_api)); my $civil_rights = $xml_civil_rights->{'FREEDOMSCORES'}->{'CIVILRIGHTS'};
#This grabs the civil rights "freedom score" for the nation from the Standard API. Note there's a second chain (->), because "CIVILRIGHTS" is bundled with "ECONOMY" and "POLITCALFREEDOM" under the "FREEDOMSCORES". Death statistics and government spending also use this sort of organization.
print "$nation_to_search has $population million people and its civil right's freedom score is $civil_rights.\n";
#Finally, this will print the output of the script -- which is rather mundane information that you could have just looked up yourself. But I'm sure if you're like me, you've got all these wonderful ideas on how you can pull information and make wonderful new and colorful calculations by combining different statistics. Once you get the information, the sky is the limit!
I'm no perl expert by any means.. I'm very amateurish, but that's usually how I make requests with Perl.
Posted: Thu Jan 19, 2012 2:28 pm
by Scoochi2
a PHP version that outputs the exact same thing as Unibot's Perl script. Note that it doesn't output HTML, so if viewed in a web browser the newline will not take effect. Also, I suck at tutorials so it probably won't make sense. And I'm tired so it could probably be done easier
if (strpos($desired_shards,'Unknown nation') != false) { echo ("nation $nation does not exist.\n"); return; }
$population = get_data('POPULATION',$desired_shards); $civil_rights = get_data('CIVILRIGHTS',$desired_shards); echo "$nation has $population million people and its civil right's freedom score is $civil_rights.\n"; }
<?php $useragent = "Custom User Agent String"; // choose a useful user agent here, ensure you change this to something relevant to your script which will allow it to be identified and for you to be contacted.
if ($useragent == "Custom User Agent String") // checks if you have changed the user agent from the default value die ("Error: user agent is not set"); // and if not, terminates the script here.
ini_set("user_agent",$useragent); // sets the user agent for your script
function get_data($tag,$shard){ /* returns a string with the contents of given tag */ $start = strpos($shard,"<$tag>")+strlen($tag)+2; // finds where in the shard given tag starts, and adds on length of the search string. $end = strpos($shard,"</$tag>"); // finds where in the shard the search string ends. No need to add anything as the pointer will be start of search string. $length = $end-$start; return substr($shard,$start,$length); //returns a substring containing just the data we want }
function echo_popandcivil($nation){ /* for a given nation, output a string detailing that nation's population and civil rights score */ $nation_withoutspace = str_replace(' ', '_', $nation); // This substitutes the spaces in any input for underscores, which is important because "the south pacific" does not equal "the_south_pacific", for example. You need all the spaces in the input to be underscores for your script to find the information you want to find. $desired_shards = file_get_contents("http://www.nationstates.net/cgi-bin/api.cgi?nation=$nation_withoutspace&q=population+freedomscores"); // gets the desired shard and saves it as a string in my variable
if (strpos($desired_shards,'Unknown nation') != false) { // this block checks if the nation exists. If it does not, it stops the function from continuing. echo ("nation $nation does not exist.\n"); // give some output. return; }
$population = get_data('POPULATION',$desired_shards); // uses the function we defined previously to find out the nation's population $civil_rights = get_data('CIVILRIGHTS',$desired_shards); // uses the function we defined previously to find out the nation's population
echo "$nation has $population million people and its civil right's freedom score is $civil_rights.\n"; // outputs a string containing our relevant information. Puts a newline at the end. }
for reference, this will be the output (at time of writing):
Scoochi2 has 7014 million people and its civil right's freedom score is 38. nation [violet] does not exist.
EDIT: updated with user agent. Have also taken Trotterdam's idea on board: the script will immediately terminate without complete execution if you do not change the default user agent.
Posted: Thu Jan 19, 2012 2:56 pm
by [violet]
Thanks! I've linked to these posts from the API doc.
More would be welcome!
Posted: Thu Jan 19, 2012 3:36 pm
by Fischistan
If anyone uses Visual Basic .NET, Here it goes: This program just returns the data from any shard you tell it to. make sure to put
Private Function get_shard(ByRef nation_name As String, ByVal api_shard As String) as String Dim api_node As XMLNode 'the xml node we're looking for Dim api_doc As XMLDocument 'the xml document we will parse nation_name = replace(nation_name, " ", "_") 'replace spaces with underscores in the nation name nation_name = nation_name.ToLower() 'make the nation name all lowercase api_doc = New XMLDocument 'initialize a new xml document api_doc.load("http://www.nationstates.net/cgi-bin/api.cgi?nation=" & nation_name & "&q=" & api_shard.ToLower()) 'load the xml document for the nation with the shard we want api_node = api_doc.SelectSingleNode("/NATION/" & api_shard.ToUpper()) 'navigate to the shard we want return api_node.InnerText() 'get the text of the node we are at End Function
Private Sub category(ByVal nation1 As String, ByVal nation2 As String) Dim message As String 'the message we will show message = nation1 & " has the category " message = message & get_shard(nation1, "category") 'get the category that nation1 has message = message & Chr(13) & Chr(13) 'add 2 new lines message = message & nation2 & " has the category " message = message & get_shard(nation2, "category") 'get the category that nation2 has MsgBox(message) 'show the data that we have gathered End Sub
Posted: Thu Jan 19, 2012 4:08 pm
by Fischistan
I guess It's worth noting that the last one was for Visual Basic .NET; it might or might not work for VB 6.
I don't know if this is the place to comment on this, but that seems an awfully complicated way to go about doing it. PHP has a built-in XML parser called SimpleXML. Here's a simple example of getting data from a full API call:
// Type-casting to convert object to string, so that it can be stored. May not be necessary here, but it's always better safe than sorry. $population = (string) $xml->POPULATION; $civil_rights = (string) $xml->FREEDOMSCORES->CIVILRIGHTS;
Because Lua requires some libraries to do anything over the web or XML related it doesn't seem ideal for this, but I really like to use Lua whenever possible.
--Lua NationStates API Example --Lua, by default, does not include XML parsing or socket information require("LuaXml") --available from http://viremo.eludi.net/LuaXML/ local http = require("socket.http") --available from http://w3.impa.br/~diego/software/luasocket/ --or just use LuaRocks and/or Lua for Windows
--Cache any results we request local nations = { }
http.USERAGENT = "Custom User Agent"
function get_data(nation, shards) address = "http://www.nationstates.net/cgi-bin/api.cgi?nation=" .. nation if type(shards) == "string" then address = address .. "&q=" .. shards end --request the API data file = http.request(address) assert(file, "Error accessing " .. address) --parse the file into a Lua table xml = xml.eval(file) assert(xml, "Error parsing XML data") return xml end
function display_pop_civilrights(nation) --if we already loaded the data, why fetch it again? if nations[nation] == nil then data = get_data(nation, "name+population+freedomscores") --store it too nations[nation] = data else data = nations[nation] end --Find the value associated with the tag "NAME" name = data:find("NAME")[1] -- [0] is the tag itself, [1] being the data contained by the tag population = data:find("POPULATION")[1] civil_rights = data:find("FREEDOMSCORES"):find("CIVILRIGHTS")[1] str = string.format("<p><b>%s</b><br />Population: %s<br />Civil Rights: %s</p>", name, population, civil_rights) print(str) return str end
If you'd like to write to a file, Lua makes it incredibly simple: handle = io:open("filename.txt", "r") handle.write(results) ]]--
Edit: Added Custom User Agent
Posted: Sat Jan 21, 2012 9:29 pm
by Frisbeeteria
GraySoap wrote:Additionally, I have a question. Would it be too much bandwidth if I had a script fetch the gzip'd nation & region data every day?
I'm fairly certain that they were created specifically for that purpose. As long as you abide by the rate limits and other rules of the API, you should be fine.
I don't know if this is the place to comment on this, but that seems an awfully complicated way to go about doing it. PHP has a built-in XML parser called SimpleXML.
Yes it does. But not all servers have a XML parser module (SimpleXML for example) installed and enabled. And the way I did it can be immediately useful for HTML as well as-is, whilst remaining simple and easily modifiable.
Both are good ways, with various benefits.
Posted: Thu Jan 26, 2012 5:46 pm
by Solm
Would it be possible to add some WA stats to the api? Like adding the vote tallies, current resolutions at vote, recent events, etc... I think it might be pretty helpful to add some WA stats to the api. (Plus, I wouldn't have to scrape )
Posted: Fri Jan 27, 2012 10:42 am
by Glen-Rhodes
Solm wrote:Would it be possible to add some WA stats to the api? Like adding the vote tallies, current resolutions at vote, recent events, etc... I think it might be pretty helpful to add some WA stats to the api. (Plus, I wouldn't have to scrape )
Yes. Pleeeease do this! Specific things I would want:
Total votes for/against
List of delegates for/against (plus their voting power)
Time data that's being used for the graph. Although really I could scrape that easily, so this isn't a big request.
Posted: Fri Jan 27, 2012 3:43 pm
by [violet]
New: World Assembly API!
Just threw something together roughly; let me know if & how you'd like the data tweaked.
At the moment there's no way to get a list of delegate votes, but I'll add that soon!
Oh. My. Gawd. That is amazing! I even can't comprehend what people will do with it.
Posted: Fri Jan 27, 2012 7:59 pm
by Solm
Thank you so much [violet]! However, I'm not able to get to the page without using the shards, I get this error when trying to view it: "This page contains the following errors: error on line 2 at column 1: Extra content at the end of the document Below is a rendering of the page up to the first error." But thanks so much! Oh, and would it be possible to add the WA recent events to the API?