master
fengyuecanzhu 3 years ago
parent 299f4bc366
commit 974d522dd5
  1. 5
      .github/workflows/reader.yml
  2. 6
      .idea/misc.xml
  3. 4
      DialogX/build.gradle
  4. 8
      app/src/main/AndroidManifest.xml
  5. 5
      app/src/main/assets/updatelog.fy
  6. 9
      app/src/main/java/xyz/fycz/myreader/entity/thirdsource/BookSource3Bean.java
  7. 39
      app/src/main/java/xyz/fycz/myreader/entity/thirdsource/ExploreKind.kt
  8. 4
      app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java
  9. 29
      app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java
  10. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java
  11. 8
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookstoreActivity.java
  12. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java
  13. 8
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReadRecordActivity.java
  14. 2
      app/src/main/java/xyz/fycz/myreader/ui/adapter/FileSystemAdapter.java
  15. 8
      app/src/main/java/xyz/fycz/myreader/ui/adapter/FontsAdapter.java
  16. 9
      app/src/main/java/xyz/fycz/myreader/ui/dialog/SourceExchangeDialog.java
  17. 60
      app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java
  18. 14
      app/src/main/java/xyz/fycz/myreader/util/UriFileUtil.java
  19. 1
      app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java
  20. 2
      app/src/main/java/xyz/fycz/myreader/util/utils/FileUtils.java
  21. 2
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/base/BaseReadCrawler.java
  22. 1
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/base/ReadCrawler.java
  23. 14
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/source/find/ThirdFindCrawler.java

@ -83,11 +83,6 @@ jobs:
echo "上传APP至蓝奏云" echo "上传APP至蓝奏云"
python3 $GITHUB_WORKSPACE/keystore/scripts/lzy.py "${{ steps.get_path.outputs.file_path }}" "${{ steps.config.outputs.lanzou_folder_id }}" python3 $GITHUB_WORKSPACE/keystore/scripts/lzy.py "${{ steps.get_path.outputs.file_path }}" "${{ steps.config.outputs.lanzou_folder_id }}"
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: ${{ steps.config.outputs.lanzou_share_url }}" echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: ${{ steps.config.outputs.lanzou_share_url }}"
- name: Upload App To Team
run: |
echo "上传APP至官网"
python3 $GITHUB_WORKSPACE/keystore/scripts/team.py "$GITHUB_WORKSPACE" "${{ steps.get_path.outputs.file_path }}" "${{ steps.config.outputs.need_create_release }}"
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 官网链接:https://reader.fycz.tk/"
- name: Create Release - name: Create Release
id: create_release id: create_release
if: ${{ steps.config.outputs.need_create_release == 'true' }} if: ${{ steps.config.outputs.need_create_release == 'true' }}

@ -6,10 +6,13 @@
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_re_seg.xml" value="0.1962962962962963" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_re_seg.xml" value="0.1962962962962963" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_about.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_about.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_donate.xml" value="0.536" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_donate.xml" value="0.536" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_feedback.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_file_picker.xml" value="0.2318840579710145" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_group_manager.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_group_manager.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_manage_group.xml" value="0.21195652173913043" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_manage_group.xml" value="0.21195652173913043" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_more_setting.xml" value="0.264" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_more_setting.xml" value="0.264" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fingerprint_dialog.xml" value="0.20425724637681159" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fingerprint_dialog.xml" value="0.20425724637681159" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_file_category.xml" value="0.2318840579710145" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_private_bookcase.xml" value="0.21195652173913043" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_private_bookcase.xml" value="0.21195652173913043" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_webdav_setting.xml" value="0.4" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_webdav_setting.xml" value="0.4" />
@ -26,6 +29,9 @@
</map> </map>
</option> </option>
</component> </component>
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>

