Skip to content

Commit

Permalink
Merge pull request #87
Browse files Browse the repository at this point in the history
Create and download extracts after logging in
  • Loading branch information
Jacob3075 authored Oct 29, 2023
2 parents ee446fc + 51c92ce commit bc22cc9
Show file tree
Hide file tree
Showing 70 changed files with 45,023 additions and 280 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ captures/
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml

.idea/httpRequests

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
Expand Down
2 changes: 2 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/dictionaries/jacob.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 0 additions & 24 deletions .idea/kotlinScripting.xml

This file was deleted.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.jacob.wakatimeapp.home.ui.destinations.ExtractUserDataPageDestination
import com.jacob.wakatimeapp.home.ui.destinations.HomePageDestination
import com.jacob.wakatimeapp.home.ui.extract.ExtractUserDataNavigator
import com.jacob.wakatimeapp.login.ui.LoginPageNavigator
import com.jacob.wakatimeapp.login.ui.destinations.LoadingPageDestination
import com.jacob.wakatimeapp.login.ui.destinations.LoginPageDestination
import com.jacob.wakatimeapp.search.ui.SearchProjectsNavigator
import com.jacob.wakatimeapp.search.ui.destinations.SearchProjectsDestination
Expand All @@ -26,14 +27,27 @@ class ApplicationNavigator(private val navigator: DestinationsNavigator) :

class ExtractUserDataNavigatorImpl(private val navigator: DestinationsNavigator) :
ExtractUserDataNavigator {
override fun toHomePage() = navigator.navigate(HomePageDestination)
override fun toHomePageFromExtractUserData() = navigator.navigate(
HomePageDestination,
navOptions = navOptions { popUpTo(ExtractUserDataPageDestination.route) { inclusive = true } },
)
}

class LoginPageNavigatorImpl(private val navigator: DestinationsNavigator) : LoginPageNavigator {
override fun toExtractUserDataPage() = navigator.navigate(
ExtractUserDataPageDestination,
navOptions = navOptions { popUpTo(LoginPageDestination.route) { inclusive = true } },
)

override fun toLoginPage() = navigator.navigate(
LoginPageDestination,
navOptions = navOptions { popUpTo(LoadingPageDestination.route) { inclusive = true } },
)

override fun toHomePageFromLoading() = navigator.navigate(
HomePageDestination,
navOptions = navOptions { popUpTo(LoadingPageDestination.route) { inclusive = true } },
)
}

class HomePageNavigatorImpl(private val navigator: DestinationsNavigator) : HomePageNavigator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import net.openid.appauth.AuthState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,26 @@ import retrofit2.Response
import timber.log.Timber

abstract class BaseNetworkData(private val authTokenProvider: AuthTokenProvider) {
protected val token
private val token
get() = runBlocking { authTokenProvider.getFreshToken().first() }

protected suspend fun <T> makeSafeApiCall(
apiCall: suspend () -> Response<T>,
apiCall: suspend (String) -> Response<T>,
methodName: String,
): Either<Error, T> = try {
apiCall().checkResponse()
apiCall("Bearer $token").checkResponse()
} catch (exception: Exception) {
Timber.e(exception)
handleNetworkException(exception, methodName)
}
}

private fun <T> Response<T>.checkResponse(): Either<Error, T> =
if (isSuccessful) body()!!.right() else NetworkErrors.create(message(), code()).left()
private fun <T> Response<T>.checkResponse(): Either<Error, T> {
return if (isSuccessful) body()!!.right() else NetworkErrors.create(
errorBody()?.string() ?: "",
code(),
).left()
}

