Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions app/src/main/java/dev/itsvic/parceltracker/api/USPSDeliveryService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package dev.itsvic.parceltracker.api

import dev.itsvic.parceltracker.R
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.coroutines.executeAsync
import android.util.Log
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.coroutines.ExperimentalForInheritanceCoroutinesApi
import org.json.JSONObject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import retrofit2.Retrofit
import retrofit2.http.Body
import retrofit2.http.Path
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import java.time.LocalDateTime

object USPSDeliveryService : DeliveryService {
override val nameResource: Int = R.string.service_usps
override val acceptsPostCode: Boolean = false
override val requiresPostCode: Boolean = false

override suspend fun getParcel(trackingId: String, postCode: String?): Parcel {
// dummy stuff just so this compiles
return Parcel(
trackingId,
listOf(ParcelHistoryItem("", LocalDateTime.now(), "")),
Status.DeliveryFailure
)
}

private val retrofit = Retrofit.Builder().baseUrl("https://api.usps.com/").client(api_client)
.addConverterFactory(api_factory).build()

private val service = retrofit.create(API::class.java)

private interface API {
@POST("oauth2/v3/token")
suspend fun getOauthToken(
@Body data: GetOauthToken
): OauthTokenResponse

@GET("tracking/v3/tracking")
suspend fun getStatus(
@Path("trackingId") trackingId: String,
@Header("Authorization") authorization: String
): StatusResponse
}

@JsonClass(generateAdapter = true)
internal data class GetOauthToken(
// from https://developers.usps.com/Oauth
val clientId: String,
val clientSecret: String,
val grantType: String = "authorization_code",
val scopes: List<String> = listOf("tracking"),
val tokenUrl: String = "https://apis.usps.com/oauth2/v3/token",
)

@JsonClass(generateAdapter = true)
internal data class OauthTokenResponse(
val oauthToken: String
)

@JsonClass(generateAdapter = true)
internal data class StatusResponse(
val expectedDeliveryDate: String,
val expectedDeliveryTime: String,
val guaranteedDeliveryDate: String,
val eventSummaries: List<EventSummary>
)

@JsonClass(generateAdapter = true)
internal data class EventSummary(
val eventDescription: String
)

/*
@OptIn(ExperimentalCoroutinesApi::class)
private suspend fun getOauthToken(clientId: String, clientSecret: String): String {

// this should work trust me
val tokenResp = service.getOauthToken()

val request = Request.Builder().post(body).url(TOKEN_URL).build()

api_client.newCall(request).executeAsync().use { response ->
Log.d("USPS", "Got Response")
var jsonWebToken = ""
if (response.code == 200) {
jsonWebToken = JSONObject(response.body.string()).optString("access_token", "")
Log.d("USPS", "Got Oauth2 token! $jsonWebToken")
// TODO: verify access token with provided public key
// if the USPS gets hacked we may have bigger problems on our hands than inaccurate package tracking
} else Log.d("USPS", "Couldn't get Oauth2 token ): response code was ${response.code}")
return jsonWebToken
}
}*/
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,5 @@
<string name="settings_api_keys">API keys</string>
<string name="service_ukrposhta">Ukrposhta</string>
<string name="service_gls_hungary">GLS Hungary</string>
<string name="service_usps">USPS</string>
</resources>
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ kotlinxSerializationJson = "1.7.3"
room = "2.6.1"
datastorePreferences = "1.1.4"
retrofit = "2.11.0"
skrapeit = "1.2.2"
work = "2.10.0"
kotlinxCoroutinesGuava = "1.10.1"
material3 = "1.4.0-alpha11"
Expand Down Expand Up @@ -53,6 +54,7 @@ room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
converter-moshi = { group = "com.squareup.retrofit2", name = "converter-moshi", version.ref = "retrofit" }
skrapeit = { module = "it.skrape:skrapeit", version.ref = "skrapeit" }
work-runtime = { group = "androidx.work", name = "work-runtime", version.ref = "work" }
work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "kotlinxCoroutinesGuava" }
Expand Down