From 7c6dbca98610046710070bc87a9730a5b7a1a701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 25 Aug 2020 10:46:50 +0200 Subject: [PATCH] [API] Implement basic profile archiving. --- .../szczodrzynski/edziennik/MainActivity.kt | 6 +- .../data/api/edziennik/EdziennikTask.kt | 25 +++++- .../data/api/edziennik/ProfileArchiver.kt | 88 +++++++++++++++++++ .../szczodrzynski/edziennik/data/db/AppDb.kt | 5 +- .../edziennik/data/db/entity/Profile.kt | 8 +- .../data/db/migration/Migration89.kt | 10 +++ .../ui/modules/debug/LabPageFragment.kt | 6 ++ app/src/main/res/layout/lab_fragment.xml | 7 ++ 8 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration89.kt diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 3033f0f0..54db8814 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -299,6 +299,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope { b.nightlyText.isVisible = true b.nightlyText.text = "Nightly\n"+BuildConfig.VERSION_NAME.substringAfterLast(".") } + else if (BuildConfig.VERSION_NAME.contains("daily")) { + b.nightlyText.isVisible = true + b.nightlyText.text = "Daily\n"+BuildConfig.VERSION_NAME.substringAfterLast(".") + } else b.nightlyText.isVisible = false @@ -399,7 +403,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { } app.db.profileDao().all.observe(this, Observer { profiles -> - drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList()) + drawer.setProfileList(profiles.filter { it.id >= 0 && !it.archived }.toMutableList()) drawer.currentProfile = App.profileId }) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt index ce50bfad..90780d7b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt @@ -26,6 +26,7 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.utils.Utils.d +import pl.szczodrzynski.edziennik.utils.models.Date open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) { companion object { @@ -72,10 +73,28 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa private var edziennikInterface: EdziennikInterface? = null internal fun run(app: App, taskCallback: EdziennikCallback) { - if (profile?.archived == true) { - taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED)) - return + profile?.let { profile -> + if (profile.dateYearEnd.month > 6) { + profile.dateYearEnd.month = 6 + profile.dateYearEnd.day = 30 + } + if (profile.archived) { + d(TAG, "The profile $profileId is archived") + taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED)) + return + } + else if (Date.getToday() >= profile.dateYearEnd) { + d(TAG, "The profile $profileId's year ended on ${profile.dateYearEnd}, archiving") + ProfileArchiver(app, profile) + } + if (Date.getToday() < profile.dateSemester1Start) { + d(TAG, "The profile $profileId's school year has not started yet; aborting sync") + cancel() + taskCallback.onCompleted() + return + } } + edziennikInterface = when (loginStore.type) { LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt new file mode 100644 index 00000000..7c8e9aa9 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt @@ -0,0 +1,88 @@ +package pl.szczodrzynski.edziennik.data.api.edziennik + +import android.content.Intent +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.Intent +import pl.szczodrzynski.edziennik.data.api.* +import pl.szczodrzynski.edziennik.data.db.entity.Profile +import pl.szczodrzynski.edziennik.utils.Utils.d +import pl.szczodrzynski.edziennik.utils.models.Date + +class ProfileArchiver(val app: App, val profile: Profile) { + companion object { + private const val TAG = "ProfileArchiver" + } + + init { + if (profile.archiveId == null) + profile.archiveId = profile.id + d(TAG, "Processing ${profile.name}#${profile.id}, archiveId = ${profile.archiveId}") + + profile.archived = true + app.db.profileDao().add(profile) + //app.db.metadataDao().setAllSeen(profile.id, true) + app.db.notificationDao().clear(profile.id) + app.db.endpointTimerDao().clear(profile.id) + d(TAG, "Archived profile ${profile.id} saved") + profile.archived = false + + // guess the nearest school year + val today = Date.getToday() + profile.studentSchoolYearStart = when { + today.month <= profile.dateYearEnd.month -> today.year - 1 + else -> today.year + } + + // set default semester dates + profile.dateSemester1Start = Date(profile.studentSchoolYearStart, 9, 1) + profile.dateSemester2Start = Date(profile.studentSchoolYearStart + 1, 2, 1) + profile.dateYearEnd = Date(profile.studentSchoolYearStart + 1, 6, 30) + + val oldId = profile.id + val newId = (app.db.profileDao().lastId ?: profile.id) + 1 + profile.id = newId + profile.subname = "Nowy rok szkolny - ${profile.studentSchoolYearStart}" + profile.studentClassName = null + + d(TAG, "New profile ID for ${profile.name}: ${profile.id}") + + when (profile.loginStoreType) { + LOGIN_TYPE_LIBRUS -> { + profile.removeStudentData("isPremium") + profile.removeStudentData("pushDeviceId") + profile.removeStudentData("startPointsSemester1") + profile.removeStudentData("startPointsSemester2") + profile.removeStudentData("enablePointGrades") + profile.removeStudentData("enableDescriptiveGrades") + } + LOGIN_TYPE_MOBIDZIENNIK -> { + + } + LOGIN_TYPE_VULCAN -> { + // DataVulcan.isApiLoginValid() returns false so it will update the semester + profile.removeStudentData("currentSemesterEndDate") + } + LOGIN_TYPE_IDZIENNIK -> { + profile.removeStudentData("schoolYearId") + } + LOGIN_TYPE_EDUDZIENNIK -> { + + } + LOGIN_TYPE_PODLASIE -> { + + } + } + + d(TAG, "Processed student data: ${profile.studentData}") + + app.db.profileDao().add(profile) + + if (app.profileId == oldId) { + val intent = Intent( + Intent.ACTION_MAIN, + "profileId" to newId + ) + app.sendBroadcast(intent) + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt index 333967b0..aee8e3af 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt @@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.* LibrusLesson::class, TimetableManual::class, Metadata::class -], version = 88) +], version = 89) @TypeConverters( ConverterTime::class, ConverterDate::class, @@ -173,7 +173,8 @@ abstract class AppDb : RoomDatabase() { Migration85(), Migration86(), Migration87(), - Migration88() + Migration88(), + Migration89() ).allowMainThreadQueries().build() } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt index 50ad82a7..e9d931a5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt @@ -28,7 +28,7 @@ import pl.szczodrzynski.navlib.getDrawableFromRes @Entity(tableName = "profiles", primaryKeys = ["profileId"]) open class Profile( @ColumnInfo(name = "profileId") - override val id: Int, + override var id: Int, /* needs to be var for ProfileArchiver */ val loginStoreId: Int, val loginStoreType: Int, @@ -64,6 +64,12 @@ open class Profile( var empty = true var archived = false + /** + * A unique ID matching [archived] profiles with current ones + * and vice-versa. + */ + var archiveId: Int? = null + var syncEnabled = true var enableSharedEvents = true var registration = REGISTRATION_UNSPECIFIED diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration89.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration89.kt new file mode 100644 index 00000000..ce665d1f --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration89.kt @@ -0,0 +1,10 @@ +package pl.szczodrzynski.edziennik.data.db.migration + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration89 : Migration(88, 89) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE profiles ADD COLUMN archiveId INTEGER DEFAULT NULL;") + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt index bad9fd9f..304a7df7 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt @@ -62,6 +62,12 @@ class LabPageFragment : LazyFragment(), CoroutineScope { app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}") } + b.unarchive.onClick { + app.profile.archived = false + app.profile.archiveId = null + app.profileSave() + } + val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity) startCoroutineTimer(500L, 300L) { val text = app.cookieJar.sessionCookies diff --git a/app/src/main/res/layout/lab_fragment.xml b/app/src/main/res/layout/lab_fragment.xml index 279c241c..acc924a7 100644 --- a/app/src/main/res/layout/lab_fragment.xml +++ b/app/src/main/res/layout/lab_fragment.xml @@ -61,6 +61,13 @@ android:layout_height="wrap_content" android:fontFamily="monospace" tools:text="Cookies:\n\nsynergia.librus.pl\n DZIENNIKSID=L01~1234567890abcdef"/> + +