package eirb.pg203; import org.json.JSONArray; import org.json.JSONObject; import eirb.pg203.WeatherData.Condition; import eirb.pg203.utils.JSONFetcher; import java.io.IOException; import java.net.URI; import java.net.URL; import java.time.Instant; import java.util.ArrayList; /** * WeatherAPI implementation */ public class WeatherAPI extends WeatherCachedAPI { private final String weatherAPIKey; private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json"; WeatherAPI(String weatherAPIKey) { this.weatherAPIKey = weatherAPIKey; } private JSONObject fetchWeather(int days, String city) throws IOException { URL url = URI.create( String.format(forecastBaseURL + "?key=%s&q=%s&days=%d", this.weatherAPIKey, city, days ) ).toURL(); return JSONFetcher.fetch(url); } private static WeatherData.Condition getConditionFromString(String str) { if (str.toLowerCase().contains("rain")) return Condition.RAINY; else if (str.toLowerCase().contains("partly")) return Condition.PARTIAL; else if (str.toLowerCase().contains("cloud")) return Condition.CLOUDY; return Condition.SUNNY; } private static WeatherData getWeatherDataFromForecast(JSONObject response, int day, String city) { JSONObject forecastDay = response.getJSONObject("forecast").getJSONArray("forecastday").getJSONObject(day); JSONArray forecastHour = forecastDay.getJSONArray("hour"); float temp_c = forecastDay.getJSONObject("day").getFloat("avgtemp_c"); // Calculates the mean for the day float windSpeed = 0; float windDirection = 0; for (int i = 0 ; i < forecastHour.length() ; ++i) { windSpeed += forecastHour.getJSONObject(i).getFloat("wind_kph"); windDirection += forecastHour.getJSONObject(i).getFloat("wind_degree"); } windSpeed /= forecastHour.length(); windDirection /= forecastHour.length(); String conditionStr = forecastDay.getJSONObject("day").getJSONObject("condition").getString("text"); return new WeatherData( new City(city), Instant.now(), temp_c, windSpeed, windDirection, getConditionFromString(conditionStr) ); } /** * @param day Day, 0 ≤ day ≤ 14 */ @Override public WeatherData getTemperature(int day, String cityName) throws IOException { JSONObject result = fetchWeather(day+1, cityName); return getWeatherDataFromForecast(result, day, cityName); } @Override public WeatherData getTemperature(int day, int hour, String cityName) throws IOException{ return getTemperature(day, cityName); } public ArrayList fetchTemperatures(int days, String cityName) throws IOException { JSONObject result = fetchWeather(days, cityName); ArrayList weatherDatas = new ArrayList<>(); for (int day = 0; day < days; ++day) { weatherDatas.add( getWeatherDataFromForecast(result, day, cityName) ); } return weatherDatas; } @Override public String getAPIName() { return "WeatherAPI"; } }