[API/Librus] Add Lessons endpoint and showing correct attendance subjects.

This commit is contained in:
Kuba Szczodrzyński 2020-01-06 16:27:37 +01:00
parent e123ff1bec
commit 52ecfba0a5
9 changed files with 131 additions and 8 deletions

View File

@ -15,6 +15,7 @@ const val ENDPOINT_LIBRUS_API_UNITS = 1005
const val ENDPOINT_LIBRUS_API_USERS = 1006
const val ENDPOINT_LIBRUS_API_SUBJECTS = 1007
const val ENDPOINT_LIBRUS_API_CLASSROOMS = 1008
const val ENDPOINT_LIBRUS_API_LESSONS = 1009
const val ENDPOINT_LIBRUS_API_PUSH_CONFIG = 1010
const val ENDPOINT_LIBRUS_API_TIMETABLES = 1015
const val ENDPOINT_LIBRUS_API_SUBSTITUTIONS = 1016
@ -57,6 +58,10 @@ const val ENDPOINT_LIBRUS_MESSAGES_GET = 3040
val LibrusFeatures = listOf(
Feature(LOGIN_TYPE_LIBRUS, FEATURE_ALWAYS_NEEDED, listOf(
ENDPOINT_LIBRUS_API_LESSONS to LOGIN_METHOD_LIBRUS_API
), listOf(LOGIN_METHOD_LIBRUS_API)),
// push config
Feature(LOGIN_TYPE_LIBRUS, FEATURE_PUSH_CONFIG, listOf(
ENDPOINT_LIBRUS_API_PUSH_CONFIG to LOGIN_METHOD_LIBRUS_API

View File

@ -75,6 +75,10 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_classrooms)
LibrusApiClassrooms(data, onSuccess)
}
ENDPOINT_LIBRUS_API_LESSONS -> {
data.startProgress(R.string.edziennik_progress_endpoint_lessons)
LibrusApiLessons(data, onSuccess)
}
// TODO push config
ENDPOINT_LIBRUS_API_TIMETABLES -> {
data.startProgress(R.string.edziennik_progress_endpoint_timetable)

View File

@ -25,6 +25,9 @@ class LibrusApiAttendances(override val data: DataLibrus,
if (data.attendanceTypes.isEmpty()) {
data.db.attendanceTypeDao().getAllNow(profileId).toSparseArray(data.attendanceTypes) { it.id }
}
if (data.librusLessons.isEmpty()) {
data.db.librusLessonDao().getAllNow(profileId).toSparseArray(data.librusLessons) { it.lessonId }
}
apiGet(TAG, "Attendances") { json ->
val attendances = json.getJsonArray("Attendances")?.asJsonObjectList()
@ -32,23 +35,25 @@ class LibrusApiAttendances(override val data: DataLibrus,
attendances?.forEach { attendance ->
val id = Utils.strToInt((attendance.getString("Id") ?: return@forEach)
.replace("[^\\d.]".toRegex(), "")).toLong()
val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id") ?: -1
val lessonId = attendance.getJsonObject("Lesson")?.getLong("Id") ?: -1
val lessonNo = attendance.getInt("LessonNo") ?: return@forEach
val startTime = data.lessonRanges.get(lessonNo).startTime
val lessonDate = Date.fromY_m_d(attendance.getString("Date"))
val semester = attendance.getInt("Semester") ?: return@forEach
val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
val typeObject = data.attendanceTypes.get(type)
val topic = typeObject?.name ?: ""
val lessonList = data.db.timetableDao().getForDateNow(profileId, lessonDate)
val subjectId = lessonList.firstOrNull { it.startTime == startTime }?.subjectId ?: -1
val startTime = data.lessonRanges.get(lessonNo).startTime
val lesson = if (lessonId != -1L)
data.librusLessons.singleOrNull { it.lessonId == lessonId }
else null
val attendanceObject = Attendance(
profileId,
id,
teacherId,
subjectId,
lesson?.teacherId ?: -1,
lesson?.subjectId ?: -1,
semester,
topic,
lessonDate,

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-1-6.
*/
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_LESSONS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LibrusLesson
class LibrusApiLessons(override val data: DataLibrus,
val onSuccess: () -> Unit) : LibrusApi(data) {
companion object {
const val TAG = "LibrusApiLessons"
}
init {
apiGet(TAG, "Lessons") { json ->
val lessons = json.getJsonArray("Lessons")?.asJsonObjectList()
lessons?.forEach { lesson ->
val id = lesson.getLong("Id") ?: return@forEach
val teacherId = lesson.getJsonObject("Teacher")?.getLong("Id") ?: return@forEach
val subjectId = lesson.getJsonObject("Subject")?.getLong("Id") ?: return@forEach
val teamId = lesson.getJsonObject("Class")?.getLong("Id")
val librusLesson = LibrusLesson(
profileId,
id,
teacherId,
subjectId,
teamId
)
data.librusLessons.put(id, librusLesson)
}
data.setSyncNext(ENDPOINT_LIBRUS_API_LESSONS, 4*DAY)
onSuccess()
}
}
}

View File

@ -35,6 +35,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsence
import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsenceType
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LibrusLesson
import pl.szczodrzynski.edziennik.singleOrNull
import pl.szczodrzynski.edziennik.toSparseArray
import pl.szczodrzynski.edziennik.utils.Utils.d
@ -122,6 +123,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
val noticeTypes = LongSparseArray<NoticeType>()
val eventTypes = LongSparseArray<EventType>()
val teacherAbsenceTypes = LongSparseArray<TeacherAbsenceType>()
val librusLessons = LongSparseArray<LibrusLesson>()
private var mTeamClass: Team? = null
var teamClass: Team?
@ -194,6 +196,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
noticeTypes.clear()
eventTypes.clear()
teacherAbsenceTypes.clear()
librusLessons.clear()
lessonList.clear()
gradeList.clear()
@ -264,6 +267,8 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
db.eventTypeDao().addAll(eventTypes.values())
if (teacherAbsenceTypes.size > 0)
db.teacherAbsenceTypeDao().addAll(teacherAbsenceTypes.values())
if (librusLessons.size > 0)
db.librusLessonDao().addAll(librusLessons.values())
// clear DB with DataRemoveModels added by endpoints
for (model in toRemove) {

View File

@ -72,6 +72,8 @@ import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsenceTypeDao
import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherDao;
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team;
import pl.szczodrzynski.edziennik.data.db.modules.teams.TeamDao;
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LibrusLesson;
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LibrusLessonDao;
import pl.szczodrzynski.edziennik.data.db.modules.timetable.TimetableDao;
import pl.szczodrzynski.edziennik.utils.models.Date;
@ -104,7 +106,8 @@ import pl.szczodrzynski.edziennik.utils.models.Date;
AttendanceType.class,
pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson.class,
ConfigEntry.class,
Metadata.class}, version = 73)
LibrusLesson.class,
Metadata.class}, version = 74)
@TypeConverters({
ConverterTime.class,
ConverterDate.class,
@ -142,6 +145,7 @@ public abstract class AppDb extends RoomDatabase {
public abstract AttendanceTypeDao attendanceTypeDao();
public abstract TimetableDao timetableDao();
public abstract ConfigDao configDao();
public abstract LibrusLessonDao librusLessonDao();
public abstract MetadataDao metadataDao();
private static volatile AppDb INSTANCE;
@ -961,6 +965,19 @@ public abstract class AppDb extends RoomDatabase {
database.execSQL("DROP TABLE lessonChanges");
}
};
public static final Migration MIGRATION_73_74 = new Migration(73, 74) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE librusLessons (" +
"profileId INTEGER NOT NULL," +
"lessonId INTEGER NOT NULL," +
"teacherId INTEGER NOT NULL," +
"subjectId INTEGER NOT NULL," +
"teamId INTEGER," +
"PRIMARY KEY(profileId, lessonId));");
database.execSQL("CREATE INDEX index_librusLessons_profileId ON librusLessons (profileId);");
}
};
public static AppDb getDatabase(final Context context) {
@ -1031,7 +1048,8 @@ public abstract class AppDb extends RoomDatabase {
MIGRATION_69_70,
MIGRATION_70_71,
MIGRATION_71_72,
MIGRATION_72_73
MIGRATION_72_73,
MIGRATION_73_74
)
.allowMainThreadQueries()
//.fallbackToDestructiveMigration()

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-1-5.
*/
package pl.szczodrzynski.edziennik.data.db.modules.timetable
import androidx.room.Entity
import androidx.room.Index
@Entity(tableName = "librusLessons",
primaryKeys = ["profileId", "lessonId"],
indices = [Index("profileId")])
data class LibrusLesson(
val profileId: Int,
val lessonId: Long,
val teacherId: Long,
val subjectId: Long,
val teamId: Long? = null
)

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-1-6.
*/
package pl.szczodrzynski.edziennik.data.db.modules.timetable
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface LibrusLessonDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun add(librusLesson: LibrusLesson)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addAll(librusLessonList: List<LibrusLesson>)
@Query("SELECT * FROM librusLessons WHERE profileId = :profileId")
fun getAllNow(profileId: Int): List<LibrusLesson>
}

View File

@ -1151,4 +1151,5 @@
<string name="timetable_generate_show_profile_name">Pokaż nazwę profilu</string>
<string name="timetable_generate_no_colors">Do wydruku (czarno-białe)</string>
<string name="timetable_generate_selected_week">Na wybrany tydzień</string>
<string name="edziennik_progress_endpoint_lessons">Pobieranie listy lekcji…</string>
</resources>