Skip to content

Commit

Permalink
Adding proxy support (#18)
Browse files Browse the repository at this point in the history
* Added Proxy Support
* Created MavenCentral Publishing
* Updated README
  • Loading branch information
husnjak authored Oct 19, 2022
1 parent cffef6a commit 0446f88
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 49 deletions.
43 changes: 29 additions & 14 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ on:
inputs:
packagePrefix:
required: true
default: 'test'
description: "Packages require a package version"
default: 'SNAPSHOT'
description: "Packages require a package version, Keep SNAPSHOT for snapshot upload. Replace SNAPSHOT for staging deploy."
release:
types: # This configuration does not affect the page_build event above
- created
Expand All @@ -27,22 +27,37 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
- uses: actions/checkout@v3
- name: Setup JDK 11
uses: actions/setup-java@v3
with:
java-version: 11
distribution: 'adopt'
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- if: github.event.release.tag_name == ''
name: Publish release package
run: gradle publish
name: Publish SNAPSHOT package
run: ./gradlew publish --no-daemon
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_VERSION: ${{ github.run_id }}
ORG_GRADLE_PROJECT_github_token: ${{ secrets.GITHUB_TOKEN }}
ORG_GRADLE_PROJECT_github_actor: ${ GITHUB_ACTOR }
ORG_GRADLE_PROJECT_sonatype_username: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_sonatype_password: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.PGP_PASSPHRASE }}
ORG_GRADLE_PROJECT_version: ${{ steps.extract_branch.outputs.branch }}-${{ github.run_id }}-${{ github.event.inputs.packagePrefix }}
- if: github.event.inputs.packagePrefix == ''
name: Publish package
run: gradle publish
name: Publish Release package
run: ./gradlew publish --no-daemon
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_VERSION: ${{ github.event.release.tag_name }} || "${{ github.event.inputs.packagePrefix }}-${{ github.run_id }}"
ORG_GRADLE_PROJECT_github_token: ${{ secrets.GITHUB_TOKEN }}
ORG_GRADLE_PROJECT_github_actor: ${ GITHUB_ACTOR }
ORG_GRADLE_PROJECT_sonatype_username: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_sonatype_password: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.PGP_PASSPHRASE }}
ORG_GRADLE_PROJECT_version: ${{ github.event.release.tag_name }}
5 changes: 3 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Execute Gradle build
run: ./gradlew build
run: ./gradlew build --no-daemon -x publish -x sign
env:
client_id: "${{ secrets.CLIENT_ID }}"
client_secret: "${{ secrets.CLIENT_SECRET }}"
bearer: "${{ secrets.BEARER_TOKEN }}"
bearer: "${{ secrets.BEARER_TOKEN }}"
ORG_GRADLE_PROJECT_version: Build-${{ github.run_id }}"
46 changes: 25 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
![Maven Central](https://img.shields.io/maven-central/v/io.github.husnjak/igdb-api-jvm)
[![](https://jitpack.io/v/husnjak/IGDB-API-JVM.svg)](https://jitpack.io/#husnjak/IGDB-API-JVM)
# IGDB API-JVM (V4)
A Kotlin wrapper for the IGDB.com Video Game Database API.
Expand Down Expand Up @@ -30,35 +31,22 @@ The Wrapper can handle both the IGDB generated classes and JSON (Strings), I hav
__Maven__

```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependency>
<groupId>com.github.husnjak</groupId>
<artifactId>IGDB-API-JVM</artifactId>
<version>1.0.6</version>
<groupId>io.github.husnjak</groupId>
<artifactId>igdb-api-jvm</artifactId>
<version>1.0.7</version>
</dependency>
```

__Gradle__

Step 1. Add this in your root build.gradle at the end of the repositories:
```Gradle
repositories {
maven { url 'https://jitpack.io' }
}
```
Step 2. Add the dependency
``` Gradle

``` gradle
dependencies {
implementation 'com.github.husnjak:IGDB-API-JVM:1.0.6'
implementation 'io.github.husnjak:igdb-api-jvm:1.0.7'
}
```
Optional Step 3 (Android, SDK: 19+). Add internet permissions in the manifest.

Optional for Android (SDK: 19+). Add internet permissions in the manifest.
``` xml
<uses-permission android:name="android.permission.INTERNET" />
```
Expand Down Expand Up @@ -105,6 +93,22 @@ You can use the access_token from the token object.
### Android projects
Do not use the `TwitchAuthenticator` in your Android applications, you don't want to create multiple access_tokens for each device.
It is recommended to create your token on a server and then use a proxy api to call the IGDB api, where you append the Bearer token for each request.

IGDB provides a [free AWS CloudFormation template](https://api-docs.igdb.com/#proxy) that you can deploy for this purpose with instructions on how to use it.
* Create a new IGDBWrapper Object connected to the AWS Proxy server.
``` java
// Java Example
IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
Map<String, String> proxyHeaders = new HashMap<String, String>() {{
put("x-api-key", "PROXY_API_KEY");
}};
wrapper.setupProxy("PROXY_URL/v4", proxyHeaders);
```
``` kotlin
// Kotlin Example
IGDBWrapper.setupProxy("PROXY_URL/v4", mapOf("x-api-key" to "PROXY_API_KEY"))
```

# How to use the wrapper
The wrapper has two "wrapping" functions, and a lot of helper functions (one for each endpoint)
The two main functions called `apiProtoRequest` and `apiJsonRequest` and they handle all the requests to the api.
Expand Down
40 changes: 35 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ plugins {
kotlin("jvm") version "1.7.20"
id("org.jetbrains.dokka") version "1.7.20"
id("maven-publish")
id("signing")
id("de.undercouch.download") version "4.0.4"
id("com.google.protobuf") version "0.8.19"
}

group = "com.api.igdb"
version = project.findProperty("com.api.igdb.version") ?: System.getenv("RELEASE_VERSION")
group = "io.github.husnjak"
version = findProperty("version") as String

val fuelVersion = "2.3.1"
val protobufJavaVersion = "3.21.7"
Expand Down Expand Up @@ -90,6 +91,7 @@ val dokkaJar by tasks.creating(Jar::class) {
}

val sourcesJar by tasks.creating(Jar::class) {
dependsOn("generateProto")
manifest {
attributes("Main-Class" to "com.api.igdb.ApiRequesterKt")
}
Expand All @@ -101,7 +103,7 @@ val sourcesJar by tasks.creating(Jar::class) {

publishing {
publications {
register<MavenPublication>("gpr") {
create<MavenPublication>("maven") {
from(components["kotlin"])
artifact(dokkaJar)
artifact(sourcesJar)
Expand All @@ -116,6 +118,7 @@ publishing {
}

pom {
name.set("igdb-api-jvm")
description.set("Kotlin wrapper for the IGDB API compiled for the JVM.")
url.set("https://github.com/husnjak/igdb-api-jvm.git")
licenses {
Expand All @@ -129,6 +132,11 @@ publishing {
id.set("husnjak")
}
}
scm {
connection.set("scm:git:https://github.com/husnjak/IGDB-API-JVM.git")
developerConnection.set("scm:git:git@github.com:husnjak/IGDB-API-JVM.git")
url.set("https://github.com/husnjak/IGDB-API-JVM")
}
}
}
}
Expand All @@ -137,9 +145,31 @@ publishing {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/husnjak/igdb-api-jvm")
credentials {
username = findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
password = findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
username = findProperty("github_actor") as String?
password = findProperty("github_token") as String?
}
}
maven {
name = "Sonatype"
val releasesRepoUrl = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
val snapshotsRepoUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
url = if (version.toString().contains("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
println("Sonatype release version: $version using: $url")
credentials {
username = findProperty("sonatype_username") as String?
password = findProperty("sonatype_password") as String?
}
}
}
}

signing {
if (version.toString().contains("local")) {
useGpgCmd()
} else {
val signingKey: String? by project
val signingPassword: String? by project
useInMemoryPgpKeys(signingKey, signingPassword)
}
sign(publishing.publications["maven"])
}
22 changes: 17 additions & 5 deletions src/main/kotlin/com/api/igdb/request/IGDBWrapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,33 @@ import com.github.kittinunf.fuel.httpPost
/**
* The ApiRequester object holds the API Key and uses it to request the IGDB API.
*/
private const val IGDB_API_URL = "https://api.igdb.com/v4"
private var IGDB_API_URL = "https://api.igdb.com/v4"
object IGDBWrapper {
private var requestHeaders: Map<String, Any> = mapOf("x-user-agent" to "igdb-api-jvm")

/**
* The Set method for API Credentials
*
* @property endpoint The endpoint the request
* @property query The Api query to request with
* @return The raw ByteArray to use with generated proto files
* @property clientID The IGDB ClientID
* @property accessToken The IGDB AccessToken
*/
fun setCredentials(clientID: String, accessToken: String) {
requestHeaders = mapOf(
"client-id" to clientID,
"authorization" to "Bearer $accessToken", "x-user-agent" to "igdb-api-jvm")
"authorization" to "Bearer $accessToken",
"x-user-agent" to "igdb-api-jvm")
}

/**
* The set method for Proxy credentials
*
* @property proxyURL The url of the Proxy Server
* @property proxyHeaders The headers to send to the Proxy Server
*/
fun setupProxy(proxyURL: String, proxyHeaders: Map<String, String>) {
IGDB_API_URL = proxyURL
proxyHeaders.toMutableMap()["x-user-agent"] = "igdb-api-jvm"
requestHeaders = proxyHeaders.toMap()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object TwitchAuthenticator {

private var twitchClientID: String = ""
private var twitchClientSecret: String = ""
var twitchToken: TwitchToken? = null
private var twitchToken: TwitchToken? = null

/**
* The Twitch OAuth request function
Expand Down
1 change: 0 additions & 1 deletion src/test/java/com/api/igdb/TestTwitchToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ void testGetTwitchToken() {
TwitchToken token = tAuth.requestTwitchToken(System.getenv("client_id"), System.getenv("client_secret"));

assertNotNull(token);
System.out.println(token.getExpires_in());
assertTrue(token.getExpires_in() > 5000000);
long tokenFutureDate = System.currentTimeMillis() + 5000000; // 57 days
assertTrue(tokenFutureDate > token.getExpiresUnix());
Expand Down
88 changes: 88 additions & 0 deletions src/test/kotlin/com/api/igdb/TestProxy.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.api.igdb

import com.api.igdb.apicalypse.APICalypse
import com.api.igdb.apicalypse.Sort
import com.api.igdb.exceptions.RequestException
import com.api.igdb.request.IGDBWrapper
import com.api.igdb.request.games
import com.api.igdb.request.search
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class TestProxy {

private val wrapper = IGDBWrapper

@BeforeEach
fun setup() {
wrapper.setupProxy(proxyURL = System.getenv("proxy_url"), proxyHeaders = mapOf("x-api-key" to System.getenv("proxy_api_key")))
}

//Get all Coming Soon PS4 games
@Test
fun testComingSoonPS4Games() {
val date = (System.currentTimeMillis() / 1000).toString()
val query = APICalypse()
.fields("*")
.where("platforms = 48 & release_dates.date > $date")
.sort("release_dates.date", Sort.ASCENDING)

try {
val ps4Games = wrapper.games(query)
assert(ps4Games.isNotEmpty())
} catch (e: RequestException) {
assert(false)
}
}

//Get all Recently released PS4 games
@Test
fun testRecentlyReleasedPS4Games() {
val date = (System.currentTimeMillis() / 1000).toString()
val query = APICalypse()
.fields("*")
.where("platforms = 48 & release_dates.date < $date")
.sort("release_dates.date", Sort.DESCENDING)

try {
val ps4Games = wrapper.games(query)
assert(ps4Games.isNotEmpty())
} catch (e: RequestException) {
assert(false)
}
}

//Get all Recently released PS4 games
@Test
fun testSearch() {
val query = APICalypse()
.search("Assassins Creed")
.fields("game.name,game.involved_companies")
.where("game != null & game.version_parent = null")

try {
val result = wrapper.search(query)
assert(result.isNotEmpty())
} catch (e: RequestException) {
assert(false)
}

}

//Get all Recently released PS4 games
@Test
fun testPS4Exclusives() {
val query = APICalypse()
.fields("name,category,platforms")
.where("category = 0 & platforms = 48")

try {
val result = wrapper.games(query)
assert(result.isNotEmpty())
} catch (e: RequestException) {
assert(false)
}

}

}

0 comments on commit 0446f88

Please sign in to comment.