From a0e19cbb428622f086249f34ac43737ebd4b6fa9 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 2 Mar 2018 17:44:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=80=E4=B8=AA=20Web=20AP?= =?UTF-8?q?I(=E5=8F=91=E9=80=81=E7=9B=B4=E6=92=AD=E9=97=B4=E5=BF=83?= =?UTF-8?q?=E8=B7=B3=E5=8C=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../com/hiczp/bilibili/api/BilibiliAPI.java | 17 +++- .../api/provider/BilibiliWebAPIProvider.java | 9 ++ .../{ => provider}/LiveClientProvider.java | 2 +- .../bilibili/api/web/BilibiliWebAPI.java | 74 +++++++++++++++ .../bilibili/api/web/BrowserProperties.java | 22 +++++ .../api/web/cookie/SimpleCookieJar.java | 7 ++ .../bilibili/api/web/live/LiveService.java | 18 ++++ .../entity/SendHeartBeatResponseEntity.java | 92 +++++++++++++++++++ 9 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java rename src/main/java/com/hiczp/bilibili/api/{ => provider}/LiveClientProvider.java (77%) create mode 100644 src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java diff --git a/README.md b/README.md index 56ff7d8..050b5ae 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 由于B站即使更新客户端, 也会继续兼容以前的旧版本客户端, 所以短期内不用担心 API 失效的问题. -对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#SSO), 然后再去调用 Bilibili Web API. +对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#sso), 然后再去调用 Bilibili Web API. # API 不完全 由于本项目还在开发初期, 大量 API 没有完成, 所以很可能没有你想要的 API. diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 22fc167..1f721a7 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -11,9 +11,9 @@ import com.hiczp.bilibili.api.passport.entity.LoginResponseEntity; import com.hiczp.bilibili.api.passport.entity.LogoutResponseEntity; import com.hiczp.bilibili.api.passport.entity.RefreshTokenResponseEntity; import com.hiczp.bilibili.api.passport.exception.CaptchaMismatchException; -import com.hiczp.bilibili.api.provider.BilibiliCaptchaProvider; -import com.hiczp.bilibili.api.provider.BilibiliServiceProvider; -import com.hiczp.bilibili.api.provider.BilibiliSsoProvider; +import com.hiczp.bilibili.api.provider.*; +import com.hiczp.bilibili.api.web.BilibiliWebAPI; +import com.hiczp.bilibili.api.web.BrowserProperties; import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; @@ -33,7 +33,7 @@ import java.util.Date; import java.util.List; import java.util.Map; -public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProvider, BilibiliSsoProvider, LiveClientProvider { +public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProvider, BilibiliSsoProvider, BilibiliWebAPIProvider, LiveClientProvider { private static final Logger LOGGER = LoggerFactory.getLogger(BilibiliAPI.class); private final Long apiInitTime = Instant.now().getEpochSecond(); //记录当前类被实例化的时间 @@ -250,6 +250,15 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv return simpleCookieJar.getCookiesMap(); } + @Override + public BilibiliWebAPI getBilibiliWebAPI() throws IOException { + return new BilibiliWebAPI(toCookies()); + } + + public BilibiliWebAPI getBilibiliWebAPI(BrowserProperties browserProperties) throws IOException { + return new BilibiliWebAPI(browserProperties, toCookies()); + } + public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException { return login(username, password, null, null); } diff --git a/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java new file mode 100644 index 0000000..d4b33b1 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.provider; + +import com.hiczp.bilibili.api.web.BilibiliWebAPI; + +import java.io.IOException; + +public interface BilibiliWebAPIProvider { + BilibiliWebAPI getBilibiliWebAPI() throws IOException; +} diff --git a/src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java similarity index 77% rename from src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java rename to src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java index d623873..b1935a0 100644 --- a/src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java +++ b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java @@ -1,4 +1,4 @@ -package com.hiczp.bilibili.api; +package com.hiczp.bilibili.api.provider; import com.hiczp.bilibili.api.live.socket.LiveClient; diff --git a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java new file mode 100644 index 0000000..d5a6f89 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java @@ -0,0 +1,74 @@ +package com.hiczp.bilibili.api.web; + +import com.hiczp.bilibili.api.BaseUrlDefinition; +import com.hiczp.bilibili.api.interceptor.AddFixedHeadersInterceptor; +import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar; +import com.hiczp.bilibili.api.web.live.LiveService; +import okhttp3.Cookie; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class BilibiliWebAPI { + private final BrowserProperties browserProperties; + private final SimpleCookieJar simpleCookieJar; + + private LiveService liveService; + + public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar simpleCookieJar) { + this.browserProperties = browserProperties; + this.simpleCookieJar = simpleCookieJar; + } + + public BilibiliWebAPI(SimpleCookieJar simpleCookieJar) { + this(BrowserProperties.defaultSetting(), simpleCookieJar); + } + + public BilibiliWebAPI(BrowserProperties browserProperties, Map> cookiesMap) { + this(browserProperties, new SimpleCookieJar(cookiesMap)); + } + + public BilibiliWebAPI(Map> cookiesMap) { + this(BrowserProperties.defaultSetting(), new SimpleCookieJar(cookiesMap)); + } + + public LiveService getLiveService() { + if (liveService == null) { + liveService = getLiveService(Collections.emptyList(), HttpLoggingInterceptor.Level.BASIC); + } + return liveService; + } + + public LiveService getLiveService(@Nonnull List interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) { + OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); + + okHttpClientBuilder + .cookieJar(simpleCookieJar) + .addInterceptor(new AddFixedHeadersInterceptor( + "User-Agent", browserProperties.getUserAgent() + )); + + interceptors.forEach(okHttpClientBuilder::addInterceptor); + + okHttpClientBuilder + .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(logLevel)); + + return new Retrofit.Builder() + .baseUrl(BaseUrlDefinition.LIVE) + .addConverterFactory(GsonConverterFactory.create()) + .client(okHttpClientBuilder.build()) + .build() + .create(LiveService.class); + } + + public SimpleCookieJar getSimpleCookieJar() { + return simpleCookieJar; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java b/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java new file mode 100644 index 0000000..2705f98 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java @@ -0,0 +1,22 @@ +package com.hiczp.bilibili.api.web; + +public class BrowserProperties { + private String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"; + + private BrowserProperties() { + + } + + public static BrowserProperties defaultSetting() { + return new BrowserProperties(); + } + + public String getUserAgent() { + return userAgent; + } + + public BrowserProperties setUserAgent(String userAgent) { + this.userAgent = userAgent; + return this; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java index af2bf80..7c29070 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java +++ b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class SimpleCookieJar implements CookieJar { private Map> cookiesMap; @@ -61,6 +62,12 @@ public class SimpleCookieJar implements CookieJar { return cookieList; } + public String getCookiesStringForHost(String host) { + return getCookiesForHost(host).stream() + .map(cookie -> String.format("%s=%s", cookie.name(), cookie.value())) + .collect(Collectors.joining(";")); + } + public Map> getCookiesMap() { return cookiesMap; } diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java new file mode 100644 index 0000000..def0680 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java @@ -0,0 +1,18 @@ +package com.hiczp.bilibili.api.web.live; + +import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface LiveService { + //直播间心跳包 + //参数为时间戳(不是 unix 时间戳) + //未登录时返回 401 + @GET("feed/v1/feed/heartBeat") + Call sendHeartBeat(@Query("_") long timestamp); + + default Call sendHeartBeat() { + return sendHeartBeat(System.currentTimeMillis()); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java new file mode 100644 index 0000000..df95cde --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java @@ -0,0 +1,92 @@ +package com.hiczp.bilibili.api.web.live.entity; + +import com.google.gson.annotations.SerializedName; + +public class SendHeartBeatResponseEntity { + /** + * code : 0 + * msg : success + * message : success + * data : {"open":1,"has_new":0,"count":0} + */ + + @SerializedName("code") + private int code; + @SerializedName("msg") + private String msg; + @SerializedName("message") + private String message; + @SerializedName("data") + private Data data; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Data getData() { + return data; + } + + public void setData(Data data) { + this.data = data; + } + + public static class Data { + /** + * open : 1 + * has_new : 0 + * count : 0 + */ + + @SerializedName("open") + private int open; + @SerializedName("has_new") + private int hasNew; + @SerializedName("count") + private int count; + + public int getOpen() { + return open; + } + + public void setOpen(int open) { + this.open = open; + } + + public int getHasNew() { + return hasNew; + } + + public void setHasNew(int hasNew) { + this.hasNew = hasNew; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + } +}