You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
13 KiB

11 years ago
package org.telegram.services;
11 years ago
import org.apache.http.HttpEntity;
11 years ago
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
11 years ago
import org.apache.http.client.methods.CloseableHttpResponse;
11 years ago
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
11 years ago
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
11 years ago
import org.apache.http.impl.client.HttpClientBuilder;
11 years ago
import org.apache.http.util.EntityUtils;
11 years ago
import org.json.JSONObject;
import org.telegram.BuildVars;
import org.telegram.database.DatabaseManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Weather service
* @date 20 of June of 2015
*/
public class WeatherService {
11 years ago
private static volatile BotLogger log = BotLogger.getLogger(WeatherService.class.getName());
11 years ago
private static final String BASEURL = "http://api.openweathermap.org/data/2.5/"; ///< Base url for REST
private static final String FORECASTPATH = "forecast/daily";
private static final String CURRENTPATH = "weather";
private static final String APIIDEND = "&APPID=" + BuildVars.OPENWEATHERAPIKEY;
11 years ago
private static final String FORECASTPARAMS = "&cnt=3&units=metric&lang=@language@";
private static final String CURRENTPARAMS = "&cnt=1&units=metric&lang=@language@";
11 years ago
private static final DateTimeFormatter dateFormaterFromDate = DateTimeFormatter.ofPattern("dd/MM/yyyy"); ///< Date to text formater
private static volatile WeatherService instance; ///< Instance of this class
/**
* Constructor (private due to singleton pattern)
*/
private WeatherService() {
}
/**
* Singleton
*
* @return Return the instance of this class
*/
public static WeatherService getInstance() {
WeatherService currentInstance;
if (instance == null) {
synchronized (WeatherService.class) {
if (instance == null) {
instance = new WeatherService();
}
currentInstance = instance;
}
} else {
currentInstance = instance;
}
return currentInstance;
}
/**
* Fetch the weather of a city
*
* @param city City to get the weather
* @return userHash to be send to use
* @note Forecast for the following 3 days
*/
11 years ago
public String fetchWeatherForecast(String city, Integer userId, String language) {
11 years ago
String cityFound;
String responseToUser;
try {
11 years ago
String completURL = BASEURL + FORECASTPATH + "?" + getCityQuery(city) +
FORECASTPARAMS.replace("@language@", language) + APIIDEND;
11 years ago
CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
11 years ago
HttpGet request = new HttpGet(completURL);
11 years ago
CloseableHttpResponse response = client.execute(request);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
String responseString = EntityUtils.toString(buf, "UTF-8");
11 years ago
JSONObject jsonObject = new JSONObject(responseString);
11 years ago
log.warning(jsonObject.toString());
11 years ago
if (jsonObject.getInt("cod") == 200) {
cityFound = jsonObject.getJSONObject("city").getString("name") + " (" +
jsonObject.getJSONObject("city").getString("country") + ")";
saveRecentWeather(userId, cityFound, jsonObject.getJSONObject("city").getInt("id"));
11 years ago
responseToUser = String.format(LocalisationService.getInstance().getString("weatherForcast", language),
cityFound, convertListOfForecastToString(jsonObject, language));
11 years ago
} else {
11 years ago
log.warning(jsonObject.toString());
11 years ago
responseToUser = LocalisationService.getInstance().getString("cityNotFound", language);
11 years ago
}
11 years ago
} catch (Exception e) {
11 years ago
log.error(e);
11 years ago
responseToUser = LocalisationService.getInstance().getString("errorFetchingWeather", language);
11 years ago
}
return responseToUser;
}
/**
* Fetch the weather of a city
*
* @return userHash to be send to use
* @note Forecast for the following 3 days
*/
11 years ago
public String fetchWeatherForecastByLocation(Double longitude, Double latitude, Integer userId, String language) {
11 years ago
String cityFound;
String responseToUser;
try {
11 years ago
String completURL = BASEURL + FORECASTPATH + "?lat=" + URLEncoder.encode(latitude + "", "UTF-8") + "&lon="
+ URLEncoder.encode(longitude + "", "UTF-8") + FORECASTPARAMS.replace("@language@", language) + APIIDEND;;
11 years ago
CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
11 years ago
HttpGet request = new HttpGet(completURL);
11 years ago
CloseableHttpResponse response = client.execute(request);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
String responseString = EntityUtils.toString(buf, "UTF-8");
11 years ago
JSONObject jsonObject = new JSONObject(responseString);
if (jsonObject.getInt("cod") == 200) {
cityFound = jsonObject.getJSONObject("city").getString("name") + " (" +
jsonObject.getJSONObject("city").getString("country") + ")";
saveRecentWeather(userId, cityFound, jsonObject.getJSONObject("city").getInt("id"));
11 years ago
responseToUser = String.format(LocalisationService.getInstance().getString("weatherForcast", language),
cityFound, convertListOfForecastToString(jsonObject, language));
11 years ago
} else {
11 years ago
log.warning(jsonObject.toString());
11 years ago
responseToUser = LocalisationService.getInstance().getString("cityNotFound", language);
11 years ago
}
11 years ago
} catch (Exception e) {
11 years ago
log.error(e);
11 years ago
responseToUser = LocalisationService.getInstance().getString("errorFetchingWeather", language);
11 years ago
}
return responseToUser;
}
/**
* Fetch the weather of a city
*
* @param city City to get the weather
* @return userHash to be send to use
* @note Forecast for the following 3 days
*/
11 years ago
public String fetchWeatherCurrent(String city, Integer userId, String language) {
11 years ago
String cityFound;
String responseToUser;
try {
11 years ago
String completURL = BASEURL + CURRENTPATH + "?" + getCityQuery(city) +
CURRENTPARAMS.replace("@language@", language) + APIIDEND;
11 years ago
CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
11 years ago
HttpGet request = new HttpGet(completURL);
11 years ago
CloseableHttpResponse response = client.execute(request);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
String responseString = EntityUtils.toString(buf, "UTF-8");
11 years ago
JSONObject jsonObject = new JSONObject(responseString);
if (jsonObject.getInt("cod") == 200) {
cityFound = jsonObject.getString("name") + " (" +
jsonObject.getJSONObject("sys").getString("country") + ")";
saveRecentWeather(userId, cityFound, jsonObject.getInt("id"));
11 years ago
responseToUser = String.format(LocalisationService.getInstance().getString("weatherCurrent", language),
cityFound, convertCurrentWeatherToString(jsonObject, language));
11 years ago
} else {
11 years ago
log.warning(jsonObject.toString());
11 years ago
responseToUser = LocalisationService.getInstance().getString("cityNotFound", language);
11 years ago
}
11 years ago
} catch (Exception e) {
11 years ago
log.error(e);
11 years ago
responseToUser = LocalisationService.getInstance().getString("errorFetchingWeather", language);
11 years ago
}
return responseToUser;
}
/**
* Fetch the weather of a city
*
* @return userHash to be send to use
* @note Forecast for the following 3 days
*/
11 years ago
public String fetchWeatherCurrentByLocation(Double longitude, Double latitude, Integer userId, String language) {
11 years ago
String cityFound;
String responseToUser;
try {
11 years ago
String completURL = BASEURL + CURRENTPATH + "?q=" + URLEncoder.encode("lat=" + latitude + "&lon=" +
longitude, "UTF-8") + CURRENTPARAMS.replace("@language@", language) + APIIDEND;;
11 years ago
CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
11 years ago
HttpGet request = new HttpGet(completURL);
11 years ago
CloseableHttpResponse response = client.execute(request);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
String responseString = EntityUtils.toString(buf, "UTF-8");
11 years ago
JSONObject jsonObject = new JSONObject(responseString);
if (jsonObject.getInt("cod") == 200) {
cityFound = jsonObject.getString("name") + " (" +
jsonObject.getJSONObject("sys").getString("country") + ")";
saveRecentWeather(userId, cityFound, jsonObject.getInt("id"));
11 years ago
responseToUser = String.format(LocalisationService.getInstance().getString("weatherCurrent", language),
cityFound, convertCurrentWeatherToString(jsonObject, language));
11 years ago
} else {
11 years ago
log.warning(jsonObject.toString());
11 years ago
responseToUser = LocalisationService.getInstance().getString("cityNotFound", language);
11 years ago
}
11 years ago
} catch (Exception e) {
11 years ago
log.error(e);
11 years ago
responseToUser = LocalisationService.getInstance().getString("errorFetchingWeather", language);
11 years ago
}
return responseToUser;
}
11 years ago
private String convertCurrentWeatherToString(JSONObject jsonObject, String language) {
11 years ago
String temp = jsonObject.getJSONObject("main").getDouble("temp")+"";
String cloudiness = jsonObject.getJSONObject("clouds").getInt("all") + "%";
String weatherDesc = jsonObject.getJSONArray("weather").getJSONObject(0).getString("description");
11 years ago
String responseToUser = LocalisationService.getInstance().getString("currentWeatherPart", language);
responseToUser = String.format(responseToUser, weatherDesc, cloudiness, temp);
11 years ago
return responseToUser;
}
/**
* Convert a list of weather forcast to a list of strings to be sent
*
* @param jsonObject JSONObject contining the list
* @return String to be sent to the user
*/
11 years ago
private String convertListOfForecastToString(JSONObject jsonObject, String language) {
11 years ago
String responseToUser = "";
for (int i = 0; i < jsonObject.getJSONArray("list").length(); i++) {
JSONObject internalJSON = jsonObject.getJSONArray("list").getJSONObject(i);
11 years ago
responseToUser += convertInternalInformationToString(internalJSON, language);
11 years ago
}
return responseToUser;
}
/**
* Convert internal part of then answer to string
*
* @param internalJSON JSONObject containing the part to convert
* @return String to be sent to the user
*/
11 years ago
private String convertInternalInformationToString(JSONObject internalJSON, String language) {
11 years ago
String responseToUser = "";
LocalDate date;
String tempMax;
String tempMin;
String weatherDesc;
date = Instant.ofEpochSecond(internalJSON.getLong("dt")).atZone(ZoneId.systemDefault()).toLocalDate();
tempMax = internalJSON.getJSONObject("temp").getDouble("max") + "";
tempMin = internalJSON.getJSONObject("temp").getDouble("min") + "";
JSONObject weatherObject = internalJSON.getJSONArray("weather").getJSONObject(0);
weatherDesc = weatherObject.getString("description");
11 years ago
responseToUser = LocalisationService.getInstance().getString("forecastWeatherPart", language);
responseToUser = String.format(responseToUser, dateFormaterFromDate.format(date), weatherDesc,
tempMax, tempMin);
11 years ago
return responseToUser;
}
private void saveRecentWeather(Integer userId, String cityName, int cityId) {
DatabaseManager.getInstance().addRecentWeather(userId, cityId, cityName);
}
private String getCityQuery(String city) throws UnsupportedEncodingException {
String cityQuery = "";
try {
cityQuery += "id=" + URLEncoder.encode(Integer.parseInt(city)+"", "UTF-8");
} catch(NumberFormatException | NullPointerException e) {
cityQuery += "q=" + URLEncoder.encode(city, "UTF-8");
}
return cityQuery;
}
}