@ -7,11 +7,11 @@ def gitUrl = 'https://github.com/kongzue/DialogX.git' //Git仓库的地址
group = "com.kongzue.dialogx" group = "com.kongzue.dialogx"
android { android {
compileSdkVersion 30 compileSdkVersion 29
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 29
versionCode 10 versionCode 10
versionName "1.0" versionName "1.0"

@ -61,7 +61,6 @@
android:resource="@xml/shortcuts" /> android:resource="@xml/shortcuts" />
</activity> </activity>
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"
@ -88,8 +87,9 @@
<intent-filter tools:ignore="AppLinkUrlError"> <intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" /> <data android:mimeType="text/plain" />
<data android:mimeType="application/epub+zip"/> <data android:mimeType="application/epub+zip" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ui.activity.FontsActivity" /> <activity android:name=".ui.activity.FontsActivity" />
@ -110,7 +110,9 @@
<activity android:name=".ui.activity.MoreSettingActivity" /> <activity android:name=".ui.activity.MoreSettingActivity" />
<activity android:name=".ui.activity.BookstoreActivity" /> <activity android:name=".ui.activity.BookstoreActivity" />
<activity android:name=".ui.activity.QRCodeScanActivity" /> <activity android:name=".ui.activity.QRCodeScanActivity" />
<activity android:name=".ui.activity.BookSourceActivity" /> <activity
android:name=".ui.activity.BookSourceActivity"
android:exported="true" />
<activity android:name=".ui.activity.SourceEditActivity" /> <activity android:name=".ui.activity.SourceEditActivity" />
<activity android:name=".ui.activity.SourceDebugActivity" /> <activity android:name=".ui.activity.SourceDebugActivity" />
<activity android:name=".ui.activity.AdSettingActivity" /> <activity android:name=".ui.activity.AdSettingActivity" />

@ -1,3 +1,8 @@
风月读书v2.2.1
更新内容:
1、修复切换书源对话框内存泄漏的问题
2、优化导入书源选择
风月读书v2.2.0 风月读书v2.2.0
更新内容: 更新内容:
1、修复从书籍详情页进入阅读后切换日夜模式闪退的bug 1、修复从书籍详情页进入阅读后切换日夜模式闪退的bug

@ -1,11 +1,15 @@
package xyz.fycz.myreader.entity.thirdsource; package xyz.fycz.myreader.entity.thirdsource;
import android.text.TextUtils;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import kotlin.jvm.Transient; import kotlin.jvm.Transient;
import xyz.fycz.myreader.util.utils.GsonUtils;
import xyz.fycz.myreader.util.utils.StringUtils;
// 解析阅读3.0的书源规则,toBookSourceBean()方法转换为阅读2.0书源规则 // 解析阅读3.0的书源规则,toBookSourceBean()方法转换为阅读2.0书源规则
// https://raw.githubusercontent.com/gedoor/legado/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt // https://raw.githubusercontent.com/gedoor/legado/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt
@ -215,6 +219,9 @@ public class BookSource3Bean {
header="@Header:"+this.header.replaceAll("\\n"," "); header="@Header:"+this.header.replaceAll("\\n"," ");
} }
if (!TextUtils.isEmpty(ruleFindUrl)){
ruleFindUrl += header;
}
return new BookSourceBean( return new BookSourceBean(
bookSourceUrl, bookSourceUrl,
@ -226,7 +233,7 @@ public class BookSource3Bean {
0, //u serialNumber, 0, //u serialNumber,
weight, weight,
true, //u enable, true, //u enable,
ruleFindUrl+header,//发现规则 ruleFindUrl, ruleFindUrl,//发现规则 ruleFindUrl,
ruleExplore.bookList, // 列表 ruleFindList, ruleExplore.bookList, // 列表 ruleFindList,
ruleExplore.name,// ruleFindName, ruleExplore.name,// ruleFindName,
ruleExplore.author,// ruleFindAuthor, ruleExplore.author,// ruleFindAuthor,

@ -0,0 +1,39 @@
package xyz.fycz.myreader.entity.thirdsource
data class ExploreKind(
val title: String,
val url: String? = null,
val style: Style? = null
) {
companion object {
val defaultStyle = Style()
}
fun style(): Style {
return style ?: defaultStyle
}
data class Style(
val layout_flexGrow: Float = 0F,
val layout_flexShrink: Float = 1F,
val layout_alignSelf: String = "auto",
val layout_flexBasisPercent: Float = -1F,
val layout_wrapBefore: Boolean = false,
) {
fun alignSelf(): Int {
return when (layout_alignSelf) {
"auto" -> -1
"flex_start" -> 0
"flex_end" -> 1
"center" -> 2
"baseline" -> 3
"stretch" -> 4
else -> -1
}
}
}
}

@ -258,6 +258,10 @@ public class SearchEngine {
}); });
} }
public boolean isSearching(){
return compositeDisposable != null && compositeDisposable.size() > 0;
}
/************************************************************************/ /************************************************************************/
public interface OnSearchListener { public interface OnSearchListener {

@ -4,6 +4,7 @@ import android.database.Cursor;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -309,6 +310,8 @@ public class BookSourceManager {
} else if (StringUtils.isCompressJsonType(string)) { } else if (StringUtils.isCompressJsonType(string)) {
return importBookSourceFromJson(StringUtils.unCompressJson(string)) return importBookSourceFromJson(StringUtils.unCompressJson(string))
.compose(RxUtils::toSimpleSingle); .compose(RxUtils::toSimpleSingle);
} else if (new File(string).isFile()) {
return importSource(FileUtils.readText(string));
} }
if (NetworkUtils.isUrl(string)) { if (NetworkUtils.isUrl(string)) {
String finalString = string; String finalString = string;
@ -316,7 +319,7 @@ public class BookSourceManager {
.flatMap(BookSourceManager::importBookSourceFromJson) .flatMap(BookSourceManager::importBookSourceFromJson)
.compose(RxUtils::toSimpleSingle); .compose(RxUtils::toSimpleSingle);
} }
return Observable.error(new Exception("不是Json或Url格式")); return Observable.error(new Exception("不是Json或Url格式或文件路径"));
} }
private static Observable<List<BookSource>> importBookSourceFromJson(String json) { private static Observable<List<BookSource>> importBookSourceFromJson(String json) {
@ -347,22 +350,22 @@ public class BookSourceManager {
if (StringUtils.isJsonArray(json)) { if (StringUtils.isJsonArray(json)) {
try { try {
List<BookSource> sources = GsonUtils.parseJArray(json, BookSource.class); List<BookSource> sources = GsonUtils.parseJArray(json, BookSource.class);
String sourcesJson = GsonExtensionsKt.getGSON().toJson(sources); String sourcesJson = GsonExtensionsKt.getGSON().toJson(sources);
if (sources.size() > 0 && sourcesJson.length() > sources.size() * SOURCE_LENGTH){ if (sources.size() > 0 && sourcesJson.length() > sources.size() * SOURCE_LENGTH) {
return sources; return sources;
} }
List<BookSourceBean> source2s = GsonUtils.parseJArray(json, BookSourceBean.class); List<BookSourceBean> source2s = GsonUtils.parseJArray(json, BookSourceBean.class);
String source2sJson = GsonExtensionsKt.getGSON().toJson(source2s); String source2sJson = GsonExtensionsKt.getGSON().toJson(source2s);
if (source2s.size() > 0 && source2sJson.length() > source2s.size() * SOURCE_LENGTH){ if (source2s.size() > 0 && source2sJson.length() > source2s.size() * SOURCE_LENGTH) {
return ThirdSourceUtil.source2sToSources(source2s); return ThirdSourceUtil.source2sToSources(source2s);
} }
List<BookSource3Bean> source3s = GsonUtils.parseJArray(json, BookSource3Bean.class); List<BookSource3Bean> source3s = GsonUtils.parseJArray(json, BookSource3Bean.class);
String source3sJson = GsonExtensionsKt.getGSON().toJson(source3s); String source3sJson = GsonExtensionsKt.getGSON().toJson(source3s);
if (source3s.size() > 0 && source3sJson.length() > source3s.size() * SOURCE_LENGTH){ if (source3s.size() > 0 && source3sJson.length() > source3s.size() * SOURCE_LENGTH) {
return ThirdSourceUtil.source3sToSources(source3s); return ThirdSourceUtil.source3sToSources(source3s);
} }
}catch (Exception e){ } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} else if (StringUtils.isJsonObject(json)) { } else if (StringUtils.isJsonObject(json)) {
@ -371,25 +374,25 @@ public class BookSourceManager {
BookSource source = GsonUtils.parseJObject(json, BookSource.class); BookSource source = GsonUtils.parseJObject(json, BookSource.class);
String sourceJson = GsonExtensionsKt.getGSON().toJson(source); String sourceJson = GsonExtensionsKt.getGSON().toJson(source);
if (!StringHelper.isEmpty(sourceJson) && sourceJson.length() > SOURCE_LENGTH){ if (!StringHelper.isEmpty(sourceJson) && sourceJson.length() > SOURCE_LENGTH) {
sources.add(source); sources.add(source);
return sources; return sources;
} }
BookSourceBean source2 = GsonUtils.parseJObject(json, BookSourceBean.class); BookSourceBean source2 = GsonUtils.parseJObject(json, BookSourceBean.class);
String source2Json = GsonExtensionsKt.getGSON().toJson(source2); String source2Json = GsonExtensionsKt.getGSON().toJson(source2);
if (!StringHelper.isEmpty(source2Json) && source2Json.length() > SOURCE_LENGTH){ if (!StringHelper.isEmpty(source2Json) && source2Json.length() > SOURCE_LENGTH) {
sources.add(ThirdSourceUtil.source2ToSource(source2)); sources.add(ThirdSourceUtil.source2ToSource(source2));
return sources; return sources;
} }
BookSource3Bean source3 = GsonUtils.parseJObject(json, BookSource3Bean.class); BookSource3Bean source3 = GsonUtils.parseJObject(json, BookSource3Bean.class);
String source3Json = GsonExtensionsKt.getGSON().toJson(source3); String source3Json = GsonExtensionsKt.getGSON().toJson(source3);
if (!StringHelper.isEmpty(source3Json) && source3Json.length() > SOURCE_LENGTH){ if (!StringHelper.isEmpty(source3Json) && source3Json.length() > SOURCE_LENGTH) {
sources.add(ThirdSourceUtil.source3ToSource(source3)); sources.add(ThirdSourceUtil.source3ToSource(source3));
return sources; return sources;
} }
}catch (Exception e){ } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

@ -138,6 +138,9 @@ public class BookDetailedActivity extends BaseActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
if (chaptersDis != null) chaptersDis.dispose(); if (chaptersDis != null) chaptersDis.dispose();
if (mSourceDialog != null) {
mSourceDialog.stopSearch();
}
super.onDestroy(); super.onDestroy();
} }

@ -116,6 +116,14 @@ public class BookstoreActivity extends BaseActivity {
getSupportActionBar().setSubtitle(subTitle); getSupportActionBar().setSubtitle(subTitle);
} }
@Override
protected void onDestroy() {
if (mSourceDia != null) {
mSourceDia.stopSearch();
}
super.onDestroy();
}
@Override @Override
protected void initData(Bundle savedInstanceState) { protected void initData(Bundle savedInstanceState) {
super.initData(savedInstanceState); super.initData(savedInstanceState);

@ -696,6 +696,9 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe
mPageLoader.closeBook(); mPageLoader.closeBook();
mPageLoader = null; mPageLoader = null;
} }
if (mSourceDialog != null) {
mSourceDialog.stopSearch();
}
} }
@Override @Override

@ -62,6 +62,14 @@ public class ReadRecordActivity extends BaseActivity {
getSupportActionBar().setTitle(getString(R.string.read_record)); getSupportActionBar().setTitle(getString(R.string.read_record));
} }
@Override
protected void onDestroy() {
if (mSourceDia != null) {
mSourceDia.stopSearch();
}
super.onDestroy();
}
@Override @Override
protected void initData(Bundle savedInstanceState) { protected void initData(Bundle savedInstanceState) {
super.initData(savedInstanceState); super.initData(savedInstanceState);

@ -86,7 +86,7 @@ public class FileSystemAdapter extends BaseListAdapter<File> {
mCheckMap.put(file, true); mCheckMap.put(file, true);
++mCheckedCount; ++mCheckedCount;
} }
notifyDataSetChanged(); notifyItemChanged(pos);
} }
public void setCheckedAll(boolean isChecked){ public void setCheckedAll(boolean isChecked){

@ -10,6 +10,7 @@ import android.os.Message;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -168,9 +169,10 @@ public class FontsAdapter extends ArrayAdapter<Font> {
dialog.show();*/ dialog.show();*/
StoragePermissionUtils.request(mFontsActivity, (permissions, all) -> { StoragePermissionUtils.request(mFontsActivity, (permissions, all) -> {
ToastUtils.showInfo("请选择一个ttf格式的字体文件"); ToastUtils.showInfo("请选择一个ttf格式的字体文件");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension("ttf");
intent.setType("*/*"); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE); .putExtra(Intent.EXTRA_MIME_TYPES, new String[]{mime})
.setType("*/*");
mFontsActivity.startActivityForResult(intent, APPCONST.SELECT_FILE_CODE); mFontsActivity.startActivityForResult(intent, APPCONST.SELECT_FILE_CODE);
}); });
}); });

