Migrate from moshi to kotlinx serialization

This commit is contained in:
Mikołaj Pich 2022-07-31 20:27:40 +02:00
parent aec4ea5221
commit bafb07cf5d
82 changed files with 909 additions and 869 deletions

View file

@ -2,6 +2,8 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '1.7.10' apply false
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
id "org.jetbrains.kotlin.plugin.serialization" version "1.7.10"
id "com.google.devtools.ksp" version "1.7.10-1.0.6" apply false
}
ext {
@ -32,12 +34,14 @@ nexusPublishing {
}
}
allprojects {
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'maven-publish'
apply plugin: 'signing'
apply plugin: "org.jlleitschuh.gradle.ktlint"
apply plugin: 'kotlinx-serialization'
repositories {
mavenCentral()
@ -125,13 +129,14 @@ subprojects {
}
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.jvmTarget = "11"
}
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
implementation "com.squareup.okhttp3:logging-interceptor"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
testImplementation "junit:junit:4.13.2"
testImplementation "com.squareup.okhttp3:mockwebserver"

View file

@ -1,7 +1,7 @@
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm'
id 'kotlin-kapt'
id "com.google.devtools.ksp"
}
dependencies {
@ -13,7 +13,8 @@ dependencies {
implementation "com.squareup.retrofit2:converter-moshi:$retrofit"
implementation "com.squareup.retrofit2:converter-scalars:$retrofit"
def moshi = "1.13.0"
implementation "com.squareup.moshi:moshi:$moshi"
implementation "com.squareup.moshi:moshi-adapters:$moshi"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
ksp "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
}

View file

@ -1,7 +1,6 @@
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm'
id 'kotlin-kapt'
}
dependencies {
@ -10,15 +9,11 @@ dependencies {
testImplementation "com.squareup.okhttp3:mockwebserver"
implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit"
implementation "com.squareup.retrofit2:converter-scalars:$retrofit"
implementation "pl.droidsonroids.retrofit2:converter-jspoon:$jspoon"
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
implementation "com.brsanthu:migbase64:2.2"
implementation "com.squareup.moshi:moshi:$moshi"
implementation "com.squareup.moshi:moshi-adapters:$moshi"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
implementation "com.squareup.okhttp3:okhttp-urlconnection"
}

View file

@ -1,39 +1,34 @@
package io.github.wulkanowy.sdk.scrapper
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class ApiResponse<out T>(
val success: Boolean,
val data: T?,
val feedback: Feedback? = null,
val errorMessage: String? = null
) {
)
@JsonClass(generateAdapter = true)
data class Feedback(
@Serializable
data class Feedback(
@Json(name = "Handled")
val handled: Boolean?,
@SerialName("Handled")
val handled: Boolean?,
@Json(name = "FType")
val type: String,
@SerialName("FType")
val type: String,
@Json(name = "Message")
val message: String,
@SerialName("Message")
val message: String,
@Json(name = "ExceptionMessage")
val exceptionMessage: String?,
@SerialName("ExceptionMessage")
val exceptionMessage: String?,
@Json(name = "InnerExceptionMessage")
val innerExceptionMessage: String?,
@SerialName("InnerExceptionMessage")
val innerExceptionMessage: String?,
@Json(name = "success")
val success: Boolean? = null
)
}
@SerialName("success")
val success: Boolean? = null,
)

View file

