mirror of
https://github.com/openflocon/Flocon.git
synced 2026-05-02 02:40:10 +00:00
refact: [NETWORK] format on data part to be able to filter and search… (#288)
Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
8c6ce2e244
commit
08e58f60f4
17 changed files with 4420 additions and 67 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -40,7 +40,7 @@ import io.github.openflocon.flocondesktop.common.db.converters.MapStringsConvert
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Database(
|
||||
version = 61,
|
||||
version = 62,
|
||||
entities = [
|
||||
FloconNetworkCallEntity::class,
|
||||
FileEntity::class,
|
||||
|
|
|
|||
|
|
@ -6,35 +6,6 @@ import io.github.openflocon.domain.network.models.responseByteSizeFormatted
|
|||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkItemViewState
|
||||
import io.ktor.http.Url
|
||||
|
||||
fun extractDomain(url: String): String {
|
||||
// Parse l'URL en un objet Url
|
||||
val parsedUrl = Url(url)
|
||||
|
||||
// Utilise host pour le domaine et encodedPathAndQuery pour le chemin
|
||||
val domainAndPath = parsedUrl.host
|
||||
|
||||
// Le code ci-dessous pourrait aussi fonctionner, mais host est plus précis pour le domaine
|
||||
// return parsedUrl.hostWithPort + parsedUrl.fullPath
|
||||
return domainAndPath.removePrefix("www.")
|
||||
}
|
||||
|
||||
fun extractDomainAndPath(url: String): String {
|
||||
// Parse l'URL en un objet Url
|
||||
val parsedUrl = Url(url)
|
||||
|
||||
// Utilise host pour le domaine et encodedPathAndQuery pour le chemin
|
||||
val domainAndPath = parsedUrl.host + parsedUrl.encodedPathAndQuery
|
||||
|
||||
// Le code ci-dessous pourrait aussi fonctionner, mais host est plus précis pour le domaine
|
||||
// return parsedUrl.hostWithPort + parsedUrl.fullPath
|
||||
return domainAndPath.removePrefix("www.")
|
||||
}
|
||||
|
||||
fun extractPath(url: String): String {
|
||||
val parsedUrl = Url(url)
|
||||
return parsedUrl.encodedPathAndQuery
|
||||
}
|
||||
|
||||
fun toUi(
|
||||
networkCall: FloconNetworkCallDomainModel,
|
||||
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel?
|
||||
|
|
@ -45,7 +16,7 @@ fun toUi(
|
|||
timeFormatted = networkCall.response?.durationFormatted,
|
||||
requestSize = networkCall.request.byteSizeFormatted,
|
||||
responseSize = networkCall.responseByteSizeFormatted(),
|
||||
domain = getDomainUi(networkCall),
|
||||
domain = networkCall.request.domainFormatted,
|
||||
type = toTypeUi(networkCall),
|
||||
method = getMethodUi(networkCall),
|
||||
status = getStatusUi(networkCall),
|
||||
|
|
@ -53,9 +24,3 @@ fun toUi(
|
|||
isFromOldAppInstance = deviceIdAndPackageName?.appInstance?.let { it != networkCall.appInstance } ?: false
|
||||
)
|
||||
}
|
||||
|
||||
fun getDomainUi(networkRequest: FloconNetworkCallDomainModel): String = when (networkRequest.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> extractDomainAndPath(networkRequest.request.url)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> extractDomain(networkRequest.request.url)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> networkRequest.request.url
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,20 +5,18 @@ import io.github.openflocon.flocondesktop.features.network.list.model.NetworkIte
|
|||
|
||||
fun toTypeUi(call: FloconNetworkCallDomainModel): NetworkItemViewState.NetworkTypeUi = when (val s = call.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> NetworkItemViewState.NetworkTypeUi.GraphQl(
|
||||
queryName = s.query,
|
||||
queryName = call.request.queryFormatted,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> {
|
||||
val query = extractPath(call.request.url)
|
||||
NetworkItemViewState.NetworkTypeUi.Url(
|
||||
query = query,
|
||||
method = call.request.method,
|
||||
query = call.request.queryFormatted,
|
||||
)
|
||||
}
|
||||
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> {
|
||||
NetworkItemViewState.NetworkTypeUi.Grpc(
|
||||
method = call.request.method,
|
||||
method = call.request.queryFormatted,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ data class NetworkItemViewState(
|
|||
|
||||
@Immutable
|
||||
data class Url(
|
||||
val method: String,
|
||||
val query: String,
|
||||
) : NetworkTypeUi {
|
||||
override fun contains(text: String): Boolean = query.contains(text, ignoreCase = true)
|
||||
|
|
@ -68,7 +67,6 @@ fun previewNetworkItemViewState(): NetworkItemViewState = NetworkItemViewState(
|
|||
status = NetworkStatusUi("200", NetworkStatusUi.Status.SUCCESS),
|
||||
type = NetworkItemViewState.NetworkTypeUi.Url(
|
||||
query = "/search?q=test",
|
||||
method = "get",
|
||||
),
|
||||
isMocked = false,
|
||||
isFromOldAppInstance = false,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ private fun FloconNetworkCallEntity.toRequestDomainModel(): FloconNetworkCallDom
|
|||
isMocked = request.isMocked,
|
||||
startTimeFormatted = request.startTimeFormatted,
|
||||
byteSizeFormatted = request.byteSizeFormatted,
|
||||
domainFormatted = request.domainFormatted,
|
||||
queryFormatted = request.queryFormatted,
|
||||
methodFormatted = request.methodFormatted,
|
||||
specificInfos = when (type) {
|
||||
FloconNetworkCallType.HTTP -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
FloconNetworkCallType.GRAPHQL -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
|
|
@ -49,6 +52,7 @@ private fun FloconNetworkResponseEmbedded.toDomainModel(): FloconNetworkCallDoma
|
|||
durationMs = durationMs,
|
||||
issue = responseError,
|
||||
durationFormatted = durationFormatted,
|
||||
statusFormatted = statusFormatted,
|
||||
)
|
||||
} else {
|
||||
FloconNetworkCallDomainModel.Response.Success(
|
||||
|
|
@ -60,6 +64,7 @@ private fun FloconNetworkResponseEmbedded.toDomainModel(): FloconNetworkCallDoma
|
|||
durationFormatted = durationFormatted,
|
||||
byteSizeFormatted = responseByteSizeFormatted ?: "",
|
||||
isImage = isImage,
|
||||
statusFormatted = statusFormatted,
|
||||
specificInfos = when {
|
||||
graphql != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl(
|
||||
httpCode = graphql.responseHttpCode,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import io.github.openflocon.data.local.network.models.graphql.NetworkCallGraphQl
|
|||
import io.github.openflocon.data.local.network.models.graphql.NetworkCallGraphQlResponseEmbedded
|
||||
import io.github.openflocon.data.local.network.models.grpc.NetworkCallGrpcResponseEmbedded
|
||||
import io.github.openflocon.data.local.network.models.http.NetworkCallHttpResponseEmbedded
|
||||
import io.github.openflocon.domain.device.models.AppInstance
|
||||
import io.github.openflocon.domain.device.models.DeviceId
|
||||
import io.github.openflocon.domain.device.models.DeviceIdAndPackageNameDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
|
||||
|
|
@ -43,7 +41,10 @@ fun FloconNetworkCallDomainModel.toEntity(
|
|||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
domainFormatted = request.domainFormatted,
|
||||
queryFormatted = request.queryFormatted,
|
||||
methodFormatted = request.methodFormatted,
|
||||
),
|
||||
response = response?.let { networkResponse ->
|
||||
when(networkResponse) {
|
||||
|
|
@ -61,6 +62,7 @@ fun FloconNetworkCallDomainModel.toEntity(
|
|||
isImage = false,
|
||||
durationFormatted = networkResponse.durationFormatted,
|
||||
responseByteSizeFormatted = null,
|
||||
statusFormatted = networkResponse.statusFormatted,
|
||||
)
|
||||
}
|
||||
is FloconNetworkCallDomainModel.Response.Success -> {
|
||||
|
|
@ -74,6 +76,7 @@ fun FloconNetworkCallDomainModel.toEntity(
|
|||
responseByteSizeFormatted = networkResponse.byteSizeFormatted,
|
||||
responseError = null,
|
||||
isImage = networkResponse.isImage,
|
||||
statusFormatted = networkResponse.statusFormatted,
|
||||
graphql = when (val s = networkResponse.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> NetworkCallGraphQlResponseEmbedded(
|
||||
responseHttpCode = s.httpCode,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ data class FloconNetworkRequestEmbedded(
|
|||
val requestByteSize: Long,
|
||||
val isMocked: Boolean,
|
||||
|
||||
val domainFormatted: String, // for sorting & filtering
|
||||
val methodFormatted: String, // for sorting & filtering
|
||||
val queryFormatted: String, // for sorting & filtering
|
||||
|
||||
@Embedded(prefix = "graphql_")
|
||||
val graphql: NetworkCallGraphQlRequestEmbedded?,
|
||||
)
|
||||
|
|
@ -72,6 +76,7 @@ data class FloconNetworkResponseEmbedded(
|
|||
val responseByteSizeFormatted: String?,
|
||||
val responseError: String?,
|
||||
val isImage: Boolean,
|
||||
val statusFormatted: String, // for sorting & filtering
|
||||
|
||||
@Embedded(prefix = "graphql_")
|
||||
val graphql: NetworkCallGraphQlResponseEmbedded?,
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@ fun toDomain(
|
|||
val requestSize = decoded.requestSize ?: 0L
|
||||
val startTime = decoded.startTime!!
|
||||
|
||||
val specificInfos = when {
|
||||
graphQl != null -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
query = graphQl.request.requestBody.query,
|
||||
operationType = graphQl.request.operationType,
|
||||
)
|
||||
|
||||
decoded.floconNetworkType == "grpc" -> FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc
|
||||
else -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
}
|
||||
|
||||
val request = FloconNetworkCallDomainModel.Request(
|
||||
url = decoded.url!!,
|
||||
startTime = startTime,
|
||||
|
|
@ -67,15 +77,20 @@ fun toDomain(
|
|||
byteSize = requestSize,
|
||||
byteSizeFormatted = ByteFormatter.formatBytes(requestSize),
|
||||
isMocked = decoded.isMocked ?: false,
|
||||
specificInfos = when {
|
||||
graphQl != null -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
query = graphQl.request.requestBody.query,
|
||||
operationType = graphQl.request.operationType,
|
||||
)
|
||||
|
||||
decoded.floconNetworkType == "grpc" -> FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc
|
||||
else -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
},
|
||||
specificInfos = specificInfos,
|
||||
domainFormatted = extractDomain(
|
||||
requestUrl = decoded.url,
|
||||
specificInfos = specificInfos,
|
||||
),
|
||||
methodFormatted = extractMethod(
|
||||
requestMethod = decoded.method,
|
||||
specificInfos = specificInfos,
|
||||
),
|
||||
queryFormatted = extractQueryFormatted(
|
||||
requestUrl = decoded.url,
|
||||
requestMethod = decoded.method,
|
||||
specificInfos = specificInfos,
|
||||
),
|
||||
)
|
||||
|
||||
FloconNetworkCallDomainModel(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.flocon.data.remote.network.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.ktor.http.Url
|
||||
|
||||
internal fun extractDomain(
|
||||
requestUrl: String,
|
||||
specificInfos: FloconNetworkCallDomainModel.Request.SpecificInfos,
|
||||
): String = when (specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> extractDomainAndPath(requestUrl)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> extractDomain(requestUrl)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> requestUrl
|
||||
}
|
||||
|
||||
private fun extractDomain(url: String): String {
|
||||
// Parse the URL into a Url object
|
||||
val parsedUrl = Url(url)
|
||||
|
||||
// Use host for the domain
|
||||
val domainAndPath = parsedUrl.host
|
||||
|
||||
// The code below could also work, but host is more precise for the domain
|
||||
// return parsedUrl.hostWithPort + parsedUrl.fullPath
|
||||
return domainAndPath.removePrefix("www.")
|
||||
}
|
||||
|
||||
private fun extractDomainAndPath(url: String): String {
|
||||
// Parse the URL into a Url object
|
||||
val parsedUrl = Url(url)
|
||||
|
||||
// Use host for the domain and encodedPathAndQuery for the path
|
||||
val domainAndPath = parsedUrl.host + parsedUrl.encodedPathAndQuery
|
||||
|
||||
// The code below could also work, but host is more precise for the domain
|
||||
// return parsedUrl.hostWithPort + parsedUrl.fullPath
|
||||
return domainAndPath.removePrefix("www.")
|
||||
}
|
||||
|
||||
internal fun extractPath(url: String): String {
|
||||
val parsedUrl = Url(url)
|
||||
return parsedUrl.encodedPathAndQuery
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.flocon.data.remote.network.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
|
||||
internal fun extractMethod(
|
||||
requestMethod: String,
|
||||
specificInfos: FloconNetworkCallDomainModel.Request.SpecificInfos,
|
||||
): String = when (specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> specificInfos.operationType.lowercase()
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> toHttpMethodUi(requestMethod)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> "grpc"
|
||||
}
|
||||
|
||||
private fun toHttpMethodUi(httpMethod: String) = httpMethod.lowercase()
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.flocon.data.remote.network.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
|
||||
internal fun extractQueryFormatted(
|
||||
requestUrl: String,
|
||||
requestMethod: String,
|
||||
specificInfos: FloconNetworkCallDomainModel.Request.SpecificInfos,
|
||||
): String = when (val s = specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> s.query
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> extractPath(requestUrl)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> requestMethod
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.flocon.data.remote.network.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
|
||||
// be sure this keep aligned with the ui mapper
|
||||
|
||||
internal fun failureStatus() = "Exception"
|
||||
|
||||
internal fun extractStatus(specificInfos: FloconNetworkCallDomainModel.Response.Success.SpecificInfos): String =
|
||||
when (val s = specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> toGraphQlNetworkStatus(isSuccess = s.isSuccess)
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> toNetworkStatus(s.httpCode)
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> toGrpcNetworkStatus(specificInfos)
|
||||
}
|
||||
|
||||
private fun toNetworkStatus(code: Int): String = code.toString()
|
||||
|
||||
private fun toGraphQlNetworkStatus(isSuccess: Boolean): String =
|
||||
if (isSuccess) "Success" else "Error"
|
||||
|
||||
private fun toGrpcNetworkStatus(
|
||||
specificInfos: FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc
|
||||
): String {
|
||||
return specificInfos.grpcStatus
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.flocon.data.remote.network.models
|
||||
|
||||
import com.flocon.data.remote.network.mapper.failureStatus
|
||||
import com.flocon.data.remote.network.mapper.extractStatus
|
||||
import io.github.openflocon.domain.common.ByteFormatter
|
||||
import io.github.openflocon.domain.common.time.formatDuration
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
|
|
@ -59,27 +61,32 @@ internal fun FloconNetworkResponseDataModel.toDomain(): FloconNetworkResponseOnl
|
|||
durationMs = durationMs,
|
||||
issue = responseError,
|
||||
durationFormatted = durationFormatted,
|
||||
statusFormatted = failureStatus(),
|
||||
)
|
||||
} else {
|
||||
val responseSize = responseSize ?: 0L
|
||||
|
||||
val specificInfos = when (floconNetworkType) {
|
||||
"grpc" -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc(
|
||||
grpcStatus = responseGrpcStatus!!,
|
||||
)
|
||||
// otherwise tread like http
|
||||
else -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http(
|
||||
httpCode = responseHttpCode!!,
|
||||
)
|
||||
}
|
||||
|
||||
FloconNetworkCallDomainModel.Response.Success(
|
||||
durationMs = durationMs,
|
||||
contentType = responseContentType,
|
||||
body = responseBody,
|
||||
headers = responseHeaders.orEmpty(),
|
||||
byteSize = responseSize,
|
||||
specificInfos = when (floconNetworkType) {
|
||||
"grpc" -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc(
|
||||
grpcStatus = responseGrpcStatus!!,
|
||||
)
|
||||
// otherwise tread like http
|
||||
else -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http(
|
||||
httpCode = responseHttpCode!!,
|
||||
)
|
||||
},
|
||||
specificInfos = specificInfos,
|
||||
isImage = isImage,
|
||||
durationFormatted = durationFormatted,
|
||||
byteSizeFormatted = ByteFormatter.formatBytes(responseSize)
|
||||
byteSizeFormatted = ByteFormatter.formatBytes(responseSize),
|
||||
statusFormatted = extractStatus(specificInfos)
|
||||
)
|
||||
}
|
||||
FloconNetworkResponseOnlyDomainModel(
|
||||
|
|
|
|||
|
|
@ -14,12 +14,15 @@ data class FloconNetworkCallDomainModel(
|
|||
val startTime: Long,
|
||||
val startTimeFormatted: String,
|
||||
val method: String,
|
||||
val methodFormatted: String,
|
||||
val headers: Map<String, String>,
|
||||
val body: String?,
|
||||
val byteSize: Long,
|
||||
val byteSizeFormatted: String,
|
||||
val isMocked: Boolean,
|
||||
val specificInfos: SpecificInfos,
|
||||
val domainFormatted: String, // extracted from url
|
||||
val queryFormatted: String, // extracted from url
|
||||
) {
|
||||
sealed interface SpecificInfos {
|
||||
data object Http: SpecificInfos
|
||||
|
|
@ -35,6 +38,7 @@ data class FloconNetworkCallDomainModel(
|
|||
|
||||
val durationMs: Double
|
||||
val durationFormatted: String
|
||||
val statusFormatted: String // extracted from response
|
||||
|
||||
data class Success(
|
||||
override val durationMs: Double,
|
||||
|
|
@ -45,7 +49,8 @@ data class FloconNetworkCallDomainModel(
|
|||
val byteSize: Long,
|
||||
val byteSizeFormatted: String,
|
||||
val specificInfos: SpecificInfos,
|
||||
val isImage: Boolean
|
||||
val isImage: Boolean,
|
||||
override val statusFormatted: String, // extracted from response
|
||||
) : Response {
|
||||
sealed interface SpecificInfos {
|
||||
data class Http(
|
||||
|
|
@ -64,6 +69,7 @@ data class FloconNetworkCallDomainModel(
|
|||
override val durationMs: Double,
|
||||
override val durationFormatted: String,
|
||||
val issue: String,
|
||||
override val statusFormatted: String, // extracted from response
|
||||
) : Response
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue