Need help with website location identifing - location

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!

Related

Logstash-extract multiple subfield values in multiple events

I have below type of events. I'm trying to split field's key, value as new event.
I'm able to do it for two fields(TOTAl_VOLUME, SUCCESS_VOLUME), but when I try for 3rd field, logstash stop responding.(Split doesn't work for more than 2 fields).
{
"agentId" => "Log_Agent",
"#metadata" => {
"A1EvtFingerprint" => "AGENTID=Log_Agent&TIME=1657708200000&RESPTYPE=DC",
"indexname" => "heal_collated_agent_txn",
"tablename" => "agent_transactions_data",
"accountid" => "mle_account",
"enable_rubydebug" => "true"
},
"total" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588
},
"success" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588
},
"max_response" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.011000156402588
},
"response_type" => "DC",
"aggLevelInMins" => 15,
"timeInGMT" => 1657708200000,
"avg_response" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 4.5954742431640625,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 4.6110687255859375,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 4.580192565917969
},
"timeout" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 777,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 839,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 781
},
"unknown" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 773,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 794,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 746
},
"fail" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 770,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 737,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 800
},
"#timestamp" => 2022-07-13T10:30:00.000Z,
"slow" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 782,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 788,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 744
},
"min_response" => {
"GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.0,
"GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.0,
"GET#/txn/branchserver23.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12" => 5.0
},
"#version" => "1"
}
Desired output should be(Splitted multiple field value into multiple events)
{
"txnId" : "GET#/txn/branchserver50.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12",
"timeInGMT" : 1657048320000,
"dcKpis" : {
"UNKNOWN_VOLUME" : 773,
"TIMEOUT_VOLUME" : 777,
"FAIL_VOLUME" : 770,
"MIN_RESPONSE_TIME" : 50,
"TOTAL_VOLUME" : 5.011000156402588,
"AVG_RESPONSE_TIME" : 4.5954742431640625,
"MAX_RESPONSE_TIME" : 5.011000156402588,
"SUCCESS_VOLUME" : 5.011000156402588,
"SLOW_VOLUME" : 782
}
},
{
"txnId" : "GET#/txn/branchserver51.aspx|srv=73689505-0ca6-48fe-a4da-4cf7ed4acd82|acc=12",
"timeInGMT" : 1657048320000,
"dcKpis" : {
"UNKNOWN_VOLUME" : 794,
"TIMEOUT_VOLUME" : 839,
"FAIL_VOLUME" : 737,
"MIN_RESPONSE_TIME" : 5.0,
"TOTAL_VOLUME" : 5.011000156402588,
"AVG_RESPONSE_TIME" : 4.6110687255859375,
"MAX_RESPONSE_TIME" : 5.011000156402588,
"SUCCESS_VOLUME" : 5.011000156402588,
"SLOW_VOLUME" : 788
}
}
Following is my pipeline:
ruby {
code => '
values = event.get("total")
if values.is_a? Hash
someField1 = []
values.each { |k, v|
someField1 << { "txnId1" => k, "total" => v }
}
event.set("someField1", someField1)
end
event.remove("total")
'
}
ruby {
code => '
values = event.get("success")
if values.is_a? Hash
someField2 = []
values.each { |k, v|
someField2 << { "txnId2" => k, "success" => v }
}
event.set("someField2", someField2)
end
event.remove("success")
'
}
split {
field => 'someField1'
}
split {
field => 'someField2'
}
mutate {
rename => {
"[someField1][txnId1]" => "[#metadata][txnId1]"
"[someField1][total]" => "[dcKpis][TOTAl_VOLUME]"
"[someField2][txnId2]" => "[#metadata][txnId2]"
"[someField2][success]" => "[dcKpis][SUCCESS_VOLUME]"
}
remove_field => ["someField1","someField2","someField3","someField4","someField5","someField6","someField7","someField8","someField9"]
}

Parsing Hash in Ruby

Bit lost while parsing the hash, actually i want to retrieve the id for "HTTP get traffic" which is in this case 9.? can anyone help?
gettest = {
"Groups" => [
{
"GroupName" => {"TextId" => "Hardware"},
"Tests" => [
{"Description"=>{"TextId"=>"ODU current measurement"}, "Id" => 0}
]
},
{
"GroupName"=>{"TextId"=>"LAN"},
"Tests" => [
{"Description" => {"TextId" => "Ethernet status"}, "Id" => 2},
{"Description" => {"TextId" => "Number of TCP Sessions"}, "Id" => 3}
]
},
{
"GroupName" => {"TextId" => "Satellite connection"},
"Tests" => [
{"Description" => {"TextId" => "Physical layer status"}, "Id" => 4},
{"Description" => {"TextId" => "Data link layer status"}, "Id" => 5},
{"Description" => {"TextId" => "Network layer status"}, "Id" => 6}
]
},
{
"GroupName" => {"TextId" => "Software"},
"Tests" => [
{"Description" => {"TextId" => "Software"}, "Id" => 1}
]
},
{
"GroupName" => {"TextId" => "Traffic"},
"Tests" => [
{"Description" => {"TextId" => "Ping traffic"}, "Id" => 7},
{"Description" => {"TextId" => "DNS traffic"}, "Id" => 8},
{"Description" => {"TextId" => "HTTP get traffic"}, "Id" => 9}
]
}
]
}
anything like this?
traffic_group = gettest['Groups'].find do |group|
group['GroupName']['TextId'] == 'Traffic'
end
if traffic_group
http_get_traffic = traffic_group['Tests'].find do |test|
test['Description']['TextId'] == 'HTTP get traffic'
end
if http_get_traffic
http_get_traffic_id = http_get_traffic['Id']
puts "HTTP get traffic id: #{http_get_traffic_id}"
else
puts 'no http get traffic node found'
end
else
puts 'no traffic group found'
end

