package com.edulify.modules.geolocation.providers;
import com.edulify.modules.geolocation.Geolocation;
import com.edulify.modules.geolocation.GeolocationProvider;
import com.fasterxml.jackson.databind.JsonNode;
import play.libs.concurrent.HttpExecution;
import play.libs.ws.WSClient;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.concurrent.CompletionStage;
@Singleton
public class FreegeoipProvider implements GeolocationProvider {
private WSClient ws;
@Inject
public FreegeoipProvider(WSClient ws) {
this.ws = ws;
}
@Override
public CompletionStage<Geolocation> get(String ip) {
String url = String.format("http://freegeoip.net/json/%s", ip);
return ws.url(url)
.get()
.thenApplyAsync(response -> {
if (response.getStatus() != 200) return null;
if (response.getBody().contains("not found")) return null;
return response.asJson();
}, HttpExecution.defaultContext())
.thenApplyAsync(json -> {
if (json == null) return Geolocation.empty();
return asGeolocation(json);
}, HttpExecution.defaultContext());
}
private Geolocation asGeolocation(JsonNode json) {
JsonNode jsonIp = json.get("ip");
JsonNode jsonCountryCode = json.get("country_code");
JsonNode jsonCountryName = json.get("country_name");
JsonNode jsonRegionCode = json.get("region_code");
JsonNode jsonRegionName = json.get("region_name");
JsonNode jsonCity = json.get("city");
JsonNode jsonLatitude = json.get("latitude");
JsonNode jsonLongitude = json.get("longitude");
JsonNode jsonTimeZone = json.get("time_zone");
if (jsonIp == null ||
jsonCountryCode == null ||
jsonCountryName == null ||
jsonRegionCode == null ||
jsonRegionName == null ||
jsonCity == null ||
jsonLatitude == null ||
jsonLongitude == null ||
jsonTimeZone == null) {
return Geolocation.empty();
}
return new Geolocation(
jsonIp.asText(),
jsonCountryCode.asText(),
jsonCountryName.asText(),
jsonRegionCode.asText(),
jsonRegionName.asText(),
jsonCity.asText(),
jsonLatitude.asDouble(),
jsonLongitude.asDouble(),
jsonTimeZone.asText()
);
}
}