Implement homepage directory API with Google Sheets fallback

This commit is contained in:
Ris-git 2026-06-05 21:23:40 +05:30
parent 4612031785
commit af1d855ea1
2 changed files with 63 additions and 3 deletions

View File

@ -0,0 +1,25 @@
package chat.zekochat.api.routes.googlesheets
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Models for the public servers API: GET https://manageapi.peptide.chat/api/directory/servers
*/
@Serializable
data class ServerEntry(
val id: String,
val name: String = "",
val description: String = "",
val inviteCode: String? = null,
val disabled: Boolean = false,
@SerialName("new") val isNew: Boolean = false,
@SerialName("showcolor") val showcolor: String? = null,
@SerialName("sortorder") val sortorder: Int? = null,
)
@Serializable
data class ServersResponse(
val success: Boolean,
val data: List<ServerEntry> = emptyList(),
)

View File

@ -1,5 +1,9 @@
package chat.zekochat.api.routes.googlesheets
import chat.zekochat.api.PeptideHttp
import chat.zekochat.api.PeptideJson
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
@ -7,16 +11,46 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.Serializable
/**
* Repository for fetching server data from a Google Sheet
* Repository for fetching server data. Tries the Public Servers API first,
* falls back to Google Sheets CSV parsing on any failure.
*/
class ServerDataRepository {
/**
* Fetches server data from Google Sheets and returns as a Flow
* @param sheetUrl The URL of the published Google Sheet (CSV or JSON)
* Fetches server data from the public API first, falling back to Google Sheets.
* @param sheetUrl The URL of the published Google Sheet (CSV or JSON) used as fallback
* @return Flow of ServerData list
*/
fun getServers(sheetUrl: String): Flow<List<ServerData>> = flow {
// Attempt Public Servers API first
try {
val apiUrl = "https://manageapi.peptide.chat/api/directory/servers"
val responseText = PeptideHttp.get(apiUrl).bodyAsText()
val apiResponse = PeptideJson.decodeFromString<ServersResponse>(responseText)
if (apiResponse.success) {
// Map API entries directly to ServerData and preserve order
val mapped = apiResponse.data.map { entry ->
ServerData(
id = entry.id,
name = entry.name ?: "",
description = entry.description ?: "",
inviteCode = entry.inviteCode ?: "",
disabled = entry.disabled,
showColor = entry.showcolor,
sortOrder = entry.sortorder
)
}
emit(mapped)
return@flow
}
} catch (e: Exception) {
// Any failure -> fallback to Google Sheets (preserve previous behavior)
e.printStackTrace()
}
// Fallback: existing Google Sheets parsing
val servers = GoogleSheetsService.fetchSheetData(
sheetUrl = sheetUrl
) { rowData ->
@ -33,6 +67,7 @@ class ServerDataRepository {
sortOrder = rowData["sortorder"]?.toIntOrNull()
)
}
emit(servers.sortedBy { it.sortOrder ?: Int.MAX_VALUE })
}.flowOn(Dispatchers.IO)