Fix open-meteo response decompression fails if downloading through iOS companion app (#114)

* Remove open-meteo gzip handling

* Fix copypaste error message

* Update release notes

* Update app/src/main/kotlin/de/timklge/karooheadwind/weatherprovider/openmeteo/OpenMeteoWeatherProvider.kt

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
timklge 2025-05-03 16:51:50 +02:00 committed by GitHub
parent c8bf0c80fa
commit 94f87ed747
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 8 additions and 27 deletions

View File

@ -93,10 +93,10 @@ tasks.register("generateManifest") {
"latestVersionCode" to android.defaultConfig.versionCode, "latestVersionCode" to android.defaultConfig.versionCode,
"developer" to "github.com/timklge", "developer" to "github.com/timklge",
"description" to "Open-source extension that provides headwind direction, wind speed, forecast and other weather data fields.", "description" to "Open-source extension that provides headwind direction, wind speed, forecast and other weather data fields.",
"releaseNotes" to "* Add relative grade, relative elevation gain data fields\n" + "releaseNotes" to "* Fix weather data download from Open-Meteo via iOS companion app (thx @keefar!)\n" +
"* Add relative grade, relative elevation gain data fields\n" +
"* Fix precipitation forecast field\n" + "* Fix precipitation forecast field\n" +
"* Interpolate between forecasted and current weather data\n" + "* Interpolate between forecasted and current weather data\n" +
"* Colorize field background instead of text\n" +
"* Add OpenWeatherMap support contributed by lockevod\n", "* Add OpenWeatherMap support contributed by lockevod\n",
"screenshotUrls" to listOf( "screenshotUrls" to listOf(
"https://github.com/timklge/karoo-headwind/releases/latest/download/preview1.png", "https://github.com/timklge/karoo-headwind/releases/latest/download/preview1.png",

View File

@ -1,19 +0,0 @@
package de.timklge.karooheadwind.util
import io.hammerhead.karooext.models.HttpResponseState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.zip.GZIPInputStream
suspend fun ungzip(response: HttpResponseState.Complete): String {
val inputStream = java.io.ByteArrayInputStream(response.body ?: ByteArray(0))
val lowercaseHeaders = response.headers.map { (k: String, v: String) -> k.lowercase() to v.lowercase() }.toMap()
val isGzippedResponse = lowercaseHeaders["content-encoding"]?.contains("gzip") == true
return if(isGzippedResponse){
val gzipStream = withContext(Dispatchers.IO) { GZIPInputStream(inputStream) }
gzipStream.use { stream -> String(stream.readBytes()) }
} else {
inputStream.use { stream -> String(stream.readBytes()) }
}
}

View File

@ -8,7 +8,6 @@ import de.timklge.karooheadwind.TemperatureUnit
import de.timklge.karooheadwind.WeatherDataProvider import de.timklge.karooheadwind.WeatherDataProvider
import de.timklge.karooheadwind.datatypes.GpsCoordinates import de.timklge.karooheadwind.datatypes.GpsCoordinates
import de.timklge.karooheadwind.jsonWithUnknownKeys import de.timklge.karooheadwind.jsonWithUnknownKeys
import de.timklge.karooheadwind.util.ungzip
import de.timklge.karooheadwind.weatherprovider.WeatherDataResponse import de.timklge.karooheadwind.weatherprovider.WeatherDataResponse
import de.timklge.karooheadwind.weatherprovider.WeatherProvider import de.timklge.karooheadwind.weatherprovider.WeatherProvider
import de.timklge.karooheadwind.weatherprovider.WeatherProviderException import de.timklge.karooheadwind.weatherprovider.WeatherProviderException
@ -28,7 +27,7 @@ import kotlin.time.Duration.Companion.seconds
class OpenMeteoWeatherProvider : WeatherProvider { class OpenMeteoWeatherProvider : WeatherProvider {
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class)
private suspend fun makeOpenMeteoWeatherRequest(karooSystemService: KarooSystemService, gpsCoordinates: List<GpsCoordinates>, settings: HeadwindSettings, profile: UserProfile?): String { private suspend fun makeOpenMeteoWeatherRequest(karooSystemService: KarooSystemService, gpsCoordinates: List<GpsCoordinates>, settings: HeadwindSettings, profile: UserProfile?): HttpResponseState.Complete {
val precipitationUnit = if (profile?.preferredUnit?.distance != UserProfile.PreferredUnit.UnitType.IMPERIAL) PrecipitationUnit.MILLIMETERS else PrecipitationUnit.INCH val precipitationUnit = if (profile?.preferredUnit?.distance != UserProfile.PreferredUnit.UnitType.IMPERIAL) PrecipitationUnit.MILLIMETERS else PrecipitationUnit.INCH
val temperatureUnit = if (profile?.preferredUnit?.temperature != UserProfile.PreferredUnit.UnitType.IMPERIAL) TemperatureUnit.CELSIUS else TemperatureUnit.FAHRENHEIT val temperatureUnit = if (profile?.preferredUnit?.temperature != UserProfile.PreferredUnit.UnitType.IMPERIAL) TemperatureUnit.CELSIUS else TemperatureUnit.FAHRENHEIT
@ -45,7 +44,7 @@ class OpenMeteoWeatherProvider : WeatherProvider {
"GET", "GET",
url, url,
waitForConnection = false, waitForConnection = false,
headers = mapOf("User-Agent" to KarooHeadwindExtension.TAG, "Accept-Encoding" to "gzip"), headers = mapOf("User-Agent" to KarooHeadwindExtension.TAG),
), ),
onEvent = { event: OnHttpResponse -> onEvent = { event: OnHttpResponse ->
if (event.state is HttpResponseState.Complete){ if (event.state is HttpResponseState.Complete){
@ -74,7 +73,7 @@ class OpenMeteoWeatherProvider : WeatherProvider {
throw WeatherProviderException(response.statusCode, "OpenMeteo API request failed with status code ${response.statusCode}") throw WeatherProviderException(response.statusCode, "OpenMeteo API request failed with status code ${response.statusCode}")
} }
return ungzip(response) return response
} }
override suspend fun getWeatherData( override suspend fun getWeatherData(
@ -84,11 +83,12 @@ class OpenMeteoWeatherProvider : WeatherProvider {
profile: UserProfile? profile: UserProfile?
): WeatherDataResponse { ): WeatherDataResponse {
val openMeteoResponse = makeOpenMeteoWeatherRequest(karooSystem, coordinates, settings, profile) val openMeteoResponse = makeOpenMeteoWeatherRequest(karooSystem, coordinates, settings, profile)
val responseBody = openMeteoResponse.body?.let { String(it) } ?: throw WeatherProviderException(500, "Null response from OpenMeteo")
val weatherData = if (coordinates.size == 1) { val weatherData = if (coordinates.size == 1) {
listOf(jsonWithUnknownKeys.decodeFromString<OpenMeteoWeatherDataForLocation>(openMeteoResponse)) listOf(jsonWithUnknownKeys.decodeFromString<OpenMeteoWeatherDataForLocation>(responseBody))
} else { } else {
jsonWithUnknownKeys.decodeFromString<List<OpenMeteoWeatherDataForLocation>>(openMeteoResponse) jsonWithUnknownKeys.decodeFromString<List<OpenMeteoWeatherDataForLocation>>(responseBody)
} }
val response = WeatherDataResponse( val response = WeatherDataResponse(