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

Commit

Permalink
Implement search endpoints (#7)
Browse files Browse the repository at this point in the history
* Add anime search endpoints

* Add manga endpoints

* Fix docs
  • Loading branch information
GSculerlor committed Apr 26, 2020
1 parent d2a012e commit 6e30c55
Show file tree
Hide file tree
Showing 16 changed files with 616 additions and 5 deletions.
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

0 comments on commit 6e30c55

Please sign in to comment.