Skip to content
This repository has been archived by the owner on Nov 22, 2020. It is now read-only.

Implement search endpoints #7

Merged
merged 3 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
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
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# JikanKt
![JikanKt Banner](https://raw.githubusercontent.com/GSculerlor/JikanKt/master/assets/JikanKt.png)

[![Discord Server](https://img.shields.io/discord/460491088004907029.svg?style=flat&logo=discord)](https://discord.gg/4tvCr36) [![CodeFactor](https://www.codefactor.io/repository/github/gsculerlor/jikankt/badge)](https://www.codefactor.io/repository/github/gsculerlor/jikankt)

![JikanKt Banner](https://raw.githubusercontent.com/GSculerlor/JikanKt/master/assets/JikanKt.png)

API wrapper for [Jikan API](https://jikan.moe) build using Kotlin + Kotlin DSL + Coroutines power 🚀

# Installation
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "com.github.GSculerlor"
version = "1.0.0"
version = "1.1.0"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/moe/ganen/jikankt/JikanClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ open class JikanClient {

companion object {
private const val JIKANKT_NAME = "JikanKt"
private const val JIKANKT_VERSION = "1.0.0"
private const val JIKANKT_VERSION = "1.1.0"
}
}
96 changes: 96 additions & 0 deletions src/main/kotlin/moe/ganen/jikankt/JikanKt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import moe.ganen.jikankt.models.prod.Magazine
import moe.ganen.jikankt.models.prod.Producer
import moe.ganen.jikankt.models.schedule.Day
import moe.ganen.jikankt.models.schedule.Schedule
import moe.ganen.jikankt.models.search.AnimeSearchQuery
import moe.ganen.jikankt.models.search.AnimeSearchResult
import moe.ganen.jikankt.models.search.MangaSearchQuery
import moe.ganen.jikankt.models.search.MangaSearchResult
import moe.ganen.jikankt.models.season.Season
import moe.ganen.jikankt.models.season.SeasonArchives
import moe.ganen.jikankt.models.season.SeasonType
Expand Down Expand Up @@ -339,4 +343,96 @@ object JikanKt {
)

//endregion

//region Search

//region Anime

/**
* Search results for the query.
* NOTE: MyAnimeList only processes queries with a minimum of 3 letters.
* @param query: String that will be the query. For UTF8 characters, percentage encoded and queries including back slashes
* @param page: Optional, default is 1. Index of page.
* @param additionalQuery: Optional, additional query.
* @return list of anime that satisfy all the queries.
*/
suspend fun searchAnime(
query: String,
additionalQuery: AnimeSearchQuery? = null,
page: Int? = 1
): AnimeSearchResult {
val formattedQuery = query.replace(" ", "_")
val formattedAdditionalQuery = additionalQuery?.toString() ?: ""

return gson.deserialize(
restClient.request("search/anime/$page?q=$formattedQuery$formattedAdditionalQuery"),
AnimeSearchResult::class.java
)
}

/**
* Search results for the query.
* @param page: Optional, default is 1. Index of page.
* @param additionalQuery: Optional, additional query.
* @return list of anime that satisfy all the queries.
*/
suspend fun searchAnime(
additionalQuery: AnimeSearchQuery? = null,
page: Int? = 1
): AnimeSearchResult {
val formattedAdditionalQuery = additionalQuery?.toString() ?: ""

return gson.deserialize(
restClient.request("search/anime/$page?$formattedAdditionalQuery"),
AnimeSearchResult::class.java
)
}

//endregion

//region Manga

/**
* Search results for the query.
* NOTE: MyAnimeList only processes queries with a minimum of 3 letters.
* @param query: String that will be the query. For UTF8 characters, percentage encoded and queries including back slashes
* @param page: Optional, default is 1. Index of page.
* @param additionalQuery: Optional, additional query.
* @return list of anime that satisfy all the queries.
*/
suspend fun searchManga(
query: String,
additionalQuery: MangaSearchQuery? = null,
page: Int? = 1
): MangaSearchResult {
val formattedQuery = query.replace(" ", "_")
val formattedAdditionalQuery = additionalQuery?.toString() ?: ""

return gson.deserialize(
restClient.request("search/manga/$page?q=$formattedQuery$formattedAdditionalQuery"),
MangaSearchResult::class.java
)
}

/**
* Search results for the query.
* @param page: Optional, default is 1. Index of page.
* @param additionalQuery: Optional, additional query.
* @return list of anime that satisfy all the queries.
*/
suspend fun searchManga(
additionalQuery: MangaSearchQuery? = null,
page: Int? = 1
): MangaSearchResult {
val formattedAdditionalQuery = additionalQuery?.toString() ?: ""

return gson.deserialize(
restClient.request("search/manga/$page?$formattedAdditionalQuery"),
MangaSearchResult::class.java
)
}

//endregion

//endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package moe.ganen.jikankt.models.base.types

import com.google.gson.annotations.SerializedName
import moe.ganen.jikankt.models.base.MalEntity
import moe.ganen.jikankt.models.base.enum.AnimeType
import java.util.*

data class AnimeSearchSubEntity(
/**
* ID associated with MyAnimeList.
*/
@SerializedName("mal_id")
override val malId: Int,

/**
* Anime's MyAnimeList link.
*/
@SerializedName("url")
val url: String? = null,

/**
* Anime's MyAnimeList cover/image link.
*/
@SerializedName("image_url")
val imageUrl: String? = null,

/**
* Title of the anime.
*/
@SerializedName("title")
val title: String? = null,

/**
* Synopsis of the anime.
*/
@SerializedName("synopsis")
val synopsis: String? = null,

/**
* Type of the anime.
* @see AnimeType for the detail.
*/
@SerializedName("type")
val type: AnimeType? = null,

/**
* Score at MyAnimeList. Formatted up to 2 decimal places.
*/
@SerializedName("score")
val score: Double? = null,

/**
* Total episode(s) of the anime.
*/
@SerializedName("episodes")
val episodes: Int? = null,

/**
* Anime's members count on MyAnimeList.
*/
@SerializedName("members")
val members: Int? = null,

/**
* Whether the anime is currently airing or not.
*/
@SerializedName("airing")
val airing: Boolean? = null,

/**
* Anime airing date.
*/
@SerializedName("start_date")
val startDate: Date? = null,

/**
* Anime finished airing date.
*/
@SerializedName("end_date")
val endDate: Date? = null,

/**
* Rating of the anime (PG, G, Rx, etc.).
*/
@SerializedName("rated")
val rated: String? = null
) : MalEntity
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package moe.ganen.jikankt.models.base.types

import com.google.gson.annotations.SerializedName
import moe.ganen.jikankt.models.base.MalEntity
import moe.ganen.jikankt.models.search.enums.MangaType
import java.util.*

data class MangaSearchSubEntity(
/**
* ID associated with MyAnimeList.
*/
@SerializedName("mal_id")
override val malId: Int,

/**
* Manga's MyAnimeList link.
*/
@SerializedName("url")
val url: String? = null,

/**
* Manga's MyAnimeList cover/image link.
*/
@SerializedName("image_url")
val imageUrl: String? = null,

/**
* Title of the manga.
*/
@SerializedName("title")
val title: String? = null,

/**
* Synopsis of the manga.
*/
@SerializedName("synopsis")
val synopsis: String? = null,

/**
* Type of the manga.
* @see MangaType for the detail.
*/
@SerializedName("type")
val type: MangaType? = null,

/**
* Score at MyAnimeList. Formatted up to 2 decimal places.
*/
@SerializedName("score")
val score: Double? = null,

/**
* Total chapter(s) of the manga.
*/
@SerializedName("chapters")
val chapters: Int? = null,

/**
* Total volume(s) of the manga.
*/
@SerializedName("volumes")
val volumes: Int? = null,

/**
* Manga's members count on MyAnimeList.
*/
@SerializedName("members")
val members: Int? = null,

/**
* Whether the manga is currently publishing or not.
*/
@SerializedName("publishing")
val publishing: Boolean? = null,

/**
* Manga publishing date.
*/
@SerializedName("start_date")
val startDate: Date? = null,

/**
* Manga finished publishing date.
*/
@SerializedName("end_date")
val endDate: Date? = null
) : MalEntity
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package moe.ganen.jikankt.models.search

import moe.ganen.jikankt.models.search.enums.*
import java.text.SimpleDateFormat
import java.util.*

data class AnimeSearchQuery(
val type: AnimeType = AnimeType.All,
val status: AnimeStatus = AnimeStatus.All,
val rated: AgeRating = AgeRating.All,
val genre: List<AnimeGenre>? = null,
val score: Int? = null,
val startDate: Date? = null,
val endDate: Date? = null,
val excludedGenre: Boolean = false,
val limit: Int? = null,
val orderBy: AnimeOrderBy = AnimeOrderBy.None,
val sort: Sort = Sort.Descending,
val producerId: Int? = null
) {
override fun toString(): String {
val stringBuilder = StringBuilder()
val queryDateFormat = SimpleDateFormat("yyyy-MM-dd")

if (type != AnimeType.All)
stringBuilder.append("&type=${type.name}")

if (status != AnimeStatus.All)
stringBuilder.append("&status=${status.name}")

if (rated != AgeRating.All)
stringBuilder.append("&rated=${rated.name}")

if (!genre.isNullOrEmpty())
stringBuilder.append("&genre=${genre.joinToString(separator = ",") { "${it.ordinal}" }}")

if (score != null && score in 1..10)
stringBuilder.append("&score=$score")

if (startDate != null)
stringBuilder.append("&start_date=${queryDateFormat.format(startDate)}")

if (endDate != null)
stringBuilder.append("&end_date=${queryDateFormat.format(endDate)}")

if (excludedGenre)
stringBuilder.append("&genre_exclude=1")

if (limit != null)
stringBuilder.append("&limit=${limit}")

if (orderBy != AnimeOrderBy.None)
stringBuilder.append("&order_by=${if (orderBy.queryString.isNullOrEmpty()) orderBy.name else orderBy.queryString}")

if (sort == Sort.Ascending)
stringBuilder.append("&sort=asc")

if (producerId != null)
stringBuilder.append("&producer=${producerId}")

return stringBuilder.toString()
}
}
Loading