2016-12-29 06:50:18 +01:00
|
|
|
package org.mariotaku.twidere.extension.model
|
2016-12-03 06:48:40 +01:00
|
|
|
|
|
|
|
import android.content.Context
|
2017-03-08 03:08:56 +01:00
|
|
|
import android.net.Uri
|
2016-12-03 06:48:40 +01:00
|
|
|
import android.text.TextUtils
|
|
|
|
import org.mariotaku.microblog.library.MicroBlog
|
|
|
|
import org.mariotaku.microblog.library.MicroBlogException
|
2017-03-11 14:15:29 +01:00
|
|
|
import org.mariotaku.microblog.library.fanfou.FanfouStream
|
2017-04-18 15:19:07 +02:00
|
|
|
import org.mariotaku.microblog.library.mastodon.Mastodon
|
|
|
|
import org.mariotaku.microblog.library.mastodon.MastodonOAuth2
|
2017-04-29 10:04:43 +02:00
|
|
|
import org.mariotaku.microblog.library.mastodon.MastodonStreaming
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.microblog.library.twitter.*
|
|
|
|
import org.mariotaku.microblog.library.twitter.auth.BasicAuthorization
|
|
|
|
import org.mariotaku.microblog.library.twitter.auth.EmptyAuthorization
|
|
|
|
import org.mariotaku.restfu.RestAPIFactory
|
2017-03-08 03:08:56 +01:00
|
|
|
import org.mariotaku.restfu.RestRequest
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.restfu.http.Authorization
|
|
|
|
import org.mariotaku.restfu.http.Endpoint
|
2017-03-08 03:08:56 +01:00
|
|
|
import org.mariotaku.restfu.http.MultiValueMap
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.restfu.oauth.OAuthAuthorization
|
|
|
|
import org.mariotaku.restfu.oauth.OAuthEndpoint
|
|
|
|
import org.mariotaku.restfu.oauth.OAuthToken
|
2017-04-18 15:19:07 +02:00
|
|
|
import org.mariotaku.restfu.oauth2.OAuth2Authorization
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.twidere.TwidereConstants.DEFAULT_TWITTER_API_URL_FORMAT
|
2017-02-11 10:03:35 +01:00
|
|
|
import org.mariotaku.twidere.annotation.AccountType
|
2017-04-18 15:19:07 +02:00
|
|
|
import org.mariotaku.twidere.model.account.cred.*
|
2017-01-29 13:09:59 +01:00
|
|
|
import org.mariotaku.twidere.util.HttpClientFactory
|
2017-05-25 04:33:19 +02:00
|
|
|
import org.mariotaku.twidere.util.InternalTwitterContentUtils
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.twidere.util.MicroBlogAPIFactory
|
2017-02-11 10:03:35 +01:00
|
|
|
import org.mariotaku.twidere.util.MicroBlogAPIFactory.sFanfouConstantPool
|
2016-12-08 16:45:07 +01:00
|
|
|
import org.mariotaku.twidere.util.MicroBlogAPIFactory.sTwitterConstantPool
|
2017-04-11 03:21:15 +02:00
|
|
|
import org.mariotaku.twidere.util.api.*
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
2017-03-08 03:08:56 +01:00
|
|
|
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
|
2016-12-03 06:48:40 +01:00
|
|
|
|
|
|
|
/**
|
2017-04-11 03:21:15 +02:00
|
|
|
* Creates [MicroBlog] instances
|
|
|
|
*
|
2016-12-03 06:48:40 +01:00
|
|
|
* Created by mariotaku on 2016/12/3.
|
|
|
|
*/
|
2017-04-01 10:04:01 +02:00
|
|
|
fun Credentials.getAuthorization(cls: Class<*>?): Authorization {
|
|
|
|
if (cls != null) {
|
|
|
|
when {
|
|
|
|
TwitterWeb::class.java.isAssignableFrom(cls) -> {
|
|
|
|
return EmptyAuthorization()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-03 06:48:40 +01:00
|
|
|
when (this) {
|
|
|
|
is OAuthCredentials -> {
|
|
|
|
return OAuthAuthorization(consumer_key, consumer_secret, OAuthToken(access_token,
|
|
|
|
access_token_secret))
|
|
|
|
}
|
2017-04-18 15:19:07 +02:00
|
|
|
is OAuth2Credentials -> {
|
|
|
|
return OAuth2Authorization(access_token)
|
|
|
|
}
|
2016-12-03 06:48:40 +01:00
|
|
|
is BasicCredentials -> {
|
|
|
|
return BasicAuthorization(username, password)
|
|
|
|
}
|
|
|
|
is EmptyCredentials -> {
|
|
|
|
return EmptyAuthorization()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw UnsupportedOperationException()
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Credentials.getEndpoint(cls: Class<*>): Endpoint {
|
|
|
|
val apiUrlFormat: String
|
|
|
|
val noVersionSuffix = this.no_version_suffix
|
|
|
|
if (!TextUtils.isEmpty(this.api_url_format)) {
|
|
|
|
apiUrlFormat = this.api_url_format
|
|
|
|
} else {
|
|
|
|
apiUrlFormat = DEFAULT_TWITTER_API_URL_FORMAT
|
|
|
|
}
|
2017-04-01 10:04:01 +02:00
|
|
|
val domain: String?
|
2016-12-03 06:48:40 +01:00
|
|
|
val versionSuffix: String?
|
|
|
|
when {
|
|
|
|
MicroBlog::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "api"
|
|
|
|
versionSuffix = if (noVersionSuffix) null else "/1.1/"
|
|
|
|
}
|
|
|
|
Twitter::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "api"
|
|
|
|
versionSuffix = if (noVersionSuffix) null else "/1.1/"
|
|
|
|
}
|
|
|
|
TwitterUpload::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "upload"
|
|
|
|
versionSuffix = if (noVersionSuffix) null else "/1.1/"
|
|
|
|
}
|
|
|
|
TwitterOAuth::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "api"
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
|
|
|
TwitterOAuth2::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "api"
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
|
|
|
TwitterUserStream::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "userstream"
|
|
|
|
versionSuffix = if (noVersionSuffix) null else "/1.1/"
|
|
|
|
}
|
|
|
|
TwitterCaps::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "caps"
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
2017-03-11 14:15:29 +01:00
|
|
|
FanfouStream::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = "stream"
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
2017-04-01 10:04:01 +02:00
|
|
|
TwitterWeb::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = null
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
2017-04-18 15:19:07 +02:00
|
|
|
Mastodon::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = null
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
|
|
|
MastodonOAuth2::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = null
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
2017-04-29 10:04:43 +02:00
|
|
|
MastodonStreaming::class.java.isAssignableFrom(cls) -> {
|
|
|
|
domain = null
|
|
|
|
versionSuffix = null
|
|
|
|
}
|
2017-03-23 15:22:07 +01:00
|
|
|
else -> throw UnsupportedOperationException("Unsupported class $cls")
|
2016-12-03 06:48:40 +01:00
|
|
|
}
|
|
|
|
val endpointUrl = MicroBlogAPIFactory.getApiUrl(apiUrlFormat, domain, versionSuffix)
|
|
|
|
if (this is OAuthCredentials) {
|
|
|
|
val signEndpointUrl: String
|
|
|
|
if (same_oauth_signing_url) {
|
|
|
|
signEndpointUrl = endpointUrl
|
|
|
|
} else {
|
|
|
|
signEndpointUrl = MicroBlogAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, domain, versionSuffix)
|
|
|
|
}
|
|
|
|
return OAuthEndpoint(endpointUrl, signEndpointUrl)
|
|
|
|
}
|
|
|
|
return Endpoint(endpointUrl)
|
|
|
|
}
|
|
|
|
|
2017-02-11 10:03:35 +01:00
|
|
|
fun <T> Credentials.newMicroBlogInstance(context: Context, @AccountType accountType: String? = null,
|
2017-03-11 14:15:29 +01:00
|
|
|
cls: Class<T>): T {
|
2017-04-18 15:19:07 +02:00
|
|
|
return newMicroBlogInstance(context, getEndpoint(cls), getAuthorization(cls), accountType, cls)
|
2016-12-03 06:48:40 +01:00
|
|
|
}
|
|
|
|
|
2017-02-11 10:03:35 +01:00
|
|
|
fun <T> newMicroBlogInstance(context: Context, endpoint: Endpoint, auth: Authorization,
|
2017-03-11 14:15:29 +01:00
|
|
|
@AccountType accountType: String? = null, cls: Class<T>): T {
|
2016-12-03 06:48:40 +01:00
|
|
|
val factory = RestAPIFactory<MicroBlogException>()
|
2017-04-11 05:31:38 +02:00
|
|
|
val extraHeaders = run {
|
|
|
|
if (auth !is OAuthAuthorization) return@run null
|
2020-04-03 11:14:42 +02:00
|
|
|
val officialKeyType = InternalTwitterContentUtils.getOfficialKeyType(context,
|
|
|
|
auth.consumerKey, auth.consumerSecret)
|
|
|
|
return@run MicroBlogAPIFactory.getExtraHeaders(context, officialKeyType)
|
2017-04-11 05:31:38 +02:00
|
|
|
} ?: UserAgentExtraHeaders(MicroBlogAPIFactory.getTwidereUserAgent(context))
|
2016-12-03 06:48:40 +01:00
|
|
|
val holder = DependencyHolder.get(context)
|
2017-03-21 03:33:27 +01:00
|
|
|
var extraRequestParams: Map<String, String>? = null
|
2017-01-29 13:09:59 +01:00
|
|
|
when (cls) {
|
2017-03-09 13:20:28 +01:00
|
|
|
TwitterUpload::class.java -> {
|
2017-01-29 13:09:59 +01:00
|
|
|
val conf = HttpClientFactory.HttpClientConfiguration(holder.preferences)
|
|
|
|
// Use longer timeout for uploading
|
|
|
|
conf.readTimeoutSecs = 30
|
|
|
|
conf.writeTimeoutSecs = 30
|
|
|
|
conf.connectionTimeoutSecs = 60
|
|
|
|
val uploadHttpClient = HttpClientFactory.createRestHttpClient(conf, holder.dns,
|
2017-03-01 09:27:45 +01:00
|
|
|
holder.connectionPool, holder.cache)
|
2017-01-29 13:09:59 +01:00
|
|
|
factory.setHttpClient(uploadHttpClient)
|
|
|
|
}
|
2017-04-29 10:04:43 +02:00
|
|
|
TwitterUserStream::class.java, FanfouStream::class.java, MastodonStreaming::class.java -> {
|
2017-03-09 11:59:30 +01:00
|
|
|
val conf = HttpClientFactory.HttpClientConfiguration(holder.preferences)
|
|
|
|
// Use longer read timeout for streaming
|
|
|
|
conf.readTimeoutSecs = 300
|
2017-03-09 13:20:28 +01:00
|
|
|
val streamHttpClient = HttpClientFactory.createRestHttpClient(conf, holder.dns,
|
2017-03-09 11:59:30 +01:00
|
|
|
holder.connectionPool, holder.cache)
|
2017-03-09 13:20:28 +01:00
|
|
|
factory.setHttpClient(streamHttpClient)
|
2017-03-09 11:59:30 +01:00
|
|
|
}
|
2017-01-29 13:09:59 +01:00
|
|
|
else -> {
|
|
|
|
factory.setHttpClient(holder.restHttpClient)
|
|
|
|
}
|
|
|
|
}
|
2016-12-03 06:48:40 +01:00
|
|
|
factory.setAuthorization(auth)
|
|
|
|
factory.setEndpoint(endpoint)
|
2017-02-11 10:03:35 +01:00
|
|
|
when (accountType) {
|
|
|
|
AccountType.TWITTER -> {
|
|
|
|
factory.setConstantPool(sTwitterConstantPool)
|
|
|
|
}
|
|
|
|
AccountType.FANFOU -> {
|
|
|
|
factory.setConstantPool(sFanfouConstantPool)
|
2017-03-21 03:33:27 +01:00
|
|
|
if (cls != FanfouStream::class.java) {
|
|
|
|
extraRequestParams = mapOf("format" to "html")
|
|
|
|
}
|
2017-02-11 10:03:35 +01:00
|
|
|
}
|
2016-12-03 06:48:40 +01:00
|
|
|
}
|
2017-04-11 03:21:15 +02:00
|
|
|
factory.setRestConverterFactory(TwitterConverterFactory)
|
|
|
|
factory.setExceptionFactory(TwidereExceptionFactory)
|
|
|
|
factory.setRestRequestFactory(TwidereRestRequestFactory(extraRequestParams))
|
|
|
|
factory.setHttpRequestFactory(TwidereHttpRequestFactory(extraHeaders))
|
2016-12-03 06:48:40 +01:00
|
|
|
return factory.build<T>(cls)
|
2017-03-08 03:08:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
internal fun Credentials.authorizationHeader(
|
|
|
|
uri: Uri,
|
2017-04-01 10:04:01 +02:00
|
|
|
modifiedUri: Uri = TwidereMediaDownloader.getReplacedUri(uri, api_url_format) ?: uri,
|
|
|
|
cls: Class<*>? = null
|
2017-03-08 03:08:56 +01:00
|
|
|
): String {
|
2017-04-01 10:04:01 +02:00
|
|
|
val auth = getAuthorization(cls)
|
2017-03-08 03:08:56 +01:00
|
|
|
val endpoint: Endpoint
|
|
|
|
if (auth is OAuthAuthorization) {
|
|
|
|
endpoint = OAuthEndpoint(TwidereMediaDownloader.getEndpoint(modifiedUri),
|
|
|
|
TwidereMediaDownloader.getEndpoint(uri))
|
|
|
|
} else {
|
|
|
|
endpoint = Endpoint(TwidereMediaDownloader.getEndpoint(modifiedUri))
|
|
|
|
}
|
|
|
|
val queries = MultiValueMap<String>()
|
|
|
|
for (name in uri.queryParameterNames) {
|
|
|
|
for (value in uri.getQueryParameters(name)) {
|
|
|
|
queries.add(name, value)
|
|
|
|
}
|
|
|
|
}
|
2019-10-25 10:50:10 +02:00
|
|
|
val info = RestRequest("GET", false, uri.path!!, null, queries, null, null, null, null)
|
2017-03-08 03:08:56 +01:00
|
|
|
return auth.getHeader(endpoint, info)
|
2016-12-03 06:48:40 +01:00
|
|
|
}
|