Skip to content

Commit

Permalink
update Ktor to 2.x and fix serialization issues
Browse files Browse the repository at this point in the history
  • Loading branch information
danielyrovas committed Feb 15, 2024
1 parent 9abe961 commit ceed827
Show file tree
Hide file tree
Showing 14 changed files with 240 additions and 189 deletions.
153 changes: 87 additions & 66 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,97 @@
name: Build, Sign, Release

permissions: write-all
on:
push:
branches:
- trunk

permissions: write-all
# tags:
# - 'v*.*.*'

jobs:
build:
test:
runs-on: ubuntu-latest

steps:
- name: checkout
uses: actions/checkout@v4

- name: Set up our JDK environment
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name:
uses: gradle/actions/setup-gradle@v3

- name: Execute Gradle build
run: ./gradlew --build-cache assembleRelease

- name: Sign artifact
id: sign_artifact
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: app/build/outputs/apk/release
alias: ${{ secrets.KEY_ALIAS }}
signingKeyBase64: ${{ secrets.KEYSTORE }}
keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "34.0.0"

- name: Upload our APK
uses: actions/upload-artifact@v2
with:
name: Release artifact
path: app/build/outputs/apk/release/app-*.apk

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: trunk
release_name: Release trunk
draft: false
prerelease: false

