mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Endurain: Update server-side workout type after uploading
This commit is contained in:
+94
-5
@@ -19,7 +19,10 @@ package nodomain.freeyourgadget.gadgetbridge.activities.endurain
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.InternetUtils
|
import nodomain.freeyourgadget.gadgetbridge.util.InternetUtils
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -258,7 +261,7 @@ class EndurainApiClient(
|
|||||||
/**
|
/**
|
||||||
* Upload activity file (GPX)
|
* Upload activity file (GPX)
|
||||||
*/
|
*/
|
||||||
fun uploadActivity(file: File, callback: (Boolean) -> Unit) {
|
fun uploadActivity(file: File, callback: (Int?) -> Unit) {
|
||||||
Thread {
|
Thread {
|
||||||
try {
|
try {
|
||||||
val uri = "$baseUrl/api/v1/activities/create/upload".toUri()
|
val uri = "$baseUrl/api/v1/activities/create/upload".toUri()
|
||||||
@@ -270,19 +273,55 @@ class EndurainApiClient(
|
|||||||
requestHeaders = headers
|
requestHeaders = headers
|
||||||
) { success, responseText ->
|
) { success, responseText ->
|
||||||
if (success && responseText != null) {
|
if (success && responseText != null) {
|
||||||
callback(true)
|
val jsonArray = JSONArray(responseText)
|
||||||
|
val firstObject = jsonArray.getJSONObject(0)
|
||||||
|
val id = firstObject.getInt("id")
|
||||||
|
callback(id)
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Activity upload failed")
|
LOG.error("Activity upload failed")
|
||||||
callback(false)
|
callback(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
LOG.error("Activity upload error", e)
|
LOG.error("Activity upload error", e)
|
||||||
callback(false)
|
callback(null)
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit uploaded activity
|
||||||
|
*/
|
||||||
|
fun editActivity(id: Int, activityKind: ActivityKind, name: String): Boolean {
|
||||||
|
try {
|
||||||
|
val uri = "$baseUrl/api/v1/activities/edit".toUri()
|
||||||
|
val headers = buildHeaders(AuthType.AUTH_TOKEN)
|
||||||
|
|
||||||
|
var activityType = 10 // Generic workout
|
||||||
|
if (activityLookup.containsKey(activityKind.ordinal)) {
|
||||||
|
activityType = activityLookup[activityKind.ordinal]!!
|
||||||
|
}
|
||||||
|
|
||||||
|
val bodyJson = JSONObject().apply {
|
||||||
|
put("id", id)
|
||||||
|
put("activity_type", activityType)
|
||||||
|
put("name", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = InternetUtils.doStringRequest(
|
||||||
|
method = "PUT",
|
||||||
|
uri = uri,
|
||||||
|
requestHeaders = headers,
|
||||||
|
body = bodyJson.toString()
|
||||||
|
)
|
||||||
|
LOG.info("editActivity result: {}", result)
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
LOG.error("Activity edit error", e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch server version string
|
* Fetch server version string
|
||||||
*/
|
*/
|
||||||
@@ -302,4 +341,54 @@ class EndurainApiClient(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Lookup map to convert ActivityKind to the integer Endurain expects,
|
||||||
|
* based on https://docs.endurain.com/developer-guide/supported-types/
|
||||||
|
*/
|
||||||
|
val activityLookup = mapOf(
|
||||||
|
ActivityKind.RUNNING.ordinal to 1,
|
||||||
|
ActivityKind.TRAIL_RUN.ordinal to 2,
|
||||||
|
ActivityKind.VIRTUAL_RUN.ordinal to 3,
|
||||||
|
ActivityKind.CYCLING.ordinal to 4,
|
||||||
|
ActivityKind.ROAD_BIKE.ordinal to 4,
|
||||||
|
ActivityKind.GRAVEL_BIKE.ordinal to 5,
|
||||||
|
ActivityKind.MOUNTAIN_BIKE.ordinal to 6,
|
||||||
|
ActivityKind.POOL_SWIM.ordinal to 8,
|
||||||
|
ActivityKind.SWIMMING_OPENWATER.ordinal to 9,
|
||||||
|
ActivityKind.TRAINING.ordinal to 10,
|
||||||
|
ActivityKind.WALKING.ordinal to 11,
|
||||||
|
ActivityKind.HIKING.ordinal to 12,
|
||||||
|
ActivityKind.ROWING.ordinal to 13,
|
||||||
|
ActivityKind.YOGA.ordinal to 14,
|
||||||
|
ActivityKind.SKIING.ordinal to 15,
|
||||||
|
ActivityKind.SNOWBOARDING.ordinal to 17,
|
||||||
|
ActivityKind.TRANSITION.ordinal to 18,
|
||||||
|
ActivityKind.STRENGTH_TRAINING.ordinal to 19,
|
||||||
|
ActivityKind.CROSSFIT.ordinal to 20,
|
||||||
|
ActivityKind.TENNIS.ordinal to 21,
|
||||||
|
ActivityKind.TABLE_TENNIS.ordinal to 22,
|
||||||
|
ActivityKind.BADMINTON.ordinal to 23,
|
||||||
|
ActivityKind.SQUASH.ordinal to 24,
|
||||||
|
ActivityKind.RACQUETBALL.ordinal to 25,
|
||||||
|
ActivityKind.PICKLEBALL.ordinal to 26,
|
||||||
|
ActivityKind.BIKE_COMMUTE.ordinal to 27,
|
||||||
|
ActivityKind.INDOOR_CYCLING.ordinal to 28,
|
||||||
|
ActivityKind.WINDSURFING.ordinal to 30,
|
||||||
|
ActivityKind.INDOOR_WALKING.ordinal to 31,
|
||||||
|
ActivityKind.STAND_UP_PADDLEBOARDING.ordinal to 32,
|
||||||
|
ActivityKind.SURFING.ordinal to 33,
|
||||||
|
ActivityKind.TRACK_RUN.ordinal to 34,
|
||||||
|
ActivityKind.E_BIKE.ordinal to 35,
|
||||||
|
ActivityKind.E_MOUNTAIN_BIKE.ordinal to 36,
|
||||||
|
ActivityKind.ICE_SKATING.ordinal to 37,
|
||||||
|
ActivityKind.SOCCER.ordinal to 38,
|
||||||
|
ActivityKind.PADEL.ordinal to 39,
|
||||||
|
ActivityKind.TREADMILL.ordinal to 40,
|
||||||
|
ActivityKind.CARDIO.ordinal to 41,
|
||||||
|
ActivityKind.KAYAKING.ordinal to 42,
|
||||||
|
ActivityKind.SAILING.ordinal to 43,
|
||||||
|
ActivityKind.INLINE_SKATING.ordinal to 45,
|
||||||
|
ActivityKind.HIIT.ordinal to 46
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
+11
-3
@@ -746,7 +746,10 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
|||||||
|
|
||||||
private fun uploadToEndurain() {
|
private fun uploadToEndurain() {
|
||||||
val workout = currentWorkout ?: return
|
val workout = currentWorkout ?: return
|
||||||
val gpxFile = ActivitySummaryUtils.getGpxFile(workout.summary)
|
val workoutName = currentWorkout!!.summary.name
|
||||||
|
val activityKind = ActivityKind.fromCode(currentWorkout!!.summary.activityKind)
|
||||||
|
val activityTrackProvider = gbDevice.deviceCoordinator.getActivityTrackProvider(gbDevice, requireContext())
|
||||||
|
val gpxFile = ActivitySummaryUtils.getShareableGpxFile(activityTrackProvider, workout.summary)
|
||||||
|
|
||||||
if (gpxFile == null) {
|
if (gpxFile == null) {
|
||||||
GB.toast("No GPX track in this activity", Toast.LENGTH_LONG, GB.INFO)
|
GB.toast("No GPX track in this activity", Toast.LENGTH_LONG, GB.INFO)
|
||||||
@@ -758,9 +761,14 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
|||||||
val serverUrl = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
val serverUrl = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
||||||
val apiClient = EndurainApiClient(serverUrl!!, endurainVm.tokenManager)
|
val apiClient = EndurainApiClient(serverUrl!!, endurainVm.tokenManager)
|
||||||
endurainVm.tokenManager.performTokenRefresh(serverUrl) {
|
endurainVm.tokenManager.performTokenRefresh(serverUrl) {
|
||||||
apiClient.uploadActivity(gpxFile) { success ->
|
LOG.info("Uploading workout '{}' (type {}) to Endurain", workoutName, activityKind)
|
||||||
|
apiClient.uploadActivity(gpxFile) { newId ->
|
||||||
|
if (newId != null) {
|
||||||
|
// Update activity type on the server
|
||||||
|
apiClient.editActivity(newId, activityKind, workoutName)
|
||||||
|
}
|
||||||
activity?.runOnUiThread {
|
activity?.runOnUiThread {
|
||||||
if (success)
|
if (newId != null)
|
||||||
GB.toast(
|
GB.toast(
|
||||||
"Successfully uploaded to Endurain",
|
"Successfully uploaded to Endurain",
|
||||||
Toast.LENGTH_SHORT,
|
Toast.LENGTH_SHORT,
|
||||||
|
|||||||
Reference in New Issue
Block a user