From ceaed6a5dc27638cf0c693ffbb7338f57d287b44 Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Sat, 22 Jan 2022 20:11:40 +0800 Subject: [PATCH] add a tool --- .../myreader/ui/activity/AboutActivity.java | 36 ++++++ .../xyz/fycz/myreader/webapi/LanZouApi.kt | 114 ++++++++++++++++++ .../main/res/layout/layout_about_content.xml | 29 +++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 180 insertions(+) create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java index 7cc3fc7..96fb8b5 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java @@ -3,9 +3,12 @@ package xyz.fycz.myreader.ui.activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; +import android.view.View; +import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import org.jetbrains.annotations.NotNull; @@ -33,6 +36,7 @@ import xyz.fycz.myreader.util.utils.FileUtils; import xyz.fycz.myreader.util.utils.ImageLoader; import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.RxUtils; +import xyz.fycz.myreader.webapi.LanZouApi; /** * @author fengyue @@ -59,6 +63,7 @@ public class AboutActivity extends BaseActivity { protected void initWidget() { super.initWidget(); binding.il.tvVersionName.setText(String.format("风月读书v%s", App.getStrVersionName())); + binding.il.rlLanZou.setVisibility(App.isDebug() ? View.VISIBLE : View.GONE); } @Override @@ -110,6 +115,37 @@ public class AboutActivity extends BaseActivity { .showFullWebViewDia(this, "file:///android_asset/PrivacyPolicy.html", false, null)); binding.il.rlDisclaimer.setOnClickListener(v -> DialogCreator.createAssetTipDialog(this, "免责声明", "disclaimer.fy")); + binding.il.rlLanZou.setOnClickListener(v -> { + String[] str = new String[1]; + MyAlertDialog.createInputDia(this, getString(R.string.lan_zou_parse), + "格式:链接+逗号+密码(没有密码就不用填)", "", true, + 100, text -> str[0] = text, (dialog, which) -> { + String url, pwd = ""; + if (str[0].contains(",") || str[0].contains(",")) { + String[] strs = str[0].split("[,,]"); + url = strs[0]; + pwd = strs[1]; + } else { + url = str[0]; + } + LanZouApi.INSTANCE.getUrl(url, pwd) + .compose(RxUtils::toSimpleSingle) + .subscribe(new MyObserver() { + @Override + public void onNext(@NonNull String s) { + ToastUtils.showInfo(s); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(s)); + startActivity(intent); + } + + @Override + public void onError(Throwable e) { + ToastUtils.showError("" + e.getLocalizedMessage()); + } + }); + }); + }); } void openIntent(String intentName, String address) { diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt new file mode 100644 index 0000000..6cf823e --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt @@ -0,0 +1,114 @@ +package xyz.fycz.myreader.webapi + +import io.reactivex.Observable +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.RequestBody.Companion.toRequestBody +import org.jsoup.Jsoup +import xyz.fycz.myreader.common.URLCONST +import xyz.fycz.myreader.util.help.StringHelper +import xyz.fycz.myreader.util.utils.OkHttpUtils +import java.net.HttpURLConnection +import java.net.URL +import java.util.* + +/** + * @author fengyue + * @date 2022/1/22 18:50 + */ +object LanZouApi { + /** + * 通过api获取蓝奏云可下载直链 + * + * @param url + * @param password + */ + fun getUrl(url: String, password: String = ""): Observable { + return Observable.create { + val html = OkHttpUtils.getHtml(url) + val url2 = if (password.isEmpty()) { + val url1 = getUrl1(html) + val key = getKey(OkHttpUtils.getHtml(url1)) + getUrl2(key, url1) + } else { + getUrl2(StringHelper.getSubString(html, "sign=", "&"), url, password) + } + it.onNext(getRedirectUrl(url2)) + it.onComplete() + } + } + + private fun getUrl1(html: String): String { + val doc = Jsoup.parse(html) + return URLCONST.LAN_ZOUS_URL + doc.getElementsByClass("ifr2").attr("src") + } + + private fun getKey(html: String): String { + var lanzousKeyStart = "var pposturl = '" + val keyName = StringHelper.getSubString(html, "'sign':", ",") + lanzousKeyStart = if (keyName.endsWith("'")) { + "'sign':'" + } else { + "var $keyName = '" + } + return StringHelper.getSubString(html, lanzousKeyStart, "'") + } + + + private fun getUrl2(key: String, referer: String, password: String = ""): String { + val mediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull() + val body = if (password.isEmpty()) { + "action=downprocess&sign=$key&ves=1" + } else { + "action=downprocess&sign=$key&p=$password" + } + val requestBody = body.toRequestBody(mediaType) + + val headers = HashMap() + headers["Referer"] = referer + + val html = OkHttpUtils.getHtml( + URLCONST.LAN_ZOUS_URL + "/ajaxm.php", requestBody, + "UTF-8", headers + ) + return getUrl2(html) + } + + private fun getUrl2(o: String): String { + val info = o.split(",").toTypedArray() + val zt = info[0].substring(info[0].indexOf(":") + 1) + if (!"1".endsWith(zt)) { + return "" + } + var dom = info[1].substring(info[1].indexOf(":") + 2, info[1].lastIndexOf("\"")) + var url = info[2].substring(info[2].indexOf(":") + 2, info[2].lastIndexOf("\"")) + dom = dom.replace("\\", "") + url = url.replace("\\", "") + return "$dom/file/$url" + } + + /** + * 获取重定向地址 + * + * @param path + */ + private fun getRedirectUrl(path: String): String { + val conn = URL(path) + .openConnection() as HttpURLConnection + conn.instanceFollowRedirects = false + conn.connectTimeout = 5000 + conn.setRequestProperty( + "User-Agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" + ) + conn.setRequestProperty("Accept-Language", "zh-cn") + conn.setRequestProperty("Connection", "Keep-Alive") + conn.setRequestProperty( + "Accept", + "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, */*" + ) + conn.connect() + val redirectUrl = conn.getHeaderField("Location") + conn.disconnect() + return redirectUrl + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/layout_about_content.xml b/app/src/main/res/layout/layout_about_content.xml index bdaa5ed..4d6f9d8 100644 --- a/app/src/main/res/layout/layout_about_content.xml +++ b/app/src/main/res/layout/layout_about_content.xml @@ -333,6 +333,35 @@ app:srcCompat="@drawable/ic_right_arrow" app:tint="@color/textSecondary" /> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9ad6e38..e078713 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -542,6 +542,7 @@ 网络连接超时 数据解析失败 拷贝书源 + 蓝奏云直链解析