change Morny use sttp as http client

This commit is contained in:
A.C.Sukazyo Eyre 2023-10-19 21:43:29 +08:00
parent a32018d600
commit c19134811d
Signed by: Eyre_S
GPG Key ID: C17CE40291207874
9 changed files with 123 additions and 103 deletions

View File

@ -77,22 +77,26 @@ repositories {
dependencies {
api "org.scala-lang:scala3-library_3:${proj_scala_lib}"
compileOnlyApi "com.github.spotbugs:spotbugs-annotations:${lib_spotbugs_v}"
api group: 'org.scala-lang', name: 'scala3-library_3', version: proj_scala_lib
final scala = (String name) -> "${name}_$proj_scala_api"
compileOnlyApi group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: lib_spotbugs_v
implementation "cc.sukazyo:messiva:${lib_messiva_v}"
implementation "cc.sukazyo:resource-tools:${lib_resourcetools_v}"
testImplementation "cc.sukazyo:resource-tools:${lib_resourcetools_v}"
implementation group: 'cc.sukazyo', name: 'messiva', version: lib_messiva_v
implementation group: 'cc.sukazyo', name: 'resource-tools', version: lib_resourcetools_v
testImplementation group: 'cc.sukazyo', name: 'resource-tools', version: lib_resourcetools_v
implementation "com.github.pengrad:java-telegram-bot-api:${lib_javatelegramapi_v}"
implementation "com.squareup.okhttp3:okhttp:${lib_okhttp_v}"
implementation "com.google.code.gson:gson:${lib_gson_v}"
implementation group: 'com.github.pengrad', name: 'java-telegram-bot-api', version: lib_javatelegramapi_v
implementation group: 'com.softwaremill.sttp.client3', name: scala('core'), version: lib_sttp_v
implementation group: 'com.softwaremill.sttp.client3', name: scala('okhttp-backend'), version: lib_sttp_v
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: lib_okhttp_v
implementation group: 'com.google.code.gson', name: 'gson', version: lib_gson_v
testImplementation group: 'org.scalatest', name: scala('scalatest'), version: lib_scalatest_v
testImplementation group: 'org.scalatest', name: scala('scalatest-freespec'), version: lib_scalatest_v
testRuntimeOnly group: 'org.scala-lang.modules', name: scala('scala-xml'), version: lib_scalamodule_xml_v
testImplementation "org.scalatest:scalatest_$proj_scala_api:${lib_scalatest_v}"
testImplementation "org.scalatest:scalatest-freespec_$proj_scala_api:${lib_scalatest_v}"
testRuntimeOnly "org.scala-lang.modules:scala-xml_$proj_scala_api:${lib_scalamodule_xml_v}"
testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.6'
// for generating HTML report // required by gradle-scalatest plugin
testRuntimeOnly group: 'com.vladsch.flexmark', name: 'flexmark-all', version: '0.64.6'
}

View File

@ -5,7 +5,7 @@ MORNY_ARCHIVE_NAME = morny-coeur
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
VERSION = 1.2.1-pre1
VERSION = 1.2.1-pre2
USE_DELTA = false
VERSION_DELTA =
@ -22,6 +22,7 @@ lib_resourcetools_v = 0.2.2
lib_javatelegramapi_v = 6.2.0
lib_sttp_v = 3.9.0
lib_okhttp_v = 4.11.0
lib_gson_v = 2.10.1

View File

@ -8,6 +8,7 @@ import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{SendMessage, SendSticker}
import sttp.client3.{HttpError, SttpClientException}
import java.io.IOException
import scala.language.postfixOps
@ -71,7 +72,7 @@ class Nbnhhsh (using coeur: MornyCoeur) extends ITelegramCommand {
message toString
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
} catch case e: IOException => {
} catch case e: (HttpError[_] | SttpClientException) => {
coeur.account exec SendMessage(
event.message.chat.id,
s"""[Exception] in query:

View File

@ -1,12 +1,13 @@
package cc.sukazyo.cono.morny.data
import cc.sukazyo.cono.morny.util.BiliTool
import cc.sukazyo.cono.morny.util.SttpPublic.Schemes
import cc.sukazyo.cono.morny.util.UseSelect.select
import okhttp3.{HttpUrl, OkHttpClient, Request}
import sttp.client3.{basicRequest, ignore, HttpError, SttpClientException}
import sttp.client3.okhttp.OkHttpSyncBackend
import sttp.model.Uri
import java.io.IOException
import scala.util.matching.Regex
import scala.util.Using
object BilibiliForms {
@ -51,11 +52,7 @@ object BilibiliForms {
case _ => throw IllegalArgumentException(s"not a valid Bilibili video link: $url")
private val httpClient = OkHttpClient
.Builder()
.followSslRedirects(true)
.followRedirects(false)
.build()
private val httpClient = OkHttpSyncBackend()
/** get the bilibili video url from b23.tv share url.
*
@ -68,28 +65,32 @@ object BilibiliForms {
* @return bilibili video url with tracking params
*/
@throws[IllegalStateException|IllegalArgumentException]
def destructB23Url (url: String): String =
val _url: HttpUrl = HttpUrl.parse(
if url startsWith "http://" then url.replaceFirst("http://", "https://") else url
)
if _url == null then throw IllegalArgumentException("not a valid url: " + url)
if _url.host != "b23.tv" then throw IllegalArgumentException(s"not a b23 share link: $url")
if (!_url.pathSegments.isEmpty) && _url.pathSegments.get(0).matches(REGEX_BILI_ID.regex) then
throw IllegalArgumentException(s"is a b23 video link: $url ; (use parse_videoUrl directly)")
val result: Option[String] =
def destructB23Url (url: String): String = {
val uri = try Uri.unsafeParse(url).scheme(Schemes.HTTPS) catch
case e: IllegalArgumentException => throw IllegalArgumentException("not a b23.tv url", e)
if uri.host.orNull != "b23.tv" then throw
IllegalArgumentException(s"not a b23.tv url: $uri")
else if uri.pathSegments.segments.size < 1 then
throw IllegalArgumentException(s"empty b23.tv url: $uri")
else if uri.pathSegments.segments.head.v matches REGEX_BILI_ID.regex then
throw IllegalArgumentException(s"is a b23 video link: $uri . (use parse_videoUrl instead)")
try {
Using(httpClient.newCall(Request.Builder().url(_url).build).execute()) { response =>
if response.isRedirect then
val _u = response header "Location"
if _u != null then
Some(_u)
else throw IllegalStateException("unable to get b23.tv redir location from: " + response)
else throw IllegalStateException("unable to get b23.tv redir location from: " + response)
}.get
} catch case e: IOException =>
throw IllegalStateException("get b23.tv failed.", e)
result match
case Some(_result) => _result
case None => throw IllegalStateException("unable to parse from b23.tv .")
val response = basicRequest
.get(uri)
.followRedirects(false)
.response(ignore)
.send(httpClient)
try response.header("Location").get
catch case _: NoSuchElementException =>
throw IllegalStateException("unable to get b23.tv redir location from: " + response)
} catch
case e: HttpError[_] =>
throw IllegalStateException("failed parse b23.tv response.", e)
case e: SttpClientException =>
throw IllegalStateException("failed request from b23.tv: ", e)
}
}

View File

@ -1,11 +1,9 @@
package cc.sukazyo.cono.morny.data
import cc.sukazyo.cono.morny.util.OkHttpPublic.MediaTypes
import com.google.gson.Gson
import okhttp3.{OkHttpClient, Request, RequestBody, ResponseBody}
import java.io.IOException
import scala.util.Using
import sttp.client3.{asString, basicRequest, HttpError, SttpClientException, UriContext}
import sttp.client3.okhttp.OkHttpSyncBackend
import sttp.model.MediaType
object NbnhhshQuery {
@ -14,24 +12,19 @@ object NbnhhshQuery {
private case class GuessRequest (text: String)
private val API_URL = "https://lab.magiconch.com/api/nbnhhsh/"
private val API_GUESS_METHOD = "guess/"
private val API_URL = uri"https://lab.magiconch.com/api/nbnhhsh/"
private val API_GUESS_METHOD = uri"$API_URL/guess/"
private val httpClient = OkHttpClient()
private val httpClient = OkHttpSyncBackend()
@throws[IOException]
@throws[HttpError[_]|SttpClientException]
def sendGuess (text: String): GuessResult = {
val requestJsonText = Gson().toJson(GuessRequest(text))
val request = Request.Builder()
.url(API_URL + API_GUESS_METHOD)
.post(RequestBody.create(requestJsonText, MediaTypes.JSON))
.build
Using (httpClient.newCall(request).execute) { response =>
val body = response.body
if body eq null then throw IOException("Nbnhhsh Request: body is null.")
val x = s"{ 'words': ${body.string} }"
Gson().fromJson(x, classOf[GuessResult])
}.get
val http = basicRequest
.body(Gson().toJson(GuessRequest(text))).contentType(MediaType.ApplicationJson)
.post(API_GUESS_METHOD)
.response(asString.getRight)
.send(httpClient)
Gson().fromJson(s"{ 'words': ${http.body} }", classOf[GuessResult])
}
}

View File

@ -1,27 +1,29 @@
package cc.sukazyo.cono.morny.data.ip186
import okhttp3.{OkHttpClient, Request}
import cc.sukazyo.cono.morny.util.SttpPublic.Schemes
import sttp.client3.{asString, basicRequest, HttpError, SttpClientException, UriContext}
import sttp.client3.okhttp.OkHttpSyncBackend
import sttp.model.Uri
import java.io.IOException
import scala.language.postfixOps
import scala.util.Using
object IP186QueryHandler {
private val SITE_URL = "https://ip.186526.xyz/"
private val QUERY_PARAM_IP = "type=json&format=true"
private val QUERY_PARAM_WHOIS = "type=plain"
private val SITE_HOST = "ip.186526.xyz"
private val QUERY_PARAM_IP = Map("type" -> "json", "format" -> "true")
private val QUERY_PARAM_WHOIS = Map("type" -> "plain")
private val httpClient = OkHttpClient()
private val httpClient = OkHttpSyncBackend()
@throws[IOException]
def query_ip (ip: String): IP186Response =
commonQuery(SITE_URL + ip, QUERY_PARAM_IP)
commonQuery(uri"/$ip?$QUERY_PARAM_IP")
@throws[IOException]
//noinspection ScalaWeakerAccess
def query_whois (domain: String): IP186Response =
commonQuery(SITE_URL+"whois/"+domain, QUERY_PARAM_WHOIS)
commonQuery(uri"/whois/$domain?$QUERY_PARAM_WHOIS")
@throws[IOException]
def query_whoisPretty (domain: String): IP186Response =
@ -29,13 +31,28 @@ object IP186QueryHandler {
IP186Response(raw.url, raw.body substring(0, (raw.body indexOf "<<<")+3))
@throws[IOException]
private def commonQuery (requestUrl: String, queryParam: String): IP186Response = {
val request = Request.Builder().url(requestUrl + "?" + queryParam).build
Using ((httpClient newCall request) execute) { response =>
val _body = response.body
if _body eq null then throw IOException("Response of ip186: body is empty!")
IP186Response(requestUrl, _body.string)
}.get
private def commonQuery (requestPath: Uri): IP186Response = {
try
val uri = requestPath.scheme(Schemes.HTTPS).host(SITE_HOST)
IP186Response(
uri.toString,
basicRequest
.get(uri)
.response(asString.getRight)
.send(httpClient)
.body
)
catch
case e: SttpClientException =>
throw IOException("request to ip186 failed: " + e.getMessage, e)
case e: HttpError[_] =>
throw IOException("failed get from ip186: " + e.getMessage, e)
// val request = Request.Builder().url(requestUrl + "?" + queryParam).build
// Using ((httpClient newCall request) execute) { response =>
// val _body = response.body
// if _body eq null then throw IOException("Response of ip186: body is empty!")
// IP186Response(requestUrl, _body.string)
// }.get
}
}

View File

@ -1,13 +0,0 @@
package cc.sukazyo.cono.morny.util
import okhttp3.MediaType
/** some public values of [[okhttp3]] */
object OkHttpPublic {
/** predefined [[okhttp3]] [[MediaType]]s */
object MediaTypes:
/** [[MediaType]] of [[https://en.wikipedia.org/wiki/JSON JSON]]. using encoding ''UTF-8'' */
val JSON: MediaType = MediaType.get("application/json; charset=utf-8")
}

View File

@ -0,0 +1,10 @@
package cc.sukazyo.cono.morny.util
object SttpPublic {
object Schemes {
val HTTP = "http"
val HTTPS = "https"
}
}

View File

@ -1,29 +1,35 @@
package cc.sukazyo.cono.morny.util.tgapi.formatting
import com.pengrad.telegrambot.model.User
import okhttp3.{OkHttpClient, Request}
import sttp.client3.{asString, basicRequest, HttpError, SttpClientException, UriContext}
import sttp.client3.okhttp.OkHttpSyncBackend
import java.io.IOException
import scala.util.matching.Regex
import scala.util.Using
object TelegramUserInformation {
private val DC_QUERY_SOURCE_SITE = "https://t.me/"
private val DC_QUERY_PROCESSOR_REGEX: Regex = "(cdn[1-9]).tele(sco.pe|gram-cdn.org)"r
private val httpClient = OkHttpClient()
private val httpClient = OkHttpSyncBackend()
@throws[IllegalArgumentException|IOException]
def getDataCenterFromUser (username: String): String = {
val request = Request.Builder().url(DC_QUERY_SOURCE_SITE + username).build
Using (httpClient.newCall(request) execute) { response =>
val body = response.body
if body eq null then "<empty-upstream-response>"
else DC_QUERY_PROCESSOR_REGEX.findFirstMatchIn(body.string) match
try
val body = basicRequest
.get(uri"https://t.me/$username")
.response(asString.getRight)
.send(httpClient)
.body
DC_QUERY_PROCESSOR_REGEX.findFirstMatchIn(body) match
case Some(res) => res.group(1)
case None => "<no-cdn-information>"
} get
catch
case _: SttpClientException =>
"<error-http-request>"
case _: HttpError[_] =>
"<error-parse-response>"
}
def getFormattedInformation (user: User): String = {