From ae57ff8e5a2bceea9ad66dfa5cb329c9ef18b55f Mon Sep 17 00:00:00 2001 From: Hermann Krumrey Date: Mon, 3 Sep 2018 23:09:44 +0200 Subject: [PATCH 1/6] Adjust gradle build --- app/build.gradle | 18 +++++++++ build.gradle | 34 ++-------------- gradle-config/dokka-android.gradle | 27 +++++++++++++ gradle-config/dokka.gradle | 2 +- gradle-config/jacoco-android.gradle | 60 +++++++++++++++++++++++++++++ gradle-config/jacoco.gradle | 38 +++--------------- gradle-config/version.gradle | 11 +++++- 7 files changed, 126 insertions(+), 64 deletions(-) create mode 100644 gradle-config/dokka-android.gradle create mode 100644 gradle-config/jacoco-android.gradle diff --git a/app/build.gradle b/app/build.gradle index cc3f78a..ac68f54 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with bundesliga-tippspiel-android. If not, see . */ +apply plugin: "com.android.application" +apply plugin: "kotlin-android" + android { compileSdkVersion 27 buildToolsVersion '27.0.3' @@ -38,3 +41,18 @@ android { exclude 'META-INF/*' } } + +dependencies { + api "com.android.support:appcompat-v7:27.1.1" + api "com.android.support:support-v4:27.1.1" + api "com.android.support:cardview-v7:27.1.1" + api "org.jetbrains.anko:anko-commons:0.10.5" + api 'com.google.code.gson:gson:2.8.5' + api "com.squareup.okhttp3:okhttp:3.10.0" + testImplementation 'org.json:json:20180130' + // api project(':lib') +} + +apply from: "$rootDir/gradle-config/jacoco-android.gradle" +apply from: "$rootDir/gradle-config/dokka-android.gradle" +apply from: "$rootDir/gradle-config/ktlint.gradle" diff --git a/build.gradle b/build.gradle index 993f83a..05c80dd 100644 --- a/build.gradle +++ b/build.gradle @@ -17,17 +17,11 @@ You should have received a copy of the GNU General Public License along with bundesliga-tippspiel-android. If not, see . */ -ext { - version = new File("$rootDir/version").text - majorVersion = version.split("\\.")[0].padLeft(2, "0") - minorVersion = version.split("\\.")[1].padLeft(2, "0") - patchVersion = version.split("\\.")[2].padLeft(2, "0") - versionCode = (majorVersion + minorVersion + patchVersion).toInteger() - versionCode += 100000 // Necessary due to mistake made in previous releases -} +apply from: "$rootDir/gradle-config/version.gradle" buildscript { repositories { + google() jcenter() mavenCentral() } @@ -38,29 +32,9 @@ buildscript { } } -subprojects { +allprojects { repositories { + google() jcenter() - mavenCentral() - maven { url "https://jitpack.io" } } - apply plugin: 'com.android.application' - apply plugin: 'kotlin-android' - - dependencies { - api "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.41" - api "org.jetbrains.anko:anko-commons:0.10.5" - api 'com.android.support:appcompat-v7:27.1.1' - api 'com.android.support:support-v4:27.1.1' - api 'com.android.support:cardview-v7:27.1.1' - api 'com.google.code.gson:gson:2.8.5' - api "com.squareup.okhttp3:okhttp:3.10.0" - testImplementation 'org.json:json:20180130' - } - - apply from: "$rootDir/gradle-config/jacoco.gradle" - apply from: "$rootDir/gradle-config/dokka.gradle" - apply from: "$rootDir/gradle-config/ktlint.gradle" } - -apply from: "$rootDir/gradle-config/version.gradle" diff --git a/gradle-config/dokka-android.gradle b/gradle-config/dokka-android.gradle new file mode 100644 index 0000000..dd52173 --- /dev/null +++ b/gradle-config/dokka-android.gradle @@ -0,0 +1,27 @@ +/* +Copyright 2017 Hermann Krumrey + +This file is part of bundesliga-tippspiel-android. + +bundesliga-tippspiel-android is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +bundesliga-tippspiel-android is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with bundesliga-tippspiel-android. If not, see . +*/ + +apply plugin: 'org.jetbrains.dokka-android' + +dokka { + outputFormat = 'javadoc' + outputDirectory = "$buildDir/javadoc" + skipEmptyPackages = true + noStdlibLink = true +} diff --git a/gradle-config/dokka.gradle b/gradle-config/dokka.gradle index dd52173..4a3d28c 100644 --- a/gradle-config/dokka.gradle +++ b/gradle-config/dokka.gradle @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with bundesliga-tippspiel-android. If not, see . */ -apply plugin: 'org.jetbrains.dokka-android' +apply plugin: 'org.jetbrains.dokka' dokka { outputFormat = 'javadoc' diff --git a/gradle-config/jacoco-android.gradle b/gradle-config/jacoco-android.gradle new file mode 100644 index 0000000..8c694bd --- /dev/null +++ b/gradle-config/jacoco-android.gradle @@ -0,0 +1,60 @@ +/* +Copyright 2017 Hermann Krumrey + +This file is part of bundesliga-tippspiel-android. + +bundesliga-tippspiel-android is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +bundesliga-tippspiel-android is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with bundesliga-tippspiel-android. If not, see . +*/ + +apply plugin: 'kotlin-android' +apply plugin: 'jacoco' + +dependencies { + testImplementation "org.jetbrains.kotlin:kotlin-test-junit:1.2.41" +} + +task jacocoTestReport(type: JacocoReport, dependsOn: "testDebugUnitTest") { + group = "Reporting" + description = "Generate Jacoco coverage reports for Debug build" + reports { + xml.enabled = true + html.enabled = true + } + + def excludes = [ + '**/R.class', + '**/R$*.class', + '**/*$ViewInjector*.*', + '**/BuildConfig.*', + '**/Manifest*.*', + '**/*Test*.*', + 'android/**/*.*', + '**/*Fragment.*', + '**/*Activity.*' + ] + + classDirectories = fileTree( + dir: "$buildDir/intermediates/classes/debug", + excludes: excludes + ) + fileTree( + dir: "$buildDir/tmp/kotlin-classes/debug", + excludes: excludes + ) + + sourceDirectories = files([ + android.sourceSets.main.java.srcDirs, + "src/main/kotlin" + ]) + executionData = files("$buildDir/jacoco/testDebugUnitTest.exec") +} \ No newline at end of file diff --git a/gradle-config/jacoco.gradle b/gradle-config/jacoco.gradle index 81b38b0..e0375d8 100644 --- a/gradle-config/jacoco.gradle +++ b/gradle-config/jacoco.gradle @@ -20,40 +20,14 @@ along with bundesliga-tippspiel-android. If not, see . */ +ext { + version = new File("$rootDir/version").text + majorVersion = version.split("\\.")[0].padLeft(2, "0") + minorVersion = version.split("\\.")[1].padLeft(2, "0") + patchVersion = version.split("\\.")[2].padLeft(2, "0") + versionCode = (majorVersion + minorVersion + patchVersion).toInteger() + versionCode += 100000 // Necessary due to mistake made in previous releases +} + task version(type: VersionTask) class VersionTask extends DefaultTask { @SuppressWarnings("GroovyUnusedDeclaration") @@ -33,4 +42,4 @@ class VersionCodeTask extends DefaultTask { def version() { println project.ext.versionCode } -} \ No newline at end of file +} From 0220ed60f12b959038511bbd906507cf6129bf08 Mon Sep 17 00:00:00 2001 From: Hermann Krumrey Date: Tue, 4 Sep 2018 13:51:22 +0200 Subject: [PATCH 2/6] Adjust request code to use API V2 --- .../kotlin/net/namibsun/hktipp/BetActivity.kt | 8 +- .../namibsun/hktipp/LeaderboardActivity.kt | 32 +++++-- .../net/namibsun/hktipp/LoginActivity.kt | 19 ++-- .../namibsun/hktipp/SingleMatchActivity.kt | 2 - .../net/namibsun/hktipp/data/GoalData.kt | 7 +- .../net/namibsun/hktipp/data/MatchData.kt | 10 ++ .../net/namibsun/hktipp/data/TeamData.kt | 4 +- .../kotlin/net/namibsun/hktipp/helper/api.kt | 80 +++++++++------- .../net/namibsun/hktipp/helper/requests.kt | 96 +++++++++++++------ .../net/namibsun/hktipp/singletons/Logos.kt | 2 + 10 files changed, 167 insertions(+), 93 deletions(-) diff --git a/app/src/main/kotlin/net/namibsun/hktipp/BetActivity.kt b/app/src/main/kotlin/net/namibsun/hktipp/BetActivity.kt index c8c47f6..65b8ee0 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/BetActivity.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/BetActivity.kt @@ -131,7 +131,6 @@ class BetActivity : AppCompatActivity() { Log.i("BetActivity", "Updating Data") - val username = this.username!! val apiKey = this.apiKey!! val matchday = this.matchDay @@ -149,8 +148,8 @@ class BetActivity : AppCompatActivity() { try { - val matches = getMatches(username, apiKey, matchday) - val bets = getBets(username, apiKey, matchday) + val matches = getMatches(apiKey, matchday) + val bets = getBets(apiKey, matchday) Log.i("BetActivity", "Data successfully fetched") // Update Matchday (Only has an effect if matchday == -1). Also reset BetViews @@ -166,7 +165,6 @@ class BetActivity : AppCompatActivity() { this@BetActivity.setUiElementEnabledState(true) } } catch (e: IOException) { // If failed to fetch data, log out - Log.e("BetActivity", "Failed to fetch data") this@BetActivity.runOnUiThread { showErrorDialog(this@BetActivity, R.string.bets_fetching_error_title, @@ -256,7 +254,7 @@ class BetActivity : AppCompatActivity() { this.findViewById(R.id.bets_progress).visibility = View.VISIBLE this.doAsync { - val result = placeBets(this@BetActivity.username!!, this@BetActivity.apiKey!!, json) + val result = placeBets(this@BetActivity.apiKey!!, json) this@BetActivity.runOnUiThread { if (!result) { showErrorDialog(this@BetActivity, diff --git a/app/src/main/kotlin/net/namibsun/hktipp/LeaderboardActivity.kt b/app/src/main/kotlin/net/namibsun/hktipp/LeaderboardActivity.kt index d4150dc..91f8d93 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/LeaderboardActivity.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/LeaderboardActivity.kt @@ -25,9 +25,10 @@ import android.view.View import android.widget.LinearLayout import android.widget.ProgressBar import org.jetbrains.anko.doAsync -import net.namibsun.hktipp.helper.post +import net.namibsun.hktipp.helper.request +import net.namibsun.hktipp.helper.HTTPMETHOD import net.namibsun.hktipp.views.LeaderboardEntryView -import org.json.JSONObject +import org.json.JSONArray /** * Activity that displays the current leadeboard of the hk-tippspiel website @@ -39,6 +40,11 @@ class LeaderboardActivity : AppCompatActivity() { */ private var username: String? = null + /** + * The API Key of the logged in user + */ + private var apiKey: String? = null + /** * Initializes the Activity. Populates the leaderboard. * @param savedInstanceState: The Instance Information of the app. @@ -49,10 +55,16 @@ class LeaderboardActivity : AppCompatActivity() { super.onCreate(savedInstanceState) this.username = intent.extras.getString("username") + this.apiKey = intent.extras.getString("api_key") this.findViewById(R.id.leaderboard_progress).visibility = View.VISIBLE this.doAsync { - val rankings = post("get_rankings", "").getJSONObject("data") + val rankings = request( + "leaderboard", + HTTPMETHOD.GET, + mutableMapOf(), + this@LeaderboardActivity.apiKey + ).getJSONObject("data").getJSONArray("leaderboard") this@LeaderboardActivity.runOnUiThread { this@LeaderboardActivity.populateList(rankings) } @@ -63,18 +75,20 @@ class LeaderboardActivity : AppCompatActivity() { * Populates the leaderboard with custom leaderboard entry views * @param rankings: The JSON ranking data */ - private fun populateList(rankings: JSONObject) { + private fun populateList(rankings: JSONArray) { this.findViewById(R.id.leaderboard_progress).visibility = View.INVISIBLE val list = this.findViewById(R.id.leaderboard_list) list.removeAllViews() - for (position in rankings.keys()) { - val userData = rankings.getJSONObject(position) + for (i in 0..(rankings.length() - 1)) { + val rankData = rankings.getJSONArray(i) + val userData = rankData.getJSONObject(0) val name = userData.getString("username") - val points = userData.getInt("points") - val view = LeaderboardEntryView(this, position, name, "$points") + val points = rankData.getInt(1) + val rank = i + 1 + val view = LeaderboardEntryView(this, "$rank", name, "$points") list.addView(view) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/net/namibsun/hktipp/LoginActivity.kt b/app/src/main/kotlin/net/namibsun/hktipp/LoginActivity.kt index 67166c1..c7598ed 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/LoginActivity.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/LoginActivity.kt @@ -32,7 +32,8 @@ import net.namibsun.hktipp.helper.getApiKeyFromSharedPreferences import net.namibsun.hktipp.helper.getUsernameFromPreferences import net.namibsun.hktipp.helper.storeApiKeyInSharedPreferences import net.namibsun.hktipp.helper.storeUsernameInSharedPreferences -import net.namibsun.hktipp.helper.post +import net.namibsun.hktipp.helper.request +import net.namibsun.hktipp.helper.HTTPMETHOD import org.jetbrains.anko.doAsync import org.json.JSONObject @@ -70,7 +71,7 @@ class LoginActivity : AppCompatActivity() { } this.findViewById(R.id.login_screen_register_button).setOnClickListener { - val uri = Uri.parse("https://hk-tippspiel.com/signup.php") + val uri = Uri.parse("https://hk-tippspiel.com/register") val intent = Intent(Intent.ACTION_VIEW, uri) this.startActivity(intent) } @@ -97,12 +98,11 @@ class LoginActivity : AppCompatActivity() { // Log in or authorize the existing API Key val response = if (apiKey != "" && password == "******") { Log.i("LoginActivity", "Authorizing existing API key") - val json = "{\"username\":\"$username\", \"api_key\":\"$apiKey\"}" - post("authorize", json) + request("authorize", HTTPMETHOD.GET, mutableMapOf(), apiKey) } else { Log.i("LoginActivity", "Attempting to log in using password") - val json = "{\"username\":\"$username\", \"password\":\"$password\"}" - post("request_api_key", json) + val json = mutableMapOf("username" to username, "password" to password) + request("api_key", HTTPMETHOD.POST, json) } this@LoginActivity.runOnUiThread { @@ -124,13 +124,14 @@ class LoginActivity : AppCompatActivity() { */ private fun handleLoginResponse(response: JSONObject, username: String, apiKey: String?) { - if (response.getString("status") == "success") { // Login successful + if (response.getString("status") == "ok") { // Login successful Log.i("LoginActivity", "Login Successful") // Check for valid API key - val validApiKey = if (response.has("key")) { - response.getString("key") // Login API Action + val responseData = response.getJSONObject("data") + val validApiKey = if (responseData.has("api_key")) { + responseData.getString("api_key") // Login API Action } else { apiKey!! // Authorize API Action } diff --git a/app/src/main/kotlin/net/namibsun/hktipp/SingleMatchActivity.kt b/app/src/main/kotlin/net/namibsun/hktipp/SingleMatchActivity.kt index 6509c93..4b61d26 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/SingleMatchActivity.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/SingleMatchActivity.kt @@ -138,7 +138,6 @@ class SingleMatchActivity : AppCompatActivity() { this.findViewById(R.id.single_match_goals_progress).visibility = View.VISIBLE this.doAsync { val goals = getGoalsForMatch( - this@SingleMatchActivity.username!!, this@SingleMatchActivity.apiKey!!, this@SingleMatchActivity.matchData!!.id ) @@ -161,7 +160,6 @@ class SingleMatchActivity : AppCompatActivity() { this.findViewById(R.id.single_match_bets_progress).visibility = View.VISIBLE this.doAsync { val bets = getBetsForMatch( - this@SingleMatchActivity.username!!, this@SingleMatchActivity.apiKey!!, this@SingleMatchActivity.matchData!!.id ) diff --git a/app/src/main/kotlin/net/namibsun/hktipp/data/GoalData.kt b/app/src/main/kotlin/net/namibsun/hktipp/data/GoalData.kt index 66c1b25..bb6abbd 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/data/GoalData.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/data/GoalData.kt @@ -48,10 +48,15 @@ class GoalData(data: JSONObject) : Serializable { */ val minute = data.getInt("minute") + /** + * The minute of extra time in which the goal was scored + */ + val minuteEt = data.getInt("minute_et") + /** * Indicates if the goal was an own goal or not */ - val ownGoal = data.getBoolean("owngoal") + val ownGoal = data.getBoolean("own_goal") /** * Indicates if the goal was scored via penalty shot or not diff --git a/app/src/main/kotlin/net/namibsun/hktipp/data/MatchData.kt b/app/src/main/kotlin/net/namibsun/hktipp/data/MatchData.kt index cbc5f6e..c20e4c2 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/data/MatchData.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/data/MatchData.kt @@ -43,6 +43,16 @@ class MatchData(data: JSONObject) : Serializable { */ val awayTeam = TeamData(data.getJSONObject("away_team")!!) + /** + * The current score of the home team + */ + val homeCurrentScore = data.getInt("home_current_score") + + /** + * The current score of the away team + */ + val awayCurrentScore = data.getInt("away_current_score") + /** * The home team's half-time score */ diff --git a/app/src/main/kotlin/net/namibsun/hktipp/data/TeamData.kt b/app/src/main/kotlin/net/namibsun/hktipp/data/TeamData.kt index 04407c1..7edd182 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/data/TeamData.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/data/TeamData.kt @@ -41,7 +41,7 @@ class TeamData(data: JSONObject) : Serializable { /** * The shortform version of the team's name */ - val shortName = data.getString("shortname")!! + val shortName = data.getString("short_name")!! /** * The team's 3-letter abbreviation @@ -51,5 +51,5 @@ class TeamData(data: JSONObject) : Serializable { /** * The path to the team's icon */ - val iconPath = data.getString("icon")!! + val iconPath = data.getString("icon_png")!! } \ No newline at end of file diff --git a/app/src/main/kotlin/net/namibsun/hktipp/helper/api.kt b/app/src/main/kotlin/net/namibsun/hktipp/helper/api.kt index ddf75f9..0aa6537 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/helper/api.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/helper/api.kt @@ -23,7 +23,6 @@ import net.namibsun.hktipp.data.BetData import net.namibsun.hktipp.data.GoalData import net.namibsun.hktipp.data.MatchData import org.json.JSONArray -import org.json.JSONObject /** * Module that contains wrappers around bundesliga-tippspiel APIs @@ -31,16 +30,20 @@ import org.json.JSONObject /** * Fetches all the match data for the specified match day - * @param username: The requesting user's username * @param apiKey: The API key of the user * @param matchDay: The match day for which to fetch the match data. * Defaults to -1, which will fetch the current match day * @return: The matches for the specified/current matchday */ -fun getMatches(username: String, apiKey: String, matchDay: Int = -1): List { - val json = if (matchDay == -1) "{}" else "{\"matchday\":\"$matchDay\"}" - val result = post("get_matches_for_matchday", json, username, apiKey) - val matchData = result.getJSONArray("data") +fun getMatches(apiKey: String, matchDay: Int = -1): List { + val json = mutableMapOf("matchday" to matchDay) + val result = request( + "match", + HTTPMETHOD.GET, + json, + apiKey + ) + val matchData = result.getJSONObject("data").getJSONArray("matches") return (0..(matchData.length() - 1)).map { MatchData(matchData.getJSONObject(it)) @@ -49,15 +52,19 @@ fun getMatches(username: String, apiKey: String, matchDay: Int = -1): List { - val json = if (matchDay == -1) "{}" else "{\"matchday\":\"$matchDay\"}" - val result = post("get_user_bets_for_matchday", json, username, apiKey).getJSONArray("data") +fun getBets(apiKey: String, matchDay: Int = -1): List { + val json = mutableMapOf("matchday" to matchDay) + val result = request( + "bet", + HTTPMETHOD.GET, + json, + apiKey + ).getJSONObject("data").getJSONArray("bets") return (0..(result.length() - 1)).map { BetData(result.getJSONObject(it)) @@ -66,32 +73,36 @@ fun getBets(username: String, apiKey: String, matchDay: Int = -1): List /** * Places bets for a user - * @param username: The user's username * @param apiKey: The user's API key * @param bets: The bets to place. Must be a JsonArray of JsonObjects with the attributes * `home_score`, `away_score` and `match_id` * @return: true if the bets where places successfully, false otherwise */ -fun placeBets(username: String, apiKey: String, bets: JSONArray): Boolean { - val betsJson = JSONObject() - betsJson.put("bets", bets) - val response = post("place_bets", betsJson.toString(), username, apiKey) - val status = response.getString("status") - return status.startsWith("success") +fun placeBets(apiKey: String, bets: JSONArray): Boolean { + val betsJson = mutableMapOf() + for (i in 0..(bets.length() - 1)) { + val bet = bets.getJSONObject(i) + val matchId = bet.getInt("match_id") + val homeScore = bet.getInt("home_score") + val awayScore = bet.getInt("away_score") + betsJson["$matchId-home"] = homeScore + betsJson["$matchId-away"] = awayScore + } + val response = request("bet", HTTPMETHOD.PUT, betsJson, apiKey) + return response.getString("status") == "ok" } /** * Retrieves goal data from the API - * @param username: The username used for authentication * @param apiKey: The API key used for authentication * @param matchId: The ID of the match for which to retrieve the goals * @return A List of GoalData objects for the specified match */ -fun getGoalsForMatch(username: String, apiKey: String, matchId: Int): List { - val postJson = JSONObject() - postJson.put("match_id", matchId) - val response = post("get_goal_data_for_match", postJson.toString(), username, apiKey) - val goals = response.getJSONArray("data") +fun getGoalsForMatch(apiKey: String, matchId: Int): List { + val goalsJson = mutableMapOf() + goalsJson["match_id"] = matchId + val response = request("goal", HTTPMETHOD.GET, goalsJson, apiKey) + val goals = response.getJSONObject("data").getJSONArray("goals") return (0..(goals.length() - 1)).map { GoalData(goals.getJSONObject(it)) } @@ -99,24 +110,21 @@ fun getGoalsForMatch(username: String, apiKey: String, matchId: Int): List { - val postJson = JSONObject() - postJson.put("match_id", matchId) - val response = post("get_bets_for_match", postJson.toString(), username, apiKey) - val bets = response.getJSONObject("data") +fun getBetsForMatch(apiKey: String, matchId: Int): Map { + val betsJson = mutableMapOf() + betsJson["match_id"] = matchId + val response = request("bet", HTTPMETHOD.GET, betsJson, apiKey) + val bets = response.getJSONObject("data").getJSONArray("bets") val betList = mutableMapOf() - for (user in bets.keys()) { - if (!bets.isNull(user)) { - betList[user] = BetData(bets.getJSONObject(user)) - } else { - betList[user] = null - } + for (i in 0..(bets.length() - 1)) { + val bet = bets.getJSONObject(i) + val user = bet.getJSONObject("user").getString("username") + betList[user] = BetData(bet) } return betList -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt index 7d6599e..b226ea1 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt @@ -23,58 +23,96 @@ import okhttp3.MediaType import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody +import okhttp3.Headers import org.json.JSONObject import java.io.IOException import java.net.SocketTimeoutException +/** + * Class that defines different HTTP methods + */ +enum class HTTPMETHOD { + POST, GET, PUT, DELETE +} + /** * Module that contains generic functions for creating requests for the bundesliga-tippspiel API */ /** - * Post a JSON body to an API endpoint of bundesliga-tippspiel and returns the result - * @param endpoint: The endpoint to POST to - * @param data: The JSON Data to POST + * Sends a HTTP request to the hk-tippspiel site + * @param endpoint: The endpoint to send the request to + * @param method: The HTTP method to use + * @param data: The data to send to the API + * @param apiKey: An API key used for authentication * @return: The resulting JSON response */ -fun post(endpoint: String, data: String): JSONObject { +fun request( + endpoint: String, + method: HTTPMETHOD, + data: MutableMap, + apiKey: String? = null +): JSONObject { - val jsonMediaType = MediaType.parse("application/json; charset=utf-8") val client = OkHttpClient() + var builder = Request.Builder() + var body: RequestBody? = null - val body = RequestBody.create(jsonMediaType, data) - val request = Request.Builder() - .url("https://hk-tippspiel.com/api/v1/$endpoint.php") - .post(body) - .build() + var endpointPath = endpoint + if (method == HTTPMETHOD.GET && data.isNotEmpty()) { + endpointPath += "?" + for ((key, value) in data) { + endpointPath += "$key=$value&" + } + endpointPath = endpointPath.substring(0, endpointPath.length - 1) + } else { + val jsonMediaType = MediaType.parse("application/json; charset=utf-8") + val jsonData = JSONObject() + for ((key, value) in data) { + jsonData.put(key, value) + } + body = RequestBody.create(jsonMediaType, jsonData.toString()) + } - val response = client.newCall(request).execute() - val responseBody = response.body()!!.string() - return JSONObject(responseBody) -} + builder = builder.url("http://192.168.178.67:5000/api/v2/$endpointPath") + if (apiKey != null) { + val headers = Headers.of(mutableMapOf("Authorization" to "Basic $apiKey")) + builder = builder.headers(headers) + } -/** - * Extends the [post] method by adding parameters for a username and API key. - * @param endpoint: The endpoint to POST to - * @param data: The JSON Data to POST - * @param username: The user's username - * @param apiKey: The user's API key - * @return: The resulting JSON response - */ -fun post(endpoint: String, data: String, username: String, apiKey: String): JSONObject { + builder = when (method) { + HTTPMETHOD.POST -> builder.post(body!!) + HTTPMETHOD.GET -> builder.get() + HTTPMETHOD.PUT -> builder.put(body!!) + HTTPMETHOD.DELETE -> builder.delete(body!!) + } - val json = JSONObject(data) - json.put("username", username) - json.put("api_key", apiKey) + val request = builder.build() try { - val result = post(endpoint, json.toString()) + val response = client.newCall(request).execute() + val responseBody = response.body()!!.string() + return JSONObject(responseBody) - if (result.get("status") == "success" || result.get("status") == "success_with_errors") { + /* + val result = JSONObject(responseBody) + if (result.get("status") == "ok") { return result } else { - throw IOException("unauthorized") + val unauthorized = mutableListOf( + "User does not exist", + "User is not confirmed", + "Invalid Password" + ) + for (reason in unauthorized) { + if (reason.toLowerCase() == result.getString("reason").toLowerCase()) { + throw IOException("unauthorized") + } + } + return result + //throw IOException(result.get("reason").toString().toLowerCase()) } + */ } catch (e: SocketTimeoutException) { throw IOException("timeout") } diff --git a/app/src/main/kotlin/net/namibsun/hktipp/singletons/Logos.kt b/app/src/main/kotlin/net/namibsun/hktipp/singletons/Logos.kt index c2caa8b..aab40fe 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/singletons/Logos.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/singletons/Logos.kt @@ -21,6 +21,7 @@ package net.namibsun.hktipp.singletons import android.graphics.Bitmap import android.graphics.BitmapFactory +import android.util.Log import net.namibsun.hktipp.data.TeamData import java.net.URL @@ -44,6 +45,7 @@ object Logos { } private fun downloadLogo(team: TeamData) { + Log.e("LOGO", team.iconPath) val url = URL(team.iconPath) val bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream()) this.logos[team.id] = bitmap From e17b9514e2855fa6415d42dcc7f34d750ad927c7 Mon Sep 17 00:00:00 2001 From: Hermann Krumrey Date: Tue, 4 Sep 2018 13:56:15 +0200 Subject: [PATCH 3/6] Fix dummy test --- app/src/test/kotlin/net/namibsun/hktipp/DummyTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/test/kotlin/net/namibsun/hktipp/DummyTest.kt b/app/src/test/kotlin/net/namibsun/hktipp/DummyTest.kt index 6983d2d..f48782d 100644 --- a/app/src/test/kotlin/net/namibsun/hktipp/DummyTest.kt +++ b/app/src/test/kotlin/net/namibsun/hktipp/DummyTest.kt @@ -37,9 +37,9 @@ class DummyTest { val x = JSONObject() x.put("id", 1) x.put("name", "AAA") - x.put("shortname", "AAA") + x.put("short_name", "AAA") x.put("abbreviation", "AAA") - x.put("icon", "AAA") + x.put("icon_png", "AAA") val y = TeamData(x) From c731006f7600a3292a6282e834bb3fbd3e5533fc Mon Sep 17 00:00:00 2001 From: Hermann Krumrey Date: Tue, 4 Sep 2018 14:09:49 +0200 Subject: [PATCH 4/6] Fix API path --- app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt index b226ea1..605234e 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt @@ -74,7 +74,7 @@ fun request( body = RequestBody.create(jsonMediaType, jsonData.toString()) } - builder = builder.url("http://192.168.178.67:5000/api/v2/$endpointPath") + builder = builder.url("https://hk-tippspiel.com/api/v2/$endpointPath") if (apiKey != null) { val headers = Headers.of(mutableMapOf("Authorization" to "Basic $apiKey")) builder = builder.headers(headers) From a1ae862c039bb88b787f6aa5efb5e9cfd534982d Mon Sep 17 00:00:00 2001 From: Hermann Krumrey Date: Tue, 4 Sep 2018 19:30:25 +0200 Subject: [PATCH 5/6] Version bump to 1.1.0 --- CHANGELOG | 2 ++ CHANGELOG-de-DE | 2 ++ .../net/namibsun/hktipp/helper/requests.kt | 28 ++++++------------- version | 2 +- 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 14ded5f..75834c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +V 1.1.0: + - Now uses V2 of the API V 1.0.5: - Small project fixes V 1.0.4: diff --git a/CHANGELOG-de-DE b/CHANGELOG-de-DE index 0afce77..0e1fa8f 100644 --- a/CHANGELOG-de-DE +++ b/CHANGELOG-de-DE @@ -1,3 +1,5 @@ +V 1.1.0: + - Verwendet nun V2 der API V 1.0.5: - Kleine Projekt-Fixes V 1.0.4: diff --git a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt index 605234e..899996c 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt @@ -19,6 +19,8 @@ along with bundesliga-tippspiel-android. If not, see Date: Tue, 4 Sep 2018 19:34:38 +0200 Subject: [PATCH 6/6] Fix lint errors --- app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt index 899996c..8857727 100644 --- a/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt +++ b/app/src/main/kotlin/net/namibsun/hktipp/helper/requests.kt @@ -100,7 +100,6 @@ fun request( Log.e("Error", result.getString("reason")) } return result - } catch (e: SocketTimeoutException) { throw IOException("timeout") }