Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 114364a0 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

feat:3141: Compute the weekly report each end of week at 11:00

parent 6205a4f0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ dependencies {
        libs.androidx.navigation.fragment,
        libs.androidx.navigation.ui,
        libs.androidx.viewpager2,
        libs.androidx.work.ktx,

        libs.bundles.koin,

+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase
import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase
import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
import foundation.e.advancedprivacy.externalinterfaces.workers.WeeklyReportWorker
import foundation.e.advancedprivacy.trackers.services.UpdateTrackersWorker
import foundation.e.lib.telemetry.Telemetry
import kotlinx.coroutines.CoroutineScope
@@ -49,6 +50,7 @@ class AdvancedPrivacyApplication : Application() {

    private fun initBackgroundSingletons() {
        UpdateTrackersWorker.periodicUpdate(this)
        WeeklyReportWorker.scheduleNext(this)

        WarningDialog.startListening(
            get(ShowFeaturesWarningUseCase::class.java),
+8 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import foundation.e.advancedprivacy.core.coreModule
import foundation.e.advancedprivacy.data.repositories.AppListRepository
import foundation.e.advancedprivacy.data.repositories.LocalStateRepositoryImpl
import foundation.e.advancedprivacy.data.repositories.ResourcesRepository
import foundation.e.advancedprivacy.data.repositories.WeeklyReportLocalRepository
import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.DisplayableApp
import foundation.e.advancedprivacy.domain.entities.ProfileType
@@ -102,6 +103,13 @@ val appModule = module {
        LocalStateRepositoryImpl(context = androidContext())
    }

    single {
        WeeklyReportLocalRepository(
            context = androidContext(),
            json = get()
        )
    }

    single<ApplicationDescription>(named("AdvancedPrivacy")) {
        ApplicationDescription(
            packageName = androidContext().packageName,
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 E FOUNDATION
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.advancedprivacy.data.repositories

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import foundation.e.advancedprivacy.core.utils.getValue
import foundation.e.advancedprivacy.core.utils.removeKey
import foundation.e.advancedprivacy.domain.entities.weeklyreport.WeeklyReport
import kotlinx.serialization.json.Json
import timber.log.Timber

class WeeklyReportLocalRepository(
    context: Context,
    private val json: Json
) {

    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "weeklyreport_datastore")
    private val store = context.dataStore

    private val weeklyReportsKey = stringPreferencesKey("weeklyReports")

    suspend fun setLastWeeklyReport(report: WeeklyReport) {
        store.updateData { pref ->
            val preferences = pref.toMutablePreferences()
            val reports = preferences.get(weeklyReportsKey)?.let {
                runCatching { json.decodeFromString<List<WeeklyReport>>(it) }.getOrNull()
            } ?: emptyList()
            val updatedReport: List<WeeklyReport> = reports + report
            preferences.set(weeklyReportsKey, json.encodeToString(updatedReport))
            preferences
        }
    }

    suspend fun getLastWeeklyReport(): WeeklyReport? {
        return getLast99Reports().lastOrNull()
    }

    suspend fun getLast99Reports(): List<WeeklyReport> {
        return store.getValue(weeklyReportsKey)?.let {
            runCatching {
                json.decodeFromString<List<WeeklyReport>>(it).takeLast(99)
            }.onFailure {
                Timber.e("Can't deserialize weeklyReports")
                store.removeKey(weeklyReportsKey)
            }.getOrNull()
        } ?: emptyList()
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -17,10 +17,14 @@

package foundation.e.advancedprivacy.domain.entities.weeklyreport

import foundation.e.advancedprivacy.core.utils.InstantSerializer
import java.time.Instant
import kotlinx.serialization.Serializable

@Serializable
data class WeeklyReport(
    @Serializable(with = InstantSerializer::class)
    val timestamp: Instant,
    val statType: StatType,
    val labelId: LabelId,
    val primaryValue: String,
Loading