Skip to content

Commit

Permalink
WTA #82: updated mappers and db api
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob3075 committed Dec 6, 2023
1 parent f3b21a4 commit 1377ff5
Show file tree
Hide file tree
Showing 27 changed files with 254 additions and 297 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import arrow.core.Either
import com.jacob.wakatimeapp.core.common.data.dtos.ExtractedDataDTO
import com.jacob.wakatimeapp.core.common.data.local.dao.ApplicationDao
import com.jacob.wakatimeapp.core.common.data.local.entities.DayWithProjects
import com.jacob.wakatimeapp.core.common.data.mappers.toDailyStateAggregate
import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay
import com.jacob.wakatimeapp.core.common.data.mappers.toDayWithProjects
import com.jacob.wakatimeapp.core.common.data.mappers.toProjectDetails
import com.jacob.wakatimeapp.core.models.DailyStatsAggregate
import com.jacob.wakatimeapp.core.models.DetailedDailyStats
import com.jacob.wakatimeapp.core.models.Error
import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.project.ProjectDetails
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.datetime.LocalDate
Expand All @@ -32,19 +29,15 @@ class WakaTimeAppDB @Inject constructor(
applicationDao.updateDbWithNewData(detailedDailyStats)
}.mapLeft { Error.DatabaseError.UnknownError("could not insert aggregate stats data into db", it) }

suspend fun getAggregateStatsForRange(startDate: LocalDate, endDate: LocalDate): Either<Error, DailyStatsAggregate> = Either.catch {
applicationDao.getStatsForRange(startDate, endDate).toDayWithProjects().toDailyStateAggregate()
}.mapLeft { Error.DatabaseError.UnknownError("could not get stats for range ($startDate - $endDate)", it) }

suspend fun getStatsForRange(startDate: LocalDate, endDate: LocalDate): Either<Error, List<DayWithProjects>> = Either.catch {
applicationDao.getStatsForRange(startDate, endDate).toDayWithProjects()
}.mapLeft { Error.DatabaseError.UnknownError("could not get stats for range ($startDate - $endDate)", it) }