private fun handleNetworkException(
exception: Throwable,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
class DependencyDTO
data class DependencyDTO(
val decimal: String,
val digital: String,
val hours: Int,
val minutes: Int,
val name: String,
val percent: Double,
val seconds: Int,
val text: String,
@SerialName("total_seconds") val totalSeconds: Double,
)

@Serializable
data class EditorDTO(
Expand Down Expand Up @@ -72,3 +82,16 @@ data class EntityDTO(
val type: String,
@SerialName("total_seconds") val totalSeconds: Double,
)

@Serializable
data class CategoryDTO(
val decimal: String,
val digital: String,
val hours: Int,
val minutes: Int,
val name: String,
val percent: Double,
val seconds: Int,
val text: String,
@SerialName("total_seconds") val totalSeconds: Double,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.jacob.wakatimeapp.core.common.data.dtos

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ExtractedDataDTO(
val days: List<DayDTO>,
val range: RangeDTO,
val user: UserDTO,
) {
@Serializable
data class DayDTO(
val categories: List<CategoryDTO>,
val date: String,
val dependencies: List<DependencyDTO>,
val editors: List<EditorDTO>,
val languages: List<LanguageDTO>,
val machines: List<MachineDTO>,
val projects: List<ProjectDTO>,
@SerialName("grand_total") val grandTotal: GrandTotalDTO,
@SerialName("operating_systems") val operatingSystems: List<OperatingSystemDTO>,
) {

@Serializable
data class ProjectDTO(
val branches: List<BranchDTO>,
val categories: List<CategoryDTO>,
val dependencies: List<DependencyDTO>,
val editors: List<EditorDTO>,
val entities: List<EntityDTO>,
val languages: List<LanguageDTO>,
val machines: List<MachineDTO>,
val name: String,
@SerialName("grand_total") val grandTotal: GrandTotalDTO,
@SerialName("operating_systems") val operatingSystems: List<OperatingSystemDTO>,
) {
@Serializable
data class BranchDTO(
val decimal: String,
val digital: String,
val hours: Int,
val minutes: Int,
val name: String,
val percent: Double,
val seconds: Int,
val text: String,
@SerialName("total_seconds") val totalSeconds: Double,
)
}
}

@Serializable
data class RangeDTO(
val end: Int,
val start: Int,
)

@Serializable
data class UserDTO(
val bio: String?,
val city: String?,
val email: String?,
val id: String,
val location: String?,
val photo: String?,
val plan: String?,
val timeout: Int?,
val timezone: String?,
val username: String,
val website: String?,
@SerialName("color_scheme") val colorScheme: String?,
@SerialName("created_at") val createdAt: String?,
@SerialName("date_format") val dateFormat: String?,
@SerialName("default_dashboard_range") val defaultDashboardRange: String?,
@SerialName("display_name") val displayName: String?,
@SerialName("durations_slice_by") val durationsSliceBy: String?,
@SerialName("full_name") val fullName: String?,
@SerialName("github_username") val githubUsername: String?,
@SerialName("has_basic_features") val hasBasicFeatures: Boolean,
@SerialName("has_premium_features") val hasPremiumFeatures: Boolean,
@SerialName("human_readable_website") val humanReadableWebsite: String?,
@SerialName("invoice_id_format") val invoiceIdFormat: String?,
@SerialName("is_email_confirmed") val isEmailConfirmed: Boolean,
@SerialName("is_email_public") val isEmailPublic: Boolean,
@SerialName("is_hireable") val isHireable: Boolean,
@SerialName("is_onboarding_finished") val isOnboardingFinished: Boolean,
@SerialName("languages_used_public") val languagesUsedPublic: Boolean,
@SerialName("last_heartbeat_at") val lastHeartbeatAt: String?,
@SerialName("last_plugin") val lastPlugin: String?,
@SerialName("last_plugin_name") val lastPluginName: String?,
@SerialName("last_project") val lastProject: String?,
@SerialName("linkedin_username") val linkedinUsername: String?,
@SerialName("logged_time_public") val loggedTimePublic: Boolean,
@SerialName("meetings_over_coding") val meetingsOverCoding: Boolean,
@SerialName("modified_at") val modifiedAt: String?,
@SerialName("needs_payment_method") val needsPaymentMethod: Boolean,
@SerialName("photo_public") val photoPublic: Boolean,
@SerialName("profile_url") val profileUrl: String?,
@SerialName("profile_url_escaped") val profileUrlEscaped: String?,
@SerialName("public_email") val publicEmail: String?,
@SerialName("public_profile_time_range") val publicProfileTimeRange: String?,
@SerialName("share_all_time_badge") val shareAllTimeBadge: Boolean,
@SerialName("share_last_year_days") val shareLastYearDays: String?,
@SerialName("show_machine_name_ip") val showMachineNameIp: Boolean,
@SerialName("time_format_24hr") val timeFormat24hr: Boolean,
@SerialName("time_format_display") val timeFormatDisplay: String?,
@SerialName("twitter_username") val twitterUsername: String?,
@SerialName("weekday_start") val weekdayStart: Int,
@SerialName("writes_only") val writesOnly: Boolean,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.jacob.wakatimeapp.core.common.data.local

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.jacob.wakatimeapp.core.common.data.local.dao.ApplicationDao
import com.jacob.wakatimeapp.core.common.data.local.entities.DayEntity
import com.jacob.wakatimeapp.core.common.data.local.entities.ProjectPerDay

@Database(entities = [DayEntity::class, ProjectPerDay::class], version = 1)
@TypeConverters(WtaTypeConverters::class)
abstract class AppDatabase : RoomDatabase() {
internal abstract fun applicationDao(): ApplicationDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.jacob.wakatimeapp.core.common.data.local

import com.jacob.wakatimeapp.core.common.data.dtos.ExtractedDataDTO
import com.jacob.wakatimeapp.core.common.data.local.dao.ApplicationDao
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.datetime.LocalDate

@Singleton
class WakaTimeAppDB @Inject constructor(
private val applicationDao: ApplicationDao,
) {
suspend fun getStatsForDay(date: LocalDate) = applicationDao.getStatsForDay(date)

suspend fun getStatsForProject(name: String) = applicationDao.getStatsForProject(name)

suspend fun getDateRangeInDb() = applicationDao.getDateRangeInDb()

suspend fun insertExtractedData(extractedDataDTO: ExtractedDataDTO) =
applicationDao.insertStatesForDay(extractedDataDTO)
}
Loading

0 comments on commit bc22cc9

Please sign in to comment.