Pushing objects into a hash inside a loop - ruby

I'm trying to achieve the following JSON results:
{
"movie" =>
[{
"title": "Thor",
"year" : 2011,
},
{
"title": "Iron Man",
"year" : 2008,
}],
"tv" =>
[{
"title": "Parks and Recreation"
"year": 2009
},
{
"title": "Friends"
"year": 1994
}]
}
With JavaScript, I would loop through my results and do something like:
results['movie'].push(item);
results['tv'].push(item);
With Ruby code, the farthest I've gone is this:
#results = Hash.new
results['Search'].each do |r|
if r['Type'] == 'movie'
#results['movie'] << {
'title' => r['Title'],
'year' => r['Year']
}
elsif r['Type'] == 'series'
#results['tv'] << {
'title' => r['Title'],
'year' => r['Year']
}
end
end
What am I missing here?

I think you can get what you want by using Enumerable#each_with_object and assigning a default value to the hash.
def group_search_results(items)
results = Hash.new { |hash, key| hash[key] = [] }
items.each_with_object(results) do |item|
results[item['Type']] << {'title' => item['Title'], 'year' => item['Year']}
end
end
describe "search_results" do
it "groups into an object" do
items = [
{'Type' => 'movie', 'Title' => 'Thor', 'Year' => 2011},
{'Type' => 'movie', 'Title' => 'Iron Man', 'Year' => 2008},
{'Type' => 'series', 'Title' => 'Parks and Recreation', 'Year' => 2009},
{'Type' => 'series', 'Title' => 'Friends', 'Year' => 1994},
]
results = group_search_results(items)
expect(results).to eq({
'movie' => [
{'title' => 'Thor', 'year' => 2011},
{'title' => 'Iron Man', 'year' => 2008},
],
'series' => [
{'title' => 'Parks and Recreation', 'year' => 2009},
{'title' => 'Friends', 'year' => 1994},
],
})
end
end

I believe the problem has to do with the initialization of your hash. The movie and tv keys aren't currently an array. You can initialize your hash like this:
#results = { 'movie' => [], 'tv' => [] }
Here's how it looks with the rest of your code:
#results = { 'movie' => [], 'tv' => [] }
results['Search'].each do |r|
if r['Type'] == 'movie'
#results['movie'] << {
'title' => r['Title'],
'year' => r['Year']
}
elsif r['Type'] == 'series'
#results['tv'] << {
'title' => r['Title'],
'year' => r['Year']
}
end
end

results = {
search: {
movie: [
{ title: 'Thor', year: 2011 },
{ title: 'Iron Man', year: 2008 },
],
tv: [
{ title: 'Parks and Recreation', year: 2009 },
{ title: 'Friends', year: 1994 },
]
}
}
#results = Hash.new{|k, v| k[v] = []}
results[:search].each do |type, array|
#results[type].push(*array)
end
results[:search].each_with_object(Hash.new{|k, v| k[v] = []}) do |(type, array), hash|
hash[type].push(*array)
end

Related

How to add OR condition in Elasticsearch ruby query?

In my use case, I would like to add an OR condition in Elasticsearch query. Here is my query,
query_body = {
'query' => {
'bool' => {
'must' => [{ 'range' => {'#timestamp' => { 'from' => stream_filters[:first_time].gmtime.strftime("%Y-%m-%dT%H:%M:%SZ"), 'to' => stream_filters[:second_time].gmtime.strftime("%Y-%m-%dT%H:%M:%SZ") } } }, {'term' => {"#timeout" => true} }, {'term' => {"#dest" => dest} }, {'term' => {"#source" => source} } ]
}
}, 'facets' => facets
}
I would like to add 'term' => {"#dest" => ' '} empty check for #dest along with 'term' => {"#dest" => dest}
I tried to add an or condition, But it is not working.
query_body = {
'query' => {
'bool' => {
'must' => [{ 'range' => {'#timestamp' => { 'from' => stream_filters[:first_time].gmtime.strftime("%Y-%m-%dT%H:%M:%SZ"), 'to' => stream_filters[:second_time].gmtime.strftime("%Y-%m-%dT%H:%M:%SZ") } } }, {'term' => {"#timeout" => true} }, {'term' => {"#source" => source} } ],
'filter' => {
'or' => [{
'term' => { "#dest" => dest }
'term' => { "#dest" => ' ' }
}]
}
}
}, 'facets' => facets
}
Could someone help me with this?
It seems like a syntax error in your filter clause. Please try with the correct syntax as below :
'filter' => {
'or' => [
{
'term' => { "#dest" => dest }
},
{
'term' => { "#dest" => ' ' }
}
]
}

