mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Endurain: Upload FIT file if available
This commit is contained in:
committed by
Arjan Schrijver
parent
d6f6287919
commit
cc529b40e2
+9
-4
@@ -750,10 +750,15 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
||||
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) {
|
||||
GB.toast(getString(R.string.no_gpx_track_in_activity_toast), Toast.LENGTH_LONG, GB.INFO)
|
||||
val activityFile = if (workout.summary.rawDetailsPath?.endsWith(".fit") == true) {
|
||||
FileUtils.tryFixPath(workout.summary.rawDetailsPath)
|
||||
} else {
|
||||
ActivitySummaryUtils.getShareableGpxFile(activityTrackProvider, workout.summary)
|
||||
}
|
||||
|
||||
if (activityFile == null) {
|
||||
GB.toast(getString(R.string.no_activity_track_in_activity_toast), Toast.LENGTH_LONG, GB.INFO)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -763,7 +768,7 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
||||
val apiClient = EndurainApiClient(serverUrl!!, endurainVm.tokenManager)
|
||||
endurainVm.tokenManager.performTokenRefresh(serverUrl) {
|
||||
LOG.info("Uploading workout '{}' (type {}) to Endurain", workoutName, activityKind)
|
||||
apiClient.uploadActivity(gpxFile) { newId ->
|
||||
apiClient.uploadActivity(activityFile) { newId ->
|
||||
if (newId != null) {
|
||||
// Update activity type on the server
|
||||
apiClient.editActivity(newId, activityKind, workoutName)
|
||||
|
||||
@@ -171,17 +171,17 @@ class InternetUtils {
|
||||
}
|
||||
|
||||
val boundary = "----GadgetbridgeFormBoundary${System.currentTimeMillis()}"
|
||||
val multipartBody = buildMultipartBody(file, fileName, mimeType, boundary)
|
||||
val multipartBodyBytes = buildMultipartBody(file, fileName, mimeType, boundary)
|
||||
|
||||
val headers = requestHeaders.toMutableMap()
|
||||
headers["Content-Type"] = "multipart/form-data; boundary=$boundary"
|
||||
|
||||
val response = if (GBApplication.hasDirectInternetAccess()) {
|
||||
directRequest(
|
||||
directBinaryRequest(
|
||||
uri = uri,
|
||||
method = "POST",
|
||||
requestHeaders = headers,
|
||||
body = multipartBody,
|
||||
body = multipartBodyBytes,
|
||||
allowInsecure = allowInsecure
|
||||
)
|
||||
} else {
|
||||
@@ -189,7 +189,7 @@ class InternetUtils {
|
||||
uri,
|
||||
HttpRequest.Method.POST,
|
||||
headers,
|
||||
multipartBody.toByteArray(),
|
||||
multipartBodyBytes,
|
||||
allowInsecure
|
||||
)
|
||||
}
|
||||
@@ -207,24 +207,57 @@ class InternetUtils {
|
||||
fileName: String,
|
||||
mimeType: String,
|
||||
boundary: String
|
||||
): String {
|
||||
): ByteArray {
|
||||
val fileBytes = file.readBytes()
|
||||
val output = ByteArrayOutputStream()
|
||||
val writer = output.bufferedWriter()
|
||||
|
||||
writer.write("--$boundary\r\n")
|
||||
writer.write("Content-Disposition: form-data; name=\"file\"; filename=\"$fileName\"\r\n")
|
||||
writer.write("Content-Type: $mimeType\r\n")
|
||||
writer.write("\r\n")
|
||||
writer.flush()
|
||||
|
||||
val header = "--$boundary\r\n" +
|
||||
"Content-Disposition: form-data; name=\"file\"; filename=\"$fileName\"\r\n" +
|
||||
"Content-Type: $mimeType\r\n" +
|
||||
"\r\n"
|
||||
output.write(header.toByteArray(Charsets.US_ASCII))
|
||||
output.write(fileBytes)
|
||||
output.write("\r\n--$boundary--\r\n".toByteArray(Charsets.US_ASCII))
|
||||
|
||||
writer.write("\r\n")
|
||||
writer.write("--$boundary--\r\n")
|
||||
writer.flush()
|
||||
return output.toByteArray()
|
||||
}
|
||||
|
||||
return output.toString("UTF-8")
|
||||
/**
|
||||
* Direct HTTP request using OkHttp with a binary body.
|
||||
*/
|
||||
private fun directBinaryRequest(
|
||||
uri: Uri,
|
||||
method: String,
|
||||
requestHeaders: Map<String, String>,
|
||||
body: ByteArray,
|
||||
allowInsecure: Boolean
|
||||
): WebResourceResponse {
|
||||
val client = if (allowInsecure) createInsecureClient() else defaultClient
|
||||
val builder = Request.Builder().url(uri.toString())
|
||||
|
||||
for ((key, value) in headersWithUserAgent(requestHeaders)) {
|
||||
builder.addHeader(key, value)
|
||||
}
|
||||
|
||||
val contentType = getHeader(requestHeaders, "content-type") ?: "application/octet-stream"
|
||||
val requestBody = body.toRequestBody(contentType.toMediaType())
|
||||
builder.method(method.uppercase(), requestBody)
|
||||
|
||||
client.newCall(builder.build()).execute().use { response ->
|
||||
val statusCode = response.code
|
||||
val message = if (!response.message.isEmpty()) response.message else "OK"
|
||||
val headers = response.headers.toMap()
|
||||
val respContentType = response.header("content-type") ?: "application/octet-stream"
|
||||
val encoding = response.header("content-encoding") ?: "UTF-8"
|
||||
return WebResourceResponse(
|
||||
respContentType,
|
||||
encoding,
|
||||
statusCode,
|
||||
message,
|
||||
headers,
|
||||
ByteArrayInputStream(response.body.bytes())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4970,6 +4970,7 @@
|
||||
<string name="pref_endurain_log_out_title">Log out of Endurain</string>
|
||||
<string name="pref_endurain_log_out_summary">Tap here to log out, this disables the integration</string>
|
||||
<string name="no_gpx_track_in_activity_toast">No GPX track in this activity</string>
|
||||
<string name="no_activity_track_in_activity_toast">No activity track in this activity</string>
|
||||
<string name="unable_to_display_gpx_track_toast">Unable to display GPX track: %1$s</string>
|
||||
<string name="unable_to_share_gpx_track_toast">Unable to share GPX track: %1$s</string>
|
||||
<string name="endurain_successfully_uploaded_toast">Successfully uploaded to Endurain</string>
|
||||
|
||||
Reference in New Issue
Block a user