Use nodeinfo endpoint to get info about the capabilities of the instance
This commit is contained in:
parent
bd39bc681d
commit
7bca413d60
|
@ -22,11 +22,11 @@ test:
|
|||
- adb shell settings put global transition_animation_scale 0.0
|
||||
- adb shell settings put global animator_duration_scale 0.0
|
||||
|
||||
- ./gradlew build connectedCheck jacocoTestReport
|
||||
- ./gradlew build connectedCheck connectedDebugAndroidTest jacocoTestReport
|
||||
|
||||
- cat app/build/reports/jacoco/jacocoTestReport/html/index.html | grep -o 'Total[^%]*%'
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- ./app/build/reports/jacoco/jacocoTestReport/
|
||||
expire_in: 1 week
|
||||
expire_in: 1 week
|
||||
|
|
|
@ -55,7 +55,7 @@ android {
|
|||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.1'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
|
@ -68,7 +68,7 @@ dependencies {
|
|||
implementation 'io.reactivex.rxjava2:rxjava:2.2.17'
|
||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||
implementation "androidx.browser:browser:1.2.0"
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.2.0'
|
||||
implementation 'com.github.connyduck:sparkbutton:4.0.0'
|
||||
|
||||
def room_version = "2.2.5"
|
||||
|
@ -140,14 +140,14 @@ dependencies {
|
|||
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
|
||||
|
||||
// Use the most recent version of CameraX
|
||||
def camerax_version = '1.0.0-beta07'
|
||||
def camerax_version = '1.0.0-beta08'
|
||||
implementation "androidx.camera:camera-core:${camerax_version}"
|
||||
implementation "androidx.camera:camera-camera2:${camerax_version}"
|
||||
// CameraX Lifecycle library
|
||||
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
||||
|
||||
// CameraX View class
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha14'
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha15'
|
||||
|
||||
implementation 'com.karumi:dexter:6.2.1'
|
||||
|
||||
|
@ -162,7 +162,7 @@ tasks.withType(Test) {
|
|||
}
|
||||
|
||||
|
||||
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
|
||||
task jacocoTestReport(type: JacocoReport, dependsOn: ['connectedDebugAndroidTest', 'testDebugUnitTest', 'createDebugCoverageReport']) {
|
||||
|
||||
reports {
|
||||
xml.enabled = true
|
||||
|
@ -181,4 +181,4 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'crea
|
|||
'jacoco/testDebugUnitTest.exec'
|
||||
|
||||
]))
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.h.pixeldroid
|
|||
|
||||
|
||||
import android.content.Context
|
||||
import android.service.autofill.Validators.and
|
||||
import android.widget.TextView
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
|
@ -17,6 +18,7 @@ import com.h.pixeldroid.db.AppDatabase
|
|||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.atPosition
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.clickChildViewWithId
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.first
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.getText
|
||||
|
@ -26,6 +28,8 @@ import com.h.pixeldroid.testUtility.CustomMatchers.Companion.typeTextInViewWithI
|
|||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
@ -217,7 +221,8 @@ class HomeFeedTest {
|
|||
(1, clickChildViewWithId(R.id.sensitiveWarning)))
|
||||
Thread.sleep(1000)
|
||||
|
||||
onView(second(withId(R.id.sensitiveWarning))).check(matches(withEffectiveVisibility(Visibility.GONE)))
|
||||
onView(withId(R.id.list))
|
||||
.check(matches(atPosition(1, not(withId(R.id.sensitiveWarning)))))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -3,14 +3,18 @@ package com.h.pixeldroid.testUtility
|
|||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.action.*
|
||||
import androidx.test.espresso.matcher.BoundedMatcher
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import org.hamcrest.BaseMatcher
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
|
||||
|
||||
abstract class CustomMatchers {
|
||||
companion object {
|
||||
fun <T> first(matcher: Matcher<T>): Matcher<T>? {
|
||||
|
@ -50,6 +54,24 @@ abstract class CustomMatchers {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fun atPosition(position: Int, itemMatcher: Matcher<View?>): Matcher<View?>? {
|
||||
return object : BoundedMatcher<View?, RecyclerView>(RecyclerView::class.java) {
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("has item at position $position: ")
|
||||
itemMatcher.describeTo(description)
|
||||
}
|
||||
|
||||
override fun matchesSafely(view: RecyclerView): Boolean {
|
||||
val viewHolder = view.findViewHolderForAdapterPosition(position)
|
||||
?: // has no item on such position
|
||||
return false
|
||||
return itemMatcher.matches(viewHolder.itemView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param percent can be 1 or 0
|
||||
* 1: swipes all the way up
|
||||
|
@ -60,8 +82,9 @@ abstract class CustomMatchers {
|
|||
GeneralSwipeAction(
|
||||
Swipe.SLOW,
|
||||
GeneralLocation.BOTTOM_CENTER,
|
||||
if(percent) GeneralLocation.TOP_CENTER else GeneralLocation.CENTER,
|
||||
Press.FINGER)
|
||||
if (percent) GeneralLocation.TOP_CENTER else GeneralLocation.CENTER,
|
||||
Press.FINGER
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -75,8 +98,9 @@ abstract class CustomMatchers {
|
|||
GeneralSwipeAction(
|
||||
Swipe.SLOW,
|
||||
GeneralLocation.CENTER_RIGHT,
|
||||
if(percent) GeneralLocation.CENTER_LEFT else GeneralLocation.CENTER,
|
||||
Press.FINGER)
|
||||
if (percent) GeneralLocation.CENTER_LEFT else GeneralLocation.CENTER,
|
||||
Press.FINGER
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package com.h.pixeldroid
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
@ -13,21 +15,38 @@ import androidx.browser.customtabs.CustomTabsIntent
|
|||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Application
|
||||
import com.h.pixeldroid.objects.Instance
|
||||
import com.h.pixeldroid.objects.Token
|
||||
import com.h.pixeldroid.objects.*
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import com.h.pixeldroid.utils.DBUtils.Companion.storeInstance
|
||||
import com.h.pixeldroid.utils.Utils
|
||||
import com.h.pixeldroid.utils.Utils.Companion.normalizeDomain
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.functions.BiFunction
|
||||
import io.reactivex.functions.Function3
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.activity_login.*
|
||||
import okhttp3.HttpUrl
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
/**
|
||||
Overview of the flow of the login process: (boxes are requests done in parallel,
|
||||
since they do not depend on each other)
|
||||
|
||||
_________________________________
|
||||
|[PixelfedAPI.registerApplication]|
|
||||
|[PixelfedAPI.wellKnownNodeInfo] |
|
||||
̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅ +----> [PixelfedAPI.nodeInfoSchema]
|
||||
+----> [promptOAuth]
|
||||
+---->____________________________
|
||||
|[PixelfedAPI.instance] |
|
||||
|[PixelfedAPI.obtainToken] |
|
||||
̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅̅ +----> [PixelfedAPI.verifyCredentials]
|
||||
|
||||
*/
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
|
@ -119,31 +138,85 @@ class LoginActivity : AppCompatActivity() {
|
|||
hideKeyboard()
|
||||
loadingAnimation(true)
|
||||
|
||||
apiHolder.setDomain(normalizedDomain).registerApplication(
|
||||
appName,"$oauthScheme://$PACKAGE_ID", SCOPE
|
||||
).enqueue(object : Callback<Application> {
|
||||
override fun onResponse(call: Call<Application>, response: Response<Application>) {
|
||||
if (!response.isSuccessful) {
|
||||
return failedRegistration()
|
||||
}
|
||||
preferences.edit()
|
||||
.putString("domain", normalizedDomain)
|
||||
.apply()
|
||||
val credentials = response.body() as Application
|
||||
val clientId = credentials.client_id ?: return failedRegistration()
|
||||
preferences.edit()
|
||||
.putString("clientID", clientId)
|
||||
.putString("clientSecret", credentials.client_secret)
|
||||
.apply()
|
||||
promptOAuth(normalizedDomain, clientId)
|
||||
}
|
||||
pixelfedAPI = apiHolder.setDomain(normalizedDomain)
|
||||
|
||||
Single.zip(
|
||||
pixelfedAPI.registerApplication(
|
||||
appName,"$oauthScheme://$PACKAGE_ID", SCOPE
|
||||
),
|
||||
pixelfedAPI.wellKnownNodeInfo(),
|
||||
BiFunction<Application, NodeInfoJRD, Pair<Application, NodeInfoJRD>> { application, nodeInfoJRD ->
|
||||
// we get here when both results have come in:
|
||||
Pair(application, nodeInfoJRD)
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Pair<Application, NodeInfoJRD>> {
|
||||
override fun onSuccess(pair: Pair<Application, NodeInfoJRD>) {
|
||||
val (credentials, nodeInfoJRD) = pair
|
||||
val clientId = credentials.client_id ?: return failedRegistration()
|
||||
preferences.edit()
|
||||
.putString("domain", normalizedDomain)
|
||||
.putString("clientID", clientId)
|
||||
.putString("clientSecret", credentials.client_secret)
|
||||
.apply()
|
||||
|
||||
override fun onFailure(call: Call<Application>, t: Throwable) {
|
||||
return failedRegistration()
|
||||
//c.f. https://nodeinfo.diaspora.software/protocol.html for more info
|
||||
val nodeInfoSchemaUrl = nodeInfoJRD.links.firstOrNull {
|
||||
it.rel == "http://nodeinfo.diaspora.software/ns/schema/2.0"
|
||||
}?.href ?: return failedRegistration(getString(R.string.instance_error))
|
||||
|
||||
nodeInfoSchema(normalizedDomain, clientId, nodeInfoSchemaUrl)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
//Error in any of the two requests will get to this
|
||||
Log.e("registerAppToServer", e.message.toString())
|
||||
failedRegistration()
|
||||
}
|
||||
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
})
|
||||
}
|
||||
|
||||
private fun nodeInfoSchema(
|
||||
normalizedDomain: String,
|
||||
clientId: String,
|
||||
nodeInfoSchemaUrl: String
|
||||
) {
|
||||
pixelfedAPI.nodeInfoSchema(nodeInfoSchemaUrl).enqueue(object : Callback<NodeInfo> {
|
||||
override fun onResponse(call: Call<NodeInfo>, response: Response<NodeInfo>) {
|
||||
if (response.body() == null || !response.isSuccessful) {
|
||||
return failedRegistration(getString(R.string.instance_error))
|
||||
}
|
||||
val nodeInfo = response.body() as NodeInfo
|
||||
|
||||
if (!nodeInfo.software?.name.orEmpty().contains("pixelfed")) {
|
||||
val builder = AlertDialog.Builder(this@LoginActivity)
|
||||
builder.apply {
|
||||
setMessage(R.string.instance_not_pixelfed_warning)
|
||||
setPositiveButton(R.string.instance_not_pixelfed_continue) { _, _ ->
|
||||
promptOAuth(normalizedDomain, clientId)
|
||||
}
|
||||
setNegativeButton(R.string.instance_not_pixelfed_cancel) { _, _ ->
|
||||
loadingAnimation(false)
|
||||
wipeSharedSettings()
|
||||
}
|
||||
}
|
||||
// Create the AlertDialog
|
||||
builder.show()
|
||||
return
|
||||
} else {
|
||||
promptOAuth(normalizedDomain, clientId)
|
||||
}
|
||||
}
|
||||
override fun onFailure(call: Call<NodeInfo>, t: Throwable) {
|
||||
failedRegistration(getString(R.string.instance_error))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private fun promptOAuth(normalizedDomain: String, client_id: String) {
|
||||
|
||||
val url = "$normalizedDomain/oauth/authorize?" +
|
||||
|
@ -178,29 +251,45 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
//Successful authorization
|
||||
val callback = object : Callback<Token> {
|
||||
override fun onResponse(call: Call<Token>, response: Response<Token>) {
|
||||
if (!response.isSuccessful || response.body() == null) {
|
||||
return failedRegistration(getString(R.string.token_error))
|
||||
}
|
||||
authenticationSuccessful(response.body()!!.access_token)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Token>, t: Throwable) {
|
||||
return failedRegistration(getString(R.string.token_error))
|
||||
}
|
||||
}
|
||||
|
||||
pixelfedAPI = apiHolder.setDomain(domain)
|
||||
pixelfedAPI.obtainToken(
|
||||
clientId, clientSecret, "$oauthScheme://$PACKAGE_ID", SCOPE, code,
|
||||
"authorization_code"
|
||||
).enqueue(callback)
|
||||
}
|
||||
|
||||
private fun authenticationSuccessful(accessToken: String) {
|
||||
saveUserAndInstance(accessToken)
|
||||
wipeSharedSettings()
|
||||
//TODO check why we can't do onErrorReturn { null } which would make more sense ¯\_(ツ)_/¯
|
||||
//Also, maybe find a nicer way to do this, this feels hacky (although it can work fine)
|
||||
val nullInstance = Instance(null, null, null, null, null, null, null, null)
|
||||
val nullToken = Token(null, null, null, null)
|
||||
|
||||
Single.zip(
|
||||
pixelfedAPI.instance().onErrorReturn { nullInstance },
|
||||
pixelfedAPI.obtainToken(
|
||||
clientId, clientSecret, "$oauthScheme://$PACKAGE_ID", SCOPE, code,
|
||||
"authorization_code"
|
||||
).onErrorReturn { nullToken },
|
||||
BiFunction<Instance, Token, Pair<Instance, Token>> { instance, token ->
|
||||
// we get here when all results have come in:
|
||||
Pair(instance, token)
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Pair<Instance, Token>> {
|
||||
override fun onSuccess(triple: Pair<Instance, Token>) {
|
||||
val (instance, token) = triple
|
||||
if(token == nullToken || token.access_token == null){
|
||||
return failedRegistration(getString(R.string.token_error))
|
||||
} else if(instance == nullInstance || instance.uri == null){
|
||||
return failedRegistration(getString(R.string.instance_error))
|
||||
}
|
||||
|
||||
DBUtils.storeInstance(db, instance)
|
||||
storeUser(token.access_token, instance.uri)
|
||||
wipeSharedSettings()
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e("saveUserAndInstance", e.message.toString())
|
||||
failedRegistration(getString(R.string.token_error))
|
||||
}
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
})
|
||||
}
|
||||
|
||||
private fun failedRegistration(message: String = getString(R.string.registration_failed)) {
|
||||
|
@ -225,24 +314,6 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun saveUserAndInstance(accessToken: String) {
|
||||
pixelfedAPI.instance().enqueue(object : Callback<Instance> {
|
||||
override fun onFailure(call: Call<Instance>, t: Throwable) {
|
||||
return failedRegistration(getString(R.string.instance_error))
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call<Instance>, response: Response<Instance>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val instance = response.body() as Instance
|
||||
storeInstance(db, instance)
|
||||
storeUser(accessToken, instance.uri)
|
||||
} else {
|
||||
return failedRegistration(getString(R.string.instance_error))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun storeUser(accessToken: String, instance: String) {
|
||||
pixelfedAPI.verifyCredentials("Bearer $accessToken")
|
||||
.enqueue(object : Callback<Account> {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.h.pixeldroid.api
|
||||
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.objects.*
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import okhttp3.MultipartBody
|
||||
import retrofit2.Call
|
||||
import retrofit2.Retrofit
|
||||
|
@ -10,9 +10,6 @@ import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
|||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.*
|
||||
import retrofit2.http.Field
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
|
||||
/*
|
||||
Implements the Pixelfed API
|
||||
|
@ -23,7 +20,12 @@ import javax.inject.Provider
|
|||
|
||||
interface PixelfedAPI {
|
||||
|
||||
|
||||
companion object {
|
||||
@Deprecated(
|
||||
"Use the DI-d PixelfedAPIHolder instead",
|
||||
ReplaceWith("apiHolder.api")
|
||||
)
|
||||
fun create(baseUrl: String): PixelfedAPI {
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
|
@ -41,7 +43,8 @@ interface PixelfedAPI {
|
|||
@Field("redirect_uris") redirect_uris: String,
|
||||
@Field("scopes") scopes: String? = null,
|
||||
@Field("website") website: String? = null
|
||||
): Call<Application>
|
||||
): Single<Application>
|
||||
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/oauth/token")
|
||||
|
@ -52,7 +55,25 @@ interface PixelfedAPI {
|
|||
@Field("scope") scope: String? = "read",
|
||||
@Field("code") code: String? = null,
|
||||
@Field("grant_type") grant_type: String? = null
|
||||
): Call<Token>
|
||||
): Single<Token>
|
||||
|
||||
// get instance configuration
|
||||
@GET("/api/v1/instance")
|
||||
fun instance() : Single<Instance>
|
||||
|
||||
/**
|
||||
* Instance info from the Nodeinfo .well_known (https://nodeinfo.diaspora.software/protocol.html) endpoint
|
||||
*/
|
||||
@GET("/.well-known/nodeinfo")
|
||||
fun wellKnownNodeInfo() : Single<NodeInfoJRD>
|
||||
|
||||
/**
|
||||
* Instance info from [NodeInfo] (https://nodeinfo.diaspora.software/schema.html) endpoint
|
||||
*/
|
||||
@GET
|
||||
fun nodeInfoSchema(
|
||||
@Url nodeInfo_schema_url: String
|
||||
) : Call<NodeInfo>
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/accounts/{id}/follow")
|
||||
|
@ -240,10 +261,6 @@ interface PixelfedAPI {
|
|||
@Part file: MultipartBody.Part
|
||||
): Observable<Attachment>
|
||||
|
||||
// get instance configuration
|
||||
@GET("/api/v1/instance")
|
||||
fun instance() : Call<Instance>
|
||||
|
||||
// get discover
|
||||
@GET("/api/v2/discover/posts")
|
||||
fun discover(
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package com.h.pixeldroid.objects
|
||||
|
||||
data class Instance (
|
||||
val description: String,
|
||||
val email: String,
|
||||
val max_toot_chars: String = DEFAULT_MAX_TOOT_CHARS.toString(),
|
||||
val registrations: Boolean,
|
||||
val thumbnail: String,
|
||||
val title: String,
|
||||
val uri: String,
|
||||
val version: String
|
||||
val description: String?,
|
||||
val email: String?,
|
||||
val max_toot_chars: String? = DEFAULT_MAX_TOOT_CHARS.toString(),
|
||||
val registrations: Boolean?,
|
||||
val thumbnail: String?,
|
||||
val title: String?,
|
||||
val uri: String?,
|
||||
val version: String?
|
||||
) {
|
||||
companion object {
|
||||
const val DEFAULT_MAX_TOOT_CHARS = 500
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.h.pixeldroid.objects
|
||||
|
||||
/*
|
||||
See https://nodeinfo.diaspora.software/schema.html and https://pixelfed.social/api/nodeinfo/2.0.json
|
||||
A lot of attributes we don't need are omitted, if in the future they are needed we
|
||||
can make new data classes for them.
|
||||
*/
|
||||
|
||||
data class NodeInfo (
|
||||
val version: String?,
|
||||
val software: Software?,
|
||||
val protocols: List<String>?,
|
||||
val openRegistrations: Boolean?,
|
||||
val metadata: PixelfedMetadata?
|
||||
){
|
||||
data class Software(
|
||||
val name: String?,
|
||||
val version: String?
|
||||
)
|
||||
data class PixelfedMetadata(
|
||||
val nodeName: String?,
|
||||
val software: Software?,
|
||||
val config: PixelfedConfig
|
||||
){
|
||||
data class Software(
|
||||
val homepage: String?,
|
||||
val repo: String?
|
||||
)
|
||||
}
|
||||
data class PixelfedConfig(
|
||||
val open_registration: Boolean?,
|
||||
val uploader: Uploader?,
|
||||
val activitypub: ActivityPub?,
|
||||
val features: Features?
|
||||
){
|
||||
data class Uploader(
|
||||
val max_photo_size: String?,
|
||||
val max_caption_length: String?,
|
||||
val album_limit: String?,
|
||||
val image_quality: String?,
|
||||
val optimize_image: Boolean?,
|
||||
val optimize_video: Boolean?,
|
||||
val media_types: String?,
|
||||
val enforce_account_limit: Boolean?
|
||||
)
|
||||
|
||||
data class ActivityPub(
|
||||
val enabled: Boolean?,
|
||||
val remote_follow: Boolean?
|
||||
)
|
||||
|
||||
data class Features(
|
||||
val mobile_apis: Boolean?,
|
||||
val circles: Boolean?,
|
||||
val stories: Boolean?,
|
||||
val video: Boolean?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class NodeInfoJRD(
|
||||
val links: List<Link>
|
||||
){
|
||||
data class Link(
|
||||
val rel: String?,
|
||||
val href: String?
|
||||
)
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package com.h.pixeldroid.objects
|
||||
|
||||
data class Token(
|
||||
val access_token: String,
|
||||
val token_type: String,
|
||||
val scope: String,
|
||||
val created_at: Int
|
||||
val access_token: String?,
|
||||
val token_type: String?,
|
||||
val scope: String?,
|
||||
val created_at: Int?
|
||||
)
|
|
@ -37,13 +37,13 @@ class DBUtils {
|
|||
}
|
||||
|
||||
fun storeInstance(db: AppDatabase, instance: Instance) {
|
||||
val maxTootChars = instance.max_toot_chars.toInt()
|
||||
val maxTootChars = instance.max_toot_chars?.toInt() ?: Instance.DEFAULT_MAX_TOOT_CHARS
|
||||
val dbInstance = InstanceDatabaseEntity(
|
||||
//make sure not to normalize to https when localhost, to allow testing
|
||||
uri = normalizeOrNot(instance.uri),
|
||||
title = instance.title,
|
||||
uri = normalizeOrNot(instance.uri.orEmpty()),
|
||||
title = instance.title.orEmpty(),
|
||||
max_toot_chars = maxTootChars,
|
||||
thumbnail = instance.thumbnail
|
||||
thumbnail = instance.thumbnail.orEmpty()
|
||||
)
|
||||
db.instanceDao().insertInstance(dbInstance)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
<string name="auth_failed">"Could not authenticate"</string>
|
||||
<string name="token_error">"Error getting token"</string>
|
||||
<string name="instance_error">"Could not get instance information"</string>
|
||||
<string name="instance_not_pixelfed_warning">"This doesn't seem to be a Pixelfed instance, so the app could break in unexpected ways."</string>
|
||||
<string name="instance_not_pixelfed_continue">"OK, continue anyway"</string>
|
||||
<string name="instance_not_pixelfed_cancel">"Cancel logging in"</string>
|
||||
<string name="title_activity_settings2">Settings</string>
|
||||
<!-- Theme Preferences -->
|
||||
<string name="theme_title">Application Theme</string>
|
||||
|
|
|
@ -4,6 +4,8 @@ import com.github.tomakehurst.wiremock.client.WireMock.*
|
|||
import com.github.tomakehurst.wiremock.junit.WireMockRule
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.objects.*
|
||||
import io.reactivex.Single
|
||||
import okhttp3.internal.wait
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
@ -106,9 +108,10 @@ class APIUnitTest {
|
|||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(""" {"id":3197,"name":"Pixeldroid","website":null,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":3197,"client_secret":"hhRwLupqUJPghKsZzpZtxNV67g5DBdPYCqW6XE3m","vapid_key":null}"""
|
||||
)))
|
||||
val call: Call<Application> = PixelfedAPI.create("http://localhost:8089")
|
||||
val call: Single<Application> = PixelfedAPI.create("http://localhost:8089")
|
||||
.registerApplication("Pixeldroid", "urn:ietf:wg:oauth:2.0:oob", "read write follow")
|
||||
val application: Application = call.execute().body()!!
|
||||
|
||||
val application: Application = call.toFuture().get()
|
||||
assertEquals("3197", application.client_id)
|
||||
assertEquals("hhRwLupqUJPghKsZzpZtxNV67g5DBdPYCqW6XE3m", application.client_secret)
|
||||
assertEquals("Pixeldroid", application.name)
|
||||
|
@ -133,10 +136,10 @@ class APIUnitTest {
|
|||
val OAUTH_SCHEME = "oauth2redirect"
|
||||
val SCOPE = "read write follow"
|
||||
val PACKAGE_ID = "com.h.pixeldroid"
|
||||
val call: Call<Token> = PixelfedAPI.create("http://localhost:8089")
|
||||
val call: Single<Token> = PixelfedAPI.create("http://localhost:8089")
|
||||
.obtainToken("123", "ssqdfqsdfqds", "$OAUTH_SCHEME://$PACKAGE_ID", SCOPE, "abc",
|
||||
"authorization_code")
|
||||
val token: Token = call.execute().body()!!
|
||||
val token: Token = call.toFuture().get()
|
||||
assertEquals("ZA-Yj3aBD8U8Cm7lKUp-lm9O9BmDgdhHzDeqsY8tlL0", token.access_token)
|
||||
assertEquals("Bearer", token.token_type)
|
||||
assertEquals("read write follow push", token.scope)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.72'
|
||||
ext.kotlin_version = '1.4.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
|
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
#Sun Jul 26 16:18:03 CEST 2020
|
||||
#Fri Aug 21 12:53:39 CEST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
|
@ -10,38 +26,38 @@
|
|||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ]; do
|
||||
ls=$(ls -ld "$PRG")
|
||||
link=$(expr "$ls" : '.*-> \(.*\)$')
|
||||
if expr "$link" : '/.*' >/dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=$(dirname "$PRG")"/$link"
|
||||
fi
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="$(pwd)"
|
||||
cd "$(dirname \"$PRG\")/" >/dev/null
|
||||
APP_HOME="$(pwd -P)"
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=$(basename "$0")
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn() {
|
||||
echo "$*"
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die() {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
|
@ -49,124 +65,121 @@ cygwin=false
|
|||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*)
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin*)
|
||||
darwin=true
|
||||
;;
|
||||
MINGW*)
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP*)
|
||||
nonstop=true
|
||||
;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ]; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
|
||||
MAX_FD_LIMIT=$(ulimit -H -n)
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ]; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
APP_HOME=$(cygpath --path --mixed "$APP_HOME")
|
||||
CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
|
||||
JAVACMD=$(cygpath --unix "$JAVACMD")
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ]; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@"; do
|
||||
CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
|
||||
CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
|
||||
eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
|
||||
else
|
||||
eval $(echo args$i)="\"$arg\""
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save() {
|
||||
for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
|
||||
echo " "
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
|
@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
|||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -35,7 +54,7 @@ goto fail
|
|||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
|
@ -45,28 +64,14 @@ echo location of your Java installation.
|
|||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
|
Loading…
Reference in New Issue