Search through Nested Hash having groups using Hashie Gem

I have a nested hash of a PDF that is in this format:
[ { :page => 1,
:lines => [
{ :y => 774.0,
:text_groups => [ { :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } ]
},
# ...
]
},
{ :page => 2,
:lines => [
{ :y => 774.0,
:text_groups => [ { :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } ]
},
# ...
],
# ...
}
]
I want to get the :x and :y for given :text from all 4 pages.
I tried this:
require 'hashie'
coordinates.extend(Hashie::Extensions::DeepLocate)
#hash_array = Hash.new
#hash_array = coordinates.deep_locate -> (key, value, object) { key == :text && value == "XXXX" }
This is giving me:
[ { :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } },
{ :x => 18.0, :width => 421.59599999999995, :text => "XXXX" },
{ :x => 18.0, :width => 421.59599999999995, :text => "XXXX" },
{ :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } ]
But I need :x and :y to be displayed like this:
x = " " and y = " "
I will use these values for my further validation.
I don't know if you'll accept a solution that doesn't use Hashie, but here's how I'd do it:
data = [
{ :page => 1,
:lines => [
{ :y => 774.0,
:text_groups => [ { :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } ]
},
# ...
]
},
{ :page => 2,
:lines => [
{ :y => 774.0,
:text_groups => [ { :x => 18.0, :width => 421.59599999999995, :text => "XXXX" } ]
},
# ...
],
# ...
}
]
SEARCH_TEXT = "XXXX"
coords = data.each_with_object([]) do |page, res|
page[:lines].each do |line|
line[:text_groups].each do |group|
next unless group[:text] == SEARCH_TEXT
res << { x: group[:x], y: line[:y] }
end
end
end
p coords
# => [ { :x => 18.0, :y => 774.0 },
# { :x => 18.0, :y => 774.0 } ]

merge every 3rd Hash in Array

Hi I can't find how to merge every 3 hashes of an array.
here is my array of hashes.
[
{:key1=>"v1"}, {:ky2 => "v2"}, {:key3 => "v3"},
{:key1=>"v4"}, {:ky2 => "v5"}, {:key3 => "v6"},
{:key1=>"v7"}, {:ky2 => "v8"}, {:key3 => "v9"},..
]
What I would need is to merge every 3 hashes to look like this :
[
{:key1=>"v1", :ky2 => "v2", :key3 => "v3"},
{:key1=>"v4", :ky2 => "v5", :key3 => "v6"},
{:key1=>"v7", :ky2 => "v8", :key3 => "v9"},..
]
Thank in advance for you help.
I'd do
hs = [
{:key1=>"v1"}, {:ky2 => "v2"}, {:key3 => "v3"},
{:key1=>"v4"}, {:ky2 => "v5"}, {:key3 => "v6"},
{:key1=>"v7"}, {:ky2 => "v8"}, {:key3 => "v9"}
]
hs.each_slice(3).map { |grouped_hs| grouped_hs.inject(:merge) }
# => [{:key1=>"v1", :ky2=>"v2", :key3=>"v3"},
# {:key1=>"v4", :ky2=>"v5", :key3=>"v6"},
# {:key1=>"v7", :ky2=>"v8", :key3=>"v9"}]
a.flat_map(&:to_a).each_slice(3).map(&:to_h)
#=> [{:key1=>"v1", :ky2=>"v2", :key3=>"v3"},
#=> {:key1=>"v4", :ky2=>"v5", :key3=>"v6"},
#=> {:key1=>"v7", :ky2=>"v8", :key3=>"v9"}]
Array#to_h was added in v2.1.
a = [
{ :key1=>'v1' }, { :ky2 => 'v2' }, { :key3 => 'v3' },
{ :key1=>'v4' }, { :ky2 => 'v5' }, { :key3 => 'v6' },
{ :key1=>'v7' }, { :ky2 => 'v8' }, { :key3 => 'v9' }
]
a.each_slice(3).map{ |e| e.inject(&:merge) }

