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"
|
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