/* * Copyright 2015. Appsi Mobile * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.appsimobile.appsii.module.weather.loader; import android.support.annotation.Nullable; import android.support.v4.util.CircularArray; import android.text.TextUtils; import android.text.format.Time; import android.util.Log; import com.appsimobile.appsii.BuildConfig; import com.appsimobile.appsii.ResponseParserException; import com.appsimobile.appsii.SimpleJson; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; /** * Created by nick on 21/01/15. */ public class WeatherDataParser { public static void parseWeatherData(CircularArray<WeatherData> result, InputStream inputStream, CircularArray<String> woeids) throws JSONException, ResponseParserException, ParseException, IOException { String json = readStreamToString(inputStream, new StringBuilder()); if (BuildConfig.DEBUG) Log.d("WeatherDataParser", "json: " + json); parseWeatherData(result, json, woeids); } private static String readStreamToString(InputStream in, StringBuilder stringBuilder) throws IOException { stringBuilder.setLength(0); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line).append("\n"); } return stringBuilder.toString(); } public static void parseWeatherData(CircularArray<WeatherData> result, String jsonString, CircularArray<String> woeids) throws JSONException, ResponseParserException, ParseException { if (woeids.isEmpty()) return; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMM yyyy", Locale.US); simpleDateFormat.setTimeZone(TimeZone.getTimeZone(Time.TIMEZONE_UTC)); SimpleJson json = new SimpleJson(jsonString); // when only a single woeid was requested, this is an object, otherwise it is an array. // So we need to check if we got an array; if so, handle each of the objects. // Otherwise get it as an object JSONArray resultsArray = json.getJsonArray("query.results.channel"); if (resultsArray == null) { JSONObject weatherObject = json.optJsonObject("query.results.channel"); if (weatherObject == null) return; String woeid = woeids.get(0); WeatherData weatherData = parseWeatherData(woeid, simpleDateFormat, weatherObject); if (weatherData != null) { result.addLast(weatherData); } return; } int length = resultsArray.length(); for (int i = 0; i < length; i++) { JSONObject weatherJson = resultsArray.getJSONObject(i); WeatherData weatherData = parseWeatherData(woeids.get(i), simpleDateFormat, weatherJson); if (weatherData == null) continue; result.addLast(weatherData); } } @Nullable private static WeatherData parseWeatherData(String woeid, SimpleDateFormat simpleDateFormat, JSONObject weatherJsonObj) throws ResponseParserException, JSONException, ParseException { SimpleJson weatherJson = new SimpleJson(weatherJsonObj); String city = weatherJson.optString("location.city"); if (city == null) { String country = weatherJson.optString("location.country"); String region = weatherJson.optString("location.region"); if (country != null && region != null) { city = TextUtils.join(", ", new String[]{country, region}); } else if (country != null) { city = country; } } if (city == null) { Log.w("WeatherDataParser", "Error in weather-query. Ignoring location"); return null; } WeatherData weatherData = new WeatherData(); weatherData.location = city; weatherData.windChill = weatherJson.getInt("wind.chill", Integer.MIN_VALUE); weatherData.windDirection = weatherJson.getInt("wind.direction", Integer.MIN_VALUE); weatherData.windSpeed = (float) weatherJson.getDouble("wind.speed", Float.MIN_VALUE); weatherData.atmosphereHumidity = weatherJson.getInt("atmosphere.humidity", Integer.MIN_VALUE); weatherData.atmospherePressure = (float) weatherJson.getDouble("atmosphere.pressure", Float.MIN_VALUE); weatherData.atmosphereRising = weatherJson.getInt("atmosphere.rising", Integer.MIN_VALUE); weatherData.atmosphereVisible = (float) weatherJson.getDouble("atmosphere.visibility", Float.MIN_VALUE); weatherData.sunrise = weatherJson.optString("astronomy.sunrise"); weatherData.sunset = weatherJson.optString("astronomy.sunset"); weatherData.nowConditionCode = weatherJson.getInt("item.condition.code", WeatherData.INVALID_CONDITION); weatherData.nowConditionText = weatherJson.optString("item.condition.text"); weatherData.nowTemperature = weatherJson.getInt("item.condition.temp", WeatherData.INVALID_TEMPERATURE); JSONArray forecastArray = weatherJson.optJsonArray("item.forecast"); if (forecastArray != null) { int fl = forecastArray.length(); for (int k = 0; k < fl; k++) { JSONObject forecastJson = forecastArray.getJSONObject(k); WeatherData.Forecast forecast = new WeatherData.Forecast(); String date = forecastJson.optString("date"); long millis = simpleDateFormat.parse(date).getTime(); forecast.julianDay = Time.getJulianDay(millis, 0); forecast.conditionCode = forecastJson.optInt("code", WeatherData.INVALID_CONDITION); forecast.forecastText = forecastJson.optString("text"); forecast.low = forecastJson.optInt("low", WeatherData.INVALID_TEMPERATURE); forecast.high = forecastJson.optInt("high", WeatherData.INVALID_TEMPERATURE); weatherData.forecasts.add(forecast); } } weatherData.woeid = woeid; return weatherData; } }