From 1e66246020459afe41844df18d96040097d244fe Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Sun, 17 May 2026 08:23:57 +0330 Subject: [PATCH] feat: seprate retrofit --- .../drug/data/remote/DarooyabApiService.kt | 17 ++++++++ .../drug/data/remote/DrugApiService.kt | 10 ----- .../data/repository/DrugRepositoryImpl.kt | 34 +++++++++++++++- .../java/com/approagency/drug/di/AppModule.kt | 40 ++++++++++++++++++- .../drug/domain/repository/DrugRepository.kt | 2 + .../domain/usecase/SearchDrugsYabUseCase.kt | 15 +++++++ .../java/com/approagency/drug/utils/Config.kt | 1 + 7 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/com/approagency/drug/data/remote/DarooyabApiService.kt create mode 100644 app/src/main/java/com/approagency/drug/domain/usecase/SearchDrugsYabUseCase.kt diff --git a/app/src/main/java/com/approagency/drug/data/remote/DarooyabApiService.kt b/app/src/main/java/com/approagency/drug/data/remote/DarooyabApiService.kt new file mode 100644 index 0000000..17242b5 --- /dev/null +++ b/app/src/main/java/com/approagency/drug/data/remote/DarooyabApiService.kt @@ -0,0 +1,17 @@ +package com.approagency.drug.data.remote + +import retrofit2.http.GET +import retrofit2.http.Headers +import retrofit2.http.Query + +interface DarooyabApiService { + @GET("Search") + @Headers( + "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Language: en-US,en;q=0.5" + ) + suspend fun searchDrugs( + @Query("SearchText") searchText: String + ): String // Returns raw HTML for the first page +} \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/data/remote/DrugApiService.kt b/app/src/main/java/com/approagency/drug/data/remote/DrugApiService.kt index 84dd236..c61a8a1 100644 --- a/app/src/main/java/com/approagency/drug/data/remote/DrugApiService.kt +++ b/app/src/main/java/com/approagency/drug/data/remote/DrugApiService.kt @@ -28,14 +28,4 @@ interface DrugApiService { @GET("drugs/goroh-darmani") suspend fun getGorohDaroei(): DarmanModel - - @GET("Search") - @Headers( - "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", - "Accept-Language: en-US,en;q=0.5" - ) - suspend fun searchDrugs( - @Query("SearchText") searchText: String - ): String // Returns raw HTML for the first page } \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/data/repository/DrugRepositoryImpl.kt b/app/src/main/java/com/approagency/drug/data/repository/DrugRepositoryImpl.kt index 1c67c77..c0f1e91 100644 --- a/app/src/main/java/com/approagency/drug/data/repository/DrugRepositoryImpl.kt +++ b/app/src/main/java/com/approagency/drug/data/repository/DrugRepositoryImpl.kt @@ -3,12 +3,20 @@ package com.approagency.drug.data.repository import com.approagency.drug.data.dto.DarmanModel import com.approagency.drug.data.dto.DrugListResponse import com.approagency.drug.data.dto.DrugModels +import com.approagency.drug.data.remote.DarooyabApiService import com.approagency.drug.data.remote.DrugApiService +import com.approagency.drug.data.remote.DrugHtmlParser import com.approagency.drug.domain.model.DrugSearchParams +import com.approagency.drug.domain.model.DrugSearchResult import com.approagency.drug.domain.repository.DrugRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.IOException class DrugRepositoryImpl( - private val apiService: DrugApiService + private val apiService: DrugApiService, + private val darooyabApiService: DarooyabApiService, + private val parser: DrugHtmlParser ): DrugRepository { override suspend fun searchDrug(params: DrugSearchParams): Result { return try { @@ -36,4 +44,28 @@ class DrugRepositoryImpl( Result.failure(e) } } + + override suspend fun searchDrugs(params: DrugSearchParams): Result> { + return withContext(Dispatchers.IO) { + try { + // 1. Fetch raw HTML from the website + val htmlResponse = darooyabApiService.searchDrugs(params.query!!) + + // 2. Parse the HTML to extract drug data + val drugList = parser.parseSearchResults(htmlResponse) + + if (drugList.isNotEmpty()) { + Result.success(drugList) + } else { + Result.failure(Exception("No drugs found for query: '${params.query}'")) + } + } catch (e: IOException) { + // Network error + Result.failure(Exception("Network error: ${e.message}", e)) + } catch (e: Exception) { + // Parsing or other error + Result.failure(Exception("An error occurred: ${e.message}", e)) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/di/AppModule.kt b/app/src/main/java/com/approagency/drug/di/AppModule.kt index 0f3eb4f..3b7b5cc 100644 --- a/app/src/main/java/com/approagency/drug/di/AppModule.kt +++ b/app/src/main/java/com/approagency/drug/di/AppModule.kt @@ -3,7 +3,9 @@ package com.approagency.drug.di import android.app.Application import com.approagency.drug.data.local.database.LabDatabase +import com.approagency.drug.data.remote.DarooyabApiService import com.approagency.drug.data.remote.DrugApiService +import com.approagency.drug.data.remote.DrugHtmlParser import com.approagency.drug.data.repository.DrugRepositoryImpl import com.approagency.drug.data.repository.LabRepositoryImpl import com.approagency.drug.domain.repository.DrugRepository @@ -12,15 +14,19 @@ import com.approagency.drug.domain.usecase.GetDrugDetailUseCase import com.approagency.drug.domain.usecase.GetDrugSearchUseCase import com.approagency.drug.domain.usecase.GetTestGroupUseCase import com.approagency.drug.domain.usecase.GetTestItemByGroupId +import com.approagency.drug.domain.usecase.SearchDrugsYabUseCase import com.approagency.drug.domain.usecase.SearchTestsUseCase import com.approagency.drug.presentation.viewModel.HomeViewModel import com.approagency.drug.presentation.viewModel.LabViewModel import com.approagency.drug.utils.Config +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import org.koin.android.ext.koin.androidContext import org.koin.core.module.dsl.viewModel import org.koin.dsl.module import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit val appModule= module { @@ -29,19 +35,47 @@ val appModule= module { single { get().testGroupDao() } single { get().testItemDao() } + single { + OkHttpClient.Builder() + .addInterceptor(HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BASIC + }) + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build() + } + + // ========== Retrofit for YOUR API ========== single { Retrofit.Builder() .baseUrl(Config.BASE_URL) + .client(get()) .addConverterFactory(GsonConverterFactory.create()) .build() } + single { get().create(DrugApiService::class.java) } + // ========== Retrofit for DAROOYAB Website API ========== + single { + Retrofit.Builder() + .baseUrl(Config.Darro_Url) // Darooyab base URL + .client(get()) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .let { retrofit -> + retrofit.create(DarooyabApiService::class.java) + } + } + + + factory { DrugHtmlParser() } + //repo single { - DrugRepositoryImpl(get()) + DrugRepositoryImpl(get() , get() , get()) } @@ -52,6 +86,10 @@ val appModule= module { } + single { + SearchDrugsYabUseCase(get()) + } + single{ GetDrugDetailUseCase(get()) } diff --git a/app/src/main/java/com/approagency/drug/domain/repository/DrugRepository.kt b/app/src/main/java/com/approagency/drug/domain/repository/DrugRepository.kt index d0790b0..2033283 100644 --- a/app/src/main/java/com/approagency/drug/domain/repository/DrugRepository.kt +++ b/app/src/main/java/com/approagency/drug/domain/repository/DrugRepository.kt @@ -4,9 +4,11 @@ import com.approagency.drug.data.dto.DarmanModel import com.approagency.drug.data.dto.DrugListResponse import com.approagency.drug.data.dto.DrugModels import com.approagency.drug.domain.model.DrugSearchParams +import com.approagency.drug.domain.model.DrugSearchResult interface DrugRepository { suspend fun searchDrug(params: DrugSearchParams): Result suspend fun drugDetail(cod:Int): Result suspend fun getGorohDaroei(): Result + suspend fun searchDrugs(params:DrugSearchParams):Result> } \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/domain/usecase/SearchDrugsYabUseCase.kt b/app/src/main/java/com/approagency/drug/domain/usecase/SearchDrugsYabUseCase.kt new file mode 100644 index 0000000..93ead65 --- /dev/null +++ b/app/src/main/java/com/approagency/drug/domain/usecase/SearchDrugsYabUseCase.kt @@ -0,0 +1,15 @@ +package com.approagency.drug.domain.usecase + +import com.approagency.drug.data.repository.DrugRepositoryImpl +import com.approagency.drug.domain.model.DrugSearchParams +import com.approagency.drug.domain.model.DrugSearchResult +import com.approagency.drug.domain.repository.DrugRepository + +class SearchDrugsYabUseCase ( + private val repository: DrugRepository +) { + suspend operator fun invoke(query: String): Result> { + val params = DrugSearchParams(query = query) + return repository.searchDrugs(params) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/utils/Config.kt b/app/src/main/java/com/approagency/drug/utils/Config.kt index 4a4d950..e9ca851 100644 --- a/app/src/main/java/com/approagency/drug/utils/Config.kt +++ b/app/src/main/java/com/approagency/drug/utils/Config.kt @@ -2,4 +2,5 @@ package com.approagency.drug.utils object Config { const val BASE_URL = "https://drug.approagency.ir/api/" + const val Darro_Url = "https://www.darooyab.ir/" } \ No newline at end of file