- name: Save name of our Artifact
id: set-result-artifact
run: |
ARTIFACT_PATHNAME_APK=$(ls app/build/outputs/apk/release/*.apk | head -n 1)
ARTIFACT_NAME_APK=$(basename $ARTIFACT_PATHNAME_APK)
echo "ARTIFACT_NAME_APK is " ${ARTIFACT_NAME_APK}
echo "ARTIFACT_PATHNAME_APK=${ARTIFACT_PATHNAME_APK}" >> $GITHUB_ENV
echo "ARTIFACT_NAME_APK=${ARTIFACT_NAME_APK}" >> $GITHUB_ENV
- uses: actions/checkout@v2
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Test
run: |
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
- name: Upload our Artifact Assets
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ env.ARTIFACT_PATHNAME_APK }}
asset_name: ${{ env.ARTIFACT_NAME_APK }}
asset_content_type: application/zip
# jobs:
# build:
# runs-on: ubuntu-latest
#
# steps:
# - name: checkout
# uses: actions/checkout@v4
#
# - name: Set up JDK env
# uses: actions/setup-java@v4
# with:
# distribution: 'temurin'
# java-version: 19
# cache: 'gradle'
#
# # - name:
# # uses: gradle/actions/setup-gradle@v3
#
# - name: Execute Gradle build
# run: ./gradlew --no-daemon --build-cache assembleRelease
#
# # - name: Setup build tool version variable
# # shell: bash
# # run: |
# # BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
# # echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
# # echo Last build tool version is: $BUILD_TOOL_VERSION
# #
# # - name: Sign artifact
# # id: sign_artifact
# # uses: r0adkll/sign-android-release@v1
# # with:
# # releaseDirectory: app/build/outputs/apk/release
# # alias: ${{ secrets.KEY_ALIAS }}
# # signingKeyBase64: ${{ secrets.KEYSTORE }}
# # keyStorePassword: ${{ secrets.KEY_PASSWD }}
# # keyPassword: ${{ secrets.KEY_PASSWD }}
# # env:
# # BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOL_VERSION }}
#
# - name: Upload our APK
# uses: actions/upload-artifact@v2
# with:
# name: Release artifact
# path: app/build/outputs/apk/release/app-*.apk
#
# - name: Create Release
# id: create_release
# uses: actions/create-release@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# tag_name: trunk
# release_name: Release trunk
# draft: false
# prerelease: false
#
# - name: Save name of our Artifact
# id: set-result-artifact
# run: |
# ARTIFACT_PATHNAME_APK=$(ls app/build/outputs/apk/release/*.apk | head -n 1)
# ARTIFACT_NAME_APK=$(basename $ARTIFACT_PATHNAME_APK)
# echo "ARTIFACT_NAME_APK is " ${ARTIFACT_NAME_APK}
# echo "ARTIFACT_PATHNAME_APK=${ARTIFACT_PATHNAME_APK}" >> $GITHUB_ENV
# echo "ARTIFACT_NAME_APK=${ARTIFACT_NAME_APK}" >> $GITHUB_ENV
#
# - name: Upload our Artifact Assets
# id: upload-release-asset
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: ${{ env.ARTIFACT_PATHNAME_APK }}
# asset_name: ${{ env.ARTIFACT_NAME_APK }}
# asset_content_type: application/zip
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
)
Expand Down Expand Up @@ -79,6 +80,8 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.ktor.client.serialization)
implementation(libs.ktor.client.logging.jvm)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
Expand Down
3 changes: 2 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
-dontwarn org.slf4j.impl.StaticLoggerBinder
20 changes: 20 additions & 0 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "org.yrovas.linklater",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "0.1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}
2 changes: 2 additions & 0 deletions app/src/main/java/org/yrovas/linklater/EmptyBookmarkAPI.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.yrovas.linklater

import android.content.Context
import androidx.annotation.Keep
import org.yrovas.linklater.data.Bookmark
import org.yrovas.linklater.data.LocalBookmark

@Keep
class EmptyBookmarkAPI : BookmarkAPI {
override suspend fun getBookmarks(
page: Int,
Expand Down
60 changes: 30 additions & 30 deletions app/src/main/java/org/yrovas/linklater/KtorClient.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
package org.yrovas.linklater

import android.util.Log
import androidx.annotation.Keep
import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
import io.ktor.client.features.DefaultRequest
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.features.logging.*
import io.ktor.client.features.observer.ResponseObserver
import io.ktor.client.plugins.DefaultRequest
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.logging.*
import io.ktor.client.request.header
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json

private const val TIME_OUT = 60_000
// private const val TIME_OUT = 60_000

class Ktor {
companion object {
val client = HttpClient(Android) {

install(JsonFeature) {
serializer = KotlinxSerializer(Json {
install(Logging) {
logger = object : Logger {
override fun log(message: String) {
Log.i("Ktor =>", message)
}
}
level = LogLevel.ALL
}
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})

engine {
connectTimeout = TIME_OUT
socketTimeout = TIME_OUT
}
}

// install(Logging) {
// logger = object : Logger {
// override fun log(message: String) {
// Log.v("Ktor =>", message)
// }
// }
// level = LogLevel.ALL
// }

install(ResponseObserver) {
onResponse { response ->
Log.d("HTTP status:", "${response.status.value}")
}
}

install(DefaultRequest) {
header(HttpHeaders.ContentType, ContentType.Application.Json)
}
}
}
}
//
//// if (BuildConfig.DEBUG) {
// install(Logging) {
// level = LogLevel.ALL
// }
//// }
//
//// if (BuildConfig.DEBUG) {
// install(ResponseObserver) {
// onResponse { response ->
// Log.i("HTTP status:", "${response.status.value}")
// }
// }
//// }
40 changes: 21 additions & 19 deletions app/src/main/java/org/yrovas/linklater/LinkDingAPI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package org.yrovas.linklater

import android.content.Context
import android.util.Log
import io.ktor.client.call.body
import io.ktor.client.request.*
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToJsonElement
Expand All @@ -13,6 +14,7 @@ import java.io.File

const val BOOKMARKS_CACHE_PATH = "bookmark_page_cache.json"
const val TAGS_CACHE_PATH = "tags_cache.json"
const val TAG = "DEBUG"

class LinkDingAPI(
private var endpoint: String,
Expand All @@ -25,33 +27,33 @@ class LinkDingAPI(
): Result<List<Bookmark>> {
return runCatching {
Log.d("DEBUG/net", "getBookmarks: starting request")
val response =
Ktor.client.get<BookmarkResponse>("$endpoint/bookmarks/") {
if (page > 0) {
url.parameters.append(
"offset", (pageSize * page).toString()
)
}
if (!query.isNullOrBlank()) {
url.parameters.append("q", query)
}
header("Authorization", "Token $token")
val response = Ktor.client.get("$endpoint/bookmarks/") {
header("Authorization", "Token $token")
if (page > 0) {
url.parameters.append(
"offset", (pageSize * page).toString()
)
}
if (!query.isNullOrBlank()) {
url.parameters.append("q", query)
}
response.results
}
// Json.decodeFromString<BookmarkResponse>(response.bodyAsText()).results
response.body<BookmarkResponse>().results // ?? very kool Ktor
}.onFailure {
Log.i(TAG, "getBookmarks: ${it.message}")
Result.failure<List<Bookmark>>(it)
}
}

override suspend fun saveBookmark(bookmark: LocalBookmark): Boolean {
return Ktor.client.post<HttpResponse>("$endpoint/bookmarks/") {
body = bookmark
return Ktor.client.post("$endpoint/bookmarks/") {
setBody(bookmark)
header("Authorization", "Token $token")
}.status.value in 200..299
}

override suspend fun getCachedBookmarks(context: Context): List<Bookmark> {
// return emptyList()
val cache = File(context.cacheDir, BOOKMARKS_CACHE_PATH)
return runCatching {
Json.decodeFromString<List<Bookmark>>(cache.readText())
Expand All @@ -73,13 +75,13 @@ class LinkDingAPI(
override suspend fun getTags(page: Int): Result<List<String>> {
return runCatching {
Log.d("DEBUG/net", "getTags: starting request")
val response = Ktor.client.get<TagResponse>("$endpoint/tags/") {
val response = Ktor.client.get("$endpoint/tags/") {
header("Authorization", "Token $token")
if (page > 0) {
url.parameters.append("offset", (pageSize * page).toString())
}
header("Authorization", "Token $token")
}
response.results
response.body<TagResponse>().results
}.onFailure {
Result.failure<List<String>>(it)
}
Expand Down
Loading

0 comments on commit ceed827

Please sign in to comment.