mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 11:14:55 +08:00
add inline share xhs url
This commit is contained in:
parent
46519138e1
commit
3c42738816
@ -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.3.5-dev
|
||||
VERSION = 1.4.0-SNAPSHOT
|
||||
|
||||
USE_DELTA = false
|
||||
VERSION_DELTA =
|
||||
|
@ -13,6 +13,7 @@ class MornyQueries (using MornyCoeur) {
|
||||
MyInformation(),
|
||||
ShareToolTwitter(),
|
||||
ShareToolBilibili(),
|
||||
ShareToolXhs(),
|
||||
ShareToolSocialContent()
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
package cc.sukazyo.cono.morny.bot.query
|
||||
import cc.sukazyo.cono.morny.extra.xhs.XHSLink
|
||||
import com.pengrad.telegrambot.model.Update
|
||||
import com.pengrad.telegrambot.model.request.InlineQueryResultArticle
|
||||
|
||||
class ShareToolXhs extends ITelegramQuery {
|
||||
|
||||
private val TITLE = "[Xiaohongshu] Share Link"
|
||||
private val ID = "[morny/share/xhs/link]"
|
||||
|
||||
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
||||
import event.inlineQuery
|
||||
|
||||
if inlineQuery.query == null then return null
|
||||
val content = inlineQuery.query
|
||||
|
||||
val xhsLink: XHSLink = {
|
||||
XHSLink.matchUrl(content) match
|
||||
case Some(matched) => matched match
|
||||
case xhsLink: XHSLink => xhsLink
|
||||
case shareLink: XHSLink.ShareLink =>
|
||||
shareLink.getXhsLink
|
||||
case None =>
|
||||
XHSLink.searchShareText(content).map(_.getXhsLink) match
|
||||
case Some(found) => found
|
||||
case None => return null
|
||||
}
|
||||
|
||||
List(
|
||||
InlineQueryUnit(InlineQueryResultArticle(
|
||||
ID+content.hashCode,
|
||||
TITLE,
|
||||
xhsLink.link
|
||||
))
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
87
src/main/scala/cc/sukazyo/cono/morny/extra/xhs/XHSLink.scala
Normal file
87
src/main/scala/cc/sukazyo/cono/morny/extra/xhs/XHSLink.scala
Normal file
@ -0,0 +1,87 @@
|
||||
package cc.sukazyo.cono.morny.extra.xhs
|
||||
|
||||
import cc.sukazyo.cono.morny.util.SttpPublic.{mornyBasicRequest, Schemes}
|
||||
import sttp.client3.okhttp.OkHttpSyncBackend
|
||||
import sttp.client3.{HttpError, RequestT, SttpClientException}
|
||||
import sttp.model.Uri
|
||||
|
||||
case class XHSLink (exploreId: String) {
|
||||
|
||||
def link =
|
||||
s"https://www.xiaohongshu.com/explore/$exploreId"
|
||||
|
||||
}
|
||||
|
||||
object XHSLink {
|
||||
|
||||
private lazy val http_client = OkHttpSyncBackend()
|
||||
|
||||
private lazy val REGEX_EXPLORER_URL = "(?:(?:https?:)?//)?(?:www\\.)?xiaohongshu\\.com/(?:explore/|discovery/item/)([a-fA-F0-9]+)/?(?:\\?.+)?"r
|
||||
private lazy val REGEX_SHARE_URL = "(?:(?:https?:)?//)?(?:www\\.)?xhslink\\.com/([a-zA-Z0-9]+)/?(?:\\?.+)?"r
|
||||
private lazy val REGEX_SHARE_TEXTS = "\uD83D\uDE06 ([0-9a-zA-Z]+) \uD83D\uDE06 (?:(?:https?:)?//)?(?:www\\.)?xhslink\\.com/([a-zA-Z0-9]+)/?"r
|
||||
|
||||
def matchExplorerUrl (url: String): Option[XHSLink] = {
|
||||
url match
|
||||
case REGEX_EXPLORER_URL(explorerId) => Some(XHSLink(explorerId))
|
||||
case _ => None
|
||||
}
|
||||
|
||||
def matchShareUrl (url: String): Option[ShareLink] = {
|
||||
url match
|
||||
case REGEX_SHARE_URL(shareId) => Some(ShareLink(shareId))
|
||||
case _ => None
|
||||
}
|
||||
|
||||
def matchUrl (url: String): Option[XHSLink|ShareLink] = {
|
||||
matchExplorerUrl(url) orElse matchShareUrl(url)
|
||||
}
|
||||
|
||||
def searchShareText (texts: String): Option[ShareLink] = {
|
||||
REGEX_SHARE_TEXTS.findFirstMatchIn(texts).map(x => ShareLink(x.group(2)))
|
||||
}
|
||||
|
||||
case class ShareLink (shareId: String) {
|
||||
|
||||
def link =
|
||||
s"https://xhslink.com/$shareId"
|
||||
|
||||
/** Get the [[XHSLink xiaohongshu explorer link]] that this share link is linked to via sttp request.
|
||||
*
|
||||
* @param http_client the sttp http client backend that will be used. defaults is [[XHSLink]] owned backend.
|
||||
* @param basic_request the sttp basic request that will be used. defaults is [[mornyBasicRequest]].
|
||||
* @throws IllegalArgumentException When the XHS server does not returns a valid explorer link. Mostly maybe the
|
||||
* share url is invalid or expired.
|
||||
* @throws IllegalStateException When cannot connect to the XHS server.
|
||||
* @return the [[XHSLink xiaohongshu explorer link]] that this share link is linked to.
|
||||
*/
|
||||
@throws[IllegalArgumentException]
|
||||
@throws[IllegalStateException]
|
||||
def getXhsLink (using
|
||||
http_client: sttp.client3.SttpBackend[sttp.client3.Identity, _] = http_client,
|
||||
basic_request: RequestT[sttp.client3.Empty, Either[String, String], Any] = mornyBasicRequest
|
||||
): XHSLink = {
|
||||
|
||||
val uri = try Uri.unsafeParse(this.link).scheme(Schemes.HTTPS) catch
|
||||
case e: IllegalArgumentException => throw IllegalStateException("Cannot format this Share link to a valid request url.").initCause(e)
|
||||
|
||||
try {
|
||||
import sttp.client3.*
|
||||
val request = basic_request
|
||||
.get(uri)
|
||||
.followRedirects(false)
|
||||
.response(ignore)
|
||||
val response = request.send(http_client)
|
||||
val redir = response.header("Location").get
|
||||
matchExplorerUrl(redir) match
|
||||
case None => throw IllegalArgumentException(s"XHS server returns a non-XHSLink url: $redir")
|
||||
case Some(link) => link
|
||||
} catch
|
||||
case e: SttpClientException => throw IllegalStateException("failed get response from xhs server.").initCause(e)
|
||||
case e: HttpError[_] => throw IllegalStateException("failed parse response from xhs server.").initCause(e)
|
||||
case e: NoSuchElementException => throw IllegalArgumentException("XHS server does not returns any url.").initCause(e)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package cc.sukazyo.cono.morny.util
|
||||
|
||||
import cc.sukazyo.cono.morny.MornySystem
|
||||
import sttp.client3.basicRequest
|
||||
import sttp.client3.{basicRequest, RequestT}
|
||||
import sttp.model.Header
|
||||
|
||||
object SttpPublic {
|
||||
@ -23,7 +23,7 @@ object SttpPublic {
|
||||
|
||||
}
|
||||
|
||||
val mornyBasicRequest =
|
||||
val mornyBasicRequest: RequestT[sttp.client3.Empty, Either[String, String], Any] =
|
||||
basicRequest
|
||||
.header(Headers.UserAgent.MORNY_CURRENT, true)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user