feat(data): add TeacherRepositoryImpl
This commit is contained in:
@@ -10,4 +10,9 @@ object VyatsuUrls {
|
||||
|
||||
fun groupPdfUrl(groupId: String, season: Season, range: DateRange): String = "$PDF_BASEURL/${groupId}_${season.apiKey}_${range.first}_${range.second}.pdf"
|
||||
|
||||
const val TEACHER_PAGE = "https://www.vyatsu.ru/studentu-1/spravochnaya-informatsiya/teacher.html"
|
||||
const val PREPOD_BASEURL = "https://www.vyatsu.ru/reports/schedule/prepod"
|
||||
|
||||
fun teacherPrepodUrl(departmentId: String, season: Season, range: DateRange): String = "$PREPOD_BASEURL/${departmentId}_${season.apiKey}_${range.first}_${range.second}.html"
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package agzam.vyatsu.data.repository
|
||||
|
||||
import agzam.vyatsu.data.local.DepartmentEntity
|
||||
import agzam.vyatsu.data.local.DepartmentPeriodEntity
|
||||
import agzam.vyatsu.data.local.TeacherDao
|
||||
import agzam.vyatsu.data.remote.TeachersParser
|
||||
import agzam.vyatsu.data.remote.VyatsuHttpClient
|
||||
import agzam.vyatsu.data.remote.VyatsuUrls
|
||||
import agzam.vyatsu.domain.ScheduleDates
|
||||
import agzam.vyatsu.domain.model.Department
|
||||
import agzam.vyatsu.domain.repository.TeacherRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class TeacherRepositoryImpl(
|
||||
private val teacherDao: TeacherDao,
|
||||
) : TeacherRepository {
|
||||
|
||||
override fun observeDepartments(): Flow<List<Department>> =
|
||||
teacherDao.observeDepartments().map { list -> list.map { it.toDomain() } }
|
||||
|
||||
override suspend fun getDepartments(): List<Department> =
|
||||
teacherDao.observeDepartments().first().map { it.toDomain() }
|
||||
|
||||
override suspend fun getFaculties(): List<String> = teacherDao.getFaculties()
|
||||
|
||||
override suspend fun refreshIfStale(): Boolean {
|
||||
val last = teacherDao.maxSyncedAt()
|
||||
if (last != null && now() - last < STALE_WINDOW_MS) {
|
||||
return true
|
||||
}
|
||||
refresh()
|
||||
return true
|
||||
}
|
||||
|
||||
override suspend fun forceRefresh(): Boolean {
|
||||
refresh()
|
||||
return true
|
||||
}
|
||||
|
||||
private suspend fun refresh() {
|
||||
val parsed = withContext(Dispatchers.IO) {
|
||||
VyatsuHttpClient.openStream(VyatsuUrls.TEACHER_PAGE).use(TeachersParser::parseStream)
|
||||
}
|
||||
val now = now()
|
||||
teacherDao.insertAll(
|
||||
parsed.departments.map { department ->
|
||||
DepartmentEntity(
|
||||
departmentId = department.departmentId,
|
||||
name = department.name,
|
||||
faculty = department.faculty,
|
||||
lastSyncedAt = now
|
||||
)
|
||||
}
|
||||
)
|
||||
val periods = parsed.departments.flatMap { department ->
|
||||
parsed.dateRanges[department.departmentId].orEmpty().flatMap { (season, ranges) ->
|
||||
ranges.map { range ->
|
||||
DepartmentPeriodEntity(
|
||||
departmentId = department.departmentId,
|
||||
season = season,
|
||||
weekStart = ScheduleDates.asDate(range.first).toEpochDay(),
|
||||
weekEnd = ScheduleDates.asDate(range.second).toEpochDay()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
teacherDao.deleteAllPeriods()
|
||||
teacherDao.insertPeriods(periods)
|
||||
}
|
||||
|
||||
private fun now(): Long = System.currentTimeMillis()
|
||||
|
||||
private fun DepartmentEntity.toDomain(): Department = Department(
|
||||
departmentId = departmentId,
|
||||
name = name,
|
||||
faculty = faculty
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val STALE_WINDOW_MS = 12 * 60 * 60 * 1000L
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user