@ -2,6 +2,7 @@ package xyz.fycz.myreader.ui.dialog;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
@ -108,14 +109,13 @@ public class SourceExchangeDialog extends Dialog {
super.onStart(); super.onStart();
if (aBooks.size() == 0) { if (aBooks.size() == 0) {
searchEngine.search(mShelfBook.getName(), mShelfBook.getAuthor()); searchEngine.search(mShelfBook.getName(), mShelfBook.getAuthor());
binding.ivStopSearch.setVisibility(View.VISIBLE);
binding.rpb.setIsAutoLoading(true); binding.rpb.setIsAutoLoading(true);
}else { }else {
if (mAdapter.getItemCount() == 0) { if (mAdapter.getItemCount() == 0) {
mAdapter.addItems(aBooks); mAdapter.addItems(aBooks);
} }
binding.ivStopSearch.setVisibility(View.GONE);
} }
binding.ivStopSearch.setVisibility(searchEngine.isSearching() ? View.VISIBLE : View.GONE);
} }
/** /**
@ -239,6 +239,11 @@ public class SourceExchangeDialog extends Dialog {
}); });
} }
public void stopSearch(){
if (searchEngine != null) {
searchEngine.stopSearch();
}
}
/**************************Interface**********************************/ /**************************Interface**********************************/
public interface OnSourceChangeListener { public interface OnSourceChangeListener {

@ -3,7 +3,9 @@ package xyz.fycz.myreader.ui.fragment;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -23,6 +25,8 @@ import com.kongzue.dialogx.dialogs.BottomMenu;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import io.reactivex.Observable; import io.reactivex.Observable;
@ -50,6 +54,7 @@ import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.ui.dialog.MyAlertDialog; import xyz.fycz.myreader.ui.dialog.MyAlertDialog;
import xyz.fycz.myreader.util.ShareUtils; import xyz.fycz.myreader.util.ShareUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.UriFileUtil;
import xyz.fycz.myreader.util.utils.ClipBoardUtil; import xyz.fycz.myreader.util.utils.ClipBoardUtil;
import xyz.fycz.myreader.util.utils.FileUtils; import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.GsonExtensionsKt; import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
@ -67,6 +72,7 @@ import static xyz.fycz.myreader.util.UriFileUtil.getPath;
* @date 2021/2/10 12:05 * @date 2021/2/10 12:05
*/ */
public class DIYSourceFragment extends BaseFragment { public class DIYSourceFragment extends BaseFragment {
private static final String TAG = DIYSourceFragment.class.getSimpleName();
private FragmentImportSourceBinding binding; private FragmentImportSourceBinding binding;
private final BookSourceActivity sourceActivity; private final BookSourceActivity sourceActivity;
@ -182,11 +188,13 @@ public class DIYSourceFragment extends BaseFragment {
ToastUtils.showError("剪切板内容为空,导入失败"); ToastUtils.showError("剪切板内容为空,导入失败");
} }
} else if (which == 1) { } else if (which == 1) {
ToastUtils.showInfo("请选择书源JSON文件"); StoragePermissionUtils.request(this, (permissions, all) -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); ToastUtils.showInfo("请选择书源文件");
intent.addCategory(Intent.CATEGORY_OPENABLE); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.setType("application/json"); .putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"text/*", "application/json"})
startActivityForResult(intent, APPCONST.REQUEST_IMPORT_BOOK_SOURCE); .setType("*/*");
startActivityForResult(intent, APPCONST.REQUEST_IMPORT_BOOK_SOURCE);
});
} else { } else {
String[] url = new String[1]; String[] url = new String[1];
MyAlertDialog.createInputDia(getContext(), "网络导入", MyAlertDialog.createInputDia(getContext(), "网络导入",
@ -236,19 +244,19 @@ public class DIYSourceFragment extends BaseFragment {
refreshSources(); refreshSources();
ToastUtils.showSuccess(String.format("成功导入%s个书源", size)); ToastUtils.showSuccess(String.format("成功导入%s个书源", size));
} else { } else {
ToastUtils.showError("格式不对"); ToastUtils.showError("书源格式错误,请导入正确的书源");
} }
dialog.dismiss(); dialog.dismiss();
} }
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
ToastUtils.showError("格式不对"); ToastUtils.showError("书源格式错误,请导入正确的书源");
dialog.dismiss(); dialog.dismiss();
} }
}); });
} else { } else {
ToastUtils.showError("导入失败"); ToastUtils.showError("书源格式错误,请导入正确的书源");
} }
} }
@ -303,13 +311,35 @@ public class DIYSourceFragment extends BaseFragment {
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
if (requestCode == APPCONST.REQUEST_IMPORT_BOOK_SOURCE) { if (requestCode == APPCONST.REQUEST_IMPORT_BOOK_SOURCE) {
String path = getPath(getContext(), data.getData()); LoadingDialog dialog = new LoadingDialog(getContext(), "读取文件", () -> {
String json = FileUtils.readText(path); if (importSourceDis != null) {
if (!isEmpty(json)) { importSourceDis.dispose();
importDataS(json); }
} else { });
ToastUtils.showError("文件读取失败"); dialog.show();
} Single.create((SingleOnSubscribe<String>) emitter -> {
String path = UriFileUtil.getChooseFileResultPath(getContext(), data.getData());
Log.d(TAG, "filePath:" + path);
emitter.onSuccess(path);
}).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
importSourceDis = d;
addDisposable(d);
}
@Override
public void onSuccess(@NonNull String s) {
importDataS(s);
dialog.dismiss();
}
@Override
public void onError(Throwable e) {
ToastUtils.showError("文件读取失败");
dialog.dismiss();
}
});
} else if (requestCode == APPCONST.REQUEST_EDIT_BOOK_SOURCE) { } else if (requestCode == APPCONST.REQUEST_EDIT_BOOK_SOURCE) {
refreshSources(); refreshSources();
} }

