增加 API

This commit is contained in:
czp3009 2019-02-21 00:09:25 +08:00
parent eb588f5798
commit 075d880f53
10 changed files with 838 additions and 44 deletions

View File

@ -55,7 +55,7 @@ https://app.bilibili.com
BilibiliClient().appAPI
为 app 提供通用接口, 例如获取个人信息. 完整示例如下
总站 API. 获取个人信息的完整示例如下:
runBlocking {
val bilibiliClient = BilibiliClient().apply {
@ -70,7 +70,14 @@ https://api.vc.bilibili.com
BilibiliClient().vcAPI
小视频有关的接口.
小视频.
# member
https://member.bilibili.com
BilibiliClient().memberAPI
创作中心.
# License
GPL V3

View File

@ -24,6 +24,11 @@ object BaseUrl {
*/
const val vc = "https://api.vc.bilibili.com"
/**
* 创作中心
*/
const val member = "https://member.bilibili.com"
/**
* 直播
*/

View File

@ -1,6 +1,7 @@
package com.hiczp.bilibili.api
import com.hiczp.bilibili.api.app.AppAPI
import com.hiczp.bilibili.api.member.MemberAPI
import com.hiczp.bilibili.api.message.MessageAPI
import com.hiczp.bilibili.api.passport.PassportAPI
import com.hiczp.bilibili.api.passport.model.LoginResponse
@ -84,15 +85,15 @@ class BilibiliClient(
"ts" to { Instant.now().epochSecond.toString() }
)
private val defaultCommonQueryParamInterceptor = CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray)
private val defaultQuerySignInterceptor = SortAndSignInterceptor(ParamType.QUERY, billingClientProperties.appSecret)
private val defaultFormSignInterceptor = SortAndSignInterceptor(ParamType.FORM_URL_ENCODED, billingClientProperties.appSecret)
/**
* 用户鉴权相关的接口
*/
@Suppress("SpellCheckingInspection")
val passportAPI by lazy {
createAPI<PassportAPI>(BaseUrl.passport, logLevel,
createAPI<PassportAPI>(BaseUrl.passport,
defaultCommonHeaderInterceptor,
CommonParamInterceptor(ParamType.FORM_URL_ENCODED,
"appkey" to { billingClientProperties.appKey },
@ -102,7 +103,7 @@ class BilibiliClient(
"platform" to { billingClientProperties.platform },
"ts" to { Instant.now().epochSecond.toString() }
),
defaultFormSignInterceptor
SortAndSignInterceptor(ParamType.FORM_URL_ENCODED, billingClientProperties.appSecret)
)
}
@ -111,7 +112,7 @@ class BilibiliClient(
*/
@Suppress("SpellCheckingInspection")
val messageAPI by lazy {
createAPI<MessageAPI>(BaseUrl.message, logLevel,
createAPI<MessageAPI>(BaseUrl.message,
defaultCommonHeaderInterceptor,
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray,
"actionKey" to { "appkey" },
@ -122,13 +123,13 @@ class BilibiliClient(
}
/**
* 提供一些通用信息
* 总站 API
*/
@Suppress("SpellCheckingInspection")
val appAPI by lazy {
createAPI<AppAPI>(BaseUrl.app, logLevel,
createAPI<AppAPI>(BaseUrl.app,
defaultCommonHeaderInterceptor,
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray),
defaultCommonQueryParamInterceptor,
defaultQuerySignInterceptor
)
}
@ -138,7 +139,7 @@ class BilibiliClient(
*/
@Suppress("SpellCheckingInspection")
val vcAPI by lazy {
createAPI<VcAPI>(BaseUrl.vc, logLevel,
createAPI<VcAPI>(BaseUrl.vc,
defaultCommonHeaderInterceptor,
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray,
"_device" to { billingClientProperties.platform },
@ -152,6 +153,17 @@ class BilibiliClient(
)
}
/**
* 创作中心
*/
val memberAPI by lazy {
createAPI<MemberAPI>(BaseUrl.member,
defaultCommonHeaderInterceptor,
defaultCommonQueryParamInterceptor,
defaultQuerySignInterceptor
)
}
/**
* 登陆
* v3 登陆接口会同时返回 cookies token
@ -207,32 +219,31 @@ class BilibiliClient(
loginResponse = null
}
private inline fun <reified T : Any> createAPI(
baseUrl: String,
vararg interceptors: Interceptor
) = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(coroutineCallAdapterFactory)
.client(OkHttpClient.Builder().apply {
interceptors.forEach {
addInterceptor(it)
}
addInterceptor(FailureResponseInterceptor)
//log
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
addNetworkInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
}
}.build())
.build()
.create(T::class.java)
companion object {
@Suppress("SpellCheckingInspection")
private val gsonConverterFactory = GsonConverterFactory.create()
private val coroutineCallAdapterFactory = CoroutineCallAdapterFactory()
private val traceIdFormat = SimpleDateFormat("yyyyMMddHHmm000ss")
private fun generateTraceId() = traceIdFormat.format(Date())
}
}
@Suppress("SpellCheckingInspection")
private val gsonConverterFactory = GsonConverterFactory.create()
private val coroutineCallAdapterFactory = CoroutineCallAdapterFactory()
private inline fun <reified T : Any> createAPI(
baseUrl: String,
logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.NONE,
vararg interceptors: Interceptor
) = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(coroutineCallAdapterFactory)
.client(OkHttpClient.Builder().apply {
interceptors.forEach {
addInterceptor(it)
}
addInterceptor(FailureResponseInterceptor)
//log
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
addNetworkInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
}
}.build())
.build()
.create(T::class.java)

View File

@ -1,16 +1,14 @@
package com.hiczp.bilibili.api.app
import com.hiczp.bilibili.api.app.model.IndexPage
import com.hiczp.bilibili.api.app.model.Mine
import com.hiczp.bilibili.api.app.model.MyInfo
import com.hiczp.bilibili.api.app.model.Sidebar
import com.hiczp.bilibili.api.app.model.*
import kotlinx.coroutines.Deferred
import retrofit2.http.GET
import retrofit2.http.Query
import java.time.Instant
import java.util.*
/**
* 提供通用信息的接口
* 总站 API
*/
@Suppress("DeferredIsResult")
interface AppAPI {
@ -34,12 +32,12 @@ interface AppAPI {
fun sidebar(): Deferred<Sidebar>
/**
* 首页内容
* 首页内容(客户端通过解析返回的内容来生成页面内容, 下同)
* 首页 -> 推荐
*/
@Suppress("SpellCheckingInspection")
@GET("/x/v2/feed/index")
fun index(
fun homePage(
@Query("ad_extra") adExtra: String? = null,
@Query("autoplay_card") autoplayCard: Int = 0,
@Query("banner_hash") bannerHash: String? = null,
@ -50,11 +48,74 @@ interface AppAPI {
@Query("fnver") fnVer: Int = 0,
@Query("force_host") forceHost: Int = 0,
@Query("idx") index: Long = Instant.now().epochSecond,
@Query("login_event") loginEvent: Int = 2,
@Query("login_event") loginEvent: Int = 0,
@Query("network") network: String = "mobile",
@Query("open_event") openEvent: String? = null,
@Query("pull") pull: Boolean = true,
@Query("qn") qn: Int = 32,
@Query("recsys_mode") recsysMode: Int = 0
): Deferred<IndexPage>
): Deferred<HomePage>
/**
* 热门页面
* 首页 -> 热门
*/
@GET("/x/v2/show/popular/index")
fun popularPage(
@Query("fnval") fnVal: Int = 16,
@Query("fnver") fnVer: Int = 0,
@Query("force_host") forceHost: Int = 0,
@Query("idx") index: Long = 0,
@Query("last_param") lastParam: String? = null,
@Query("login_event") loginEvent: Int = 0,
@Query("qn") qn: Int = 32,
@Query("ver") ver: Long? = null //ver 的值为上一次请求该接口时的 timestamp-1
): Deferred<PopularPage>
/**
* 视频页面
* 包含视频基本信息, 推荐和广告
*
* @param aid 视频的唯一标识
*/
@Suppress("SpellCheckingInspection")
@GET("/x/v2/view")
fun view(
@Query("ad_extra") adExtra: String? = null,
@Query("aid") aid: Long,
@Query("autoplay") autoplay: Int = 0,
@Query("fnval") fnVal: Int = 16,
@Query("fnver") fnVer: Int = 0,
@Query("force_host") forceHost: Int = 0,
@Query("from") from: Int? = null,
@Query("plat") plat: Int = 0,
@Query("qn") qn: Int = 32,
@Query("trackid") trackId: String? = null //all_10.shylf-ai-recsys-120.1550674524909.237
): Deferred<View>
//TODO 这里的 appkey 变为 iVGUTjsxvpLeuDCf
/**
* 获得视频的播放地址
*
* @param expire 默认为下个月的这一天的时间戳
* @param mid 当前用户 ID
* @param cid view() 接口的返回值里
* @param aid 视频的唯一标识
*/
@Suppress("SpellCheckingInspection")
@GET("/x/playurl")
fun playUrl(
@Query("device") device: String = "android",
@Query("expire") expire: Long = Calendar.getInstance().apply { add(Calendar.MONTH, 1) }.toInstant().epochSecond,
@Query("force_host") forceHost: Int = 0,
@Query("mid") mid: Long? = null,
@Query("fnval") fnVal: Int = 16,
@Query("qn") qn: Int = 32,
@Query("npcybs") npcybs: Int = 0,
@Query("cid") cid: Long? = null,
@Query("otype") otype: String = "json",
@Query("fnver") fnVer: Int = 0,
@Query("buvid") buildVersionId: String? = null,
@Query("aid") aid: Long
): Deferred<PlayUrl>
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.app.model
import com.google.gson.annotations.SerializedName
data class IndexPage(
data class HomePage(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")

View File

@ -0,0 +1,80 @@
package com.hiczp.bilibili.api.app.model
import com.google.gson.annotations.SerializedName
data class PlayUrl(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // 0
@SerializedName("ttl")
var ttl: Int // 1
) {
data class Data(
@SerializedName("accept_description")
var acceptDescription: List<String>,
@SerializedName("accept_format")
var acceptFormat: String, // flv720,flv480,flv360
@SerializedName("accept_quality")
var acceptQuality: List<Int>,
@SerializedName("dash")
var dash: Dash,
@SerializedName("fnval")
var fnval: Int, // 16
@SerializedName("fnver")
var fnver: Int, // 0
@SerializedName("format")
var format: String, // flv480
@SerializedName("from")
var from: String, // local
@SerializedName("quality")
var quality: Int, // 32
@SerializedName("result")
var result: String, // suee
@SerializedName("seek_param")
var seekParam: String, // start
@SerializedName("seek_type")
var seekType: String, // offset
@SerializedName("timelength")
var timelength: Int, // 443737
@SerializedName("video_codecid")
var videoCodecid: Int, // 7
@SerializedName("video_project")
var videoProject: Boolean // true
) {
data class Dash(
@SerializedName("audio")
var audio: List<Audio>,
@SerializedName("video")
var video: List<Video>
) {
data class Video(
@SerializedName("backup_url")
var backupUrl: List<String>,
@SerializedName("bandwidth")
var bandwidth: Int, // 980114
@SerializedName("base_url")
var baseUrl: String, // http://112.13.92.195/upgcxcode/86/69/77356986/77356986-1-30064.m4s?expires=1550682900&platform=android&ssig=vLwE2fl303BrUu1wF1grNQ&oi=3670888805&trid=cf1bde09d63149168c0a0a997a3757d8&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
@SerializedName("codecid")
var codecid: Int, // 7
@SerializedName("id")
var id: Int // 64
)
data class Audio(
@SerializedName("backup_url")
var backupUrl: List<String>,
@SerializedName("bandwidth")
var bandwidth: Int, // 67125
@SerializedName("base_url")
var baseUrl: String, // http://117.148.189.5/upgcxcode/86/69/77356986/77356986-1-30216.m4s?expires=1550682900&platform=android&ssig=LlSJk_i74xGEjSOwmjUYzA&oi=3670888805&trid=cf1bde09d63149168c0a0a997a3757d8&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
@SerializedName("codecid")
var codecid: Int, // 0
@SerializedName("id")
var id: Int // 30216
)
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,446 @@
package com.hiczp.bilibili.api.app.model
import com.google.gson.JsonElement
import com.google.gson.annotations.SerializedName
data class View(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // 0
@SerializedName("ttl")
var ttl: Int // 1
) {
data class Data(
@SerializedName("aid")
var aid: Int, // 44172743
@SerializedName("attribute")
var attribute: Int, // 16512
@SerializedName("cid")
var cid: Int, // 77356986
@SerializedName("cm_config")
var cmConfig: CmConfig,
@SerializedName("cms")
var cms: List<Cm>,
@SerializedName("copyright")
var copyright: Int, // 1
@SerializedName("ctime")
var ctime: Int, // 1550654012
@SerializedName("desc")
var desc: String,
@SerializedName("dimension")
var dimension: Dimension,
@SerializedName("dislike_reasons")
var dislikeReasons: List<DislikeReason>,
@SerializedName("dm_seg")
var dmSeg: Int, // 1
@SerializedName("duration")
var duration: Int, // 444
@SerializedName("dynamic")
var `dynamic`: String, // #流浪地球##木星##太阳#
@SerializedName("elec")
var elec: Elec,
@SerializedName("owner")
var owner: Owner,
@SerializedName("owner_ext")
var ownerExt: OwnerExt,
@SerializedName("pages")
var pages: List<Page>,
@SerializedName("pic")
var pic: String, // http://i0.hdslb.com/bfs/archive/783445f04541299ee84de21a2479cce88d8268ff.jpg
@SerializedName("pubdate")
var pubdate: Int, // 1550654012
@SerializedName("relates")
var relates: List<Relate>,
@SerializedName("req_user")
var reqUser: ReqUser,
@SerializedName("rights")
var rights: Rights,
@SerializedName("staff")
var staff: List<Staff>,
@SerializedName("stat")
var stat: Stat,
@SerializedName("state")
var state: Int, // 0
@SerializedName("tag")
var tag: List<Tag>,
@SerializedName("tid")
var tid: Int, // 96
@SerializedName("title")
var title: String, // 模拟流浪地球进入木星的洛希极限,太阳要膨胀吞没地球这事是真的吗?
@SerializedName("tname")
var tname: String, // 星海
@SerializedName("videos")
var videos: Int // 1
) {
data class Cm(
@SerializedName("ad_info")
var adInfo: JsonElement, // {}
@SerializedName("client_ip")
var clientIp: String, // 218.205.81.101
@SerializedName("index")
var index: Int, // 1
@SerializedName("is_ad_loc")
var isAdLoc: Boolean, // true
@SerializedName("request_id")
var requestId: String, // 1550675871470q172a22a56a79q738
@SerializedName("rsc_id")
var rscId: Int, // 2337
@SerializedName("src_id")
var srcId: Int // 2338
)
data class Owner(
@SerializedName("face")
var face: String, // http://i1.hdslb.com/bfs/face/9a586d1ef659b322af150c925976a134ad046a74.jpg
@SerializedName("mid")
var mid: Int, // 393484294
@SerializedName("name")
var name: String // 娱乐酱鸭
)
data class Elec(
@SerializedName("elec_set")
var elecSet: ElecSet,
@SerializedName("list")
var list: List<Any>,
@SerializedName("show")
var show: Boolean // true
) {
data class ElecSet(
@SerializedName("elec_list")
var elecList: List<Elec>,
@SerializedName("elec_theme")
var elecTheme: Int, // 0
@SerializedName("integrity_rate")
var integrityRate: Double, // 10.0
@SerializedName("rmb_rate")
var rmbRate: Double, // 10.0
@SerializedName("round_mode")
var roundMode: Int // 0
) {
data class Elec(
@SerializedName("elec_num")
var elecNum: Int, // 0
@SerializedName("is_customize")
var isCustomize: Int, // 1
@SerializedName("max_elec")
var maxElec: Int, // 99999
@SerializedName("min_elec")
var minElec: Int, // 20
@SerializedName("title")
var title: String // 自定义
)
}
}
data class ReqUser(
@SerializedName("attention")
var attention: Int, // -999
@SerializedName("coin")
var coin: Int, // 0
@SerializedName("dislike")
var dislike: Int, // 0
@SerializedName("favorite")
var favorite: Int, // 0
@SerializedName("like")
var like: Int // 0
)
data class Stat(
@SerializedName("aid")
var aid: Int, // 44172743
@SerializedName("coin")
var coin: Int, // 23
@SerializedName("danmaku")
var danmaku: Int, // 19
@SerializedName("dislike")
var dislike: Int, // 0
@SerializedName("favorite")
var favorite: Int, // 10
@SerializedName("his_rank")
var hisRank: Int, // 0
@SerializedName("like")
var like: Int, // 35
@SerializedName("now_rank")
var nowRank: Int, // 0
@SerializedName("reply")
var reply: Int, // 11
@SerializedName("share")
var share: Int, // 0
@SerializedName("view")
var view: Int // 1995
)
data class OwnerExt(
@SerializedName("assists")
var assists: Any?, // null
@SerializedName("fans")
var fans: Int, // 275
@SerializedName("official_verify")
var officialVerify: OfficialVerify,
@SerializedName("vip")
var vip: Vip
) {
data class OfficialVerify(
@SerializedName("desc")
var desc: String,
@SerializedName("type")
var type: Int // -1
)
data class Vip(
@SerializedName("accessStatus")
var accessStatus: Int, // 0
@SerializedName("dueRemark")
var dueRemark: String,
@SerializedName("vipDueDate")
var vipDueDate: Int, // 0
@SerializedName("vipStatus")
var vipStatus: Int, // 0
@SerializedName("vipStatusWarn")
var vipStatusWarn: String,
@SerializedName("vipType")
var vipType: Int // 0
)
}
data class Tag(
@SerializedName("attribute")
var attribute: Int, // 0
@SerializedName("cover")
var cover: String,
@SerializedName("hated")
var hated: Int, // 0
@SerializedName("hates")
var hates: Int, // 0
@SerializedName("is_activity")
var isActivity: Int, // 0
@SerializedName("liked")
var liked: Int, // 0
@SerializedName("likes")
var likes: Int, // 0
@SerializedName("tag_id")
var tagId: Int, // 7534
@SerializedName("tag_name")
var tagName: String // 未来
)
data class Staff(
@SerializedName("attention")
var attention: Int, // 0
@SerializedName("face")
var face: String, // http://i1.hdslb.com/bfs/face/9a586d1ef659b322af150c925976a134ad046a74.jpg
@SerializedName("mid")
var mid: Int, // 393484294
@SerializedName("name")
var name: String, // 娱乐酱鸭
@SerializedName("official_verify")
var officialVerify: OfficialVerify,
@SerializedName("title")
var title: String, // UP主
@SerializedName("vip")
var vip: Vip
) {
data class OfficialVerify(
@SerializedName("desc")
var desc: String,
@SerializedName("type")
var type: Int // -1
)
data class Vip(
@SerializedName("accessStatus")
var accessStatus: Int, // 0
@SerializedName("dueRemark")
var dueRemark: String,
@SerializedName("vipDueDate")
var vipDueDate: Int, // 0
@SerializedName("vipStatus")
var vipStatus: Int, // 0
@SerializedName("vipStatusWarn")
var vipStatusWarn: String,
@SerializedName("vipType")
var vipType: Int // 0
)
}
data class DislikeReason(
@SerializedName("reason_id")
var reasonId: Int, // 8
@SerializedName("reason_name")
var reasonName: String // 营销广告
)
data class Relate(
@SerializedName("ad_index")
var adIndex: Int, // 2
@SerializedName("aid")
var aid: Int, // 38496110
@SerializedName("card_index")
var cardIndex: Int, // 3
@SerializedName("cid")
var cid: Int, // 67669037
@SerializedName("client_ip")
var clientIp: String, // 218.205.81.101
@SerializedName("duration")
var duration: Int, // 189
@SerializedName("goto")
var goto: String, // av
@SerializedName("is_ad_loc")
var isAdLoc: Boolean, // true
@SerializedName("owner")
var owner: Owner,
@SerializedName("param")
var `param`: String, // 38496110
@SerializedName("pic")
var pic: String, // http://i2.hdslb.com/bfs/archive/ca80fb7c554e083716feb910370b77caa5e124b3.jpg
@SerializedName("request_id")
var requestId: String, // 1550675871470q172a22a56a79q738
@SerializedName("src_id")
var srcId: Int, // 2334
@SerializedName("stat")
var stat: Stat,
@SerializedName("title")
var title: String, // 《流浪地球》发布创想特辑,从无到有呈现刘慈欣科幻想象
@SerializedName("trackid")
var trackid: String, // related_0.shylf-ai-recsys-87.1550675871470.909
@SerializedName("uri")
var uri: String // bilibili://video/38496110?player_width=1920&player_height=1080&player_rotate=0&trackid=related_0.shylf-ai-recsys-87.1550675871470.909
) {
data class Owner(
@SerializedName("face")
var face: String, // http://static.hdslb.com/images/member/noface.gif
@SerializedName("mid")
var mid: Int, // 334512441
@SerializedName("name")
var name: String // 达岸电影2018
)
data class Stat(
@SerializedName("aid")
var aid: Int, // 38496110
@SerializedName("coin")
var coin: Int, // 130
@SerializedName("danmaku")
var danmaku: Int, // 152
@SerializedName("dislike")
var dislike: Int, // 0
@SerializedName("favorite")
var favorite: Int, // 194
@SerializedName("his_rank")
var hisRank: Int, // 0
@SerializedName("like")
var like: Int, // 341
@SerializedName("now_rank")
var nowRank: Int, // 0
@SerializedName("reply")
var reply: Int, // 264
@SerializedName("share")
var share: Int, // 278
@SerializedName("view")
var view: Int // 19397
)
}
data class Page(
@SerializedName("cid")
var cid: Int, // 77356986
@SerializedName("dimension")
var dimension: Dimension,
@SerializedName("dm")
var dm: Dm,
@SerializedName("dmlink")
var dmlink: String, // http://comment.bilibili.com/77356986.xml
@SerializedName("duration")
var duration: Int, // 444
@SerializedName("from")
var from: String, // vupload
@SerializedName("metas")
var metas: List<Meta>,
@SerializedName("page")
var page: Int, // 1
@SerializedName("part")
var part: String, // 2.20.2
@SerializedName("vid")
var vid: String,
@SerializedName("weblink")
var weblink: String
) {
data class Dm(
@SerializedName("closed")
var closed: Boolean, // false
@SerializedName("count")
var count: Int, // 19
@SerializedName("mask")
var mask: JsonElement, // {}
@SerializedName("real_name")
var realName: Boolean, // false
@SerializedName("subtitles")
var subtitles: Any? // null
)
data class Dimension(
@SerializedName("height")
var height: Int, // 720
@SerializedName("rotate")
var rotate: Int, // 0
@SerializedName("width")
var width: Int // 1280
)
data class Meta(
@SerializedName("format")
var format: String,
@SerializedName("quality")
var quality: Int, // 48
@SerializedName("size")
var size: Int // 81074
)
}
data class Rights(
@SerializedName("autoplay")
var autoplay: Int, // 1
@SerializedName("bp")
var bp: Int, // 0
@SerializedName("download")
var download: Int, // 1
@SerializedName("elec")
var elec: Int, // 1
@SerializedName("hd5")
var hd5: Int, // 0
@SerializedName("is_cooperation")
var isCooperation: Int, // 0
@SerializedName("movie")
var movie: Int, // 0
@SerializedName("no_reprint")
var noReprint: Int, // 1
@SerializedName("pay")
var pay: Int, // 0
@SerializedName("ugc_pay")
var ugcPay: Int // 0
)
data class Dimension(
@SerializedName("height")
var height: Int, // 720
@SerializedName("rotate")
var rotate: Int, // 0
@SerializedName("width")
var width: Int // 1280
)
data class CmConfig(
@SerializedName("ads_control")
var adsControl: AdsControl
) {
data class AdsControl(
@SerializedName("has_danmu")
var hasDanmu: Int // 0
)
}
}
}

View File

@ -0,0 +1,18 @@
package com.hiczp.bilibili.api.member
import com.hiczp.bilibili.api.member.model.Pre
import kotlinx.coroutines.Deferred
import retrofit2.http.GET
/**
* 创作中心
*/
@Suppress("DeferredIsResult")
interface MemberAPI {
/**
* 刚登陆时会访问该 API, 使用返回的 url 来创建一个指向一系列 H5 页面的 ListView
* 侧拉抽屉 -> 创作中心 -> 更多功能
*/
@GET("/x/app/pre")
fun pre(): Deferred<Pre>
}

View File

@ -0,0 +1,78 @@
package com.hiczp.bilibili.api.member.model
import com.google.gson.annotations.SerializedName
data class Pre(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // 0
@SerializedName("ttl")
var ttl: Int // 1
) {
data class Data(
@SerializedName("academy")
var academy: Academy,
@SerializedName("act")
var act: Act,
@SerializedName("creative")
var creative: Creative,
@SerializedName("entrance")
var entrance: Entrance
) {
data class Entrance(
@SerializedName("guidance")
var guidance: String, // 投稿
@SerializedName("show")
var show: Int // 1
)
data class Creative(
@SerializedName("portal_list")
var portalList: List<Portal>,
@SerializedName("show")
var show: Int // 1
) {
data class Portal(
@SerializedName("icon")
var icon: String, // http://i0.hdslb.com/bfs/archive/31f485451e415bbbc59407f1fddce8f317db6287.png
@SerializedName("id")
var id: Int, // 0
@SerializedName("more")
var more: Int, // 0
@SerializedName("mtime")
var mtime: Int, // 1547466050
@SerializedName("new")
var new: Int, // 1
@SerializedName("position")
var position: Int, // 8
@SerializedName("subtitle")
var subtitle: String,
@SerializedName("title")
var title: String, // 更多功能
@SerializedName("url")
var url: String // activity://uper/user_center/more_portal
)
}
data class Act(
@SerializedName("show")
var show: Int, // 1
@SerializedName("title")
var title: String, // 热门活动
@SerializedName("url")
var url: String // https://www.bilibili.com/blackboard/x/activity-tougao-h5/all
)
data class Academy(
@SerializedName("show")
var show: Int, // 0
@SerializedName("title")
var title: String,
@SerializedName("url")
var url: String
)
}
}