package ru.gelin.android.weather.openweathermap;
import android.content.Context;
import org.apache.http.client.methods.HttpGet;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import ru.gelin.android.weather.*;
import ru.gelin.android.weather.source.DebugDumper;
import ru.gelin.android.weather.source.HttpWeatherSource;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;
/**
* Weather source implementation which uses openweathermap.org
*/
public class OpenWeatherMapSource extends HttpWeatherSource implements WeatherSource {
/** Base API URL */
static final String API_BASE_URL = "http://openweathermap.org/data/2.5";
/** Current weather API URL */
static final String API_WEATHER_URL = API_BASE_URL + "/weather?";
/** Forecasts API URL */
static final String API_FORECAST_URL = API_BASE_URL + "/forecast/daily?cnt=4&id=";
/** API key */
static final String API_KEY = "616a1aaacb2a1e3e3ca80c8e78455f76";
private final Context context;
private final DebugDumper debugDumper;
public OpenWeatherMapSource(Context context) {
this.context = context;
this.debugDumper = new DebugDumper(context, API_BASE_URL);
}
@Override
public Weather query(Location location) throws WeatherException {
if (location == null) {
throw new WeatherException("null location");
}
if (location.getText().startsWith("-")) {
return new TestWeather(Integer.parseInt(location.getText()));
}
if (location.getText().startsWith("+")) {
return new TestWeather(Integer.parseInt(location.getText().substring(1)));
}
OpenWeatherMapWeather weather = new OpenWeatherMapWeather(this.context);
weather.parseCurrentWeather(queryCurrentWeather(location));
if (weather.isEmpty()) {
return weather;
}
weather.parseDailyForecast(queryDailyForecast(weather.getCityId()));
return weather;
}
@Override
public Weather query(Location location, Locale locale) throws WeatherException {
return query(location);
//TODO: what to do with locale?
}
@Override
protected void prepareRequest(HttpGet request) {
request.addHeader("X-API-Key", API_KEY);
}
JSONObject queryCurrentWeather(Location location) throws WeatherException {
String url = API_WEATHER_URL + location.getQuery();
JSONTokener parser = new JSONTokener(readJSON(url));
try {
return (JSONObject)parser.nextValue();
} catch (JSONException e) {
throw new WeatherException("can't parse weather", e);
}
}
JSONObject queryDailyForecast(int cityId) throws WeatherException {
String url = API_FORECAST_URL + String.valueOf(cityId);
JSONTokener parser = new JSONTokener(readJSON(url));
try {
return (JSONObject)parser.nextValue();
} catch (JSONException e) {
throw new WeatherException("can't parse forecast", e);
}
}
String readJSON(String url) throws WeatherException {
StringBuilder result = new StringBuilder();
InputStreamReader reader = getReaderForURL(url);
char[] buf = new char[1024];
try {
int read = reader.read(buf);
while (read >= 0) {
result.append(buf, 0 , read);
read = reader.read(buf);
}
} catch (IOException e) {
throw new WeatherException("can't read weather", e);
}
String content = result.toString();
this.debugDumper.dump(url, content);
return content;
}
}