@ -40,6 +40,20 @@ public class UriFileUtil {
return uri; return uri;
} }
public static String getChooseFileResultPath(Context context, Uri uri) {
String chooseFilePath = null;
if ("file".equalsIgnoreCase(uri.getScheme())) {//使用第三方应用打开
chooseFilePath = uri.getPath();
return chooseFilePath;
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
chooseFilePath = getPath(context, uri);
} else {//4.4以下下系统调用方法
chooseFilePath = getRealPathFromUri(context, uri);
}
return chooseFilePath;
}
public static String getRealPathFromUri(Context context, Uri contentUri) { public static String getRealPathFromUri(Context context, Uri contentUri) {
Cursor cursor = null; Cursor cursor = null;
try { try {

@ -34,6 +34,7 @@ import xyz.fycz.myreader.util.utils.StringUtils;
@Keep @Keep
@SuppressWarnings({"unused"}) @SuppressWarnings({"unused"})
public interface JsExtensions { public interface JsExtensions {
String TAG = JsExtensions.class.getSimpleName(); String TAG = JsExtensions.class.getSimpleName();

@ -358,7 +358,7 @@ public class FileUtils {
return sb.toString(); return sb.toString();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return "";
}finally { }finally {
IOUtils.close(br); IOUtils.close(br);
} }

@ -14,6 +14,7 @@ import xyz.fycz.myreader.entity.StrResponse;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.entity.Chapter; import xyz.fycz.myreader.greendao.entity.Chapter;
import xyz.fycz.myreader.model.mulvalmap.ConMVMap; import xyz.fycz.myreader.model.mulvalmap.ConMVMap;
import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
/** /**
@ -50,6 +51,7 @@ public abstract class BaseReadCrawler implements ReadCrawler {
return Observable.create(emitter -> { return Observable.create(emitter -> {
ConMVMap<SearchBookBean, Book> bookMap = getBooksFromSearchHtml(response.body()); ConMVMap<SearchBookBean, Book> bookMap = getBooksFromSearchHtml(response.body());
for (Book book : bookMap.values()){ for (Book book : bookMap.values()){
book.setId(StringHelper.getStringRandom(25));
if (!TextUtils.isEmpty(book.getImgUrl())){ if (!TextUtils.isEmpty(book.getImgUrl())){
book.setImgUrl(NetworkUtils.getAbsoluteURL(getNameSpace(), book.getImgUrl())); book.setImgUrl(NetworkUtils.getAbsoluteURL(getNameSpace(), book.getImgUrl()));
} }

@ -15,7 +15,6 @@ import java.util.Map;
* @author fengyue * @author fengyue
* @date 2020/4/28 16:18 * @date 2020/4/28 16:18
*/ */
public interface ReadCrawler { public interface ReadCrawler {
String getSearchLink(); // 书源的搜索url String getSearchLink(); // 书源的搜索url
String getCharset(); // 书源的字符编码 String getCharset(); // 书源的字符编码

@ -11,11 +11,13 @@ import io.reactivex.Observable;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import xyz.fycz.myreader.entity.FindKind; import xyz.fycz.myreader.entity.FindKind;
import xyz.fycz.myreader.entity.StrResponse; import xyz.fycz.myreader.entity.StrResponse;
import xyz.fycz.myreader.entity.thirdsource.ExploreKind;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.entity.rule.BookSource; import xyz.fycz.myreader.greendao.entity.rule.BookSource;
import xyz.fycz.myreader.greendao.entity.rule.FindRule; import xyz.fycz.myreader.greendao.entity.rule.FindRule;
import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager;
import xyz.fycz.myreader.model.third2.analyzeRule.AnalyzeRule; import xyz.fycz.myreader.model.third2.analyzeRule.AnalyzeRule;
import xyz.fycz.myreader.util.utils.GsonUtils;
import xyz.fycz.myreader.util.utils.StringUtils; import xyz.fycz.myreader.util.utils.StringUtils;
import xyz.fycz.myreader.webapi.crawler.base.BaseFindCrawler; import xyz.fycz.myreader.webapi.crawler.base.BaseFindCrawler;
@ -54,6 +56,18 @@ public class ThirdFindCrawler extends BaseFindCrawler {
public Observable<Boolean> initData() { public Observable<Boolean> initData() {
return Observable.create(emitter -> { return Observable.create(emitter -> {
try { try {
if (StringUtils.isJsonArray(findRuleBean.getUrl())) {
List<ExploreKind> kinds = GsonUtils.parseJArray(findRuleBean.getUrl(), ExploreKind.class);
StringBuilder sb = new StringBuilder();
for (ExploreKind kind : kinds){
String url = kind.getUrl() == null ? "" : kind.getUrl();
sb.append(kind.getTitle()).append("::").append(url).append("\n");
}
if (sb.length() > 0){
sb.deleteCharAt(sb.length() - 1);
}
findRuleBean.setUrl(sb.toString());
}
String[] kindA; String[] kindA;
String findRule; String findRule;
if (!TextUtils.isEmpty(findRuleBean.getUrl()) && !source.containsGroup(findError)) { if (!TextUtils.isEmpty(findRuleBean.getUrl()) && !source.containsGroup(findError)) {

Loading…
Cancel
Save