1
0

Compare commits

...

115 Commits

Author SHA1 Message Date
763543a16e Merge branch 'release/0.17.4' 2020-04-23 19:24:54 +02:00
acabe90c9f Version 0.17.4 2020-04-23 19:24:49 +02:00
f79da9003a Merge tag '0.17.3' into develop
Version 0.17.3
2020-04-23 16:22:49 +02:00
fc9e558cd6 Merge branch 'release/0.17.3' 2020-04-23 16:22:44 +02:00
68140bd544 Version 0.17.3 2020-04-23 16:22:39 +02:00
2c4c2d1f49 Fix injector of ErrorDialog (#780) 2020-04-23 11:07:18 +02:00
4894086d9d Bump about_libraries from 8.1.1 to 8.1.2 (#779) 2020-04-21 16:21:44 +00:00
1d29ef5fe3 Merge tag '0.17.2' into develop
Version 0.17.2
2020-04-19 23:42:00 +02:00
7fa333cff2 Merge branch 'release/0.17.2' 2020-04-19 23:41:53 +02:00
c1ffc2ae72 Version 0.17.2 2020-04-19 23:37:29 +02:00
9c0e2dc533 Refresh semesters if previous list was downloaded in different m… (#776) 2020-04-19 23:21:59 +02:00
9b18e3669d Fix crash after send message when activity is in background (#777) 2020-04-19 23:21:25 +02:00
366ebc781d Add error message and bug report button to error dialog (#778) 2020-04-19 23:20:55 +02:00
4bd0459155 Don't log common errors to crashlytics (#775) 2020-04-18 23:07:20 +02:00
b19084cb57 Fix visibility of dialog close button when homework content is l… (#774) 2020-04-18 23:06:05 +02:00
69be7ca412 Bump kotlin_version from 1.3.71 to 1.3.72 (#773) 2020-04-17 21:01:41 +00:00
07307b9709 Bump swiperefreshlayout from 1.1.0-beta01 to 1.1.0-rc01 (#770) 2020-04-17 20:59:02 +00:00
ee4a5e56a9 Bump gradle from 3.6.2 to 3.6.3 (#772) 2020-04-17 20:37:38 +00:00
c8f8ec77a9 Bump preference-ktx from 1.1.0 to 1.1.1 (#771) 2020-04-17 20:35:24 +00:00
be46a43427 Merge tag '0.17.1' into develop
Version 0.17.1
2020-04-12 19:20:59 +02:00
183e379223 Merge branch 'release/0.17.1' 2020-04-12 19:20:53 +02:00
2350fc2ddf Version 0.17.1 2020-04-12 19:20:44 +02:00
152f966a66 Bump firebase-inappmessaging-display-ktx from 19.0.4 to 19.0.5 (#767) 2020-04-12 17:19:06 +00:00
85ee7fad1d Bump firebase-inappmessaging-ktx from 19.0.4 to 19.0.5 (#768) 2020-04-12 16:58:23 +00:00
3ac085573f Show all known adfslight registers in register list (#766) 2020-04-12 18:55:16 +02:00
64a19d9627 Bump about_libraries from 8.1.0 to 8.1.1 (#769) 2020-04-12 15:14:08 +00:00
76af623c94 Add Sdk.init(student) call in all remote repositories (#764) 2020-04-12 15:13:35 +02:00
11c285be01 Fix homework dialog size (#765) 2020-04-12 15:12:25 +02:00
a0528496eb Fix crash caused by updating view in not attached fragment (#763) 2020-04-09 23:46:42 +02:00
299345b864 Fix crash in message preview (#762) 2020-04-09 23:30:56 +02:00
0a18fefb1f Use recycler view in homework details dialog (#761) 2020-04-08 18:17:20 +02:00
a26f0ec8c8 Merge tag '0.17.0' into develop
Version 0.17.0
2020-04-05 18:42:42 +02:00
232d8d38bd Merge branch 'release/0.17.0' 2020-04-05 18:42:36 +02:00
4833e1e130 Version 0.17.0 2020-04-05 18:35:00 +02:00
bb30cf2ce3 Revert "Add "System theme" option to widgets" (#753) 2020-04-05 18:32:57 +02:00
c9b35bed7e Bump chucker from 3.1.1 to 3.2.0 (#755) 2020-04-05 16:22:50 +00:00
999672fcc3 Bump threetenbp from 1.4.2 to 1.4.3 (#756) 2020-04-05 15:32:18 +00:00
6a0ce3a58d Add force sync feature in settings (#643) 2020-04-05 16:46:49 +02:00
3612326628 Add missing sdk initialization in lucky number repository (#752) 2020-04-04 20:59:44 +02:00
bf61dd1bad Add more details in email template (#751) 2020-04-04 20:57:50 +02:00
18c1153e12 Add mark as done feature in homework (#743) 2020-04-03 17:39:36 +02:00
651be69ad2 Add firebase messaging (#740) 2020-04-02 22:47:10 +02:00
394e3bb79c Add firebase messaging (#740) 2020-04-02 22:43:03 +02:00
502a98b70a Add message attachments (#734) 2020-04-02 20:27:53 +02:00
da357775ff Add better validation to login/email field (#741) 2020-04-02 20:27:14 +02:00
c0adeaadfd Add "System theme" option to widgets (#739) 2020-04-02 20:26:28 +02:00
358c87528a Update gradle to 6.2.2 (#750) 2020-04-02 00:34:24 +02:00
0cb4866f40 Bump appcompat from 1.2.0-alpha03 to 1.2.0-beta01 (#749) 2020-04-01 22:21:25 +00:00
6ec13c896d Bump about_libraries from 8.0.2 to 8.1.0 (#747) 2020-04-01 22:01:41 +00:00
a0587a8bce Bump fragment-ktx from 1.2.3 to 1.2.4 (#748) 2020-04-01 22:00:50 +00:00
184c9413f8 Bump firebase-core from 17.2.3 to 17.3.0 (#746) 2020-04-01 18:58:26 +00:00
6440820dc5 Bump gradle from 3.6.1 to 3.6.2 (#744) 2020-04-01 18:56:41 +00:00
d9322b0df4 Bump aboutlibraries-core from 7.1.0 to 8.0.0 (#731) 2020-03-29 18:55:00 +02:00
b9a19b60e4 Bump appcompat from 1.1.0 to 1.2.0-alpha03 to fix webview crash… (#737) 2020-03-29 14:38:39 +02:00
6f697eff47 Add points to notes (#738) 2020-03-29 14:26:56 +02:00
d9c8bb399b Change strings.xml form from male to impersonal (#736) 2020-03-28 19:51:22 +01:00
2137b6c225 Bump threetenabp from 1.2.2 to 1.2.3 (#735) 2020-03-28 10:56:07 +00:00
0320079d02 Bump chucker from 2.0.4 to 3.1.1 (#733) 2020-03-28 11:44:09 +01:00
95a833ea85 Bump room from 2.2.4 to 2.2.5 (#727) 2020-03-24 22:04:25 +00:00
a85a4fe7a0 Bump kotlin_version from 1.3.70 to 1.3.71 (#732) 2020-03-24 20:30:48 +00:00
f94b8c9be8 Bump threetenbp from 1.4.1 to 1.4.2 (#730) 2020-03-24 19:53:59 +00:00
5dfe9cdd4f Bump work_manager from 2.3.3 to 2.3.4 (#728) 2020-03-24 19:52:47 +00:00
9a83b43d57 Bump fragment-ktx from 1.2.2 to 1.2.3 (#729) 2020-03-24 19:52:33 +00:00
7d21babd38 Bump rxjava from 2.2.18 to 2.2.19 (#726) 2020-03-14 22:25:05 +00:00
f763a42323 Bump mockito-inline from 3.3.1 to 3.3.3 (#725) 2020-03-14 22:20:14 +00:00
478596c4e6 Fix marking message as read in hybrid and mobile api mode (#722) 2020-03-14 23:19:59 +01:00
37842a3603 Bump dagger from 2.26 to 2.27 (#724) 2020-03-14 22:19:47 +00:00
1775e2fe62 Bump mockito-android from 3.3.1 to 3.3.3 (#723) 2020-03-14 22:18:34 +00:00
68b26d5e2b Update gradle-publisher to 2.7.2 (#719) 2020-03-07 13:38:15 +01:00
6304395050 Bump swiperefreshlayout from 1.1.0-alpha03 to 1.1.0-beta01 (#718) 2020-03-05 10:59:07 +00:00
fa3c357665 Bump work_manager from 2.3.2 to 2.3.3 (#717) 2020-03-05 10:58:38 +00:00
83282aeab6 Merge tag '0.16.0' into develop
Version 0.16.0
2020-03-05 09:47:43 +01:00
5de2e9afbd Merge branch 'release/0.16.0' 2020-03-05 09:47:37 +01:00
cd99c6b2aa Version 0.16.0 2020-03-05 09:20:46 +01:00
42aacb755c Add some login help messages (#716) 2020-03-04 22:39:28 +01:00
a880b3a9db Bump kotlin_version from 1.3.61 to 1.3.70 (#715)
Bumps `kotlin_version` from 1.3.61 to 1.3.70.

Updates `kotlin-gradle-plugin` from 1.3.61 to 1.3.70

Updates `kotlin-stdlib-jdk8` from 1.3.61 to 1.3.70
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.3.61...v1.3.70)

Updates `kotlin-test` from 1.3.61 to 1.3.70
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.3.61...v1.3.70)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-04 16:39:13 +01:00
7837fae2aa Add German language (#712) 2020-03-03 22:20:57 +01:00
70e9f025bb Replace Creators with Contributors (#675) 2020-03-03 18:07:38 +01:00
ab1d9b358e Change asset name and contributor name (#714) 2020-03-03 18:06:37 +01:00
2634c270b1 Set missing styles to small lesson items (#707) 2020-03-02 22:45:56 +01:00
79bd2fccdf Replace Maybe with Single in Message DAO (#710) 2020-03-02 22:31:55 +01:00
87107ec474 Filter lucky numbers by school shortcut (#708) 2020-03-02 22:22:41 +01:00
8aaa066142 Update Ukrainian language (#711) 2020-03-02 21:31:02 +01:00
5b7d465064 Add Ukrainian language (#709) 2020-03-02 20:56:53 +01:00
75c94865e4 Sort the second group's lessons below the student's lessons (#706) 2020-02-29 23:07:47 +01:00
f294e3d57c Add separate host in login form to login to VULCAN adfslight (#704) 2020-02-29 10:30:20 +01:00
565114a2d2 Update gradle to 6.2.1 (#705) 2020-02-29 02:37:58 +01:00
be057dd63c Show list of charts in grade statistics (#689) 2020-02-29 02:19:48 +01:00
e61c2bced8 Add new notifications categories (#685) 2020-02-29 01:15:26 +01:00
3abfb9f819 Bump gradle from 3.6.0 to 3.6.1 (#702) 2020-02-28 23:19:38 +00:00
7c86fabd7b Bump firebase-core from 17.2.2 to 17.2.3 (#703) 2020-02-28 23:19:00 +00:00
59f2d4b0f3 Bump gradle from 3.5.3 to 3.6.0 (#698) 2020-02-27 21:22:37 +00:00
8571586b0c Bump room from 2.2.3 to 2.2.4 (#694) 2020-02-27 21:11:48 +00:00
e21de811e2 Bump mockito-android from 3.2.4 to 3.3.1 (#696) 2020-02-27 20:35:50 +00:00
7b502ce9a8 Bump mockito-inline from 3.2.4 to 3.3.1 (#693) 2020-02-27 20:35:28 +00:00
33447d2ada Bump fragment-ktx from 1.2.0 to 1.2.2 (#695) 2020-02-27 20:35:05 +00:00
7f6b2ec096 Bump coil from 0.9.4 to 0.9.5 (#699) 2020-02-27 20:33:25 +00:00
2c35117dfa Bump rxjava from 2.2.17 to 2.2.18 (#700) 2020-02-27 20:32:38 +00:00
5b2ca07506 Bump work_manager from 2.3.0 to 2.3.2 (#697) 2020-02-27 20:30:36 +00:00
18d6ec6961 Add account recover (#635) 2020-02-27 00:10:11 +01:00
96c1bb4c69 Automatically switch semesters without sync (#681) 2020-02-24 00:24:40 +01:00
00f5b9431e Add log viewer (#686) 2020-02-22 21:24:06 +01:00
9a87df7315 Respect user settings in timetable app widget (#687) 2020-02-22 20:42:02 +01:00
30e43501ac Refactor the resizing of the lucky number app widget (#682) 2020-02-14 10:04:53 +01:00
34738a4839 Show semester in appbar subtitle in grades view (#684) 2020-02-14 09:58:58 +01:00
1cc2080cb9 Bump material from 1.1.0-rc02 to 1.1.0 (#680) 2020-02-05 00:22:51 +00:00
0826e45a25 Bump coil from 0.9.2 to 0.9.4 (#679) 2020-02-05 00:22:12 +00:00
6925204019 Fix showing empty total summary and ordering of summary months (#678) 2020-02-05 00:53:07 +01:00
bdbf1fe304 Add dynamic nick/email in login (#676) 2020-02-05 00:42:49 +01:00
720a530a6c Disable signed in students in login (#677) 2020-02-04 09:43:24 +01:00
2f56f7e4a4 Bump dagger from 2.25.4 to 2.26 (#673) 2020-02-02 15:50:12 +00:00
c3a6842027 Add total attendance summary (#672) 2020-02-02 16:40:00 +01:00
731afbb00c Fix login more options button in dark theme (#674) 2020-02-02 16:38:14 +01:00
fb3853dc70 Fix timetable_show_whole_class_entries en translation (#668) 2020-01-30 00:13:34 +01:00
ec5503678a Merge tag '0.15.0' into develop
Version 0.15.0
2020-01-26 18:15:16 +01:00
308 changed files with 13430 additions and 1959 deletions

1
.gitignore vendored
View File

@ -63,6 +63,7 @@ captures/
.idea/dynamic.xml
.idea/uiDesigner.xml
.idea/runConfigurations.xml
.idea/discord.xml
# Keystore files
*.jks

View File

@ -1,9 +1,6 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>

View File

@ -4,7 +4,7 @@ jdk: oraclejdk8
env:
global:
- ANDROID_API_LEVEL=29
- ANDROID_BUILD_TOOLS_VERSION=29.0.2
- ANDROID_BUILD_TOOLS_VERSION=29.0.3
cache:
directories:
@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- 0.15.0
- 0.17.4
android:
licenses:
@ -49,9 +49,9 @@ script:
- ./gradlew dependencies --stacktrace --daemon
- fossa --no-ansi || true
#- ./gradlew lintPlayRelease -x fabricGenerateResourcesPlayRelease --stacktrace --daemon
- ./gradlew testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
- ./gradlew createFdroidDebugCoverageReport --stacktrace --daemon
- ./gradlew jacocoTestReport --stacktrace --daemon
- ./gradlew -Pcoverage testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
- ./gradlew -Pcoverage createFdroidDebugCoverageReport --stacktrace --daemon
- ./gradlew -Pcoverage jacocoTestReport --stacktrace --daemon
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
git fetch --unshallow;
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesPlayRelease -x fabricGenerateResourcesFdroidRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;

View File

@ -4,21 +4,22 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
apply plugin: 'com.github.triplet.play'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 16
minSdkVersion 17
targetSdkVersion 29
versionCode 52
versionName "0.15.0"
versionCode 57
versionName "0.17.4"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -61,7 +62,7 @@ android {
buildConfigField "boolean", "CRASHLYTICS_ENABLED", project.hasProperty("enableCrashlytics") ? "true" : "false"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
testCoverageEnabled = true
testCoverageEnabled = project.hasProperty('coverage')
ext.enableCrashlytics = project.hasProperty("enableCrashlytics")
}
}
@ -96,6 +97,10 @@ android {
exclude 'META-INF/library_release.kotlin_module'
exclude 'META-INF/library-core_release.kotlin_module'
}
aboutLibraries {
configPath = "app/src/main/res/raw"
}
}
androidExtensions {
@ -110,10 +115,11 @@ play {
}
ext {
work_manager = "2.3.0"
room = "2.2.3"
dagger = "2.25.4"
chucker = "2.0.4"
work_manager = "2.3.4"
room = "2.2.5"
dagger = "2.27"
// don't update https://github.com/ChuckerTeam/chucker/issues/242
chucker = "3.2.0"
mockk = "1.9.2"
}
@ -122,24 +128,24 @@ configurations.all {
}
dependencies {
implementation "io.github.wulkanowy:sdk:0.15.0"
implementation "io.github.wulkanowy:sdk:0.17.4"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation "androidx.core:core-ktx:1.2.0"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.appcompat:appcompat:1.2.0-beta01"
implementation "androidx.appcompat:appcompat-resources:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.2.0"
implementation "androidx.fragment:fragment-ktx:1.2.4"
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0-rc02"
implementation "com.google.android.material:material:1.1.0"
implementation "com.github.wulkanowy:material-chips-input:2.0.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
@ -148,6 +154,8 @@ dependencies {
implementation "androidx.work:work-rxjava2:$work_manager"
implementation "androidx.work:work-gcm:$work_manager"
implementation 'com.github.PaulinaSadowska:RxWorkManagerObservers:1.0.0'
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-rxjava2:$room"
implementation "androidx.room:room-ktx:$room"
@ -163,33 +171,37 @@ dependencies {
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.1.0"
implementation "com.github.YarikSOffice:lingver:1.2.1"
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.17"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.2"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.3"
implementation "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "com.mikepenz:aboutlibraries-core:7.1.0"
implementation "fr.bipi.treessence:treessence:0.3.2"
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:0.9.5"
implementation("io.coil-kt:coil:0.9.2")
playImplementation "com.google.firebase:firebase-core:17.2.2"
playImplementation 'com.google.firebase:firebase-analytics:17.3.0'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.5'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.5"
playImplementation "com.google.firebase:firebase-messaging:20.1.0"
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
debugImplementation "fr.o80.chucker:library:$chucker"
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
testImplementation "junit:junit:4.13"
testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.threeten:threetenbp:1.4.1"
testImplementation "org.mockito:mockito-inline:3.2.4"
testImplementation "org.threeten:threetenbp:1.4.3"
testImplementation "org.mockito:mockito-inline:3.3.3"
androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0"
@ -197,7 +209,7 @@ dependencies {
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-android:3.2.4"
androidTestImplementation "org.mockito:mockito-android:3.3.3"
}
apply plugin: 'com.google.gms.google-services'

View File

@ -43,3 +43,10 @@
#Config for Material Components
-keep class com.google.android.material.tabs.** { *; }
#Config for About Libraries
-keep class .R
-keep class **.R$* {
<fields>;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@ -104,45 +103,45 @@ class Migration13Test : AbstractMigrationTest() {
val db = helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val semesters1 = getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 1 AND class_id = 5")
assertTrue { semesters1.single { it.isCurrent }.isCurrent }
assertTrue { semesters1.single { it.second }.second }
semesters1[0].run {
assertFalse(isCurrent)
assertEquals(1, semesterId)
assertEquals(1, diaryId)
assertFalse(second)
assertEquals(1, first.semesterId)
assertEquals(1, first.diaryId)
}
semesters1[2].run {
assertFalse(isCurrent)
assertEquals(3, semesterId)
assertEquals(2, diaryId)
assertFalse(second)
assertEquals(3, first.semesterId)
assertEquals(2, first.diaryId)
}
semesters1[3].run {
assertTrue(isCurrent)
assertEquals(4, semesterId)
assertEquals(2, diaryId)
assertTrue(second)
assertEquals(4, first.semesterId)
assertEquals(2, first.diaryId)
}
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertEquals(1970, it[0].schoolYear)
assertEquals(of(1970, 1, 1), it[0].end)
assertEquals(of(1970, 1, 1), it[0].start)
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
assertTrue { it.single { it.second }.second }
assertEquals(1970, it[0].first.schoolYear)
assertEquals(of(1970, 1, 1), it[0].first.end)
assertEquals(of(1970, 1, 1), it[0].first.start)
assertFalse(it[0].second)
assertFalse(it[1].second)
assertFalse(it[2].second)
assertTrue(it[3].second)
}
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
assertTrue { it.single { it.second }.second }
assertFalse(it[0].second)
assertFalse(it[1].second)
assertFalse(it[2].second)
assertTrue(it[3].second)
}
}
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Semester> {
val semesters = mutableListOf<Semester>()
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Pair<Semester, Boolean>> {
val semesters = mutableListOf<Pair<Semester, Boolean>>()
val cursor = db.query(query)
if (cursor.moveToFirst()) {
@ -153,13 +152,12 @@ class Migration13Test : AbstractMigrationTest() {
diaryName = cursor.getString(3),
semesterId = cursor.getInt(4),
semesterName = cursor.getInt(5),
isCurrent = cursor.getInt(6) == 1,
classId = cursor.getInt(7),
unitId = cursor.getInt(8),
schoolYear = cursor.getInt(9),
start = Converters().timestampToDate(cursor.getLong(10))!!,
end = Converters().timestampToDate(cursor.getLong(11))!!
))
) to (cursor.getInt(6) == 1))
} while (cursor.moveToNext())
}
return semesters.toList()

View File

@ -0,0 +1,29 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.entities.Student
import org.threeten.bp.LocalDateTime
fun getStudent(): Student {
return Student(
email = "test",
password = "test123",
schoolSymbol = "23",
scrapperBaseUrl = "fakelog.cf",
loginType = "AUTO",
isCurrent = true,
studentName = "",
schoolShortName = "",
schoolName = "",
studentId = 0,
classId = 1,
symbol = "",
registrationDate = LocalDateTime.now(),
className = "",
loginMode = "API",
certificateKey = "",
privateKey = "",
mobileBaseUrl = "",
userLoginId = 0,
isParent = false
)
}

View File

@ -10,8 +10,8 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -35,19 +35,19 @@ class AttendanceLocalTest {
@Test
fun saveAndReadTest() {
attendanceLocal.saveAttendance(listOf(
Attendance(1, 2, 3, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
Attendance(1, 2, 3, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
Attendance(1, 2, 3, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
Attendance(1, 2, 3, of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
Attendance(1, 2, 3, of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
Attendance(1, 2, 3, of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
))
val attendance = attendanceLocal
.getAttendance(Semester(1, 2, "", 1, 3, 2019, true, now(), now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)
.blockingGet()
.getAttendance(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, attendance.size)
assertEquals(attendance[0].date, LocalDate.of(2018, 9, 10))
assertEquals(attendance[1].date, LocalDate.of(2018, 9, 14))
assertEquals(attendance[0].date, of(2018, 9, 10))
assertEquals(attendance[1].date, of(2018, 9, 14))
}
}

View File

@ -11,6 +11,8 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -35,20 +37,20 @@ class CompletedLessonsLocalTest {
@Test
fun saveAndReadTest() {
completedLessonsLocal.saveCompletedLessons(listOf(
getCompletedLesson(LocalDate.of(2018, 9, 10), 1),
getCompletedLesson(LocalDate.of(2018, 9, 14), 2),
getCompletedLesson(LocalDate.of(2018, 9, 17), 3)
getCompletedLesson(of(2018, 9, 10), 1),
getCompletedLesson(of(2018, 9, 14), 2),
getCompletedLesson(of(2018, 9, 17), 3)
))
val completed = completedLessonsLocal
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, completed.size)
assertEquals(completed[0].date, LocalDate.of(2018, 9, 10))
assertEquals(completed[1].date, LocalDate.of(2018, 9, 14))
assertEquals(completed[0].date, of(2018, 9, 10))
assertEquals(completed[1].date, of(2018, 9, 14))
}
private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson {

View File

@ -10,7 +10,8 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -34,19 +35,19 @@ class ExamLocalTest {
@Test
fun saveAndReadTest() {
examLocal.saveExams(listOf(
Exam(1, 2, LocalDate.of(2018, 9, 10), LocalDate.now(), "", "", "", "", "", ""),
Exam(1, 2, LocalDate.of(2018, 9, 14), LocalDate.now(), "", "", "", "", "", ""),
Exam(1, 2, LocalDate.of(2018, 9, 17), LocalDate.now(), "", "", "", "", "", "")
Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "")
))
val exams = examLocal
.getExams(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)
.blockingGet()
.getExams(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, exams.size)
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))
assertEquals(exams[0].date, of(2018, 9, 10))
assertEquals(exams[1].date, of(2018, 9, 14))
}
}

View File

@ -40,7 +40,7 @@ class GradeLocalTest {
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
))
val semester = Semester(1, 2, "", 2019, 2, 1, true, now(), now(), 1, 1)
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
val grades = gradeLocal
.getGrades(semester)

View File

@ -6,7 +6,6 @@ import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
@ -15,9 +14,6 @@ import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK
import io.mockk.just
import io.mockk.runs
import io.reactivex.Single
import org.junit.After
import org.junit.Before

View File

@ -11,7 +11,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -40,10 +40,7 @@ class GradeStatisticsLocalTest {
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Matematyka"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Matematyka").blockingGet()
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Matematyka")
}
@ -56,12 +53,11 @@ class GradeStatisticsLocalTest {
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Wszystkie"
).blockingGet()
assertEquals(1, stats.size)
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Wszystkie").blockingGet()
assertEquals(3, stats.size)
assertEquals(stats[0].subject, "Wszystkie")
assertEquals(stats[1].subject, "Matematyka")
assertEquals(stats[2].subject, "Chemia")
}
@Test
@ -72,11 +68,8 @@ class GradeStatisticsLocalTest {
getGradePointsStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
with(stats) {
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
with(stats[0]) {
assertEquals(subject, "Matematyka")
assertEquals(others, 5.0)
assertEquals(student, 5.0)
@ -87,10 +80,7 @@ class GradeStatisticsLocalTest {
fun saveAndRead_subjectEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
assertEquals(null, stats)
}
@ -98,13 +88,14 @@ class GradeStatisticsLocalTest {
fun saveAndRead_allEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Wszystkie"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Wszystkie").blockingGet()
assertEquals(null, stats)
}
private fun getSemester(): Semester {
return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1)
}
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
}

View File

@ -6,11 +6,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -36,7 +38,7 @@ class LuckyNumberLocalTest {
fun saveAndReadTest() {
luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
val luckyNumber = luckyNumberLocal.getLuckyNumber(Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", 1, false, now()),
LocalDate.of(2019, 1, 20)
).blockingGet()

View File

@ -42,7 +42,7 @@ class RecipientLocalTest {
))
val recipients = recipientLocal.getRecipients(
Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", 1, true, LocalDateTime.now()),
Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", "", 1, true, LocalDateTime.now()),
2,
ReportingUnit(1, 4, "", 0, "", emptyList())
).blockingGet()

View File

@ -5,13 +5,11 @@ import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.getStudent
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDateTime.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -21,14 +19,13 @@ class StudentLocalTest {
private lateinit var testDb: AppDatabase
private lateinit var sharedProvider: SharedPrefProvider
private val student = getStudent()
@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.build()
sharedProvider = SharedPrefProvider(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
studentLocal = StudentLocal(testDb.studentDao, context)
}
@ -39,8 +36,7 @@ class StudentLocalTest {
@Test
fun saveAndReadTest() {
studentLocal.saveStudents(listOf(Student(email = "test", password = "test123", schoolSymbol = "23", scrapperBaseUrl = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = "", loginMode = "API", certificateKey = "", privateKey = "", mobileBaseUrl = "", userLoginId = 0, isParent = false)))
.blockingGet()
studentLocal.saveStudents(listOf(student)).blockingGet()
val student = studentLocal.getCurrentStudent(true).blockingGet()
assertEquals("23", student.schoolSymbol)

View File

@ -21,7 +21,7 @@ fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", s
teacher = teacher,
teacherOld = "",
info = "",
studentPlan = true,
isStudentPlan = true,
changes = changes,
canceled = false
)

View File

@ -41,7 +41,7 @@ class TimetableLocalTest {
))
val exams = timetableDb.getTimetable(
Semester(1, 2, "", 1, 1, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
).blockingGet()

View File

@ -9,6 +9,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.data.repositories.getStudent
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations
import io.mockk.every
@ -33,6 +34,8 @@ class TimetableRepositoryTest {
.strategy(TestInternetObservingStrategy())
.build()
private val student = getStudent()
@MockK
private lateinit var semesterMock: Semester
@ -78,7 +81,7 @@ class TimetableRepositoryTest {
))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
.getTimetable(student, semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
.blockingGet()
assertEquals(4, lessons.size)
@ -124,7 +127,7 @@ class TimetableRepositoryTest {
))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
.getTimetable(student, semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
.blockingGet()
assertEquals(12, lessons.size)

View File

@ -0,0 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<bool name="pref_default_notification_debug">true</bool>
</resources>

View File

@ -5,13 +5,12 @@ package io.github.wulkanowy.utils
import android.content.Context
import timber.log.Timber
fun initCrashlytics(context: Context, appInfo: AppInfo) {
// do nothing
fun initCrashlytics(context: Context, appInfo: AppInfo) {}
open class TimberTreeNoOp : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
}
class CrashlyticsTree : Timber.Tree() {
class CrashlyticsTree : TimberTreeNoOp()
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// do nothing
}
}
class CrashlyticsExceptionTree : TimberTreeNoOp()

View File

@ -22,7 +22,8 @@
<activity
android:name=".ui.modules.splash.SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/WulkanowyTheme.SplashScreen">
android:theme="@style/WulkanowyTheme.SplashScreen"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -43,8 +44,8 @@
android:name=".ui.modules.message.send.SendMessageActivity"
android:configChanges="orientation|screenSize"
android:label="@string/send_message_title"
android:windowSoftInputMode="adjustResize"
android:theme="@style/WulkanowyTheme.NoActionBar" />
android:theme="@style/WulkanowyTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
android:excludeFromRecents="true"
@ -96,11 +97,29 @@
android:exported="false"
tools:node="remove" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<meta-data
android:name="io.fabric.ApiKey"
android:value="${fabric_api_key}" />
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="${crashlytics_enabled}" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_push" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="push_channel" />
</application>
</manifest>

View File

@ -20,7 +20,7 @@
"githubUsername": "doteq"
},
{
"displayName": "Pavuloff",
"displayName": "Paweł Krzyś",
"githubUsername": "pavuloff"
},
{
@ -30,5 +30,9 @@
{
"displayName": "Dinolek",
"githubUsername": "Dinolek"
},
{
"displayName": "Mateusz Idziejczak",
"githubUsername": "PanTajemnic"
}
]

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy
import android.content.Context
import android.util.Log.DEBUG
import android.util.Log.INFO
import android.util.Log.VERBOSE
import androidx.multidex.MultiDex
@ -11,11 +12,13 @@ import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.utils.Log
import fr.bipi.tressence.file.FileLoggerTree
import io.github.wulkanowy.di.DaggerAppComponent
import io.github.wulkanowy.services.sync.SyncWorkerFactory
import io.github.wulkanowy.ui.base.ThemeManager
import io.github.wulkanowy.utils.ActivityLifecycleLogger
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
import io.github.wulkanowy.utils.CrashlyticsTree
import io.github.wulkanowy.utils.DebugLogTree
import io.github.wulkanowy.utils.initCrashlytics
@ -54,9 +57,17 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
private fun initLogging() {
if (appInfo.isDebug) {
Timber.plant(DebugLogTree())
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
Timber.plant(DebugLogTree())
Timber.plant(FileLoggerTree.Builder()
.withFileName("wulkanowy.%g.log")
.withDirName(applicationContext.filesDir.absolutePath)
.withFileLimit(10)
.withMinPriority(DEBUG)
.build()
)
} else {
Timber.plant(CrashlyticsExceptionTree())
Timber.plant(CrashlyticsTree())
}
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())

View File

@ -7,9 +7,9 @@ import android.content.res.Resources
import androidx.preference.PreferenceManager
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
import com.readystatesoftware.chuck.api.ChuckCollector
import com.readystatesoftware.chuck.api.ChuckInterceptor
import com.readystatesoftware.chuck.api.RetentionManager
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
import dagger.Module
import dagger.Provides
import io.github.wulkanowy.data.db.AppDatabase
@ -32,23 +32,25 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideSdk(chuckCollector: ChuckCollector, context: Context): Sdk {
fun provideSdk(chuckerCollector: ChuckerCollector, context: Context): Sdk {
return Sdk().apply {
androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL
setSimpleHttpLogger { Timber.d(it) }
// for debug only
addInterceptor(ChuckInterceptor(context, chuckCollector).maxContentLength(250000L), true)
addInterceptor(ChuckerInterceptor(context, chuckerCollector), true)
}
}
@Singleton
@Provides
fun provideChuckCollector(context: Context, prefRepository: PreferencesRepository): ChuckCollector {
return ChuckCollector(context)
.showNotification(prefRepository.isDebugNotificationEnable)
.retentionManager(RetentionManager(context, ChuckCollector.Period.ONE_HOUR))
fun provideChuckerCollector(context: Context, prefRepository: PreferencesRepository): ChuckerCollector {
return ChuckerCollector(
context = context,
showNotification = prefRepository.isDebugNotificationEnable,
retentionPeriod = RetentionManager.Period.ONE_HOUR
)
}
@Singleton
@ -95,6 +97,10 @@ internal class RepositoryModule {
@Provides
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
@Singleton
@Provides
fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao
@Singleton
@Provides
fun provideExamDao(database: AppDatabase) = database.examsDao

View File

@ -1,30 +0,0 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import javax.inject.Inject
class SdkHelper @Inject constructor(private val sdk: Sdk) {
fun init(student: Student) {
sdk.apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
classId = student.classId
if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
scrapperBaseUrl = student.scrapperBaseUrl
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
}
loginId = student.userLoginId
mode = Sdk.Mode.valueOf(student.loginMode)
mobileBaseUrl = student.mobileBaseUrl
certKey = student.certificateKey
privateKey = student.privateKey
}
}
}

View File

@ -17,6 +17,7 @@ import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.dao.HomeworkDao
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.NoteDao
@ -39,6 +40,7 @@ import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Recipient
@ -62,6 +64,10 @@ import io.github.wulkanowy.data.db.migrations.Migration19
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration20
import io.github.wulkanowy.data.db.migrations.Migration21
import io.github.wulkanowy.data.db.migrations.Migration22
import io.github.wulkanowy.data.db.migrations.Migration23
import io.github.wulkanowy.data.db.migrations.Migration24
import io.github.wulkanowy.data.db.migrations.Migration25
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
import io.github.wulkanowy.data.db.migrations.Migration5
@ -85,6 +91,7 @@ import javax.inject.Singleton
GradeStatistics::class,
GradePointsStatistics::class,
Message::class,
MessageAttachment::class,
Note::class,
Homework::class,
Subject::class,
@ -103,7 +110,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 21
const val VERSION_SCHEMA = 25
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
return arrayOf(
@ -126,7 +133,11 @@ abstract class AppDatabase : RoomDatabase() {
Migration18(),
Migration19(sharedPrefProvider),
Migration20(),
Migration21()
Migration21(),
Migration22(),
Migration23(),
Migration24(),
Migration25()
)
}
@ -162,6 +173,8 @@ abstract class AppDatabase : RoomDatabase() {
abstract val messagesDao: MessagesDao
abstract val messageAttachmentDao: MessageAttachmentDao
abstract val noteDao: NoteDao
abstract val homeworkDao: HomeworkDao

View File

@ -48,4 +48,14 @@ class Converters {
fun gsonToIntList(value: String): List<Int> {
return Gson().fromJson(value, object : TypeToken<List<Int>>() {}.type)
}
@TypeConverter
fun stringPairListToGson(list: List<Pair<String, String>>): String {
return Gson().toJson(list)
}
@TypeConverter
fun gsonToStringPairList(value: String): List<Pair<String, String>> {
return Gson().fromJson(value, object : TypeToken<List<Pair<String, String>>>() {}.type)
}
}

View File

@ -11,7 +11,7 @@ import javax.inject.Singleton
interface GradePointsStatisticsDao : BaseDao<GradePointsStatistics> {
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<GradePointsStatistics>
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<List<GradePointsStatistics>>
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradePointsStatistics>>

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import io.github.wulkanowy.data.db.entities.MessageAttachment
@Dao
interface MessageAttachmentDao : BaseDao<MessageAttachment> {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAttachments(items: List<MessageAttachment>): List<Long>
}

View File

@ -2,18 +2,22 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.reactivex.Maybe
import io.reactivex.Single
@Dao
interface MessagesDao : BaseDao<Message> {
@Transaction
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId")
fun loadMessageWithAttachment(studentId: Int, messageId: Int): Single<MessageWithAttachment>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>
@Query("SELECT * FROM Messages WHERE id = :id")
fun load(id: Long): Maybe<Message>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
fun loadDeleted(studentId: Int): Maybe<List<Message>>
}

View File

@ -22,6 +22,9 @@ interface StudentDao {
@Query("SELECT * FROM Students WHERE is_current = 1")
fun loadCurrent(): Maybe<Student>
@Query("SELECT * FROM Students WHERE id = :id")
fun loadById(id: Int): Maybe<Student>
@Query("SELECT * FROM Students")
fun loadAll(): Maybe<List<Student>>

View File

@ -27,10 +27,14 @@ data class Homework(
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
val teacherSymbol: String
val teacherSymbol: String,
val attachments: List<Pair<String, String>>
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_done")
var isDone: Boolean = false
}

View File

@ -44,7 +44,10 @@ data class Message(
@ColumnInfo(name = "read_by")
val readBy: Int,
val removed: Boolean
val removed: Boolean,
@ColumnInfo(name = "has_attachments")
val hasAttachments: Boolean
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "MessageAttachments")
data class MessageAttachment(
@PrimaryKey
@ColumnInfo(name = "real_id")
val realId: Int,
@ColumnInfo(name = "message_id")
val messageId: Int,
@ColumnInfo(name = "one_drive_id")
val oneDriveId: String,
@ColumnInfo(name = "url")
val url: String,
@ColumnInfo(name = "filename")
val filename: String
) : Serializable

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.Embedded
import androidx.room.Relation
data class MessageWithAttachment(
@Embedded
val message: Message,
@Relation(parentColumn = "message_id", entityColumn = "message_id")
val attachments: List<MessageAttachment>
)

View File

@ -16,8 +16,19 @@ data class Note(
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
val teacherSymbol: String,
val category: String,
@ColumnInfo(name = "category_type")
val categoryType: Int,
@ColumnInfo(name = "is_points_show")
val isPointsShow: Boolean,
val points: Int,
val content: String
) : Serializable {

View File

@ -27,9 +27,6 @@ data class Semester(
@ColumnInfo(name = "semester_name")
val semesterName: Int,
@ColumnInfo(name = "is_current")
val isCurrent: Boolean,
val start: LocalDate,
val end: LocalDate,
@ -43,4 +40,8 @@ data class Semester(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_current")
var current: Boolean = false
}

View File

@ -49,6 +49,9 @@ data class Student(
@ColumnInfo(name = "school_id")
val schoolSymbol: String,
@ColumnInfo(name ="school_short")
val schoolShortName: String,
@ColumnInfo(name = "school_name")
val schoolName: String,

View File

@ -41,7 +41,7 @@ data class Timetable(
val info: String,
@ColumnInfo(name = "student_plan")
val studentPlan: Boolean,
val isStudentPlan: Boolean,
val changes: Boolean,

View File

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration22 : Migration(21, 22) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Students ADD COLUMN school_short TEXT NOT NULL DEFAULT ''")
}
}

View File

@ -0,0 +1,14 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration23 : Migration(22, 23) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Notes ADD COLUMN teacher_symbol TEXT NOT NULL DEFAULT ''")
database.execSQL("ALTER TABLE Notes ADD COLUMN category_type INTEGER NOT NULL DEFAULT 0")
database.execSQL("ALTER TABLE Notes ADD COLUMN is_points_show INTEGER NOT NULL DEFAULT 0")
database.execSQL("ALTER TABLE Notes ADD COLUMN points INTEGER NOT NULL DEFAULT 0")
}
}

View File

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration24 : Migration(23, 24) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0")
database.execSQL("""
CREATE TABLE IF NOT EXISTS MessageAttachments (
real_id INTEGER NOT NULL,
message_id INTEGER NOT NULL,
one_drive_id TEXT NOT NULL,
url TEXT NOT NULL,
filename TEXT NOT NULL,
PRIMARY KEY(real_id)
)
""")
}
}

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration25 : Migration(24, 25) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Homework ADD COLUMN is_done INTEGER NOT NULL DEFAULT 0")
database.execSQL("ALTER TABLE Homework ADD COLUMN attachments TEXT NOT NULL DEFAULT \"[]\"")
}
}

View File

@ -0,0 +1,14 @@
package io.github.wulkanowy.data.pojos
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
data class GradeStatisticsItem(
val type: ViewType,
val partial: List<GradeStatistics>,
val points: GradePointsStatistics?
)

View File

@ -12,7 +12,7 @@ class AppCreatorRepository @Inject constructor(private val assets: AssetManager)
fun getAppCreators(): Single<List<AppCreator>> {
return Single.fromCallable<List<AppCreator>> {
Gson().fromJson(
assets.open("creators.json").bufferedReader().use { it.readText() },
assets.open("contributors.json").bufferedReader().use { it.readText() },
Array<AppCreator>::class.java
).toList()
}

View File

@ -2,8 +2,10 @@ package io.github.wulkanowy.data.repositories.attendance
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Absent
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
@ -14,8 +16,9 @@ import javax.inject.Singleton
@Singleton
class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendance(startDate, endDate, semester.semesterId)
fun getAttendance(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getAttendance(startDate, endDate, semester.semesterId)
.map { attendance ->
attendance.map {
Attendance(
@ -39,8 +42,8 @@ class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
}
}
fun excuseAbsence(semester: Semester, absenceList: List<Attendance>, reason: String?): Single<Boolean> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance ->
fun excuseAbsence(student: Student, semester: Semester, absenceList: List<Attendance>, reason: String?): Single<Boolean> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance ->
Absent(
date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)),
timeId = attendance.timeId

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
@ -20,29 +21,25 @@ class AttendanceRepository @Inject constructor(
private val remote: AttendanceRemote
) {
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean)
: Single<List<Attendance>> {
return Single.fromCallable { startDate.monday to endDate.friday }
.flatMap { dates ->
local.getAttendance(semester, dates.first, dates.second).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getAttendance(semester, dates.first, dates.second)
else Single.error(UnknownHostException())
}.flatMap { newAttendance ->
local.getAttendance(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { oldAttendance ->
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
}
}.flatMap {
local.getAttendance(semester, dates.first, dates.second)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in startDate..endDate } }
}
fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): Single<List<Attendance>> {
return local.getAttendance(semester, start.monday, end.friday).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getAttendance(student, semester, start.monday, end.friday)
else Single.error(UnknownHostException())
}.flatMap { newAttendance ->
local.getAttendance(semester, start.monday, end.friday)
.toSingle(emptyList())
.doOnSuccess { oldAttendance ->
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
}
}.flatMap {
local.getAttendance(semester, start.monday, end.friday)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in start..end } }
}
fun excuseForAbsence(semester: Semester, attendanceList: List<Attendance>, reason: String? = null): Single<Boolean> {
return remote.excuseAbsence(semester, attendanceList, reason)
fun excuseForAbsence(student: Student, semester: Semester, attendanceList: List<Attendance>, reason: String? = null): Single<Boolean> {
return remote.excuseAbsence(student, semester, attendanceList, reason)
}
}

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.attendancesummary
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,8 +12,9 @@ import javax.inject.Singleton
@Singleton
class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) {
fun getAttendanceSummary(semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendanceSummary(subjectId)
fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getAttendanceSummary(subjectId)
.map { attendance ->
attendance.map {
AttendanceSummary(

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
@ -17,11 +18,11 @@ class AttendanceSummaryRepository @Inject constructor(
private val remote: AttendanceSummaryRemote
) {
fun getAttendanceSummary(semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>> {
fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>> {
return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getAttendanceSummary(semester, subjectId)
if (it) remote.getAttendanceSummary(student, semester, subjectId)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getAttendanceSummary(semester, subjectId).toSingle(emptyList())

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.completedlessons
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -11,8 +13,9 @@ import javax.inject.Singleton
@Singleton
class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) {
fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getCompletedLessons(startDate, endDate)
fun getCompletedLessons(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getCompletedLessons(startDate, endDate)
.map { lessons ->
lessons.map {
it.absence

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
@ -20,25 +21,22 @@ class CompletedLessonsRepository @Inject constructor(
private val remote: CompletedLessonsRemote
) {
fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
return Single.fromCallable { startDate.monday to endDate.friday }
.flatMap { dates ->
local.getCompletedLessons(semester, dates.first, dates.second).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getCompletedLessons(semester, dates.first, dates.second)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getCompletedLessons(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { old ->
local.deleteCompleteLessons(old.uniqueSubtract(new))
local.saveCompletedLessons(new.uniqueSubtract(old))
}
}.flatMap {
local.getCompletedLessons(semester, dates.first, dates.second)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in startDate..endDate } }
}
fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
return local.getCompletedLessons(semester, start.monday, end.friday).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getCompletedLessons(student, semester, start.monday, end.friday)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getCompletedLessons(semester, start.monday, end.friday)
.toSingle(emptyList())
.doOnSuccess { old ->
local.deleteCompleteLessons(old.uniqueSubtract(new))
local.saveCompletedLessons(new.uniqueSubtract(old))
}
}.flatMap {
local.getCompletedLessons(semester, start.monday, end.friday)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in start..end } }
}
}

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.exam
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -11,8 +13,9 @@ import javax.inject.Singleton
@Singleton
class ExamRemote @Inject constructor(private val sdk: Sdk) {
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getExams(startDate, endDate, semester.semesterId)
fun getExams(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getExams(startDate, endDate, semester.semesterId)
.map { exams ->
exams.map {
Exam(

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
@ -20,25 +21,22 @@ class ExamRepository @Inject constructor(
private val remote: ExamRemote
) {
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
return Single.fromCallable { startDate.monday to endDate.friday }
.flatMap { dates ->
local.getExams(semester, dates.first, dates.second).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getExams(semester, dates.first, dates.second)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getExams(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { old ->
local.deleteExams(old.uniqueSubtract(new))
local.saveExams(new.uniqueSubtract(old))
}
}.flatMap {
local.getExams(semester, dates.first, dates.second)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in startDate..endDate } }
}
fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
return local.getExams(semester, start.monday, end.friday).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getExams(student, semester, start.monday, end.friday)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getExams(semester, start.monday, end.friday)
.toSingle(emptyList())
.doOnSuccess { old ->
local.deleteExams(old.uniqueSubtract(new))
local.saveExams(new.uniqueSubtract(old))
}
}.flatMap {
local.getExams(semester, start.monday, end.friday)
.toSingle(emptyList())
}).map { list -> list.filter { it.date in start..end } }
}
}

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.grade
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,8 +12,9 @@ import javax.inject.Singleton
@Singleton
class GradeRemote @Inject constructor(private val sdk: Sdk) {
fun getGrades(semester: Semester): Single<List<Grade>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGrades(semester.semesterId)
fun getGrades(student: Student, semester: Semester): Single<List<Grade>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGrades(semester.semesterId)
.map { grades ->
grades.map {
Grade(

View File

@ -23,7 +23,7 @@ class GradeRepository @Inject constructor(
return local.getGrades(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getGrades(semester)
if (it) remote.getGrades(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGrades(semester).toSingle(emptyList())

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.gradessummary
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,8 +12,9 @@ import javax.inject.Singleton
@Singleton
class GradeSummaryRemote @Inject constructor(private val sdk: Sdk) {
fun getGradeSummary(semester: Semester): Single<List<GradeSummary>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesSummary(semester.semesterId)
fun getGradeSummary(student: Student, semester: Semester): Single<List<GradeSummary>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGradesSummary(semester.semesterId)
.map { gradesSummary ->
gradesSummary.map {
GradeSummary(

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
@ -17,11 +18,11 @@ class GradeSummaryRepository @Inject constructor(
private val remote: GradeSummaryRemote
) {
fun getGradesSummary(semester: Semester, forceRefresh: Boolean = false): Single<List<GradeSummary>> {
fun getGradesSummary(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<GradeSummary>> {
return local.getGradesSummary(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getGradeSummary(semester)
if (it) remote.getGradeSummary(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGradesSummary(semester).toSingle(emptyList())

View File

@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.roundToDecimalPlaces
import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@ -30,23 +29,17 @@ class GradeStatisticsLocal @Inject constructor(
list.groupBy { it.grade }.map {
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key,
it.value.fold(0) { acc, e -> acc + e.amount }, false)
}
} + list
}
else -> gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)
}.filter { it.isNotEmpty() }
}
fun getGradesPointsStatistics(semester: Semester, subjectName: String): Maybe<GradePointsStatistics> {
fun getGradesPointsStatistics(semester: Semester, subjectName: String): Maybe<List<GradePointsStatistics>> {
return when (subjectName) {
"Wszystkie" -> gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).flatMap { list ->
if (list.isEmpty()) return@flatMap Maybe.empty<GradePointsStatistics>()
Maybe.just(GradePointsStatistics(semester.studentId, semester.semesterId, subjectName,
(list.fold(.0) { acc, e -> acc + e.others } / list.size).roundToDecimalPlaces(2),
(list.fold(.0) { acc, e -> acc + e.student } / list.size).roundToDecimalPlaces(2)
))
}
"Wszystkie" -> gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId)
else -> gradePointsStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName)
}
}.filter { it.isNotEmpty() }
}
fun saveGradesStatistics(gradesStatistics: List<GradeStatistics>) {

View File

@ -3,7 +3,9 @@ package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -11,8 +13,8 @@ import javax.inject.Singleton
@Singleton
class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).let {
fun getGradeStatistics(student: Student, semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).let {
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
else it.getGradesPartialStatistics(semester.semesterId)
}.map { gradeStatistics ->
@ -29,8 +31,9 @@ class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
}
}
fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesPointsStatistics(semester.semesterId)
fun getGradePointsStatistics(student: Student, semester: Semester): Single<List<GradePointsStatistics>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGradesPointsStatistics(semester.semesterId)
.map { gradePointsStatistics ->
gradePointsStatistics.map {
GradePointsStatistics(

View File

@ -5,8 +5,10 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -19,11 +21,11 @@ class GradeStatisticsRepository @Inject constructor(
private val remote: GradeStatisticsRemote
) {
fun getGradesStatistics(semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): Single<List<GradeStatistics>> {
return local.getGradesStatistics(semester, isSemester, subjectName).filter { !forceRefresh }
fun getGradesStatistics(student: Student, semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): Single<List<GradeStatisticsItem>> {
return local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getGradeStatistics(semester, isSemester)
if (it) remote.getGradeStatistics(student, semester, isSemester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGradesStatistics(semester, isSemester).toSingle(emptyList())
@ -31,21 +33,43 @@ class GradeStatisticsRepository @Inject constructor(
local.deleteGradesStatistics(old.uniqueSubtract(new))
local.saveGradesStatistics(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).toSingle(emptyList()) })
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.toSingle(emptyList()) })
}
fun getGradesPointsStatistics(semester: Semester, subjectName: String, forceRefresh: Boolean): Maybe<GradePointsStatistics> {
return local.getGradesPointsStatistics(semester, subjectName).filter { !forceRefresh }
fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean): Single<List<GradeStatisticsItem>> {
return local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMapMaybe {
if (it) remote.getGradePointsStatistics(semester).toMaybe()
else Maybe.error(UnknownHostException())
.flatMap {
if (it) remote.getGradePointsStatistics(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGradesPointsStatistics(semester).defaultIfEmpty(emptyList())
local.getGradesPointsStatistics(semester).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteGradesPointsStatistics(old.uniqueSubtract(new))
local.saveGradesPointsStatistics(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesPointsStatistics(semester, subjectName) })
}.flatMap { local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.toSingle(emptyList()) })
}
private fun List<GradeStatistics>.mapToStatisticItems(): List<GradeStatisticsItem> {
return groupBy { it.subject }.map {
GradeStatisticsItem(
type = ViewType.PARTIAL,
partial = it.value
.sortedByDescending { item -> item.grade }
.filter { item -> item.amount != 0 },
points = null
)
}
}
private fun List<GradePointsStatistics>.mapToStatisticsItem(): List<GradeStatisticsItem> {
return map {
GradeStatisticsItem(
type = ViewType.POINTS,
partial = emptyList(),
points = it
)
}
}
}

View File

@ -19,6 +19,10 @@ class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
homeworkDb.deleteAll(homework)
}
fun updateHomework(homework: List<Homework>) {
homeworkDb.updateAll(homework)
}
fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Homework>> {
return homeworkDb.loadAll(semester.semesterId, semester.studentId, startDate, endDate)
.filter { it.isNotEmpty() }

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.homework
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -11,8 +13,9 @@ import javax.inject.Singleton
@Singleton
class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getHomework(startDate, endDate)
fun getHomework(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getHomework(startDate, endDate)
.map { homework ->
homework.map {
Homework(
@ -23,7 +26,8 @@ class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
subject = it.subject,
content = it.content,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol
teacherSymbol = it.teacherSymbol,
attachments = it.attachments.map { attachment -> attachment.url to attachment.name }
)
}
}

View File

@ -4,9 +4,11 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Single
import org.threeten.bp.LocalDate
import java.net.UnknownHostException
@ -20,12 +22,12 @@ class HomeworkRepository @Inject constructor(
private val remote: HomeworkRemote
) {
fun getHomework(semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
local.getHomework(semester, monday, friday).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getHomework(semester, monday, friday)
if (it) remote.getHomework(student, semester, monday, friday)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getHomework(semester, monday, friday).toSingle(emptyList())
@ -36,4 +38,12 @@ class HomeworkRepository @Inject constructor(
}.flatMap { local.getHomework(semester, monday, friday).toSingle(emptyList()) })
}
}
fun toggleDone(homework: Homework): Completable {
return Completable.fromCallable {
local.updateHomework(listOf(homework.apply {
isDone = !isDone
}))
}
}
}

View File

@ -0,0 +1,39 @@
package io.github.wulkanowy.data.repositories.logger
import android.content.Context
import io.reactivex.Single
import java.io.File
import java.io.FileNotFoundException
import javax.inject.Inject
class LoggerRepository @Inject constructor(private val context: Context) {
fun getLastLogLines(): Single<List<String>> {
return getLastModified()
.map { it.readText() }
.map { it.split("\n") }
}
fun getLogFiles(): Single<List<File>> {
return Single.fromCallable {
File(context.filesDir.absolutePath).listFiles(File::isFile)?.filter {
it.name.endsWith(".log")
}
}
}
private fun getLastModified(): Single<File> {
return Single.fromCallable {
var lastModifiedTime = Long.MIN_VALUE
var chosenFile: File? = null
File(context.filesDir.absolutePath).listFiles(File::isFile)?.forEach { file ->
if (file.lastModified() > lastModifiedTime) {
lastModifiedTime = file.lastModified()
chosenFile = file
}
}
if (chosenFile == null) throw FileNotFoundException("Log file not found")
chosenFile
}
}
}

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -23,7 +23,7 @@ class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumbe
luckyNumberDb.deleteAll(listOf(luckyNumber))
}
fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> {
return luckyNumberDb.load(semester.studentId, date)
fun getLuckyNumber(student: Student, date: LocalDate): Maybe<LuckyNumber> {
return luckyNumberDb.load(student.studentId, date)
}
}

View File

@ -1,8 +1,9 @@
package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -11,14 +12,13 @@ import javax.inject.Singleton
@Singleton
class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) {
fun getLuckyNumber(semester: Semester): Maybe<LuckyNumber> {
return sdk.getLuckyNumber()
.map {
LuckyNumber(
studentId = semester.studentId,
date = LocalDate.now(),
luckyNumber = it
)
}
fun getLuckyNumber(student: Student): Maybe<LuckyNumber> {
return sdk.init(student).getLuckyNumber(student.schoolShortName).map {
LuckyNumber(
studentId = student.studentId,
date = LocalDate.now(),
luckyNumber = it
)
}
}
}

View File

@ -3,7 +3,7 @@ package io.github.wulkanowy.data.repositories.luckynumber
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Completable
import io.reactivex.Maybe
import org.threeten.bp.LocalDate
@ -18,14 +18,14 @@ class LuckyNumberRepository @Inject constructor(
private val remote: LuckyNumberRemote
) {
fun getLuckyNumber(semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Maybe<LuckyNumber> {
return local.getLuckyNumber(semester, LocalDate.now()).filter { !forceRefresh }
fun getLuckyNumber(student: Student, forceRefresh: Boolean = false, notify: Boolean = false): Maybe<LuckyNumber> {
return local.getLuckyNumber(student, LocalDate.now()).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMapMaybe {
if (it) remote.getLuckyNumber(semester)
if (it) remote.getLuckyNumber(student)
else Maybe.error(UnknownHostException())
}.flatMap { new ->
local.getLuckyNumber(semester, LocalDate.now())
local.getLuckyNumber(student, LocalDate.now())
.doOnSuccess { old ->
if (new != old) {
local.deleteLuckyNumber(old)
@ -39,13 +39,13 @@ class LuckyNumberRepository @Inject constructor(
if (notify) isNotified = false
})
}
}.flatMap({ local.getLuckyNumber(semester, LocalDate.now()) }, { Maybe.error(it) },
{ local.getLuckyNumber(semester, LocalDate.now()) })
}.flatMap({ local.getLuckyNumber(student, LocalDate.now()) }, { Maybe.error(it) },
{ local.getLuckyNumber(student, LocalDate.now()) })
)
}
fun getNotNotifiedLuckyNumber(semester: Semester): Maybe<LuckyNumber> {
return local.getLuckyNumber(semester, LocalDate.now()).filter { !it.isNotified }
fun getNotNotifiedLuckyNumber(student: Student): Maybe<LuckyNumber> {
return local.getLuckyNumber(student, LocalDate.now()).filter { !it.isNotified }
}
fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {

View File

@ -1,15 +1,22 @@
package io.github.wulkanowy.data.repositories.message
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
import io.reactivex.Maybe
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
class MessageLocal @Inject constructor(
private val messagesDb: MessagesDao,
private val messageAttachmentDao: MessageAttachmentDao
) {
fun saveMessages(messages: List<Message>) {
messagesDb.insertAll(messages)
@ -23,8 +30,12 @@ class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
messagesDb.deleteAll(messages)
}
fun getMessage(id: Long): Maybe<Message> {
return messagesDb.load(id)
fun getMessageWithAttachment(student: Student, message: Message): Single<MessageWithAttachment> {
return messagesDb.loadMessageWithAttachment(student.id.toInt(), message.messageId)
}
fun saveMessageAttachments(attachments: List<MessageAttachment>) {
messageAttachmentDao.insertAttachments(attachments)
}
fun getMessages(student: Student, folder: MessageFolder): Maybe<List<Message>> {

View File

@ -1,12 +1,14 @@
package io.github.wulkanowy.data.repositories.message
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Folder
import io.github.wulkanowy.sdk.pojo.SentMessage
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDateTime.now
import javax.inject.Inject
@ -17,7 +19,7 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
class MessageRemote @Inject constructor(private val sdk: Sdk) {
fun getMessages(student: Student, semester: Semester, folder: MessageFolder): Single<List<Message>> {
return sdk.getMessages(Folder.valueOf(folder.name), semester.start.atStartOfDay(), semester.end.atStartOfDay()).map { messages ->
return sdk.init(student).getMessages(Folder.valueOf(folder.name), semester.start.atStartOfDay(), semester.end.atStartOfDay()).map { messages ->
messages.map {
Message(
studentId = student.id.toInt(),
@ -33,18 +35,29 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
unread = it.unread ?: false,
unreadBy = it.unreadBy ?: 0,
readBy = it.readBy ?: 0,
removed = it.removed
removed = it.removed,
hasAttachments = it.hasAttachments
)
}
}
}
fun getMessagesContent(message: Message, markAsRead: Boolean = false): Single<String> {
return sdk.getMessageContent(message.messageId, message.folderId, markAsRead, message.realId)
fun getMessagesContentDetails(student: Student, message: Message, markAsRead: Boolean = false): Single<Pair<String, List<MessageAttachment>>> {
return sdk.init(student).getMessageDetails(message.messageId, message.folderId, markAsRead, message.realId).map { details ->
details.content to details.attachments.map {
MessageAttachment(
realId = it.id,
messageId = it.messageId,
oneDriveId = it.oneDriveId,
url = it.url,
filename = it.filename
)
}
}
}
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
return sdk.sendMessage(
fun sendMessage(student: Student, subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
return sdk.init(student).sendMessage(
subject = subject,
content = content,
recipients = recipients.map {
@ -61,7 +74,7 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
)
}
fun deleteMessage(message: Message): Single<Boolean> {
return sdk.deleteMessages(listOf(Pair(message.realId, message.folderId)))
fun deleteMessage(student: Student, message: Message): Single<Boolean> {
return sdk.init(student).deleteMessages(listOf(Pair(message.realId, message.folderId)))
}
}

View File

@ -2,8 +2,8 @@ package io.github.wulkanowy.data.repositories.message
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
@ -11,8 +11,8 @@ import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
import io.github.wulkanowy.sdk.pojo.SentMessage
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.Single
import timber.log.Timber
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@ -21,54 +21,53 @@ import javax.inject.Singleton
class MessageRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: MessageLocal,
private val remote: MessageRemote,
private val sdkHelper: SdkHelper
private val remote: MessageRemote
) {
fun getMessages(student: Student, semester: Semester, folder: MessageFolder, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Message>> {
return Single.just(sdkHelper.init(student))
.flatMap { _ ->
local.getMessages(student, folder).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getMessages(student, semester, folder)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getMessages(student, folder).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteMessages(old.uniqueSubtract(new))
local.saveMessages(new.uniqueSubtract(old)
.onEach {
it.isNotified = !notify
})
}
}.flatMap { local.getMessages(student, folder).toSingle(emptyList()) }
)
}
return local.getMessages(student, folder).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getMessages(student, semester, folder)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getMessages(student, folder).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteMessages(old.uniqueSubtract(new))
local.saveMessages(new.uniqueSubtract(old)
.onEach {
it.isNotified = !notify
})
}
}.flatMap { local.getMessages(student, folder).toSingle(emptyList()) }
)
}
fun getMessage(student: Student, messageDbId: Long, markAsRead: Boolean = false): Single<Message> {
return Single.just(sdkHelper.init(student))
.flatMap { _ ->
local.getMessage(messageDbId)
.filter { it.content.isNotEmpty() }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) local.getMessage(messageDbId).toSingle()
else Single.error(UnknownHostException())
}
.flatMap { dbMessage ->
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
local.updateMessages(listOf(dbMessage.copy(unread = false).apply {
id = dbMessage.id
content = content.ifBlank { it }
}))
}
}.flatMap {
local.getMessage(messageDbId).toSingle()
}
)
fun getMessage(student: Student, message: Message, markAsRead: Boolean = false): Single<MessageWithAttachment> {
return local.getMessageWithAttachment(student, message)
.filter {
it.message.content.isNotEmpty().also { status ->
Timber.d("Message content in db empty: ${!status}")
} && !it.message.unread
}
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) local.getMessageWithAttachment(student, message)
else Single.error(UnknownHostException())
}
.flatMap { dbMessage ->
remote.getMessagesContentDetails(student, dbMessage.message, markAsRead).doOnSuccess { (downloadedMessage, attachments) ->
local.updateMessages(listOf(dbMessage.message.copy(unread = !markAsRead).apply {
id = dbMessage.message.id
content = content.ifBlank { downloadedMessage }
}))
local.saveMessageAttachments(attachments)
Timber.d("Message ${message.messageId} with blank content: ${dbMessage.message.content.isBlank()}, marked as read")
}
}.flatMap {
local.getMessageWithAttachment(student, message)
}
)
}
fun getNotNotifiedMessages(student: Student): Single<List<Message>> {
@ -77,29 +76,24 @@ class MessageRepository @Inject constructor(
.toSingle(emptyList())
}
fun updateMessage(message: Message): Completable {
return Completable.fromCallable { local.updateMessages(listOf(message)) }
}
fun updateMessages(messages: List<Message>): Completable {
return Completable.fromCallable { local.updateMessages(messages) }
}
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
fun sendMessage(student: Student, subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.sendMessage(subject, content, recipients)
if (it) remote.sendMessage(student, subject, content, recipients)
else Single.error(UnknownHostException())
}
}
fun deleteMessage(message: Message): Maybe<Boolean> {
fun deleteMessage(student: Student, message: Message): Single<Boolean> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.deleteMessage(message)
if (it) remote.deleteMessage(student, message)
else Single.error(UnknownHostException())
}
.filter { it }
.doOnSuccess {
if (!message.removed) local.updateMessages(listOf(message.copy(removed = true).apply {
id = message.id

View File

@ -2,8 +2,10 @@ package io.github.wulkanowy.data.repositories.mobiledevice
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -11,13 +13,14 @@ import javax.inject.Singleton
@Singleton
class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
fun getDevices(semester: Semester): Single<List<MobileDevice>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getRegisteredDevices()
fun getDevices(student: Student, semester: Semester): Single<List<MobileDevice>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getRegisteredDevices()
.map { devices ->
devices.map {
MobileDevice(
studentId = semester.studentId,
date = it.date,
date = it.createDate,
deviceId = it.id,
name = it.name
)
@ -25,12 +28,14 @@ class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
}
}
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).unregisterDevice(device.deviceId)
fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice): Single<Boolean> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.unregisterDevice(device.deviceId)
}
fun getToken(semester: Semester): Single<MobileDeviceToken> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getToken()
fun getToken(student: Student, semester: Semester): Single<MobileDeviceToken> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getToken()
.map {
MobileDeviceToken(
token = it.token,

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
@ -18,11 +19,11 @@ class MobileDeviceRepository @Inject constructor(
private val remote: MobileDeviceRemote
) {
fun getDevices(semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
fun getDevices(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
return local.getDevices(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getDevices(semester)
if (it) remote.getDevices(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getDevices(semester).toSingle(emptyList())
@ -34,18 +35,18 @@ class MobileDeviceRepository @Inject constructor(
).flatMap { local.getDevices(semester).toSingle(emptyList()) }
}
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice): Single<Boolean> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.unregisterDevice(semester, device)
if (it) remote.unregisterDevice(student, semester, device)
else Single.error(UnknownHostException())
}
}
fun getToken(semester: Semester): Single<MobileDeviceToken> {
fun getToken(student: Student, semester: Semester): Single<MobileDeviceToken> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getToken(semester)
if (it) remote.getToken(student, semester)
else Single.error(UnknownHostException())
}
}

View File

@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.note
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,15 +12,20 @@ import javax.inject.Singleton
@Singleton
class NoteRemote @Inject constructor(private val sdk: Sdk) {
fun getNotes(semester: Semester): Single<List<Note>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getNotes(semester.semesterId)
fun getNotes(student: Student, semester: Semester): Single<List<Note>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getNotes(semester.semesterId)
.map { notes ->
notes.map {
Note(
studentId = semester.studentId,
date = it.date,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol,
category = it.category,
categoryType = it.categoryType.id,
isPointsShow = it.showPoints,
points = it.points,
content = it.content
)
}

View File

@ -23,7 +23,7 @@ class NoteRepository @Inject constructor(
return local.getNotes(student).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getNotes(semester)
if (it) remote.getNotes(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getNotes(student).toSingle(emptyList())

View File

@ -3,7 +3,9 @@ package io.github.wulkanowy.data.repositories.recipient
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -12,15 +14,15 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
@Singleton
class RecipientRemote @Inject constructor(private val sdk: Sdk) {
fun getRecipients(role: Int, unit: ReportingUnit): Single<List<Recipient>> {
return sdk.getRecipients(unit.realId, role)
fun getRecipients(student: Student, role: Int, unit: ReportingUnit): Single<List<Recipient>> {
return sdk.init(student).getRecipients(unit.realId, role)
.map { recipients ->
recipients.map { it.toRecipient() }
}
}
fun getMessageRecipients(message: Message): Single<List<Recipient>> {
return sdk.getMessageRecipients(message.messageId, message.senderId)
fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> {
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId)
.map { recipients ->
recipients.map { it.toRecipient() }
}

View File

@ -2,7 +2,6 @@ package io.github.wulkanowy.data.repositories.recipient
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
@ -17,36 +16,31 @@ import javax.inject.Singleton
class RecipientRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: RecipientLocal,
private val remote: RecipientRemote,
private val sdkHelper: SdkHelper
private val remote: RecipientRemote
) {
fun getRecipients(student: Student, role: Int, unit: ReportingUnit, forceRefresh: Boolean = false): Single<List<Recipient>> {
return Single.just(sdkHelper.init(student))
.flatMap { _ ->
local.getRecipients(student, role, unit).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getRecipients(role, unit)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getRecipients(student, role, unit).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteRecipients(old.uniqueSubtract(new))
local.saveRecipients(new.uniqueSubtract(old))
}
}.flatMap {
local.getRecipients(student, role, unit).toSingle(emptyList())
return local.getRecipients(student, role, unit).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getRecipients(student, role, unit)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getRecipients(student, role, unit).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteRecipients(old.uniqueSubtract(new))
local.saveRecipients(new.uniqueSubtract(old))
}
)
}
}.flatMap {
local.getRecipients(student, role, unit).toSingle(emptyList())
}
)
}
fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> {
return Single.just(sdkHelper.init(student))
.flatMap { ReactiveNetwork.checkInternetConnectivity(settings) }
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getMessageRecipients(message)
if (it) remote.getMessageRecipients(student, message)
else Single.error(UnknownHostException())
}
}

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.repositories.recover
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RecoverRemote @Inject constructor(private val sdk: Sdk) {
fun getReCaptchaSiteKey(host: String, symbol: String): Single<Pair<String, String>> {
return sdk.getPasswordResetCaptchaCode(host, symbol)
}
fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): Single<String> {
return sdk.sendPasswordResetRequest(url, symbol, email, reCaptchaResponse)
}
}

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.data.repositories.recover
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RecoverRepository @Inject constructor(private val settings: InternetObservingSettings, private val remote: RecoverRemote) {
fun getReCaptchaSiteKey(host: String, symbol: String): Single<Pair<String, String>> {
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getReCaptchaSiteKey(host, symbol)
else Single.error(UnknownHostException())
}
}
fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): Single<String> {
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.sendRecoverRequest(url, symbol, email, reCaptchaResponse)
else Single.error(UnknownHostException())
}
}
}

View File

@ -1,7 +1,9 @@
package io.github.wulkanowy.data.repositories.reportingunit
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -9,8 +11,8 @@ import javax.inject.Singleton
@Singleton
class ReportingUnitRemote @Inject constructor(private val sdk: Sdk) {
fun getReportingUnits(): Single<List<ReportingUnit>> {
return sdk.getReportingUnits().map {
fun getReportingUnits(student: Student): Single<List<ReportingUnit>> {
return sdk.init(student).getReportingUnits().map {
it.map { unit ->
ReportingUnit(
studentId = sdk.studentId,

View File

@ -2,7 +2,6 @@ package io.github.wulkanowy.data.repositories.reportingunit
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
@ -16,41 +15,34 @@ import javax.inject.Singleton
class ReportingUnitRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: ReportingUnitLocal,
private val remote: ReportingUnitRemote,
private val sdkHelper: SdkHelper
private val remote: ReportingUnitRemote
) {
fun getReportingUnits(student: Student, forceRefresh: Boolean = false): Single<List<ReportingUnit>> {
return Single.just(sdkHelper.init(student))
.flatMap { _ ->
local.getReportingUnits(student).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getReportingUnits()
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getReportingUnits(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteReportingUnits(old.uniqueSubtract(new))
local.saveReportingUnits(new.uniqueSubtract(old))
}
}.flatMap { local.getReportingUnits(student).toSingle(emptyList()) }
)
}
return local.getReportingUnits(student).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getReportingUnits(student)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getReportingUnits(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteReportingUnits(old.uniqueSubtract(new))
local.saveReportingUnits(new.uniqueSubtract(old))
}
}.flatMap { local.getReportingUnits(student).toSingle(emptyList()) }
)
}
fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> {
return Maybe.just(sdkHelper.init(student))
.flatMap { _ ->
local.getReportingUnit(student, unitId)
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) getReportingUnits(student, true)
else Single.error(UnknownHostException())
}.flatMapMaybe {
local.getReportingUnit(student, unitId)
}
)
}
return local.getReportingUnit(student, unitId)
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) getReportingUnits(student, true)
else Single.error(UnknownHostException())
}.flatMapMaybe {
local.getReportingUnit(student, unitId)
}
)
}
}

View File

@ -2,14 +2,17 @@ package io.github.wulkanowy.data.repositories.school
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
class SchoolRemote @Inject constructor(private val sdk: Sdk) {
fun getSchoolInfo(semester: Semester): Single<School> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSchool()
fun getSchoolInfo(student: Student, semester: Semester): Single<School> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getSchool()
.map {
School(
studentId = semester.studentId,

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
@ -17,11 +18,11 @@ class SchoolRepository @Inject constructor(
private val remote: SchoolRemote
) {
fun getSchoolInfo(semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
fun getSchoolInfo(student: Student, semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
return local.getSchool(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSchoolInfo(semester)
if (it) remote.getSchoolInfo(student, semester)
else Single.error(UnknownHostException())
}.flatMapMaybe { new ->
local.getSchool(semester)

View File

@ -19,6 +19,6 @@ class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) {
}
fun getSemesters(student: Student): Maybe<List<Semester>> {
return semesterDb.loadAll(student.studentId, student.classId).filter { !it.isEmpty() }
return semesterDb.loadAll(student.studentId, student.classId).filter { it.isNotEmpty() }
}
}

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.semester
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -11,7 +12,7 @@ import javax.inject.Singleton
class SemesterRemote @Inject constructor(private val sdk: Sdk) {
fun getSemesters(student: Student): Single<List<Semester>> {
return sdk.getSemesters().map { semesters ->
return sdk.init(student).getSemesters().map { semesters ->
semesters.map {
Semester(
studentId = student.studentId,
@ -20,7 +21,6 @@ class SemesterRemote @Inject constructor(private val sdk: Sdk) {
schoolYear = it.schoolYear,
semesterId = it.semesterId,
semesterName = it.semesterNumber,
isCurrent = it.current,
start = it.start,
end = it.end,
classId = it.classId,

View File

@ -2,13 +2,13 @@ package io.github.wulkanowy.data.repositories.semester
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.getCurrentOrLast
import io.github.wulkanowy.utils.isCurrent
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Maybe
import io.reactivex.Single
import timber.log.Timber
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@ -17,32 +17,31 @@ import javax.inject.Singleton
class SemesterRepository @Inject constructor(
private val remote: SemesterRemote,
private val local: SemesterLocal,
private val settings: InternetObservingSettings,
private val sdkHelper: SdkHelper
private val settings: InternetObservingSettings
) {
fun getSemesters(student: Student, forceRefresh: Boolean = false): Single<List<Semester>> {
return Maybe.just(sdkHelper.init(student))
.flatMap { local.getSemesters(student).filter { !forceRefresh } }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSemesters(student) else Single.error(UnknownHostException())
}.flatMap { new ->
val currentSemesters = new.filter { it.isCurrent }
if (currentSemesters.size == 1) {
local.getSemesters(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteSemesters(old.uniqueSubtract(new))
local.saveSemesters(new.uniqueSubtract(old))
}
} else {
Timber.i("Current semesters list:\n${new.joinToString(separator = "\n")}")
throw IllegalArgumentException("Current semester can be only one.")
}
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
return local.getSemesters(student).filter { !forceRefresh }.filter { semesters ->
when {
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> semesters.firstOrNull { it.isCurrent }?.diaryId != 0
refreshOnNoCurrent -> semesters.any { semester -> semester.isCurrent }
else -> true
}
}.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSemesters(student)
else Single.error(UnknownHostException())
}.flatMap { new ->
if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!")
local.getSemesters(student).toSingle(emptyList()).doOnSuccess { old ->
local.deleteSemesters(old.uniqueSubtract(new))
local.saveSemesters(new.uniqueSubtract(old))
}
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
}
fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single<Semester> {
return getSemesters(student, forceRefresh).map { item -> item.single { it.isCurrent } }
return getSemesters(student, forceRefresh).map { it.getCurrentOrLast() }
}
}

View File

@ -29,10 +29,18 @@ class StudentLocal @Inject constructor(
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
return studentDb.loadAll()
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
.map { list -> list.map { it.apply { if (decryptPass && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) } } }
.filter { it.isNotEmpty() }
}
fun getStudentById(id: Int): Maybe<Student> {
return studentDb.loadById(id).map {
it.apply {
if (Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password)
}
}
}
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
return studentDb.loadCurrent().map {
it.apply {

View File

@ -22,6 +22,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
userLoginId = student.userLoginId,
studentName = student.studentName,
schoolSymbol = student.schoolSymbol,
schoolShortName = student.schoolShortName,
schoolName = student.schoolName,
className = student.className,
classId = student.classId,

View File

@ -29,7 +29,7 @@ class StudentRepository @Inject constructor(
}
}
fun getStudentsScrapper(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
fun getStudentsScrapper(email: String, password: String, endpoint: String, symbol: String): Single<List<Student>> {
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getStudentsScrapper(email, password, endpoint, symbol)
else Single.error(UnknownHostException("No internet connection"))
@ -47,6 +47,12 @@ class StudentRepository @Inject constructor(
return local.getStudents(decryptPass).toSingle(emptyList())
}
fun getStudentById(id: Int): Single<Student> {
return local.getStudentById(id)
.switchIfEmpty(Maybe.error(NoCurrentStudentException()))
.toSingle()
}
fun getCurrentStudent(decryptPass: Boolean = true): Single<Student> {
return local.getCurrentStudent(decryptPass)
.switchIfEmpty(Maybe.error(NoCurrentStudentException()))

View File

@ -12,7 +12,7 @@ class SubjectLocal @Inject constructor(private val subjectDao: SubjectDao) {
fun getSubjects(semester: Semester): Maybe<List<Subject>> {
return subjectDao.loadAll(semester.diaryId, semester.studentId)
.filter { !it.isEmpty() }
.filter { it.isNotEmpty() }
}
fun saveSubjects(subjects: List<Subject>) {

View File

@ -1,8 +1,10 @@
package io.github.wulkanowy.data.repositories.subject
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,8 +12,9 @@ import javax.inject.Singleton
@Singleton
class SubjectRemote @Inject constructor(private val sdk: Sdk) {
fun getSubjects(semester: Semester): Single<List<Subject>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSubjects()
fun getSubjects(student: Student, semester: Semester): Single<List<Subject>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getSubjects()
.map { subjects ->
subjects.map {
Subject(

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.subject
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
@ -17,11 +18,11 @@ class SubjectRepository @Inject constructor(
private val remote: SubjectRemote
) {
fun getSubjects(semester: Semester, forceRefresh: Boolean = false): Single<List<Subject>> {
fun getSubjects(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<Subject>> {
return local.getSubjects(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSubjects(semester)
if (it) remote.getSubjects(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getSubjects(semester)

View File

@ -1,8 +1,10 @@
package io.github.wulkanowy.data.repositories.teacher
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@ -10,8 +12,9 @@ import javax.inject.Singleton
@Singleton
class TeacherRemote @Inject constructor(private val sdk: Sdk) {
fun getTeachers(semester: Semester): Single<List<Teacher>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTeachers(semester.semesterId)
fun getTeachers(student: Student, semester: Semester): Single<List<Teacher>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getTeachers(semester.semesterId)
.map { teachers ->
teachers.map {
Teacher(

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.teacher
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
@ -17,11 +18,11 @@ class TeacherRepository @Inject constructor(
private val remote: TeacherRemote
) {
fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> {
fun getTeachers(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> {
return local.getTeachers(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getTeachers(semester)
if (it) remote.getTeachers(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getTeachers(semester).toSingle(emptyList())

View File

@ -1,8 +1,10 @@
package io.github.wulkanowy.data.repositories.timetable
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
@ -11,8 +13,9 @@ import javax.inject.Singleton
@Singleton
class TimetableRemote @Inject constructor(private val sdk: Sdk) {
fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTimetable(startDate, endDate)
fun getTimetable(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getTimetable(startDate, endDate)
.map { lessons ->
lessons.map {
Timetable(
@ -30,7 +33,7 @@ class TimetableRemote @Inject constructor(private val sdk: Sdk) {
teacher = it.teacher,
teacherOld = it.teacherOld,
info = it.info,
studentPlan = it.studentPlan,
isStudentPlan = it.studentPlan,
changes = it.changes,
canceled = it.canceled
)

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.timetable
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
@ -20,11 +21,11 @@ class TimetableRepository @Inject constructor(
private val remote: TimetableRemote
) {
fun getTimetable(semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
fun getTimetable(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
local.getTimetable(semester, monday, friday).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getTimetable(semester, monday, friday)
if (it) remote.getTimetable(student, semester, monday, friday)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getTimetable(semester, monday, friday)

Some files were not shown because too many files have changed in this diff Show More