Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
package com.lagradost.cloudstream3.ui.search

import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.nicehttp.NiceResponse

/**
* API for fetching search suggestions from external sources.
* Uses Google's suggestion API which provides movie/show related suggestions.
* Uses TheMovieDB API to provide movie/show/anime related suggestions.
*/
object SearchSuggestionApi {
private const val GOOGLE_SUGGESTION_URL = "https://suggestqueries.google.com/complete/search"
private const val TMDB_API_URL = "https://api.themoviedb.org/3/search/multi"
private const val TMDB_API_KEY = "e6333b32409e02a4a6eba6fb7ff866bb"

data class TmdbSearchResult(
@JsonProperty("results") val results: List<TmdbSearchItem>?
)

data class TmdbSearchItem(
@JsonProperty("media_type") val mediaType: String?,
@JsonProperty("title") val title: String?,
@JsonProperty("name") val name: String?,
@JsonProperty("original_title") val originalTitle: String?,
@JsonProperty("original_name") val originalName: String?
)

/**
* Fetches search suggestions from Google's autocomplete API.
* Fetches search suggestions from TheMovieDB multi search API.
* Returns suggestions for movies, TV series, and anime.
*
* @param query The search query to get suggestions for
* @return List of suggestion strings, empty list on failure
Expand All @@ -22,16 +37,15 @@ object SearchSuggestionApi {

return try {
val response = app.get(
GOOGLE_SUGGESTION_URL,
TMDB_API_URL,
params = mapOf(
"client" to "firefox", // Returns JSON format
"q" to query,
"hl" to "en" // Language hint
"api_key" to TMDB_API_KEY,
"query" to query,
"language" to "en-US"
),
cacheTime = 60 * 24 // Cache for 1 day (cacheUnit default is Minutes)
)

// Response format: ["query",["suggestion1","suggestion2",...]]
parseSuggestions(response)
} catch (e: Exception) {
logError(e)
Expand All @@ -40,18 +54,18 @@ object SearchSuggestionApi {
}

/**
* Parses the Google suggestion JSON response.
* Format: ["query",["suggestion1","suggestion2",...]]
* Parses the TMDB search response and extracts movie/TV show titles.
* Filters to only include movies, TV shows, and anime.
*/
private fun parseSuggestions(response: NiceResponse): List<String> {
return try {
val parsed = response.parsed<Array<Any>>()
val suggestions = parsed.getOrNull(1)
when (suggestions) {
is List<*> -> suggestions.filterIsInstance<String>().take(10)
is Array<*> -> suggestions.filterIsInstance<String>().take(10)
else -> emptyList()
}
val parsed = response.parsed<TmdbSearchResult>()
parsed.results
?.filter { it.mediaType == "movie" || it.mediaType == "tv" }
?.mapNotNull { it.title ?: it.name }
?.distinct()
?.take(10)
?: emptyList()
} catch (e: Exception) {
logError(e)
emptyList()
Expand Down