0.6.0
This commit is contained in:
1
providers/github/.gitignore
vendored
Normal file
1
providers/github/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build
|
||||
24
providers/github/build.gradle.kts
Normal file
24
providers/github/build.gradle.kts
Normal file
@@ -0,0 +1,24 @@
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.android.lint)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.providers.common)
|
||||
|
||||
implementation(libs.kotlin.coroutines)
|
||||
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.cio)
|
||||
implementation(libs.ktor.client.content.negotiation)
|
||||
implementation(libs.ktor.client.serialization)
|
||||
implementation(libs.ktor.serialization.json)
|
||||
|
||||
detektPlugins(libs.detekt.compose)
|
||||
detektPlugins(libs.detekt.formatting)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(libs.versions.jvm.get().toInt())
|
||||
}
|
||||
55
providers/github/src/main/kotlin/it/hamy/github/GitHub.kt
Normal file
55
providers/github/src/main/kotlin/it/hamy/github/GitHub.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
package it.hamy.github
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.plugins.defaultRequest
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.accept
|
||||
import io.ktor.client.request.parameter
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.contentType
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
private const val API_VERSION = "2022-11-28"
|
||||
private const val CONTENT_TYPE = "application"
|
||||
private const val CONTENT_SUBTYPE = "vnd.github+json"
|
||||
|
||||
object GitHub {
|
||||
internal val httpClient by lazy {
|
||||
HttpClient(CIO) {
|
||||
val contentType = ContentType(CONTENT_TYPE, CONTENT_SUBTYPE)
|
||||
|
||||
install(ContentNegotiation) {
|
||||
val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
|
||||
json(json)
|
||||
json(
|
||||
json = json,
|
||||
contentType = contentType
|
||||
)
|
||||
}
|
||||
|
||||
defaultRequest {
|
||||
url("https://api.github.com")
|
||||
headers["X-GitHub-Api-Version"] = API_VERSION
|
||||
|
||||
accept(contentType)
|
||||
contentType(ContentType.Application.Json)
|
||||
}
|
||||
|
||||
expectSuccess = true
|
||||
}
|
||||
}
|
||||
|
||||
fun HttpRequestBuilder.withPagination(size: Int, page: Int) {
|
||||
require(page > 0) { "GitHub error: invalid page ($page), pagination starts at page 1" }
|
||||
require(size > 0) { "GitHub error: invalid page size ($size), a page has to have at least a single item" }
|
||||
|
||||
parameter("per_page", size)
|
||||
parameter("page", page)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package it.hamy.github.models
|
||||
|
||||
import it.hamy.extensions.SerializableUrl
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Reactions(
|
||||
val url: SerializableUrl,
|
||||
@SerialName("total_count")
|
||||
val count: Int,
|
||||
@SerialName("+1")
|
||||
val likes: Int,
|
||||
@SerialName("-1")
|
||||
val dislikes: Int,
|
||||
@SerialName("laugh")
|
||||
val laughs: Int,
|
||||
val confused: Int,
|
||||
@SerialName("heart")
|
||||
val hearts: Int,
|
||||
@SerialName("hooray")
|
||||
val hoorays: Int,
|
||||
val eyes: Int,
|
||||
@SerialName("rocket")
|
||||
val rockets: Int
|
||||
)
|
||||
@@ -0,0 +1,71 @@
|
||||
package it.hamy.github.models
|
||||
|
||||
import it.hamy.extensions.SerializableIso8601Date
|
||||
import it.hamy.extensions.SerializableUrl
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Release(
|
||||
val id: Int,
|
||||
@SerialName("node_id")
|
||||
val nodeId: String,
|
||||
val url: SerializableUrl,
|
||||
@SerialName("html_url")
|
||||
val frontendUrl: SerializableUrl,
|
||||
@SerialName("assets_url")
|
||||
val assetsUrl: SerializableUrl,
|
||||
@SerialName("tag_name")
|
||||
val tag: String,
|
||||
val name: String? = null,
|
||||
@SerialName("body")
|
||||
val markdown: String? = null,
|
||||
val draft: Boolean,
|
||||
@SerialName("prerelease")
|
||||
val preRelease: Boolean,
|
||||
@SerialName("created_at")
|
||||
val createdAt: SerializableIso8601Date,
|
||||
@SerialName("published_at")
|
||||
val publishedAt: SerializableIso8601Date? = null,
|
||||
val author: SimpleUser,
|
||||
val assets: List<Asset> = emptyList(),
|
||||
@SerialName("body_html")
|
||||
val html: String? = null,
|
||||
@SerialName("body_text")
|
||||
val text: String? = null,
|
||||
@SerialName("discussion_url")
|
||||
val discussionUrl: SerializableUrl? = null,
|
||||
val reactions: Reactions? = null
|
||||
) {
|
||||
@Serializable
|
||||
data class Asset(
|
||||
val url: SerializableUrl,
|
||||
@SerialName("browser_download_url")
|
||||
val downloadUrl: SerializableUrl,
|
||||
val id: Int,
|
||||
@SerialName("node_id")
|
||||
val nodeId: String,
|
||||
val name: String,
|
||||
val label: String? = null,
|
||||
val state: State,
|
||||
@SerialName("content_type")
|
||||
val contentType: String,
|
||||
val size: Long,
|
||||
@SerialName("download_count")
|
||||
val downloads: Int,
|
||||
@SerialName("created_at")
|
||||
val createdAt: SerializableIso8601Date,
|
||||
@SerialName("updated_at")
|
||||
val updatedAt: SerializableIso8601Date,
|
||||
val uploader: SimpleUser? = null
|
||||
) {
|
||||
@Serializable
|
||||
enum class State {
|
||||
@SerialName("uploaded")
|
||||
Uploaded,
|
||||
|
||||
@SerialName("open")
|
||||
Open
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package it.hamy.github.models
|
||||
|
||||
import it.hamy.extensions.SerializableUrl
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SimpleUser(
|
||||
val name: String? = null,
|
||||
val email: String? = null,
|
||||
val login: String,
|
||||
val id: Int,
|
||||
@SerialName("node_id")
|
||||
val nodeId: String,
|
||||
@SerialName("avatar_url")
|
||||
val avatarUrl: SerializableUrl,
|
||||
@SerialName("gravatar_id")
|
||||
val gravatarId: String? = null,
|
||||
val url: SerializableUrl,
|
||||
@SerialName("html_url")
|
||||
val frontendUrl: SerializableUrl,
|
||||
@SerialName("followers_url")
|
||||
val followersUrl: SerializableUrl,
|
||||
@SerialName("following_url")
|
||||
val followingUrl: SerializableUrl,
|
||||
@SerialName("gists_url")
|
||||
val gistsUrl: SerializableUrl,
|
||||
@SerialName("starred_url")
|
||||
val starredUrl: SerializableUrl,
|
||||
@SerialName("subscriptions_url")
|
||||
val subscriptionsUrl: SerializableUrl,
|
||||
@SerialName("organizations_url")
|
||||
val organizationsUrl: SerializableUrl,
|
||||
@SerialName("repos_url")
|
||||
val reposUrl: SerializableUrl,
|
||||
@SerialName("events_url")
|
||||
val eventsUrl: SerializableUrl,
|
||||
@SerialName("received_events_url")
|
||||
val receivedEventsUrl: SerializableUrl,
|
||||
val type: String,
|
||||
@SerialName("site_admin")
|
||||
val admin: Boolean
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package it.hamy.github.requests
|
||||
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import it.hamy.extensions.runCatchingCancellable
|
||||
import it.hamy.github.GitHub
|
||||
import it.hamy.github.models.Release
|
||||
|
||||
suspend fun GitHub.releases(
|
||||
owner: String,
|
||||
repo: String,
|
||||
page: Int = 1,
|
||||
pageSize: Int = 30
|
||||
) = runCatchingCancellable {
|
||||
httpClient.get("repos/$owner/$repo/releases") {
|
||||
withPagination(page = page, size = pageSize)
|
||||
}.body<List<Release>>()
|
||||
}
|
||||
Reference in New Issue
Block a user