mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-13 14:10:46 +02:00
Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
dc9e6081c5 | |||
26f8c03570 | |||
97e0f36f09 | |||
9b13552b73 | |||
d8559637a5 | |||
00a90a14dc | |||
d56afb034b | |||
0327ba37f1 | |||
12a54e58b5 | |||
238250e8c9 | |||
041bfc6cc0 | |||
8a4866cb62 | |||
0e4d609bbf | |||
f07b12bd87 | |||
0413dbffa2 | |||
c214b48409 | |||
91a6366548 | |||
03c9932b8c | |||
ea4919a25d | |||
f98b174857 | |||
c0aeb0d2f3 | |||
fcb627aac6 | |||
7f0aea29cd | |||
f6dcbb6594 | |||
b790421693 | |||
f5a7799924 | |||
b052b5bd66 | |||
12d8de1def | |||
9303483470 | |||
f8adc86a0e | |||
db57c258c5 | |||
ddb2760c16 | |||
14d267a95a | |||
a6c4053896 | |||
949a68ec1d | |||
93333a8c48 | |||
da48c059ec | |||
ee5566d1ef | |||
b794b30346 | |||
0db6393bb0 | |||
fcc3c55110 | |||
328c07eaf4 | |||
b004ec048e | |||
b9f83875a0 | |||
8c869d082b | |||
043f8210ba | |||
41a79caf83 | |||
0427fa6087 | |||
2f3c912dbe | |||
219a7443c0 | |||
6deb408d80 | |||
c6e1ff2164 | |||
bc0918a115 | |||
55ff9173be | |||
d4d548846f | |||
ef4527f140 | |||
0b1e7242bb |
3
.gitignore
vendored
3
.gitignore
vendored
@ -86,4 +86,5 @@ app/schemas/
|
|||||||
|
|
||||||
signatures/
|
signatures/
|
||||||
|
|
||||||
app/.cxx
|
app/.cxx
|
||||||
|
/i18n/
|
||||||
|
10
.idea/jarRepositories.xml
generated
10
.idea/jarRepositories.xml
generated
@ -41,5 +41,15 @@
|
|||||||
<option name="name" value="MavenRepo" />
|
<option name="name" value="MavenRepo" />
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven4" />
|
||||||
|
<option name="name" value="maven4" />
|
||||||
|
<option name="url" value="https://dl.bintray.com/undervoid/Powerpermission" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven4" />
|
||||||
|
<option name="name" value="maven4" />
|
||||||
|
<option name="url" value="https://dl.bintray.com/undervoid/PowerPermission" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
1
annotation/.gitignore
vendored
Normal file
1
annotation/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
29
annotation/build.gradle
Normal file
29
annotation/build.gradle
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'java-library'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = "7"
|
||||||
|
targetCompatibility = "7"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.annotation
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@MustBeDocumented
|
||||||
|
annotation class SelectiveDao(
|
||||||
|
val db: KClass<*>
|
||||||
|
)
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.annotation
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@MustBeDocumented
|
||||||
|
annotation class UpdateSelective(
|
||||||
|
val primaryKeys: Array<String>,
|
||||||
|
val skippedColumns: Array<String> = []
|
||||||
|
)
|
@ -193,6 +193,14 @@ dependencies {
|
|||||||
implementation "io.coil-kt:coil:0.9.2"
|
implementation "io.coil-kt:coil:0.9.2"
|
||||||
|
|
||||||
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
||||||
|
|
||||||
|
implementation project(":annotation")
|
||||||
|
kapt project(":codegen")
|
||||||
|
|
||||||
|
implementation 'com.google.android:flexbox:2.0.1'
|
||||||
|
|
||||||
|
implementation 'com.qifan.powerpermission:powerpermission:1.0.0'
|
||||||
|
implementation 'com.qifan.powerpermission:powerpermission-coroutines:1.0.0'
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
<!-- PowerPermission uses minSdk 21, it's safe to override as it is used only in >= 23 -->
|
||||||
|
<uses-sdk tools:overrideLibrary="com.qifan.powerpermission.coroutines, com.qifan.powerpermission.core" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
<h3>Wersja 4.0-rc.2, 2020-03-26</h3>
|
<h3>Wersja 4.0, 2020-04-19</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
||||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkość oraz poprawność pobieranych danych</li>
|
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkość oraz poprawność pobieranych danych</li>
|
||||||
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
||||||
|
<li>Wyszukiwarka wiadomości, pozwalająca na łatwe znalezienie potrzebnej konwersacji.</li>
|
||||||
|
<li>Możliwość pobierania załączników do zadań domowych oraz wiadomości w każdym dzienniku.</li>
|
||||||
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
||||||
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
||||||
<li>Nowe <b>Oceny</b> - z możliwością zmiany wartości plusów oraz minusów oraz wyłączenia niektórych ocen ze średniej</li>
|
<li>Nowe <b>Oceny</b> - z możliwością zmiany wartości plusów oraz minusów oraz wyłączenia niektórych ocen ze średniej</li>
|
||||||
@ -10,6 +12,7 @@
|
|||||||
<li>Znaczki nieprzeczytanych informacji na obrazkach profili.</li>
|
<li>Znaczki nieprzeczytanych informacji na obrazkach profili.</li>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
<li>Udoskonalone tłumaczenie na j.angielski (dzięki @Predator)</li>
|
||||||
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
||||||
<li>Nowe, przyjemniejsze powiadomienia</li>
|
<li>Nowe, przyjemniejsze powiadomienia</li>
|
||||||
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*secret password - removed for source code publication*/
|
/*secret password - removed for source code publication*/
|
||||||
static toys AES_IV[16] = {
|
static toys AES_IV[16] = {
|
||||||
0x30, 0xfe, 0xe2, 0x8d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
0x38, 0xd4, 0x73, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||||
|
|
||||||
|
@ -43,10 +43,7 @@ import pl.szczodrzynski.edziennik.sync.SyncWorker
|
|||||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||||
import pl.szczodrzynski.edziennik.utils.*
|
import pl.szczodrzynski.edziennik.utils.*
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
import pl.szczodrzynski.edziennik.utils.managers.*
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
|
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.TimetableManager
|
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
@ -67,6 +64,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
|||||||
val userActionManager by lazy { UserActionManager(this) }
|
val userActionManager by lazy { UserActionManager(this) }
|
||||||
val gradesManager by lazy { GradesManager(this) }
|
val gradesManager by lazy { GradesManager(this) }
|
||||||
val timetableManager by lazy { TimetableManager(this) }
|
val timetableManager by lazy { TimetableManager(this) }
|
||||||
|
val eventManager by lazy { EventManager(this) }
|
||||||
|
val permissionManager by lazy { PermissionManager(this) }
|
||||||
|
|
||||||
val db
|
val db
|
||||||
get() = App.db
|
get() = App.db
|
||||||
@ -168,7 +167,11 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
|||||||
db.profileDao().firstId?.let { profileLoadById(it) }
|
db.profileDao().firstId?.let { profileLoadById(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
config.ui.language?.let {
|
||||||
|
setLanguage(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
devMode = BuildConfig.DEBUG
|
||||||
|
|
||||||
Signing.getCert(this)
|
Signing.getCert(this)
|
||||||
|
|
||||||
|
@ -27,10 +27,7 @@ import android.util.Base64.NO_WRAP
|
|||||||
import android.util.Base64.encodeToString
|
import android.util.Base64.encodeToString
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.CheckBox
|
import android.widget.*
|
||||||
import android.widget.CompoundButton
|
|
||||||
import android.widget.RadioButton
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.*
|
import androidx.annotation.*
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.database.getIntOrNull
|
import androidx.core.database.getIntOrNull
|
||||||
@ -40,7 +37,11 @@ import androidx.core.util.forEach
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.google.android.gms.security.ProviderInstaller
|
import com.google.android.gms.security.ProviderInstaller
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
@ -141,6 +142,10 @@ fun CharSequence?.isNotNullNorEmpty(): Boolean {
|
|||||||
return this != null && this.isNotEmpty()
|
return this != null && this.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> Collection<T>?.isNotNullNorEmpty(): Boolean {
|
||||||
|
return this != null && this.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
fun CharSequence?.isNotNullNorBlank(): Boolean {
|
fun CharSequence?.isNotNullNorBlank(): Boolean {
|
||||||
return this != null && this.isNotBlank()
|
return this != null && this.isNotBlank()
|
||||||
}
|
}
|
||||||
@ -160,6 +165,13 @@ fun Bundle?.getString(key: String, defaultValue: String): String {
|
|||||||
return this?.getString(key, defaultValue) ?: defaultValue
|
return this?.getString(key, defaultValue) ?: defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Bundle?.getIntOrNull(key: String): Int? {
|
||||||
|
return this?.get(key) as? Int
|
||||||
|
}
|
||||||
|
fun <T : Any> Bundle?.get(key: String): T? {
|
||||||
|
return this?.get(key) as? T?
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ` The quick BROWN_fox Jumps OveR THE LAZy-DOG. `
|
* ` The quick BROWN_fox Jumps OveR THE LAZy-DOG. `
|
||||||
*
|
*
|
||||||
@ -442,7 +454,7 @@ operator fun MatchResult.get(group: Int): String {
|
|||||||
return groupValues[group]
|
return groupValues[group]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.setLanguage(language: String) {
|
fun Context.setLanguage(language: String) {
|
||||||
val locale = Locale(language.toLowerCase(Locale.ROOT))
|
val locale = Locale(language.toLowerCase(Locale.ROOT))
|
||||||
val configuration = resources.configuration
|
val configuration = resources.configuration
|
||||||
Locale.setDefault(locale)
|
Locale.setDefault(locale)
|
||||||
@ -451,7 +463,6 @@ fun Activity.setLanguage(language: String) {
|
|||||||
}
|
}
|
||||||
configuration.locale = locale
|
configuration.locale = locale
|
||||||
resources.updateConfiguration(configuration, resources.displayMetrics)
|
resources.updateConfiguration(configuration, resources.displayMetrics)
|
||||||
baseContext.resources.updateConfiguration(configuration, baseContext.resources.displayMetrics)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -560,7 +571,7 @@ fun CharSequence?.asBoldSpannable(): Spannable {
|
|||||||
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignoreCase: Boolean = false): Spannable {
|
fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignoreCase: Boolean = false, ignoreDiacritics: Boolean = false): Spannable {
|
||||||
val spannable = SpannableString(this)
|
val spannable = SpannableString(this)
|
||||||
if (substring == null) {
|
if (substring == null) {
|
||||||
spans.forEach {
|
spans.forEach {
|
||||||
@ -568,17 +579,44 @@ fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (substring.isNotEmpty()) {
|
else if (substring.isNotEmpty()) {
|
||||||
var index = indexOf(substring, ignoreCase = ignoreCase)
|
val string =
|
||||||
|
if (ignoreDiacritics)
|
||||||
|
this.cleanDiacritics()
|
||||||
|
else this
|
||||||
|
|
||||||
|
var index = string.indexOf(substring, ignoreCase = ignoreCase)
|
||||||
|
.takeIf { it != -1 } ?: indexOf(substring, ignoreCase = ignoreCase)
|
||||||
while (index >= 0) {
|
while (index >= 0) {
|
||||||
spans.forEach {
|
spans.forEach {
|
||||||
spannable.setSpan(it, index, index + substring.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(it, index, index + substring.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
index = indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
index = string.indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
||||||
|
.takeIf { it != -1 } ?: indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun CharSequence.cleanDiacritics(): String {
|
||||||
|
val nameClean = StringBuilder()
|
||||||
|
forEach {
|
||||||
|
val ch = when (it) {
|
||||||
|
'ż' -> 'z'
|
||||||
|
'ó' -> 'o'
|
||||||
|
'ł' -> 'l'
|
||||||
|
'ć' -> 'c'
|
||||||
|
'ę' -> 'e'
|
||||||
|
'ś' -> 's'
|
||||||
|
'ą' -> 'a'
|
||||||
|
'ź' -> 'z'
|
||||||
|
'ń' -> 'n'
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
nameClean.append(ch)
|
||||||
|
}
|
||||||
|
return nameClean.toString()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new read-only list only of those given elements, that are not empty.
|
* Returns a new read-only list only of those given elements, that are not empty.
|
||||||
* Applies for CharSequence and descendants.
|
* Applies for CharSequence and descendants.
|
||||||
@ -722,6 +760,13 @@ inline fun <T : View> T.onClick(crossinline onClickListener: (v: T) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : View> T.onLongClick(crossinline onLongClickListener: (v: T) -> Boolean) {
|
||||||
|
setOnLongClickListener { v: View ->
|
||||||
|
onLongClickListener(v as T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
||||||
setOnCheckedChangeListener { buttonView, isChecked ->
|
setOnCheckedChangeListener { buttonView, isChecked ->
|
||||||
@ -729,6 +774,19 @@ inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : MaterialButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
||||||
|
clearOnCheckedChangeListeners()
|
||||||
|
addOnCheckedChangeListener { buttonView, isChecked ->
|
||||||
|
onChangeListener(buttonView as T, isChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun View.attachToastHint(stringRes: Int) = onLongClick {
|
||||||
|
Toast.makeText(it.context, stringRes, Toast.LENGTH_SHORT).show()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
|
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
|
||||||
observe(lifecycleOwner, object : Observer<T> {
|
observe(lifecycleOwner, object : Observer<T> {
|
||||||
override fun onChanged(t: T?) {
|
override fun onChanged(t: T?) {
|
||||||
@ -784,7 +842,7 @@ fun View.findParentById(targetId: Int): View? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = launch {
|
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: suspend CoroutineScope.() -> Unit) = launch {
|
||||||
delay(delayMillis)
|
delay(delayMillis)
|
||||||
if (repeatMillis > 0) {
|
if (repeatMillis > 0) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -1008,6 +1066,7 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
Notification.TYPE_FEEDBACK_MESSAGE -> R.string.notification_type_feedback_message
|
Notification.TYPE_FEEDBACK_MESSAGE -> R.string.notification_type_feedback_message
|
||||||
Notification.TYPE_NEW_ANNOUNCEMENT -> R.string.notification_type_new_announcement
|
Notification.TYPE_NEW_ANNOUNCEMENT -> R.string.notification_type_new_announcement
|
||||||
Notification.TYPE_AUTO_ARCHIVING -> R.string.notification_type_auto_archiving
|
Notification.TYPE_AUTO_ARCHIVING -> R.string.notification_type_auto_archiving
|
||||||
|
Notification.TYPE_TEACHER_ABSENCE -> R.string.notification_type_new_teacher_absence
|
||||||
Notification.TYPE_GENERAL -> R.string.notification_type_general
|
Notification.TYPE_GENERAL -> R.string.notification_type_general
|
||||||
else -> R.string.notification_type_general
|
else -> R.string.notification_type_general
|
||||||
})
|
})
|
||||||
@ -1166,3 +1225,23 @@ fun TextView.getTextPosition(range: IntRange): Rect {
|
|||||||
|
|
||||||
return parentTextViewRect
|
return parentTextViewRect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun ViewPager.addOnPageSelectedListener(crossinline block: (position: Int) -> Unit) = addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||||
|
override fun onPageScrollStateChanged(state: Int) {}
|
||||||
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||||
|
override fun onPageSelected(position: Int) { block(position) }
|
||||||
|
})
|
||||||
|
|
||||||
|
val SwipeRefreshLayout.onScrollListener: RecyclerView.OnScrollListener
|
||||||
|
get() = object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
|
if (recyclerView.canScrollVertically(-1))
|
||||||
|
this@onScrollListener.isEnabled = false
|
||||||
|
if (!recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE)
|
||||||
|
this@onScrollListener.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun <K, V> Iterable<Pair<K, V>>.get(key: K): V? {
|
||||||
|
return firstOrNull { it.first == key }?.second
|
||||||
|
}
|
||||||
|
@ -20,7 +20,6 @@ import androidx.appcompat.widget.PopupMenu
|
|||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.danimahardhika.cafebar.CafeBar
|
import com.danimahardhika.cafebar.CafeBar
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.mikepenz.iconics.IconicsColor
|
import com.mikepenz.iconics.IconicsColor
|
||||||
@ -55,22 +54,22 @@ import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
|||||||
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.DebugFragment
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.MainSnackbar
|
import pl.szczodrzynski.edziennik.ui.modules.base.MainSnackbar
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment
|
import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.DebugFragment
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.LabFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
|
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
|
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
|
import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesListFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeFragment
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.compose.MessagesComposeFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsListFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment
|
import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
||||||
@ -129,6 +128,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
const val TARGET_MESSAGES_DETAILS = 503
|
const val TARGET_MESSAGES_DETAILS = 503
|
||||||
const val TARGET_MESSAGES_COMPOSE = 504
|
const val TARGET_MESSAGES_COMPOSE = 504
|
||||||
const val TARGET_WEB_PUSH = 140
|
const val TARGET_WEB_PUSH = 140
|
||||||
|
const val TARGET_LAB = 1000
|
||||||
|
|
||||||
const val HOME_ID = DRAWER_ITEM_HOME
|
const val HOME_ID = DRAWER_ITEM_HOME
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
.withBadgeTypeId(TYPE_EVENT)
|
.withBadgeTypeId(TYPE_EVENT)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
|
|
||||||
list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesFragment::class)
|
list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesListFragment::class)
|
||||||
.withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box_outline)
|
.withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box_outline)
|
||||||
.withBadgeTypeId(TYPE_GRADE)
|
.withBadgeTypeId(TYPE_GRADE)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
@ -185,7 +185,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
|
|
||||||
|
|
||||||
// static drawer items
|
// static drawer items
|
||||||
list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsFragment::class)
|
list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsListFragment::class)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_bell_ring_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_bell_ring_outline)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
.isStatic(true)
|
.isStatic(true)
|
||||||
@ -226,7 +226,14 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
|
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
|
||||||
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class)
|
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class)
|
||||||
list += NavTarget(TARGET_WEB_PUSH, R.string.menu_web_push, WebPushFragment::class)
|
list += NavTarget(TARGET_WEB_PUSH, R.string.menu_web_push, WebPushFragment::class)
|
||||||
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
if (App.debugMode) {
|
||||||
|
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
||||||
|
list += NavTarget(TARGET_LAB, R.string.menu_lab, LabFragment::class)
|
||||||
|
.withIcon(CommunityMaterial.Icon.cmd_flask_outline)
|
||||||
|
.isInDrawer(true)
|
||||||
|
.isBelowSeparator(true)
|
||||||
|
.isStatic(true)
|
||||||
|
}
|
||||||
|
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
@ -407,8 +414,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
R.color.md_green_500
|
R.color.md_green_500
|
||||||
)
|
)
|
||||||
|
|
||||||
isStoragePermissionGranted()
|
|
||||||
|
|
||||||
SyncWorker.scheduleNext(app)
|
SyncWorker.scheduleNext(app)
|
||||||
UpdateWorker.scheduleNext(app)
|
UpdateWorker.scheduleNext(app)
|
||||||
|
|
||||||
@ -509,7 +514,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon2.cmd_help_circle_outline)
|
.withIcon(CommunityMaterial.Icon2.cmd_help_circle_outline)
|
||||||
.withOnClickListener(View.OnClickListener { loadTarget(TARGET_FEEDBACK) })
|
.withOnClickListener(View.OnClickListener { loadTarget(TARGET_FEEDBACK) })
|
||||||
)
|
)
|
||||||
if (App.devMode) {
|
if (App.debugMode) {
|
||||||
bottomSheet += BottomSheetPrimaryItem(false)
|
bottomSheet += BottomSheetPrimaryItem(false)
|
||||||
.withTitle(R.string.menu_debug)
|
.withTitle(R.string.menu_debug)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_android_studio)
|
.withIcon(CommunityMaterial.Icon.cmd_android_studio)
|
||||||
@ -880,9 +885,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
app.profileLoad(id) {
|
app.profileLoad(id) {
|
||||||
MessagesFragment.pageSelection = -1
|
MessagesFragment.pageSelection = -1
|
||||||
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
|
|
||||||
setDrawerItems()
|
setDrawerItems()
|
||||||
// the drawer profile is updated automatically when the drawer item is clicked
|
// the drawer profile is updated automatically when the drawer item is clicked
|
||||||
@ -907,9 +909,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
loadTarget(target, arguments)
|
loadTarget(target, arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun loadTarget(target: NavTarget, arguments: Bundle? = null) {
|
private fun loadTarget(target: NavTarget, args: Bundle? = null) {
|
||||||
d("NavDebug", "loadTarget(target = $target, arguments = $arguments)")
|
d("NavDebug", "loadTarget(target = $target, args = $args)")
|
||||||
|
|
||||||
|
val arguments = args ?: navBackStack.firstOrNull { it.first.id == target.id }?.second ?: Bundle()
|
||||||
bottomSheet.close()
|
bottomSheet.close()
|
||||||
bottomSheet.removeAllContextual()
|
bottomSheet.removeAllContextual()
|
||||||
bottomSheet.toggleGroupEnabled = false
|
bottomSheet.toggleGroupEnabled = false
|
||||||
@ -957,6 +960,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
navBackStack.removeAt(navBackStack.lastIndex)
|
navBackStack.removeAt(navBackStack.lastIndex)
|
||||||
}
|
}
|
||||||
navTarget = target
|
navTarget = target
|
||||||
|
navArguments = arguments
|
||||||
|
|
||||||
return@let null
|
return@let null
|
||||||
}?.let {
|
}?.let {
|
||||||
@ -966,7 +970,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
R.anim.task_open_enter,
|
R.anim.task_open_enter,
|
||||||
R.anim.task_open_exit
|
R.anim.task_open_exit
|
||||||
)
|
)
|
||||||
navBackStack.add(navTarget to arguments)
|
navBackStack.add(navTarget to navArguments)
|
||||||
navTarget = target
|
navTarget = target
|
||||||
navArguments = arguments
|
navArguments = arguments
|
||||||
}
|
}
|
||||||
@ -1068,6 +1072,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
.also { if (target.icon != null) it.withIcon(target.icon!!) }
|
.also { if (target.icon != null) it.withIcon(target.icon!!) }
|
||||||
.also { if (target.title != null) it.withAppTitle(getString(target.title!!)) }
|
.also { if (target.title != null) it.withAppTitle(getString(target.title!!)) }
|
||||||
.also { if (target.badgeTypeId != null) it.withBadgeStyle(drawer.badgeStyle)}
|
.also { if (target.badgeTypeId != null) it.withBadgeStyle(drawer.badgeStyle)}
|
||||||
|
.withSelectedBackgroundAnimated(false)
|
||||||
|
|
||||||
if (target.badgeTypeId != null)
|
if (target.badgeTypeId != null)
|
||||||
drawer.addUnreadCounterType(target.badgeTypeId!!, target.id)
|
drawer.addUnreadCounterType(target.badgeTypeId!!, target.id)
|
||||||
|
@ -22,7 +22,7 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
|
|
||||||
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
||||||
companion object {
|
companion object {
|
||||||
const val DATA_VERSION = 11
|
const val DATA_VERSION = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
@ -18,7 +18,7 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
|
|
||||||
class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEntry>) : CoroutineScope, AbstractConfig {
|
class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEntry>) : CoroutineScope, AbstractConfig {
|
||||||
companion object {
|
companion object {
|
||||||
const val DATA_VERSION = 1
|
const val DATA_VERSION = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
@ -64,11 +64,25 @@ class ConfigMigration(app: App, config: Config) {
|
|||||||
dataVersion = 2
|
dataVersion = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dataVersion < 3) {
|
||||||
|
update = null
|
||||||
|
privacyPolicyAccepted = false
|
||||||
|
debugMode = false
|
||||||
|
devModePassword = null
|
||||||
|
appInstalledTime = 0L
|
||||||
|
appRateSnackbarTime = 0L
|
||||||
|
|
||||||
|
dataVersion = 3
|
||||||
|
}
|
||||||
|
|
||||||
if (dataVersion < 10) {
|
if (dataVersion < 10) {
|
||||||
ui.openDrawerOnBackPressed = false
|
ui.openDrawerOnBackPressed = false
|
||||||
ui.snowfall = false
|
ui.snowfall = false
|
||||||
ui.bottomSheetOpened = false
|
ui.bottomSheetOpened = false
|
||||||
sync.dontShowAppManagerDialog = false
|
sync.dontShowAppManagerDialog = false
|
||||||
|
sync.webPushEnabled = true
|
||||||
|
sync.lastAppSync = 0L
|
||||||
|
|
||||||
|
|
||||||
dataVersion = 10
|
dataVersion = 10
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
@ -14,11 +15,23 @@ class ProfileConfigMigration(config: ProfileConfig) {
|
|||||||
|
|
||||||
if (dataVersion < 1) {
|
if (dataVersion < 1) {
|
||||||
grades.colorMode = COLOR_MODE_WEIGHTED
|
grades.colorMode = COLOR_MODE_WEIGHTED
|
||||||
grades.dontCountEnabled = false
|
|
||||||
grades.yearAverageMode = YEAR_ALL_GRADES
|
grades.yearAverageMode = YEAR_ALL_GRADES
|
||||||
|
grades.hideImproved = false
|
||||||
|
grades.averageWithoutWeight = true
|
||||||
|
grades.plusValue = null
|
||||||
|
grades.minusValue = null
|
||||||
|
grades.dontCountEnabled = false
|
||||||
|
grades.dontCountGrades = listOf()
|
||||||
ui.agendaViewType = AGENDA_DEFAULT
|
ui.agendaViewType = AGENDA_DEFAULT
|
||||||
|
// no migration for ui.homeCards
|
||||||
|
|
||||||
dataVersion = 1
|
dataVersion = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dataVersion < 2) {
|
||||||
|
sync.notificationFilter = sync.notificationFilter + Notification.TYPE_TEACHER_ABSENCE
|
||||||
|
|
||||||
|
dataVersion = 2
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,9 @@ class ApiService : Service() {
|
|||||||
context.startService(Intent(context, ApiService::class.java))
|
context.startService(Intent(context, ApiService::class.java))
|
||||||
EventBus.getDefault().postSticky(request)
|
EventBus.getDefault().postSticky(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastEventTime = System.currentTimeMillis()
|
||||||
|
var taskCancelTries = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private val app by lazy { applicationContext as App }
|
private val app by lazy { applicationContext as App }
|
||||||
@ -64,9 +67,6 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
private val notification by lazy { EdziennikNotification(app) }
|
private val notification by lazy { EdziennikNotification(app) }
|
||||||
|
|
||||||
private var lastEventTime = System.currentTimeMillis()
|
|
||||||
private var taskCancelTries = 0
|
|
||||||
|
|
||||||
/* ______ _ _ _ _ _____ _ _ _ _
|
/* ______ _ _ _ _ _____ _ _ _ _
|
||||||
| ____| | | (_) (_) | / ____| | | | | | |
|
| ____| | | (_) (_) | / ____| | | | | | |
|
||||||
| |__ __| |_____ ___ _ __ _ __ _| | __ | | __ _| | | |__ __ _ ___| | __
|
| |__ __| |_____ ___ _ __ _ __ _| | __ | | __ _| | | |__ __ _ ___| | __
|
||||||
|
@ -56,6 +56,8 @@ const val LIBRUS_SYNERGIA_TOKEN_LOGIN_URL = "https://synergia.librus.pl/loguj/to
|
|||||||
const val LIBRUS_MESSAGES_URL = "https://wiadomosci.librus.pl/module"
|
const val LIBRUS_MESSAGES_URL = "https://wiadomosci.librus.pl/module"
|
||||||
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
||||||
|
|
||||||
|
const val LIBRUS_SYNERGIA_HOMEWORK_ATTACHMENT_URL = "https://synergia.librus.pl/homework/downloadFile"
|
||||||
|
|
||||||
const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
||||||
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
||||||
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
||||||
@ -74,6 +76,8 @@ const val IDZIENNIK_WEB_GET_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/Pobier
|
|||||||
const val IDZIENNIK_WEB_GET_RECIPIENT_LIST = "mod_komunikator/WS_wiadomosci.asmx/pobierzListeOdbiorcowPanelRodzic"
|
const val IDZIENNIK_WEB_GET_RECIPIENT_LIST = "mod_komunikator/WS_wiadomosci.asmx/pobierzListeOdbiorcowPanelRodzic"
|
||||||
const val IDZIENNIK_WEB_SEND_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/WyslijWiadomosc"
|
const val IDZIENNIK_WEB_SEND_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/WyslijWiadomosc"
|
||||||
const val IDZIENNIK_WEB_GET_ATTACHMENT = "mod_komunikator/Download.ashx"
|
const val IDZIENNIK_WEB_GET_ATTACHMENT = "mod_komunikator/Download.ashx"
|
||||||
|
const val IDZIENNIK_WEB_GET_HOMEWORK = "mod_panelRodzica/pracaDomowa/WS_pracaDomowa.asmx/pobierzJednaPraceDomowa"
|
||||||
|
const val IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT = "mod_panelRodzica/pracaDomowa.aspx"
|
||||||
|
|
||||||
val IDZIENNIK_API_USER_AGENT = SYSTEM_USER_AGENT
|
val IDZIENNIK_API_USER_AGENT = SYSTEM_USER_AGENT
|
||||||
const val IDZIENNIK_API_URL = "https://iuczniowie.progman.pl/idziennik/api"
|
const val IDZIENNIK_API_URL = "https://iuczniowie.progman.pl/idziennik/api"
|
||||||
@ -107,5 +111,7 @@ const val VULCAN_API_ENDPOINT_MESSAGES_SENT = "mobile-api/Uczen.v3.Uczen/Wiadomo
|
|||||||
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
|
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_ADD = "mobile-api/Uczen.v3.Uczen/DodajWiadomosc"
|
const val VULCAN_API_ENDPOINT_MESSAGES_ADD = "mobile-api/Uczen.v3.Uczen/DodajWiadomosc"
|
||||||
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
|
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
|
||||||
|
const val VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/WiadomosciZalacznik"
|
||||||
|
const val VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/ZadaniaDomoweZalacznik"
|
||||||
|
|
||||||
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
||||||
|
@ -8,11 +8,12 @@ import android.app.Notification
|
|||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.Bundle
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
@ -35,16 +36,18 @@ class EdziennikNotification(val app: App) {
|
|||||||
var serviceClosed = false
|
var serviceClosed = false
|
||||||
|
|
||||||
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = SzkolnyReceiver.getIntent(app, Bundle(
|
||||||
intent.putExtra("task", "TaskCancelRequest")
|
"task" to "TaskCancelRequest",
|
||||||
intent.putExtra("taskId", taskId)
|
"taskId" to taskId
|
||||||
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
))
|
||||||
|
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) as PendingIntent
|
||||||
}
|
}
|
||||||
private val closePendingIntent: PendingIntent
|
private val closePendingIntent: PendingIntent
|
||||||
get() {
|
get() {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = SzkolnyReceiver.getIntent(app, Bundle(
|
||||||
intent.putExtra("task", "ServiceCloseRequest")
|
"task" to "ServiceCloseRequest"
|
||||||
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
))
|
||||||
|
return PendingIntent.getBroadcast(app, 0, intent, 0) as PendingIntent
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun errorCountText(): String? {
|
private fun errorCountText(): String? {
|
||||||
|
@ -126,6 +126,7 @@ const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED = 184
|
|||||||
const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185
|
const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185
|
||||||
const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186
|
const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186
|
||||||
const val ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST = 187
|
const val ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST = 187
|
||||||
|
const val ERROR_LIBRUS_MESSAGES_ATTACHMENT_NOT_FOUND = 188
|
||||||
|
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
||||||
@ -157,6 +158,7 @@ const val ERROR_LOGIN_VULCAN_NO_PUPILS = 331
|
|||||||
const val ERROR_VULCAN_API_MAINTENANCE = 340
|
const val ERROR_VULCAN_API_MAINTENANCE = 340
|
||||||
const val ERROR_VULCAN_API_BAD_REQUEST = 341
|
const val ERROR_VULCAN_API_BAD_REQUEST = 341
|
||||||
const val ERROR_VULCAN_API_OTHER = 342
|
const val ERROR_VULCAN_API_OTHER = 342
|
||||||
|
const val ERROR_VULCAN_ATTACHMENT_DOWNLOAD = 343
|
||||||
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
|
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
|
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
|
||||||
@ -206,5 +208,6 @@ const val EXCEPTION_IDZIENNIK_WEB_API_REQUEST = 913
|
|||||||
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
|
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
|
||||||
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
||||||
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
||||||
|
const val ERROR_ONEDRIVE_DOWNLOAD = 930
|
||||||
|
|
||||||
const val LOGIN_NO_ARGUMENTS = 1201
|
const val LOGIN_NO_ARGUMENTS = 1201
|
||||||
|
@ -13,8 +13,8 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
|
|
||||||
internal const val FEATURE_TIMETABLE = 1
|
internal const val FEATURE_TIMETABLE = 1
|
||||||
internal const val FEATURE_AGENDA = 2
|
internal const val FEATURE_AGENDA = 2
|
||||||
|
@ -84,6 +84,22 @@ object Regexes {
|
|||||||
"""<strong>(.+?) - (.*?)</strong>.+?<small>.+?\((.+?), .+?(.+?)\)""".toRegex(DOT_MATCHES_ALL)
|
"""<strong>(.+?) - (.*?)</strong>.+?<small>.+?\((.+?), .+?(.+?)\)""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ROW by lazy {
|
||||||
|
"""class="rowRolling">(.+?</div>\s*</td>)""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ITEM by lazy {
|
||||||
|
"""<p><b>(.+?):</b>\s*(.+?)\s*</p>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_BODY by lazy {
|
||||||
|
"""Treść:</b>(.+?)<p><b>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ID by lazy {
|
||||||
|
"""zadanieFormularz\(([0-9]+),""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ATTACHMENT by lazy {
|
||||||
|
"""zalacznik(_zadania)?=([0-9]+)'.+?word-break">(.+?)</td>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val IDZIENNIK_LOGIN_HIDDEN_FIELDS by lazy {
|
val IDZIENNIK_LOGIN_HIDDEN_FIELDS by lazy {
|
||||||
@ -155,6 +171,9 @@ object Regexes {
|
|||||||
val EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION by lazy {
|
val EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION by lazy {
|
||||||
"""<div class="desc">.*?<p>(.*?)</p>""".toRegex(DOT_MATCHES_ALL)
|
"""<div class="desc">.*?<p>(.*?)</p>""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
val EDUDZIENNIK_HOMEWORK_DESCRIPTION by lazy {
|
||||||
|
"""<div class="desc">(.*?)</div>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
val EDUDZIENNIK_SUBJECT_ID by lazy {
|
val EDUDZIENNIK_SUBJECT_ID by lazy {
|
||||||
"""/Courses/([\w-_]+?)/""".toRegex()
|
"""/Courses/([\w-_]+?)/""".toRegex()
|
||||||
|
@ -19,9 +19,9 @@ import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
|
||||||
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
||||||
@ -36,8 +36,9 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
||||||
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
||||||
fun announcementGet(profileId: Int, announcement: AnnouncementFull) = EdziennikTask(profileId, AnnouncementGetRequest(announcement))
|
fun announcementGet(profileId: Int, announcement: AnnouncementFull) = EdziennikTask(profileId, AnnouncementGetRequest(announcement))
|
||||||
fun attachmentGet(profileId: Int, message: Message, attachmentId: Long, attachmentName: String) = EdziennikTask(profileId, AttachmentGetRequest(message, attachmentId, attachmentName))
|
fun attachmentGet(profileId: Int, owner: Any, attachmentId: Long, attachmentName: String) = EdziennikTask(profileId, AttachmentGetRequest(owner, attachmentId, attachmentName))
|
||||||
fun recipientListGet(profileId: Int) = EdziennikTask(profileId, RecipientListGetRequest())
|
fun recipientListGet(profileId: Int) = EdziennikTask(profileId, RecipientListGetRequest())
|
||||||
|
fun eventGet(profileId: Int, event: EventFull) = EdziennikTask(profileId, EventGetRequest(event))
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var loginStore: LoginStore
|
private lateinit var loginStore: LoginStore
|
||||||
@ -92,8 +93,9 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
||||||
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
||||||
is AnnouncementGetRequest -> edziennikInterface?.getAnnouncement(request.announcement)
|
is AnnouncementGetRequest -> edziennikInterface?.getAnnouncement(request.announcement)
|
||||||
is AttachmentGetRequest -> edziennikInterface?.getAttachment(request.message, request.attachmentId, request.attachmentName)
|
is AttachmentGetRequest -> edziennikInterface?.getAttachment(request.owner, request.attachmentId, request.attachmentName)
|
||||||
is RecipientListGetRequest -> edziennikInterface?.getRecipientList()
|
is RecipientListGetRequest -> edziennikInterface?.getRecipientList()
|
||||||
|
is EventGetRequest -> edziennikInterface?.getEvent(request.event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +115,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
||||||
class AnnouncementsReadRequest
|
class AnnouncementsReadRequest
|
||||||
data class AnnouncementGetRequest(val announcement: AnnouncementFull)
|
data class AnnouncementGetRequest(val announcement: AnnouncementFull)
|
||||||
data class AttachmentGetRequest(val message: Message, val attachmentId: Long, val attachmentName: String)
|
data class AttachmentGetRequest(val owner: Any, val attachmentId: Long, val attachmentName: String)
|
||||||
class RecipientListGetRequest
|
class RecipientListGetRequest
|
||||||
|
data class EventGetRequest(val event: EventFull)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetHomework
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
||||||
@ -16,10 +17,10 @@ import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -94,13 +95,22 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {}
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
|
||||||
override fun getRecipientList() {}
|
override fun getRecipientList() {}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
EdudziennikLoginWeb(data) {
|
||||||
|
EdudziennikWebGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
|
override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -39,17 +39,16 @@ class EdudziennikWebEvents(override val data: DataEdudziennik,
|
|||||||
?: return@forEach
|
?: return@forEach
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
null,
|
time = null,
|
||||||
title,
|
topic = title,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_CLASS_EVENT,
|
type = Event.TYPE_CLASS_EVENT,
|
||||||
false,
|
teacherId = -1,
|
||||||
-1,
|
subjectId = -1,
|
||||||
-1,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -56,17 +56,16 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
val eventType = data.getEventType(eventTypeId, eventTypeName)
|
val eventType = data.getEventType(eventTypeId, eventTypeName)
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
eventType.id,
|
type = eventType.id,
|
||||||
false,
|
teacherId = -1,
|
||||||
-1,
|
subjectId = subject.id,
|
||||||
subject.id,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
||||||
|
|
||||||
|
import android.text.Html
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
|
|
||||||
|
class EdudziennikWebGetHomework(
|
||||||
|
override val data: DataEdudziennik,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : EdudziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "EdudziennikWebGetHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (event.attachmentNames.isNotNullNorEmpty()) {
|
||||||
|
val id = event.attachmentNames!![0]
|
||||||
|
|
||||||
|
webGet(TAG, "Homework/$id") { text ->
|
||||||
|
val description = Regexes.EDUDZIENNIK_HOMEWORK_DESCRIPTION.find(text)?.get(1)?.trim()
|
||||||
|
|
||||||
|
if (description != null) event.topic = Html.fromHtml(description).toString()
|
||||||
|
|
||||||
|
event.homeworkBody = ""
|
||||||
|
event.attachmentNames = null
|
||||||
|
|
||||||
|
data.eventList += event
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,8 +33,8 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
|
if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
|
||||||
doc.getElementsByTag("tr").forEach { homeworkElement ->
|
doc.getElementsByTag("tr").forEach { homeworkElement ->
|
||||||
val dateElement = homeworkElement.getElementsByClass("date").first().child(0)
|
val dateElement = homeworkElement.getElementsByClass("date").first().child(0)
|
||||||
val id = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1)?.crc32()
|
val idStr = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1) ?: return@forEach
|
||||||
?: return@forEach
|
val id = idStr.crc32()
|
||||||
val date = Date.fromY_m_d(dateElement.text())
|
val date = Date.fromY_m_d(dateElement.text())
|
||||||
|
|
||||||
val subjectElement = homeworkElement.child(1).child(0)
|
val subjectElement = homeworkElement.child(1).child(0)
|
||||||
@ -49,22 +49,23 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
val teacherName = homeworkElement.child(2).text()
|
val teacherName = homeworkElement.child(2).text()
|
||||||
val teacher = data.getTeacherByFirstLast(teacherName)
|
val teacher = data.getTeacherByFirstLast(teacherName)
|
||||||
|
|
||||||
val topic = homeworkElement.child(4).text()
|
val topic = homeworkElement.child(4).text()?.trim()
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic ?: "",
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacher.id,
|
||||||
teacher.id,
|
subjectId = subject.id,
|
||||||
subject.id,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
eventObject.attachmentNames = mutableListOf(idStr)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.helper
|
||||||
|
|
||||||
|
import im.wangchao.mhttp.Request
|
||||||
|
import im.wangchao.mhttp.Response
|
||||||
|
import im.wangchao.mhttp.callback.FileCallbackHandler
|
||||||
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_ONEDRIVE_DOWNLOAD
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.SYSTEM_USER_AGENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class OneDriveDownloadAttachment(
|
||||||
|
app: App,
|
||||||
|
fileUrl: String,
|
||||||
|
val onSuccess: (file: File) -> Unit,
|
||||||
|
val onProgress: (written: Long, total: Long) -> Unit,
|
||||||
|
val onError: (apiError: ApiError) -> Unit
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "OneDriveDownloadAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
Request.builder()
|
||||||
|
.url(fileUrl)
|
||||||
|
.userAgent(SYSTEM_USER_AGENT)
|
||||||
|
.withClient(app.httpLazy)
|
||||||
|
.callback(object : TextCallbackHandler() {
|
||||||
|
override fun onSuccess(text: String, response: Response) {
|
||||||
|
val location = response.headers().get("Location")
|
||||||
|
// https://onedrive.live.com/redir?resid=D75496A2EB87531C!706&authkey=!ABjZeh3pHMqj11Q
|
||||||
|
if (location?.contains("onedrive.live.com/redir?resid=") != true) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withApiResponse(text)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val url = location
|
||||||
|
.replace("onedrive.live.com/redir?resid=", "storage.live.com/items/")
|
||||||
|
.replace("?", "&")
|
||||||
|
.replaceFirst("&", "?")
|
||||||
|
downloadFile(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response, throwable: Throwable) {
|
||||||
|
onError(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadFile(url: String) {
|
||||||
|
val targetFile = Utils.getStorageDir()
|
||||||
|
|
||||||
|
val callback = object : FileCallbackHandler(targetFile) {
|
||||||
|
override fun onSuccess(file: File?, response: Response?) {
|
||||||
|
if (file == null) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
onSuccess(file)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgress(bytesWritten: Long, bytesTotal: Long) {
|
||||||
|
try {
|
||||||
|
this@OneDriveDownloadAttachment.onProgress(bytesWritten, bytesTotal)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||||
|
onError(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.builder()
|
||||||
|
.url(url)
|
||||||
|
.userAgent(SYSTEM_USER_AGENT)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
}
|
@ -8,20 +8,15 @@ import com.google.gson.JsonObject
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetAttachment
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetRecipientList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSendMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin.IdziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin.IdziennikFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -103,10 +98,17 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
override fun markAllAnnouncementsAsRead() {}
|
override fun markAllAnnouncementsAsRead() {}
|
||||||
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
||||||
IdziennikWebGetAttachment(data, message, attachmentId, attachmentName) {
|
if (owner is Message) {
|
||||||
completed()
|
IdziennikWebGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (owner is Event) {
|
||||||
|
IdziennikWebGetHomeworkAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,10 +121,19 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
||||||
|
IdziennikWebGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { IdziennikFirstLogin(data) { completed() } }
|
override fun firstLogin() { IdziennikFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -229,6 +229,7 @@ open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?)
|
|||||||
.apply {
|
.apply {
|
||||||
parameters.forEach { (k, v) -> addParameter(k, v) }
|
parameters.forEach { (k, v) -> addParameter(k, v) }
|
||||||
}
|
}
|
||||||
|
.contentType("application/x-www-form-urlencoded")
|
||||||
.post()
|
.post()
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
|
@ -11,8 +11,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.getBoolean
|
import pl.szczodrzynski.edziennik.getBoolean
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||||
@ -33,11 +33,11 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
json.asJsonObjectList()?.forEach { jMessage ->
|
json.asJsonObjectList().forEach { jMessage ->
|
||||||
val subject = jMessage.getString("tytul")
|
val subject = jMessage.getString("tytul") ?: ""
|
||||||
if (subject?.contains("(") == true && subject.startsWith("iDziennik - "))
|
if (subject.contains("(") && subject.startsWith("iDziennik - "))
|
||||||
return@forEach
|
return@forEach
|
||||||
if (subject?.startsWith("Uwaga dla ucznia (klasa:") == true)
|
if (subject.startsWith("Uwaga dla ucznia (klasa:"))
|
||||||
return@forEach
|
return@forEach
|
||||||
|
|
||||||
val messageIdStr = jMessage.getString("id")
|
val messageIdStr = jMessage.getString("id")
|
||||||
@ -64,13 +64,12 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
messageId,
|
id = messageId,
|
||||||
subject,
|
type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
||||||
body,
|
subject = subject,
|
||||||
if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
body = body,
|
||||||
rTeacher.id,
|
senderId = rTeacher.id
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val messageRecipient = MessageRecipient(
|
val messageRecipient = MessageRecipient(
|
||||||
@ -81,7 +80,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
/*messageId*/ messageId
|
/*messageId*/ messageId
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.messageRecipientList.add(messageRecipient)
|
data.messageRecipientList.add(messageRecipient)
|
||||||
data.setSeenMetadataList.add(Metadata(
|
data.setSeenMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||||
@ -46,13 +46,12 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
messageId,
|
id = messageId,
|
||||||
subject,
|
type = TYPE_SENT,
|
||||||
body,
|
subject = subject,
|
||||||
TYPE_SENT,
|
body = body,
|
||||||
-1,
|
senderId = null
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
||||||
@ -76,7 +75,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
data.messageRecipientIgnoreList.add(messageRecipient)
|
data.messageRecipientIgnoreList.add(messageRecipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
||||||
val teacherName = exam.getString("wpisal") ?: return@forEach
|
val teacherName = exam.getString("wpisal") ?: return@forEach
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
||||||
val topic = exam.getString("zakres") ?: ""
|
val topic = exam.getString("zakres")?.trim() ?: ""
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate)
|
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
@ -80,17 +80,16 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
examDate,
|
date = examDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
eventType,
|
type = eventType,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.utils.Utils
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
||||||
val message: Message,
|
val owner: Any,
|
||||||
val attachmentId: Long,
|
val attachmentId: Long,
|
||||||
val attachmentName: String,
|
val attachmentName: String,
|
||||||
val onSuccess: () -> Unit
|
val onSuccess: () -> Unit
|
||||||
@ -25,6 +25,8 @@ class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
val message = owner as Message
|
||||||
|
|
||||||
val messageId = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex().find(message.body ?: "")?.get(2) ?: -1
|
val messageId = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex().find(message.body ?: "")?.get(2) ?: -1
|
||||||
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
||||||
|
|
||||||
@ -34,29 +36,29 @@ class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
|||||||
), { file ->
|
), { file ->
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_FINISHED,
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
file.absolutePath
|
file.absolutePath
|
||||||
)
|
)
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.messageId}_${event.attachmentId}")
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
|
||||||
}) { written, _ ->
|
}) { written, _ ->
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_PROGRESS,
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
bytesWritten = written
|
bytesWritten = written
|
||||||
)
|
)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.getBoolean
|
||||||
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
|
||||||
|
class IdziennikWebGetHomework(override val data: DataIdziennik,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "IdziennikWebGetHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
webApiGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK, mapOf(
|
||||||
|
"idP" to data.registerId,
|
||||||
|
"idPD" to event.id
|
||||||
|
)) { result ->
|
||||||
|
val json = result.getJsonObject("d") ?: run {
|
||||||
|
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
||||||
|
.withApiResponse(result))
|
||||||
|
return@webApiGet
|
||||||
|
}
|
||||||
|
|
||||||
|
val homework = json.getJsonObject("praca") ?: return@webApiGet
|
||||||
|
|
||||||
|
if (homework.getBoolean("zalacznik", false)) {
|
||||||
|
event.attachmentIds = mutableListOf(event.id)
|
||||||
|
event.attachmentNames = mutableListOf("Załącznik do zadania")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.attachmentIds = mutableListOf()
|
||||||
|
event.attachmentNames = mutableListOf()
|
||||||
|
}
|
||||||
|
event.homeworkBody = homework.getString("tresc")
|
||||||
|
|
||||||
|
data.eventList.add(event)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.set
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class IdziennikWebGetHomeworkAttachment(override val data: DataIdziennik,
|
||||||
|
val owner: Any,
|
||||||
|
val attachmentId: Long,
|
||||||
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "IdziennikWebGetHomeworkAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val homework = owner as Event
|
||||||
|
|
||||||
|
/*val request = Request.Builder()
|
||||||
|
.url("")
|
||||||
|
.build()
|
||||||
|
data.app.http.newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
val filename = response.header("content-disposition")?.substringAfter("\"")?.substringBeforeLast("\"")
|
||||||
|
|
||||||
|
val file: File = File(Utils.getStorageDir(), filename)
|
||||||
|
val sink = file.sink().buffer()
|
||||||
|
response.body()?.source()?.let {
|
||||||
|
sink.writeAll(it)
|
||||||
|
}
|
||||||
|
sink.close()
|
||||||
|
}
|
||||||
|
})*/
|
||||||
|
|
||||||
|
webGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT) { text ->
|
||||||
|
val hiddenFields = JsonObject()
|
||||||
|
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
||||||
|
hiddenFields[it[1]] = it[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
webGetFile(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT, Utils.getStorageDir(), mapOf(
|
||||||
|
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
||||||
|
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
||||||
|
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
||||||
|
"__EVENTTARGET" to "ctl00\$cphContent\$bt_pobraniePliku",
|
||||||
|
"ctl00\$dxComboUczniowie" to data.registerId,
|
||||||
|
"ctl00\$cphContent\$idPracyDomowej" to attachmentId
|
||||||
|
), { file ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
|
file.absolutePath
|
||||||
|
)
|
||||||
|
|
||||||
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
|
homework.attachmentNames = mutableListOf(file.name)
|
||||||
|
data.eventList.add(homework)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
onSuccess()
|
||||||
|
|
||||||
|
}) { written, _ ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
|
bytesWritten = written
|
||||||
|
)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,8 @@ import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_MESSAGE
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||||
@ -50,7 +50,11 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
|||||||
message.recipients?.clear()
|
message.recipients?.clear()
|
||||||
when (message.type) {
|
when (message.type) {
|
||||||
TYPE_RECEIVED -> {
|
TYPE_RECEIVED -> {
|
||||||
val recipientObject = MessageRecipientFull(profileId, -1, message.id)
|
val recipientObject = MessageRecipientFull(
|
||||||
|
profileId = profileId,
|
||||||
|
id = -1,
|
||||||
|
messageId = message.id
|
||||||
|
)
|
||||||
|
|
||||||
val readDateString = it.getString("DataOdczytania")
|
val readDateString = it.getString("DataOdczytania")
|
||||||
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
||||||
@ -67,7 +71,11 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
|||||||
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
||||||
val teacher = data.getTeacherByLastFirst(recipientName)
|
val teacher = data.getTeacherByLastFirst(recipientName)
|
||||||
|
|
||||||
val recipientObject = MessageRecipientFull(profileId, teacher.id, message.id)
|
val recipientObject = MessageRecipientFull(
|
||||||
|
profileId = profileId,
|
||||||
|
id = teacher.id,
|
||||||
|
messageId = message.id
|
||||||
|
)
|
||||||
|
|
||||||
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
||||||
recipientObject.fullName = teacher.fullName
|
recipientObject.fullName = teacher.fullName
|
||||||
@ -91,9 +99,10 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageList.add(message)
|
||||||
|
data.messageListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,13 +52,14 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { homework ->
|
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { homework ->
|
||||||
val id = homework.getLong("_recordId") ?: return@forEach
|
val id = homework.getLong("_recordId") ?: return@forEach
|
||||||
val eventDate = Date.fromY_m_d(homework.getString("dataO") ?: return@forEach)
|
val eventDate = Date.fromY_m_d(homework.getString("dataO") ?: return@forEach)
|
||||||
|
val addedDate = Date.fromY_m_d(homework.getString("dataZ") ?: return@forEach)
|
||||||
val subjectName = homework.getString("przed") ?: return@forEach
|
val subjectName = homework.getString("przed") ?: return@forEach
|
||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
||||||
val teacherName = homework.getString("usr") ?: return@forEach
|
val teacherName = homework.getString("usr") ?: return@forEach
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
|
||||||
val topic = homework.getString("tytul") ?: ""
|
val topic = homework.getString("tytul")?.trim() ?: ""
|
||||||
|
|
||||||
val seen = when (profile?.empty) {
|
val seen = when (profile?.empty) {
|
||||||
true -> true
|
true -> true
|
||||||
@ -67,17 +68,16 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
|
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
@ -87,7 +87,7 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
eventObject.id,
|
eventObject.id,
|
||||||
seen,
|
seen,
|
||||||
seen,
|
seen,
|
||||||
System.currentTimeMillis()
|
addedDate.inMillis
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
@ -20,7 +21,6 @@ import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
import pl.szczodrzynski.edziennik.getJsonArray
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue
|
|
||||||
|
|
||||||
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
||||||
override val lastSync: Long?,
|
override val lastSync: Long?,
|
||||||
@ -39,36 +39,64 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
.withApiResponse(result))
|
.withApiResponse(result))
|
||||||
return@webApiGet
|
return@webApiGet
|
||||||
}
|
}
|
||||||
|
val manager = data.app.gradesManager
|
||||||
|
|
||||||
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { subject ->
|
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { subject ->
|
||||||
val subjectName = subject.getString("Przedmiot") ?: return@forEach
|
val subjectName = subject.getString("Przedmiot") ?: return@forEach
|
||||||
val subjectObject = data.getSubject(subjectName, null, subjectName)
|
val subjectObject = data.getSubject(subjectName, null, subjectName)
|
||||||
|
|
||||||
val semester1Proposed = subject.getString("OcenaSem1") ?: ""
|
val semester1Proposed = subject.getString("OcenaSem1") ?: ""
|
||||||
val semester1Value = getWordGradeValue(semester1Proposed)
|
val semester1Value = manager.getGradeValue(semester1Proposed)
|
||||||
val semester1Id = subjectObject.id * (-100) - 1
|
val semester1Id = subjectObject.id * (-100) - 1
|
||||||
|
val semester1Type =
|
||||||
|
if (semester1Value == 0f) TYPE_DESCRIPTIVE
|
||||||
|
else TYPE_SEMESTER1_PROPOSED
|
||||||
|
val semester1Name = when {
|
||||||
|
semester1Value == 0f -> " "
|
||||||
|
semester1Value % 1.0f == 0f -> semester1Value.toInt().toString()
|
||||||
|
else -> semester1Value.toString()
|
||||||
|
}
|
||||||
|
val semester1Color =
|
||||||
|
if (semester1Value == 0f) 0xff536dfe.toInt()
|
||||||
|
else -1
|
||||||
|
|
||||||
val semester2Proposed = subject.getString("OcenaSem2") ?: ""
|
val semester2Proposed = subject.getString("OcenaSem2") ?: ""
|
||||||
val semester2Value = getWordGradeValue(semester2Proposed)
|
val semester2Value = manager.getGradeValue(semester2Proposed)
|
||||||
val semester2Id = subjectObject.id * (-100) - 2
|
val semester2Id = subjectObject.id * (-100) - 2
|
||||||
|
val semester2Type =
|
||||||
|
if (semester2Value == 0f) TYPE_DESCRIPTIVE
|
||||||
|
else TYPE_YEAR_PROPOSED
|
||||||
|
val semester2Name = when {
|
||||||
|
semester2Value == 0f -> " "
|
||||||
|
semester2Value % 1.0f == 0f -> semester2Value.toInt().toString()
|
||||||
|
else -> semester2Value.toString()
|
||||||
|
}
|
||||||
|
val semester2Color =
|
||||||
|
if (semester2Value == 0f) 0xffff4081.toInt()
|
||||||
|
else -1
|
||||||
|
|
||||||
if (semester1Proposed != "") {
|
if (semester1Proposed != "") {
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId = profileId,
|
profileId = profileId,
|
||||||
id = semester1Id,
|
id = semester1Id,
|
||||||
name = semester1Value.toString(),
|
name = semester1Name,
|
||||||
type = TYPE_SEMESTER1_PROPOSED,
|
type = semester1Type,
|
||||||
value = semester1Value.toFloat(),
|
value = semester1Value,
|
||||||
weight = 0f,
|
weight = 0f,
|
||||||
color = -1,
|
color = semester1Color,
|
||||||
category = null,
|
category = if (semester1Value == 0f) "Ocena opisowa semestralna" else null,
|
||||||
description = null,
|
description = if (semester1Value == 0f) semester1Proposed else null,
|
||||||
comment = null,
|
comment = null,
|
||||||
semester = 1,
|
semester = 1,
|
||||||
teacherId = -1,
|
teacherId = -1,
|
||||||
subjectId = subjectObject.id
|
subjectId = subjectObject.id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val addedDate = if (data.profile.empty)
|
||||||
|
data.profile.dateSemester1Start.inMillis
|
||||||
|
else
|
||||||
|
System.currentTimeMillis()
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
@ -76,7 +104,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
gradeObject.id,
|
gradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
System.currentTimeMillis()
|
addedDate
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,13 +112,13 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId = profileId,
|
profileId = profileId,
|
||||||
id = semester2Id,
|
id = semester2Id,
|
||||||
name = semester2Value.toString(),
|
name = semester2Name,
|
||||||
type = TYPE_YEAR_PROPOSED,
|
type = semester2Type,
|
||||||
value = semester2Value.toFloat(),
|
value = semester2Value,
|
||||||
weight = 0f,
|
weight = 0f,
|
||||||
color = -1,
|
color = semester2Color,
|
||||||
category = null,
|
category = if (semester2Value == 0f) "Ocena opisowa końcoworoczna" else null,
|
||||||
description = null,
|
description = if (semester2Value == 0f) semester2Proposed else null,
|
||||||
comment = null,
|
comment = null,
|
||||||
semester = 2,
|
semester = 2,
|
||||||
teacherId = -1,
|
teacherId = -1,
|
||||||
@ -98,7 +126,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
)
|
)
|
||||||
|
|
||||||
val addedDate = if (data.profile.empty)
|
val addedDate = if (data.profile.empty)
|
||||||
data.profile.dateSemester1Start.inMillis
|
data.profile.dateSemester2Start.inMillis
|
||||||
else
|
else
|
||||||
System.currentTimeMillis()
|
System.currentTimeMillis()
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class IdziennikWebSendMessage(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IdziennikApiMessagesSent(data, null) {
|
IdziennikApiMessagesSent(data, null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.Librus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetMessage
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetMessage
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetRecipientList
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetRecipientList
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesSendMessage
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesSendMessage
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaGetHomework
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaHomeworkGetAttachment
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaMarkAllAnnouncementsAsRead
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaMarkAllAnnouncementsAsRead
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
||||||
@ -24,6 +26,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -118,11 +121,23 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
login(LOGIN_METHOD_LIBRUS_MESSAGES) {
|
when (owner) {
|
||||||
LibrusMessagesGetAttachment(data, message, attachmentId, attachmentName) {
|
is Message -> {
|
||||||
completed()
|
login(LOGIN_METHOD_LIBRUS_MESSAGES) {
|
||||||
|
LibrusMessagesGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
is EventFull -> {
|
||||||
|
login(LOGIN_METHOD_LIBRUS_SYNERGIA) {
|
||||||
|
LibrusSynergiaHomeworkGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,10 +149,19 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_LIBRUS_SYNERGIA) {
|
||||||
|
LibrusSynergiaGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { LibrusFirstLogin(data) { completed() } }
|
override fun firstLogin() { LibrusFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -252,10 +252,11 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
|
|||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sandboxGetFile(tag: String, action: String, targetFile: File, onSuccess: (file: File) -> Unit,
|
fun sandboxGetFile(tag: String, url: String, targetFile: File, onSuccess: (file: File) -> Unit,
|
||||||
|
method: Int = GET,
|
||||||
onProgress: (written: Long, total: Long) -> Unit) {
|
onProgress: (written: Long, total: Long) -> Unit) {
|
||||||
|
|
||||||
d(tag, "Request: Librus/Messages - $LIBRUS_SANDBOX_URL$action")
|
d(tag, "Request: Librus/Messages - $url")
|
||||||
|
|
||||||
val callback = object : FileCallbackHandler(targetFile) {
|
val callback = object : FileCallbackHandler(targetFile) {
|
||||||
override fun onSuccess(file: File?, response: Response?) {
|
override fun onSuccess(file: File?, response: Response?) {
|
||||||
@ -291,9 +292,14 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Request.builder()
|
Request.builder()
|
||||||
.url("$LIBRUS_SANDBOX_URL$action")
|
.url(url)
|
||||||
.userAgent(SYNERGIA_USER_AGENT)
|
.userAgent(SYNERGIA_USER_AGENT)
|
||||||
.post()
|
.also {
|
||||||
|
when (method) {
|
||||||
|
POST -> it.post()
|
||||||
|
else -> it.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
|
@ -35,7 +35,7 @@ open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!text.contains("jesteś zalogowany")) {
|
if (!text.contains("jesteś zalogowany") && !text.contains("Podgląd zadania")) {
|
||||||
when {
|
when {
|
||||||
text.contains("stop.png") -> ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED
|
text.contains("stop.png") -> ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED
|
||||||
text.contains("Przerwa techniczna") -> ERROR_LIBRUS_SYNERGIA_MAINTENANCE
|
text.contains("Przerwa techniczna") -> ERROR_LIBRUS_SYNERGIA_MAINTENANCE
|
||||||
@ -48,7 +48,6 @@ open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
onSuccess(text)
|
onSuccess(text)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -90,4 +89,42 @@ open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
|
|||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun redirectUrlGet(tag: String, url: String, onSuccess: (url: String) -> Unit) {
|
||||||
|
val callback = object : TextCallbackHandler() {
|
||||||
|
override fun onSuccess(text: String?, response: Response) {
|
||||||
|
val redirectUrl = response.headers().get("Location")
|
||||||
|
|
||||||
|
if (redirectUrl != null) {
|
||||||
|
try {
|
||||||
|
onSuccess(redirectUrl)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
data.error(ApiError(tag, EXCEPTION_LIBRUS_SYNERGIA_REQUEST)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(e)
|
||||||
|
.withApiResponse(text))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.error(ApiError(tag, ERROR_LIBRUS_SYNERGIA_OTHER)
|
||||||
|
.withResponse(response)
|
||||||
|
.withApiResponse(text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||||
|
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.builder()
|
||||||
|
.url(url)
|
||||||
|
.userAgent(LIBRUS_USER_AGENT)
|
||||||
|
.withClient(data.app.httpLazy)
|
||||||
|
.get()
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class LibrusApiEvents(override val data: DataLibrus,
|
|||||||
events?.forEach { event ->
|
events?.forEach { event ->
|
||||||
val id = event.getLong("Id") ?: return@forEach
|
val id = event.getLong("Id") ?: return@forEach
|
||||||
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
||||||
val topic = event.getString("Content") ?: ""
|
val topic = event.getString("Content")?.trim() ?: ""
|
||||||
val type = event.getJsonObject("Category")?.getLong("Id") ?: -1
|
val type = event.getJsonObject("Category")?.getLong("Id") ?: -1
|
||||||
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
||||||
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
||||||
@ -47,17 +47,16 @@ class LibrusApiEvents(override val data: DataLibrus,
|
|||||||
val addedDate = Date.fromIso(event.getString("AddDate"))
|
val addedDate = Date.fromIso(event.getString("AddDate"))
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
type,
|
type = type,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = teamId
|
||||||
teamId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -34,17 +34,16 @@ class LibrusApiHomework(override val data: DataLibrus,
|
|||||||
val addedDate = Date.fromY_m_d(homework.getString("Date"))
|
val addedDate = Date.fromY_m_d(homework.getString("Date"))
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
null,
|
time = null,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
-1,
|
type = -1,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = -1,
|
||||||
-1,
|
teamId = -1
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -39,17 +39,16 @@ class LibrusApiPtMeetings(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_PT_MEETING,
|
type = Event.TYPE_PT_MEETING,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = -1,
|
||||||
-1,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -59,7 +59,7 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
|
|||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_TEACHER_ABSENCE,
|
Metadata.TYPE_TEACHER_ABSENCE,
|
||||||
id,
|
id,
|
||||||
profile?.empty ?: false,
|
true,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false,
|
||||||
System.currentTimeMillis()
|
System.currentTimeMillis()
|
||||||
))
|
))
|
||||||
|
@ -4,22 +4,12 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages
|
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import org.greenrobot.eventbus.EventBus
|
import kotlinx.coroutines.Dispatchers
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_FILE_DOWNLOAD
|
import kotlinx.coroutines.Job
|
||||||
import pl.szczodrzynski.edziennik.data.api.EXCEPTION_LIBRUS_MESSAGES_REQUEST
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_FINISHED
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_PROGRESS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import java.io.File
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class LibrusMessagesGetAttachment(override val data: DataLibrus,
|
class LibrusMessagesGetAttachment(override val data: DataLibrus,
|
||||||
@ -37,8 +27,6 @@ class LibrusMessagesGetAttachment(override val data: DataLibrus,
|
|||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = job + Dispatchers.Default
|
get() = job + Dispatchers.Default
|
||||||
|
|
||||||
private var getAttachmentCheckKeyTries = 0
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
messagesGet(TAG, "GetFileDownloadLink", parameters = mapOf(
|
messagesGet(TAG, "GetFileDownloadLink", parameters = mapOf(
|
||||||
"fileId" to attachmentId,
|
"fileId" to attachmentId,
|
||||||
@ -46,81 +34,8 @@ class LibrusMessagesGetAttachment(override val data: DataLibrus,
|
|||||||
"archive" to 0
|
"archive" to 0
|
||||||
)) { doc ->
|
)) { doc ->
|
||||||
val downloadLink = doc.select("response GetFileDownloadLink downloadLink").text()
|
val downloadLink = doc.select("response GetFileDownloadLink downloadLink").text()
|
||||||
val keyMatcher = Regexes.LIBRUS_ATTACHMENT_KEY.find(downloadLink)
|
|
||||||
|
|
||||||
if (keyMatcher != null) {
|
LibrusSandboxDownloadAttachment(data, downloadLink, message, attachmentId, attachmentName, onSuccess)
|
||||||
getAttachmentCheckKeyTries = 0
|
|
||||||
|
|
||||||
val attachmentKey = keyMatcher[1]
|
|
||||||
getAttachmentCheckKey(attachmentKey) {
|
|
||||||
downloadAttachment(attachmentKey)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data.error(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
|
||||||
.withApiResponse(doc.toString()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAttachmentCheckKey(attachmentKey: String, callback: () -> Unit) {
|
|
||||||
sandboxGet(TAG, "CSCheckKey",
|
|
||||||
parameters = mapOf("singleUseKey" to attachmentKey)) { json ->
|
|
||||||
|
|
||||||
when (json.getString("status")) {
|
|
||||||
"not_downloaded_yet" -> {
|
|
||||||
if (getAttachmentCheckKeyTries++ > 5) {
|
|
||||||
data.error(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
|
||||||
.withApiResponse(json))
|
|
||||||
return@sandboxGet
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
delay(2000)
|
|
||||||
getAttachmentCheckKey(attachmentKey, callback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"ready" -> {
|
|
||||||
launch { callback() }
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
data.error(ApiError(TAG, EXCEPTION_LIBRUS_MESSAGES_REQUEST)
|
|
||||||
.withApiResponse(json))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun downloadAttachment(attachmentKey: String) {
|
|
||||||
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
|
||||||
|
|
||||||
sandboxGetFile(TAG, "CSDownload&singleUseKey=$attachmentKey", targetFile, { file ->
|
|
||||||
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
message.id,
|
|
||||||
attachmentId,
|
|
||||||
TYPE_FINISHED,
|
|
||||||
file.absolutePath
|
|
||||||
)
|
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.messageId}_${event.attachmentId}")
|
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
|
|
||||||
}) { written, _ ->
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
message.id,
|
|
||||||
attachmentId,
|
|
||||||
TYPE_PROGRESS,
|
|
||||||
bytesWritten = written
|
|
||||||
)
|
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESS
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESSAGES_SENT
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESSAGES_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.fixName
|
import pl.szczodrzynski.edziennik.fixName
|
||||||
import pl.szczodrzynski.edziennik.singleOrNull
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
@ -78,7 +78,7 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
|||||||
|
|
||||||
val senderId = when (type) {
|
val senderId = when (type) {
|
||||||
TYPE_RECEIVED -> recipientId
|
TYPE_RECEIVED -> recipientId
|
||||||
else -> -1
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiverId = when (type) {
|
val receiverId = when (type) {
|
||||||
@ -92,13 +92,12 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val messageObject = Message(
|
val messageObject = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = type,
|
||||||
null,
|
subject = subject,
|
||||||
type,
|
body = null,
|
||||||
senderId,
|
senderId = senderId
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
val messageRecipientObject = MessageRecipient(
|
||||||
@ -109,7 +108,12 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
|||||||
id
|
id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(messageObject)
|
element.select("isAnyFileAttached")?.text()?.let {
|
||||||
|
if (it == "1")
|
||||||
|
messageObject.hasAttachments = true
|
||||||
|
}
|
||||||
|
|
||||||
|
data.messageList.add(messageObject)
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
data.setSeenMetadataList.add(Metadata(
|
data.setSeenMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -9,8 +9,8 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
@ -102,11 +102,10 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipientFull(
|
val messageRecipientObject = MessageRecipientFull(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
-1,
|
id = -1,
|
||||||
-1,
|
messageId = messageObject.id,
|
||||||
readDate,
|
readDate = readDate
|
||||||
messageObject.id
|
|
||||||
)
|
)
|
||||||
|
|
||||||
messageRecipientObject.fullName = profile.accountName ?: profile.studentNameLong ?: ""
|
messageRecipientObject.fullName = profile.accountName ?: profile.studentNameLong ?: ""
|
||||||
@ -132,11 +131,10 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipientFull(
|
val messageRecipientObject = MessageRecipientFull(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
receiverId,
|
id = receiverId,
|
||||||
-1,
|
messageId = messageObject.id,
|
||||||
readDate,
|
readDate = readDate
|
||||||
messageObject.id
|
|
||||||
)
|
)
|
||||||
|
|
||||||
messageRecipientObject.fullName = "$receiverFirstName $receiverLastName"
|
messageRecipientObject.fullName = "$receiverFirstName $receiverLastName"
|
||||||
@ -159,7 +157,9 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
|||||||
|
|
||||||
messageObject.recipients = messageRecipientList
|
messageObject.recipients = messageRecipientList
|
||||||
data.messageRecipientList.addAll(messageRecipientList)
|
data.messageRecipientList.addAll(messageRecipientList)
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
data.messageList.add(messageObject)
|
||||||
|
data.messageListReplace = true
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
|
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
@ -48,7 +48,7 @@ class LibrusMessagesSendMessage(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) {
|
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||||
|
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class LibrusSandboxDownloadAttachment(override val data: DataLibrus,
|
||||||
|
downloadLink: String,
|
||||||
|
val owner: Any,
|
||||||
|
val attachmentId: Long,
|
||||||
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : LibrusMessages(data, null), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "LibrusSandboxDownloadAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var job = Job()
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Default
|
||||||
|
|
||||||
|
private var getAttachmentCheckKeyTries = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
val keyMatcher = Regexes.LIBRUS_ATTACHMENT_KEY.find(downloadLink)
|
||||||
|
|
||||||
|
when {
|
||||||
|
downloadLink.contains("CSDownloadFailed") -> {
|
||||||
|
data.error(ApiError(TAG, ERROR_LIBRUS_MESSAGES_ATTACHMENT_NOT_FOUND))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
keyMatcher != null -> {
|
||||||
|
getAttachmentCheckKeyTries = 0
|
||||||
|
|
||||||
|
val attachmentKey = keyMatcher[1]
|
||||||
|
getAttachmentCheckKey(attachmentKey) {
|
||||||
|
downloadAttachment("${LIBRUS_SANDBOX_URL}CSDownload&singleUseKey=$attachmentKey", method = POST)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
downloadAttachment("$downloadLink/get", method = GET)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAttachmentCheckKey(attachmentKey: String, callback: () -> Unit) {
|
||||||
|
sandboxGet(TAG, "CSCheckKey",
|
||||||
|
parameters = mapOf("singleUseKey" to attachmentKey)) { json ->
|
||||||
|
|
||||||
|
when (json.getString("status")) {
|
||||||
|
"not_downloaded_yet" -> {
|
||||||
|
if (getAttachmentCheckKeyTries++ > 5) {
|
||||||
|
data.error(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
||||||
|
.withApiResponse(json))
|
||||||
|
return@sandboxGet
|
||||||
|
}
|
||||||
|
launch {
|
||||||
|
delay(2000)
|
||||||
|
getAttachmentCheckKey(attachmentKey, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"ready" -> {
|
||||||
|
launch { callback() }
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
data.error(ApiError(TAG, EXCEPTION_LIBRUS_MESSAGES_REQUEST)
|
||||||
|
.withApiResponse(json))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadAttachment(url: String, method: Int = GET) {
|
||||||
|
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
||||||
|
|
||||||
|
sandboxGetFile(TAG, url, targetFile, { file ->
|
||||||
|
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
|
file.absolutePath
|
||||||
|
)
|
||||||
|
|
||||||
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
|
||||||
|
onSuccess()
|
||||||
|
|
||||||
|
}) { written, _ ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
|
bytesWritten = written
|
||||||
|
)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia
|
||||||
|
|
||||||
|
import android.text.Html
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
|
||||||
|
class LibrusSynergiaGetHomework(override val data: DataLibrus,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : LibrusSynergia(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "LibrusSynergiaGetHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
synergiaGet(TAG, "moje_zadania/podglad/${event.id}") { text ->
|
||||||
|
val doc = Jsoup.parse(text)
|
||||||
|
|
||||||
|
val table = doc.select("table.decorated tbody > tr")
|
||||||
|
|
||||||
|
event.topic = table[1].select("td")[1].text()
|
||||||
|
event.homeworkBody = Html.fromHtml(table[5].select("td")[1].html()).toString()
|
||||||
|
|
||||||
|
event.attachmentIds = mutableListOf()
|
||||||
|
event.attachmentNames = mutableListOf()
|
||||||
|
|
||||||
|
if (table.size > 6) {
|
||||||
|
table[6].select("a").forEach { a ->
|
||||||
|
val attachmentId = a.attr("href").split('/')
|
||||||
|
.last().toLongOrNull() ?: return@forEach
|
||||||
|
val filename = a.text()
|
||||||
|
event.attachmentIds?.add(attachmentId)
|
||||||
|
event.attachmentNames?.add(filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.eventList.add(event)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -42,8 +42,6 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
|
|||||||
doc.select("table.myHomeworkTable > tbody").firstOrNull()?.also { homeworkTable ->
|
doc.select("table.myHomeworkTable > tbody").firstOrNull()?.also { homeworkTable ->
|
||||||
val homeworkElements = homeworkTable.children()
|
val homeworkElements = homeworkTable.children()
|
||||||
|
|
||||||
val graphElements = doc.select("table[border].center td[align=left] tbody").first().children()
|
|
||||||
|
|
||||||
homeworkElements.forEachIndexed { i, el ->
|
homeworkElements.forEachIndexed { i, el ->
|
||||||
val elements = el.children()
|
val elements = el.children()
|
||||||
|
|
||||||
@ -63,43 +61,22 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
|
|||||||
val lessons = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
val lessons = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
||||||
val startTime = lessons.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessons.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
|
|
||||||
/*val moreInfo = graphElements[2 * i + 1].select("td[title]")
|
|
||||||
.attr("title").trim()*/
|
|
||||||
|
|
||||||
var description = ""
|
|
||||||
|
|
||||||
graphElements.forEach { graphEl ->
|
|
||||||
graphEl.select("td[title]")?.also {
|
|
||||||
val title = it.attr("title")
|
|
||||||
val r = "Temat: (.*?)<br.?/>Data udostępnienia: (.*?)<br.?/>Termin wykonania: (.*?)<br.?/>Treść: (.*)"
|
|
||||||
.toRegex(RegexOption.DOT_MATCHES_ALL).find(title) ?: return@forEach
|
|
||||||
val gTopic = r[1].trim()
|
|
||||||
val gAddedDate = Date.fromY_m_d(r[2].trim())
|
|
||||||
val gEventDate = Date.fromY_m_d(r[3].trim())
|
|
||||||
if (gTopic == topic && gAddedDate == addedDate && gEventDate == eventDate) {
|
|
||||||
description = r[4].replace("<br.?/>".toRegex(), "\n").trim()
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val seen = when (profile.empty) {
|
val seen = when (profile.empty) {
|
||||||
true -> true
|
true -> true
|
||||||
else -> eventDate < Date.getToday()
|
else -> eventDate < Date.getToday()
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
"$topic\n$description",
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LIBRUS_SYNERGIA_HOMEWORK_ATTACHMENT_URL
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusSandboxDownloadAttachment
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
|
||||||
|
class LibrusSynergiaHomeworkGetAttachment(
|
||||||
|
override val data: DataLibrus,
|
||||||
|
val event: EventFull,
|
||||||
|
val attachmentId: Long,
|
||||||
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : LibrusSynergia(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "LibrusSynergiaHomeworkGetAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
redirectUrlGet(TAG, "$LIBRUS_SYNERGIA_HOMEWORK_ATTACHMENT_URL/$attachmentId") { url ->
|
||||||
|
LibrusSandboxDownloadAttachment(data, url, event, attachmentId, attachmentName, onSuccess)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,20 +8,17 @@ import com.google.gson.JsonObject
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.MobidziennikWebGetAttachment
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.MobidziennikWebGetMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.MobidziennikWebGetRecipientList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.MobidziennikWebSendMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.firstlogin.MobidziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.firstlogin.MobidziennikFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -105,9 +102,9 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
|||||||
override fun markAllAnnouncementsAsRead() {}
|
override fun markAllAnnouncementsAsRead() {}
|
||||||
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
login(LOGIN_METHOD_MOBIDZIENNIK_WEB) {
|
login(LOGIN_METHOD_MOBIDZIENNIK_WEB) {
|
||||||
MobidziennikWebGetAttachment(data, message, attachmentId, attachmentName) {
|
MobidziennikWebGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
completed()
|
completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,10 +118,19 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_MOBIDZIENNIK_WEB) {
|
||||||
|
MobidziennikWebGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { MobidziennikFirstLogin(data) { completed() } }
|
override fun firstLogin() { MobidziennikFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -17,6 +17,7 @@ const val ENDPOINT_MOBIDZIENNIK_WEB_NOTICES = 2040
|
|||||||
const val ENDPOINT_MOBIDZIENNIK_WEB_ATTENDANCE = 2050
|
const val ENDPOINT_MOBIDZIENNIK_WEB_ATTENDANCE = 2050
|
||||||
const val ENDPOINT_MOBIDZIENNIK_WEB_MANUALS = 2100
|
const val ENDPOINT_MOBIDZIENNIK_WEB_MANUALS = 2100
|
||||||
const val ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL = 2200
|
const val ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL = 2200
|
||||||
|
const val ENDPOINT_MOBIDZIENNIK_WEB_HOMEWORK = 2300 // not used as an endpoint
|
||||||
const val ENDPOINT_MOBIDZIENNIK_API2_MAIN = 3000
|
const val ENDPOINT_MOBIDZIENNIK_API2_MAIN = 3000
|
||||||
|
|
||||||
val MobidziennikFeatures = listOf(
|
val MobidziennikFeatures = listOf(
|
||||||
|
@ -30,7 +30,7 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
|
|||||||
val teacherId = cols[1].toLong()
|
val teacherId = cols[1].toLong()
|
||||||
val subjectId = cols[3].toLong()
|
val subjectId = cols[3].toLong()
|
||||||
var type = Event.TYPE_DEFAULT
|
var type = Event.TYPE_DEFAULT
|
||||||
var topic = cols[5]
|
var topic = cols[5].trim()
|
||||||
Regexes.MOBIDZIENNIK_EVENT_TYPE.find(topic)?.let {
|
Regexes.MOBIDZIENNIK_EVENT_TYPE.find(topic)?.let {
|
||||||
val typeText = it.groupValues[1]
|
val typeText = it.groupValues[1]
|
||||||
when (typeText) {
|
when (typeText) {
|
||||||
@ -51,17 +51,16 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
|
|||||||
|
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
data.profileId,
|
profileId = data.profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
type,
|
type = type,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = teamId)
|
||||||
teamId)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
data.metadataList.add(
|
data.metadataList.add(
|
||||||
@ -76,6 +75,8 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_DEFAULT))
|
||||||
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_EXAM))
|
||||||
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_SHORT_QUIZ))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
|
||||||
|
|
||||||
|
import android.text.Html
|
||||||
import androidx.core.util.contains
|
import androidx.core.util.contains
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
@ -25,22 +26,21 @@ class MobidziennikApiHomework(val data: DataMobidziennik, rows: List<String>) {
|
|||||||
val id = cols[0].toLong()
|
val id = cols[0].toLong()
|
||||||
val teacherId = cols[7].toLong()
|
val teacherId = cols[7].toLong()
|
||||||
val subjectId = cols[6].toLong()
|
val subjectId = cols[6].toLong()
|
||||||
val topic = cols[1]
|
val topic = Html.fromHtml(cols[1])?.toString()?.trim() ?: ""
|
||||||
val eventDate = Date.fromYmd(cols[2])
|
val eventDate = Date.fromYmd(cols[2])
|
||||||
val startTime = Time.fromYmdHm(cols[3])
|
val startTime = Time.fromYmdHm(cols[3])
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
data.profileId,
|
profileId = data.profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = teamId)
|
||||||
teamId)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
data.metadataList.add(
|
data.metadataList.add(
|
||||||
|
@ -44,7 +44,7 @@ class MobidziennikApiTeams(val data: DataMobidziennik, tableTeams: List<String>?
|
|||||||
|
|
||||||
val studentId = cols[1].toInt()
|
val studentId = cols[1].toInt()
|
||||||
val teamId = cols[2].toLong()
|
val teamId = cols[2].toLong()
|
||||||
val studentNumber = cols[4].toInt()
|
val studentNumber = cols[4].toIntOrNull() ?: -1
|
||||||
|
|
||||||
if (studentId != data.studentId)
|
if (studentId != data.studentId)
|
||||||
continue
|
continue
|
||||||
|
@ -61,26 +61,25 @@ class MobidziennikWebCalendar(override val data: DataMobidziennik,
|
|||||||
val title = event.getString("title")
|
val title = event.getString("title")
|
||||||
val comment = event.getString("comment")
|
val comment = event.getString("comment")
|
||||||
|
|
||||||
var topic = title
|
var topic = title ?: ""
|
||||||
if (title != comment) {
|
if (title != comment) {
|
||||||
topic += "\n" + comment
|
topic += "\n" + comment
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == -1L) {
|
if (id == -1L) {
|
||||||
id = crc16(topic?.toByteArray()).toLong()
|
id = crc16(topic.toByteArray()).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate, null,
|
date = eventDate, time = null,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
eventType,
|
type = eventType,
|
||||||
false,
|
teacherId = -1,
|
||||||
-1,
|
subjectId = -1,
|
||||||
-1,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -8,12 +8,14 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class MobidziennikWebGetAttachment(override val data: DataMobidziennik,
|
class MobidziennikWebGetAttachment(override val data: DataMobidziennik,
|
||||||
val message: Message,
|
val owner: Any,
|
||||||
val attachmentId: Long,
|
val attachmentId: Long,
|
||||||
val attachmentName: String,
|
val attachmentName: String,
|
||||||
val onSuccess: () -> Unit
|
val onSuccess: () -> Unit
|
||||||
@ -25,25 +27,40 @@ class MobidziennikWebGetAttachment(override val data: DataMobidziennik,
|
|||||||
init {
|
init {
|
||||||
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
||||||
|
|
||||||
val typeUrl = if (message.type == Message.TYPE_SENT)
|
val typeUrl = when (owner) {
|
||||||
"wiadwyslana"
|
is Message -> if (owner.type == Message.TYPE_SENT)
|
||||||
else
|
"dziennik/wiadwyslana/?id="
|
||||||
"wiadodebrana"
|
else
|
||||||
|
"dziennik/wiadodebrana/?id="
|
||||||
|
|
||||||
webGetFile(TAG, "/dziennik/$typeUrl/?id=${message.id}&zalacznik=$attachmentId", targetFile, { file ->
|
is Event -> if (owner.date >= Date.getToday())
|
||||||
|
"dziennik/wyslijzadanie/?id_zadania="
|
||||||
|
else
|
||||||
|
"dziennik/wyslijzadanie/?id_zadania="
|
||||||
|
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val ownerId = when (owner) {
|
||||||
|
is Message -> owner.id
|
||||||
|
is Event -> owner.id
|
||||||
|
else -> -1
|
||||||
|
}
|
||||||
|
|
||||||
|
webGetFile(TAG, "/$typeUrl${ownerId}&uczen=${data.studentId}&zalacznik=$attachmentId", targetFile, { file ->
|
||||||
|
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_FINISHED,
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
file.absolutePath
|
file.absolutePath
|
||||||
)
|
)
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.messageId}_${event.attachmentId}")
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
|
||||||
@ -51,13 +68,13 @@ class MobidziennikWebGetAttachment(override val data: DataMobidziennik,
|
|||||||
// TODO make use of bytesTotal
|
// TODO make use of bytesTotal
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_PROGRESS,
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
bytesWritten = written
|
bytesWritten = written
|
||||||
)
|
)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-31.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
|
class MobidziennikWebGetHomework(override val data: DataMobidziennik,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : MobidziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "MobidziennikWebHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val endpoint = if (event.date >= Date.getToday())
|
||||||
|
"zadaniadomowe"
|
||||||
|
else
|
||||||
|
"zadaniadomowearchiwalne"
|
||||||
|
|
||||||
|
webGet(TAG, "/mobile/$endpoint") { text ->
|
||||||
|
MobidziennikLuckyNumberExtractor(data, text)
|
||||||
|
|
||||||
|
Regexes.MOBIDZIENNIK_HOMEWORK_ROW.findAll(text).forEach { homeworkMatch ->
|
||||||
|
val tableRow = homeworkMatch[1].ifBlank { return@forEach }
|
||||||
|
|
||||||
|
val id = Regexes.MOBIDZIENNIK_HOMEWORK_ID.find(tableRow)?.get(1)?.toLongOrNull() ?: return@forEach
|
||||||
|
if (event.id != id)
|
||||||
|
return@forEach
|
||||||
|
|
||||||
|
event.attachmentIds = mutableListOf()
|
||||||
|
event.attachmentNames = mutableListOf()
|
||||||
|
Regexes.MOBIDZIENNIK_HOMEWORK_ATTACHMENT.findAll(tableRow).forEach {
|
||||||
|
event.attachmentIds?.add(it[2].toLongOrNull() ?: return@forEach)
|
||||||
|
event.attachmentNames?.add(it[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
event.homeworkBody = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
data.eventList.add(event)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||||
@ -61,19 +61,17 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val recipient = MessageRecipientFull(
|
val recipient = MessageRecipientFull(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
-1,
|
id = -1,
|
||||||
-1,
|
messageId = message.id,
|
||||||
readDate,
|
readDate = readDate
|
||||||
message.id
|
|
||||||
)
|
)
|
||||||
|
|
||||||
recipient.fullName = profile?.accountName ?: profile?.studentNameLong ?: ""
|
recipient.fullName = profile?.accountName ?: profile?.studentNameLong ?: ""
|
||||||
|
|
||||||
messageRecipientList.add(recipient)
|
messageRecipientList.add(recipient)
|
||||||
} else {
|
} else {
|
||||||
message.senderId = -1
|
message.senderId = null
|
||||||
message.senderReplyId = -1
|
|
||||||
|
|
||||||
content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
|
content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
|
||||||
val senderEl = recipientEl.select("td:eq(0)").first()
|
val senderEl = recipientEl.select("td:eq(0)").first()
|
||||||
@ -100,11 +98,10 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val recipient = MessageRecipientFull(
|
val recipient = MessageRecipientFull(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
receiverId,
|
id = receiverId,
|
||||||
-1,
|
messageId = message.id,
|
||||||
readDate,
|
readDate = readDate
|
||||||
message.id
|
|
||||||
)
|
)
|
||||||
|
|
||||||
recipient.fullName = teacher?.fullName ?: "?"
|
recipient.fullName = teacher?.fullName ?: "?"
|
||||||
@ -149,7 +146,9 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
|||||||
|
|
||||||
message.recipients = messageRecipientList
|
message.recipients = messageRecipientList
|
||||||
data.messageRecipientList.addAll(messageRecipientList)
|
data.messageRecipientList.addAll(messageRecipientList)
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageList.add(message)
|
||||||
|
data.messageListReplace = true
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-31.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
|
class MobidziennikWebHomework(override val data: DataMobidziennik,
|
||||||
|
override val lastSync: Long?,
|
||||||
|
val type: Int = TYPE_CURRENT,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : MobidziennikWeb(data, lastSync) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "MobidziennikWebHomework"
|
||||||
|
const val TYPE_CURRENT = 0
|
||||||
|
const val TYPE_PAST = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val endpoint = when (type) {
|
||||||
|
TYPE_PAST -> "zadaniadomowearchiwalne"
|
||||||
|
else -> "zadaniadomowe"
|
||||||
|
}
|
||||||
|
webGet(TAG, "/mobile/$endpoint") { text ->
|
||||||
|
MobidziennikLuckyNumberExtractor(data, text)
|
||||||
|
|
||||||
|
Regexes.MOBIDZIENNIK_HOMEWORK_ROW.findAll(text).forEach { homeworkMatch ->
|
||||||
|
val tableRow = homeworkMatch[1].ifBlank { return@forEach }
|
||||||
|
|
||||||
|
/*val items = Regexes.MOBIDZIENNIK_HOMEWORK_ITEM.findAll(tableRow).map { match ->
|
||||||
|
match[1] to match[2].fixWhiteSpaces()
|
||||||
|
}.toList()*/
|
||||||
|
|
||||||
|
val id = Regexes.MOBIDZIENNIK_HOMEWORK_ID.find(tableRow)?.get(1)?.toLongOrNull() ?: return@forEach
|
||||||
|
if (event.id != id)
|
||||||
|
return@forEach
|
||||||
|
|
||||||
|
//val homeworkBody = Regexes.MOBIDZIENNIK_HOMEWORK_BODY.find(tableRow)?.get(1) ?: ""
|
||||||
|
|
||||||
|
event.attachmentIds = mutableListOf()
|
||||||
|
event.attachmentNames = mutableListOf()
|
||||||
|
Regexes.MOBIDZIENNIK_HOMEWORK_ATTACHMENT.findAll(tableRow).forEach {
|
||||||
|
event.attachmentIds?.add(it[1].toLongOrNull() ?: return@forEach)
|
||||||
|
event.attachmentNames?.add(it[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
event.homeworkBody = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
//data.eventList.add(eventObject)
|
||||||
|
//data.metadataList.add(
|
||||||
|
// Metadata(
|
||||||
|
// profileId,
|
||||||
|
// Metadata.TYPE_EVENT,
|
||||||
|
// eventObject.id,
|
||||||
|
// profile?.empty ?: false,
|
||||||
|
// profile?.empty ?: false,
|
||||||
|
// System.currentTimeMillis() /* no addedDate here though */
|
||||||
|
// ))
|
||||||
|
|
||||||
|
// not used as an endpoint
|
||||||
|
//data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
||||||
|
data.eventList.add(event)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_HOMEWORK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.fixName
|
import pl.szczodrzynski.edziennik.fixName
|
||||||
@ -54,12 +54,12 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
|
|||||||
type = TYPE_SENT
|
type = TYPE_SENT
|
||||||
|
|
||||||
val senderEl = item.select("td:eq(3) div").first()
|
val senderEl = item.select("td:eq(3) div").first()
|
||||||
var senderId: Long = -1
|
var senderId: Long? = null
|
||||||
|
|
||||||
if (type == TYPE_RECEIVED) {
|
if (type == TYPE_RECEIVED) {
|
||||||
// search sender teacher
|
// search sender teacher
|
||||||
val senderName = senderEl.text().fixName()
|
val senderName = senderEl.text().fixName()
|
||||||
senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id ?: -1
|
senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
|
||||||
data.messageRecipientList.add(MessageRecipient(profileId, -1, id))
|
data.messageRecipientList.add(MessageRecipient(profileId, -1, id))
|
||||||
} else {
|
} else {
|
||||||
// TYPE_SENT, so multiple recipients possible
|
// TYPE_SENT, so multiple recipients possible
|
||||||
@ -72,16 +72,15 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = type,
|
||||||
null,
|
subject = subject,
|
||||||
type,
|
body = null,
|
||||||
senderId,
|
senderId = senderId
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate))
|
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,25 +52,24 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
|
|||||||
|
|
||||||
val senderEl = item.select("td:eq(2)").first()
|
val senderEl = item.select("td:eq(2)").first()
|
||||||
val senderName = senderEl.ownText().fixName()
|
val senderName = senderEl.ownText().fixName()
|
||||||
val senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id ?: -1
|
val senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
|
||||||
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, -1, id))
|
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, -1, id))
|
||||||
|
|
||||||
val isRead = item.select("td:eq(3) span").first().hasClass("wiadomosc_przeczytana")
|
val isRead = item.select("td:eq(3) span").first().hasClass("wiadomosc_przeczytana")
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = Message.TYPE_RECEIVED,
|
||||||
null,
|
subject = subject,
|
||||||
Message.TYPE_RECEIVED,
|
body = null,
|
||||||
senderId,
|
senderId = senderId
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (hasAttachments)
|
if (hasAttachments)
|
||||||
message.setHasAttachments()
|
message.hasAttachments = true
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.setSeenMetadataList.add(
|
data.setSeenMetadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -73,19 +73,18 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
|
|||||||
val addedDate = Date.fromIsoHm(addedDateEl.text())
|
val addedDate = Date.fromIsoHm(addedDateEl.text())
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = Message.TYPE_SENT,
|
||||||
null,
|
subject = subject,
|
||||||
Message.TYPE_SENT,
|
body = null,
|
||||||
-1,
|
senderId = null
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (hasAttachments)
|
if (hasAttachments)
|
||||||
message.setHasAttachments()
|
message.hasAttachments = true
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.setSeenMetadataList.add(
|
data.setSeenMetadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -43,7 +43,7 @@ class MobidziennikWebSendMessage(override val data: DataMobidziennik,
|
|||||||
|
|
||||||
// TODO create MobidziennikWebMessagesSent and replace this
|
// TODO create MobidziennikWebMessagesSent and replace this
|
||||||
MobidziennikWebMessagesAll(data, null) {
|
MobidziennikWebMessagesAll(data, null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||||
|
|
||||||
|
@ -16,10 +16,10 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|||||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
import pl.szczodrzynski.edziennik.data.api.prepare
|
||||||
import pl.szczodrzynski.edziennik.data.api.templateLoginMethods
|
import pl.szczodrzynski.edziennik.data.api.templateLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +87,10 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() {
|
override fun firstLogin() {
|
||||||
TemplateFirstLogin(data) {
|
TemplateFirstLogin(data) {
|
||||||
completed()
|
completed()
|
||||||
@ -96,6 +100,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -5,26 +5,31 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_API
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.helper.OneDriveDownloadAttachment
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanData
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiAttachments
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiMessagesChangeStatus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiMessagesChangeStatus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiSendMessage
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiSendMessage
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.firstlogin.VulcanFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.firstlogin.VulcanFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLogin
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.prepareFor
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.vulcanLoginMethods
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
companion object {
|
companion object {
|
||||||
@ -87,8 +92,29 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
override fun getMessage(message: MessageFull) {
|
override fun getMessage(message: MessageFull) {
|
||||||
login(LOGIN_METHOD_VULCAN_API) {
|
login(LOGIN_METHOD_VULCAN_API) {
|
||||||
VulcanApiMessagesChangeStatus(data, message) {
|
if (message.attachmentIds != null) {
|
||||||
completed()
|
VulcanApiMessagesChangeStatus(data, message) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
return@login
|
||||||
|
}
|
||||||
|
val list = data.app.db.messageDao().getAllNow(data.profileId)
|
||||||
|
VulcanApiAttachments(data, list, message, MessageFull::class) { _ ->
|
||||||
|
list.forEach {
|
||||||
|
if (it.attachmentIds == null)
|
||||||
|
it.attachmentIds = mutableListOf()
|
||||||
|
data.messageList.add(it)
|
||||||
|
}
|
||||||
|
data.messageListReplace = true
|
||||||
|
|
||||||
|
if (message.seen) {
|
||||||
|
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||||
|
completed()
|
||||||
|
return@VulcanApiAttachments
|
||||||
|
}
|
||||||
|
VulcanApiMessagesChangeStatus(data, message) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,26 +127,74 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markAllAnnouncementsAsRead() {
|
override fun markAllAnnouncementsAsRead() {}
|
||||||
|
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
||||||
|
override fun getRecipientList() {}
|
||||||
|
|
||||||
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
|
val fileUrl = attachmentName.substringAfter(":")
|
||||||
|
if (attachmentName == fileUrl) {
|
||||||
|
data.error(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
OneDriveDownloadAttachment(
|
||||||
|
app,
|
||||||
|
fileUrl,
|
||||||
|
onSuccess = { file ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
data.profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
|
file.absolutePath
|
||||||
|
)
|
||||||
|
|
||||||
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${data.profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
|
||||||
|
completed()
|
||||||
|
},
|
||||||
|
onProgress = { written, total ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
data.profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
|
bytesWritten = written
|
||||||
|
)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
},
|
||||||
|
onError = { apiError ->
|
||||||
|
data.error(apiError)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAnnouncement(announcement: AnnouncementFull) {
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_VULCAN_API) {
|
||||||
}
|
val list = data.app.db.eventDao().getAllNow(data.profileId).filter { !it.addedManually }
|
||||||
|
VulcanApiAttachments(data, list, eventFull, EventFull::class) { _ ->
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
list.forEach {
|
||||||
|
it.homeworkBody = ""
|
||||||
}
|
data.eventList.add(it)
|
||||||
|
}
|
||||||
override fun getRecipientList() {
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(eventFull))
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun firstLogin() { VulcanFirstLogin(data) { completed() } }
|
override fun firstLogin() { VulcanFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
data.cancel()
|
data.cancel()
|
||||||
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-6.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.asJsonObjectList
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
import pl.szczodrzynski.edziennik.getJsonArray
|
||||||
|
import pl.szczodrzynski.edziennik.getLong
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
class VulcanApiAttachments(override val data: DataVulcan,
|
||||||
|
val list: List<*>,
|
||||||
|
val owner: Any?,
|
||||||
|
val ownerClass: KClass<*>,
|
||||||
|
val onSuccess: (list: List<*>) -> Unit
|
||||||
|
) : VulcanApi(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanApiAttachments"
|
||||||
|
}
|
||||||
|
|
||||||
|
init { run {
|
||||||
|
val endpoint = when (ownerClass) {
|
||||||
|
MessageFull::class -> VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS
|
||||||
|
EventFull::class -> VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS
|
||||||
|
else -> null
|
||||||
|
} ?: return@run
|
||||||
|
|
||||||
|
val idName = when (ownerClass) {
|
||||||
|
MessageFull::class -> "IdWiadomosc"
|
||||||
|
EventFull::class -> "IdZadanieDomowe"
|
||||||
|
else -> null
|
||||||
|
} ?: return@run
|
||||||
|
|
||||||
|
val startDate = profile?.getSemesterStart(profile?.currentSemester ?: 1)?.inUnix ?: 0
|
||||||
|
val endDate = Date.getToday().stepForward(0, 1, 0).inUnix
|
||||||
|
|
||||||
|
apiGet(TAG, endpoint, parameters = mapOf(
|
||||||
|
"DataPoczatkowa" to startDate,
|
||||||
|
"DataKoncowa" to endDate,
|
||||||
|
"LoginId" to data.studentLoginId,
|
||||||
|
"IdUczen" to data.studentId
|
||||||
|
)) { json, _ ->
|
||||||
|
|
||||||
|
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { attachment ->
|
||||||
|
val id = attachment.getLong("Id") ?: return@forEach
|
||||||
|
val itemId = attachment.getLong(idName) ?: return@forEach
|
||||||
|
val url = attachment.getString("Url") ?: return@forEach
|
||||||
|
val fileName = "${attachment.getString("NazwaPliku")}:$url"
|
||||||
|
|
||||||
|
list.forEach {
|
||||||
|
if (it is MessageFull
|
||||||
|
&& it.profileId == profileId
|
||||||
|
&& it.id == itemId
|
||||||
|
&& it.attachmentIds?.contains(id) != true) {
|
||||||
|
if (it.attachmentIds == null)
|
||||||
|
it.attachmentIds = mutableListOf()
|
||||||
|
if (it.attachmentNames == null)
|
||||||
|
it.attachmentNames = mutableListOf()
|
||||||
|
it.attachmentIds?.add(id)
|
||||||
|
it.attachmentNames?.add(fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it is EventFull
|
||||||
|
&& it.profileId == profileId
|
||||||
|
&& it.id == itemId
|
||||||
|
&& it.attachmentIds?.contains(id) != true) {
|
||||||
|
if (it.attachmentIds == null)
|
||||||
|
it.attachmentIds = mutableListOf()
|
||||||
|
if (it.attachmentNames == null)
|
||||||
|
it.attachmentNames = mutableListOf()
|
||||||
|
it.attachmentIds?.add(id)
|
||||||
|
it.attachmentNames?.add(fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner is MessageFull
|
||||||
|
&& it is MessageFull
|
||||||
|
&& owner.profileId == it.profileId
|
||||||
|
&& owner.id == it.id) {
|
||||||
|
owner.attachmentIds = it.attachmentIds
|
||||||
|
owner.attachmentNames = it.attachmentNames
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner is EventFull
|
||||||
|
&& it is EventFull
|
||||||
|
&& owner.profileId == it.profileId
|
||||||
|
&& owner.id == it.id) {
|
||||||
|
owner.attachmentIds = it.attachmentIds
|
||||||
|
owner.attachmentNames = it.attachmentNames
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (owner is MessageFull) {
|
||||||
|
list.forEach {
|
||||||
|
(it as? MessageFull)?.let { message ->
|
||||||
|
data.messageList.add(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.messageListReplace = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner is EventFull) {
|
||||||
|
list.forEach {
|
||||||
|
(it as? EventFull)?.let { it1 ->
|
||||||
|
it1.homeworkBody = ""
|
||||||
|
data.eventList.add(it1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.eventListReplace = true
|
||||||
|
}*/
|
||||||
|
|
||||||
|
onSuccess(list)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
@ -57,7 +57,7 @@ class VulcanApiEvents(override val data: DataVulcan,
|
|||||||
val eventDate = Date.fromY_m_d(event.getString("DataTekst") ?: return@forEach)
|
val eventDate = Date.fromY_m_d(event.getString("DataTekst") ?: return@forEach)
|
||||||
val subjectId = event.getLong("IdPrzedmiot") ?: -1
|
val subjectId = event.getLong("IdPrzedmiot") ?: -1
|
||||||
val teacherId = event.getLong("IdPracownik") ?: -1
|
val teacherId = event.getLong("IdPracownik") ?: -1
|
||||||
val topic = event.getString("Opis") ?: ""
|
val topic = event.getString("Opis")?.trim() ?: ""
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
@ -72,17 +72,16 @@ class VulcanApiEvents(override val data: DataVulcan,
|
|||||||
val teamId = event.getLong("IdOddzial") ?: data.teamClass?.id ?: -1
|
val teamId = event.getLong("IdOddzial") ?: data.teamClass?.id ?: -1
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
type,
|
type = type,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = teamId
|
||||||
teamId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
|
@ -9,7 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_CHANGE_S
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_INBOX
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_INBOX
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import kotlin.text.replace
|
import kotlin.text.replace
|
||||||
@ -44,8 +44,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
|||||||
val body = message.getString("Tresc") ?: ""
|
val body = message.getString("Tresc") ?: ""
|
||||||
|
|
||||||
val senderLoginId = message.getString("NadawcaId") ?: return@forEach
|
val senderLoginId = message.getString("NadawcaId") ?: return@forEach
|
||||||
val senderId = data.teacherList
|
val senderId = data.teacherList.singleOrNull { it.loginId == senderLoginId }?.id ?: {
|
||||||
.singleOrNull { it.loginId == senderLoginId }?.id ?: {
|
|
||||||
|
|
||||||
val senderName = message.getString("Nadawca") ?: ""
|
val senderName = message.getString("Nadawca") ?: ""
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
|||||||
data.teacherList.put(teacherObject.id, teacherObject)
|
data.teacherList.put(teacherObject.id, teacherObject)
|
||||||
teacherObject.id
|
teacherObject.id
|
||||||
}
|
}
|
||||||
}.invoke() ?: -1
|
}.invoke()
|
||||||
|
|
||||||
val sentDate = message.getLong("DataWyslaniaUnixEpoch")?.let { it * 1000 }
|
val sentDate = message.getLong("DataWyslaniaUnixEpoch")?.let { it * 1000 }
|
||||||
?: -1
|
?: -1
|
||||||
@ -68,13 +67,12 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
|||||||
?: -1
|
?: -1
|
||||||
|
|
||||||
val messageObject = Message(
|
val messageObject = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = TYPE_RECEIVED,
|
||||||
body.replace("\n", "<br>"),
|
subject = subject,
|
||||||
TYPE_RECEIVED,
|
body = body.replace("\n", "<br>"),
|
||||||
senderId,
|
senderId = senderId
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
val messageRecipientObject = MessageRecipient(
|
||||||
@ -85,7 +83,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
|||||||
id
|
id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(messageObject)
|
data.messageList.add(messageObject)
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
data.setSeenMetadataList.add(Metadata(
|
data.setSeenMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_SENT
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
@ -92,16 +92,15 @@ class VulcanApiMessagesSent(override val data: DataVulcan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val messageObject = Message(
|
val messageObject = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
type = TYPE_SENT,
|
||||||
body.replace("\n", "<br>"),
|
subject = subject,
|
||||||
TYPE_SENT,
|
body = body.replace("\n", "<br>"),
|
||||||
-1,
|
senderId = null
|
||||||
-1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(messageObject)
|
data.messageList.add(messageObject)
|
||||||
data.setSeenMetadataList.add(Metadata(
|
data.setSeenMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_MESSAGE,
|
Metadata.TYPE_MESSAGE,
|
||||||
|
@ -52,7 +52,7 @@ class VulcanApiSendMessage(override val data: DataVulcan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VulcanApiMessagesSent(data, null) {
|
VulcanApiMessagesSent(data, null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||||
|
|
||||||
|
@ -4,11 +4,21 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.events
|
package pl.szczodrzynski.edziennik.data.api.events
|
||||||
|
|
||||||
data class AttachmentGetEvent(val profileId: Int, val messageId: Long, val attachmentId: Long,
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
|
|
||||||
|
data class AttachmentGetEvent(val profileId: Int, val owner: Any, val attachmentId: Long,
|
||||||
var eventType: Int = TYPE_PROGRESS, val fileName: String? = null,
|
var eventType: Int = TYPE_PROGRESS, val fileName: String? = null,
|
||||||
val bytesWritten: Long = 0) {
|
val bytesWritten: Long = 0) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TYPE_PROGRESS = 0
|
const val TYPE_PROGRESS = 0
|
||||||
const val TYPE_FINISHED = 1
|
const val TYPE_FINISHED = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ownerId
|
||||||
|
get() = when (owner) {
|
||||||
|
is Message -> owner.id
|
||||||
|
is Event -> owner.id
|
||||||
|
else -> -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-31.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.events
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
|
||||||
|
data class EventGetEvent(val event: EventFull)
|
@ -5,9 +5,9 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.interfaces
|
package pl.szczodrzynski.edziennik.data.api.interfaces
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
|
||||||
interface EdziennikInterface {
|
interface EdziennikInterface {
|
||||||
@ -16,8 +16,9 @@ interface EdziennikInterface {
|
|||||||
fun sendMessage(recipients: List<Teacher>, subject: String, text: String)
|
fun sendMessage(recipients: List<Teacher>, subject: String, text: String)
|
||||||
fun markAllAnnouncementsAsRead()
|
fun markAllAnnouncementsAsRead()
|
||||||
fun getAnnouncement(announcement: AnnouncementFull)
|
fun getAnnouncement(announcement: AnnouncementFull)
|
||||||
fun getAttachment(message: Message, attachmentId: Long, attachmentName: String)
|
fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String)
|
||||||
fun getRecipientList()
|
fun getRecipientList()
|
||||||
|
fun getEvent(eventFull: EventFull)
|
||||||
fun firstLogin()
|
fun firstLogin()
|
||||||
fun cancel()
|
fun cancel()
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,8 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
val gradeCategories = LongSparseArray<GradeCategory>()
|
val gradeCategories = LongSparseArray<GradeCategory>()
|
||||||
|
|
||||||
var teacherOnConflictStrategy = OnConflictStrategy.IGNORE
|
var teacherOnConflictStrategy = OnConflictStrategy.IGNORE
|
||||||
|
var eventListReplace = false
|
||||||
|
var messageListReplace = false
|
||||||
|
|
||||||
val classrooms = LongSparseArray<Classroom>()
|
val classrooms = LongSparseArray<Classroom>()
|
||||||
val attendanceTypes = LongSparseArray<AttendanceType>()
|
val attendanceTypes = LongSparseArray<AttendanceType>()
|
||||||
@ -125,7 +127,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
val teacherAbsenceList = mutableListOf<TeacherAbsence>()
|
val teacherAbsenceList = mutableListOf<TeacherAbsence>()
|
||||||
|
|
||||||
val messageList = mutableListOf<Message>()
|
val messageList = mutableListOf<Message>()
|
||||||
val messageIgnoreList = mutableListOf<Message>()
|
|
||||||
val messageRecipientList = mutableListOf<MessageRecipient>()
|
val messageRecipientList = mutableListOf<MessageRecipient>()
|
||||||
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
||||||
|
|
||||||
@ -181,7 +182,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
luckyNumberList.clear()
|
luckyNumberList.clear()
|
||||||
teacherAbsenceList.clear()
|
teacherAbsenceList.clear()
|
||||||
messageList.clear()
|
messageList.clear()
|
||||||
messageIgnoreList.clear()
|
|
||||||
messageRecipientList.clear()
|
messageRecipientList.clear()
|
||||||
messageRecipientIgnoreList.clear()
|
messageRecipientIgnoreList.clear()
|
||||||
metadataList.clear()
|
metadataList.clear()
|
||||||
@ -197,6 +197,13 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
|
|
||||||
profile.userCode = generateUserCode()
|
profile.userCode = generateUserCode()
|
||||||
|
|
||||||
|
// update profile subname with class name, school year and account type
|
||||||
|
profile.subname = joinNotNullStrings(
|
||||||
|
" - ",
|
||||||
|
profile.studentClassName,
|
||||||
|
"${profile.studentSchoolYearStart}/${profile.studentSchoolYearStart + 1}"
|
||||||
|
) + " " + app.getString(if (profile.isParent) R.string.login_summary_account_parent else R.string.login_summary_account_child)
|
||||||
|
|
||||||
db.profileDao().add(profile)
|
db.profileDao().add(profile)
|
||||||
db.loginStoreDao().add(loginStore)
|
db.loginStoreDao().add(loginStore)
|
||||||
|
|
||||||
@ -284,7 +291,10 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
db.gradeDao().addAll(gradeList)
|
db.gradeDao().addAll(gradeList)
|
||||||
}
|
}
|
||||||
if (eventList.isNotEmpty()) {
|
if (eventList.isNotEmpty()) {
|
||||||
db.eventDao().addAll(eventList)
|
if (eventListReplace)
|
||||||
|
db.eventDao().replaceAll(eventList)
|
||||||
|
else
|
||||||
|
db.eventDao().upsertAll(eventList, removeNotKept = true)
|
||||||
}
|
}
|
||||||
if (noticeList.isNotEmpty()) {
|
if (noticeList.isNotEmpty()) {
|
||||||
db.noticeDao().clear(profile.id)
|
db.noticeDao().clear(profile.id)
|
||||||
@ -301,10 +311,12 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
if (teacherAbsenceList.isNotEmpty())
|
if (teacherAbsenceList.isNotEmpty())
|
||||||
db.teacherAbsenceDao().addAll(teacherAbsenceList)
|
db.teacherAbsenceDao().addAll(teacherAbsenceList)
|
||||||
|
|
||||||
if (messageList.isNotEmpty())
|
if (messageList.isNotEmpty()) {
|
||||||
db.messageDao().addAll(messageList)
|
if (messageListReplace)
|
||||||
if (messageIgnoreList.isNotEmpty())
|
db.messageDao().replaceAll(messageList)
|
||||||
db.messageDao().addAllIgnore(messageIgnoreList)
|
else
|
||||||
|
db.messageDao().upsertAll(messageList, removeNotKept = false) // TODO dataRemoveModel for messages
|
||||||
|
}
|
||||||
if (messageRecipientList.isNotEmpty())
|
if (messageRecipientList.isNotEmpty())
|
||||||
db.messageRecipientDao().addAll(messageRecipientList)
|
db.messageRecipientDao().addAll(messageRecipientList)
|
||||||
if (messageRecipientIgnoreList.isNotEmpty())
|
if (messageRecipientIgnoreList.isNotEmpty())
|
||||||
|
@ -56,9 +56,9 @@ open class DataRemoveModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun commit(profileId: Int, dao: EventDao) {
|
fun commit(profileId: Int, dao: EventDao) {
|
||||||
type?.let { dao.removeFutureWithType(profileId, Date.getToday(), it) }
|
type?.let { dao.dontKeepFutureWithType(profileId, Date.getToday(), it) }
|
||||||
exceptType?.let { dao.removeFutureExceptType(profileId, Date.getToday(), it) }
|
exceptType?.let { dao.dontKeepFutureExceptType(profileId, Date.getToday(), it) }
|
||||||
exceptTypes?.let { dao.removeFutureExceptTypes(profileId, Date.getToday(), it) }
|
exceptTypes?.let { dao.dontKeepFutureExceptTypes(profileId, Date.getToday(), it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +196,11 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
// skip blacklisted events
|
// skip blacklisted events
|
||||||
if (event.id in blacklistedIds)
|
if (event.id in blacklistedIds)
|
||||||
return@forEach
|
return@forEach
|
||||||
|
|
||||||
|
// force nullable non-negative colors
|
||||||
|
if (event.color == -1)
|
||||||
|
event.color = null
|
||||||
|
|
||||||
// create the event for every matching team and profile
|
// create the event for every matching team and profile
|
||||||
teams.filter { it.code == event.teamCode }.onEach { team ->
|
teams.filter { it.code == event.teamCode }.onEach { team ->
|
||||||
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@onEach
|
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@onEach
|
||||||
|
@ -46,6 +46,6 @@ object Signing {
|
|||||||
|
|
||||||
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
|
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
|
||||||
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
|
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
|
||||||
return "$param1.MTIzNDU2Nzg5MDmD46bIpY===.$param2".sha256()
|
return "$param1.MTIzNDU2Nzg5MDP/4SAI6B===.$param2".sha256()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ data class EventShareRequest (
|
|||||||
|
|
||||||
val action: String = "event",
|
val action: String = "event",
|
||||||
|
|
||||||
val sharedByName: String,
|
/* If null, the server shows an error */
|
||||||
|
val sharedByName: String?,
|
||||||
val shareTeamCode: String? = null,
|
val shareTeamCode: String? = null,
|
||||||
val unshareTeamCode: String? = null,
|
val unshareTeamCode: String? = null,
|
||||||
val requesterName: String? = null,
|
val requesterName: String? = null,
|
||||||
|
@ -34,7 +34,7 @@ class AppSync(val app: App, val notifications: MutableList<Notification>, val pr
|
|||||||
if (events.isNotEmpty()) {
|
if (events.isNotEmpty()) {
|
||||||
val today = Date.getToday()
|
val today = Date.getToday()
|
||||||
app.db.metadataDao().addAllIgnore(events.map { event ->
|
app.db.metadataDao().addAllIgnore(events.map { event ->
|
||||||
val isPast = event.eventDate < today
|
val isPast = event.date < today
|
||||||
Metadata(
|
Metadata(
|
||||||
event.profileId,
|
event.profileId,
|
||||||
Metadata.TYPE_EVENT,
|
Metadata.TYPE_EVENT,
|
||||||
@ -44,7 +44,7 @@ class AppSync(val app: App, val notifications: MutableList<Notification>, val pr
|
|||||||
event.addedDate
|
event.addedDate
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
return app.db.eventDao().addAll(events).size
|
return app.db.eventDao().upsertAll(events).size
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
announcementNotifications()
|
announcementNotifications()
|
||||||
messageNotifications()
|
messageNotifications()
|
||||||
luckyNumberNotifications()
|
luckyNumberNotifications()
|
||||||
|
teacherAbsenceNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun timetableNotifications() {
|
private fun timetableNotifications() {
|
||||||
@ -58,7 +59,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun eventNotifications() {
|
private fun eventNotifications() {
|
||||||
for (event in app.db.eventDao().notNotifiedNow.filter { it.eventDate >= today }) {
|
for (event in app.db.eventDao().getNotNotifiedNow().filter { it.date >= today }) {
|
||||||
val text = if (event.type == Event.TYPE_HOMEWORK)
|
val text = if (event.type == Event.TYPE_HOMEWORK)
|
||||||
app.getString(
|
app.getString(
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
if (event.subjectLongName.isNullOrEmpty())
|
||||||
@ -66,7 +67,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
else
|
else
|
||||||
R.string.notification_homework_format,
|
R.string.notification_homework_format,
|
||||||
event.subjectLongName,
|
event.subjectLongName,
|
||||||
event.eventDate.formattedString
|
event.date.formattedString
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
app.getString(
|
app.getString(
|
||||||
@ -74,8 +75,8 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
R.string.notification_event_no_subject_format
|
R.string.notification_event_no_subject_format
|
||||||
else
|
else
|
||||||
R.string.notification_event_format,
|
R.string.notification_event_format,
|
||||||
event.typeName,
|
event.typeName ?: "wydarzenie",
|
||||||
event.eventDate.formattedString,
|
event.date.formattedString,
|
||||||
event.subjectLongName
|
event.subjectLongName
|
||||||
)
|
)
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
||||||
@ -88,17 +89,17 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
addedDate = event.addedDate
|
addedDate = event.addedDate
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
).addExtra("eventId", event.id).addExtra("eventDate", event.date.value.toLong())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sharedEventNotifications() {
|
fun sharedEventNotifications() {
|
||||||
for (event in app.db.eventDao().notNotifiedNow.filter { it.eventDate >= today && it.sharedBy != null }) {
|
for (event in app.db.eventDao().getNotNotifiedNow().filter { it.date >= today && it.sharedBy != null }) {
|
||||||
val text = app.getString(
|
val text = app.getString(
|
||||||
R.string.notification_shared_event_format,
|
R.string.notification_shared_event_format,
|
||||||
event.sharedByName,
|
event.sharedByName,
|
||||||
event.typeName ?: "wydarzenie",
|
event.typeName ?: "wydarzenie",
|
||||||
event.eventDate.formattedString,
|
event.date.formattedString,
|
||||||
event.topic
|
event.topic
|
||||||
)
|
)
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
||||||
@ -111,7 +112,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
addedDate = event.addedDate
|
addedDate = event.addedDate
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
).addExtra("eventId", event.id).addExtra("eventDate", event.date.value.toLong())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,10 +227,10 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun messageNotifications() {
|
private fun messageNotifications() {
|
||||||
for (message in app.db.messageDao().receivedNotNotifiedNow) {
|
for (message in app.db.messageDao().getNotNotifiedNow()) {
|
||||||
val text = app.getString(
|
val text = app.getString(
|
||||||
R.string.notification_message_format,
|
R.string.notification_message_format,
|
||||||
message.senderFullName,
|
message.senderName,
|
||||||
message.subject
|
message.subject
|
||||||
)
|
)
|
||||||
notifications += Notification(
|
notifications += Notification(
|
||||||
@ -274,4 +275,23 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun teacherAbsenceNotifications() {
|
||||||
|
for (teacherAbsence in app.db.teacherAbsenceDao().getNotNotifiedNow()) {
|
||||||
|
val message = app.getString(
|
||||||
|
R.string.notification_teacher_absence_new_format,
|
||||||
|
teacherAbsence.teacherFullName
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(teacherAbsence.profileId, Notification.TYPE_TEACHER_ABSENCE, teacherAbsence.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_TEACHER_ABSENCE),
|
||||||
|
text = message,
|
||||||
|
type = Notification.TYPE_TEACHER_ABSENCE,
|
||||||
|
profileId = teacherAbsence.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == teacherAbsence.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
addedDate = teacherAbsence.addedDate
|
||||||
|
).addExtra("eventDate", teacherAbsence.dateFrom.value.toLong())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
|||||||
LibrusLesson::class,
|
LibrusLesson::class,
|
||||||
TimetableManual::class,
|
TimetableManual::class,
|
||||||
Metadata::class
|
Metadata::class
|
||||||
], version = 79)
|
], version = 85)
|
||||||
@TypeConverters(
|
@TypeConverters(
|
||||||
ConverterTime::class,
|
ConverterTime::class,
|
||||||
ConverterDate::class,
|
ConverterDate::class,
|
||||||
@ -164,7 +164,13 @@ abstract class AppDb : RoomDatabase() {
|
|||||||
Migration76(),
|
Migration76(),
|
||||||
Migration77(),
|
Migration77(),
|
||||||
Migration78(),
|
Migration78(),
|
||||||
Migration79()
|
Migration79(),
|
||||||
|
Migration80(),
|
||||||
|
Migration81(),
|
||||||
|
Migration82(),
|
||||||
|
Migration83(),
|
||||||
|
Migration84(),
|
||||||
|
Migration85()
|
||||||
).allowMainThreadQueries().build()
|
).allowMainThreadQueries().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.*
|
||||||
|
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Keepable
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface BaseDao<T : Keepable, F : T> {
|
||||||
|
@RawQuery
|
||||||
|
fun getRaw(query: SupportSQLiteQuery): LiveData<List<F>>
|
||||||
|
fun getRaw(query: String) = getRaw(SimpleSQLiteQuery(query))
|
||||||
|
@RawQuery
|
||||||
|
fun getRawNow(query: SupportSQLiteQuery): List<F>
|
||||||
|
fun getRawNow(query: String) = getRawNow(SimpleSQLiteQuery(query))
|
||||||
|
@RawQuery
|
||||||
|
fun getOneNow(query: SupportSQLiteQuery): F?
|
||||||
|
fun getOneNow(query: String) = getOneNow(SimpleSQLiteQuery(query))
|
||||||
|
|
||||||
|
@Query("DELETE FROM events WHERE keep = 0")
|
||||||
|
fun removeNotKept()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INSERT an [item] into the database,
|
||||||
|
* ignoring any conflicts.
|
||||||
|
*/
|
||||||
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
|
fun add(item: T): Long
|
||||||
|
/**
|
||||||
|
* INSERT [items] into the database,
|
||||||
|
* ignoring any conflicts.
|
||||||
|
*/
|
||||||
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
|
fun addAll(items: List<T>): LongArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REPLACE an [item] in the database,
|
||||||
|
* removing any conflicting rows.
|
||||||
|
*/
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun replace(item: T)
|
||||||
|
/**
|
||||||
|
* REPLACE [items] in the database,
|
||||||
|
* removing any conflicting rows.
|
||||||
|
*/
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun replaceAll(items: List<T>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selective UPDATE an [item] in the database.
|
||||||
|
* Do nothing if a matching item does not exist.
|
||||||
|
*/
|
||||||
|
fun update(item: T): Long
|
||||||
|
/**
|
||||||
|
* Selective UPDATE [items] in the database.
|
||||||
|
* Do nothing for those items which do not exist.
|
||||||
|
*/
|
||||||
|
fun updateAll(items: List<T>): LongArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all items from the database,
|
||||||
|
* that match the given [profileId].
|
||||||
|
*/
|
||||||
|
fun clear(profileId: Int)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INSERT an [item] into the database,
|
||||||
|
* doing a selective [update] on conflicts.
|
||||||
|
* @return the newly inserted item's ID or -1L if the item was updated instead
|
||||||
|
*/
|
||||||
|
@Transaction
|
||||||
|
fun upsert(item: T): Long {
|
||||||
|
val id = add(item)
|
||||||
|
if (id == -1L) update(item)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* INSERT [items] into the database,
|
||||||
|
* doing a selective [update] on conflicts.
|
||||||
|
* @return a [LongArray] of IDs of newly inserted items or -1L if the item existed before
|
||||||
|
*/
|
||||||
|
@Transaction
|
||||||
|
fun upsertAll(items: List<T>, removeNotKept: Boolean = false): LongArray {
|
||||||
|
val insertResult = addAll(items)
|
||||||
|
val updateList = mutableListOf<T>()
|
||||||
|
|
||||||
|
insertResult.forEachIndexed { index, result ->
|
||||||
|
if (result == -1L) updateList.add(items[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateList.isNotEmpty()) updateAll(items)
|
||||||
|
if (removeNotKept) removeNotKept()
|
||||||
|
return insertResult
|
||||||
|
}
|
||||||
|
}
|
@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.room.Dao;
|
|
||||||
import androidx.room.Insert;
|
|
||||||
import androidx.room.OnConflictStrategy;
|
|
||||||
import androidx.room.Query;
|
|
||||||
import androidx.room.RawQuery;
|
|
||||||
import androidx.room.Transaction;
|
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_EVENT;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_HOMEWORK;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LESSON_CHANGE;
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
public abstract class EventDao {
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
public abstract long add(Event event);
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
public abstract long[] addAll(List<Event> eventList);
|
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId")
|
|
||||||
public abstract void clear(int profileId);
|
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
|
|
||||||
public abstract void remove(int profileId, long id);
|
|
||||||
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
|
||||||
public abstract void removeMetadata(int profileId, int thingType, long thingId);
|
|
||||||
@Transaction
|
|
||||||
public void remove(int profileId, long type, long id) {
|
|
||||||
remove(profileId, id);
|
|
||||||
removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id);
|
|
||||||
}
|
|
||||||
@Transaction
|
|
||||||
public void remove(Event event) {
|
|
||||||
remove(event.profileId, event.type, event.id);
|
|
||||||
}
|
|
||||||
@Transaction
|
|
||||||
public void remove(int profileId, Event event) {
|
|
||||||
remove(profileId, event.type, event.id);
|
|
||||||
}
|
|
||||||
@Query("DELETE FROM events WHERE teamId = :teamId AND eventId = :id")
|
|
||||||
public abstract void removeByTeamId(long teamId, long id);
|
|
||||||
|
|
||||||
@RawQuery(observedEntities = {Event.class})
|
|
||||||
abstract LiveData<List<EventFull>> getAll(SupportSQLiteQuery query);
|
|
||||||
public LiveData<List<EventFull>> getAll(int profileId, String filter, String limit) {
|
|
||||||
String query = "SELECT \n" +
|
|
||||||
"*, \n" +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName,\n" +
|
|
||||||
"eventTypes.eventTypeName AS typeName,\n" +
|
|
||||||
"eventTypes.eventTypeColor AS typeColor\n" +
|
|
||||||
"FROM events\n" +
|
|
||||||
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
|
|
||||||
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
|
|
||||||
"LEFT JOIN teams USING(profileId, teamId)\n" +
|
|
||||||
"LEFT JOIN eventTypes USING(profileId, eventType)\n" +
|
|
||||||
"LEFT JOIN metadata ON eventId = thingId AND (thingType = " + TYPE_EVENT + " OR thingType = " + TYPE_HOMEWORK + ") AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE events.profileId = "+profileId+" AND events.eventBlacklisted = 0 AND "+filter+"\n" +
|
|
||||||
"GROUP BY eventId\n" +
|
|
||||||
"ORDER BY eventDate, eventStartTime ASC "+limit;
|
|
||||||
Log.d("DB", query);
|
|
||||||
return getAll(new SimpleSQLiteQuery(query));
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAll(int profileId) {
|
|
||||||
return getAll(profileId, "1", "");
|
|
||||||
}
|
|
||||||
public List<EventFull> getAllNow(int profileId) {
|
|
||||||
return getAllNow(profileId, "1");
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) {
|
|
||||||
return getAll(profileId, filter, "");
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAllByType(int profileId, long type, String filter) {
|
|
||||||
return getAll(profileId, "eventType = "+type+" AND "+filter, "");
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) {
|
|
||||||
return getAll(profileId, "eventDate = '"+date.getStringY_m_d()+"'", "");
|
|
||||||
}
|
|
||||||
public List<EventFull> getAllByDateNow(int profileId, @NonNull Date date) {
|
|
||||||
return getAllNow(profileId, "eventDate = '"+date.getStringY_m_d()+"'");
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAllByDateTime(int profileId, @NonNull Date date, Time time) {
|
|
||||||
if (time == null)
|
|
||||||
return getAllByDate(profileId, date);
|
|
||||||
return getAll(profileId, "eventDate = '"+date.getStringY_m_d()+"' AND eventStartTime = '"+time.getStringValue()+"'", "");
|
|
||||||
}
|
|
||||||
public LiveData<List<EventFull>> getAllNearest(int profileId, @NonNull Date today, int limit) {
|
|
||||||
return getAll(profileId, "eventDate >= '"+today.getStringY_m_d()+"'", "LIMIT "+limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RawQuery
|
|
||||||
abstract List<EventFull> getAllNow(SupportSQLiteQuery query);
|
|
||||||
public List<EventFull> getAllNow(int profileId, String filter) {
|
|
||||||
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
|
|
||||||
"*, \n" +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName,\n" +
|
|
||||||
"eventTypes.eventTypeName AS typeName,\n" +
|
|
||||||
"eventTypes.eventTypeColor AS typeColor\n" +
|
|
||||||
"FROM events \n" +
|
|
||||||
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
|
|
||||||
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
|
|
||||||
"LEFT JOIN teams USING(profileId, teamId)\n" +
|
|
||||||
"LEFT JOIN eventTypes USING(profileId, eventType)\n" +
|
|
||||||
"LEFT JOIN metadata ON eventId = thingId AND (thingType = " + TYPE_EVENT + " OR thingType = " + TYPE_HOMEWORK + ") AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE events.profileId = "+profileId+" AND events.eventBlacklisted = 0 AND "+filter+"\n" +
|
|
||||||
"GROUP BY eventId\n" +
|
|
||||||
"ORDER BY eventStartTime, addedDate ASC"));
|
|
||||||
}
|
|
||||||
public List<EventFull> getNotNotifiedNow(int profileId) {
|
|
||||||
return getAllNow(profileId, "notified = 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query("SELECT eventId FROM events WHERE profileId = :profileId AND eventBlacklisted = 1")
|
|
||||||
public abstract List<Long> getBlacklistedIds(int profileId);
|
|
||||||
@Query("SELECT eventId FROM events WHERE eventBlacklisted = 1")
|
|
||||||
public abstract List<Long> getBlacklistedIds();
|
|
||||||
|
|
||||||
@Query("SELECT " +
|
|
||||||
"*, " +
|
|
||||||
"eventTypes.eventTypeName AS typeName, " +
|
|
||||||
"eventTypes.eventTypeColor AS typeColor " +
|
|
||||||
"FROM events " +
|
|
||||||
"LEFT JOIN subjects USING(profileId, subjectId) " +
|
|
||||||
"LEFT JOIN eventTypes USING(profileId, eventType) " +
|
|
||||||
"LEFT JOIN metadata ON eventId = thingId AND (thingType = " + TYPE_EVENT + " OR thingType = " + TYPE_HOMEWORK + ") AND metadata.profileId = events.profileId " +
|
|
||||||
"WHERE events.eventBlacklisted = 0 AND notified = 0 " +
|
|
||||||
"GROUP BY eventId " +
|
|
||||||
"ORDER BY addedDate ASC")
|
|
||||||
public abstract List<EventFull> getNotNotifiedNow();
|
|
||||||
|
|
||||||
public EventFull getByIdNow(int profileId, long eventId) {
|
|
||||||
List<EventFull> eventList = getAllNow(profileId, "eventId = "+eventId);
|
|
||||||
return eventList.size() == 0 ? null : eventList.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query("UPDATE events SET eventAddedManually = 1 WHERE profileId = :profileId AND eventDate < :date")
|
|
||||||
public abstract void convertOlderToManual(int profileId, Date date);
|
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0")
|
|
||||||
public abstract void removeNotManual(int profileId);
|
|
||||||
|
|
||||||
@RawQuery
|
|
||||||
abstract long removeFuture(SupportSQLiteQuery query);
|
|
||||||
@Transaction
|
|
||||||
public void removeFuture(int profileId, Date todayDate, String filter) {
|
|
||||||
removeFuture(new SimpleSQLiteQuery("DELETE FROM events WHERE profileId = " + profileId
|
|
||||||
+ " AND eventAddedManually = 0 AND eventDate >= '" + todayDate.getStringY_m_d() + "'" +
|
|
||||||
" AND " + filter));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType = :type")
|
|
||||||
public abstract void removeFutureWithType(int profileId, Date todayDate, long type);
|
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType != :exceptType")
|
|
||||||
public abstract void removeFutureExceptType(int profileId, Date todayDate, long exceptType);
|
|
||||||
|
|
||||||
@Transaction
|
|
||||||
public void removeFutureExceptTypes(int profileId, Date todayDate, List<Long> exceptTypes) {
|
|
||||||
removeFuture(profileId, todayDate, "eventType NOT IN " + exceptTypes.toString().replace('[', '(').replace(']', ')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query("UPDATE metadata SET seen = :seen WHERE profileId = :profileId AND (thingType = "+TYPE_EVENT+" OR thingType = "+TYPE_LESSON_CHANGE+" OR thingType = "+TYPE_HOMEWORK+") AND thingId IN (SELECT eventId FROM events WHERE profileId = :profileId AND eventDate = :date)")
|
|
||||||
public abstract void setSeenByDate(int profileId, Date date, boolean seen);
|
|
||||||
|
|
||||||
@Query("UPDATE events SET eventBlacklisted = :blacklisted WHERE profileId = :profileId AND eventId = :eventId")
|
|
||||||
public abstract void setBlacklisted(int profileId, long eventId, boolean blacklisted);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.RawQuery
|
||||||
|
import androidx.room.Transaction
|
||||||
|
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
|
||||||
|
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
@SelectiveDao(db = AppDb::class)
|
||||||
|
abstract class EventDao : BaseDao<Event, EventFull> {
|
||||||
|
companion object {
|
||||||
|
private const val QUERY = """
|
||||||
|
SELECT
|
||||||
|
*,
|
||||||
|
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
|
||||||
|
eventTypes.eventTypeName AS typeName,
|
||||||
|
eventTypes.eventTypeColor AS typeColor
|
||||||
|
FROM events
|
||||||
|
LEFT JOIN subjects USING(profileId, subjectId)
|
||||||
|
LEFT JOIN teachers USING(profileId, teacherId)
|
||||||
|
LEFT JOIN teams USING(profileId, teamId)
|
||||||
|
LEFT JOIN eventTypes USING(profileId, eventType)
|
||||||
|
LEFT JOIN metadata ON eventId = thingId AND (thingType = ${Metadata.TYPE_EVENT} OR thingType = ${Metadata.TYPE_HOMEWORK}) AND metadata.profileId = events.profileId
|
||||||
|
"""
|
||||||
|
|
||||||
|
private const val ORDER_BY = """GROUP BY eventId ORDER BY eventDate, eventTime, addedDate ASC"""
|
||||||
|
private const val NOT_BLACKLISTED = """events.eventBlacklisted = 0"""
|
||||||
|
private const val NOT_DONE = """events.eventIsDone = 0"""
|
||||||
|
}
|
||||||
|
|
||||||
|
private val selective by lazy { EventDaoSelective(App.db) }
|
||||||
|
|
||||||
|
@RawQuery(observedEntities = [Event::class])
|
||||||
|
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<EventFull>>
|
||||||
|
|
||||||
|
// SELECTIVE UPDATE
|
||||||
|
@UpdateSelective(primaryKeys = ["profileId", "eventId"], skippedColumns = ["eventIsDone", "eventBlacklisted", "homeworkBody", "attachmentIds", "attachmentNames"])
|
||||||
|
override fun update(item: Event) = selective.update(item)
|
||||||
|
override fun updateAll(items: List<Event>) = selective.updateAll(items)
|
||||||
|
|
||||||
|
// CLEAR
|
||||||
|
@Query("DELETE FROM events WHERE profileId = :profileId")
|
||||||
|
abstract override fun clear(profileId: Int)
|
||||||
|
|
||||||
|
// GET ALL - LIVE DATA
|
||||||
|
fun getAll(profileId: Int) =
|
||||||
|
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId $ORDER_BY")
|
||||||
|
fun getAllByType(profileId: Int, type: Long, filter: String = "1") =
|
||||||
|
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventType = $type AND $filter $ORDER_BY")
|
||||||
|
fun getAllByDate(profileId: Int, date: Date) =
|
||||||
|
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate = '${date.stringY_m_d}' $ORDER_BY")
|
||||||
|
fun getAllByDateTime(profileId: Int, date: Date, time: Time) =
|
||||||
|
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate = '${date.stringY_m_d}' AND eventTime = '${time.stringValue}' $ORDER_BY")
|
||||||
|
fun getNearestNotDone(profileId: Int, today: Date, limit: Int) =
|
||||||
|
getRaw("$QUERY WHERE $NOT_BLACKLISTED AND $NOT_DONE AND events.profileId = $profileId AND eventDate >= '${today.stringY_m_d}' $ORDER_BY LIMIT $limit")
|
||||||
|
|
||||||
|
// GET ALL - NOW
|
||||||
|
fun getAllNow(profileId: Int) =
|
||||||
|
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId $ORDER_BY")
|
||||||
|
fun getNotNotifiedNow() =
|
||||||
|
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND notified = 0 $ORDER_BY")
|
||||||
|
fun getNotNotifiedNow(profileId: Int) =
|
||||||
|
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND notified = 0 $ORDER_BY")
|
||||||
|
fun getAllByDateNow(profileId: Int, date: Date) =
|
||||||
|
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate = '${date.stringY_m_d}' $ORDER_BY")
|
||||||
|
|
||||||
|
// GET ONE - NOW
|
||||||
|
fun getByIdNow(profileId: Int, id: Long) =
|
||||||
|
getOneNow("$QUERY WHERE events.profileId = $profileId AND eventId = $id")
|
||||||
|
|
||||||
|
|
||||||
|
@Query("SELECT eventId FROM events WHERE profileId = :profileId AND eventBlacklisted = 1")
|
||||||
|
abstract fun getBlacklistedIds(profileId: Int): List<Long>
|
||||||
|
|
||||||
|
@get:Query("SELECT eventId FROM events WHERE eventBlacklisted = 1")
|
||||||
|
abstract val blacklistedIds: List<Long>
|
||||||
|
|
||||||
|
/*@Query("UPDATE events SET eventAddedManually = 1 WHERE profileId = :profileId AND eventDate < :date")
|
||||||
|
abstract fun convertOlderToManual(profileId: Int, date: Date?)
|
||||||
|
|
||||||
|
@Query("DELETE FROM events WHERE teamId = :teamId AND eventId = :id")
|
||||||
|
abstract fun removeByTeamId(teamId: Long, id: Long)
|
||||||
|
|
||||||
|
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0")
|
||||||
|
abstract fun removeNotManual(profileId: Int)*/
|
||||||
|
|
||||||
|
@RawQuery
|
||||||
|
abstract fun dontKeepFuture(query: SupportSQLiteQuery?): Long
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
open fun dontKeepFuture(profileId: Int, todayDate: Date, filter: String) {
|
||||||
|
dontKeepFuture(SimpleSQLiteQuery("UPDATE events SET keep = 0 WHERE profileId = " + profileId
|
||||||
|
+ " AND eventAddedManually = 0 AND eventDate >= '" + todayDate.stringY_m_d + "'" +
|
||||||
|
" AND " + filter))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query("UPDATE events SET keep = 0 WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType = :type")
|
||||||
|
abstract fun dontKeepFutureWithType(profileId: Int, todayDate: Date, type: Long)
|
||||||
|
|
||||||
|
@Query("UPDATE events SET keep = 0 WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType != :exceptType")
|
||||||
|
abstract fun dontKeepFutureExceptType(profileId: Int, todayDate: Date, exceptType: Long)
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
open fun dontKeepFutureExceptTypes(profileId: Int, todayDate: Date, exceptTypes: List<Long>) {
|
||||||
|
dontKeepFuture(profileId, todayDate, "eventType NOT IN " + exceptTypes.toString().replace('[', '(').replace(']', ')'))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query("UPDATE metadata SET seen = :seen WHERE profileId = :profileId AND (thingType = " + Metadata.TYPE_EVENT + " OR thingType = " + Metadata.TYPE_LESSON_CHANGE + " OR thingType = " + Metadata.TYPE_HOMEWORK + ") AND thingId IN (SELECT eventId FROM events WHERE profileId = :profileId AND eventDate = :date)")
|
||||||
|
abstract fun setSeenByDate(profileId: Int, date: Date, seen: Boolean)
|
||||||
|
|
||||||
|
@Query("UPDATE events SET eventBlacklisted = :blacklisted WHERE profileId = :profileId AND eventId = :eventId")
|
||||||
|
abstract fun setBlacklisted(profileId: Int, eventId: Long, blacklisted: Boolean)
|
||||||
|
|
||||||
|
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
|
||||||
|
abstract fun remove(profileId: Int, id: Long)
|
||||||
|
|
||||||
|
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
||||||
|
abstract fun removeMetadata(profileId: Int, thingType: Int, thingId: Long)
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
open fun remove(profileId: Int, type: Long, id: Long) {
|
||||||
|
remove(profileId, id)
|
||||||
|
removeMetadata(profileId, if (type == Event.TYPE_HOMEWORK) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
open fun remove(event: Event) {
|
||||||
|
remove(event.profileId, event.type, event.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
open fun remove(profileId: Int, event: Event) {
|
||||||
|
remove(profileId, event.type, event.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.room.Dao;
|
|
||||||
import androidx.room.Insert;
|
|
||||||
import androidx.room.OnConflictStrategy;
|
|
||||||
import androidx.room.Query;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType;
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
public interface EventTypeDao {
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
void add(EventType gradeCategory);
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
void addAll(List<EventType> gradeCategoryList);
|
|
||||||
|
|
||||||
@Query("DELETE FROM eventTypes WHERE profileId = :profileId")
|
|
||||||
void clear(int profileId);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId AND eventType = :typeId")
|
|
||||||
EventType getByIdNow(int profileId, long typeId);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
|
||||||
LiveData<List<EventType>> getAll(int profileId);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
|
||||||
List<EventType> getAllNow(int profileId);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes")
|
|
||||||
List<EventType> getAllNow();
|
|
||||||
}
|
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_CLASS_EVENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_DEFAULT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_ESSAY
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXAM
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXCURSION
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_INFORMATION
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PROJECT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PT_MEETING
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_READING
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_SHORT_QUIZ
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_CLASS_EVENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_DEFAULT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_ESSAY
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXAM
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXCURSION
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_INFORMATION
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PROJECT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PT_MEETING
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_READING
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_SHORT_QUIZ
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
abstract class EventTypeDao {
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
abstract fun add(eventType: EventType)
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
abstract fun addAll(eventTypeList: List<EventType>)
|
||||||
|
|
||||||
|
@Query("DELETE FROM eventTypes WHERE profileId = :profileId")
|
||||||
|
abstract fun clear(profileId: Int)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId AND eventType = :typeId")
|
||||||
|
abstract fun getByIdNow(profileId: Int, typeId: Long): EventType?
|
||||||
|
|
||||||
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
||||||
|
abstract fun getAll(profileId: Int): LiveData<List<EventType>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
||||||
|
abstract fun getAllNow(profileId: Int): List<EventType>
|
||||||
|
|
||||||
|
@get:Query("SELECT * FROM eventTypes")
|
||||||
|
abstract val allNow: List<EventType>
|
||||||
|
|
||||||
|
fun addDefaultTypes(context: Context, profileId: Int): List<EventType> {
|
||||||
|
val typeList = listOf(
|
||||||
|
EventType(profileId, TYPE_HOMEWORK, context.getString(R.string.event_type_homework), COLOR_HOMEWORK),
|
||||||
|
EventType(profileId, TYPE_DEFAULT, context.getString(R.string.event_other), COLOR_DEFAULT),
|
||||||
|
EventType(profileId, TYPE_EXAM, context.getString(R.string.event_exam), COLOR_EXAM),
|
||||||
|
EventType(profileId, TYPE_SHORT_QUIZ, context.getString(R.string.event_short_quiz), COLOR_SHORT_QUIZ),
|
||||||
|
EventType(profileId, TYPE_ESSAY, context.getString(R.string.event_essay), COLOR_ESSAY),
|
||||||
|
EventType(profileId, TYPE_PROJECT, context.getString(R.string.event_project), COLOR_PROJECT),
|
||||||
|
EventType(profileId, TYPE_PT_MEETING, context.getString(R.string.event_pt_meeting), COLOR_PT_MEETING),
|
||||||
|
EventType(profileId, TYPE_EXCURSION, context.getString(R.string.event_excursion), COLOR_EXCURSION),
|
||||||
|
EventType(profileId, TYPE_READING, context.getString(R.string.event_reading), COLOR_READING),
|
||||||
|
EventType(profileId, TYPE_CLASS_EVENT, context.getString(R.string.event_class_event), COLOR_CLASS_EVENT),
|
||||||
|
EventType(profileId, TYPE_INFORMATION, context.getString(R.string.event_information), COLOR_INFORMATION)
|
||||||
|
)
|
||||||
|
addAll(typeList)
|
||||||
|
return typeList
|
||||||
|
}
|
||||||
|
}
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.room.Dao;
|
|
||||||
import androidx.room.Insert;
|
|
||||||
import androidx.room.OnConflictStrategy;
|
|
||||||
import androidx.room.Query;
|
|
||||||
import androidx.room.RawQuery;
|
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_MESSAGE;
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
public abstract class MessageDao {
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
public abstract long add(Message message);
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
public abstract void addAll(List<Message> messageList);
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
|
||||||
public abstract void addAllIgnore(List<Message> messageList);
|
|
||||||
|
|
||||||
@Query("DELETE FROM messages WHERE profileId = :profileId")
|
|
||||||
public abstract void clear(int profileId);
|
|
||||||
|
|
||||||
@RawQuery(observedEntities = {Message.class})
|
|
||||||
abstract LiveData<List<MessageFull>> getAll(SupportSQLiteQuery query);
|
|
||||||
@RawQuery(observedEntities = {Message.class, Metadata.class})
|
|
||||||
abstract List<MessageFull> getNow(SupportSQLiteQuery query);
|
|
||||||
@RawQuery(observedEntities = {Message.class, Metadata.class})
|
|
||||||
abstract MessageFull getOneNow(SupportSQLiteQuery query);
|
|
||||||
|
|
||||||
public LiveData<List<MessageFull>> getWithMetadataAndSenderName(int profileId, int messageType, String filter) {
|
|
||||||
return getAll(new SimpleSQLiteQuery("SELECT \n" +
|
|
||||||
"*, \n" +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
|
||||||
"FROM messages \n" +
|
|
||||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
|
||||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE messages.profileId = "+profileId+" AND messageType = "+messageType+" AND "+filter+"\n" +
|
|
||||||
"ORDER BY addedDate DESC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<MessageFull>> getWithMetadata(int profileId, int messageType, String filter) {
|
|
||||||
return getAll(new SimpleSQLiteQuery("SELECT \n" +
|
|
||||||
"* \n" +
|
|
||||||
"FROM messages \n" +
|
|
||||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE messages.profileId = "+profileId+" AND messageType = "+messageType+" AND "+filter+"\n" +
|
|
||||||
"ORDER BY addedDate DESC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public MessageFull getById(int profileId, long messageId) {
|
|
||||||
return getOneNow(new SimpleSQLiteQuery("SELECT \n" +
|
|
||||||
"*, \n" +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
|
||||||
"FROM messages \n" +
|
|
||||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
|
||||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE messages.profileId = "+profileId+" AND messageId = "+messageId+"\n" +
|
|
||||||
"ORDER BY addedDate DESC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<MessageFull>> getReceived(int profileId) {
|
|
||||||
return getWithMetadataAndSenderName(profileId, TYPE_RECEIVED, "1");
|
|
||||||
}
|
|
||||||
public LiveData<List<MessageFull>> getDeleted(int profileId) {
|
|
||||||
return getWithMetadataAndSenderName(profileId, TYPE_DELETED, "1");
|
|
||||||
}
|
|
||||||
public LiveData<List<MessageFull>> getSent(int profileId) {
|
|
||||||
return getWithMetadata(profileId, TYPE_SENT, "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MessageFull> getReceivedNow(int profileId, String filter) {
|
|
||||||
return getNow(new SimpleSQLiteQuery("SELECT \n" +
|
|
||||||
"*, \n" +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
|
||||||
"FROM messages \n" +
|
|
||||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
|
||||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
|
||||||
"WHERE messages.profileId = "+profileId+" AND messageType = 0 AND "+filter+"\n" +
|
|
||||||
"ORDER BY addedDate DESC"));
|
|
||||||
}
|
|
||||||
public List<MessageFull> getReceivedNotNotifiedNow(int profileId) {
|
|
||||||
return getReceivedNow(profileId, "notified = 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query("SELECT " +
|
|
||||||
"*, " +
|
|
||||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName " +
|
|
||||||
"FROM messages " +
|
|
||||||
"LEFT JOIN teachers ON teachers.profileId = messages.profileId AND teacherId = senderId " +
|
|
||||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = messages.profileId " +
|
|
||||||
"WHERE messageType = 0 AND notified = 0 " +
|
|
||||||
"ORDER BY addedDate DESC")
|
|
||||||
public abstract List<MessageFull> getReceivedNotNotifiedNow();
|
|
||||||
}
|
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.RawQuery
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
|
||||||
|
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
@SelectiveDao(db = AppDb::class)
|
||||||
|
abstract class MessageDao : BaseDao<Message, MessageFull> {
|
||||||
|
companion object {
|
||||||
|
private const val QUERY = """
|
||||||
|
SELECT
|
||||||
|
*,
|
||||||
|
teachers.teacherName ||" "|| teachers.teacherSurname AS senderName
|
||||||
|
FROM messages
|
||||||
|
LEFT JOIN teachers ON teachers.profileId = messages.profileId AND teacherId = senderId
|
||||||
|
LEFT JOIN metadata ON messageId = thingId AND thingType = ${Metadata.TYPE_MESSAGE} AND metadata.profileId = messages.profileId
|
||||||
|
"""
|
||||||
|
|
||||||
|
private const val ORDER_BY = """ORDER BY messageIsPinned, addedDate DESC"""
|
||||||
|
}
|
||||||
|
|
||||||
|
private val selective by lazy { MessageDaoSelective(App.db) }
|
||||||
|
|
||||||
|
@RawQuery(observedEntities = [Message::class])
|
||||||
|
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<MessageFull>>
|
||||||
|
|
||||||
|
@UpdateSelective(primaryKeys = ["profileId", "messageId"], skippedColumns = ["messageType", "messageBody", "messageIsPinned", "attachmentIds", "attachmentNames", "attachmentSizes"])
|
||||||
|
override fun update(item: Message) = selective.update(item)
|
||||||
|
override fun updateAll(items: List<Message>) = selective.updateAll(items)
|
||||||
|
|
||||||
|
// CLEAR
|
||||||
|
@Query("DELETE FROM messages WHERE profileId = :profileId")
|
||||||
|
abstract override fun clear(profileId: Int)
|
||||||
|
|
||||||
|
// GET ALL - LIVE DATA
|
||||||
|
fun getAll(profileId: Int) =
|
||||||
|
getRaw("$QUERY WHERE messages.profileId = $profileId $ORDER_BY")
|
||||||
|
fun getAllByType(profileId: Int, type: Int) =
|
||||||
|
getRaw("$QUERY WHERE messages.profileId = $profileId AND messageType = $type $ORDER_BY")
|
||||||
|
fun getReceived(profileId: Int) = getAllByType(profileId, Message.TYPE_RECEIVED)
|
||||||
|
fun getSent(profileId: Int) = getAllByType(profileId, Message.TYPE_SENT)
|
||||||
|
fun getDeleted(profileId: Int) = getAllByType(profileId, Message.TYPE_DELETED)
|
||||||
|
fun getDraft(profileId: Int) = getAllByType(profileId, Message.TYPE_DRAFT)
|
||||||
|
|
||||||
|
// GET ALL - NOW
|
||||||
|
fun getAllNow(profileId: Int) =
|
||||||
|
getRawNow("$QUERY WHERE messages.profileId = $profileId $ORDER_BY")
|
||||||
|
fun getNotNotifiedNow() =
|
||||||
|
getRawNow("$QUERY WHERE notified = 0 AND messageType = ${Message.TYPE_RECEIVED} $ORDER_BY")
|
||||||
|
|
||||||
|
// GET ONE - NOW
|
||||||
|
fun getByIdNow(profileId: Int, id: Long) =
|
||||||
|
getOneNow("$QUERY WHERE messages.profileId = $profileId AND messageId = $id")
|
||||||
|
}
|
@ -78,8 +78,8 @@ public abstract class MetadataDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof Event) {
|
if (o instanceof Event) {
|
||||||
if (add(new Metadata(profileId, ((Event) o).type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).id, seen, false, 0)) == -1) {
|
if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen, false, 0)) == -1) {
|
||||||
updateSeen(profileId, ((Event) o).type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).id, seen);
|
updateSeen(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof LessonFull) {
|
if (o instanceof LessonFull) {
|
||||||
@ -93,8 +93,8 @@ public abstract class MetadataDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof Message) {
|
if (o instanceof Message) {
|
||||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).id, seen, false, 0)) == -1) {
|
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen, false, 0)) == -1) {
|
||||||
updateSeen(profileId, TYPE_MESSAGE, ((Message) o).id, seen);
|
updateSeen(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,8 +117,8 @@ public abstract class MetadataDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof Event) {
|
if (o instanceof Event) {
|
||||||
if (add(new Metadata(profileId, ((Event) o).type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).id, false, notified, 0)) == -1) {
|
if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), false, notified, 0)) == -1) {
|
||||||
updateNotified(profileId, ((Event) o).type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).id, notified);
|
updateNotified(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), notified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof LessonFull) {
|
if (o instanceof LessonFull) {
|
||||||
@ -132,8 +132,8 @@ public abstract class MetadataDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof Message) {
|
if (o instanceof Message) {
|
||||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).id, false, notified, 0)) == -1) {
|
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), false, notified, 0)) == -1) {
|
||||||
updateNotified(profileId, TYPE_MESSAGE, ((Message) o).id, notified);
|
updateNotified(profileId, TYPE_MESSAGE, ((Message) o).getId(), notified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,9 +141,9 @@ public abstract class MetadataDao {
|
|||||||
@Transaction
|
@Transaction
|
||||||
public void setBoth(int profileId, Event o, boolean seen, boolean notified, long addedDate) {
|
public void setBoth(int profileId, Event o, boolean seen, boolean notified, long addedDate) {
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
if (add(new Metadata(profileId, o.type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.id, seen, notified, addedDate)) == -1) {
|
if (add(new Metadata(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen, notified, addedDate)) == -1) {
|
||||||
updateSeen(profileId, o.type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.id, seen);
|
updateSeen(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen);
|
||||||
updateNotified(profileId, o.type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.id, notified);
|
updateNotified(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), notified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,17 @@ interface TeacherAbsenceDao {
|
|||||||
"AND :date BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo")
|
"AND :date BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo")
|
||||||
fun getAllByDateNow(profileId: Int, date: Date): List<TeacherAbsenceFull>
|
fun getAllByDateNow(profileId: Int, date: Date): List<TeacherAbsenceFull>
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
SELECT *,
|
||||||
|
teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName
|
||||||
|
FROM teacherAbsence
|
||||||
|
LEFT JOIN teachers USING (profileId, teacherId)
|
||||||
|
LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = ${Metadata.TYPE_TEACHER_ABSENCE}
|
||||||
|
AND teachers.profileId = metadata.profileId WHERE metadata.notified = 0
|
||||||
|
ORDER BY addedDate DESC
|
||||||
|
""")
|
||||||
|
fun getNotNotifiedNow(): List<TeacherAbsenceFull>
|
||||||
|
|
||||||
@Query("DELETE FROM teacherAbsence WHERE profileId = :profileId")
|
@Query("DELETE FROM teacherAbsence WHERE profileId = :profileId")
|
||||||
fun clear(profileId: Int)
|
fun clear(profileId: Int)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.dao
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.room.Dao
|
import androidx.room.*
|
||||||
import androidx.room.Insert
|
import androidx.sqlite.db.SupportSQLiteQuery
|
||||||
import androidx.room.OnConflictStrategy
|
|
||||||
import androidx.room.Query
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -18,6 +16,9 @@ interface TeacherDao {
|
|||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
fun addAllIgnore(teacherList: List<Teacher>)
|
fun addAllIgnore(teacherList: List<Teacher>)
|
||||||
|
|
||||||
|
@RawQuery
|
||||||
|
fun query(query: SupportSQLiteQuery): Int
|
||||||
|
|
||||||
@Query("DELETE FROM teachers WHERE profileId = :profileId")
|
@Query("DELETE FROM teachers WHERE profileId = :profileId")
|
||||||
fun clear(profileId: Int)
|
fun clear(profileId: Int)
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user