mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-02-23 00:04:44 +01:00
Merge branch 'bugfix/2.5.2' into develop
This commit is contained in:
commit
27eb0588d7
@ -27,8 +27,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 150
|
versionCode 151
|
||||||
versionName "2.5.1"
|
versionName "2.5.2"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
resValue "string", "app_name", "Wulkanowy"
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
@ -161,7 +161,7 @@ play {
|
|||||||
track = 'production'
|
track = 'production'
|
||||||
releaseStatus = ReleaseStatus.IN_PROGRESS
|
releaseStatus = ReleaseStatus.IN_PROGRESS
|
||||||
userFraction = 0.50d
|
userFraction = 0.50d
|
||||||
updatePriority = 1
|
updatePriority = 3
|
||||||
enabled.set(false)
|
enabled.set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.wulkanowy:sdk:2.5.1'
|
implementation 'io.github.wulkanowy:sdk:2.5.2'
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||||
|
|
||||||
|
2547
app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json
Normal file
2547
app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,7 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
schoolSymbol = student.schoolSymbol
|
schoolSymbol = student.schoolSymbol
|
||||||
studentId = student.studentId
|
studentId = student.studentId
|
||||||
classId = student.classId
|
classId = student.classId
|
||||||
|
isEduOne = student.isEduOne
|
||||||
emptyCookieJarInterceptor = true
|
emptyCookieJarInterceptor = true
|
||||||
|
|
||||||
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
||||||
|
@ -174,6 +174,7 @@ import javax.inject.Singleton
|
|||||||
AutoMigration(from = 58, to = 59),
|
AutoMigration(from = 58, to = 59),
|
||||||
AutoMigration(from = 59, to = 60),
|
AutoMigration(from = 59, to = 60),
|
||||||
AutoMigration(from = 60, to = 61),
|
AutoMigration(from = 60, to = 61),
|
||||||
|
AutoMigration(from = 61, to = 62),
|
||||||
],
|
],
|
||||||
version = AppDatabase.VERSION_SCHEMA,
|
version = AppDatabase.VERSION_SCHEMA,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
@ -182,7 +183,7 @@ import javax.inject.Singleton
|
|||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VERSION_SCHEMA = 61
|
const val VERSION_SCHEMA = 62
|
||||||
|
|
||||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
||||||
Migration2(),
|
Migration2(),
|
||||||
|
@ -9,6 +9,7 @@ import androidx.room.Transaction
|
|||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.StudentIsAuthorized
|
||||||
import io.github.wulkanowy.data.db.entities.StudentName
|
import io.github.wulkanowy.data.db.entities.StudentName
|
||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -23,6 +24,9 @@ abstract class StudentDao {
|
|||||||
@Delete
|
@Delete
|
||||||
abstract suspend fun delete(student: Student)
|
abstract suspend fun delete(student: Student)
|
||||||
|
|
||||||
|
@Update(entity = Student::class)
|
||||||
|
abstract suspend fun update(studentIsAuthorized: StudentIsAuthorized)
|
||||||
|
|
||||||
@Update(entity = Student::class)
|
@Update(entity = Student::class)
|
||||||
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
|
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
|
||||||
|
|
||||||
|
@ -78,6 +78,13 @@ data class Student(
|
|||||||
|
|
||||||
@ColumnInfo(name = "registration_date")
|
@ColumnInfo(name = "registration_date")
|
||||||
val registrationDate: Instant,
|
val registrationDate: Instant,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_authorized", defaultValue = "0")
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_edu_one", defaultValue = "0")
|
||||||
|
val isEduOne: Boolean,
|
||||||
|
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.github.wulkanowy.data.db.entities
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class StudentIsAuthorized(
|
||||||
|
@ColumnInfo(name = "is_authorized", defaultValue = "0")
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
) : Serializable {
|
||||||
|
|
||||||
|
@PrimaryKey
|
||||||
|
var id: Long = 0
|
||||||
|
}
|
@ -34,17 +34,19 @@ fun SdkRegisterUser.mapToPojo(password: String?) = RegisterUser(
|
|||||||
error = it.error,
|
error = it.error,
|
||||||
students = it.subjects
|
students = it.subjects
|
||||||
.filterIsInstance<SdkRegisterStudent>()
|
.filterIsInstance<SdkRegisterStudent>()
|
||||||
.map { registerSubject ->
|
.map { registerStudent ->
|
||||||
RegisterStudent(
|
RegisterStudent(
|
||||||
studentId = registerSubject.studentId,
|
studentId = registerStudent.studentId,
|
||||||
studentName = registerSubject.studentName,
|
studentName = registerStudent.studentName,
|
||||||
studentSecondName = registerSubject.studentSecondName,
|
studentSecondName = registerStudent.studentSecondName,
|
||||||
studentSurname = registerSubject.studentSurname,
|
studentSurname = registerStudent.studentSurname,
|
||||||
className = registerSubject.className,
|
className = registerStudent.className,
|
||||||
classId = registerSubject.classId,
|
classId = registerStudent.classId,
|
||||||
isParent = registerSubject.isParent,
|
isParent = registerStudent.isParent,
|
||||||
semesters = registerSubject.semesters
|
isAuthorized = registerStudent.isAuthorized,
|
||||||
.mapToEntities(registerSubject.studentId),
|
isEduOne = registerStudent.isEduOne,
|
||||||
|
semesters = registerStudent.semesters
|
||||||
|
.mapToEntities(registerStudent.studentId),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -84,6 +86,8 @@ fun RegisterStudent.mapToStudentWithSemesters(
|
|||||||
password = user.password.orEmpty(),
|
password = user.password.orEmpty(),
|
||||||
isCurrent = false,
|
isCurrent = false,
|
||||||
registrationDate = Instant.now(),
|
registrationDate = Instant.now(),
|
||||||
|
isAuthorized = this.isAuthorized,
|
||||||
|
isEduOne = this.isEduOne,
|
||||||
).apply {
|
).apply {
|
||||||
avatarColor = colors.random()
|
avatarColor = colors.random()
|
||||||
},
|
},
|
||||||
|
@ -45,4 +45,6 @@ data class RegisterStudent(
|
|||||||
val classId: Int,
|
val classId: Int,
|
||||||
val isParent: Boolean,
|
val isParent: Boolean,
|
||||||
val semesters: List<Semester>,
|
val semesters: List<Semester>,
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
val isEduOne: Boolean
|
||||||
) : java.io.Serializable
|
) : java.io.Serializable
|
||||||
|
@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.dao.SemesterDao
|
|||||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.StudentIsAuthorized
|
||||||
import io.github.wulkanowy.data.db.entities.StudentName
|
import io.github.wulkanowy.data.db.entities.StudentName
|
||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
@ -15,6 +16,7 @@ import io.github.wulkanowy.data.mappers.mapToPojo
|
|||||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.DispatchersProvider
|
import io.github.wulkanowy.utils.DispatchersProvider
|
||||||
|
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||||
import io.github.wulkanowy.utils.security.Scrambler
|
import io.github.wulkanowy.utils.security.Scrambler
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -99,6 +101,25 @@ class StudentRepository @Inject constructor(
|
|||||||
return student
|
return student
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun checkCurrentStudentAuthorizationStatus() {
|
||||||
|
val student = getCurrentStudent()
|
||||||
|
|
||||||
|
if (!student.isAuthorized) {
|
||||||
|
val currentSemester = semesterDb.loadAll(
|
||||||
|
studentId = student.studentId,
|
||||||
|
classId = student.classId,
|
||||||
|
).getCurrentOrLast()
|
||||||
|
val initializedSdk = wulkanowySdkFactory.create(student, currentSemester)
|
||||||
|
val isAuthorized = initializedSdk.getCurrentStudent()?.isAuthorized ?: false
|
||||||
|
|
||||||
|
if (isAuthorized) {
|
||||||
|
studentDb.update(StudentIsAuthorized(isAuthorized = true).apply {
|
||||||
|
id = student.id
|
||||||
|
})
|
||||||
|
} else throw NoAuthorizationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
|
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
|
||||||
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException()
|
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException()
|
||||||
|
|
||||||
@ -173,3 +194,6 @@ class StudentRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoAuthorizationException : Exception()
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.ui.base
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
import io.github.wulkanowy.sdk.scrapper.exception.AuthorizationRequiredException
|
import io.github.wulkanowy.data.repositories.NoAuthorizationException
|
||||||
import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException
|
import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException
|
||||||
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
||||||
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
|
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
|
||||||
@ -40,7 +40,7 @@ open class ErrorHandler @Inject constructor(@ApplicationContext protected val co
|
|||||||
is ScramblerException -> onDecryptionFailed()
|
is ScramblerException -> onDecryptionFailed()
|
||||||
is BadCredentialsException -> onExpiredCredentials()
|
is BadCredentialsException -> onExpiredCredentials()
|
||||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||||
is AuthorizationRequiredException -> onAuthorizationRequired()
|
is NoAuthorizationException -> onAuthorizationRequired()
|
||||||
is CloudflareVerificationException -> onCaptchaVerificationRequired(error.originalUrl)
|
is CloudflareVerificationException -> onCaptchaVerificationRequired(error.originalUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ class MainPresenter @Inject constructor(
|
|||||||
syncManager.startPeriodicSyncWorker()
|
syncManager.startPeriodicSyncWorker()
|
||||||
|
|
||||||
checkAppSupport()
|
checkAppSupport()
|
||||||
|
checkCurrentStudentAuthorizationStatus()
|
||||||
|
|
||||||
analytics.logEvent("app_open", "destination" to initDestination.toString())
|
analytics.logEvent("app_open", "destination" to initDestination.toString())
|
||||||
Timber.i("Main view was initialized with $initDestination")
|
Timber.i("Main view was initialized with $initDestination")
|
||||||
@ -191,4 +192,13 @@ class MainPresenter @Inject constructor(
|
|||||||
|
|
||||||
view?.showStudentAvatar(currentStudent)
|
view?.showStudentAvatar(currentStudent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkCurrentStudentAuthorizationStatus() {
|
||||||
|
presenterScope.launch {
|
||||||
|
runCatching { studentRepository.checkCurrentStudentAuthorizationStatus() }
|
||||||
|
.onFailure { errorHandler.dispatch(it) }
|
||||||
|
|
||||||
|
Timber.i("Current student authorization status checked")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
Wersja 2.5.1
|
Wersja 2.5.2
|
||||||
|
|
||||||
— dodaliśmy wyświetlanie ogłoszeń
|
— naprawiliśmy omyłkowe wyświetlanie ekranu z wymaganą autoryzacją numerem PESEL
|
||||||
— dodaliśmy opcję przywracania wiadomości z kosza
|
— naprawiliśmy kilka problemów ze stabilnością
|
||||||
— dodaliśmy opcję wyciszania nadawców wiadomości
|
— poprawiliśmy wyświetlanie kolorów we frekwencji
|
||||||
— naprawiliśmy opcjonalne liczenie średniej arytmetycznej, kiedy brak ocen z wagą w drugim semestrze
|
|
||||||
— usprawniliśmy ładowanie frekwencji i planu lekcji
|
|
||||||
— naprawiliśmy usprawiedliwianie nieobecności i autoryzację u użytkowników eduOne
|
|
||||||
— zmieniliśmy komunikat o zmienionym haśle
|
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -5,8 +5,8 @@ import io.github.wulkanowy.data.db.entities.MailboxType
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.Instant.now
|
import java.time.Instant.now
|
||||||
|
import java.time.LocalDate
|
||||||
import io.github.wulkanowy.sdk.pojo.Semester as SdkSemester
|
import io.github.wulkanowy.sdk.pojo.Semester as SdkSemester
|
||||||
|
|
||||||
fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate = LocalDate.now(), end: LocalDate = LocalDate.now(), semesterName: Int = 1) = Semester(
|
fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate = LocalDate.now(), end: LocalDate = LocalDate.now(), semesterName: Int = 1) = Semester(
|
||||||
@ -72,6 +72,8 @@ fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.HEBE) = Student(
|
|||||||
symbol = "",
|
symbol = "",
|
||||||
userLoginId = 1,
|
userLoginId = 1,
|
||||||
userName = "",
|
userName = "",
|
||||||
|
isEduOne = false,
|
||||||
|
isAuthorized = false
|
||||||
).apply {
|
).apply {
|
||||||
id = 1
|
id = 1
|
||||||
}
|
}
|
||||||
|
@ -222,5 +222,7 @@ class GetMailboxByStudentUseCaseTest {
|
|||||||
symbol = "",
|
symbol = "",
|
||||||
userLoginId = 1,
|
userLoginId = 1,
|
||||||
userName = userName,
|
userName = userName,
|
||||||
|
isAuthorized = false,
|
||||||
|
isEduOne = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,9 @@ class GradeAverageProviderTest {
|
|||||||
className = "",
|
className = "",
|
||||||
classId = 1,
|
classId = 1,
|
||||||
isCurrent = true,
|
isCurrent = true,
|
||||||
registrationDate = Instant.now()
|
registrationDate = Instant.now(),
|
||||||
|
isAuthorized = false,
|
||||||
|
isEduOne = false
|
||||||
)
|
)
|
||||||
|
|
||||||
private val semesters = mutableListOf(
|
private val semesters = mutableListOf(
|
||||||
|
@ -71,6 +71,8 @@ class LoginStudentSelectPresenterTest {
|
|||||||
classId = 0,
|
classId = 0,
|
||||||
isParent = false,
|
isParent = false,
|
||||||
semesters = listOf(),
|
semesters = listOf(),
|
||||||
|
isEduOne = false,
|
||||||
|
isAuthorized = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val school = RegisterUnit(
|
private val school = RegisterUnit(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.main
|
package io.github.wulkanowy.ui.modules.main
|
||||||
|
|
||||||
|
import io.github.wulkanowy.MainCoroutineRule
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
@ -7,14 +8,23 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
|||||||
import io.github.wulkanowy.utils.AdsHelper
|
import io.github.wulkanowy.utils.AdsHelper
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.clearMocks
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.verify
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class MainPresenterTest {
|
class MainPresenterTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val coroutineRule = MainCoroutineRule()
|
||||||
|
|
||||||
@MockK(relaxed = true)
|
@MockK(relaxed = true)
|
||||||
lateinit var errorHandler: ErrorHandler
|
lateinit var errorHandler: ErrorHandler
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user