Fix Open Humans Uploader

This commit is contained in:
TebbeUbben 2020-05-28 15:19:35 +02:00
parent 5533f87bbc
commit fa8e784733
5 changed files with 65 additions and 35 deletions

View file

@ -106,7 +106,7 @@ public class DetermineBasalAdapterMAJS {
log.debug("Result: " + result);
try {
JSONObject resultJson = new JSONObject(result);
OpenHumansUploader.INSTANCE.enqueueAMAData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, resultJson);
OpenHumansUploader.INSTANCE.enqueueMAData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, resultJson);
determineBasalResultMA = new DetermineBasalResultMA(jsResult, resultJson);
} catch (JSONException e) {
log.error("Unhandled exception", e);

View file

@ -13,8 +13,10 @@ class OHUploadWorker(
) : RxWorker(context, workerParameters) {
override fun createWork() = Single.defer {
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
if (SP.getBoolean("key_oh_wifi_only", true) && wifiManager.isWifiEnabled && wifiManager.connectionInfo.networkId != -1) {
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
val wifiOnly = SP.getBoolean("key_oh_wifi_only", true)
val isConnectedToWifi = wifiManager?.isWifiEnabled ?: false && wifiManager?.connectionInfo?.networkId != -1
if (!wifiOnly || (wifiOnly && isConnectedToWifi)) {
OpenHumansUploader.uploadData()
.andThen(Single.just(Result.success()))
.onErrorResumeNext { Single.just(Result.retry()) }

View file

@ -6,12 +6,12 @@ import io.reactivex.Completable
import io.reactivex.Single
import io.reactivex.disposables.Disposables
import okhttp3.*
import okio.BufferedSink
import org.json.JSONArray
import org.json.JSONObject
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import okio.BufferedSink
class OpenHumansAPI(
private val baseUrl: String,
@ -32,7 +32,7 @@ class OpenHumansAPI(
fun refreshAccessToken(refreshToken: String): Single<OAuthTokens> = sendTokenRequest(FormBody.Builder()
.add("grant_type", "refresh_token")
.add("redirect_uri", redirectUri)
.add("code", refreshToken)
.add("refresh_token", refreshToken)
.build())
private fun sendTokenRequest(body: FormBody) = Request.Builder()
@ -49,8 +49,10 @@ class OpenHumansAPI(
if (jsonObject == null) throw OHHttpException(response.code, response.message, "No body")
if (!jsonObject.has("expires_in")) throw OHMissingFieldException("expires_in")
OAuthTokens(
accessToken = jsonObject.getString("access_token") ?: throw OHMissingFieldException("access_token"),
refreshToken = jsonObject.getString("refresh_token") ?: throw OHMissingFieldException("refresh_token"),
accessToken = jsonObject.getString("access_token")
?: throw OHMissingFieldException("access_token"),
refreshToken = jsonObject.getString("refresh_token")
?: throw OHMissingFieldException("refresh_token"),
expiresAt = response.sentRequestAtMillis + jsonObject.getInt("expires_in") * 1000L
)
}
@ -61,7 +63,10 @@ class OpenHumansAPI(
.get()
.build()
.toSingle()
.map { it.jsonBody.getString("project_member_id") ?: throw OHMissingFieldException("project_member_id") }
.map {
it.jsonBody.getString("project_member_id")
?: throw OHMissingFieldException("project_member_id")
}
fun prepareFileUpload(accessToken: String, fileName: String, metadata: FileMetadata): Single<PreparedUpload> = Request.Builder()
.url("$baseUrl/api/direct-sharing/project/files/upload/direct/?access_token=$accessToken")
@ -109,7 +114,6 @@ class OpenHumansAPI(
.doOnSuccess { it.jsonBody }
.ignoreElement()
private fun Request.toSingle() = Single.create<Response> {
val call = client.newCall(this)
call.enqueue(object : Callback {
@ -124,11 +128,13 @@ class OpenHumansAPI(
it.setDisposable(Disposables.fromRunnable { call.cancel() })
}
private val Response.jsonBody get() = use { _ ->
val jsonObject = body?.let { JSONObject(it.string()) } ?: throw OHHttpException(code, message, null)
if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail"))
jsonObject
}
private val Response.jsonBody
get() = use { _ ->
val jsonObject = body?.let { JSONObject(it.string()) }
?: throw OHHttpException(code, message, null)
if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail"))
jsonObject
}
data class OAuthTokens(
val accessToken: String,
@ -144,6 +150,7 @@ class OpenHumansAPI(
val startDate: Long? = null,
val endDate: Long? = null
) {
fun toJSON(): JSONObject {
val jsonObject = JSONObject()
jsonObject.put("tags", JSONArray().apply { tags.forEach { put(it) } })
@ -166,12 +173,14 @@ class OpenHumansAPI(
val meaning: String,
val detail: String?
) : RuntimeException() {
override val message: String get() = toString()
}
data class OHMissingFieldException(
val name: String
) : RuntimeException() {
override val message: String get() = toString()
}

View file

@ -52,16 +52,16 @@ object OpenHumansUploader : PluginBase(
private val log = LoggerFactory.getLogger(L.OPENHUMANS)
const val OPEN_HUMANS_URL = "https://www.openhumans.org"
const val CLIENT_ID = "oie6DvnaEOagTxSoD6BukkLPwDhVr6cMlN74Ihz1"
const val CLIENT_SECRET = "jR0N8pkH1jOwtozHc7CsB1UPcJzFN95ldHcK4VGYIApecr8zGJox0v06xLwPLMASScngT12aIaIHXAVCJeKquEXAWG1XekZdbubSpccgNiQBmuVmIF8nc1xSKSNJltCf"
const val REDIRECT_URL = "androidaps://setup-openhumans"
private const val OPEN_HUMANS_URL = "https://www.openhumans.org"
private const val CLIENT_ID = "oie6DvnaEOagTxSoD6BukkLPwDhVr6cMlN74Ihz1"
private const val CLIENT_SECRET = "jR0N8pkH1jOwtozHc7CsB1UPcJzFN95ldHcK4VGYIApecr8zGJox0v06xLwPLMASScngT12aIaIHXAVCJeKquEXAWG1XekZdbubSpccgNiQBmuVmIF8nc1xSKSNJltCf"
private const val REDIRECT_URL = "androidaps://setup-openhumans"
const val AUTH_URL = "https://www.openhumans.org/direct-sharing/projects/oauth2/authorize/?client_id=$CLIENT_ID&response_type=code"
const val WORK_NAME = "Open Humans"
const val COPY_NOTIFICATION_ID = 3122
const val FAILURE_NOTIFICATION_ID = 3123
const val SUCCESS_NOTIFICATION_ID = 3124
const val SIGNED_OUT_NOTIFICATION_ID = 3125
private const val COPY_NOTIFICATION_ID = 3122
private const val FAILURE_NOTIFICATION_ID = 3123
private const val SUCCESS_NOTIFICATION_ID = 3124
private const val SIGNED_OUT_NOTIFICATION_ID = 3125
private val openHumansAPI = OpenHumansAPI(OPEN_HUMANS_URL, CLIENT_ID, CLIENT_SECRET, REDIRECT_URL)
private val FILE_NAME_DATE_FORMAT = SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.US).apply { timeZone = TimeZone.getTimeZone("UTC") }
@ -123,13 +123,13 @@ object OpenHumansUploader : PluginBase(
super.onStart()
setupNotificationChannel()
if (isSetup) scheduleWorker(false)
SP.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
SP.registerListener(this)
}
override fun onStop() {
copyDisposable?.dispose()
cancelWorker()
SP.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
SP.unregisterListener(this)
super.onStop()
}
@ -250,7 +250,7 @@ object OpenHumansUploader : PluginBase(
put("result", result)
}
fun enqueueAMAData(profile: JSONObject, glucoseStatus: JSONObject, iobData: JSONObject, mealData: JSONObject, currentTemp: JSONObject, result: JSONObject) = insertQueueItem("APSData") {
fun enqueueMAData(profile: JSONObject, glucoseStatus: JSONObject, iobData: JSONObject, mealData: JSONObject, currentTemp: JSONObject, result: JSONObject) = insertQueueItem("APSData") {
put("algorithm", "MA")
put("profile", profile)
put("glucoseStatus", glucoseStatus)
@ -290,6 +290,9 @@ object OpenHumansUploader : PluginBase(
copyExistingDataToQueue()
RxBus.send(OpenHumansFragment.UpdateViewEvent)
}
.doOnError {
log.error("Failed to login to Open Humans", it)
}
.ignoreElement()
fun logout() {
@ -318,22 +321,22 @@ object OpenHumansUploader : PluginBase(
.map { enqueueBGReading(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allCareportalEvents) })
.map { enqueueCareportalEvent(it); increaseCounter() }
.map { enqueueCareportalEvent(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allExtendedBoluses) })
.map { enqueueExtendedBolus(it); increaseCounter() }
.map { enqueueExtendedBolus(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allProfileSwitches) })
.map { enqueueProfileSwitch(it); increaseCounter() }
.map { enqueueProfileSwitch(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTDDs) })
.map { enqueueTotalDailyDose(it); increaseCounter() }
.map { enqueueTotalDailyDose(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTemporaryBasals) })
.map { enqueueTemporaryBasal(it); increaseCounter() }
.map { enqueueTemporaryBasal(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTempTargets) })
.map { enqueueTempTarget(it); increaseCounter() }
.map { enqueueTempTarget(it); increaseCounter() }
.ignoreElements()
.doOnSubscribe {
wakeLock.acquire(TimeUnit.MINUTES.toMillis(20))
@ -362,7 +365,8 @@ object OpenHumansUploader : PluginBase(
.setContentTitle(MainApp.gs(R.string.finishing_open_humans_setup))
.setContentText(MainApp.gs(R.string.this_may_take_a_while))
.setStyle(NotificationCompat.BigTextStyle())
.setProgress(maxProgress?.toInt() ?: 0, currentProgress?.toInt() ?: 0, maxProgress == null || currentProgress == null)
.setProgress(maxProgress?.toInt() ?: 0, currentProgress?.toInt()
?: 0, maxProgress == null || currentProgress == null)
.setOngoing(true)
.setAutoCancel(false)
.setSmallIcon(R.drawable.notif_icon)
@ -406,8 +410,15 @@ object OpenHumansUploader : PluginBase(
if (it is OpenHumansAPI.OHHttpException && it.code == 401 && it.detail == "Invalid token.") {
handleSignOut()
}
log.error("Error while uploading to Open Humans", it)
}
.doOnComplete {
log.info("Upload successful")
RxBus.send(OpenHumansFragment.UpdateQueueEvent)
}
.doOnSubscribe {
log.info("Starting upload")
}
.doOnComplete { RxBus.send(OpenHumansFragment.UpdateQueueEvent) }
private fun uploadFile(accessToken: String, uploadData: UploadData) = Completable.defer {
openHumansAPI.prepareFileUpload(accessToken, uploadData.fileName, uploadData.metadata)
@ -450,7 +461,7 @@ object OpenHumansUploader : PluginBase(
zos.writeFile("ApplicationInfo.json", applicationInfo.toString().toByteArray())
tags.add("ApplicationInfo")
val preferences = JSONObject(SP.sharedPreferences.all.filterKeys { it.isAllowedKey() })
val preferences = JSONObject(SP.getAll().filterKeys { it.isAllowedKey() })
zos.writeFile("Preferences.json", preferences.toString().toByteArray())
tags.add("Preferences")

View file

@ -12,7 +12,7 @@ import info.nightscout.androidaps.MainApp;
*/
public class SP {
public static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
private static final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
static public Map<String, ?> getAll() {
return sharedPreferences.getAll();
@ -26,6 +26,14 @@ public class SP {
return sharedPreferences.contains(key);
}
static public void registerListener(SharedPreferences.OnSharedPreferenceChangeListener listener) {
sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
}
static public void unregisterListener(SharedPreferences.OnSharedPreferenceChangeListener listener) {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener);
}
static public boolean contains(int resourceId) {
return sharedPreferences.contains(MainApp.gs(resourceId));
}