diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..fde12b1d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,6 @@ +## Please include a summary of your changes. + + +## Before merging: +* [ ] If this PR targets dev branch, do a Squash-merge. +* [ ] If the target branch is prod, do a Regular merge. diff --git a/fetcher-web/Dockerfile b/fetcher-web/Dockerfile index 34751257..c706e348 100644 --- a/fetcher-web/Dockerfile +++ b/fetcher-web/Dockerfile @@ -1,10 +1,12 @@ -FROM gradle:6.9-jdk11 AS builder +FROM gradle:7.6-jdk11 AS builder COPY . /fetcher-web WORKDIR /fetcher-web RUN gradle build FROM openjdk:11-jre-slim +RUN apt update && apt install git -y + RUN mkdir /app COPY --from=builder /fetcher-web/build/libs/bible-translation-tools_fetcher.jar /app/fetcher.jar diff --git a/fetcher-web/build.gradle b/fetcher-web/build.gradle index 88561f11..0f84f95d 100644 --- a/fetcher-web/build.gradle +++ b/fetcher-web/build.gradle @@ -17,12 +17,13 @@ plugins { id 'io.gitlab.arturbosch.detekt' version "$detekt_ver" id 'org.jlleitschuh.gradle.ktlint' version "$ktlint_ver" id 'com.github.johnrengelman.shadow' version "$shadowjar_ver" + id 'com.apollographql.apollo3' version "$graphql_ver" } apply plugin: 'application' group 'org.bibletranslationtools' -version '0.1.0' +version '0.2.0' sourceCompatibility = 11 @@ -56,6 +57,7 @@ dependencies { implementation "me.xdrop:fuzzywuzzy:$fuzzy_wuzzy_ver" implementation "io.insert-koin:koin-ktor:$koin_ver" implementation "net.lingala.zip4j:zip4j:$zip4j_ver" + implementation "com.apollographql.apollo3:apollo-runtime:$graphql_ver" detektPlugins "io.gitlab.arturbosch.detekt:detekt-formatting:$detekt_ver" implementation "org.jetbrains.kotlinx:kotlinx-html-jvm:$kotlinx_html_ver" // detekt report @@ -91,3 +93,9 @@ shadowJar { ) } } + +apollo { + service("service") { + packageName.set("org.bibletranslationtools.fetcher.graphql.generated") + } +} diff --git a/fetcher-web/dependencies.gradle b/fetcher-web/dependencies.gradle index 28ab9769..7388f7d0 100644 --- a/fetcher-web/dependencies.gradle +++ b/fetcher-web/dependencies.gradle @@ -3,10 +3,10 @@ ext { detekt_ver = '1.16.0' kotlinx_html_ver='0.7.2' // detekt report ktlint_ver = '9.2.1' - shadowjar_ver = '5.2.0' + shadowjar_ver = '7.1.2' // Libraries - kotlin_ver = '1.3.72' + kotlin_ver = '1.6.0' ktor_ver = '1.5.2' thymeleaf_ver = '3.0.11.RELEASE' jackson_csv_ver = '2.8.8' @@ -21,6 +21,7 @@ ext { fuzzy_wuzzy_ver='1.3.1' koin_ver='3.0.1-beta-2' zip4j_ver='2.7.0' + graphql_ver='3.7.5' system_lambda_ver='1.2.0' } \ No newline at end of file diff --git a/fetcher-web/gradle/wrapper/gradle-wrapper.properties b/fetcher-web/gradle/wrapper/gradle-wrapper.properties index 20dd3678..c0a5b465 100644 --- a/fetcher-web/gradle/wrapper/gradle-wrapper.properties +++ b/fetcher-web/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ #Fri Jun 26 15:59:28 EDT 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/fetcher-web/src/main/graphql/GetPrimaryRepos.graphql b/fetcher-web/src/main/graphql/GetPrimaryRepos.graphql new file mode 100644 index 00000000..87f83fe0 --- /dev/null +++ b/fetcher-web/src/main/graphql/GetPrimaryRepos.graphql @@ -0,0 +1,21 @@ +query GetPrimaryReposQuery { + GitRepos: git_repo( + where: { + content: { + wa_content_metadata: { + status: { + _eq: "Primary" + } + } + } + } + ) { + repoUrl: repo_url + content { + resourceType: resource_type + language { + languageCode: ietf_code + } + } + } +} \ No newline at end of file diff --git a/fetcher-web/src/main/graphql/GetPrimaryRepos.graphqls b/fetcher-web/src/main/graphql/GetPrimaryRepos.graphqls new file mode 100644 index 00000000..4731688b --- /dev/null +++ b/fetcher-web/src/main/graphql/GetPrimaryRepos.graphqls @@ -0,0 +1,62 @@ +schema { + query: Query +} + +input String_comparison_exp { + _eq: String +} + +input git_repo_bool_exp { + _and: [git_repo_bool_exp!] + _not: git_repo_bool_exp + _or: [git_repo_bool_exp!] + content: content_bool_exp + repo_name: String_comparison_exp + repo_url: String_comparison_exp +} + +input content_bool_exp { + _and: [content_bool_exp!] + _not: content_bool_exp + _or: [content_bool_exp!] + language: language_bool_exp + resource_type: String_comparison_exp + wa_content_metadata: wa_content_metadata_bool_exp +} + +input wa_content_metadata_bool_exp { + _and: [wa_content_metadata_bool_exp!] + _not: wa_content_metadata_bool_exp + _or: [wa_content_metadata_bool_exp!] + status: String_comparison_exp +} + +input language_bool_exp { + _and: [language_bool_exp!] + _not: language_bool_exp + _or: [language_bool_exp!] + ietf_code: String_comparison_exp +} + +type Query { + git_repo(where: git_repo_bool_exp): [Repo!]! +} + +type Repo { + repo_url: String + content: Content +} + +type Content { + language: Language + resource_type: String + wa_content_metadata: [ContentMetadata] +} + +type Language { + ietf_code: String +} + +type ContentMetadata { + status: String +} \ No newline at end of file diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/di/DIModule.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/di/DIModule.kt index ef4dd5e8..b3575cba 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/di/DIModule.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/di/DIModule.kt @@ -2,28 +2,29 @@ package org.bibletranslationtools.fetcher.di import org.bibletranslationtools.fetcher.config.DevEnvironmentConfig import org.bibletranslationtools.fetcher.config.EnvironmentConfig -import org.bibletranslationtools.fetcher.impl.repository.AvailabilityCacheAccessor import org.bibletranslationtools.fetcher.impl.repository.BookCatalogImpl import org.bibletranslationtools.fetcher.impl.repository.BookRepositoryImpl import org.bibletranslationtools.fetcher.impl.repository.ChapterCatalogImpl -import org.bibletranslationtools.fetcher.impl.repository.ContentAvailabilityCacheBuilder import org.bibletranslationtools.fetcher.impl.repository.DirectoryProviderImpl +import org.bibletranslationtools.fetcher.impl.repository.LangType import org.bibletranslationtools.fetcher.impl.repository.LanguageRepositoryImpl -import org.bibletranslationtools.fetcher.impl.repository.PortGatewayLanguageCatalog import org.bibletranslationtools.fetcher.impl.repository.ProductCatalogImpl +import org.bibletranslationtools.fetcher.impl.repository.RequestResourceContainerImpl import org.bibletranslationtools.fetcher.impl.repository.RCRepositoryImpl +import org.bibletranslationtools.fetcher.impl.repository.SourceTextAccessorImpl import org.bibletranslationtools.fetcher.impl.repository.StorageAccessImpl -import org.bibletranslationtools.fetcher.impl.repository.UnfoldingWordHeartLanguagesCatalog +import org.bibletranslationtools.fetcher.impl.repository.UnfoldingWordLanguagesCatalog import org.bibletranslationtools.fetcher.io.LocalFileTransferClient import org.bibletranslationtools.fetcher.repository.BookCatalog import org.bibletranslationtools.fetcher.repository.BookRepository import org.bibletranslationtools.fetcher.repository.ChapterCatalog -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.DirectoryProvider import org.bibletranslationtools.fetcher.repository.LanguageCatalog import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.ProductCatalog +import org.bibletranslationtools.fetcher.repository.RequestResourceContainer import org.bibletranslationtools.fetcher.repository.ResourceContainerRepository +import org.bibletranslationtools.fetcher.repository.SourceTextAccessor import org.bibletranslationtools.fetcher.repository.StorageAccess import org.koin.core.qualifier.named import org.koin.dsl.module @@ -42,30 +43,22 @@ val appDependencyModule = module(createdAtStart = true) { single { StorageAccessImpl(get()) } single { ChapterCatalogImpl() } - single(named("GL")) { PortGatewayLanguageCatalog() } - single(named("HL")) { UnfoldingWordHeartLanguagesCatalog(get()) } + single(named(LangType.GL.name)) { UnfoldingWordLanguagesCatalog(get(), LangType.GL) } + single(named(LangType.HL.name)) { UnfoldingWordLanguagesCatalog(get(), LangType.HL) } + single(named(LangType.ALL.name)) { UnfoldingWordLanguagesCatalog(get(), LangType.ALL) } single { LanguageRepositoryImpl( - get(named("GL")), - get(named("HL")) + get(named(LangType.GL.name)), + get(named(LangType.HL.name)) ) } single { ProductCatalogImpl() } single { BookCatalogImpl() } single { BookRepositoryImpl(get()) } - single { RCRepositoryImpl(get()) } + single { RCRepositoryImpl(get(), get()) } single { LocalFileTransferClient(get()) } + single { RequestResourceContainerImpl(get(), get(), get(), get()) } - single { - ContentAvailabilityCacheBuilder( - envConfig = get(), - languageCatalog = get(named("GL")), - productCatalog = get(), - chapterCatalog = get(), - bookRepository = get(), - storageAccess = get() - ) - } - single { AvailabilityCacheAccessor(get()) } + single { SourceTextAccessorImpl() } } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/ChapterCatalogImpl.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/ChapterCatalogImpl.kt index a8f4289d..eb347c47 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/ChapterCatalogImpl.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/ChapterCatalogImpl.kt @@ -3,8 +3,6 @@ package org.bibletranslationtools.fetcher.impl.repository import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue -import io.ktor.client.request.get -import io.ktor.util.error import java.io.IOException import java.net.HttpURLConnection import java.net.URL diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RCRepositoryImpl.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RCRepositoryImpl.kt index 244e4d00..38127884 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RCRepositoryImpl.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RCRepositoryImpl.kt @@ -1,12 +1,17 @@ package org.bibletranslationtools.fetcher.impl.repository -import java.io.File import org.bibletranslationtools.fetcher.repository.ResourceContainerRepository +import org.bibletranslationtools.fetcher.repository.SourceTextAccessor import org.bibletranslationtools.fetcher.repository.StorageAccess +import org.slf4j.LoggerFactory +import java.io.File + class RCRepositoryImpl( - private val storageAccess: StorageAccess + private val storageAccess: StorageAccess, + private val sourceTextAccessor: SourceTextAccessor ) : ResourceContainerRepository { + private val logger = LoggerFactory.getLogger(javaClass) private val rcTemplateName = "%s_%s" override fun getRC( @@ -16,4 +21,30 @@ class RCRepositoryImpl( val repoName = String.format(rcTemplateName, languageCode, resourceId) return storageAccess.getRepoFromFileSystem(repoName) } + + override fun downloadRC( + languageCode: String, + resourceId: String + ): File? { + return sourceTextAccessor.getRepoUrl( + languageCode, + resourceId + )?.let { repoUrl -> + val repoName = "${languageCode}_$resourceId" + val reposDirectory = storageAccess.getReposDir() + + val process = ProcessBuilder() + .command("git", "clone", repoUrl, repoName) + .directory(reposDirectory) + .start() + + val exit = process.waitFor() + + if (exit != 0) { + logger.error("An error occurred in cloneRepo with exit code: $exit") + } + + storageAccess.getRepoFromFileSystem(repoName) + } + } } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/RequestResourceContainer.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RequestResourceContainerImpl.kt similarity index 93% rename from fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/RequestResourceContainer.kt rename to fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RequestResourceContainerImpl.kt index 2b3b8d5c..2db2bc73 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/RequestResourceContainer.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/RequestResourceContainerImpl.kt @@ -1,13 +1,13 @@ -package org.bibletranslationtools.fetcher.usecase +package org.bibletranslationtools.fetcher.impl.repository import java.io.File import org.bibletranslationtools.fetcher.config.EnvironmentConfig import org.bibletranslationtools.fetcher.data.Deliverable import org.bibletranslationtools.fetcher.data.RCDeliverable -import org.bibletranslationtools.fetcher.impl.repository.RCUtils -import org.bibletranslationtools.fetcher.impl.repository.StorageAccessImpl +import org.bibletranslationtools.fetcher.repository.RequestResourceContainer import org.bibletranslationtools.fetcher.repository.ResourceContainerRepository import org.bibletranslationtools.fetcher.repository.StorageAccess +import org.bibletranslationtools.fetcher.usecase.ProductFileQuality import org.wycliffeassociates.rcmediadownloader.RCMediaDownloader import org.wycliffeassociates.rcmediadownloader.data.MediaDivision import org.wycliffeassociates.rcmediadownloader.data.MediaType @@ -19,17 +19,17 @@ import org.wycliffeassociates.resourcecontainer.entity.MediaManifest import org.wycliffeassociates.resourcecontainer.entity.MediaProject import java.util.zip.Adler32 -class RequestResourceContainer( +class RequestResourceContainerImpl( envConfig: EnvironmentConfig, private val rcRepository: ResourceContainerRepository, private val storageAccess: StorageAccess, private val downloadClient: IDownloadClient -) { +) : RequestResourceContainer { private val baseRCUrl = envConfig.CDN_BASE_RC_URL private val baseContentUrl = envConfig.CONTENT_ROOT_DIR private val outputDir = envConfig.RC_OUTPUT_DIR - fun getResourceContainer( + override fun getResourceContainer( deliverable: Deliverable ): RCDeliverable? { val rcName = RCUtils.createRCFileName(deliverable, "") @@ -74,6 +74,10 @@ class RequestResourceContainer( } } + override fun getResourceContainer(languageCode: String, resourceId: String): File? { + return rcRepository.getRC(languageCode, resourceId) + } + private fun getChapterFiles(deliverable: Deliverable): List { val templateRC = getTemplateRC(deliverable) ?: return listOf() @@ -147,6 +151,9 @@ class RequestResourceContainer( val templateRC = rcRepository.getRC( deliverable.language.code, deliverable.resourceId + ) ?: rcRepository.downloadRC( + deliverable.language.code, + deliverable.resourceId ) return if (templateRC != null && templateRC.exists()) { @@ -247,7 +254,7 @@ class RequestResourceContainer( val mediaTypes = listOf(MediaType.MP3, MediaType.CUE) private val mediaQualityMap = mapOf( - MediaType.MP3.toString() to "hi", + MediaType.MP3.toString() to ProductFileQuality.HI.quality, MediaType.WAV.toString() to "", MediaType.CUE.toString() to "" ) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/SourceTextAccessorImpl.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/SourceTextAccessorImpl.kt new file mode 100644 index 00000000..25da2469 --- /dev/null +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/SourceTextAccessorImpl.kt @@ -0,0 +1,37 @@ +package org.bibletranslationtools.fetcher.impl.repository + +import com.apollographql.apollo3.ApolloClient +import kotlinx.coroutines.runBlocking +import org.bibletranslationtools.fetcher.graphql.generated.GetPrimaryReposQuery +import org.bibletranslationtools.fetcher.repository.SourceTextAccessor + +class SourceTextAccessorImpl : SourceTextAccessor { + private var cache: List = listOf() + + init { + buildCache() + } + + override fun update() { + buildCache() + } + + override fun getRepoUrl(languageCode: String, resourceId: String): String? { + return cache.singleOrNull { + it.content?.language?.languageCode == languageCode && + it.content.resourceType == resourceId + }?.repoUrl + } + + private fun buildCache() { + val client = ApolloClient.Builder() + .serverUrl("https://api-biel-dev.walink.org/v1/graphql") + .build() + + cache = runBlocking { + val query = GetPrimaryReposQuery() + val response = client.query(query).execute() + response.data?.GitRepos ?: listOf() + } + } +} \ No newline at end of file diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/StorageAccessImpl.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/StorageAccessImpl.kt index 0af52be1..af4148e3 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/StorageAccessImpl.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/StorageAccessImpl.kt @@ -10,51 +10,32 @@ import org.bibletranslationtools.fetcher.data.Division import org.bibletranslationtools.fetcher.repository.DirectoryProvider import org.bibletranslationtools.fetcher.repository.FileAccessRequest import org.bibletranslationtools.fetcher.repository.StorageAccess +import org.bibletranslationtools.fetcher.usecase.ProductFileExtension +import org.bibletranslationtools.fetcher.usecase.resourceIdByLanguage import org.slf4j.LoggerFactory class StorageAccessImpl(private val directoryProvider: DirectoryProvider) : StorageAccess { companion object { - fun getPathPrefixDir( - languageCode: String, - resourceId: String, - fileExtension: String, - directoryProvider: DirectoryProvider, - bookSlug: String = "", - chapter: String = "" - ): File { - return getPathPrefixDir( - directoryProvider.getContentRoot(), - languageCode, - resourceId, - fileExtension, - bookSlug, - chapter - ) - } - fun getPathPrefixDir( root: File, languageCode: String, resourceId: String, - fileExtension: String, - bookSlug: String = "", - chapter: String = "" + fileExtension: String? = null, + bookSlug: String? = null, + chapter: String? = null ): File { - val trimmedChapter = chapter.trimStart('0') - - return when { - bookSlug.isNotEmpty() && trimmedChapter.isNotEmpty() -> - root.resolve( - "$languageCode/$resourceId/$bookSlug/$trimmedChapter/CONTENTS/$fileExtension" - ) - bookSlug.isNotEmpty() -> root.resolve( - "$languageCode/$resourceId/$bookSlug/CONTENTS/$fileExtension" - ) - else -> root.resolve( - "$languageCode/$resourceId/CONTENTS/$fileExtension" - ) - } + val trimmedChapter = chapter?.trimStart('0') + + val languagePart = languageCode + val resourcePart = "/$resourceId" + val bookPart = if (!bookSlug.isNullOrEmpty()) "/$bookSlug" else "" + val chapterPart = if (!trimmedChapter.isNullOrEmpty()) "/$trimmedChapter" else "" + val extensionPart = if (!fileExtension.isNullOrEmpty()) "/CONTENTS/$fileExtension" else "" + + return root.resolve( + "$languagePart$resourcePart$bookPart$chapterPart$extensionPart" + ) } fun getContentDir( @@ -85,20 +66,47 @@ class StorageAccessImpl(private val directoryProvider: DirectoryProvider) : Stor return directoryProvider.getContentRoot() } - override fun getLanguageCodes(): List { + override fun getReposDir(): File { + return directoryProvider.getRCRepositoriesDir() + } + + override fun hasLanguageContent(languageCode: String): Boolean { val sourceFileRootDir = directoryProvider.getContentRoot() val dirs = sourceFileRootDir.listFiles(File::isDirectory) - return if (dirs.isNullOrEmpty()) listOf() else dirs.map { it.name } + return dirs?.any { it.name == languageCode } ?: false + } + + override fun hasProductContent(languageCode: String, fileExtensions: List): Boolean { + val resourceId = resourceIdByLanguage(languageCode) + val booksDir = getPathPrefixDir( + directoryProvider.getContentRoot(), + languageCode, + resourceId + ) + + return booksDir.listFiles(File::isDirectory)?.any { bookDir -> + val bookSlug = bookDir.name + fileExtensions.any { ext -> + val dir = getPathPrefixDir( + directoryProvider.getContentRoot(), + languageCode, + resourceId, + ext, + bookSlug + ) + dir.exists() + } + } ?: false } override fun getBookFile(request: FileAccessRequest): File? { val bookPrefixDir = getPathPrefixDir( + directoryProvider.getContentRoot(), languageCode = request.languageCode, resourceId = request.resourceId, bookSlug = request.bookSlug, - fileExtension = request.fileExtension, - directoryProvider = directoryProvider + fileExtension = request.fileExtension ) val grouping = getGrouping(request.fileExtension, Division.BOOK) @@ -126,12 +134,12 @@ class StorageAccessImpl(private val directoryProvider: DirectoryProvider) : Stor override fun getChapterFile(request: FileAccessRequest): File? { val chapterPrefixDir = getPathPrefixDir( + directoryProvider.getContentRoot(), languageCode = request.languageCode, resourceId = request.resourceId, bookSlug = request.bookSlug, fileExtension = request.fileExtension, - chapter = request.chapter, - directoryProvider = directoryProvider + chapter = request.chapter ) val grouping = getGrouping(request.fileExtension, Division.CHAPTER) @@ -188,11 +196,11 @@ class StorageAccessImpl(private val directoryProvider: DirectoryProvider) : Stor ): Boolean { for (ext in fileExtensionList) { val bookPrefixDir = getPathPrefixDir( + directoryProvider.getContentRoot(), languageCode = languageCode, resourceId = resourceId, bookSlug = bookSlug, - fileExtension = ext, - directoryProvider = directoryProvider + fileExtension = ext ) val walkBookDir = bookPrefixDir.walk() val grouping = getGrouping(ext, Division.BOOK) @@ -238,7 +246,7 @@ class StorageAccessImpl(private val directoryProvider: DirectoryProvider) : Stor private fun getGrouping(ext: String, division: Division): String { return when { - ext == "tr" -> "verse" + ext == ProductFileExtension.BTTR.fileType -> "verse" else -> division.name.toLowerCase() } } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordHeartLanguagesCatalog.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordLanguagesCatalog.kt similarity index 86% rename from fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordHeartLanguagesCatalog.kt rename to fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordLanguagesCatalog.kt index de6dfa1f..0e73579d 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordHeartLanguagesCatalog.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/impl/repository/UnfoldingWordLanguagesCatalog.kt @@ -10,7 +10,6 @@ import java.io.IOException import java.net.HttpURLConnection import java.net.URL import org.bibletranslationtools.fetcher.data.Language -import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get import org.bibletranslationtools.fetcher.repository.LanguageCatalog import org.slf4j.LoggerFactory @@ -18,8 +17,18 @@ private const val LANGUAGE_CODE_ID = "lc" private const val ANGLICIZED_NAME_ID = "ang" private const val LOCALIZED_NAME_ID = "ln" private const val IS_GATEWAY = "gw" +private const val DIRECTION = "ld" -class UnfoldingWordHeartLanguagesCatalog(envConfig: EnvironmentConfig) : LanguageCatalog { +enum class LangType { + GL, + HL, + ALL +} + +class UnfoldingWordLanguagesCatalog( + envConfig: EnvironmentConfig, + private val langType: LangType +) : LanguageCatalog { @JsonIgnoreProperties(ignoreUnknown = true) private data class UnfoldingWordHeartLanguage( @@ -45,7 +54,11 @@ class UnfoldingWordHeartLanguagesCatalog(envConfig: EnvironmentConfig) : Languag return languages .filter { - !it.isGateway + when (langType) { + LangType.GL -> it.isGateway + LangType.HL -> !it.isGateway + LangType.ALL -> true + } } .map { Language(it.code, it.anglicizedName, it.localizedName, isGateway = false) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/FileAccessRequest.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/FileAccessRequest.kt index 07f0fb41..37d10d76 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/FileAccessRequest.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/FileAccessRequest.kt @@ -3,7 +3,7 @@ package org.bibletranslationtools.fetcher.repository data class FileAccessRequest( val languageCode: String, val resourceId: String, - val fileExtension: String, + val fileExtension: String = "", val bookSlug: String = "", val chapter: String = "", val mediaExtension: String = "", diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/RequestResourceContainer.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/RequestResourceContainer.kt new file mode 100644 index 00000000..e935e35a --- /dev/null +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/RequestResourceContainer.kt @@ -0,0 +1,10 @@ +package org.bibletranslationtools.fetcher.repository + +import org.bibletranslationtools.fetcher.data.Deliverable +import org.bibletranslationtools.fetcher.data.RCDeliverable +import java.io.File + +interface RequestResourceContainer { + fun getResourceContainer(deliverable: Deliverable): RCDeliverable? + fun getResourceContainer(languageCode: String, resourceId: String): File? +} \ No newline at end of file diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/ResourceContainerRepository.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/ResourceContainerRepository.kt index c5d586fc..7d51b88c 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/ResourceContainerRepository.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/ResourceContainerRepository.kt @@ -7,4 +7,9 @@ interface ResourceContainerRepository { languageCode: String, resourceId: String ): File? + + fun downloadRC( + languageCode: String, + resourceId: String + ): File? } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/SourceTextAccessor.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/SourceTextAccessor.kt new file mode 100644 index 00000000..f07ea99c --- /dev/null +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/SourceTextAccessor.kt @@ -0,0 +1,6 @@ +package org.bibletranslationtools.fetcher.repository + +interface SourceTextAccessor { + fun update() + fun getRepoUrl(languageCode: String, resourceId: String): String? +} \ No newline at end of file diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/StorageAccess.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/StorageAccess.kt index 44063f4c..a78372e2 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/StorageAccess.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/repository/StorageAccess.kt @@ -4,7 +4,9 @@ import java.io.File interface StorageAccess { fun getContentRoot(): File - fun getLanguageCodes(): List + fun getReposDir(): File + fun hasLanguageContent(languageCode: String): Boolean + fun hasProductContent(languageCode: String, fileExtensions: List): Boolean fun getBookFile(request: FileAccessRequest): File? fun getChapterFile(request: FileAccessRequest): File? fun hasBookContent( diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchBookViewData.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchBookViewData.kt index dad1d167..3446f424 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchBookViewData.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchBookViewData.kt @@ -6,7 +6,6 @@ import org.bibletranslationtools.fetcher.data.ContainerExtensions import org.bibletranslationtools.fetcher.data.Language import org.bibletranslationtools.fetcher.data.Product import org.bibletranslationtools.fetcher.repository.BookRepository -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.FileAccessRequest import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.viewdata.BookViewData @@ -26,34 +25,26 @@ class FetchBookViewData( private val fileExtensionList = if (ContainerExtensions.isSupported(productExtension.fileType)) { - listOf("tr") + listOf(ProductFileExtension.BTTR.fileType) } else { - listOf("wav", "mp3") + listOf(ProductFileExtension.MP3.fileType, ProductFileExtension.WAV.fileType) } private val priorityList = listOf( - PriorityItem("mp3", "hi"), - PriorityItem("mp3", "low"), - PriorityItem("wav", "") + PriorityItem(ProductFileExtension.MP3.fileType, ProductFileQuality.HI.quality), + PriorityItem(ProductFileExtension.MP3.fileType, ProductFileQuality.LOW.quality), + PriorityItem(ProductFileExtension.WAV.fileType, "") ) - fun getViewDataList( - currentPath: String, - cacheAccessor: ContentCacheAccessor, - isGateway: Boolean = true - ): List { + fun getViewDataList(currentPath: String): List { val books = bookRepo.getBooks(resourceId = resourceId, languageCode = language.code) return books.map { book -> - book.availability = if (isGateway) { - cacheAccessor.isBookAvailable(book.slug, language.code, product.slug) - } else { - storage.hasBookContent( - language.code, - resourceId, - book.slug, - fileExtensionList - ) - } + book.availability = storage.hasBookContent( + language.code, + resourceId, + book.slug, + fileExtensionList + ) BookViewData( index = book.index, @@ -65,17 +56,9 @@ class FetchBookViewData( } } - fun getViewData( - bookSlug: String, - cacheAccessor: ContentCacheAccessor, - isGateway: Boolean = true - ): BookViewData? { + fun getViewData(bookSlug: String): BookViewData? { val book = bookRepo.getBook(bookSlug) - val url = if (isGateway) { - cacheAccessor.getBookUrl(bookSlug, language.code, product.slug) - } else { - getBookDownloadUrl(bookSlug) - } + val url = getBookDownloadUrl(bookSlug) return if (book != null) BookViewData( index = book.index, @@ -95,6 +78,7 @@ class FetchBookViewData( ProductFileExtension.ORATURE -> return "#" ProductFileExtension.BTTR -> getBTTRFileAccessRequest(bookSlug, priority) ProductFileExtension.MP3 -> getMp3FileAccessRequest(bookSlug, priority) + else -> return "" } val bookFile = storage.getBookFile(fileAccessRequest) @@ -113,7 +97,7 @@ class FetchBookViewData( return FileAccessRequest( languageCode = language.code, resourceId = resourceId, - fileExtension = "tr", + fileExtension = ProductFileExtension.BTTR.fileType, bookSlug = bookSlug, mediaExtension = priorityItem.fileExtension, mediaQuality = priorityItem.mediaQuality diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchChapterViewData.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchChapterViewData.kt index f83e8b78..d20f1a56 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchChapterViewData.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchChapterViewData.kt @@ -8,7 +8,6 @@ import org.bibletranslationtools.fetcher.data.Chapter import org.bibletranslationtools.fetcher.data.Language import org.bibletranslationtools.fetcher.data.Product import org.bibletranslationtools.fetcher.repository.ChapterCatalog -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.FileAccessRequest import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.viewdata.ChapterViewData @@ -27,9 +26,9 @@ class FetchChapterViewData( private data class PriorityItem(val fileExtension: String, val mediaQuality: String) private val priorityList = listOf( - PriorityItem("mp3", "hi"), - PriorityItem("mp3", "low"), - PriorityItem("wav", "") + PriorityItem(ProductFileExtension.MP3.fileType, ProductFileQuality.HI.quality), + PriorityItem(ProductFileExtension.MP3.fileType, ProductFileQuality.LOW.quality), + PriorityItem(ProductFileExtension.WAV.fileType, "") ) private val chapters: List = try { @@ -41,23 +40,8 @@ class FetchChapterViewData( throw ex } - fun getViewDataList( - contentCache: ContentCacheAccessor, - isGateway: Boolean - ): List { - return if (isGateway) { - chapters.map { - val requestUrl = contentCache.getChapterUrl( - number = it.number, - bookSlug = book.slug, - languageCode = language.code, - productSlug = product.slug - ) - ChapterViewData(it.number, url = requestUrl) - } - } else { - chaptersFromDirectory() - } + fun getViewDataList(): List { + return chaptersFromDirectory() } fun chaptersFromDirectory(): List { @@ -69,13 +53,18 @@ class FetchChapterViewData( for (priority in priorityList) { val fileAccessRequest = when (productExtension) { ProductFileExtension.BTTR -> getBTTRFileAccessRequest(chapterNumber, priority) - ProductFileExtension.MP3 -> getMp3FileAccessRequest(chapterNumber, priority) + ProductFileExtension.MP3, ProductFileExtension.ORATURE -> { + getMp3FileAccessRequest(chapterNumber, priority) + } else -> return listOf() } val chapterFile = storage.getChapterFile(fileAccessRequest) if (chapterFile != null) { - url = formatChapterDownloadUrl(chapterFile) + url = when (productExtension) { + ProductFileExtension.ORATURE -> "#" + else -> formatChapterDownloadUrl(chapterFile) + } break } } @@ -92,7 +81,7 @@ class FetchChapterViewData( return FileAccessRequest( languageCode = language.code, resourceId = resourceIdByLanguage(language.code), - fileExtension = "tr", + fileExtension = ProductFileExtension.BTTR.fileType, bookSlug = book.slug, chapter = chapterNumber.toString(), mediaExtension = priorityItem.fileExtension, diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchLanguageViewData.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchLanguageViewData.kt index 81c6799a..9140b81b 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchLanguageViewData.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchLanguageViewData.kt @@ -1,43 +1,45 @@ package org.bibletranslationtools.fetcher.usecase import org.bibletranslationtools.fetcher.data.Language -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.viewdata.LanguageViewData class FetchLanguageViewData( private val languageRepo: LanguageRepository, - private val contentCache: ContentCacheAccessor, - storage: StorageAccess + private val storage: StorageAccess ) { companion object { const val DISPLAY_ITEMS_LIMIT = 30 private const val MATCHING_RESULT_TAKE = 20 } - private val languageCodesFromStorage = storage.getLanguageCodes() + + private val comparator = compareBy(LanguageViewData::isGateway) + .then(compareByDescending { it.url != null }) fun getViewDataList( currentPath: String ): List { - val languages = languageRepo.getGatewayLanguages() - - val listViewData = languages.map { - val available = contentCache.isLanguageAvailable(it.code) + val languages = languageRepo.getAll() - LanguageViewData( - code = it.code, - anglicizedName = it.anglicizedName, - localizedName = it.localizedName, - url = if (available) { - "$currentPath/${it.code}" - } else { - null - } - ) - } + return languages + .map { + val available = storage.hasLanguageContent(it.code) - return listViewData.filter { it.url != null } + listViewData.filter { it.url == null } + LanguageViewData( + code = it.code, + anglicizedName = it.anglicizedName, + localizedName = it.localizedName, + isGateway = it.isGateway, + url = if (available) { + "$currentPath/${it.code}" + } else { + null + } + ) + } + .sortedWith(comparator) + .take(DISPLAY_ITEMS_LIMIT) } fun filterLanguages( @@ -45,22 +47,15 @@ class FetchLanguageViewData( currentPath: String, currentIndex: Int = 0 ): List { - val result = getMatchingLanguages(query, languageRepo.getAll()) - - return result - .drop(currentIndex) - .take(DISPLAY_ITEMS_LIMIT) + return getMatchingLanguages(query, languageRepo.getAll()) .map { - val available = if (it.isGateway) { - contentCache.isLanguageAvailable(it.code) - } else { - it.code in languageCodesFromStorage - } + val available = storage.hasLanguageContent(it.code) LanguageViewData( code = it.code, anglicizedName = it.anglicizedName, localizedName = it.localizedName, + isGateway = it.isGateway, url = if (available) { "$currentPath/${it.code}" } else { @@ -68,6 +63,9 @@ class FetchLanguageViewData( } ) } + .sortedWith(comparator) + .drop(currentIndex) + .take(DISPLAY_ITEMS_LIMIT) } fun loadMoreLanguages( @@ -76,18 +74,15 @@ class FetchLanguageViewData( ): List { if (currentIndex < 0) return listOf() - // load more (default) is only applied to HL - val languages = languageRepo.getHeartLanguages() - - return languages - .drop(currentIndex) - .take(DISPLAY_ITEMS_LIMIT) + return languageRepo.getAll() .map { - val available = it.code in languageCodesFromStorage + val available = storage.hasLanguageContent(it.code) + LanguageViewData( code = it.code, anglicizedName = it.anglicizedName, localizedName = it.localizedName, + isGateway = it.isGateway, url = if (available) { "$currentPath/${it.code}" } else { @@ -95,6 +90,9 @@ class FetchLanguageViewData( } ) } + .sortedWith(comparator) + .drop(currentIndex + DISPLAY_ITEMS_LIMIT) + .take(DISPLAY_ITEMS_LIMIT) } private fun getMatchingLanguages( diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchProductViewData.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchProductViewData.kt index a1346a51..6b44ea32 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchProductViewData.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/FetchProductViewData.kt @@ -1,26 +1,38 @@ package org.bibletranslationtools.fetcher.usecase +import org.bibletranslationtools.fetcher.data.ContainerExtensions import org.bibletranslationtools.fetcher.data.Product -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor -import org.bibletranslationtools.fetcher.repository.ProductCatalog +import org.bibletranslationtools.fetcher.repository.* import org.bibletranslationtools.fetcher.usecase.viewdata.ProductViewData class FetchProductViewData( productCatalog: ProductCatalog, + private val storage: StorageAccess, + private val sourceTextAccessor: SourceTextAccessor, + private val requestResourceContainer: RequestResourceContainer, private val languageCode: String ) { private val products: List = productCatalog.getAll() fun getListViewData( - currentPath: String, - cacheAccessor: ContentCacheAccessor, - isGateway: Boolean + currentPath: String ): List { return products.map { - val isAvailable = if (isGateway) { - cacheAccessor.isProductAvailable(it.slug, languageCode) - } else { - it.slug == ProductFileExtension.MP3.name.toLowerCase() + val productExtension = ProductFileExtension.getType(it.slug)!! + val fileExtensions = if (ContainerExtensions.isSupported(productExtension.fileType)) { + listOf(ProductFileExtension.BTTR.fileType) + } else { + listOf(ProductFileExtension.MP3.fileType, ProductFileExtension.WAV.fileType) + } + + val hasAudioContent = storage.hasProductContent(languageCode, fileExtensions) + + val isAvailable = when (productExtension) { + ProductFileExtension.ORATURE -> { + val hasSourceText = hasSourceText() + hasAudioContent && hasSourceText + } + else -> hasAudioContent } ProductViewData( @@ -32,4 +44,14 @@ class FetchProductViewData( ) } } + + private fun hasSourceText(): Boolean { + val resourceId = resourceIdByLanguage(languageCode) + + return when { + requestResourceContainer.getResourceContainer(languageCode, resourceId) != null -> true + sourceTextAccessor.getRepoUrl(languageCode, resourceId) != null -> true + else -> false + } + } } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileExtension.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileExtension.kt index dea97472..4cdda115 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileExtension.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileExtension.kt @@ -4,6 +4,7 @@ import java.lang.IllegalArgumentException enum class ProductFileExtension(val fileType: String) { MP3("mp3"), + WAV("wav"), BTTR("tr"), ORATURE("zip"); diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileQuality.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileQuality.kt new file mode 100644 index 00000000..4386111f --- /dev/null +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/ProductFileQuality.kt @@ -0,0 +1,6 @@ +package org.bibletranslationtools.fetcher.usecase + +enum class ProductFileQuality(val quality: String) { + HI("hi"), + LOW("low") +} \ No newline at end of file diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/viewdata/LanguageViewData.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/viewdata/LanguageViewData.kt index 70d87870..5ba36cf0 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/viewdata/LanguageViewData.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/usecase/viewdata/LanguageViewData.kt @@ -4,5 +4,6 @@ data class LanguageViewData( val code: String, val anglicizedName: String, val localizedName: String, + val isGateway: Boolean, val url: String? ) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/AppModule.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/AppModule.kt index a33f0a53..37b0a17f 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/AppModule.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/AppModule.kt @@ -18,7 +18,7 @@ import kotlin.concurrent.thread import org.bibletranslationtools.fetcher.config.EnvironmentConfig import org.bibletranslationtools.fetcher.di.appDependencyModule import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor +import org.bibletranslationtools.fetcher.repository.SourceTextAccessor import org.bibletranslationtools.fetcher.web.controllers.bookController import org.bibletranslationtools.fetcher.web.controllers.chapterController import org.bibletranslationtools.fetcher.web.controllers.homeController @@ -84,15 +84,15 @@ fun Application.appModule() { private fun scheduleCacheUpdate() { val envConfig: EnvironmentConfig = get() - val cacheAccessor: ContentCacheAccessor = get() + val sourceTextAccessor: SourceTextAccessor = get() - thread(start = true, isDaemon = true, name = "cache-update") { + thread(start = true, isDaemon = true, name = "cache-update") { val minutes = envConfig.CACHE_REFRESH_MINUTES.toLong() while (true) { Thread.sleep(MILLISECONDS_PER_MINUTE * minutes) logger.info("Updating cache...") try { - cacheAccessor.update() + sourceTextAccessor.update() logger.info("Cache updated!") } catch (e: Exception) { logger.error("An error occurred while updating the content cache.", e) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/BookController.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/BookController.kt index 2f32f025..1406466b 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/BookController.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/BookController.kt @@ -11,12 +11,10 @@ import io.ktor.routing.route import org.bibletranslationtools.fetcher.config.EnvironmentConfig import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get import org.bibletranslationtools.fetcher.repository.BookRepository -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.ProductCatalog import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.FetchBookViewData -import org.bibletranslationtools.fetcher.usecase.resourceIdByLanguage import org.bibletranslationtools.fetcher.web.controllers.utils.GL_ROUTE import org.bibletranslationtools.fetcher.web.controllers.utils.LANGUAGE_PARAM_KEY import org.bibletranslationtools.fetcher.web.controllers.utils.PRODUCT_PARAM_KEY @@ -61,7 +59,6 @@ private fun booksView( params: UrlParameters, path: String ): ThymeleafContent { - val contentCache = get() val language = get().getLanguage(params.languageCode)!! val product = get().getProduct(params.productSlug)!! @@ -71,7 +68,7 @@ private fun booksView( get(), language, product - ).getViewDataList(path, contentCache, language.isGateway) + ).getViewDataList(path) return ThymeleafContent( template = "books", @@ -81,7 +78,7 @@ private fun booksView( "languagesNavUrl" to "/$GL_ROUTE", "fileTypesNavTitle" to product.titleKey, "fileTypesNavUrl" to "/$GL_ROUTE/${params.languageCode}", - "booksNavUrl" to "#" + "booksNavUrl" to "" ), locale = getPreferredLocale(contentLanguage, "books") ) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ChapterController.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ChapterController.kt index 09ededce..6b29e694 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ChapterController.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ChapterController.kt @@ -14,16 +14,14 @@ import org.bibletranslationtools.fetcher.data.Deliverable import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get import org.bibletranslationtools.fetcher.repository.BookRepository import org.bibletranslationtools.fetcher.repository.ChapterCatalog -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.ProductCatalog -import org.bibletranslationtools.fetcher.repository.ResourceContainerRepository +import org.bibletranslationtools.fetcher.repository.RequestResourceContainer import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.DeliverableBuilder import org.bibletranslationtools.fetcher.usecase.FetchBookViewData import org.bibletranslationtools.fetcher.usecase.FetchChapterViewData import org.bibletranslationtools.fetcher.usecase.ProductFileExtension -import org.bibletranslationtools.fetcher.usecase.RequestResourceContainer import org.bibletranslationtools.fetcher.usecase.viewdata.BookViewData import org.bibletranslationtools.fetcher.usecase.viewdata.ChapterViewData import org.bibletranslationtools.fetcher.web.controllers.utils.BOOK_PARAM_KEY @@ -36,7 +34,6 @@ import org.bibletranslationtools.fetcher.web.controllers.utils.contentLanguage import org.bibletranslationtools.fetcher.web.controllers.utils.errorPage import org.bibletranslationtools.fetcher.web.controllers.utils.getPreferredLocale import org.bibletranslationtools.fetcher.web.controllers.utils.validator -import org.wycliffeassociates.rcmediadownloader.io.IDownloadClient fun Routing.chapterController() { route("/$GL_ROUTE/{$LANGUAGE_PARAM_KEY}/{$PRODUCT_PARAM_KEY}/{$BOOK_PARAM_KEY}") { @@ -105,12 +102,8 @@ private fun Route.oratureChapters() { } } -private fun chaptersView( - paramObjects: Deliverable -): ThymeleafContent { - val isGateway = paramObjects.language.isGateway +private fun chaptersView(paramObjects: Deliverable): ThymeleafContent { val envConfig = get() - val contentCache = get() val storageAccess = get() val bookViewData: BookViewData? = FetchBookViewData( @@ -119,7 +112,7 @@ private fun chaptersView( storageAccess, paramObjects.language, paramObjects.product - ).getViewData(paramObjects.book.slug, contentCache, isGateway) + ).getViewData(paramObjects.book.slug) val chapterViewDataList: List? = try { FetchChapterViewData( @@ -129,7 +122,7 @@ private fun chaptersView( paramObjects.language, paramObjects.product, paramObjects.book - ).getViewDataList(contentCache, isGateway) + ).getViewDataList() } catch (ex: ClientRequestException) { return errorPage( "internal_error", @@ -182,10 +175,6 @@ private fun oratureFileDownload( get() ).build(params) - return RequestResourceContainer( - get(), - get(), - get(), - get() - ).getResourceContainer(deliverable)?.url + return get() + .getResourceContainer(deliverable)?.url } diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/LanguageController.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/LanguageController.kt index 7b90bed4..f9737077 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/LanguageController.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/LanguageController.kt @@ -11,7 +11,6 @@ import io.ktor.routing.get import io.ktor.routing.route import java.lang.NumberFormatException import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.FetchLanguageViewData @@ -86,7 +85,6 @@ private fun languagesView( ): ThymeleafContent { val languageList = FetchLanguageViewData( get(), - get(), get() ).getViewDataList(path) @@ -94,7 +92,7 @@ private fun languagesView( template = "languages", model = mapOf( "languageList" to languageList, - "languagesNavUrl" to "#", + "languagesNavUrl" to "", "gatewayCount" to languageList.size ), locale = getPreferredLocale(contentLanguage, "languages") @@ -108,7 +106,6 @@ private fun filterLanguages( ): ThymeleafContent { val resultLanguages = FetchLanguageViewData( get(), - get(), get() ).filterLanguages(query, currentPath, currentIndex) @@ -129,7 +126,6 @@ private fun loadMore( ): ThymeleafContent { val moreLanguages = FetchLanguageViewData( get(), - get(), get() ).loadMoreLanguages(path, currentIndex) diff --git a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ProductController.kt b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ProductController.kt index 4c8b9021..819c6e00 100644 --- a/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ProductController.kt +++ b/fetcher-web/src/main/kotlin/org/bibletranslationtools/fetcher/web/controllers/ProductController.kt @@ -9,9 +9,11 @@ import io.ktor.routing.Routing import io.ktor.routing.get import io.ktor.routing.route import org.bibletranslationtools.fetcher.di.ext.CommonKoinExt.get -import org.bibletranslationtools.fetcher.repository.ContentCacheAccessor import org.bibletranslationtools.fetcher.repository.LanguageRepository import org.bibletranslationtools.fetcher.repository.ProductCatalog +import org.bibletranslationtools.fetcher.repository.RequestResourceContainer +import org.bibletranslationtools.fetcher.repository.SourceTextAccessor +import org.bibletranslationtools.fetcher.repository.StorageAccess import org.bibletranslationtools.fetcher.usecase.FetchProductViewData import org.bibletranslationtools.fetcher.web.controllers.utils.GL_ROUTE import org.bibletranslationtools.fetcher.web.controllers.utils.LANGUAGE_PARAM_KEY @@ -54,12 +56,14 @@ private fun productsView( path: String ): ThymeleafContent { val language = get().getLanguage(languageCode)!! - val contentCache = get() val productList = FetchProductViewData( get(), + get(), + get(), + get(), language.code - ).getListViewData(path, contentCache, language.isGateway) + ).getListViewData(path) return ThymeleafContent( template = "products", @@ -67,7 +71,7 @@ private fun productsView( "productList" to productList, "languagesNavTitle" to language.localizedName, "languagesNavUrl" to "/$GL_ROUTE", - "fileTypesNavUrl" to "#" + "fileTypesNavUrl" to "" ), locale = getPreferredLocale(contentLanguage, "products") ) diff --git a/fetcher-web/src/main/resources/templates/fragments/card.html b/fetcher-web/src/main/resources/templates/fragments/card.html index 58bf2f21..7b6db2bb 100644 --- a/fetcher-web/src/main/resources/templates/fragments/card.html +++ b/fetcher-web/src/main/resources/templates/fragments/card.html @@ -15,7 +15,7 @@
-

አማርኛ

Amharic

diff --git a/fetcher-web/src/main/resources/templates/fragments/navbar.html b/fetcher-web/src/main/resources/templates/fragments/navbar.html index 5fca9d00..5ed32557 100644 --- a/fetcher-web/src/main/resources/templates/fragments/navbar.html +++ b/fetcher-web/src/main/resources/templates/fragments/navbar.html @@ -5,25 +5,25 @@