This commit is contained in:
2024-02-27 22:09:30 +03:00
parent bfa3231823
commit 38a3141d43
479 changed files with 36348 additions and 10142 deletions

1
providers/github/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
build

View 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())
}

View 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)
}
}

View File

@@ -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
)

View File

@@ -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
}
}
}

View File

@@ -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
)

View File

@@ -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>>()
}