Skip to content

Commit

Permalink
Merge pull request #86 from kakao-tech-campus-2nd-step3/Develop
Browse files Browse the repository at this point in the history
[Integrate] Weekly8 과제 제출합니다.
  • Loading branch information
aengzu authored Oct 25, 2024
2 parents ef7e5b5 + a507bea commit 04498c7
Show file tree
Hide file tree
Showing 85 changed files with 1,693 additions and 700 deletions.
23 changes: 22 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.util.Properties

plugins {
id("iguana.android.application")
id("org.jetbrains.kotlin.android")
Expand All @@ -19,6 +21,15 @@ android {
targetSdk = 34
}

buildFeatures {
buildConfig = true
}

defaultConfig {
val apiBaseUrl: String = getApiBaseUrl()
buildConfigField("String", "API_BASE_URL", "\"$apiBaseUrl\"")
}

packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
Expand All @@ -40,6 +51,16 @@ dependencies {
implementation(projects.core.designsystem)
implementation(projects.feature.login)
implementation(projects.feature.dashBoard)
implementation(projects.feature.notetaking)
implementation("com.kakao.sdk:v2-user:2.20.6")
}

fun getApiBaseUrl(): String {
val localProperties = project.rootProject.file("local.properties")
if (localProperties.exists()) {
val properties = Properties().apply {
load(localProperties.inputStream())
}
return properties.getProperty("API_BASE_URL", "https://example.com/")
}
return "https://example.com/" // 기본값
}
6 changes: 2 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.INTERNET"/>

<application
android:networkSecurityConfig="@xml/network_security_config"
android:name=".NotaiApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -14,12 +15,9 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Notai.AppTheme"
android:theme="@style/AppTheme"
tools:targetApi="31"
tools:replace="android:theme">
<activity
android:name=".DesignSampleActivity"
android:exported="false" />
<activity
android:name="com.iguana.login.LoginActivity"
android:exported="true">
Expand Down
10 changes: 0 additions & 10 deletions app/src/main/res/values/colors.xml

This file was deleted.

6 changes: 6 additions & 0 deletions app/src/main/res/xml/network_security_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">121.183.242.176</domain>
</domain-config>
</network-security-config>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal fun Project.configureKotlinAndroid() {
compileSdkVersion(34)

defaultConfig {
minSdk = 24
minSdk = 26
}

compileOptions {
Expand Down
25 changes: 25 additions & 0 deletions core/data/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import java.util.Properties

plugins {
id("iguana.android.library")
id("iguana.android.hilt")
id("iguana.kotlin.hilt")
id("dagger.hilt.android.plugin")
alias(libs.plugins.kotlin.android)
id("kotlin-kapt")
}

android {
namespace = "com.iguana.data"

buildFeatures {
buildConfig = true
}

defaultConfig {
val apiBaseUrl: String = getApiBaseUrl()
buildConfigField("String", "API_BASE_URL", "\"$apiBaseUrl\"")
}
}
dependencies {
implementation(libs.retrofit.core)
Expand All @@ -18,4 +31,16 @@ dependencies {
implementation(libs.coroutines.android)
implementation(projects.core.domain) // domain 에 있는 걸 구현하므로
implementation(libs.okhttp.logging)
}

// local.properties 파일에서 API_BASE_URL 읽어오는 함수
fun getApiBaseUrl(): String {
val localProperties = project.rootProject.file("local.properties")
if (localProperties.exists()) {
val properties = Properties().apply {
load(localProperties.inputStream())
}
return properties.getProperty("API_BASE_URL", "https://example.com/")
}
return "https://example.com/" // 기본값
}
14 changes: 14 additions & 0 deletions core/data/src/main/java/com/iguana/data/di/AuthInterceptor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iguana.data.di

import okhttp3.Interceptor
import okhttp3.Response

class AuthInterceptor(private val tokenProvider: () -> String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val token = tokenProvider()
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
return chain.proceed(request)
}
}
23 changes: 21 additions & 2 deletions core/data/src/main/java/com/iguana/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.iguana.data.di

import com.iguana.data.BuildConfig
import com.iguana.data.remote.api.AnnotationApi
import com.iguana.data.remote.api.DocumentApi
import com.iguana.data.remote.api.SummarizeApi
import com.iguana.domain.repository.SharedPreferencesHelper
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton
Expand All @@ -16,9 +20,18 @@ object NetworkModule {

@Provides
@Singleton
fun provideRetrofit(): Retrofit {
fun provideOkHttpClient(sharedPreferencesHelper: SharedPreferencesHelper): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(AuthInterceptor { sharedPreferencesHelper.getAccessToken() ?: "" })
.build()
}

@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl("https://example.com/") // 실제 API URL로 변경 필요
.baseUrl(BuildConfig.API_BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
Expand All @@ -40,4 +53,10 @@ object NetworkModule {
fun provideAnnotationApi(retrofit: Retrofit): AnnotationApi {
return retrofit.create(AnnotationApi::class.java)
}

@Provides
@Singleton
fun provideSummarizeApi(retrofit: Retrofit): SummarizeApi {
return retrofit.create(SummarizeApi::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.iguana.data.di

import com.iguana.data.repository.AIRepositoryImpl
import com.iguana.data.repository.AnnotationRepositoryImpl
import com.iguana.data.repository.DocumentsRepositoryImpl
import com.iguana.data.repository.LoginRepositoryImpl
import com.iguana.data.repository.RecentFileRepositoryImpl
import com.iguana.domain.repository.AIRepository
import com.iguana.domain.repository.AnnotationRepository
import com.iguana.domain.repository.DocumentsRepository
import com.iguana.domain.repository.LoginRepository
Expand Down Expand Up @@ -40,4 +42,10 @@ abstract class RepositoryModule {
abstract fun bindLoginRepository(
loginRepositoryImpl: LoginRepositoryImpl
): LoginRepository

@Binds
@Singleton
abstract fun bindAIRepository(
aiRepositoryImpl: AIRepositoryImpl
): AIRepository
}
14 changes: 0 additions & 14 deletions core/data/src/main/java/com/iguana/data/local/db/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,4 @@ import kotlinx.coroutines.launch
@Database(entities = [RecentFileEntity::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun recentFileDao(): RecentFileDao

private class AppDatabaseCallback(private val database: AppDatabase, private val scope: CoroutineScope) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
scope.launch(Dispatchers.IO) {
populateDatabase(database.recentFileDao())
}
}

suspend fun populateDatabase(recentFileDao: RecentFileDao) {
// 데이터베이스가 생성될 때 초기 데이터를 삽입하거나 다른 설정을 수행할 수 있습니다.
// 예: recentFileDao.insertRecentFile(RecentFileEntity(...))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ class SharedPreferencesHelperImpl @Inject constructor(
return sharedPreferences.getString(KEY_ACCESS_TOKEN, null)
}

override fun getRefreshToken(): String? {
return sharedPreferences.getString(KEY_REFRESH_TOKEN, null)
}

override fun isLoggedIn(): Boolean {
return getAccessToken() != null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,33 @@ class RecordingFileStorage @Inject constructor(
) {

// 로컬 스토리지에 녹음 파일 저장
fun saveRecordingFile(file: File): Result<Unit> {
return try {
val destination = File(baseDir, file.name)
file.copyTo(destination, overwrite = true)
Result.success(Unit)
} catch (e: Exception) {
Result.failure(e)
}
fun saveRecordingFile(file: File) {
val destination = File(baseDir, file.name)
file.copyTo(destination, overwrite = true)
}

// 페이지 이동 이벤트 저장
fun savePageTurnEvents(recordingId: Long, events: List<PageTurnEventDto>): Result<Unit> {
return try {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
file.writeText(events.joinToString(separator = "\n") { event ->
"${event.prevPage},${event.nextPage},${event.timestamp}"
})
Result.success(Unit)
} catch (e: Exception) {
Result.failure(e)
}
fun savePageTurnEvents(recordingId: Long, events: List<PageTurnEventDto>) {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
file.writeText(events.joinToString(separator = "\n") { event ->
"${event.prevPage},${event.nextPage},${event.timestamp}"
})
}

// 로컬 스토리지에서 페이지 이동 이벤트 삭제
fun deletePageTurnEvents(recordingId: Long): Result<Unit> {
return try {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
if (file.exists()) {
file.delete()
Result.success(Unit)
} else {
Result.failure(AppError.FileNotFound)
}
} catch (e: Exception) {
Result.failure(e)
fun deletePageTurnEvents(recordingId: Long) {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
if (file.exists()) {
file.delete()
Result.success(Unit)
} else {
throw AppError.FileNotFound
}
}

// 파일 존재 여부 확인 함수
fun isFileExists(filePath: String): Boolean {
val file = File(filePath)
return file.exists()
}
}
55 changes: 55 additions & 0 deletions core/data/src/main/java/com/iguana/data/mapper/SummarizeMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.iguana.data.mapper

import com.iguana.data.remote.model.*
import com.iguana.domain.model.ai.AIResult
import com.iguana.domain.model.ai.AIStatusResult
import com.iguana.domain.model.ai.AIStatusResultByPage
import com.iguana.domain.model.ai.SummarizationStatus

// 요약 결과 매퍼
fun SummarizeResultsResponseDto.toDomain(): List<AIResult> {
return results.map { pageResult ->
AIResult(
documentId = this.documentId,
pageNumber = pageResult.pageNumber,
summary = pageResult.content.summary,
problem = pageResult.content.problem
)
}
}

// 상태 체크 응답 매퍼
fun StatusCheckResponseDto.toDomain(): AIStatusResult {
return AIStatusResult(
documentId = this.documentId,
overallStatus = when (this.overallStatus) {
"IN_PROGRESS" -> SummarizationStatus.IN_PROGRESS
"COMPLETED" -> SummarizationStatus.COMPLETED
else -> SummarizationStatus.FAILED
},
totalPages = this.totalPages,
completedPages = this.completedPages
)
}

// 상태 체크 응답 (페이지별) 매퍼
fun StatusCheckByPageResponseDto.toDomain(): AIStatusResultByPage {
return AIStatusResultByPage(
status = when (this.status) {
"IN_PROGRESS" -> SummarizationStatus.IN_PROGRESS
"COMPLETED" -> SummarizationStatus.COMPLETED
"NOT_REQUESTED" -> SummarizationStatus.NOT_REQUESTED
else -> SummarizationStatus.FAILED
}
)
}

// 요약 결과 (페이지별) 매퍼
fun SummarizeResultsByPageResponseDto.toDomain(documentId:Long, pageNumber: Int): AIResult {
return AIResult(
documentId = documentId,
pageNumber = pageNumber,
summary = this.summary,
problem = this.problem
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import com.iguana.data.remote.model.FolderContentResponseDto
import com.iguana.data.remote.model.MoveFolderRequestDto
import com.iguana.domain.model.FolderContentItem
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.*

interface DocumentApi {
@Multipart
@POST("/api/folders/{folderId}/document")
@POST("/api/folders/{folderId}/documents")
suspend fun uploadDocument(
@Path("folderId") folderId: Long,
@Part file: MultipartBody.Part
@Part pdfFile: MultipartBody.Part,
@Part("documentSaveRequest") documentSaveRequest: RequestBody
): DocumentDto

@GET("/api/folders/{folderId}")
Expand Down
Loading

0 comments on commit 04498c7

Please sign in to comment.