fix schedule request. Add Moshi and network logger
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
|
||||
7
app/src/main/java/ru/fincode/tsudesk/App.kt
Normal file
7
app/src/main/java/ru/fincode/tsudesk/App.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package ru.fincode.tsudesk
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class App : Application()
|
||||
@@ -1,21 +1,33 @@
|
||||
package ru.fincode.tsudesk
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.usecase.GetScheduleUseCase
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.usecase.GetScheduleUseCase.ScheduleType
|
||||
import javax.inject.Inject
|
||||
|
||||
import ru.fincode.tsudesk.core.network.NetworkConstants
|
||||
import ru.fincode.tsudesk.core.network.RetrofitProvider
|
||||
import ru.fincode.tsudesk.core.network.NetworkModule
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleApi
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
@Inject
|
||||
lateinit var getScheduleUseCase: GetScheduleUseCase
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val result = getScheduleUseCase(
|
||||
ScheduleType.Group("220631")
|
||||
)
|
||||
Log.d("TSUDesk", result.isSuccess.toString())
|
||||
} catch (e: Exception) {
|
||||
Log.e("TSUDesk", "Error loading schedule", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,5 +42,12 @@ dependencies {
|
||||
api(libs.retrofit)
|
||||
api(libs.okhttp)
|
||||
|
||||
implementation(libs.retrofit.simplexml)
|
||||
implementation(libs.okhttp.logging)
|
||||
implementation(libs.converter.gson)
|
||||
|
||||
api(libs.moshi)
|
||||
api(libs.moshiKotlin)
|
||||
api(libs.retrofitMoshi)
|
||||
|
||||
api(libs.retrofit.simplexml)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package ru.fincode.tsudesk.core.network
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import android.util.Log
|
||||
|
||||
class DebugInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
|
||||
Log.d("NETWORK_DEBUG", "URL: ${request.url}")
|
||||
Log.d("NETWORK_DEBUG", "Method: ${request.method}")
|
||||
Log.d("NETWORK_DEBUG", "Headers: ${request.headers}")
|
||||
|
||||
return chain.proceed(request)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package ru.fincode.tsudesk.core.network
|
||||
|
||||
object NetworkConstants {
|
||||
const val BASE_URL = "https://api.tsu.tula.ru/"
|
||||
const val BASE_URL = "https://tulsu.ru/schedule/queries/"
|
||||
}
|
||||
@@ -8,12 +8,16 @@ import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Singleton
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object NetworkModule {
|
||||
|
||||
private const val TIMEOUT_SEC = 30L
|
||||
val logging = HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@@ -23,6 +27,7 @@ object NetworkModule {
|
||||
.readTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
|
||||
.writeTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(true)
|
||||
.addInterceptor(DebugInterceptor())
|
||||
.build()
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
package ru.fincode.tsudesk.core.network
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.simplexml.SimpleXmlConverterFactory
|
||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||
import javax.inject.Inject
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class RetrofitProvider @Inject constructor() {
|
||||
|
||||
private val moshi: Moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
class RetrofitProvider {
|
||||
fun process(baseUrl: String, client: OkHttpClient): Retrofit =
|
||||
Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.client(client)
|
||||
.addConverterFactory(SimpleXmlConverterFactory.create())
|
||||
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package ru.fincode.tsudesk.feature.schedule.data
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleRemoteDataSource
|
||||
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleDtoToDomainMapper
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -10,12 +10,11 @@ class ScheduleRepositoryImpl @Inject constructor(
|
||||
private val remote: ScheduleRemoteDataSource, private val mapper: ScheduleDtoToDomainMapper
|
||||
) : ScheduleRepository {
|
||||
|
||||
override suspend fun loadScheduleByGroup(groupNumber: String): Schedule {
|
||||
return mapper.map(remote.loadScheduleByGroup(groupNumber))
|
||||
}
|
||||
|
||||
override suspend fun loadScheduleByTeacher(teacherName: String): Schedule {
|
||||
return mapper.map(remote.loadScheduleByTeacher(teacherName))
|
||||
}
|
||||
override suspend fun loadScheduleByGroup(
|
||||
groupNumber: String
|
||||
): Result<ScheduleEntity> = remote.loadScheduleByGroup(groupNumber).map(mapper::invoke)
|
||||
|
||||
override suspend fun loadScheduleByTeacher(
|
||||
name: String
|
||||
): Result<ScheduleEntity> = remote.loadScheduleByTeacher(name).map(mapper::invoke)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.datasource
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.local.ScheduleEntity
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleDto
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
|
||||
|
||||
interface ScheduleLocalDataSource {
|
||||
suspend fun getScheduleByGroup(groupNumber: String): ScheduleEntity?
|
||||
suspend fun getScheduleByTeacherName(teacherName: String): ScheduleEntity?
|
||||
suspend fun getScheduleByTeacher(teacherName: String): ScheduleEntity?
|
||||
suspend fun saveSchedule(entity: ScheduleEntity)
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.datasource
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleApi
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleDto
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleXmlParser
|
||||
import java.io.IOException
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto.ScheduleSearchField.GROUP_P
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto.ScheduleSearchField.PREP
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.ScheduleDto
|
||||
import javax.inject.Inject
|
||||
|
||||
class ScheduleRemoteDataSource(
|
||||
private val api: ScheduleApi, private val xmlParser: ScheduleXmlParser
|
||||
class ScheduleRemoteDataSource @Inject constructor(
|
||||
private val api: ScheduleApi
|
||||
) {
|
||||
suspend fun loadScheduleByGroup(groupNumber: String): ScheduleDto {
|
||||
val response = api.getScheduleByGroup(groupNumber)
|
||||
return xmlParser.parse(response.body() ?: throw IOException("Response body is null"))
|
||||
}
|
||||
suspend fun loadScheduleByGroup(groupNumber: String): Result<ScheduleDto> =
|
||||
runCatching { api.getSchedule(GROUP_P, groupNumber) }
|
||||
|
||||
suspend fun loadScheduleByTeacher(name: String): ScheduleDto {
|
||||
val response = api.getScheduleByTeacherName(name)
|
||||
return xmlParser.parse(response.body() ?: throw IOException("Response body is null"))
|
||||
}
|
||||
suspend fun loadScheduleByTeacher(name: String): Result<ScheduleDto> =
|
||||
runCatching { api.getSchedule(PREP, name) }
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.datasource
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleDtoToDomainMapper
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class ScheduleRepositoryImpl @Inject constructor(
|
||||
class ScheduleRemoteDataSourceImpl @Inject constructor(
|
||||
private val remote: ScheduleRemoteDataSource,
|
||||
private val mapper: ScheduleDtoToDomainMapper
|
||||
) : ScheduleRepository {
|
||||
|
||||
override suspend fun loadScheduleByGroup(groupNumber: String): Schedule {
|
||||
return mapper.map(remote.loadScheduleByGroup(groupNumber));
|
||||
}
|
||||
override suspend fun loadScheduleByGroup(groupNumber: String): Result<ScheduleEntity> =
|
||||
remote
|
||||
.loadScheduleByGroup(groupNumber) // Result<ScheduleDto>
|
||||
.map(mapper::invoke) // Result<ScheduleEntity>
|
||||
|
||||
override suspend fun loadScheduleByTeacher(teacherName: String): Schedule {
|
||||
return mapper.map(remote.loadScheduleByTeacher(teacherName));
|
||||
}
|
||||
override suspend fun loadScheduleByTeacher(name: String): Result<ScheduleEntity> =
|
||||
remote
|
||||
.loadScheduleByTeacher(name) // Result<ScheduleDto>
|
||||
.map(mapper::invoke) // Result<ScheduleEntity>
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.local;
|
||||
|
||||
public class ScheduleEntity {
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.mapper
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleDto
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.ScheduleDto
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Lesson
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
import javax.inject.Inject
|
||||
|
||||
class ScheduleDtoToDomainMapper {
|
||||
class ScheduleDtoToDomainMapper @Inject constructor() {
|
||||
|
||||
fun map(dto: ScheduleDto): Schedule =
|
||||
Schedule(
|
||||
lessons = dto.lessons.map { l ->
|
||||
operator fun invoke(dto: ScheduleDto): ScheduleEntity =
|
||||
ScheduleEntity(lessons = dto.map(::mapLesson))
|
||||
|
||||
private fun mapLesson(item: LessonDto): Lesson =
|
||||
Lesson(
|
||||
dayOfWeek = l.dayOfWeek,
|
||||
dayName = l.dayName,
|
||||
weekType = l.weekType,
|
||||
time = l.time,
|
||||
room = l.room,
|
||||
subjectName = l.subjectName,
|
||||
teacherName = l.teacherName
|
||||
)
|
||||
}
|
||||
date = item.date.trim(),
|
||||
time = item.time.trim(),
|
||||
subject = item.discipline.trim(),
|
||||
typeName = item.typeName.trim(),
|
||||
room = item.room.trim(),
|
||||
teacher = item.teacher.trim(),
|
||||
groupId = item.groups.firstOrNull()?.groupCode.orEmpty(),
|
||||
type = item.type.trim()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.remote
|
||||
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto.*
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.ScheduleDto
|
||||
|
||||
interface ScheduleApi {
|
||||
@GET("schedule")
|
||||
suspend fun getScheduleByGroup(
|
||||
@Query("group") groupNumber: String
|
||||
): Response<ResponseBody>
|
||||
|
||||
@GET("schedule")
|
||||
suspend fun getScheduleByTeacherName(
|
||||
@Query("fio") teacherName: String
|
||||
): Response<ResponseBody>
|
||||
/**
|
||||
* Расписание по номеру группы.
|
||||
* Пример: search_field=GROUP_P&search_value=220631
|
||||
* https://tulsu.ru/schedule/queries/GetSchedule.php?search_field=GROUP_P&search_value=220631
|
||||
*
|
||||
*
|
||||
* Расписание по ФИО преподавателя (строкой).
|
||||
* Пример: search_field=PREP&search_value=Набродова Ирина Николаевна
|
||||
*
|
||||
* Важно: Retrofit сам URL-энкодит параметр search_value
|
||||
* https://tulsu.ru/schedule/queries/GetDates.php?search_value=%D0%9D%D0%B0%D0%B1%D1%80%D0%BE%D0%B4%D0%BE%D0%B2%D0%B0%20%D0%98%D1%80%D0%B8%D0%BD%D0%B0%20%D0%9D%D0%B8%D0%BA%D0%BE%D0%BB%D0%B0%D0%B5%D0%B2%D0%BD%D0%B0
|
||||
*/
|
||||
@GET("GetSchedule.php")
|
||||
suspend fun getSchedule(
|
||||
@Query("search_field") searchField: String,
|
||||
@Query("search_value") searchValue: String
|
||||
): ScheduleDto
|
||||
}
|
||||
|
||||
@@ -1,15 +1,38 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.remote
|
||||
package ru.fincode.tsudesk.feature.schedule.data.remote.model
|
||||
|
||||
data class ScheduleDto(
|
||||
val lessons: List<LessonDto>
|
||||
)
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
typealias ScheduleDto = List<LessonDto>
|
||||
|
||||
@JsonClass(generateAdapter = false) // reflection-адаптер через moshi-kotlin
|
||||
data class LessonDto(
|
||||
val dayOfWeek: String,
|
||||
val dayName: String,
|
||||
val time: String,
|
||||
val room: String,
|
||||
val subjectName: String,
|
||||
val teacherName: String,
|
||||
val weekType: Int
|
||||
)
|
||||
@Json(name = "DATE_Z")
|
||||
val date: String, // "12.01.2026"
|
||||
@Json(name = "TIME_Z")
|
||||
val time: String, // "11:00 - 13:55"
|
||||
@Json(name = "DISCIP")
|
||||
val discipline: String, // предмет
|
||||
@Json(name = "KOW")
|
||||
val typeName: String, // "Лекции", "Лабораторные занятия", "Э", "зч", "КР", "ДЗ" и т.п.
|
||||
@Json(name = "AUD")
|
||||
val room: String, // можно назвать audience, но ключ в JSON "AUD"
|
||||
@Json(name = "PREP")
|
||||
val teacher: String,
|
||||
@Json(name = "GROUPS")
|
||||
val groups: List<GroupDto>,
|
||||
@Json(name = "CLASS")
|
||||
val type: String // "lecture" / "lab" / "practice" / "default"
|
||||
) {
|
||||
|
||||
data class GroupDto(
|
||||
@Json(name = "GROUP_P")
|
||||
val groupCode: String
|
||||
)
|
||||
object ScheduleSearchField {
|
||||
const val GROUP_P = "GROUP_P"
|
||||
const val PREP = "PREP"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.remote
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.model.LessonDto
|
||||
|
||||
class ScheduleJsonParser {
|
||||
|
||||
private val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
private val type = Types.newParameterizedType(
|
||||
List::class.java,
|
||||
LessonDto::class.java
|
||||
)
|
||||
|
||||
private val adapter = moshi.adapter<List<LessonDto>>(type)
|
||||
fun parse(json: String): List<LessonDto> =
|
||||
adapter.fromJson(json)
|
||||
?: throw IllegalStateException("Schedule JSON is null/invalid")
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.data.remote
|
||||
|
||||
import okhttp3.ResponseBody
|
||||
|
||||
interface ScheduleXmlParser {
|
||||
fun parse(body: ResponseBody): ScheduleDto
|
||||
}
|
||||
|
||||
|
||||
class ScheduleXmlParserImpl : ScheduleXmlParser {
|
||||
override fun parse(body: ResponseBody): ScheduleDto {
|
||||
val xml = body.string()
|
||||
return ScheduleDto(lessons = emptyList())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import retrofit2.Retrofit
|
||||
import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleApi
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object ScheduleNetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideScheduleApi(retrofit: Retrofit): ScheduleApi =
|
||||
retrofit.create(ScheduleApi::class.java)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import ru.fincode.tsudesk.feature.schedule.data.ScheduleRepositoryImpl
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class ScheduleRepositoryModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract fun bindScheduleRepository(
|
||||
impl: ScheduleRepositoryImpl
|
||||
): ScheduleRepository
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.domain.model
|
||||
|
||||
data class Schedule(
|
||||
val lessons: List<Lesson>
|
||||
)
|
||||
|
||||
data class Lesson(
|
||||
val dayOfWeek: String,
|
||||
val dayName: String,
|
||||
val time: String,
|
||||
val room: String,
|
||||
val subjectName: String,
|
||||
val teacherName: String,
|
||||
val weekType: Int
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.domain.model
|
||||
|
||||
data class ScheduleEntity(
|
||||
val lessons: List<Lesson>
|
||||
)
|
||||
|
||||
data class Lesson(
|
||||
val date: String, // "12.01.2026"
|
||||
val time: String, // "11:00 - 13:55"
|
||||
val subject: String, // discipline
|
||||
val typeName: String, // "Лекции", "Лабораторные занятия" и т.д.
|
||||
val room: String,
|
||||
val teacher: String,
|
||||
val groupId: String,
|
||||
val type: String // "lecture" / "lab" / "practice" / "default"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.domain.repository
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
|
||||
interface ScheduleRepository {
|
||||
suspend fun loadScheduleByGroup(groupNumber: String): Schedule
|
||||
suspend fun loadScheduleByTeacher(teacherName: String): Schedule
|
||||
suspend fun loadScheduleByGroup(groupNumber: String): Result<ScheduleEntity>
|
||||
suspend fun loadScheduleByTeacher(name: String): Result<ScheduleEntity>
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.domain.repository
|
||||
|
||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleRemoteDataSource
|
||||
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleDtoToDomainMapper
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule
|
||||
import javax.inject.Inject
|
||||
|
||||
class ScheduleRepositoryImpl @Inject constructor(
|
||||
private val remoteDataSource: ScheduleRemoteDataSource,
|
||||
private val localDataSource: ScheduleLocalDataSource,
|
||||
private val mapper: ScheduleDtoToDomainMapper
|
||||
) : ScheduleRepository {
|
||||
|
||||
override suspend fun loadScheduleByGroup(groupNumber: String): Schedule {
|
||||
val dto = remoteDataSource.loadScheduleByGroup(groupNumber)
|
||||
return mapper.map(dto)
|
||||
}
|
||||
|
||||
override suspend fun loadScheduleByTeacher(teacherName: String): Schedule {
|
||||
val dto = remoteDataSource.loadScheduleByTeacher(teacherName)
|
||||
return mapper.map(dto)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,20 @@
|
||||
package ru.fincode.tsudesk.feature.schedule.domain.usecase
|
||||
|
||||
class GetScheduleUseCase {
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetScheduleUseCase @Inject constructor(
|
||||
private val repository: ScheduleRepository
|
||||
) {
|
||||
sealed interface ScheduleType {
|
||||
data class Group(val groupNumber: String) : ScheduleType
|
||||
data class Teacher(val teacherName: String) : ScheduleType
|
||||
}
|
||||
|
||||
suspend operator fun invoke(type: ScheduleType): Result<ScheduleEntity> =
|
||||
when (type) {
|
||||
is ScheduleType.Group -> repository.loadScheduleByGroup(type.groupNumber)
|
||||
is ScheduleType.Teacher -> repository.loadScheduleByTeacher(type.teacherName)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ versionName = "1.0"
|
||||
versionCode = "1"
|
||||
|
||||
agp = "8.12.0"
|
||||
kotlin = "2.0.21"
|
||||
kotlin = "1.9.24"
|
||||
jvmTarget = "17"
|
||||
|
||||
coreKtx = "1.10.1"
|
||||
@@ -19,6 +19,10 @@ hilt = "2.50"
|
||||
retrofit = "2.11.0"
|
||||
okhttp = "4.12.0"
|
||||
|
||||
moshi = "1.15.1"
|
||||
lifecycle = "2.7.0"
|
||||
coroutines = "1.8.1"
|
||||
|
||||
[libraries]
|
||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
@@ -34,6 +38,18 @@ hiltandroid = { module = "com.google.dagger:hilt-android", version.ref = "hilt"
|
||||
hiltcompiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
||||
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
|
||||
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
||||
|
||||
|
||||
moshi = { group="com.squareup.moshi", name="moshi", version.ref="moshi" }
|
||||
moshiKotlin = { group="com.squareup.moshi", name="moshi-kotlin", version.ref="moshi" }
|
||||
retrofitMoshi = { group="com.squareup.retrofit2", name="converter-moshi", version.ref="retrofit" }
|
||||
|
||||
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
||||
|
||||
|
||||
|
||||
|
||||
[plugins]
|
||||
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
||||
|
||||
@@ -13,12 +13,13 @@ pluginManagement {
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories(fun RepositoryHandler.() {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rootProject.name = "TSUDesk"
|
||||
include(":app")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user