suspend fun getAllProjects(): Either<Error, List<ProjectDetails>> = Either.catch {
applicationDao.getAllProjects().toProjectDetails()
suspend fun getAllProjects(): Either<Error, List<ProjectPerDay>> = Either.catch {
applicationDao.getAllProjects()
}.mapLeft { Error.DatabaseError.UnknownError("could not get all projects", it) }

suspend fun getDetailsForProject(projectName: String): Either<Error, List<ProjectDetails>> = Either.catch {
applicationDao.getDetailsForProject(projectName).toProjectDetails()
suspend fun getDetailsForProject(projectName: String): Either<Error, List<ProjectPerDay>> = Either.catch {
applicationDao.getDetailsForProject(projectName)
}.mapLeft { Error.DatabaseError.UnknownError("could not get details for project: $projectName", it) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,13 @@ package com.jacob.wakatimeapp.core.common.data.mappers
import com.jacob.wakatimeapp.core.common.data.local.entities.DayEntity
import com.jacob.wakatimeapp.core.common.data.local.entities.DayWithProjects
import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay
import com.jacob.wakatimeapp.core.models.DailyStats
import com.jacob.wakatimeapp.core.models.DailyStatsAggregate
import com.jacob.wakatimeapp.core.models.DetailedDailyStats
import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.core.models.project.DetailedProjectStatsForDay
import com.jacob.wakatimeapp.core.models.project.Project
import com.jacob.wakatimeapp.core.models.project.ProjectDetails
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.datetime.LocalDate

fun List<DayWithProjects>.toDailyStateAggregate() = DailyStatsAggregate(
values = map {
DailyStats(
timeSpent = it.day.grandTotal,
projectsWorkedOn = it.projectsForDay.map { projectPerDay ->
Project(
time = projectPerDay.grandTotal,
name = projectPerDay.name,
percent = projectPerDay.grandTotal.totalSeconds / it.day.grandTotal.totalSeconds,
)
}.toImmutableList(),
mostUsedLanguage = "",
mostUsedEditor = "",
mostUsedOs = "",
date = it.day.date,
)
},
)

fun List<ProjectPerDay>.toModel(): ImmutableList<Project> {
val totalSeconds = sumOf { it.grandTotal.totalSeconds }
return map {
Expand All @@ -44,19 +20,17 @@ fun List<ProjectPerDay>.toModel(): ImmutableList<Project> {
)
}.toImmutableList()
}
fun DetailedProjectStatsForDay.toEntity(dayId: LocalDate): ProjectPerDay {
return ProjectPerDay(
projectPerDayId = 0,
day = dayId,
name = name,
grandTotal = totalTime,
editors = editors,
languages = languages,
operatingSystems = operatingSystems,
branches = branches,
machines = machines,
)
}
fun DetailedProjectStatsForDay.toEntity(dayId: LocalDate) = ProjectPerDay(
projectPerDayId = 0,
day = dayId,
name = name,
grandTotal = totalTime,
editors = editors,
languages = languages,
operatingSystems = operatingSystems,
branches = branches,
machines = machines,
)

fun DetailedDailyStats.toEntity() = DayEntity(
date = date,
Expand All @@ -67,23 +41,6 @@ fun DetailedDailyStats.toEntity() = DayEntity(
machines = emptyList(),
)

fun List<ProjectPerDay>.toProjectDetails() = groupBy(ProjectPerDay::name)
.map {
it.value
.fold(
ProjectDetails(
name = it.key,
time = Time.ZERO,
range = Range(
startDate = it.value.minOf(ProjectPerDay::day),
endDate = it.value.maxOf(ProjectPerDay::day),
),
),
) { acc, projectPerDay ->
acc.copy(time = acc.time + projectPerDay.grandTotal)
}
}

fun Map<DayEntity, List<ProjectPerDay>>.toDayWithProjects() = map { (dayEntity, projectsPerDay) ->
DayWithProjects(
day = dayEntity,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.jacob.wakatimeapp.core.models.project

import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.Time
import kotlinx.serialization.Serializable

Expand All @@ -10,5 +9,3 @@ data class Project(
val name: String,
val percent: Double,
)

data class ProjectDetails(val name: String, val time: Time, val range: Range)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.jacob.wakatimeapp.details.data

import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay
import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.details.domain.models.ProjectDetails

internal fun List<ProjectPerDay>.toProjectDetails() = groupBy(ProjectPerDay::name)
.map {
it.value
.fold(
ProjectDetails(
name = it.key,
time = Time.ZERO,
range = Range(
startDate = it.value.minOf(ProjectPerDay::day),
endDate = it.value.maxOf(ProjectPerDay::day),
),
),
) { acc, projectPerDay ->
acc.copy(time = acc.time + projectPerDay.grandTotal)
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
package com.jacob.wakatimeapp.details.domain.models

import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.Time

data class ProjectDetails(
val name: String,
val time: Time,
val range: Range,
)
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.jacob.wakatimeapp.details.domain.usecases

import com.jacob.wakatimeapp.core.common.data.local.WakaTimeAppDB
import com.jacob.wakatimeapp.details.data.ProjectDetailsNetworkData
import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay
import com.jacob.wakatimeapp.details.data.toProjectDetails
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
internal class GetProjectDetailsUC @Inject constructor(
private val projectDetailsNetworkData: ProjectDetailsNetworkData,
private val wakaTimeAppDB: WakaTimeAppDB,
) {
suspend operator fun invoke(projectName: String) =
wakaTimeAppDB.getDetailsForProject(projectName)
wakaTimeAppDB.getDetailsForProject(projectName).map(List<ProjectPerDay>::toProjectDetails)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import arrow.core.left
import arrow.core.raise.either
import com.jacob.wakatimeapp.core.common.utils.InstantProvider
import com.jacob.wakatimeapp.core.models.Error
import com.jacob.wakatimeapp.details.data.ProjectDetailsNetworkData
import com.jacob.wakatimeapp.details.domain.models.DetailedProjectStatsUiData
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -15,7 +14,6 @@ import kotlinx.coroutines.Dispatchers
@Singleton
internal class GetProjectStatsUC @Inject constructor(
dispatcher: CoroutineContext = Dispatchers.IO,
private val projectStatsNetworkData: ProjectDetailsNetworkData,
private val instantProvider: InstantProvider,
) {
private val ioScope = CoroutineScope(dispatcher)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import com.jacob.wakatimeapp.core.common.utils.log
import com.jacob.wakatimeapp.core.models.Error
import com.jacob.wakatimeapp.core.models.Error.DatabaseError
import com.jacob.wakatimeapp.home.data.local.entities.Last7DaysStatsEntity
import com.jacob.wakatimeapp.home.data.local.mappers.toEntity
import com.jacob.wakatimeapp.home.data.local.mappers.toModel
import com.jacob.wakatimeapp.home.data.mappers.toEntity
import com.jacob.wakatimeapp.home.data.mappers.toModel
import com.jacob.wakatimeapp.home.domain.models.Last7DaysStats
import com.jacob.wakatimeapp.home.domain.models.Streak
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.jacob.wakatimeapp.home.data.local.mappers
package com.jacob.wakatimeapp.home.data.mappers

import com.jacob.wakatimeapp.core.common.data.local.entities.DayWithProjects
import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.jacob.wakatimeapp.home.data.mappers

import com.jacob.wakatimeapp.core.common.data.dtos.EditorDTO
import com.jacob.wakatimeapp.core.common.data.dtos.LanguageDTO
import com.jacob.wakatimeapp.core.common.data.dtos.OperatingSystemDTO
import com.jacob.wakatimeapp.core.common.data.dtos.ProjectDTO
import com.jacob.wakatimeapp.core.common.data.local.entities.DayWithProjects
import com.jacob.wakatimeapp.core.common.data.mappers.toModel
import com.jacob.wakatimeapp.core.models.DailyStats
import com.jacob.wakatimeapp.core.models.DailyStatsAggregate
import com.jacob.wakatimeapp.core.models.Range
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.core.models.WeeklyStats
import com.jacob.wakatimeapp.core.models.project.Project
import com.jacob.wakatimeapp.home.data.network.dtos.GetDailyStatsResDTO
import com.jacob.wakatimeapp.home.data.network.dtos.GetLast7DaysStatsResDTO
import com.jacob.wakatimeapp.home.data.network.dtos.GetStatsForRangeResDTO
import com.jacob.wakatimeapp.home.data.network.dtos.GetStatsForRangeResDTO.Data
import kotlinx.collections.immutable.toImmutableList
import kotlinx.datetime.toLocalDate

internal fun List<DayWithProjects>.toDailyStateAggregate() = DailyStatsAggregate(
values = map {
DailyStats(
timeSpent = it.day.grandTotal,
projectsWorkedOn = it.projectsForDay.map { projectPerDay ->
Project(
time = projectPerDay.grandTotal,
name = projectPerDay.name,
percent = projectPerDay.grandTotal.totalSeconds / it.day.grandTotal.totalSeconds,
)
}.toImmutableList(),
mostUsedLanguage = "",
mostUsedEditor = "",
mostUsedOs = "",
date = it.day.date,
)
},
)

internal fun GetDailyStatsResDTO.toModel() = DailyStats(
timeSpent = Time.createFrom(cumulativeTotal.digital, cumulativeTotal.decimal),
projectsWorkedOn = data.first().projects.map(ProjectDTO::toModel).toImmutableList(),
mostUsedLanguage = "",
mostUsedEditor = "",
mostUsedOs = "",
date = data.first().range.date.toLocalDate(),
)

internal fun GetStatsForRangeResDTO.toModel() = DailyStatsAggregate(
values = getDailyStatsFromDto(data),
)

private fun getDailyStatsFromDto(data: List<Data>) = data.map {
DailyStats(
timeSpent = Time.createFrom(
digitalString = it.grandTotal.digital,
decimal = it.grandTotal.decimal,
),
mostUsedEditor = it.editors.maxByOrNull(EditorDTO::percent)?.name ?: "NA",
mostUsedLanguage = it.languages.maxByOrNull(LanguageDTO::percent)?.name ?: "NA",
mostUsedOs = it.operatingSystems.maxByOrNull(OperatingSystemDTO::percent)?.name ?: "NA",
date = it.range.date.toLocalDate(),
projectsWorkedOn = it.projects
.filterNot(ProjectDTO::isUnknownProject)
.map(ProjectDTO::toModel)
.toImmutableList(),
)
}

internal fun GetLast7DaysStatsResDTO.toModel() = WeeklyStats(
totalTime = Time.createFrom(cumulativeTotal.digital, cumulativeTotal.decimal),
dailyStats = getDailyStatsFromDto(data),
range = Range(startDate = start, endDate = end),
)

private fun getDailyStatsFromDto(data: List<GetLast7DaysStatsResDTO.Data>) = data.map {
DailyStats(
timeSpent = Time.createFrom(
digitalString = it.grandTotal.digital,
decimal = it.grandTotal.decimal,
),
mostUsedEditor = it.editors.maxByOrNull(EditorDTO::percent)?.name ?: "NA",
mostUsedLanguage = it.languages.maxByOrNull(LanguageDTO::percent)?.name ?: "NA",
mostUsedOs = it.operatingSystems.maxByOrNull(OperatingSystemDTO::percent)?.name ?: "NA",
date = it.range.date.toLocalDate(),
projectsWorkedOn = it.projects
.filterNot(ProjectDTO::isUnknownProject)
.map(ProjectDTO::toModel)
.toImmutableList(),
)
}.toImmutableList()
Loading

0 comments on commit 1377ff5

Please sign in to comment.