mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2025-02-07 16:29:51 +08:00
add urlencode/decode for /encrypt, add b23.tv parse for InlineBilibiliShare
This commit is contained in:
parent
79206dd13b
commit
60dbcef140
@ -5,12 +5,12 @@ MORNY_ARCHIVE_NAME = morny-coeur
|
|||||||
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
|
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
|
||||||
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
|
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
|
||||||
|
|
||||||
VERSION = 1.1.1.xiongan-dev2
|
VERSION = 1.2.0-alpha1
|
||||||
|
|
||||||
USE_DELTA = false
|
USE_DELTA = false
|
||||||
VERSION_DELTA =
|
VERSION_DELTA =
|
||||||
|
|
||||||
CODENAME = nanchang
|
CODENAME = xiongan
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.command
|
|||||||
|
|
||||||
import cc.sukazyo.cono.morny.Log.logger
|
import cc.sukazyo.cono.morny.Log.logger
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
import cc.sukazyo.cono.morny.bot.command.ICommandAlias.ListedAlias
|
||||||
import cc.sukazyo.cono.morny.data.TelegramStickers
|
import cc.sukazyo.cono.morny.data.TelegramStickers
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import cc.sukazyo.cono.morny.util.CommonEncrypt
|
import cc.sukazyo.cono.morny.util.CommonEncrypt
|
||||||
@ -13,6 +14,7 @@ import com.pengrad.telegrambot.model.request.ParseMode
|
|||||||
import com.pengrad.telegrambot.request.{GetFile, SendDocument, SendMessage, SendSticker}
|
import com.pengrad.telegrambot.request.{GetFile, SendDocument, SendMessage, SendSticker}
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.net.{URLDecoder, URLEncoder}
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
@ -20,7 +22,7 @@ import scala.language.postfixOps
|
|||||||
class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
override val name: String = "encrypt"
|
override val name: String = "encrypt"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = Array(ListedAlias("enc"))
|
||||||
override val paramRule: String = "[algorithm|(l)] [(uppercase)]"
|
override val paramRule: String = "[algorithm|(l)] [(uppercase)]"
|
||||||
override val description: String = "通过指定算法加密回复的内容 (目前只支持文本)"
|
override val description: String = "通过指定算法加密回复的内容 (目前只支持文本)"
|
||||||
|
|
||||||
@ -135,6 +137,12 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
|||||||
def genResult_hash (source: XEncryptable, processor: Array[Byte]=>Array[Byte]): EXHash =
|
def genResult_hash (source: XEncryptable, processor: Array[Byte]=>Array[Byte]): EXHash =
|
||||||
val hashed = processor(source asByteArray) toHex;
|
val hashed = processor(source asByteArray) toHex;
|
||||||
EXHash(if mod_uppercase then hashed toUpperCase else hashed)
|
EXHash(if mod_uppercase then hashed toUpperCase else hashed)
|
||||||
|
//noinspection UnitMethodIsParameterless
|
||||||
|
def echo_unsupported: Unit =
|
||||||
|
coeur.account exec SendSticker(
|
||||||
|
event.message.chat.id,
|
||||||
|
TelegramStickers ID_404
|
||||||
|
).replyToMessageId(event.message.messageId)
|
||||||
val result: EXHash|EXFile|EXText = args(0) match
|
val result: EXHash|EXFile|EXText = args(0) match
|
||||||
case "base64" | "b64" | "base64url" | "base64u" | "b64u" =>
|
case "base64" | "b64" | "base64url" | "base64u" | "b64u" =>
|
||||||
val _tool_b64 =
|
val _tool_b64 =
|
||||||
@ -154,21 +162,27 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
|||||||
_tool_b64d.decode,
|
_tool_b64d.decode,
|
||||||
CommonEncrypt.lint_base64FileName
|
CommonEncrypt.lint_base64FileName
|
||||||
) } catch case _: IllegalArgumentException =>
|
) } catch case _: IllegalArgumentException =>
|
||||||
coeur.account exec SendSticker(
|
echo_unsupported
|
||||||
event.message.chat.id,
|
|
||||||
TelegramStickers ID_404 // todo: is here better erro notify?
|
|
||||||
).replyToMessageId(event.message.messageId)
|
|
||||||
return
|
return
|
||||||
|
case "urlencoder" | "urlencode" | "urlenc" | "url" =>
|
||||||
|
input match
|
||||||
|
case x: XText =>
|
||||||
|
EXText(URLEncoder.encode(x.data, ENCRYPT_STANDARD_CHARSET))
|
||||||
|
case _: XFile => echo_unsupported; return;
|
||||||
|
case "urldecoder" | "urldecode" | "urldec" | "urld" =>
|
||||||
|
input match
|
||||||
|
case _: XFile => echo_unsupported; return;
|
||||||
|
case x: XText =>
|
||||||
|
try { EXText(URLDecoder.decode(x.data, ENCRYPT_STANDARD_CHARSET)) }
|
||||||
|
catch case _: IllegalArgumentException =>
|
||||||
|
echo_unsupported
|
||||||
|
return
|
||||||
case "md5" => genResult_hash(input, MD5)
|
case "md5" => genResult_hash(input, MD5)
|
||||||
case "sha1" => genResult_hash(input, SHA1)
|
case "sha1" => genResult_hash(input, SHA1)
|
||||||
case "sha256" => genResult_hash(input, SHA256)
|
case "sha256" => genResult_hash(input, SHA256)
|
||||||
case "sha512" => genResult_hash(input, SHA512)
|
case "sha512" => genResult_hash(input, SHA512)
|
||||||
case _ =>
|
case _ =>
|
||||||
coeur.account exec SendSticker(
|
echo_unsupported; return;
|
||||||
event.message.chat.id,
|
|
||||||
TelegramStickers ID_404
|
|
||||||
).replyToMessageId(event.message.messageId)
|
|
||||||
return;
|
|
||||||
// END BLOCK: encrypt
|
// END BLOCK: encrypt
|
||||||
|
|
||||||
// output
|
// output
|
||||||
@ -203,6 +217,8 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
|||||||
* '''__base64url__''', base64u, b64u<br>
|
* '''__base64url__''', base64u, b64u<br>
|
||||||
* '''__base64decode__''', base64d, b64d<br>
|
* '''__base64decode__''', base64d, b64d<br>
|
||||||
* '''__base64url-decode__''', base64ud, b64ud<br>
|
* '''__base64url-decode__''', base64ud, b64ud<br>
|
||||||
|
* '''urlencode''', urlencode, urlenc, url<br>
|
||||||
|
* '''__urldecoder__''', urldecode, urldec, urld<br>
|
||||||
* '''__sha1__'''<br>
|
* '''__sha1__'''<br>
|
||||||
* '''__sha256__'''<br>
|
* '''__sha256__'''<br>
|
||||||
* '''__sha512__'''<br>
|
* '''__sha512__'''<br>
|
||||||
@ -218,6 +234,8 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
|||||||
|<b><u>base64url</u></b>, base64u, b64u
|
|<b><u>base64url</u></b>, base64u, b64u
|
||||||
|<b><u>base64decode</u></b>, base64d, b64d
|
|<b><u>base64decode</u></b>, base64d, b64d
|
||||||
|<b><u>base64url-decode</u></b>, base64ud, b64ud
|
|<b><u>base64url-decode</u></b>, base64ud, b64ud
|
||||||
|
|<b><u>urlencoder</u></b>, urlencode, urlenc, url
|
||||||
|
|<b><u>urldecoder</u></b>, urldecode, urldec, urld
|
||||||
|<b><u>sha1</u></b>
|
|<b><u>sha1</u></b>
|
||||||
|<b><u>sha256</u></b>
|
|<b><u>sha256</u></b>
|
||||||
|<b><u>sha512</u></b>
|
|<b><u>sha512</u></b>
|
||||||
|
@ -7,7 +7,6 @@ import com.pengrad.telegrambot.model.Update
|
|||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
import com.pengrad.telegrambot.request.SendMessage
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
import javax.annotation.{Nonnull, Nullable}
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
class Testing (using coeur: MornyCoeur) extends ISimpleCommand {
|
class Testing (using coeur: MornyCoeur) extends ISimpleCommand {
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.query
|
package cc.sukazyo.cono.morny.bot.query
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.Log.logger
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.NamingUtils.inlineQueryId
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.NamingUtils.inlineQueryId
|
||||||
import cc.sukazyo.cono.morny.util.BiliTool
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.util.UseSelect.select
|
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTextMessageContent, ParseMode}
|
import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTextMessageContent, ParseMode}
|
||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.util.matching.Regex
|
import scala.util.matching.Regex
|
||||||
|
|
||||||
class ShareToolBilibili extends ITelegramQuery {
|
class ShareToolBilibili (using coeur: MornyCoeur) extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE_BILI_AV = "[bilibili] Share video / av"
|
private val TITLE_BILI_AV = "[bilibili] Share video / av"
|
||||||
private val TITLE_BILI_BV = "[bilibili] Share video / BV"
|
private val TITLE_BILI_BV = "[bilibili] Share video / BV"
|
||||||
@ -23,54 +22,40 @@ class ShareToolBilibili extends ITelegramQuery {
|
|||||||
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
||||||
|
|
||||||
if (event.inlineQuery.query == null) return null
|
if (event.inlineQuery.query == null) return null
|
||||||
|
if (event.inlineQuery.query isBlank) return null
|
||||||
|
|
||||||
event.inlineQuery.query match
|
import cc.sukazyo.cono.morny.data.BilibiliForms.*
|
||||||
case REGEX_BILI_VIDEO(_url_v, _url_av, _url_bv, _url_param, _url_v_part, _raw_av, _raw_bv) =>
|
val result: BiliVideoId =
|
||||||
|
try
|
||||||
logger debug
|
parse_videoUrl(event.inlineQuery.query)
|
||||||
s"""====== Share Tool Bilibili Catch ok
|
catch case _: IllegalArgumentException =>
|
||||||
|1: ${_url_v}
|
try
|
||||||
|2: ${_url_av}
|
parse_videoUrl(destructB23Url(event.inlineQuery.query))
|
||||||
|3: ${_url_bv}
|
catch
|
||||||
|4: ${_url_param}
|
case _: IllegalArgumentException =>
|
||||||
|5: ${_url_v_part}
|
return null;
|
||||||
|6: ${_raw_av}
|
case e: IllegalStateException =>
|
||||||
|7: ${_raw_bv}"""
|
logger error exceptionLog(e)
|
||||||
.stripMargin
|
coeur.daemons.reporter.exception(e)
|
||||||
|
return null;
|
||||||
var av = select(_url_av, _raw_av)
|
|
||||||
var bv = select(_url_bv, _raw_bv)
|
val av = result.av
|
||||||
logger trace s"catch id av[$av] bv[$bv]"
|
val bv = result.bv
|
||||||
val part: Int|Null = if (_url_v_part!=null) _url_v_part toInt else null
|
val id_av = s"av$av"
|
||||||
logger trace s"catch video part[$part]"
|
val id_bv = s"BV$bv"
|
||||||
|
val linkParams = if (result.part != null) s"?p=${result.part}" else ""
|
||||||
if (av == null) {
|
val link_av = LINK_PREFIX + id_av + linkParams
|
||||||
assert (bv != null)
|
val link_bv = LINK_PREFIX + id_bv + linkParams
|
||||||
av = BiliTool.toAv(bv) toString;
|
List(
|
||||||
logger trace s"converted bv[$av] to av[$av]"
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
} else {
|
inlineQueryId(ID_PREFIX_BILI_AV + av), TITLE_BILI_AV + av,
|
||||||
bv = BiliTool.toBv(av toLong)
|
InputTextMessageContent(SHARE_FORMAT_HTML.format(link_av, id_av)).parseMode(ParseMode HTML)
|
||||||
logger trace s"converted av[$av] to bv[$bv]"
|
)),
|
||||||
}
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
|
inlineQueryId(ID_PREFIX_BILI_BV + bv), TITLE_BILI_BV + bv,
|
||||||
val id_av = s"av$av"
|
InputTextMessageContent(SHARE_FORMAT_HTML.format(link_bv, id_bv)).parseMode(ParseMode HTML)
|
||||||
val id_bv = s"BV$bv"
|
))
|
||||||
val linkParams = if (part!=null) s"?p=$part" else ""
|
)
|
||||||
val link_av = LINK_PREFIX + id_av + linkParams
|
|
||||||
val link_bv = LINK_PREFIX + id_bv + linkParams
|
|
||||||
|
|
||||||
List(
|
|
||||||
InlineQueryUnit(InlineQueryResultArticle(
|
|
||||||
inlineQueryId(ID_PREFIX_BILI_AV+av), TITLE_BILI_AV+av,
|
|
||||||
InputTextMessageContent(SHARE_FORMAT_HTML.format(link_av, id_av)).parseMode(ParseMode HTML)
|
|
||||||
)),
|
|
||||||
InlineQueryUnit(InlineQueryResultArticle(
|
|
||||||
inlineQueryId(ID_PREFIX_BILI_BV + bv), TITLE_BILI_BV + bv,
|
|
||||||
InputTextMessageContent(SHARE_FORMAT_HTML.format(link_bv, id_bv)).parseMode(ParseMode HTML)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
|
|
||||||
case _ => null
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.util.BiliTool
|
||||||
|
import cc.sukazyo.cono.morny.util.UseSelect.select
|
||||||
|
import okhttp3.{HttpUrl, OkHttpClient, Request}
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import scala.util.matching.Regex
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
|
object BilibiliForms {
|
||||||
|
|
||||||
|
case class BiliVideoId (av: Long, bv: String, part: Int|Null = null)
|
||||||
|
|
||||||
|
private val REGEX_BILI_ID = "^((?:av|AV)(\\d{1,12})|(?:bv|BV)([A-HJ-NP-Za-km-z1-9]{10}))$"r
|
||||||
|
private val REGEX_BILI_VIDEO: Regex = "^(?:(?:https?://)?(?:www\\.)?bilibili\\.com(?:/s)?/video/((?:av|AV)(\\d{1,12})|(?:bv|BV)([A-HJ-NP-Za-km-z1-9]{10}))/?(\\?(?:p=(\\d+))?.*)?|(?:av|AV)(\\d{1,12})|(?:bv|BV)([A-HJ-NP-Za-km-z1-9]{10}))$" r
|
||||||
|
|
||||||
|
/** parse a Bilibili video link to a [[BiliVideoId]] format Bilibili Video Id
|
||||||
|
*
|
||||||
|
* @param url the Bilibili video link -- should be a valid link with av/BV,
|
||||||
|
* can take some tracking params (will be ignored), can be a search
|
||||||
|
* result link (have `s/` path).
|
||||||
|
* @throws IllegalArgumentException when the link is not the valid bilibili video link
|
||||||
|
* @return the [[BiliVideoId]] contains raw or converted av id, and raw or converted bv id,
|
||||||
|
* and video part id.
|
||||||
|
*/
|
||||||
|
@throws[IllegalArgumentException]
|
||||||
|
def parse_videoUrl (url: String): BiliVideoId =
|
||||||
|
url match
|
||||||
|
case REGEX_BILI_VIDEO(_url_v, _url_av, _url_bv, _url_param, _url_v_part, _raw_av, _raw_bv) =>
|
||||||
|
val av = select(_url_av, _raw_av)
|
||||||
|
val bv = select(_url_bv, _raw_bv)
|
||||||
|
val part: Int | Null = if (_url_v_part != null) _url_v_part toInt else null
|
||||||
|
if (av == null) {
|
||||||
|
assert(bv != null)
|
||||||
|
BiliVideoId(BiliTool.toAv(bv), bv, part)
|
||||||
|
} else {
|
||||||
|
val _av = av.toLong
|
||||||
|
BiliVideoId(_av, BiliTool.toBv(_av), part)
|
||||||
|
}
|
||||||
|
case _ => throw IllegalArgumentException(s"not a valid Bilibili video link: $url")
|
||||||
|
|
||||||
|
private val httpClient = OkHttpClient
|
||||||
|
.Builder()
|
||||||
|
.followSslRedirects(true)
|
||||||
|
.followRedirects(false)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
/** get the bilibili video url from b23.tv share url.
|
||||||
|
*
|
||||||
|
* result url can be used in [[parse_videoUrl]]
|
||||||
|
*
|
||||||
|
* @param url b23.tv share url
|
||||||
|
* @throws IllegalArgumentException the input `url` is not a b23.tv url
|
||||||
|
* @throws IllegalStateException some exception occurred when getting information from remote
|
||||||
|
* host, or failed to parse the information got
|
||||||
|
* @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] =
|
||||||
|
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 .")
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package cc.sukazyo.cono.morny.test.cc.sukazyo.cono.morny.data
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.data.BilibiliForms.*
|
||||||
|
import cc.sukazyo.cono.morny.test.MornyTests
|
||||||
|
import org.scalatest.prop.TableDrivenPropertyChecks
|
||||||
|
|
||||||
|
class BilibiliFormsTest extends MornyTests with TableDrivenPropertyChecks {
|
||||||
|
|
||||||
|
"while parsing bilibili video link :" - {
|
||||||
|
|
||||||
|
"raw avXXX should be parsed" in:
|
||||||
|
parse_videoUrl("av455017605") shouldEqual BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"raw BVXXX should be parsed" in:
|
||||||
|
parse_videoUrl("BV1T24y197V2") shouldEqual BiliVideoId(688730800L, "1T24y197V2")
|
||||||
|
"raw id without av/BV prefix should not be parsed" in:
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("1T24y197V2")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("455017605")
|
||||||
|
"av/bv prefix can be either uppercase or lowercase" in:
|
||||||
|
parse_videoUrl("bv1T24y197V2") shouldEqual BiliVideoId(688730800L, "1T24y197V2")
|
||||||
|
parse_videoUrl("AV455017605") shouldEqual BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
|
||||||
|
"av/bv bilibili.com link should be parsed" in:
|
||||||
|
parse_videoUrl("https://www.bilibili.com/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
parse_videoUrl("https://www.bilibili.com/video/bv1T24y197V2") shouldEqual
|
||||||
|
BiliVideoId(688730800L, "1T24y197V2")
|
||||||
|
"bilibili.com link can have protocol http:// or https://" in:
|
||||||
|
parse_videoUrl("http://www.bilibili.com/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"bilibili.com link can omit protocol http or https" in :
|
||||||
|
parse_videoUrl("www.bilibili.com/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"bilibili.com link can omit www. prefix" in :
|
||||||
|
parse_videoUrl("bilibili.com/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
parse_videoUrl("https://bilibili.com/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"bilibili.com link can be search result link (with /s path prefix)" in :
|
||||||
|
parse_videoUrl("bilibili.com/s/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
parse_videoUrl("https://www.bilibili.com/s/video/AV455017605") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"bilibili.com link can only be video link" in :
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("bilibili.com/s/media/AV455017605")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://www.bilibili.com/media/AV455017605")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://www.bilibili.com/AV455017605")
|
||||||
|
"bilibili.com link can take parameters" in :
|
||||||
|
parse_videoUrl("https://www.bilibili.com/video/av455017605?vd_source=123456") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
parse_videoUrl("bilibili.com/video/AV455017605?mid=12hdowhAID82EQ&289EHD8AHDOIWU8=r2aur9%3Bi0%3AJ%7BRQJH%28QJ.%5BropWG%3AKR%24%28O%7BGR") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg")
|
||||||
|
"video part within bilibili.com link params should be parsed" in :
|
||||||
|
parse_videoUrl("https://www.bilibili.com/video/BV1Q541167Qg?p=1") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg", 1)
|
||||||
|
parse_videoUrl("https://www.bilibili.com/video/av455017605?p=1&vd_source=123456") shouldEqual
|
||||||
|
BiliVideoId(455017605L, "1Q541167Qg", 1)
|
||||||
|
// todo: implement it
|
||||||
|
// parse_videoUrl("bilibili.com/video/AV455017605?mid=12hdowhAI&p=5&x=D82EQ&289EHD8AHDOIWU8=r2aur9%3Bi0%3AJ%7BRQJH%28QJ.%5BropWG%3AKR%24%28O%7BGR") shouldEqual
|
||||||
|
// BiliVideoId(455017605L, "1Q541167Qg", 5)
|
||||||
|
|
||||||
|
"av id with more than 12 digits should not be parsed" in :
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("av4550176087554")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("bilibili.com/video/av4550176087554")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("av455017608755634345565341256")
|
||||||
|
"av id with 0 digits should not be parsed" in :
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("av")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("bilibili.com/video/av")
|
||||||
|
"BV id with not 10 digits should not be parsed" in :
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("BV123456789")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("BV12345678")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("bilibili.com/video/BV12345678901")
|
||||||
|
|
||||||
|
"url which is not bilibili link should not be parsed" in:
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://www.pilipili.com/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://pilipili.com/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://blilblil.com/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://bilibili.cc/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://vxbilibili.com/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("https://bilibiliexc.com/video/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("b23.tv/av123456") // todo: support it
|
||||||
|
an[IllegalArgumentException] should be thrownBy parse_videoUrl("C# does not have type erasure. C# has actual generic types deeply baked into the runtime.\n\n好文明")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"while destruct b23.tv share link :" - {
|
||||||
|
|
||||||
|
val examples = Table(
|
||||||
|
("b23_link", "bilibili_video_link"),
|
||||||
|
("https://b23.tv/iiCldvZ", "https://www.bilibili.com/video/BV1Gh411P7Sh?buvid=XY6F25B69BE9CF469FF5B917D012C93E95E72&is_story_h5=false&mid=wD6DQnYivIG5pfA3sAGL6A%3D%3D&p=1&plat_id=114&share_from=ugc&share_medium=android&share_plat=android&share_session_id=8081015b-1210-4dea-a665-6746b4850fcd&share_source=COPY&share_tag=s_i×tamp=1689605644&unique_k=iiCldvZ&up_id=19977489"),
|
||||||
|
("http://b23.tv/3ymowwx", "https://www.bilibili.com/video/BV15Y411n754?p=1&share_medium=android_i&share_plat=android&share_source=COPY&share_tag=s_i×tamp=1650293889&unique_k=3ymowwx")
|
||||||
|
)
|
||||||
|
|
||||||
|
"not b23.tv link is not supported" in:
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("sukazyo.cc/2xhUHO2e")
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("https://sukazyo.cc/2xhUHO2e")
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("长月烬明澹台烬心理分析向解析(一)因果之锁,渡魔之路")
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("https://b23.tvb/JDo2eaD")
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("https://ab23.tv/JDo2eaD")
|
||||||
|
"b23.tv/avXXX video link is not supported" in:
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("https://b23.tv/av123456")
|
||||||
|
an[IllegalArgumentException] should be thrownBy destructB23Url("https://b23.tv/BV1Q541167Qg")
|
||||||
|
|
||||||
|
forAll (examples) { (origin, result) =>
|
||||||
|
s"b23 link $origin should be destructed to $result" in:
|
||||||
|
destructB23Url(origin) shouldEqual result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user