@ -1,36 +1,27 @@
package io.github.wulkanowy.sdk.scrapper.adapter
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.ToJson
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
class CustomDateAdapter : JsonAdapter<Date>() {
@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = LocalDateTime::class)
object CustomDateAdapter : KSerializer<LocalDateTime> {
private val dateFormat = SimpleDateFormat(SERVER_FORMAT, Locale.getDefault())
private const val SERVER_FORMAT = "yyyy-MM-dd HH:mm:ss"
private val formatter = DateTimeFormatter.ofPattern(SERVER_FORMAT)
companion object {
const val SERVER_FORMAT = "yyyy-MM-dd HH:mm:ss"
override fun deserialize(decoder: Decoder): LocalDateTime {
val date = decoder.decodeString()
return LocalDateTime.parse(date, formatter)
}
@FromJson
override fun fromJson(reader: JsonReader): Date? {
val dateAsString = reader.nextString()
return synchronized(dateFormat) {
dateFormat.parse(dateAsString)
}
}
@ToJson
override fun toJson(writer: JsonWriter, value: Date?) {
if (value != null) {
synchronized(dateFormat) {
writer.value(dateFormat.format(value))
}
}
override fun serialize(encoder: Encoder, value: LocalDateTime) {
encoder.encodeString(value.format(formatter))
}
}

View file

@ -1,32 +1,30 @@
package io.github.wulkanowy.sdk.scrapper.adapter
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.ToJson
import io.github.wulkanowy.sdk.scrapper.grades.GradeDate
import io.github.wulkanowy.sdk.scrapper.toDate
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class GradeDateDeserializer : JsonAdapter<GradeDate?>() {
@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = LocalDate::class)
object GradeDateDeserializer : KSerializer<LocalDate> {
companion object {
const val SERVER_FORMAT = GradeDate.FORMAT
private const val SERVER_FORMAT = "dd.MM.yyyy"
private const val SERVER_FORMAT_2 = "dd.M.yyyy"
private val formatter = DateTimeFormatter.ofPattern("[$SERVER_FORMAT][$SERVER_FORMAT_2]")
override fun deserialize(decoder: Decoder): LocalDate {
val date = if (decoder.decodeNotNullMark()) {
decoder.decodeString()
} else "01.01.1970"
return LocalDate.parse(date, formatter)
}
@FromJson
override fun fromJson(reader: JsonReader): GradeDate? {
val value = reader.readJsonValue()
val dateAsString = value?.toString()
return synchronized(reader) {
GradeDate::class.java.getDeclaredConstructor().newInstance().apply {
time = (dateAsString ?: "01.01.1970").toDate(SERVER_FORMAT).time
}
}
}
@ToJson
override fun toJson(writer: JsonWriter, value: GradeDate?) {
throw NotImplementedError()
override fun serialize(encoder: Encoder, value: LocalDate) {
encoder.encodeString(value.format(formatter))
}
}

View file

@ -0,0 +1,18 @@
package io.github.wulkanowy.sdk.scrapper.adapter
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = Object::class)
object ObjectSerializer : KSerializer<Any> {
override fun deserialize(decoder: Decoder): Any = Any()
override fun serialize(encoder: Encoder, value: Any) {
encoder.encodeString("{}")
}
}

View file

@ -1,22 +1,25 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Attendance(
@Json(name = "IdPoraLekcji")
@SerialName("IdPoraLekcji")
val timeId: Int = 0,
@Json(name = "Data")
val date: Date,
@SerialName("Data")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "PrzedmiotNazwa")
@SerialName("PrzedmiotNazwa")
val subject: String?,
@Json(name = "IdKategoria")
@SerialName("IdKategoria")
val categoryId: Int = -1
) {

View file

@ -1,33 +1,33 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class AttendanceExcuseRequest(
@Json(name = "usprawiedliwienie")
@SerialName("usprawiedliwienie")
val excuse: Excuse
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Excuse(
@Json(name = "Nieobecnosci")
@SerialName("Nieobecnosci")
val absents: List<Absent>,
@Json(name = "Tresc")
@SerialName("Tresc")
val content: String?
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Absent(
@Json(name = "Data")
@SerialName("Data")
val date: String,
@Json(name = "IdPoraLekcji")
val timeId: Int?
@SerialName("IdPoraLekcji")
val timeId: Int? = null,
)
}
}

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceCategory.ABSENCE_UNEXCUSED
import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceCategory.UNEXCUSED_LATENESS
import io.github.wulkanowy.sdk.scrapper.timetable.CacheResponse.Time
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.time.LocalDate
import java.time.Month
@ -24,12 +24,13 @@ fun AttendanceResponse.mapAttendanceList(start: LocalDate, end: LocalDate?, time
}.sortedWith(compareBy({ it.date }, { it.number }))
}
fun AttendanceSummaryResponse.mapAttendanceSummaryList(moshi: Moshi.Builder): List<AttendanceSummary> {
fun AttendanceSummaryResponse.mapAttendanceSummaryList(): List<AttendanceSummary> {
val jsonObject = Json {
isLenient = true
}
val stats = items.map {
val json = AttendanceSummaryResponse_SummaryJsonAdapter(moshi.build()).serializeNulls().toJson(it)
val type = Types.newParameterizedType(MutableMap::class.java, String::class.java, String::class.java)
val adapter = moshi.build().adapter<Map<String, String?>>(type)
adapter.fromJson(json).orEmpty()
val json = jsonObject.encodeToString(it)
jsonObject.decodeFromString<Map<String, String?>>(json)
}
val getMonthValue = fun(type: Int, month: Int): Int {
@ -38,9 +39,9 @@ fun AttendanceSummaryResponse.mapAttendanceSummaryList(moshi: Moshi.Builder): Li
return (1..12).map {
AttendanceSummary(
Month.of(if (it < 5) 8 + it else it - 4),
getMonthValue(0, it), getMonthValue(1, it), getMonthValue(2, it), getMonthValue(3, it),
getMonthValue(4, it), getMonthValue(5, it), getMonthValue(6, it)
month = Month.of(if (it < 5) 8 + it else it - 4),
presence = getMonthValue(0, it), absence = getMonthValue(1, it), absenceExcused = getMonthValue(2, it), absenceForSchoolReasons = getMonthValue(3, it),
lateness = getMonthValue(4, it), latenessExcused = getMonthValue(5, it), exemption = getMonthValue(6, it)
)
}.filterNot { summary ->
summary.absence == 0 &&

View file

@ -1,15 +1,17 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class AttendanceRequest(
@Json(name = "data")
val date: Date,
@SerialName("data")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "idTypWpisuFrekwencji")
@SerialName("idTypWpisuFrekwencji")
val typeId: Int = -1
)

View file

@ -1,17 +1,17 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class AttendanceResponse(
@Json(name = "UsprawiedliwieniaAktywne")
@SerialName("UsprawiedliwieniaAktywne")
val excuseActive: Boolean,
@Json(name = "Frekwencje")
@SerialName("Frekwencje")
val lessons: List<Attendance>,
@Json(name = "UsprawiedliwieniaWyslane")
@SerialName("UsprawiedliwieniaWyslane")
val sentExcuses: List<SentExcuse>
)

View file

@ -1,10 +1,10 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class AttendanceSummaryRequest(
@Json(name = "idPrzedmiot")
@SerialName("idPrzedmiot")
val id: Int?
)

View file

@ -1,63 +1,60 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
class AttendanceSummaryResponse {
@Json(name = "Podsumowanie")
var percentage: Double = .0
@Json(name = "Statystyki")
@SerialName("Statystyki")
var items: List<Summary> = emptyList()
@JsonClass(generateAdapter = true)
@Serializable
data class Summary(
@Json(name = "Id")
@SerialName("Id")
val id: Int,
@Json(name = "NazwaTypuFrekwencji")
@SerialName("NazwaTypuFrekwencji")
val type: String,
@Json(name = "Wrzesien")
@SerialName("Wrzesien")
val september: Int?,
@Json(name = "Pazdziernik")
@SerialName("Pazdziernik")
val october: Int?,
@Json(name = "Listopad")
@SerialName("Listopad")
val november: Int?,
@Json(name = "Grudzien")
@SerialName("Grudzien")
val december: Int?,
@Json(name = "Styczen")
@SerialName("Styczen")
val january: Int?,
@Json(name = "Luty")
@SerialName("Luty")
val february: Int?,
@Json(name = "Marzec")
@SerialName("Marzec")
val march: Int?,
@Json(name = "Kwiecien")
@SerialName("Kwiecien")
val april: Int?,
@Json(name = "Maj")
@SerialName("Maj")
val may: Int?,
@Json(name = "Czerwiec")
@SerialName("Czerwiec")
val june: Int?,
@Json(name = "Lipiec")
@SerialName("Lipiec")
val july: Int?,
@Json(name = "Sierpien")
@SerialName("Sierpien")
val august: Int?,
@Json(name = "Razem")
@SerialName("Razem")
val total: Int?
)
}

View file

@ -1,19 +1,21 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
class SentExcuse {
@Json(name = "Status")
@SerialName("Status")
var status: Int = 0
@Json(name = "Dzien")
lateinit var date: Date
@SerialName("Dzien")
@Serializable(with = CustomDateAdapter::class)
lateinit var date: LocalDateTime
@Json(name = "IdPoraLekcji")
@SerialName("IdPoraLekcji")
var timeId: Int? = null
enum class Status(val id: Int) {

View file

@ -1,14 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class Subject(
@Json(name = "Nazwa")
@SerialName("Nazwa")
var name: String = "Wszystkie",
@Json(name = "Id")
@SerialName("Id")
var value: Int = -1
)

View file

@ -1,28 +1,29 @@
package io.github.wulkanowy.sdk.scrapper.conferences
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Conference(
@Json(name = "Tytul")
@SerialName("Tytul")
val title: String,
@Json(name = "TematZebrania")
@SerialName("TematZebrania")
val subject: String,
@Json(name = "Agenda")
@SerialName("Agenda")
val agenda: String,
@Json(name = "ObecniNaZebraniu")
@SerialName("ObecniNaZebraniu")
val presentOnConference: String,
@Json(name = "ZebranieOnline")
val online: Any?,
@SerialName("ZebranieOnline")
val online: String?,
@Json(name = "Id")
@SerialName("Id")
val id: Int,
@Transient

View file

@ -1,30 +1,36 @@
package io.github.wulkanowy.sdk.scrapper.exams
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Exam(
@Json(name = "DataModyfikacji")
val entryDate: Date,
@SerialName("DataModyfikacji")
@Serializable(with = CustomDateAdapter::class)
val entryDate: LocalDateTime,
@Json(name = "Nazwa")
@SerialName("Nazwa")
val subject: String,
@Json(name = "Rodzaj")
val type: String,
@SerialName("Rodzaj")
val type: Int,
@Json(name = "Opis")
@SerialName("Opis")
val description: String,
@Json(name = "Pracownik")
@SerialName("Pracownik")
val teacher: String
) {
@Transient
lateinit var date: Date
lateinit var typeName: String
@Transient
lateinit var date: LocalDateTime
@Transient
lateinit var teacherSymbol: String

View file

@ -1,15 +1,17 @@
package io.github.wulkanowy.sdk.scrapper.exams
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class ExamRequest(
@Json(name = "data")
val date: Date,
@SerialName("data")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "rokSzkolny")
@SerialName("rokSzkolny")
val schoolYear: Int
)

View file

@ -1,22 +1,24 @@
package io.github.wulkanowy.sdk.scrapper.exams
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
class ExamResponse {
@Json(name = "SprawdzianyGroupedByDayList")
@SerialName("SprawdzianyGroupedByDayList")
var weeks: List<ExamDay> = emptyList()
@JsonClass(generateAdapter = true)
@Serializable
class ExamDay {
@Json(name = "Data")
lateinit var date: Date
@SerialName("Data")
@Serializable(with = CustomDateAdapter::class)
lateinit var date: LocalDateTime
@Json(name = "Sprawdziany")
@SerialName("Sprawdziany")
lateinit var exams: List<Exam>
}
}

View file

@ -1,6 +1,5 @@
package io.github.wulkanowy.sdk.scrapper.exams
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import java.time.LocalDate
fun List<ExamResponse>.mapExamsList(startDate: LocalDate, endDate: LocalDate?): List<Exam> {
@ -12,13 +11,13 @@ fun List<ExamResponse>.mapExamsList(startDate: LocalDate, endDate: LocalDate?):
exam.copy(
teacher = teacherAndSymbol.first(),
subject = exam.subject,
type = when (exam.type) {
"1" -> "Sprawdzian"
"2" -> "Kartkówka"
else -> "Praca klasowa"
}
).apply {
date = day.date
typeName = when (exam.type) {
1 -> "Sprawdzian"
2 -> "Kartkówka"
else -> "Praca klasowa"
}
teacherSymbol = teacherAndSymbol.last().removeSuffix("]")
}

View file

@ -1,31 +1,34 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.GradeDateDeserializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDate
@JsonClass(generateAdapter = true)
@Serializable
data class Grade(
@Json(name = "Wpis")
@SerialName("Wpis")
val entry: String = "",
@Json(name = "KolorOceny") // dec
val color: String = "",
@SerialName("KolorOceny") // dec
val color: Int = -1,
@Json(name = "KodKolumny")
@SerialName("KodKolumny")
val symbol: String? = "",
@Json(name = "NazwaKolumny")
@SerialName("NazwaKolumny")
val description: String? = "",
@Json(name = "Waga")
@SerialName("Waga")
val weightValue: Double = .0,
@Json(name = "DataOceny")
internal val privateDate: GradeDate,
@SerialName("DataOceny")
@Serializable(with = GradeDateDeserializer::class)
internal val privateDate: LocalDate,
@Json(name = "Nauczyciel")
@SerialName("Nauczyciel")
val teacher: String = ""
) {
@ -45,11 +48,8 @@ data class Grade(
var weight: String = ""
@Transient
var date: Date = Date()
}
var colorHex: String = ""
class GradeDate : Date() {
companion object {
const val FORMAT = "dd.MM.yyyy"
}
@Transient
lateinit var date: LocalDate
}

View file

@ -1,24 +1,24 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GradePointsSummaryResponse(
@Json(name = "Items")
@SerialName("Items")
val items: List<GradePointsSummary>
)
@JsonClass(generateAdapter = true)
@Serializable
data class GradePointsSummary(
@Json(name = "Subject")
@SerialName("Subject")
val subject: String,
@Json(name = "Value1")
@SerialName("Value1")
val others: Double,
@Json(name = "Value2")
@SerialName("Value2")
val student: Double
)

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GradeRequest(
@Json(name = "okres")
@SerialName("okres")
val semesterId: Int?
)

View file

@ -22,12 +22,12 @@ fun GradesResponse.mapGradesList() = gradesWithSubjects.map { gradesSubject ->
else -> removeSurrounding("(", ")")
}
},
color = if ("0" == grade.color) "000000" else grade.color.toInt().toString(16).uppercase(),
symbol = grade.symbol.orEmpty(),
description = grade.description.orEmpty(),
weightValue = if (isGradeValid(gradeEntryWithoutComment)) grade.weightValue else .0,
teacher = grade.teacher
).apply {
colorHex = if (0 == grade.color) "000000" else grade.color.toString(16).uppercase()
subject = gradesSubject.name
comment = gradeEntryWithoutComment.run {
when {

View file

@ -1,52 +1,52 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GradesResponse(
@Json(name = "IsSrednia")
@SerialName("IsSrednia")
val isAverage: Boolean,
@Json(name = "IsPunkty")
@SerialName("IsPunkty")
val isPoints: Boolean,
@Json(name = "Oceny")
@SerialName("Oceny")
val gradesWithSubjects: List<Subject>
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Subject(
@Json(name = "WidocznyPrzedmiot")
@SerialName("WidocznyPrzedmiot")
val visibleSubject: Boolean = false,
@Json(name = "Pozycja")
@SerialName("Pozycja")
val order: Int = 0,
@Json(name = "Przedmiot")
@SerialName("Przedmiot")
val name: String = "",
@Json(name = "Srednia")
@SerialName("Srednia")
val average: Double = .0,
@Json(name = "ProponowanaOcenaRoczna")
@SerialName("ProponowanaOcenaRoczna")
val proposed: String? = "",
@Json(name = "OcenaRoczna")
@SerialName("OcenaRoczna")
val annual: String? = "",
@Json(name = "SumaPunktow")
@SerialName("SumaPunktow")
val pointsSum: String? = "",
@Json(name = "ProponowanaOcenaRocznaPunkty")
@SerialName("ProponowanaOcenaRocznaPunkty")
val proposedPoints: String? = "",
@Json(name = "OcenaRocznaPunkty")
@SerialName("OcenaRocznaPunkty")
val finalPoints: String? = "",
@Json(name = "OcenyCzastkowe")
@SerialName("OcenyCzastkowe")
val grades: List<Grade> = emptyList()
)
}

View file

@ -1,44 +1,45 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@JsonClass(generateAdapter = true)
@Serializable
data class GradesStatisticsPartial(
@Json(name = "Subject")
@SerialName("Subject")
val subject: String,
@Json(name = "IsAverage")
@SerialName("IsAverage")
val isAverage: Boolean,
@Json(name = "ClassSeries")
@SerialName("ClassSeries")
val classSeries: GradeStatisticsPartialSeries,
@Json(name = "StudentSeries")
@SerialName("StudentSeries")
val studentSeries: GradeStatisticsPartialSeries
)
@JsonClass(generateAdapter = true)
@Serializable
data class GradeStatisticsPartialSeries(
@Json(name = "Average")
@SerialName("Average")
val average: String?,
@Json(name = "IsEmpty")
@SerialName("IsEmpty")
val isEmpty: Boolean,
@Json(name = "Items")
@SerialName("Items")
val items: List<GradeStatisticsPartialItem>?
)
@JsonClass(generateAdapter = true)
@Serializable
data class GradeStatisticsPartialItem(
@Json(name = "Label")
@SerialName("Label")
val label: String,
@Json(name = "Value")
@SerialName("Value")
val amount: Int? = 0
) {

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GradesStatisticsRequest(
@Json(name = "idOkres")
@SerialName( "idOkres")
val semesterId: Int
)

View file

@ -1,31 +1,32 @@
package io.github.wulkanowy.sdk.scrapper.grades
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@JsonClass(generateAdapter = true)
@Serializable
data class GradesStatisticsSemester(
@Json(name = "Subject")
@SerialName("Subject")
val subject: String,
@Json(name = "IsEmpty")
@SerialName("IsEmpty")
val isEmpty: Boolean,
@Json(name = "Items")
@SerialName("Items")
val items: List<GradesStatisticsSemesterSubItem>?
)
@JsonClass(generateAdapter = true)
@Serializable
data class GradesStatisticsSemesterSubItem(
@Json(name = "Label")
@SerialName("Label")
internal val label: String,
@Json(name = "Description")
@SerialName("Description")
internal val description: String,
@Json(name = "Value")
@SerialName("Value")
val amount: Int
) {

View file

@ -1,20 +1,20 @@
package io.github.wulkanowy.sdk.scrapper.home
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GovernmentMember(
@Json(name = "Name")
@SerialName("Name")
val name: String,
@Json(name = "Position")
@SerialName("Position")
val position: String,
@Json(name = "Division")
@SerialName("Division")
val division: String,
@Json(name = "Id")
@SerialName("Id")
val id: Int
)

View file

@ -1,14 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.home
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class GovernmentUnit(
@Json(name = "UnitName")
@SerialName( "UnitName")
val unitName: String,
@Json(name = "People")
@SerialName( "People")
val people: List<GovernmentMember>
)

View file

@ -1,32 +1,32 @@
package io.github.wulkanowy.sdk.scrapper.home
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class HomepageTileResponse(
@Json(name = "IkonkaNazwa")
@SerialName("IkonkaNazwa")
val iconName: String?,
@Json(name = "Num")
@SerialName("Num")
val number: Int?,
@Json(name = "Zawartosc")
@SerialName("Zawartosc")
val content: List<HomepageTileResponse>,
@Json(name = "Nazwa")
@SerialName("Nazwa")
val name: String,
@Json(name = "Url")
@SerialName("Url")
val url: String?,
@Json(name = "Dane")
@SerialName("Dane")
val data: String?,
@Json(name = "Symbol")
@SerialName("Symbol")
val symbol: String?,
@Json(name = "Nieaktywny")
@SerialName("Nieaktywny")
val inactive: Boolean
)

View file

@ -1,37 +1,41 @@
package io.github.wulkanowy.sdk.scrapper.homework
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Homework(
@Json(name = "HomeworkId")
@SerialName("HomeworkId")
val homeworkId: Int,
@Json(name = "Subject")
@SerialName("Subject")
val subject: String,
@Json(name = "Teacher")
@SerialName("Teacher")
val teacher: String,
@Json(name = "Description")
@SerialName("Description")
val content: String,
@Json(name = "Date")
val date: Date,
@SerialName("Date")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "ModificationDate")
val entryDate: Date,
@SerialName("ModificationDate")
@Serializable(with = CustomDateAdapter::class)
val entryDate: LocalDateTime,
@Json(name = "Status")
val status: String,
@SerialName("Status")
val status: Int,
@Json(name = "AnswerRequired")
@SerialName("AnswerRequired")
val isAnswerRequired: Boolean,
@Json(name = "Attachments")
@SerialName("Attachments")
val attachments: List<HomeworkAttachment>
) {

View file

@ -1,26 +1,26 @@
package io.github.wulkanowy.sdk.scrapper.homework
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class HomeworkAttachment(
@Json(name = "IdZadanieDomowe")
@SerialName("IdZadanieDomowe")
val homeworkId: Int,
@Json(name = "HtmlTag")
@SerialName("HtmlTag")
val html: String,
@Json(name = "Url")
@SerialName("Url")
val url: String,
@Json(name = "NazwaPliku")
@SerialName("NazwaPliku")
val filename: String,
@Json(name = "IdOneDrive")
@SerialName("IdOneDrive")
val oneDriveId: String,
@Json(name = "Id")
@SerialName("Id")
val id: Int
)

View file

@ -1,18 +1,20 @@
package io.github.wulkanowy.sdk.scrapper.homework
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class HomeworkDay(
@Json(name = "Date")
val date: Date,
@SerialName("Date")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "Homework")
@SerialName("Homework")
val items: List<Homework>,
@Json(name = "Show")
@SerialName("Show")
val show: Boolean
)

View file

@ -1,6 +1,5 @@
package io.github.wulkanowy.sdk.scrapper.homework
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import org.jsoup.parser.Parser
import java.time.LocalDate

View file

@ -1,18 +1,20 @@
package io.github.wulkanowy.sdk.scrapper.homework
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class HomeworkRequest(
@Json(name = "date")
val date: Date,
@SerialName("date")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "schoolYear")
@SerialName("schoolYear")
val schoolYear: Int,
@Json(name = "statusFilter")
@SerialName("statusFilter")
val statusFilter: Int
)

View file

@ -1,23 +1,23 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class Attachment(
@Json(name = "Url")
@SerialName("Url")
val url: String,
@Json(name = "IdOneDrive")
@SerialName("IdOneDrive")
val oneDriveId: String,
@Json(name = "IdWiadomosc")
@SerialName("IdWiadomosc")
val messageId: Int,
@Json(name = "NazwaPliku")
@SerialName("NazwaPliku")
val filename: String,
@Json(name = "Id")
@SerialName("Id")
val id: Int
)

View file

@ -1,14 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class DeleteMessageRequest(
@Json(name = "folder")
@SerialName("folder")
val folder: Int,
@Json(name = "messages")
@SerialName("messages")
val messages: List<Int>
)

View file

@ -1,49 +1,51 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Message(
@Json(name = "Id")
@SerialName("Id")
val id: Int?,
@Json(name = "Nieprzeczytana")
@SerialName("Nieprzeczytana")
val unread: Boolean?,
@Json(name = "Nieprzeczytane")
@SerialName("Nieprzeczytane")
val unreadBy: Int?,
@Json(name = "Przeczytane")
@SerialName("Przeczytane")
val readBy: Int?,
@Json(name = "Data")
val date: Date?,
@SerialName("Data")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime?,
@Json(name = "Tresc")
@SerialName("Tresc")
val content: String?,
@Json(name = "Temat")
@SerialName("Temat")
val subject: String?,
@Json(name = "Nadawca")
@SerialName("Nadawca")
val sender: Recipient?,
@Json(name = "IdWiadomosci")
@SerialName("IdWiadomosci")
val messageId: Int?,
@Json(name = "HasZalaczniki")
@SerialName("HasZalaczniki")
val hasAttachments: Boolean = false,
@Json(name = "FolderWiadomosci")
@SerialName("FolderWiadomosci")
val folderId: Int = 0,
@Json(name = "Adresaci")
@SerialName("Adresaci")
val recipients: List<Recipient>?,
@Json(name = "Zalaczniki")
@SerialName("Zalaczniki")
val attachments: List<Attachment>? = emptyList() // nullable just to make sure it doesn't break anything
) {
var removed: Boolean = false

View file

@ -1,27 +1,28 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@JsonClass(generateAdapter = true)
@Serializable
data class Recipient(
@Json(name = "Id")
@SerialName("Id")
val id: String,
@Json(name = "Name")
@SerialName("Name")
val name: String,
@Json(name = "IdLogin")
@SerialName("IdLogin")
val loginId: Int,
@Json(name = "UnitId")
@SerialName("UnitId")
val reportingUnitId: Int?,
@Json(name = "Role")
@SerialName("Role")
val role: Int,
@Json(name = "Hash")
@SerialName("Hash")
val hash: String,
@Transient

View file

@ -1,32 +1,32 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class RecipientsRequest(
@Json(name = "paramsVo")
@SerialName("paramsVo")
val paramsVo: ParamsVo
) {
@JsonClass(generateAdapter = true)
@Serializable
data class ParamsVo(
@Json(name = "IdJednostkaSprawozdawcza")
@SerialName("IdJednostkaSprawozdawcza")
val unitId: Int,
@Json(name = "IdOddzial")
@SerialName("IdOddzial")
val classId: Int? = null,
@Json(name = "IdPrzedszkoleOddzial")
@SerialName("IdPrzedszkoleOddzial")
val kindergartenClassId: Int? = null,
@Json(name = "IdWychowankowieOddzial")
@SerialName("IdWychowankowieOddzial")
val studentsClassId: Int? = null,
@Json(name = "Poziom")
@SerialName("Poziom")
val level: Int? = null,
@Json(name = "Rola")
@SerialName("Rola")
val role: Int
)
}

View file

@ -1,23 +1,23 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class ReportingUnit(
@Json(name = "IdJednostkaSprawozdawcza")
@SerialName("IdJednostkaSprawozdawcza")
val unitId: Int = 0,
@Json(name = "Skrot")
@SerialName("Skrot")
val short: String = "",
@Json(name = "Id")
@SerialName("Id")
val senderId: Int = 0,
@Json(name = "Role")
@SerialName("Role")
val roles: List<Int> = emptyList(),
@Json(name = "NazwaNadawcy")
@SerialName("NazwaNadawcy")
val senderName: String = ""
)

View file

@ -1,35 +1,35 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class SendMessageRequest(
@Json(name = "incoming")
@SerialName("incoming")
val incoming: Incoming,
@Json(name = "incomming")
@SerialName("incomming")
val incomming: Incoming // for compatibility sake
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Incoming(
@Json(name = "Adresaci")
@SerialName("Adresaci")
val recipients: List<Recipient>,
@Json(name = "Id")
@SerialName("Id")
val id: Int = 0,
@Json(name = "Nadawca")
@SerialName("Nadawca")
val sender: Sender = Sender(),
@Json(name = "Temat")
@SerialName("Temat")
val subject: String,
@Json(name = "Tresc")
@SerialName("Tresc")
val content: String
)
}

View file

@ -1,26 +1,26 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class Sender(
@Json(name = "Id")
@SerialName("Id")
val id: String? = null,
@Json(name = "Name")
@SerialName("Name")
val name: String? = null,
@Json(name = "IdLogin")
@SerialName("IdLogin")
val loginId: Int? = null,
@Json(name = "UnitId")
@SerialName("UnitId")
val reportingUnitId: Int? = null,
@Json(name = "Role")
@SerialName("Role")
val role: Int? = null,
@Json(name = "Hash")
@SerialName("Hash")
val hash: String? = null
)

View file

@ -1,26 +1,26 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class SentMessage(
@Json(name = "Adresaci")
@SerialName("Adresaci")
val recipients: List<Recipient>,
@Json(name = "Temat")
@SerialName("Temat")
val subject: String,
@Json(name = "Tresc")
@SerialName("Tresc")
val content: String,
@Json(name = "Nadawca")
@SerialName("Nadawca")
val sender: Sender,
@Json(name = "WiadomoscPowitalna")
@SerialName("WiadomoscPowitalna")
val isWelcomeMessage: Boolean,
@Json(name = "Id")
@SerialName("Id")
val id: Int
)

View file

@ -1,24 +1,27 @@
package io.github.wulkanowy.sdk.scrapper.mobile
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Device(
@Json(name = "Id")
@SerialName("Id")
val id: Int = 0,
@Json(name = "IdentyfikatorUrzadzenia")
@SerialName("IdentyfikatorUrzadzenia")
val deviceId: String? = null,
@Json(name = "NazwaUrzadzenia")
@SerialName("NazwaUrzadzenia")
val name: String? = null,
@Json(name = "DataUtworzenia")
val createDate: Date? = null,
@SerialName("DataUtworzenia")
@Serializable(with = CustomDateAdapter::class)
val createDate: LocalDateTime? = null,
@Json(name = "DataModyfikacji")
val modificationDate: Date? = null
@SerialName("DataModyfikacji")
@Serializable(with = CustomDateAdapter::class)
val modificationDate: LocalDateTime? = null
)

View file

@ -1,20 +1,20 @@
package io.github.wulkanowy.sdk.scrapper.mobile
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class TokenResponse(
@Json(name = "TokenKey")
@SerialName("TokenKey")
val token: String,
@Json(name = "CustomerGroup")
@SerialName("CustomerGroup")
val symbol: String,
@Json(name = "PIN")
@SerialName("PIN")
val pin: String,
@Json(name = "QrCodeImage")
@SerialName("QrCodeImage")
val qrCodeImage: String
)

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.mobile
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class UnregisterDeviceRequest(
@Json(name = "id")
@SerialName("id")
val id: Int
)

View file

@ -1,31 +1,34 @@
package io.github.wulkanowy.sdk.scrapper.notes
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Note(
@Json(name = "DataWpisu")
val date: Date,
@SerialName("DataWpisu")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "Nauczyciel")
@SerialName("Nauczyciel")
val teacher: String,
@Json(name = "Kategoria")
@SerialName("Kategoria")
val category: String,
@Json(name = "TrescUwagi")
@SerialName("TrescUwagi")
val content: String,
@Json(name = "Punkty")
@SerialName("Punkty")
val points: String = "",
@Json(name = "PokazPunkty")
@SerialName("PokazPunkty")
val showPoints: Boolean = false,
@Json(name = "KategoriaTyp")
@SerialName("KategoriaTyp")
val categoryType: Int = 0
) {

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.notes
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class NotesResponse(
@Json(name = "Uwagi")
@SerialName("Uwagi")
val notes: List<Note> = emptyList()
)

View file

@ -1,151 +1,156 @@
package io.github.wulkanowy.sdk.scrapper.register
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class Diary(
@Json(name = "Id")
@SerialName("Id")
val id: Int,
@Json(name = "IdUczen")
@SerialName("IdUczen")
val studentId: Int,
@Json(name = "UczenImie")
@SerialName("UczenImie")
val studentName: String,
@Json(name = "UczenImie2")
@SerialName("UczenImie2")
val studentSecondName: String?,
@Json(name = "UczenNazwisko")
@SerialName("UczenNazwisko")
val studentSurname: String,
@Json(name = "UczenPseudonim")
@SerialName("UczenPseudonim")
val studentNick: String?,
@Json(name = "IsDziennik")
@SerialName("IsDziennik")
val isDiary: Boolean,
@Json(name = "IdDziennik")
@SerialName("IdDziennik")
val diaryId: Int,
@Json(name = "IdPrzedszkoleDziennik")
@SerialName("IdPrzedszkoleDziennik")
val kindergartenDiaryId: Int,
@Json(name = "IdWychowankowieDziennik")
@SerialName("IdWychowankowieDziennik")
val fosterDiaryId: Int?,
@Json(name = "Poziom")
@SerialName("Poziom")
val level: Int,
@Json(name = "Symbol")
@SerialName("Symbol")
val symbol: String?,
@Json(name = "Nazwa")
@SerialName("Nazwa")
val name: String?,
@Json(name = "DziennikRokSzkolny")
@SerialName("DziennikRokSzkolny")
val year: Int,
@Json(name = "Okresy")
@SerialName("Okresy")
val semesters: List<Semester>? = emptyList(),
@Json(name = "UczenOddzialOkresy")
val classSemesters: List<Any>? = emptyList(),
// @SerialName("UczenOddzialOkresy")
// val classSemesters: List<Any>? = emptyList(),
@Json(name = "DziennikDataOd")
val start: Date,
@Serializable(with = CustomDateAdapter::class)
@SerialName("DziennikDataOd")
val start: LocalDateTime,
@Json(name = "DziennikDataDo")
val end: Date,
@Serializable(with = CustomDateAdapter::class)
@SerialName("DziennikDataDo")
val end: LocalDateTime,
@Json(name = "IdJednostkaSkladowa")
@SerialName("IdJednostkaSkladowa")
val componentUnitId: Int?,
@Json(name = "IdSioTyp")
@SerialName("IdSioTyp")
val sioTypeId: Int?,
@Json(name = "IsDorosli")
@SerialName("IsDorosli")
val isAdults: Boolean?,
@Json(name = "IsPolicealna")
@SerialName("IsPolicealna")
val isPostSecondary: Boolean?,
@Json(name = "Is13")
@SerialName("Is13")
val is13: Boolean?,
@Json(name = "IsArtystyczna")
@SerialName("IsArtystyczna")
val isArtistic: Boolean?,
@Json(name = "IsArtystyczna13")
@SerialName("IsArtystyczna13")
val isArtistic13: Boolean?,
@Json(name = "IsSpecjalny")
@SerialName("IsSpecjalny")
val isSpecial: Boolean?,
@Json(name = "IsPrzedszkola")
@SerialName("IsPrzedszkola")
val isKindergarten: Boolean?,
@Json(name = "IsWychowankowie")
@SerialName("IsWychowankowie")
val isFoster: Boolean?,
@Json(name = "IsArchiwalny")
@SerialName("IsArchiwalny")
val isArchived: Boolean?,
@Json(name = "IsOplaty")
@SerialName("IsOplaty")
val isCharges: Boolean?,
@Json(name = "IsPlatnosci")
@SerialName("IsPlatnosci")
val isPayments: Boolean?,
@Json(name = "IsPayButtonOn")
@SerialName("IsPayButtonOn")
val isPayButtonOn: Boolean?,
@Json(name = "CanMergeAccounts")
@SerialName("CanMergeAccounts")
val canMergeAccounts: Boolean?,
@Json(name = "UczenPelnaNazwa")
@SerialName("UczenPelnaNazwa")
val fullName: String,
@Json(name = "O365PassType")
@SerialName("O365PassType")
val o365PassType: Int?,
@Json(name = "IsAdult")
@SerialName("IsAdult")
val isAdult: Boolean?,
@Json(name = "IsAuthorized")
@SerialName("IsAuthorized")
val isAuthorized: Boolean?,
@Json(name = "Obywatelstwo")
@SerialName("Obywatelstwo")
val citizenship: Int?,
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Semester(
@Json(name = "NumerOkresu")
@SerialName("NumerOkresu")
val number: Int,
@Json(name = "Poziom")
@SerialName("Poziom")
val level: Int,
@Json(name = "DataOd")
val start: Date,
@SerialName("DataOd")
@Serializable(with = CustomDateAdapter::class)
val start: LocalDateTime,
@Json(name = "DataDo")
val end: Date,
@SerialName("DataDo")
@Serializable(with = CustomDateAdapter::class)
val end: LocalDateTime,
@Json(name = "IdOddzial")
@SerialName("IdOddzial")
val classId: Int,
@Json(name = "IdJednostkaSprawozdawcza")
@SerialName("IdJednostkaSprawozdawcza")
val unitId: Int,
@Json(name = "IsLastOkres")
@SerialName("IsLastOkres")
val isLast: Boolean,
@Json(name = "Id")
val id: Int
@SerialName("Id")
val id: Int,
)
}

View file

@ -1,56 +1,56 @@
package io.github.wulkanowy.sdk.scrapper.register
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class Permission(
@Json(name = "AuthInfos")
@SerialName("AuthInfos")
val authInfos: List<AuthInfo>,
@Json(name = "Units")
@SerialName("Units")
val units: List<Unit>
)
@JsonClass(generateAdapter = true)
@Serializable
data class AuthInfo(
@Json(name = "JednostkaSprawozdawczaId")
@SerialName("JednostkaSprawozdawczaId")
val unitId: Int,
@Json(name = "LinkedAccountUids")
@SerialName("LinkedAccountUids")
val linkedAccountUids: List<Int>,
@Json(name = "LoginId")
@SerialName("LoginId")
val loginId: Int,
@Json(name = "LoginValue")
@SerialName("LoginValue")
val loginValue: String,
@Json(name = "OpiekunIds")
@SerialName("OpiekunIds")
val parentIds: List<Int>,
@Json(name = "PracownikIds")
@SerialName("PracownikIds")
val employeeIds: List<Int>,
@Json(name = "Roles")
@SerialName("Roles")
val roles: List<Int>,
@Json(name = "UczenIds")
@SerialName("UczenIds")
val studentIds: List<Int>
)
@JsonClass(generateAdapter = true)
@Serializable
data class Unit(
@Json(name = "Id")
@SerialName("Id")
val id: Int,
@Json(name = "Nazwa")
@SerialName("Nazwa")
val name: String,
@Json(name = "Skrot")
@SerialName("Skrot")
val short: String,
@Json(name = "Symbol")
@SerialName("Symbol")
val symbol: String
)

View file

@ -1,7 +1,6 @@
package io.github.wulkanowy.sdk.scrapper.repository
import com.migcomponents.migbase64.Base64
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
import io.github.wulkanowy.sdk.scrapper.exception.TemporarilyDisabledException
@ -14,7 +13,6 @@ import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.messages.ReportingUnit
import io.github.wulkanowy.sdk.scrapper.register.Diary
import io.github.wulkanowy.sdk.scrapper.register.Permission
import io.github.wulkanowy.sdk.scrapper.register.PermissionJsonAdapter
import io.github.wulkanowy.sdk.scrapper.register.Student
import io.github.wulkanowy.sdk.scrapper.register.toSemesters
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS
@ -25,6 +23,8 @@ import io.github.wulkanowy.sdk.scrapper.service.MessagesService
import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.jsoup.parser.Parser
@ -48,8 +48,6 @@ class RegisterRepository(
private val logger = LoggerFactory.getLogger(this::class.java)
}
private val moshi by lazy { Moshi.Builder().build() }
suspend fun getStudents(): List<Student> {
return getSymbols().flatMap { (symbol, certificate) ->
val cert = try {
@ -105,6 +103,7 @@ class RegisterRepository(
}
}
}
page.select(SELECTOR_ADFS_CARDS).isNotEmpty() -> Scrapper.LoginType.ADFSCards
else -> throw ScrapperException("Nieznany typ dziennika: ${page.text()}")
}
@ -194,7 +193,7 @@ class RegisterRepository(
private fun getPermissions(homepage: String): Permission? {
val base64 = getScriptParam("permissions", homepage).substringBefore("|")
return Base64.decode(base64).toString(StandardCharsets.UTF_8).takeIf { it.isNotBlank() }?.let {
PermissionJsonAdapter(moshi).fromJson(it)
Json.decodeFromString<Permission>(it)
}
}
}

View file

@ -1,8 +1,5 @@
package io.github.wulkanowy.sdk.scrapper.repository
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.ApiResponseJsonAdapter
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import io.github.wulkanowy.sdk.scrapper.attendance.Absent
import io.github.wulkanowy.sdk.scrapper.attendance.Attendance
import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceExcuseRequest
@ -58,15 +55,12 @@ import io.github.wulkanowy.sdk.scrapper.timetable.mapCompletedLessonsList
import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableAdditional
import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableHeaders
import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableList
import io.github.wulkanowy.sdk.scrapper.toDate
import io.github.wulkanowy.sdk.scrapper.toFormat
import org.jsoup.Jsoup
import java.time.LocalDate
class StudentRepository(private val api: StudentService) {
private val moshi by lazy { Moshi.Builder().add(CustomDateAdapter()) }
private fun LocalDate.toISOFormat(): String = toFormat("yyyy-MM-dd'T00:00:00'")
private suspend fun getCache(): CacheResponse {
@ -85,7 +79,7 @@ class StudentRepository(private val api: StudentService) {
}
suspend fun getAttendance(startDate: LocalDate, endDate: LocalDate?): List<Attendance> {
return api.getAttendance(AttendanceRequest(startDate.toDate()))
return api.getAttendance(AttendanceRequest(startDate.atStartOfDay()))
.handleErrors()
.data?.mapAttendanceList(startDate, endDate, getCache().times).orEmpty()
}
@ -93,7 +87,7 @@ class StudentRepository(private val api: StudentService) {
suspend fun getAttendanceSummary(subjectId: Int?): List<AttendanceSummary> {
return api.getAttendanceStatistics(AttendanceSummaryRequest(subjectId))
.handleErrors()
.data?.mapAttendanceSummaryList(moshi).orEmpty()
.data?.mapAttendanceSummaryList().orEmpty()
}
suspend fun excuseForAbsence(absents: List<Absent>, content: String?): Boolean {
@ -121,7 +115,7 @@ class StudentRepository(private val api: StudentService) {
}
suspend fun getExams(startDate: LocalDate, endDate: LocalDate? = null): List<Exam> {
return api.getExams(ExamRequest(startDate.toDate(), startDate.getSchoolYear()))
return api.getExams(ExamRequest(startDate.atStartOfDay(), startDate.getSchoolYear()))
.handleErrors()
.data.orEmpty().mapExamsList(startDate, endDate)
}
@ -165,7 +159,7 @@ class StudentRepository(private val api: StudentService) {
}
suspend fun getHomework(startDate: LocalDate, endDate: LocalDate? = null): List<Homework> {
return api.getHomework(HomeworkRequest(startDate.toDate(), startDate.getSchoolYear(), -1))
return api.getHomework(HomeworkRequest(startDate.atStartOfDay(), startDate.getSchoolYear(), -1))
.handleErrors()
.data.orEmpty().mapHomework(startDate, endDate)
}
@ -226,9 +220,7 @@ class StudentRepository(private val api: StudentService) {
if (!cache.showCompletedLessons) throw FeatureDisabledException("Widok lekcji zrealizowanych został wyłączony przez Administratora szkoły")
val res = api.getCompletedLessons(CompletedLessonsRequest(start.toISOFormat(), end.toISOFormat(), subjectId))
val adapter = ApiResponseJsonAdapter<Any>(moshi.build(), arrayOf(Any::class.java))
return adapter.fromJson(res)?.handleErrors()?.mapCompletedLessonsList(start, endDate, moshi).orEmpty()
return res.handleErrors().mapCompletedLessonsList(start, endDate)
}
suspend fun getTeachers(): List<Teacher> {

View file

@ -1,23 +1,23 @@
package io.github.wulkanowy.sdk.scrapper.school
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class School(
@Json(name = "Nazwa")
@SerialName("Nazwa")
val name: String,
@Json(name = "Adres")
@SerialName("Adres")
val address: String,
@Json(name = "Kontakt")
@SerialName("Kontakt")
val contact: String,
@Json(name = "Dyrektor")
@SerialName("Dyrektor")
val headmaster: String,
@Json(name = "Pedagog")
@SerialName("Pedagog")
val pedagogue: String
)

View file

@ -1,14 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.school
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
class SchoolAndTeachersResponse {
@Json(name = "Nauczyciele")
@SerialName("Nauczyciele")
var teachers: List<Teacher> = emptyList()
@Json(name = "Szkola")
@SerialName("Szkola")
lateinit var school: School
}

View file

@ -1,15 +1,16 @@
package io.github.wulkanowy.sdk.scrapper.school
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@JsonClass(generateAdapter = true)
@Serializable
data class Teacher(
@Json(name = "Nauczyciel")
@SerialName("Nauczyciel")
val name: String,
@Json(name = "Nazwa")
@SerialName("Nazwa")
val subject: String
) {

View file

@ -1,25 +1,28 @@
package io.github.wulkanowy.sdk.scrapper.service
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
import io.github.wulkanowy.sdk.scrapper.TLSSocketFactory
import io.github.wulkanowy.sdk.scrapper.adapter.GradeDateDeserializer
import io.github.wulkanowy.sdk.scrapper.adapter.ObjectSerializer
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
import io.github.wulkanowy.sdk.scrapper.interceptor.AutoLoginInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.HttpErrorInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.StudentCookieInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.UserAgentInterceptor
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import okhttp3.Interceptor
import okhttp3.JavaNetCookieJar
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.create
import java.net.CookieManager
@ -64,6 +67,18 @@ class ServiceManager(
UrlGenerator(schema, host, symbol, schoolSymbol)
}
@OptIn(ExperimentalSerializationApi::class)
val json by lazy {
Json {
explicitNulls = false
ignoreUnknownKeys = true
coerceInputValues = true
serializersModule = SerializersModule {
contextual(ObjectSerializer)
}
}
}
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf(
HttpLoggingInterceptor().setLevel(logLevel) to true,
ErrorInterceptor() to false,
@ -155,17 +170,14 @@ class ServiceManager(
return getRetrofit(getClientBuilder(), urlGenerator.generate(UrlGenerator.Site.HOME), gson = true).create()
}
@OptIn(ExperimentalSerializationApi::class)
private fun getRetrofit(client: OkHttpClient.Builder, baseUrl: String, gson: Boolean = false) = Retrofit.Builder()
.baseUrl(baseUrl)
.client(client.build())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(
if (gson) MoshiConverterFactory.create(
Moshi.Builder()
.add(CustomDateAdapter())
.add(GradeDateDeserializer())
.build()
) else JspoonConverterFactory.create()
if (gson) json.asConverterFactory("application/json".toMediaType())
else JspoonConverterFactory.create()
)
.build()

View file

@ -27,6 +27,7 @@ import io.github.wulkanowy.sdk.scrapper.school.SchoolAndTeachersResponse
import io.github.wulkanowy.sdk.scrapper.student.StudentInfo
import io.github.wulkanowy.sdk.scrapper.student.StudentPhoto
import io.github.wulkanowy.sdk.scrapper.timetable.CacheResponse
import io.github.wulkanowy.sdk.scrapper.timetable.CompletedLesson
import io.github.wulkanowy.sdk.scrapper.timetable.CompletedLessonsRequest
import io.github.wulkanowy.sdk.scrapper.timetable.TimetableRequest
import io.github.wulkanowy.sdk.scrapper.timetable.TimetableResponse
@ -47,7 +48,7 @@ interface StudentService {
@Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String,
@Body body: Any = Object()
@Body body: Any = Any()
): ApiResponse<CacheResponse>
@POST("UczenCache.mvc/Get")
@ -55,14 +56,14 @@ interface StudentService {
@Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String,
@Body body: Any = Object()
@Body body: Any = Any()
): ApiResponse<CacheResponse>
@POST
suspend fun getSchoolInfo(@Url url: String, @Body body: Any = Object()): ApiResponse<List<Diary>>
suspend fun getSchoolInfo(@Url url: String, @Body body: Any = Any()): ApiResponse<List<Diary>>
@POST("UczenDziennik.mvc/Get")
suspend fun getDiaries(@Body body: Any = Object()): ApiResponse<List<Diary>>
suspend fun getDiaries(@Body body: Any = Any()): ApiResponse<List<Diary>>
@POST("Oceny.mvc/Get")
suspend fun getGrades(@Body gradeRequest: GradeRequest): ApiResponse<GradesResponse>
@ -83,7 +84,7 @@ interface StudentService {
suspend fun getAttendanceStatistics(@Body attendanceSummaryRequest: AttendanceSummaryRequest): ApiResponse<AttendanceSummaryResponse>
@POST("FrekwencjaStatystykiPrzedmioty.mvc/Get")
suspend fun getAttendanceSubjects(@Body body: Any = Object()): ApiResponse<List<Subject>>
suspend fun getAttendanceSubjects(@Body body: Any = Any()): ApiResponse<List<Subject>>
@POST("Usprawiedliwienia.mvc/Post")
suspend fun excuseForAbsence(
@ -91,7 +92,7 @@ interface StudentService {
@Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String,
@Body attendanceExcuseRequest: AttendanceExcuseRequest
): ApiResponse<Any>
): ApiResponse<ApiResponse<String?>>
@POST("EgzaminyZewnetrzne.mvc/Get")
suspend fun getExternalExaminations()
@ -106,22 +107,22 @@ interface StudentService {
suspend fun getTimetable(@Body timetableRequest: TimetableRequest): ApiResponse<TimetableResponse>
@POST("LekcjeZrealizowane.mvc/GetPrzedmioty")
suspend fun getRealizedSubjects(@Body body: Any = Object())
suspend fun getRealizedSubjects(@Body body: Any = Any())
@POST("LekcjeZrealizowane.mvc/GetZrealizowane")
suspend fun getCompletedLessons(@Body completedLessonsRequest: CompletedLessonsRequest): String
suspend fun getCompletedLessons(@Body completedLessonsRequest: CompletedLessonsRequest): ApiResponse<Map<String, List<CompletedLesson>>>
@POST("UwagiIOsiagniecia.mvc/Get")
suspend fun getNotes(@Body body: Any = Object()): ApiResponse<NotesResponse>
suspend fun getNotes(@Body body: Any = Any()): ApiResponse<NotesResponse>
@POST("Zebrania.mvc/Get")
suspend fun getConferences(): ApiResponse<List<Conference>>
@POST("ZarejestrowaneUrzadzenia.mvc/Get")
suspend fun getRegisteredDevices(@Body body: Any = Object()): ApiResponse<List<Device>>
suspend fun getRegisteredDevices(@Body body: Any = Any()): ApiResponse<List<Device>>
@POST("RejestracjaUrzadzeniaToken.mvc/Get")
suspend fun getToken(@Body body: Any = Object()): ApiResponse<TokenResponse>
suspend fun getToken(@Body body: Any = Any()): ApiResponse<TokenResponse>
@POST("ZarejestrowaneUrzadzenia.mvc/Delete")
suspend fun unregisterDevice(
@ -132,7 +133,7 @@ interface StudentService {
): ApiResponse<Any>
@POST("SzkolaINauczyciele.mvc/Get")
suspend fun getSchoolAndTeachers(@Body body: Any = Object()): ApiResponse<SchoolAndTeachersResponse>
suspend fun getSchoolAndTeachers(@Body body: Any = Any()): ApiResponse<SchoolAndTeachersResponse>
@POST("Uczen.mvc/Get")
suspend fun getStudentInfo(): ApiResponse<StudentInfo>

View file

@ -1,41 +1,41 @@
package io.github.wulkanowy.sdk.scrapper.student
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class StudentGuardian(
@Json(name = "Id")
@SerialName("Id")
val id: Int,
@Json(name = "Imie")
@SerialName("Imie")
val name: String,
@Json(name = "Nazwisko")
@SerialName("Nazwisko")
val lastName: String,
@Json(name = "StPokrewienstwa")
@SerialName("StPokrewienstwa")
val kinship: String?,
@Json(name = "Adres")
@SerialName("Adres")
val address: String,
@Json(name = "TelDomowy")
@SerialName("TelDomowy")
val homePhone: String?,
@Json(name = "TelKomorkowy")
@SerialName("TelKomorkowy")
val cellPhone: String?,
@Json(name = "TelSluzbowy")
@SerialName("TelSluzbowy")
val workPhone: String?,
@Json(name = "Email")
@SerialName("Email")
val email: String?,
@Json(name = "FullName")
@SerialName("FullName")
val fullName: String,
@Json(name = "Telefon")
@SerialName("Telefon")
val phone: String
)

View file

@ -1,84 +1,86 @@
package io.github.wulkanowy.sdk.scrapper.student
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class StudentInfo(
@Json(name = "Imie")
@SerialName("Imie")
val name: String,
@Json(name = "Imie2")
@SerialName("Imie2")
val middleName: String?,
@Json(name = "NumerDokumentu")
val idNumber: Any?,
// @SerialName("NumerDokumentu")
// val idNumber: Any?,
@Json(name = "Nazwisko")
@SerialName("Nazwisko")
val lastName: String,
@Json(name = "DataUrodzenia")
val birthDate: Date,
@SerialName("DataUrodzenia")
@Serializable(with = CustomDateAdapter::class)
val birthDate: LocalDateTime,
@Json(name = "MiejsceUrodzenia")
@SerialName("MiejsceUrodzenia")
val birthPlace: String?,
@Json(name = "NazwiskoRodowe")
@SerialName("NazwiskoRodowe")
val familyName: String?,
@Json(name = "ObywatelstwoPolskie")
@SerialName("ObywatelstwoPolskie")
val polishCitizenship: Int,
@Json(name = "ImieMatki")
@SerialName("ImieMatki")
val motherName: String?,
@Json(name = "ImieOjca")
@SerialName("ImieOjca")
val fatherName: String?,
@Json(name = "Plec")
@SerialName("Plec")
val gender: Boolean,
@Json(name = "AdresZamieszkania")
@SerialName("AdresZamieszkania")
val address: String,
@Json(name = "AdresZameldowania")
@SerialName("AdresZameldowania")
val registeredAddress: String,
@Json(name = "AdresKorespondencji")
@SerialName("AdresKorespondencji")
val correspondenceAddress: String,
@Json(name = "TelDomowy")
@SerialName("TelDomowy")
val homePhone: String?,
@Json(name = "TelKomorkowy")
@SerialName("TelKomorkowy")
val cellPhone: String?,
@Json(name = "Email")
@SerialName("Email")
val email: String?,
@Json(name = "CzyWidocznyPesel")
@SerialName("CzyWidocznyPesel")
val isVisiblePesel: Boolean,
@Json(name = "Opiekun1")
@SerialName("Opiekun1")
val guardianFirst: StudentGuardian?,
@Json(name = "Opiekun2")
@SerialName("Opiekun2")
val guardianSecond: StudentGuardian?,
@Json(name = "UkryteDaneAdresowe")
@SerialName("UkryteDaneAdresowe")
val hideAddress: Boolean,
@Json(name = "ImieNazwisko")
@SerialName("ImieNazwisko")
val fullName: String,
@Json(name = "PosiadaPesel")
@SerialName("PosiadaPesel")
val hasPesel: Boolean,
@Json(name = "Polak")
@SerialName("Polak")
val isPole: Boolean,
@Json(name = "ImieMatkiIOjca")
@SerialName("ImieMatkiIOjca")
val motherAndFatherNames: String?
)

View file

@ -1,23 +1,23 @@
package io.github.wulkanowy.sdk.scrapper.student
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class StudentPhoto(
@Json(name = "Status")
@SerialName("Status")
val status: Long?,
@Json(name = "Error")
val error: Any?,
// @SerialName("Error")
// val error: Any?,
@Json(name = "Warning")
val warning: Any?,
// @SerialName("Warning")
// val warning: Any?,
@Json(name = "ZdjecieBase64")
@SerialName("ZdjecieBase64")
val photoBase64: String?,
@Json(name = "Id")
@SerialName("Id")
val id: Long?,
)

View file

@ -1,46 +1,50 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
class CacheResponse {
@Json(name = "isParentUser")
@SerialName("isParentUser")
var isParent: Boolean = false
@Json(name = "poryLekcji")
@SerialName("poryLekcji")
lateinit var times: List<Time>
@Json(name = "isMenuOn")
@SerialName("isMenuOn")
var isMenu: Boolean = false
@Json(name = "pokazLekcjeZrealizowane")
@SerialName("pokazLekcjeZrealizowane")
var showCompletedLessons: Boolean = false
@JsonClass(generateAdapter = true)
@Serializable
class Time {
@Json(name = "Id")
@SerialName("Id")
var id: Int = 0
@Json(name = "Numer")
@SerialName("Numer")
var number: Int = 0
@Json(name = "Poczatek")
lateinit var start: Date
@SerialName("Poczatek")
@Serializable(with = CustomDateAdapter::class)
lateinit var start: LocalDateTime
@Json(name = "Koniec")
lateinit var end: Date
@SerialName("Koniec")
@Serializable(with = CustomDateAdapter::class)
lateinit var end: LocalDateTime
@Json(name = "DataModyfikacji")
lateinit var modified: Date
@SerialName("DataModyfikacji")
@Serializable(with = CustomDateAdapter::class)
lateinit var modified: LocalDateTime
@Json(name = "IdJednostkaSprawozdawcza")
@SerialName("IdJednostkaSprawozdawcza")
var organizationUnitId: Int = 0
@Json(name = "Nazwa")
@SerialName("Nazwa")
lateinit var name: String
}
}

View file

@ -1,35 +1,37 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
class CompletedLesson {
@Serializable
data class CompletedLesson(
@Json(name = "Data")
lateinit var date: Date
@SerialName("Data")
@Serializable(with = CustomDateAdapter::class)
val date: LocalDateTime,
@Json(name = "NrLekcji")
var number: Int = 0
@SerialName("NrLekcji")
val number: Int = 0,
@Json(name = "Przedmiot")
var subject: String = ""
@SerialName("Przedmiot")
val subject: String? = "",
@Json(name = "Temat")
var topic: String = ""
@SerialName("Temat")
val topic: String? = "",
@Json(name = "Nauczyciel")
var teacher: String = ""
@SerialName("Nauczyciel")
val teacher: String? = "",
var teacherSymbol: String = ""
val teacherSymbol: String? = "",
@Json(name = "Zastepstwo")
var substitution: String = ""
@SerialName("Zastepstwo")
val substitution: String? = "",
@Json(name = "Nieobecnosc")
var absence: String = ""
@SerialName("Nieobecnosc")
val absence: String? = "",
@Json(name = "ZasobyPubliczne")
var resources: String = ""
}
@SerialName("ZasobyPubliczne")
val resources: String? = "",
)

View file

@ -1,17 +1,17 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
class CompletedLessonsRequest(
@Json(name = "poczatek")
@SerialName("poczatek")
val startDate: String,
@Json(name = "koniec")
@SerialName("koniec")
val endDate: String,
@Json(name = "idPrzedmiot")
@SerialName("idPrzedmiot")
val subject: Int = -1
)

View file

@ -1,25 +1,27 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.github.wulkanowy.sdk.scrapper.ApiResponse
import io.github.wulkanowy.sdk.scrapper.toDate
import io.github.wulkanowy.sdk.scrapper.toFormat
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.github.wulkanowy.sdk.scrapper.toLocalTime
import org.jsoup.Jsoup
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
private val parser = TimetableParser()
private val formatter1 = DateTimeFormatter.ofPattern("dd.MM.yyyy")
private val formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
fun TimetableResponse.mapTimetableList(startDate: LocalDate, endDate: LocalDate?) = rows.flatMap { lessons ->
lessons.drop(1).mapIndexed { i, it ->
val times = lessons[0].split("<br />")
val header = headers.drop(1)[i].date.split("<br />")
val date = header[1].toLocalDate("dd.MM.yyyy")
val date = LocalDate.parse(header[1], formatter1)
TimetableCell(
date = date,
start = date.atTime(times[1].toLocalTime()),
end = date.atTime(times[2].toLocalTime()),
start = LocalDateTime.parse("${date.toFormat("yyyy-MM-dd")} ${times[1]}", formatter2),
end = LocalDateTime.parse("${date.toFormat("yyyy-MM-dd")} ${times[2]}", formatter2),
number = times[0].toInt(),
td = Jsoup.parse(it)
)
@ -37,38 +39,28 @@ fun TimetableResponse.mapTimetableHeaders() = headers.drop(1).map {
}
fun TimetableResponse.mapTimetableAdditional() = additional.flatMap { day ->
val date = day.header.substringAfter(", ").toLocalDate("dd.MM.yyyy")
val date = LocalDate.parse(day.header.substringAfter(", "), formatter1)
day.descriptions.map { lesson ->
val description = Jsoup.parse(lesson.description).text()
val startTime = description.substringBefore(" - ")
val endTime = description.split(" ")[2]
TimetableAdditional(
date = date,
start = date.atTime(startTime.toLocalTime()),
end = date.atTime(endTime.toLocalTime()),
start = LocalDateTime.parse("${date.toFormat("yyyy-MM-dd")} $startTime", formatter2),
end = LocalDateTime.parse("${date.toFormat("yyyy-MM-dd")} $endTime", formatter2),
subject = description.substringAfter("$endTime ")
)
}
}
fun ApiResponse<*>.mapCompletedLessonsList(start: LocalDate, endDate: LocalDate?, moshi: Moshi.Builder): List<CompletedLesson> {
val type = Types.newParameterizedType(MutableMap::class.java, String::class.java, List::class.java)
val adapter = moshi.build().adapter<Map<String, List<Map<String, Any>>>>(type)
val mapType = Types.newParameterizedType(List::class.java, MutableMap::class.java)
val mapAdapter = moshi.build().adapter<List<Map<String, Any>>>(mapType)
val lessonType = Types.newParameterizedType(List::class.java, CompletedLesson::class.java)
val completedLessonAdapter = moshi.build().adapter<List<CompletedLesson>>(lessonType)
return adapter.fromJsonValue(data).orEmpty()
.map { it.value }
.map { mapAdapter.toJson(it) }
.flatMap { completedLessonAdapter.fromJson(it).orEmpty() }
fun ApiResponse<Map<String, List<CompletedLesson>>>.mapCompletedLessonsList(start: LocalDate, endDate: LocalDate?): List<CompletedLesson> {
return data.orEmpty()
.flatMap { it.value }
.map {
it.apply {
teacherSymbol = teacher.substringAfter(" [").substringBefore("]")
teacher = teacher.substringBefore(" [")
}
it.copy(
teacherSymbol = it.teacher?.substringAfter(" [")?.substringBefore("]"),
teacher = it.teacher?.substringBefore(" ["),
)
}.sortedWith(compareBy({ it.date }, { it.number })).toList().filter {
it.date.toLocalDate() >= start && it.date.toLocalDate() <= (endDate ?: start.plusDays(4))
}

View file

@ -1,11 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@JsonClass(generateAdapter = true)
@Serializable
data class TimetableRequest(
@Json(name = "data")
@SerialName("data")
val date: String
)

View file

@ -1,45 +1,45 @@
package io.github.wulkanowy.sdk.scrapper.timetable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.jsoup.nodes.Element
import java.time.LocalDate
import java.time.LocalDateTime
@JsonClass(generateAdapter = true)
@Serializable
data class TimetableResponse(
@Json(name = "Headers")
@SerialName("Headers")
val headers: List<TimetableHeader> = emptyList(),
@Json(name = "Rows")
@SerialName("Rows")
val rows: List<List<String>> = emptyList(),
@Json(name = "Additionals")
@SerialName("Additionals")
val additional: List<TimetableAdditionalDay>
)
@JsonClass(generateAdapter = true)
@Serializable
data class TimetableHeader(
@Json(name = "Text")
@SerialName("Text")
val date: String
)
@JsonClass(generateAdapter = true)
@Serializable
data class TimetableAdditionalDay(
@Json(name = "Header")
@SerialName("Header")
val header: String,
@Json(name = "Descriptions")
@SerialName("Descriptions")
val descriptions: List<TimetableAdditionalLesson>
)
@JsonClass(generateAdapter = true)
@Serializable
data class TimetableAdditionalLesson(
@Json(name = "Description")
@SerialName("Description")
val description: String
)

View file

@ -1,8 +1,7 @@
package io.github.wulkanowy.sdk.scrapper
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import io.github.wulkanowy.sdk.scrapper.adapter.GradeDateDeserializer
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import io.github.wulkanowy.sdk.scrapper.adapter.ObjectSerializer
import io.github.wulkanowy.sdk.scrapper.interceptor.AutoLoginInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.HttpErrorInterceptor
@ -10,6 +9,11 @@ import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository
import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.mockwebserver.MockResponse
@ -17,7 +21,6 @@ import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.net.CookieManager
@ -26,7 +29,7 @@ abstract class BaseLocalTest : BaseTest() {
val server = MockWebServer()
fun MockWebServer.enqueue(fileName: String, clazz: Class<*> = this@BaseLocalTest::class.java) {
enqueue(MockResponse().setBody(clazz.getResource(fileName).readText()))
enqueue(MockResponse().setBody(clazz.getResource(fileName)!!.readText()))
}
@After
@ -44,6 +47,18 @@ abstract class BaseLocalTest : BaseTest() {
return StudentRepository(getService(StudentService::class.java, server.url("/").toString(), false, okHttp))
}
@OptIn(ExperimentalSerializationApi::class)
private val json = Json {
explicitNulls = false
ignoreUnknownKeys = true
encodeDefaults = true
isLenient = true
serializersModule = SerializersModule {
contextual(ObjectSerializer)
}
}
@OptIn(ExperimentalSerializationApi::class)
fun <T> getService(
service: Class<T>,
url: String = this.server.url("/").toString(),
@ -53,12 +68,8 @@ abstract class BaseLocalTest : BaseTest() {
.client(okHttp)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(
if (!html) MoshiConverterFactory.create(
Moshi.Builder()
.add(CustomDateAdapter())
.add(GradeDateDeserializer())
.build()
) else JspoonConverterFactory.create()
if (!html) json.asConverterFactory("application/json".toMediaType())
else JspoonConverterFactory.create()
)
.baseUrl(url)
.build()

View file

@ -2,8 +2,6 @@ package io.github.wulkanowy.sdk.scrapper
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.Calendar
import java.util.Date
open class BaseTest {
@ -15,15 +13,7 @@ open class BaseTest {
return LocalDateTime.of(year, month, day, hour, minute, second)
}
fun getDate(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0, mili: Int = 0): Date {
return Calendar.getInstance().apply {
set(Calendar.YEAR, year)
set(Calendar.MONTH, month - 1)
set(Calendar.DAY_OF_MONTH, day)
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minute)
set(Calendar.SECOND, second)
set(Calendar.MILLISECOND, mili)
}.time
fun getDate(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0, mili: Int = 0): LocalDateTime {
return LocalDateTime.of(year, month, day, hour, minute, second)
}
}

View file

@ -177,7 +177,7 @@ class ScrapperRemoteTest : BaseTest() {
assertEquals(getDate(2018, 5, 7), date)
assertEquals(getDate(1970, 1, 1), entryDate)
assertEquals("Matematyka", subject)
assertEquals("Sprawdzian", type)
assertEquals("Sprawdzian", typeName)
assertEquals("Figury na płaszczyźnie.", description)
assertEquals("Aleksandra Krajewska", teacher)
assertEquals("AK", teacherSymbol)
@ -219,12 +219,12 @@ class ScrapperRemoteTest : BaseTest() {
grades[7].run {
assertEquals("Religia", subject)
assertEquals("1", entry)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("Kart", symbol)
assertEquals("", description)
assertEquals("3,00", weight)
assertEquals(3.0, weightValue, .0)
assertEquals(LocalDate.now().toDate(), date)
assertEquals(LocalDate.now(), date)
assertEquals("Michał Mazur", teacher)
}

View file

@ -1,10 +1,10 @@
package io.github.wulkanowy.sdk.scrapper.attendance
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.adapter.CustomDateAdapter
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
@ -165,10 +165,10 @@ class AttendanceTest : BaseLocalTest() {
runBlocking { repo.getAttendance(getLocalDate(2018, 10, 1), null) }
val request = server.takeRequest()
val adapter = AttendanceRequestJsonAdapter(Moshi.Builder().add(CustomDateAdapter()).build())
val requestObject = adapter.fromJson(request.body.readUtf8())
assertEquals(getDate(2018, 10, 1, 0, 0, 0), requestObject?.date)
assertEquals(-1, requestObject?.typeId)
val requestObject = Json.decodeFromString<AttendanceRequest>(request.body.readUtf8())
assertEquals(getDate(2018, 10, 1, 0, 0, 0), requestObject.date)
assertEquals(-1, requestObject.typeId)
}
@Test
@ -205,10 +205,8 @@ class AttendanceTest : BaseLocalTest() {
val request = server.takeRequest()
val adapter = AttendanceExcuseRequestJsonAdapter(Moshi.Builder().build())
val expected = adapter.fromJson(AttendanceTest::class.java.getResource("Usprawiedliwienie.json").readText())
val actual = adapter.fromJson(request.body.readUtf8())
val expected = Json.decodeFromString<AttendanceExcuseRequest>(AttendanceTest::class.java.getResource("Usprawiedliwienie.json")!!.readText())
val actual = Json.decodeFromString<AttendanceExcuseRequest>(request.body.readUtf8())
assertEquals(expected, actual)
assertEquals(

View file

@ -20,7 +20,7 @@ class ExamsTest : BaseLocalTest() {
fun getExam_normal() {
with(exams[0]) {
assertEquals("Język polski", subject)
assertEquals("Sprawdzian", type)
assertEquals("Sprawdzian", typeName)
assertEquals("Dwudziestolecie", description)
assertEquals("Czerwieńska Agata", teacher)
assertEquals("CA", teacherSymbol)
@ -32,7 +32,7 @@ class ExamsTest : BaseLocalTest() {
fun getExam_group() {
with(exams[1]) {
assertEquals("Język angielski", subject)
assertEquals("Sprawdzian", type)
assertEquals("Sprawdzian", typeName)
assertEquals("Czasy teraźniejsze", description)
assertEquals("Natalia Nowak", teacher)
assertEquals("NN", teacherSymbol)
@ -44,7 +44,7 @@ class ExamsTest : BaseLocalTest() {
fun getExam_type() {
with(exams[2]) {
assertEquals("Metodologia programowania", subject)
assertEquals("Kartkówka", type)
assertEquals("Kartkówka", typeName)
assertEquals("programowanie obiektowe", description)
assertEquals("Małgorzata Nowacka", teacher)
assertEquals("MN", teacherSymbol)
@ -56,7 +56,7 @@ class ExamsTest : BaseLocalTest() {
fun getExam_emptyDescription() {
with(exams[3]) {
assertEquals("Metodologia programowania", subject)
assertEquals("Praca klasowa", type)
assertEquals("Praca klasowa", typeName)
assertEquals("", description)
assertEquals("Małgorzata Nowacka", teacher)
assertEquals("MN", teacherSymbol)

View file

@ -29,12 +29,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(4, value)
assertEquals(.0, modifier, .0)
assertEquals("", comment)
assertEquals("F04C4C", color)
assertEquals("F04C4C", colorHex)
assertEquals("S1", symbol)
assertEquals("PIERWSZA POMOC I RESUSCYTACJA", description)
assertEquals("5,00", weight)
assertEquals(5.0, weightValue, .0)
assertEquals(getDate(2018, 12, 12), date)
assertEquals(getLocalDate(2018, 12, 12), date)
assertEquals("Weronika Ratajczak", teacher)
}
}
@ -47,12 +47,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(2, value)
assertEquals(.33, modifier, .0)
assertEquals("", comment)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("O", symbol)
assertEquals("Odpowiedź", description)
assertEquals("3,00", weight)
assertEquals(3.0, weightValue, .0)
assertEquals(getDate(2018, 12, 5), date)
assertEquals(getLocalDate(2018, 12, 5), date)
assertEquals("Jakub Michalak", teacher)
}
}
@ -65,12 +65,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(5, value)
assertEquals(-.33, modifier, .0)
assertEquals("", comment)
assertEquals("1289F7", color)
assertEquals("1289F7", colorHex)
assertEquals("BW3", symbol)
assertEquals("Writing", description)
assertEquals("3,00", weight)
assertEquals(3.0, weightValue, .0)
assertEquals(getDate(2018, 11, 28), date)
assertEquals(getLocalDate(2018, 11, 28), date)
assertEquals("Oliwia Woźniak", teacher)
}
}
@ -83,12 +83,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(2, value)
assertEquals(-.50, modifier, .0)
assertEquals("", comment)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("K", symbol)
assertEquals("Kordian", description)
assertEquals("5,00", weight)
assertEquals(5.0, weightValue, .0)
assertEquals(getDate(2018, 11, 21), date)
assertEquals(getLocalDate(2018, 11, 21), date)
assertEquals("Amelia Stępień", teacher)
}
}
@ -101,12 +101,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(1, value)
assertEquals(.33, modifier, .0)
assertEquals("", comment)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("STR", symbol)
assertEquals("", description)
assertEquals("8,00", weight)
assertEquals(8.0, weightValue, .0)
assertEquals(getDate(2018, 11, 14), date)
assertEquals(getLocalDate(2018, 11, 14), date)
assertEquals("Klaudia Dziedzic", teacher)
}
}
@ -119,12 +119,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(5, value)
assertEquals(.33, modifier, .0)
assertEquals("", comment)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("+Odp", symbol)
assertEquals("Kordian", description)
assertEquals("5,00", weight)
assertEquals(5.0, weightValue, .0)
assertEquals(getDate(2018, 11, 7), date)
assertEquals(getLocalDate(2018, 11, 7), date)
assertEquals("Amelia Stępień", teacher)
}
}
@ -137,12 +137,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(5, value)
assertEquals(.0, modifier, .0)
assertEquals("pomoc przy tej uroczystości była wyjątkowa (naprawdę)", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("A1", symbol)
assertEquals("Dzień Kobiet w naszej klasie", description)
assertEquals("1,50", weight)
assertEquals(1.50, weightValue, .0)
assertEquals(getDate(2018, 10, 31), date)
assertEquals(getLocalDate(2018, 10, 31), date)
assertEquals("Patryk Maciejewski", teacher)
}
}
@ -155,12 +155,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("%", comment)
assertEquals("20A4F7", color)
assertEquals("20A4F7", colorHex)
assertEquals("MP1", symbol)
assertEquals("matura próbna", description)
assertEquals("0,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 10, 24), date)
assertEquals(getLocalDate(2018, 10, 24), date)
assertEquals("Jadwiga Czerwieńska", teacher)
}
}
@ -173,12 +173,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("", comment)
assertEquals("F04C4C", color)
assertEquals("F04C4C", colorHex)
assertEquals("S2", symbol)
assertEquals("słownictwo (człowiek) 4.10", description)
assertEquals("10,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 10, 4), date)
assertEquals(getLocalDate(2018, 10, 4), date)
assertEquals("Jadwiga Czerwieńska", teacher)
}
}
@ -191,12 +191,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("dop(2.03)", comment)
assertEquals("F04C4C", color)
assertEquals("F04C4C", colorHex)
assertEquals("ZAL", symbol)
assertEquals("", description)
assertEquals("10,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 10, 3), date)
assertEquals(getLocalDate(2018, 10, 3), date)
assertEquals("Jadwiga Czerwieńska", teacher)
}
}
@ -209,12 +209,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("d1", symbol)
assertEquals("Sprawozdanie - wyznaczanie przyspieczenia.", description)
assertEquals("3,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2017, 11, 23), date)
assertEquals(getLocalDate(2017, 11, 23), date)
assertEquals("Anonimus Max", teacher)
}
}
@ -227,12 +227,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("spr", symbol)
assertEquals("sprawdzian z tematów 11-15", description)
assertEquals("4,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2017, 11, 22), date)
assertEquals(getLocalDate(2017, 11, 22), date)
assertEquals("Anonimus Max", teacher)
}
}
@ -245,12 +245,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("85/100", comment)
assertEquals("6ECD07", color)
assertEquals("6ECD07", colorHex)
assertEquals("", symbol)
assertEquals("diagnoza", description)
assertEquals("0,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2019, 9, 10), date)
assertEquals(getLocalDate(2019, 9, 10), date)
assertEquals("Weronika Ratajczak", teacher)
}
}
@ -263,12 +263,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("komentarz", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("O", symbol)
assertEquals("Odpowiedź", description)
assertEquals("0,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 12, 5), date)
assertEquals(getLocalDate(2018, 12, 5), date)
assertEquals("Jakub Michalak", teacher)
}
}
@ -281,12 +281,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("komentarz", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("O", symbol)
assertEquals("Odpowiedź", description)
assertEquals("0,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 12, 4), date)
assertEquals(getLocalDate(2018, 12, 4), date)
assertEquals("Jakub Michalak", teacher)
}
}
@ -299,12 +299,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.0, modifier, .0)
assertEquals("47.5/50", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("K3", symbol)
assertEquals("Liczebniki", description)
assertEquals("1,00", weight)
assertEquals(0.0, weightValue, .0)
assertEquals(getDate(2018, 12, 3), date)
assertEquals(getLocalDate(2018, 12, 3), date)
assertEquals("Jakub Michalak", teacher)
}
}
@ -317,12 +317,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(0, value)
assertEquals(.5, modifier, .0)
assertEquals("", comment)
assertEquals("000000", color)
assertEquals("000000", colorHex)
assertEquals("A1", symbol)
assertEquals("Podnoszenie ciężarów", description)
assertEquals("0,00", weight)
assertEquals(.0, weightValue, .0)
assertEquals(getDate(2017, 9, 1), date)
assertEquals(getLocalDate(2017, 9, 1), date)
assertEquals("Klaudia Dziedzic", teacher)
}
}
@ -335,12 +335,12 @@ class GradesTest : BaseLocalTest() {
assertEquals(4, value)
assertEquals(.0, modifier, .0)
assertEquals("", comment)
assertEquals("F04C4C", color)
assertEquals("F04C4C", colorHex)
assertEquals("S1", symbol)
assertEquals("Rodzaje broni chemicznych", description)
assertEquals("5,00", weight)
assertEquals(5.0, weightValue, .0)
assertEquals(getDate(1970, 1, 1, 0, 0, 0), date)
assertEquals(getLocalDate(1970, 1, 1), date)
assertEquals("Weronika Ratajczak", teacher)
}
}

View file

@ -1,14 +1,15 @@
package io.github.wulkanowy.sdk.scrapper.messages
import com.squareup.moshi.Moshi
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.repository.MessagesRepository
import io.github.wulkanowy.sdk.scrapper.service.MessagesService
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.SerializationException
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals
import org.junit.Test
import java.io.EOFException
class MessagesTest : BaseLocalTest() {
@ -226,10 +227,9 @@ class MessagesTest : BaseLocalTest() {
server.takeRequest()
val adapter = SendMessageRequestJsonAdapter(Moshi.Builder().build())
val expected = adapter.fromJson(MessagesTest::class.java.getResource("NowaWiadomosc.json").readText())
val expected = Json.decodeFromString<SendMessageRequest>(MessagesTest::class.java.getResource("NowaWiadomosc.json")!!.readText())
val request = server.takeRequest()
val actual = adapter.fromJson(request.body.readUtf8())
val actual = Json.decodeFromString<SendMessageRequest>(request.body.readUtf8())
assertEquals(expected, actual)
assertEquals(
@ -252,10 +252,9 @@ class MessagesTest : BaseLocalTest() {
server.takeRequest()
val adapter = DeleteMessageRequestJsonAdapter(Moshi.Builder().build())
val expected = adapter.fromJson(MessagesTest::class.java.getResource("UsunWiadomosc.json").readText())
val expected = Json.decodeFromString<DeleteMessageRequest>(MessagesTest::class.java.getResource("UsunWiadomosc.json")!!.readText())
val request = server.takeRequest()
val actual = adapter.fromJson(request.body.readUtf8())
val actual = Json.decodeFromString<DeleteMessageRequest>(request.body.readUtf8())
assertEquals(expected, actual)
assertEquals(
@ -277,7 +276,7 @@ class MessagesTest : BaseLocalTest() {
val res = runCatching { runBlocking { api.deleteMessages(listOf(74, 69), 3) } }
val exception = res.exceptionOrNull()!!
assertEquals(EOFException::class.java, exception::class.java)
assertEquals("End of input", exception.message)
assert(exception is SerializationException)
assertEquals("Expected start of the object '{', but had 'EOF' instead at path: \$\nJSON input: ", exception.message)
}
}

View file

@ -2,7 +2,6 @@ package io.github.wulkanowy.sdk.mapper
import io.github.wulkanowy.sdk.mobile.dictionaries.Dictionaries
import io.github.wulkanowy.sdk.pojo.Exam
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.sdk.mobile.exams.Exam as ApiExam
import io.github.wulkanowy.sdk.scrapper.exams.Exam as ScrapperExam
@ -34,6 +33,6 @@ fun List<ScrapperExam>.mapExams() = map {
teacherSymbol = it.teacherSymbol,
teacher = it.teacher,
subject = it.subject,
type = it.type
type = it.typeName
)
}

View file

@ -5,7 +5,6 @@ import io.github.wulkanowy.sdk.mobile.grades.GradesSummaryResponse
import io.github.wulkanowy.sdk.pojo.Grade
import io.github.wulkanowy.sdk.pojo.GradeSummary
import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.sdk.mobile.grades.Grade as ApiGrade
import io.github.wulkanowy.sdk.scrapper.grades.Grade as ScrapperGrade
@ -34,12 +33,12 @@ fun List<ScrapperGrade>.mapGradesDetails() = map {
description = it.description.orEmpty(),
symbol = it.symbol.orEmpty(),
comment = it.comment,
date = it.date.toLocalDate(),
date = it.date,
teacher = it.teacher,
entry = it.entry,
weight = it.weight,
weightValue = it.weightValue,
color = it.color,
color = it.colorHex,
value = it.value.toDouble(),
modifier = it.modifier
)

View file

@ -46,8 +46,8 @@ fun List<ScrapperMessage>.mapMessages(zoneId: ZoneId) = map {
Message(
id = it.id,
subject = it.subject.orEmpty(),
date = it.date?.toLocalDateTime(),
dateZoned = it.date?.toLocalDateTime()?.atZone(zoneId),
date = it.date,
dateZoned = it.date?.atZone(zoneId),
content = it.content,
folderId = it.folderId,
messageId = it.messageId,

View file

@ -3,7 +3,6 @@ package io.github.wulkanowy.sdk.mapper
import io.github.wulkanowy.sdk.pojo.Device
import io.github.wulkanowy.sdk.pojo.Token
import io.github.wulkanowy.sdk.scrapper.mobile.TokenResponse
import io.github.wulkanowy.sdk.toLocalDateTime
import java.time.LocalDateTime.now
import java.time.ZoneId
import io.github.wulkanowy.sdk.scrapper.mobile.Device as ScrapperDevice
@ -20,9 +19,9 @@ fun List<ScrapperDevice>.mapDevices(zoneId: ZoneId) = map {
id = it.id,
deviceId = it.deviceId.orEmpty(),
name = it.name.orEmpty(),
createDate = it.createDate?.toLocalDateTime() ?: now(),
modificationDate = it.modificationDate?.toLocalDateTime(),
createDateZoned = (it.createDate?.toLocalDateTime() ?: now()).atZone(zoneId),
modificationDateZoned = it.modificationDate?.toLocalDateTime()?.atZone(zoneId)
createDate = it.createDate ?: now(),
modificationDate = it.modificationDate,
createDateZoned = (it.createDate ?: now()).atZone(zoneId),
modificationDateZoned = it.modificationDate?.atZone(zoneId)
)
}

View file

@ -6,7 +6,6 @@ import io.github.wulkanowy.sdk.pojo.Timetable
import io.github.wulkanowy.sdk.pojo.TimetableAdditional
import io.github.wulkanowy.sdk.pojo.TimetableDayHeader
import io.github.wulkanowy.sdk.pojo.TimetableFull
import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.sdk.toLocalDateTime
import java.time.ZoneId
@ -110,12 +109,12 @@ fun List<ScrapperCompletedLesson>.mapCompletedLessons() = map {
CompletedLesson(
date = it.date.toLocalDate(),
number = it.number,
subject = it.subject,
topic = it.topic,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol,
substitution = it.substitution,
absence = it.absence,
resources = it.resources
subject = it.subject.orEmpty(),
topic = it.topic.orEmpty(),
teacher = it.teacher.orEmpty(),
teacherSymbol = it.teacherSymbol.orEmpty(),
substitution = it.substitution.orEmpty(),
absence = it.absence.orEmpty(),
resources = it.resources.orEmpty(),
)
}

View file

@ -6,7 +6,7 @@ import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceCategory
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import java.util.Date
import java.time.LocalDateTime
class AttendanceMapperTest : BaseLocalTest() {
@ -107,7 +107,7 @@ class AttendanceMapperTest : BaseLocalTest() {
}
private fun createAttendance(cat: AttendanceCategory): List<Attendance> {
val item = Attendance(1, Date(), "").apply {
val item = Attendance(1, LocalDateTime.now(), "").apply {
number = 0
category = cat
excusable = false