From 04b8164ebaf794835fc04245319cd535c1e308d2 Mon Sep 17 00:00:00 2001 From: Shcherbatykh Oleg Date: Tue, 10 Feb 2026 20:20:39 +0300 Subject: [PATCH] Start Schedule development --- .../java/ru/fincode/tsudesk/MainActivity.kt | 19 ++++------- .../core/network/HttpClientProvider.kt | 10 ------ .../tsudesk/core/network/NetworkModule.kt | 34 +++++++++++++++++++ .../tsudesk/core/network/RetrofitProvider.kt | 7 ++-- .../tsudesk/core/network/di/NetworkModule.kt | 25 -------------- .../schedule/data/ScheduleRepositoryImpl.kt | 21 ++++++++++-- .../datasource/ScheduleLocalDataSource.kt | 10 ++++-- .../datasource/ScheduleRemoteDataSource.kt | 20 +++++++++-- .../ScheduleRemoteDataSourceImpl.kt | 20 +++++++++++ .../data/mapper/ScheduleDtoToDomainMapper.kt | 21 +++++++++++- .../mapper/ScheduleEntityToDomainMapper.kt | 4 --- .../schedule/data/remote/ScheduleApi.kt | 18 ++++++++-- .../schedule/data/remote/ScheduleDto.kt | 15 ++++++-- .../schedule/data/remote/ScheduleXmlParser.kt | 15 ++++++-- .../feature/schedule/domain/model/Lesson.kt | 4 --- .../feature/schedule/domain/model/Schedule.kt | 17 ++++++++-- .../schedule/domain/model/ScheduleDay.kt | 4 --- .../domain/repository/ScheduleRepository.kt | 5 +-- .../repository/ScheduleRepositoryImpl.kt | 24 +++++++++++++ 19 files changed, 214 insertions(+), 79 deletions(-) delete mode 100644 core/network/src/main/java/ru/fincode/tsudesk/core/network/HttpClientProvider.kt create mode 100644 core/network/src/main/java/ru/fincode/tsudesk/core/network/NetworkModule.kt delete mode 100644 core/network/src/main/java/ru/fincode/tsudesk/core/network/di/NetworkModule.kt create mode 100644 feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSourceImpl.kt delete mode 100644 feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleEntityToDomainMapper.kt delete mode 100644 feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Lesson.kt delete mode 100644 feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/ScheduleDay.kt create mode 100644 feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepositoryImpl.kt diff --git a/app/src/main/java/ru/fincode/tsudesk/MainActivity.kt b/app/src/main/java/ru/fincode/tsudesk/MainActivity.kt index 39f80fa..ac0d030 100644 --- a/app/src/main/java/ru/fincode/tsudesk/MainActivity.kt +++ b/app/src/main/java/ru/fincode/tsudesk/MainActivity.kt @@ -6,23 +6,16 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +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 + + class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_main) - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets - } - val okHttpClient = HttpClientProvider.provide() - - val retrofit = RetrofitProvider.provide( - baseUrl = NetworkConstants.BASE_URL, - client = okHttpClient - ) - - val api = retrofit.create(ScheduleApi::class.java) } } \ No newline at end of file diff --git a/core/network/src/main/java/ru/fincode/tsudesk/core/network/HttpClientProvider.kt b/core/network/src/main/java/ru/fincode/tsudesk/core/network/HttpClientProvider.kt deleted file mode 100644 index f8681ad..0000000 --- a/core/network/src/main/java/ru/fincode/tsudesk/core/network/HttpClientProvider.kt +++ /dev/null @@ -1,10 +0,0 @@ -package ru.fincode.tsudesk.core.network - -object HttpClientProvider { - - fun provide(): OkHttpClient = - OkHttpClient.Builder() - .connectTimeout(15, TimeUnit.SECONDS) - .readTimeout(15, TimeUnit.SECONDS) - .build() -} \ No newline at end of file diff --git a/core/network/src/main/java/ru/fincode/tsudesk/core/network/NetworkModule.kt b/core/network/src/main/java/ru/fincode/tsudesk/core/network/NetworkModule.kt new file mode 100644 index 0000000..d9dca1e --- /dev/null +++ b/core/network/src/main/java/ru/fincode/tsudesk/core/network/NetworkModule.kt @@ -0,0 +1,34 @@ +package ru.fincode.tsudesk.core.network + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import java.util.concurrent.TimeUnit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object NetworkModule { + + private const val TIMEOUT_SEC = 30L + + @Provides + @Singleton + fun provideOkHttpClient(): OkHttpClient = + OkHttpClient.Builder() + .connectTimeout(TIMEOUT_SEC, TimeUnit.SECONDS) + .readTimeout(TIMEOUT_SEC, TimeUnit.SECONDS) + .writeTimeout(TIMEOUT_SEC, TimeUnit.SECONDS) + .retryOnConnectionFailure(true) + .build() + + @Provides + fun provideRetrofit( + provider: RetrofitProvider, + client: OkHttpClient + ): Retrofit = provider.process(NetworkConstants.BASE_URL, client) + +} \ No newline at end of file diff --git a/core/network/src/main/java/ru/fincode/tsudesk/core/network/RetrofitProvider.kt b/core/network/src/main/java/ru/fincode/tsudesk/core/network/RetrofitProvider.kt index 9946976..4ccd2f3 100644 --- a/core/network/src/main/java/ru/fincode/tsudesk/core/network/RetrofitProvider.kt +++ b/core/network/src/main/java/ru/fincode/tsudesk/core/network/RetrofitProvider.kt @@ -1,8 +1,11 @@ package ru.fincode.tsudesk.core.network -object RetrofitProvider { +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.simplexml.SimpleXmlConverterFactory - fun provide(baseUrl: String, client: OkHttpClient): Retrofit = +class RetrofitProvider { + fun process(baseUrl: String, client: OkHttpClient): Retrofit = Retrofit.Builder() .baseUrl(baseUrl) .client(client) diff --git a/core/network/src/main/java/ru/fincode/tsudesk/core/network/di/NetworkModule.kt b/core/network/src/main/java/ru/fincode/tsudesk/core/network/di/NetworkModule.kt deleted file mode 100644 index 2ae3a28..0000000 --- a/core/network/src/main/java/ru/fincode/tsudesk/core/network/di/NetworkModule.kt +++ /dev/null @@ -1,25 +0,0 @@ -package ru.fincode.tsudesk.core.network.di - -import okhttp3.OkHttpClient -import retrofit2.Retrofit -import ru.fincode.tsudesk.core.network.HttpClientProvider -import ru.fincode.tsudesk.core.network.NetworkConstants -import ru.fincode.tsudesk.core.network.RetrofitProvider - -@Module -@InstallIn(SingletonComponent::class) -object NetworkModule { - - @Provides - @Singleton - fun provideOkHttpClient(): OkHttpClient = - HttpClientProvider.provide() - - @Provides - @Singleton - fun provideRetrofit(client: OkHttpClient): Retrofit = - RetrofitProvider.provide( - baseUrl = NetworkConstants.BASE_URL, - client = client - ) -} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/ScheduleRepositoryImpl.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/ScheduleRepositoryImpl.kt index 08770a2..21ae38e 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/ScheduleRepositoryImpl.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/ScheduleRepositoryImpl.kt @@ -1,4 +1,21 @@ package ru.fincode.tsudesk.feature.schedule.data -class ScheduleRepositoryImpl { -} \ No newline at end of file +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.repository.ScheduleRepository +import javax.inject.Inject + +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)) + } + +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleLocalDataSource.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleLocalDataSource.kt index 80992b3..435171d 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleLocalDataSource.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleLocalDataSource.kt @@ -1,4 +1,10 @@ package ru.fincode.tsudesk.feature.schedule.data.datasource -class ScheduleLocalDataSource { -} \ No newline at end of file +import ru.fincode.tsudesk.feature.schedule.data.local.ScheduleEntity +import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleDto + +interface ScheduleLocalDataSource { + suspend fun getScheduleByGroup(groupNumber: String): ScheduleEntity? + suspend fun getScheduleByTeacherName(teacherName: String): ScheduleEntity? + suspend fun saveSchedule(entity: ScheduleEntity) +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSource.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSource.kt index f6de75f..a25b861 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSource.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSource.kt @@ -1,4 +1,20 @@ package ru.fincode.tsudesk.feature.schedule.data.datasource -class ScheduleRemoteDataSource { -} \ No newline at end of file +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 + +class ScheduleRemoteDataSource( + private val api: ScheduleApi, private val xmlParser: ScheduleXmlParser +) { + suspend fun loadScheduleByGroup(groupNumber: String): ScheduleDto { + val response = api.getScheduleByGroup(groupNumber) + return xmlParser.parse(response.body() ?: throw IOException("Response body is null")) + } + + suspend fun loadScheduleByTeacher(name: String): ScheduleDto { + val response = api.getScheduleByTeacherName(name) + return xmlParser.parse(response.body() ?: throw IOException("Response body is null")) + } +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSourceImpl.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSourceImpl.kt new file mode 100644 index 0000000..300d3be --- /dev/null +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/datasource/ScheduleRemoteDataSourceImpl.kt @@ -0,0 +1,20 @@ +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.repository.ScheduleRepository +import javax.inject.Inject + +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)); + } +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleDtoToDomainMapper.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleDtoToDomainMapper.kt index 64fdc82..94410dc 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleDtoToDomainMapper.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleDtoToDomainMapper.kt @@ -1,4 +1,23 @@ package ru.fincode.tsudesk.feature.schedule.data.mapper +import ru.fincode.tsudesk.feature.schedule.data.remote.ScheduleDto +import ru.fincode.tsudesk.feature.schedule.domain.model.Lesson +import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule + class ScheduleDtoToDomainMapper { -} \ No newline at end of file + + fun map(dto: ScheduleDto): Schedule = + Schedule( + lessons = dto.lessons.map { l -> + Lesson( + dayOfWeek = l.dayOfWeek, + dayName = l.dayName, + weekType = l.weekType, + time = l.time, + room = l.room, + subjectName = l.subjectName, + teacherName = l.teacherName + ) + } + ) +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleEntityToDomainMapper.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleEntityToDomainMapper.kt deleted file mode 100644 index ee59197..0000000 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/mapper/ScheduleEntityToDomainMapper.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ru.fincode.tsudesk.feature.schedule.data.mapper - -class ScheduleEntityToDomainMapper { -} \ No newline at end of file diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleApi.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleApi.kt index d4efe4b..f920c30 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleApi.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleApi.kt @@ -1,4 +1,18 @@ package ru.fincode.tsudesk.feature.schedule.data.remote -class ScheduleApi { -} \ No newline at end of file +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Query + +interface ScheduleApi { + @GET("schedule") + suspend fun getScheduleByGroup( + @Query("group") groupNumber: String + ): Response + + @GET("schedule") + suspend fun getScheduleByTeacherName( + @Query("fio") teacherName: String + ): Response +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleDto.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleDto.kt index 73a5ce4..051f919 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleDto.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleDto.kt @@ -1,4 +1,15 @@ package ru.fincode.tsudesk.feature.schedule.data.remote -class ScheduleDto { -} \ No newline at end of file +data class ScheduleDto( + val lessons: List +) + +data class LessonDto( + val dayOfWeek: String, + val dayName: String, + val time: String, + val room: String, + val subjectName: String, + val teacherName: String, + val weekType: Int +) diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleXmlParser.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleXmlParser.kt index c344b81..ba1bc1f 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleXmlParser.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/data/remote/ScheduleXmlParser.kt @@ -1,4 +1,15 @@ package ru.fincode.tsudesk.feature.schedule.data.remote -class ScheduleXmlParser { -} \ No newline at end of file +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()) + } +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Lesson.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Lesson.kt deleted file mode 100644 index e9eb8b8..0000000 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Lesson.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ru.fincode.tsudesk.feature.schedule.domain.model - -class Lesson { -} \ No newline at end of file diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Schedule.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Schedule.kt index beac111..5993bf1 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Schedule.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/Schedule.kt @@ -1,4 +1,17 @@ package ru.fincode.tsudesk.feature.schedule.domain.model -class Schedule { -} \ No newline at end of file +data class Schedule( + val lessons: List +) + +data class Lesson( + val dayOfWeek: String, + val dayName: String, + val time: String, + val room: String, + val subjectName: String, + val teacherName: String, + val weekType: Int +) + + diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/ScheduleDay.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/ScheduleDay.kt deleted file mode 100644 index c843eba..0000000 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/model/ScheduleDay.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ru.fincode.tsudesk.feature.schedule.domain.model - -class ScheduleDay { -} \ No newline at end of file diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepository.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepository.kt index f1b92ca..6f47845 100644 --- a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepository.kt +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepository.kt @@ -3,5 +3,6 @@ package ru.fincode.tsudesk.feature.schedule.domain.repository import ru.fincode.tsudesk.feature.schedule.domain.model.Schedule interface ScheduleRepository { - suspend fun getSchedule(groupId: String): Schedule -} \ No newline at end of file + suspend fun loadScheduleByGroup(groupNumber: String): Schedule + suspend fun loadScheduleByTeacher(teacherName: String): Schedule +} diff --git a/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepositoryImpl.kt b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepositoryImpl.kt new file mode 100644 index 0000000..cc08215 --- /dev/null +++ b/feature/schedule/src/main/java/ru/fincode/tsudesk/feature/schedule/domain/repository/ScheduleRepositoryImpl.kt @@ -0,0 +1,24 @@ +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) + } +}