How to add custom shipment CS-Cart

I need to add dynamic shipment option to the checkout page, the shipment's pricing, duration and name come from other API.
I tried these hook, none of these invoked during checkout.
'get_available_shippings',
'get_shipping_methods',
'get_shipping_methods_post',
'get_shipments_info_post'
tried to hook shipping_methods_list.pre.tpl
{assign var="s" value=$all_shippings[0][1]}
{$s["shipping_id"] = '2'}
{$all_shippings[0][2] = $s}
I'm using cs-cart 4.14
The right hook was shippings_get_shippings_list_post, since it's not adding to the database, it seems you need to hook orders:shipping_info on the backend for further customization.
function fn_example_addons_shippings_get_shippings_list_post(&$group, &$lang, &$area, &$shippings_info)
{
$package_info = $group['package_info'];
$fromZipcode = $package_info['origination']['zipcode'];
$toZipcode = $package_info['location']['zipcode'];
$weight = (int)round(ceil($package_info["W"]));
$item_price = (int)round(ceil($package_info["C"]));
$shipments = fn_example_addons_getRates($fromZipcode, $toZipcode, $weight, $item_price);
foreach ($shipments as $key => $shipment) {
$shippings_info[$key] = $shipment;
}
}
for the shipments
$shipments["SHIPMENT_ID"] = array(
"shipping_id" => "SHIPMENT_ID",
"shipping" => "Example Shipment"
"delivery_time" => "2-3 days",
"description" => "",
"rate_calculation" => "M",
"service_params" => array(),
"destination" => "I",
"min_weight" => "0.0",
"max_weight" => "0.0",
"service_id" => "0",
"free_shipping" => "N",
"module" => null,
"service_code" => null,
"is_address_required" => "Y",
"rate_info" => array(
"rate_id" => "0",
"shipping_id" => "0",
"rate_value" => array(
"C" => array(
array(
"range_from_value" => 0,
"range_to_value" => "",
"value" => $price_in_point
)
)
),
"destination_id" => "1",
"base_rate" => "0.0"
),
"disable_payments_ids" => array()
);

Pushing objects into a hash inside a loop

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

Delete an element from a hash based on a condition

I have these parameters:
Parameters: {transactions"=>{
"2"=>{"amount"=>"10", "finance_id"=>"4", "payee_id"=>"5", "category_id"=>"14", "payee_type"=>"Student", "transaction_date"=>"2015-08-10", "title"=>"Receipt No.. (Multiple Fees) F4", "finance_type"=>"FinanceFee", "payment_mode"=>"Cash", "payment_note"=>""},
"1"=>{"amount"=>"10", "finance_id"=>"4", "payee_id"=>"2", "category_id"=>"14", "payee_type"=>"Student", "transaction_date"=>"2015-08-10", "title"=>"Receipt No.. (Multiple Fees) F4", "finance_type"=>"FinanceFee", "payment_mode"=>"Cash", "payment_note"=>""}
}}
I need to set a condition to delete the transaction with amount = 0.I tried this:
params[:transactions].each do |trans|
trans.delete_if {|amount, value| value == 0 || value.nil? || value.empty?}
end
but this doesn't delet the transaction with amount 0.
Just try this
transactions = {
"transactions" =>
{
"2" => {
"amount" => "10",
"finance_id" => "4",
"payee_id" => "5",
"category_id" => "14",
"payee_type" => "Student",
"transaction_date" => "2015-08-10",
"title" => "Receipt No.. (Multiple Fees) F4",
"finance_type" => "FinanceFee",
"payment_mode" => "Cash",
"payment_note" => ""
},
"1" => {
"amount" => "10",
"finance_id" => "4",
"payee_id" => "2",
"category_id" => "14",
"payee_type" => "Student",
"transaction_date" => "2015-08-10",
"title" => "Receipt No.. (Multiple Fees) F4",
"finance_type" => "FinanceFee",
"payment_mode" => "Cash",
"payment_note" => ""
},
"3" => {
"amount" => "0",
"finance_id" => "4",
"payee_id" => "2",
"category_id" => "14",
"payee_type" => "Student",
"transaction_date" => "2015-08-10",
"title" => "Receipt No.. (Multiple Fees) F4",
"finance_type" => "FinanceFee",
"payment_mode" => "Cash",
"payment_note" => ""
},
"4" => {
"amount" => nil,
"finance_id" => "4",
"payee_id" => "2",
"category_id" => "14",
"payee_type" => "Student",
"transaction_date" => "2015-08-10",
"title" => "Receipt No.. (Multiple Fees) F4",
"finance_type" => "FinanceFee",
"payment_mode" => "Cash",
"payment_note" => ""
},
"4" => {
"amount" => "",
"finance_id" => "4",
"payee_id" => "2",
"category_id" => "14",
"payee_type" => "Student",
"transaction_date" => "2015-08-10",
"title" => "Receipt No.. (Multiple Fees) F4",
"finance_type" => "FinanceFee",
"payment_mode" => "Cash",
"payment_note" => ""
}
}
}
transactions["transactions"].delete_if{|_, v| v["amount"].to_s.strip.to_i == 0}
Your value is an string convert this to integer
value.to_i == 0
or
value == 0.to_s
or
value.to_i.zero?

Resources