What's the best way to replace a string inside a string in ruby?

I have a bunch of these:
'link' => "http://twitter.com/home?status=Check out "{title}" {url}",
And Want to replace the {title} and {url} bits.
I'm currently doing this with gsub:
l.gsub! "{url}", URI::encode(#opts[:url])
l.gsub! "{title}", URI::encode(#opts[:title])
But I have the feeling there's a much better way to do this than with gsub...
#
This is an edit / addition to clarify:
class SocialBookmarkMaker
require 'open-uri'
attr_accessor :opts
def initialize(opts)
#opts = ##default_opts.merge opts
end
##default_opts = {
:icon_folder => "/images/icons/social_aquatic/24 X 24",
:sites => ['facebook', 'twitter', 'delicious', 'digg', 'stumbleupon', 'reddit', 'technorati', ],
:ext => 'png',
:url => 'not provided',
:title => 'not provided',
}
##bookmarks = {
'yahoo' => {
'name' => 'Yahoo! My Web',
'link' => 'http://myweb2.search.yahoo.com/myresults/bookmarklet?u={url}&t={title}',
},
'google' => {
'name' => 'Google Bookmarks',
'link' => 'http://www.google.com/bookmarks/mark?op=edit&bkmk={url}&title={title}',
},
'windows' => {
'name' => 'Windows Live',
'link' => 'https://favorites.live.com/quickadd.aspx?url={url}&title={title}',
},
'facebook' => {
'name' => 'Facebook',
'link' => 'http://www.facebook.com/sharer.php?u={url}&t={title}',
},
'digg' => {
'name' => 'Digg',
'link' => 'http://digg.com/submit?phase=2&url={url}&title={title}',
},
'ask' => {
'name' => 'Ask',
'link' => 'http://myjeeves.ask.com/mysearch/BookmarkIt?v=1.2&t=webpages&url={url}&title={title}',
},
'technorati' => {
'name' => 'Technorati',
'link' => 'http://www.technorati.com/faves?add={url}',
},
'delicious' => {
'name' => 'del.icio.us',
'link' => 'http://del.icio.us/post?url={url}&title={title}',
},
'stumbleupon' => {
'name' => 'StumbleUpon',
'link' => 'http://www.stumbleupon.com/submit?url={url}&title={title}',
},
'squidoo' => {
'name' => 'Squidoo',
'link' => 'http://www.squidoo.com/lensmaster/bookmark?{url}'
},
'netscape' => {
'name' => 'Netscape',
'link' => 'http://www.netscape.com/submit/?U={url}&T={title}',
},
'slashdot' => {
'name' => 'Slashdot',
'link' => 'http://slashdot.org/bookmark.pl?url={url}&title={title}',
},
'reddit' => {
'name' => 'reddit',
'link' => 'http://reddit.com/submit?url={url}&title={title}',
},
'furl' => {
'name' => 'Furl',
'link' => 'http://furl.net/storeIt.jsp?u={url}&t={title}',
},
'blinklist' => {
'name' => 'BlinkList',
'link' => 'http://blinklist.com/index.php?Action=Blink/addblink.php&Url={url}&Title={title}',
},
'dzone' => {
'name' => 'dzone',
'link' => 'http://www.dzone.com/links/add.html?url={url}&title={title}',
},
'swik' => {
'name' => 'SWiK',
'link' => 'http://stories.swik.net/?submitUrl&url={url}'
},
'shoutwire' => {
'name' => 'Shoutwrie',
'link' => 'http://www.shoutwire.com/?p=submit&&link={url}',
},
'blinkbits' => {
'name' => 'Blinkbits',
'link' => 'http://www.blinkbits.com/bookmarklets/save.php?v=1&source_url={url}',
},
'spurl' => {
'name' => 'Spurl',
'link' => 'http://www.spurl.net/spurl.php?url={url}&title={title}',
},
'diigo' => {
'name' => 'Diigo',
'link' => 'http://www.diigo.com/post?url={url}&title={title}',
},
'tailrank' => {
'name' => 'Tailrank',
'link' => 'http://tailrank.com/share/?link_href={url}&title={title}',
},
'rawsugar' => {
'name' => 'Rawsugar',
'link' => 'http://www.rawsugar.com/tagger/?turl={url}&tttl={title}&editorInitialized=1',
},
'twitter' => {
'name' => 'Twitter',
'link' => "http://twitter.com/home?status=Check out "{title}" {url}",
},
}
def self.bookmarks
##bookmarks
end
def icon_loc(site)
"http://common-resources.---.net.s3.amazonaws.com#{#opts[:icon_folder]}/#{site}.#{#opts[:ext]}"
end
def link_url(site)
l = SocialBookmarkMaker.bookmarks[site]['link']
l.gsub! "{url}", URI::encode(#opts[:url])
l.gsub! "{title}", URI::encode(#opts[:title])
l
end
end
shared/social_bookmarks/standard.html.haml
- opts ||= {}
- opts.merge! :url => request.url
- opts.merge! :title => "---.net: #{#layout[:social_bookmark_title] || #layout[:title] || default_view_title}"
- b = SocialBookmarkMaker.new opts
- b.opts[:sites].each do |site|
= link_to(image_tag( b.icon_loc(site) ), b.link_url(site), :title => "Share on #{SocialBookmarkMaker.bookmarks[site]['name']}")
I then call this like this in my rails layout:
render :partial => "shared/social_bookmarks/standard", :locals => { :opts => {:icon_folder => "/images/icons/social_aquatic/48 X 48" }}
Either you change your string to look like
"http://twitter.com/home?status=Check out "%{title}" %{url}"
and then use printf with a Hash
s = "http://twitter.com/home?status=Check out "%{title}" %{url}"
# you can of course use #opts as the Hash here.
s = s % {:title => "abc", :url => "def"} # => "http://twitter.com/home?status=Check out "abc" def"
and accept that it only works with Ruby 1.9.2 and upwards, or you continue using gsub but using the block syntax to condense it:
s.gsub!(/\{(.+?)\}/) do |m|
#opts[$1.to_sym]
end
You can just embed the variables directly in the string
'link' => "http://twitter.com/home?status=Check out "#{title}" #{url}"

Need help with website location identifing

I have a website and I want to make it identify the user's location and according to that move the user to the correct subdomain.
An example:
If I go to the website from France, I want it to redirect me to www.website.com/France
and throw on...
How can I do that please?
At the application server level you can find out which country the user is from by looking it up in a ip-2-country database. They are usually products you buy from a software company specializing in this with different databases for different needs.
Here is one: ip2country
You can also do this on a dns-level if you have a dns provider that can do this for you. This is probably what makes most sense for you. Then your visitors would at once be sent to the nearest server without having to contact a "dispatcher" server first (the dns server would be the router) and after that the correct ip would be cached at some way between the dns server responsible for the domain and dns server along the way all the way to the user.
Here is the solution I'm using on my site [www.vladonai.com][1], it's 100% free (using daily updated [www.zaigadgets.com/geoip][2] source), very fast (possibly much faster than MySQL could do), and requires no database. The database is stored in a binary file, so all what you need is any version of PHP.
The function to convert IP to Country name looks like this:
function GetCountryFromIP($ip = "")
{
if ($ip == "")
$ip = $_SERVER['REMOTE_ADDR'];
//the db obtained from ZaiGadgets.com and converted using convert_ip2country_db_from_csv_to_binary_file_format function
$db_file_path = ip2Country_binary_db_filename;
if (!file_exists($db_file_path))
return "";
$db_file_handle = fopen($db_file_path, "rb");
if (!$db_file_handle)
return "";
$one_record_size = 10; //bytes
$low = 0;
$high = (filesize($db_file_path) / $one_record_size) - 1;
$mid = 0;
$ipFrom = 0;
$ipTo = 0;
$ipArrParts = explode('.', $ip);
$ipLong = ($ipArrParts[0] * 0x1000000) + ($ipArrParts[1] * 0x10000) + ($ipArrParts[2] * 0x100) + ($ipArrParts[3]);
$country = ""; //result
while($low <= $high)
{
$mid = (int)(($low + $high) / 2);
$file_pos = $mid * $one_record_size;
fseek($db_file_handle, $file_pos, SEEK_SET);
$ipFrom = ipdbv2_read32($db_file_handle);
$ipTo = ipdbv2_read32($db_file_handle);
if ($ipFrom < 0)
$ipFrom += pow(2, 32);
if ($ipTo < 0)
$ipTo += pow(2, 32);
if (($ipLong >= $ipFrom) && ($ipLong < $ipTo))
{
//found IP range :)
//echo "Found!!!!!<br>";
$country = fread($db_file_handle, 2);
fclose($db_file_handle);
$country = GetCountryNameFromCountryCode($country);
return $country;
} else
{
if($ipLong <$ipFrom)
{
$high = $mid - 1;
} else
{
$low = $mid + 1;
}
}
}
fclose($db_file_handle);
return "";
}
function ipdbv2_read32($db_file_handle)
{
$data = fread($db_file_handle, 4);
$output = unpack('V', $data);
$val_32_bit = $output[1];
if ($val_32_bit < 0)
$val_32_bit += 4294967296; //correct signed/unsigned issue on 32-bit platforms
return $val_32_bit;
}
Before using the function above you'll need to compile the datbase file using function below:
define( "ip2Country_binary_db_filename", "ip2country_zaigadgets.bin" );
function convert_ip2country_db_from_csv_to_binary_file_format($input_file_path = "")
{
//convert dataf from ZaiGadgets.com to binary db format
if ($input_file_path == "")
$input_file_path = "db.csv";
$output_file_path = ip2Country_binary_db_filename;
$input_file_content = file_get_contents($input_file_path); //read_text_file_content($input_file_path);
if ($input_file_content == "")
{
echo "Error: empty input db - " . $input_file_path . "<br>";
return; //nothing to do
}
unlink($output_file_path); //delete file content
$out_fileHandle = fopen($output_file_path, "cb");
if (!$out_fileHandle)
{
echo "ERROR: Cannot Create file! " . $output_file_path . "<br>";
return;
}
$records_count = 0;
$input_file_lines = explode("\n", $input_file_content); //split it to lines
echo "Text lines count: " . count($input_file_lines) . "<br>";
//for ($input_line_n = 0; $input_line_n < 10; $input_line_n ++)
for ($input_line_n = 0; $input_line_n < count($input_file_lines); $input_line_n ++)
{
$sub_line = $input_file_lines[$input_line_n];
if (strlen($sub_line) > 0 && is_numeric($sub_line[0]))
{
$sub_values = explode(",", $input_file_lines[$input_line_n]);
if (count($sub_values) == 4)
{
$start_ip_addr = $sub_values[0];
$end_ip_addr = $sub_values[1];
$country_code = $sub_values[2];
if (strlen($country_code) == 2)
{
fwrite($out_fileHandle, pack("V", (float)$start_ip_addr), 4);
fwrite($out_fileHandle, pack("V", (float)$end_ip_addr), 4);
fwrite($out_fileHandle, $country_code, strlen($country_code));
$records_count ++;
} else
{
echo "Invalid line " . $input_line_n . " [wrong country len]: " . $sub_line . "<br>";
}
} else
{
echo "Invalid line " . $input_line_n . ": " . $sub_line . "<br>";
}
} else
if ($sub_line != "" && $sub_line[0] != '#' && $sub_line != "startip,endip,countrycode,countryname")
{
echo "Invalid line " . $input_line_n . ": " . $sub_line . "<br>";
}
}
fclose($out_fileHandle);
echo "Data size verification result: " . ($records_count * 10 == filesize($output_file_path) ? "OK" : "Error") . "<br>";
echo "Exported records (blocks) count: " . $records_count . "<br>";
echo "Exporting complete.<br>";
}
Now, if you like it, you can use function below to convert 2-letter country code to readable country name:
function GetCountryNameFromCountryCode($country_code, $b_very_strict = false)
{
$countries = array (
"ac" => "ASCENSION ISLAND",
"ad" => "ANDORRA",
"ae" => "UNITED ARAB EMIRATES",
"af" => "AFGHANISTAN",
"ag" => "ANTIGUA AND BARBUDA",
"ai" => "ANGUILLA",
"al" => "ALBANIA",
"am" => "ARMENIA",
"an" => "NETHERLANDS ANTILLES",
"ao" => "ANGOLA",
"aq" => "ANTARCTICA",
"ar" => "ARGENTINA",
"as" => "AMERICAN SAMOA",
"at" => "AUSTRIA",
"au" => "AUSTRALIA",
"aw" => "ARUBA",
"ax" => "ALAND",
"az" => "AZERBAIJAN",
"ba" => "BOSNIA AND HERZEGOVINA",
"bb" => "BARBADOS",
"bd" => "BANGLADESH",
"be" => "BELGIUM",
"bf" => "BURKINA FASO",
"bg" => "BULGARIA",
"bh" => "BAHRAIN",
"bi" => "BURUNDI",
"bj" => "BENIN",
"bl" => "SAINT BARTHELEMY",
"bm" => "BERMUDA",
"bn" => "BRUNEI DARUSSALAM",
"bo" => "BOLIVIA",
"bu" => "BONAIRE, SAINT EUSTATIUS AND SABA",
"br" => "BRAZIL",
"bs" => "BAHAMAS",
"bt" => "BHUTAN",
"bv" => "BOUVET ISLAND",
"bw" => "BOTSWANA",
"by" => "BELARUS",
"bz" => "BELIZE",
"ca" => "CANADA",
"cc" => "COCOS (KEELING) ISLANDS",
"cd" => "CONGO",
"cf" => "CENTRAL AFRICAN REPUBLIC",
"cg" => "REPUBLIC OF THE CONGO",
"ch" => "SWITZERLAND",
"ci" => "COTE D?VOIRE",
"ck" => "COOK ISLANDS",
"cl" => "CHILE",
"cm" => "CAMEROON",
"cn" => "CHINA",
"co" => "COLOMBIA",
"cr" => "COSTA RICA",
"cu" => "CUBA",
"cv" => "CAPE VERDE",
"cw" => "CURACAO",
"cx" => "CHRISTMAS ISLAND",
"cy" => "CYPRUS",
"cz" => "CZECH REPUBLIC",
"de" => "GERMANY",
"dj" => "DJIBOUTI",
"dk" => "DENMARK",
"dm" => "DOMINICA",
"do" => "DOMINICAN REPUBLIC",
"dz" => "ALGERIA",
"ec" => "ECUADOR",
"ee" => "ESTONIA",
"eg" => "EGYPT",
"eh" => "WESTERN SAHARA",
"er" => "ERITREA",
"eu" => "EUROPEAN UNION",
"es" => "SPAIN",
"et" => "ETHIOPIA",
"fi" => "FINLAND",
"fj" => "FIJI",
"fk" => "FALKLAND ISLANDS",
"fm" => "MICRONESIA",
"fo" => "FAROE ISLANDS",
"fr" => "FRANCE",
"ga" => "GABON",
"gb" => "UNITED KINGDOM",
"gd" => "GRENADA",
"ge" => "GEORGIA",
"gf" => "FRENCH GUIANA",
"gg" => "GUERNSEY",
"gh" => "GHANA",
"gi" => "GIBRALTAR",
"gl" => "GREENLAND",
"gm" => "THE GAMBIA",
"gn" => "GUINEA",
"gp" => "GUADELOUPE",
"gq" => "EQUATORIAL GUINEA",
"gr" => "GREECE",
"gs" => "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS",
"gt" => "GUATEMALA",
"gu" => "GUAM",
"gw" => "GUINEA-BISSAU",
"gy" => "GUYANA",
"hk" => "HONG KONG",
"hn" => "HONDURAS",
"hr" => "CROATIA",
"ht" => "HAITI",
"hu" => "HUNGARY",
"id" => "INDONESIA",
"ie" => "IRELAND",
"il" => "ISRAEL",
"im" => "ISLE OF MAN",
"in" => "INDIA",
"io" => "BRITISH INDIAN OCEAN TERRITORY",
"iq" => "IRAQ",
"ir" => "IRAN",
"is" => "ICELAND",
"it" => "ITALY",
"je" => "JERSEY",
"jm" => "JAMAICA",
"jo" => "JORDAN",
"jp" => "JAPAN",
"ke" => "KENYA",
"kg" => "KYRGYZSTAN",
"kh" => "CAMBODIA",
"ki" => "KIRIBATI",
"km" => "COMOROS",
"kn" => "SAINT KITTS AND NEVIS",
"kp" => "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF",
"kr" => "SOUTH KOREA",
"kw" => "KUWAIT",
"ky" => "CAYMAN ISLANDS",
"kz" => "KAZAKHSTAN",
"la" => "LAOS",
"lb" => "LEBANON",
"lc" => "SAINT LUCIA",
"li" => "LIECHTENSTEIN",
"lk" => "SRI LANKA",
"lr" => "LIBERIA",
"ls" => "LESOTHO",
"lt" => "LITHUANIA",
"lu" => "LUXEMBOURG",
"lv" => "LATVIA",
"ly" => "LIBYA",
"ma" => "MOROCCO",
"mc" => "MONACO",
"md" => "MOLDOVA",
"me" => "MONTENEGRO",
"mf" => "SAINT MARTIN (FRENCH PART)",
"mg" => "MADAGASCAR",
"mh" => "MARSHALL ISLANDS",
"mk" => "REPUBLIC OF MACEDONIA",
"ml" => "MALI",
"mm" => "MYANMAR",
"mn" => "MONGOLIA",
"mo" => "MACAO",
"mp" => "NORTHERN MARIANA ISLANDS",
"mq" => "MARTINIQUE",
"mr" => "MAURITANIA",
"ms" => "MONTSERRAT",
"mt" => "MALTA",
"mu" => "MAURITIUS",
"mv" => "MALDIVES",
"mw" => "MALAWI",
"mx" => "MEXICO",
"my" => "MALAYSIA",
"mz" => "MOZAMBIQUE",
"na" => "NAMIBIA",
"nc" => "NEW CALEDONIA",
"ne" => "NIGER",
"nf" => "NORFOLK ISLAND",
"ng" => "NIGERIA",
"ni" => "NICARAGUA",
"nl" => "NETHERLANDS",
"no" => "NORWAY",
"np" => "NEPAL",
"nr" => "NAURU",
"nu" => "NIUE",
"nz" => "NEW ZEALAND",
"om" => "OMAN",
"pa" => "PANAMA",
"pe" => "PERU",
"pf" => "FRENCH POLYNESIA",
"pg" => "PAPUA NEW GUINEA",
"ph" => "PHILIPPINES",
"pk" => "PAKISTAN",
"pl" => "POLAND",
"pm" => "SAINT PIERRE AND MIQUELON",
"pn" => "PITCAIRN ISLANDS",
"pr" => "PUERTO RICO",
"ps" => "PALESTINIAN TERRITORY, OCCUPIED",
"pt" => "PORTUGAL",
"pw" => "PALAU",
"py" => "PARAGUAY",
"qa" => "QATAR",
"re" => "REUNION",
"ro" => "ROMANIA",
"rs" => "SERBIA",
"ru" => "RUSSIA",
"rw" => "RWANDA",
"sa" => "SAUDI ARABIA",
"sb" => "SOLOMON ISLANDS",
"sc" => "SEYCHELLES",
"sd" => "SUDAN",
"se" => "SWEDEN",
"sg" => "SINGAPORE",
"sh" => "SAINT HELENA",
"si" => "SLOVENIA",
"sj" => "SVALBARD AND JAN MAYEN",
"sk" => "SLOVAKIA",
"sl" => "SIERRA LEONE",
"sm" => "SAN MARINO",
"sn" => "SENEGAL",
"so" => "SOMALIA",
"sr" => "SURINAME",
"st" => "SAO TOME AND PRINCIPE",
"su" => "RUSSIA", //ex-USSR, let's presume it's russia
"sv" => "EL SALVADOR",
"sx" => "SINT MAARTEN (DUTCH PART)",
"sy" => "SYRIA",
"sz" => "SWAZILAN",
"tc" => "TURKS AND CAICOS ISLANDS",
"td" => "CHAD",
"tf" => "FRENCH SOUTHERN TERRITORIES",
"tg" => "TOGO",
"th" => "THAILAND",
"tj" => "TAJIKISTAN",
"tk" => "TOKELAU",
"tl" => "EAST TIMOR",
"tm" => "TURKMENISTAN",
"tn" => "TUNISIA",
"to" => "TONGA",
"tp" => "EAST TIMOR",
"tr" => "TURKEY",
"tt" => "TRINIDAD AND TOBAGO",
//"tv" => "TUVALU", don't include it here - it conflicts with .tv domain!
"tw" => "TAIWAN",
"tz" => "TANZANIA",
"ua" => "UKRAINE",
"ug" => "UGANDA",
"uk" => "UNITED KINGDOM",
"um" => "UNITED STATES MINOR OUTLYING ISLAND",
"us" => "UNITED STATES",
"uy" => "URUGUAY",
"uz" => "UZBEKISTAN",
"va" => "VATICAN CITY STATE",
"vc" => "SAINT VINCENT AND THE GRENADINES",
"ve" => "VENEZUELA",
"vg" => "BRITISH VIRGIN ISLANDS",
"vi" => "U.S. VIRGIN ISLANDS",
"vn" => "VIETNAM",
"vu" => "VANUATU",
"wf" => "WALLIS AND FUTUNA",
"ws" => "SAMOA",
"ye" => "YEMEN",
"yt" => "MAYOTTE",
"yu" => "YUGOSLAVIA",
"za" => "SOUTH AFRICA",
"zm" => "ZAMBIA",
"zw" => "ZIMBABWE"
);
$country = $countries[strtolower($country_code)];
if ($country == "" && !$b_very_strict)
$country = $country_code; //return at least something
return $country;
}
Enjoy!

Resources