pull/5/head
fengyuecanzhu 4 years ago
parent 1e906116c2
commit f5a5d76b1e
  1. 2
      app/build.gradle
  2. 71
      app/src/main/java/xyz/fycz/myreader/entity/bookstore/FindBook.java
  3. 2
      app/src/main/java/xyz/fycz/myreader/entity/sourceedit/EditEntityUtil.kt
  4. 32
      app/src/main/java/xyz/fycz/myreader/greendao/entity/Book.java
  5. 1
      app/src/main/java/xyz/fycz/myreader/model/third2/content/BookInfo.java
  6. 9
      app/src/main/java/xyz/fycz/myreader/model/third2/content/BookList.java
  7. 10
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java
  8. 156
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceDebugActivity.java
  9. 19
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java
  10. 10
      app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java
  11. 1
      app/src/main/java/xyz/fycz/myreader/webapi/BookApi.java
  12. 2
      app/src/main/java/xyz/fycz/myreader/webapi/ThirdSourceApi.java
  13. 1
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiQuGeReadCrawler.java
  14. 1
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/FYReadCrawler.java
  15. 1
      app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/TianLaiReadCrawler.java
  16. 2
      app/src/main/res/layout/actiity_bookstore.xml
  17. 12
      app/src/main/res/layout/listview_book_type_item.xml

@ -208,7 +208,7 @@ dependencies {
} }
greendao { greendao {
schemaVersion 27 schemaVersion 28
daoPackage 'xyz.fycz.myreader.greendao.gen' daoPackage 'xyz.fycz.myreader.greendao.gen'
// targetGenDir 'src/main/java' // targetGenDir 'src/main/java'
} }

@ -0,0 +1,71 @@
package xyz.fycz.myreader.entity.bookstore;
/**
* @author fengyue
* @date 2021/5/15 15:46
*/
public class FindBook {
private String name;
private String author;
private String imgUrl;
private String source;
private String center;
private String bottomLeft;
private String bottomRight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getCenter() {
return center;
}
public void setCenter(String center) {
this.center = center;
}
public String getBottomLeft() {
return bottomLeft;
}
public void setBottomLeft(String bottomLeft) {
this.bottomLeft = bottomLeft;
}
public String getBottomRight() {
return bottomRight;
}
public void setBottomRight(String bottomRight) {
this.bottomRight = bottomRight;
}
}

@ -17,7 +17,7 @@ object EditEntityUtil {
add(EditEntity("sourceGroup", source?.sourceGroup, R.string.source_group, "不同分组以;/,隔开")) add(EditEntity("sourceGroup", source?.sourceGroup, R.string.source_group, "不同分组以;/,隔开"))
add(EditEntity("sourceCharset", source?.sourceCharset, R.string.source_charset, "默认UTF-8")) add(EditEntity("sourceCharset", source?.sourceCharset, R.string.source_charset, "默认UTF-8"))
add(EditEntity("sourceHeaders", source?.sourceHeaders, R.string.source_headers, "json格式")) add(EditEntity("sourceHeaders", source?.sourceHeaders, R.string.source_headers, "json格式"))
add(EditEntity("loginUrl", source?.loginUrl, R.string.login_url)) add(EditEntity("loginUrl", source?.loginUrl, R.string.login_url, ""))
add(EditEntity("sourceComment", source?.sourceComment, R.string.comment, "这是您留给使用者的说明")) add(EditEntity("sourceComment", source?.sourceComment, R.string.comment, "这是您留给使用者的说明"))
} }
return sourceEntities return sourceEntities

@ -22,11 +22,6 @@ import java.util.Objects;
import static xyz.fycz.myreader.common.APPCONST.MAP_STRING; import static xyz.fycz.myreader.common.APPCONST.MAP_STRING;
/**
*
* Created by fengyue on 2020/08/23.
*/
@Entity @Entity
public class Book implements Serializable { public class Book implements Serializable {
@Transient @Transient
@ -47,7 +42,6 @@ public class Book implements Serializable {
private String status; private String status;
private String newestChapterId;//最新章节id private String newestChapterId;//最新章节id
private String newestChapterTitle;//最新章节标题 private String newestChapterTitle;//最新章节标题
private String newestChapterUrl;//最新章节url
private String historyChapterId;//上次关闭时的章节ID private String historyChapterId;//上次关闭时的章节ID
private int histtoryChapterNum;//上次关闭时的章节数 private int histtoryChapterNum;//上次关闭时的章节数
@ -82,13 +76,17 @@ public class Book implements Serializable {
@Transient @Transient
private Map<String, String> variableMap; private Map<String, String> variableMap;
@Generated(hash = 1284526947) @Generated(hash = 1839243756)
public Book() {
}
@Generated(hash = 1910282685)
public Book(String id, String name, String chapterUrl, String infoUrl, String imgUrl, String desc, public Book(String id, String name, String chapterUrl, String infoUrl, String imgUrl, String desc,
String author, String type, String updateDate, String wordCount, String status, String author, String type, String updateDate, String wordCount, String status,
String newestChapterId, String newestChapterTitle, String newestChapterUrl, String historyChapterId, String newestChapterId, String newestChapterTitle, String historyChapterId, int histtoryChapterNum,
int histtoryChapterNum, int sortCode, int noReadNum, int chapterTotalNum, int lastReadPosition, int sortCode, int noReadNum, int chapterTotalNum, int lastReadPosition, String source,
String source, boolean isCloseUpdate, boolean isDownLoadAll, String groupId, int groupSort, boolean isCloseUpdate, boolean isDownLoadAll, String groupId, int groupSort, String tag,
String tag, Boolean replaceEnable, long lastReadTime, String variable) { Boolean replaceEnable, long lastReadTime, String variable) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.chapterUrl = chapterUrl; this.chapterUrl = chapterUrl;
@ -102,7 +100,6 @@ public class Book implements Serializable {
this.status = status; this.status = status;
this.newestChapterId = newestChapterId; this.newestChapterId = newestChapterId;
this.newestChapterTitle = newestChapterTitle; this.newestChapterTitle = newestChapterTitle;
this.newestChapterUrl = newestChapterUrl;
this.historyChapterId = historyChapterId; this.historyChapterId = historyChapterId;
this.histtoryChapterNum = histtoryChapterNum; this.histtoryChapterNum = histtoryChapterNum;
this.sortCode = sortCode; this.sortCode = sortCode;
@ -120,11 +117,6 @@ public class Book implements Serializable {
this.variable = variable; this.variable = variable;
} }
@Generated(hash = 1839243756)
public Book() {
}
@Override @Override
public Object clone() { public Object clone() {
try { try {
@ -196,12 +188,6 @@ public class Book implements Serializable {
public void setNewestChapterTitle(String newestChapterTitle) { public void setNewestChapterTitle(String newestChapterTitle) {
this.newestChapterTitle = newestChapterTitle; this.newestChapterTitle = newestChapterTitle;
} }
public String getNewestChapterUrl() {
return this.newestChapterUrl;
}
public void setNewestChapterUrl(String newestChapterUrl) {
this.newestChapterUrl = newestChapterUrl;
}
public String getHistoryChapterId() { public String getHistoryChapterId() {
return this.historyChapterId; return this.historyChapterId;
} }

@ -27,6 +27,7 @@ public class BookInfo {
public Observable<Book> analyzeBookInfo(String s, final Book book) { public Observable<Book> analyzeBookInfo(String s, final Book book) {
return Observable.create(e -> { return Observable.create(e -> {
String baseUrl = book.getInfoUrl(); String baseUrl = book.getInfoUrl();
book.setInfoUrl(baseUrl);
InfoRule infoRule = source.getInfoRule(); InfoRule infoRule = source.getInfoRule();
if (TextUtils.isEmpty(s)) { if (TextUtils.isEmpty(s)) {
e.onError(new Throwable("书籍信息获取失败" + baseUrl)); e.onError(new Throwable("书籍信息获取失败" + baseUrl));

@ -171,6 +171,7 @@ public class BookList {
item.setTag(tag); item.setTag(tag);
item.setSource(bookSource.getSourceUrl()); item.setSource(bookSource.getSourceUrl());
item.setChapterUrl(baseUrl); item.setChapterUrl(baseUrl);
item.setInfoUrl(baseUrl);
Log.d(tag, ">书籍网址:" + baseUrl); Log.d(tag, ">书籍网址:" + baseUrl);
Log.d(tag, "┌获取书名"); Log.d(tag, "┌获取书名");
String bookName = StringUtils.formatHtml(analyzer.getString(infoRule.getName())); String bookName = StringUtils.formatHtml(analyzer.getString(infoRule.getName()));
@ -185,13 +186,17 @@ public class BookList {
Log.d(tag, "└" + item.getType()); Log.d(tag, "└" + item.getType());
Log.d(tag, "┌获取最新章节"); Log.d(tag, "┌获取最新章节");
item.setNewestChapterTitle(analyzer.getString(infoRule.getLastChapter())); item.setNewestChapterTitle(analyzer.getString(infoRule.getLastChapter()));
Log.d(tag, "└" + item.getNewestChapterId()); Log.d(tag, "└" + item.getNewestChapterTitle());
Log.d(tag, "┌获取简介"); Log.d(tag, "┌获取简介");
item.setDesc(analyzer.getString(infoRule.getDesc())); item.setDesc(analyzer.getString(infoRule.getDesc()));
Log.d(tag, "└" + item.getDesc()); Log.d(tag, "└" + item.getDesc());
Log.d(tag, "┌获取封面"); Log.d(tag, "┌获取封面");
item.setImgUrl(analyzer.getString(infoRule.getImgUrl(), true)); item.setImgUrl(analyzer.getString(infoRule.getImgUrl(), true));
Log.d(tag, "└" + item.getImgUrl()); Log.d(tag, "└" + item.getImgUrl());
Log.d(tag, "┌获取目录网址");
String bookCatalogUrl = analyzer.getString(infoRule.getTocUrl(), true);
if (!isEmpty(bookCatalogUrl)) item.setChapterUrl(bookCatalogUrl);;
Log.d(tag, "└" + item.getChapterUrl());
return item; return item;
} }
return null; return null;
@ -216,7 +221,7 @@ public class BookList {
if (printLog) Log.d(tag,"└" + item.getType()); if (printLog) Log.d(tag,"└" + item.getType());
if (printLog) Log.d(tag, "┌获取最新章节"); if (printLog) Log.d(tag, "┌获取最新章节");
item.setNewestChapterTitle(String.valueOf(nativeObject.get(ruleLastChapter))); item.setNewestChapterTitle(String.valueOf(nativeObject.get(ruleLastChapter)));
if (printLog) Log.d(tag, "└" + item.getNewestChapterId()); if (printLog) Log.d(tag, "└" + item.getNewestChapterTitle());
if (printLog) Log.d(tag, "┌获取简介"); if (printLog) Log.d(tag, "┌获取简介");
item.setDesc(String.valueOf(nativeObject.get(ruleIntroduce))); item.setDesc(String.valueOf(nativeObject.get(ruleIntroduce)));
if (printLog) Log.d(tag, "└" + item.getDesc()); if (printLog) Log.d(tag, "└" + item.getDesc());

@ -210,7 +210,7 @@ public class BookDetailedActivity extends BaseActivity {
binding.ic.bookDetailRvCatalog.setLayoutManager(new LinearLayoutManager(this)); binding.ic.bookDetailRvCatalog.setLayoutManager(new LinearLayoutManager(this));
binding.ic.bookDetailRvCatalog.setAdapter(mCatalogAdapter); binding.ic.bookDetailRvCatalog.setAdapter(mCatalogAdapter);
if (!thirdSource || isCollected) initChapters(false); if (!thirdSource) initChapters(false);
mCatalogAdapter.setOnItemClickListener((view, pos) -> { mCatalogAdapter.setOnItemClickListener((view, pos) -> {
mBook.setHisttoryChapterNum(mChapters.size() - pos - 1); mBook.setHisttoryChapterNum(mChapters.size() - pos - 1);
@ -410,7 +410,7 @@ public class BookDetailedActivity extends BaseActivity {
BookSource source = BookSourceManager.getBookSourceByStr(mBook.getSource()); BookSource source = BookSourceManager.getBookSourceByStr(mBook.getSource());
binding.ih.bookDetailSource.setText(String.format("书源:%s", source.getSourceName())); binding.ih.bookDetailSource.setText(String.format("书源:%s", source.getSourceName()));
ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(source); ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(source);
if ((rc instanceof BookInfoCrawler && StringHelper.isEmpty(mBook.getImgUrl())) || (thirdSource && !isCollected)) { if ((rc instanceof BookInfoCrawler && StringHelper.isEmpty(mBook.getImgUrl())) || thirdSource) {
binding.pbLoading.setVisibility(View.VISIBLE); binding.pbLoading.setVisibility(View.VISIBLE);
BookInfoCrawler bic = (BookInfoCrawler) rc; BookInfoCrawler bic = (BookInfoCrawler) rc;
BookApi.getBookInfo(mBook, bic).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<Book>() { BookApi.getBookInfo(mBook, bic).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<Book>() {
@ -418,18 +418,22 @@ public class BookDetailedActivity extends BaseActivity {
public void onNext(@NotNull Book book) { public void onNext(@NotNull Book book) {
if (!App.isDestroy(BookDetailedActivity.this)) { if (!App.isDestroy(BookDetailedActivity.this)) {
mHandler.sendMessage(mHandler.obtainMessage(4)); mHandler.sendMessage(mHandler.obtainMessage(4));
}
if (thirdSource) { if (thirdSource) {
initChapters(false); initChapters(false);
} }
} }
}
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
if (!App.isDestroy(BookDetailedActivity.this)) {
ToastUtils.showError("书籍详情加载失败!"); ToastUtils.showError("书籍详情加载失败!");
if (thirdSource) { if (thirdSource) {
initChapters(false); initChapters(false);
} }
binding.pbLoading.setVisibility(View.GONE);
}
if (App.isDebug()) e.printStackTrace(); if (App.isDebug()) e.printStackTrace();
} }
}); });

@ -10,35 +10,48 @@ import androidx.appcompat.widget.Toolbar;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe; import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull; import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import okhttp3.MediaType; import okhttp3.MediaType;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.base.BaseActivity; import xyz.fycz.myreader.base.BaseActivity;
import xyz.fycz.myreader.base.observer.MyObserver; import xyz.fycz.myreader.base.observer.MyObserver;
import xyz.fycz.myreader.databinding.ActivitySourceDebugBinding; import xyz.fycz.myreader.databinding.ActivitySourceDebugBinding;
import xyz.fycz.myreader.entity.SearchBookBean;
import xyz.fycz.myreader.entity.StrResponse;
import xyz.fycz.myreader.entity.sourcedebug.DebugBook; import xyz.fycz.myreader.entity.sourcedebug.DebugBook;
import xyz.fycz.myreader.entity.sourcedebug.DebugChapter; import xyz.fycz.myreader.entity.sourcedebug.DebugChapter;
import xyz.fycz.myreader.entity.sourcedebug.DebugEntity; import xyz.fycz.myreader.entity.sourcedebug.DebugEntity;
import xyz.fycz.myreader.entity.sourcedebug.ListResult; import xyz.fycz.myreader.entity.sourcedebug.ListResult;
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.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.util.utils.GsonExtensionsKt; import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.OkHttpUtils;
import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.util.utils.RxUtils;
import xyz.fycz.myreader.webapi.BookApi;
import xyz.fycz.myreader.webapi.ThirdSourceApi;
import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil;
import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler;
import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler;
import xyz.fycz.myreader.webapi.crawler.source.ThirdCrawler;
import xyz.fycz.myreader.widget.codeview.Language; import xyz.fycz.myreader.widget.codeview.Language;
import static xyz.fycz.myreader.util.utils.OkHttpUtils.getCookies;
/** /**
* @author fengyue * @author fengyue
* @date 2021/2/12 18:55 * @date 2021/2/12 18:55
@ -149,52 +162,31 @@ public class SourceDebugActivity extends BaseActivity {
private void initDebugEntity() { private void initDebugEntity() {
loadingDialog.show(); loadingDialog.show();
Observable.create((ObservableOnSubscribe<Boolean>) emitter -> { Observable<Boolean> observable;
try { if (rc instanceof ThirdCrawler) {
observable = debugThirdSource();
} else {
observable = Observable.create((ObservableOnSubscribe<StrResponse>) emitter -> {
String url = debugEntity.getUrl(); String url = debugEntity.getUrl();
Map<String, String> headers = rc.getHeaders();
headers.putAll(getCookies(rc.getNameSpace()));
if (debugEntity.getDebugMode() == DebugEntity.SEARCH && rc.isPost()) { if (debugEntity.getDebugMode() == DebugEntity.SEARCH && rc.isPost()) {
String[] urlInfo = url.split(","); String[] urlInfo = url.split(",");
url = NetworkUtils.getAbsoluteURL(rc.getNameSpace(), urlInfo[0]); url = NetworkUtils.getAbsoluteURL(rc.getNameSpace(), urlInfo[0]);
String body = urlInfo[1]; String body = urlInfo[1];
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody requestBody = RequestBody.create(mediaType, body); RequestBody requestBody = RequestBody.create(mediaType, body);
debugEntity.setHtml(OkHttpUtils.getHtml(url, requestBody, rc.getCharset(), rc.getHeaders())); emitter.onNext(OkHttpUtils.getStrResponse(url, requestBody, rc.getCharset(), headers));
} else { } else {
debugEntity.setHtml(OkHttpUtils.getHtml(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), url), rc.getCharset(), rc.getHeaders())); emitter.onNext((OkHttpUtils.getStrResponse(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), url), rc.getCharset(), headers)));
}
ListResult listResult = new ListResult();
switch (debugEntity.getDebugMode()) {
case DebugEntity.SEARCH:
default:
List<DebugBook> debugBooks = book2DebugBook(rc.getBooksFromSearchHtml(debugEntity.getHtml()).values());
listResult.set信息(String.format("解析完毕,共%s本书籍", debugBooks.size()));
listResult.set结果(debugBooks);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
break;
case DebugEntity.INFO:
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(book2DebugBook(((BookInfoCrawler) rc).getBookInfo(debugEntity.getHtml(), new Book()))));
break;
case DebugEntity.TOC:
List<DebugChapter> debugChapters = chapter2DebugChapter(rc.getChaptersFromHtml(debugEntity.getHtml()));
listResult.set信息(String.format("解析完毕,共%s个章节", debugChapters.size()));
listResult.set结果(debugChapters);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
break;
case DebugEntity.CONTENT:
debugEntity.setParseResult(rc.getContentFormHtml(debugEntity.getHtml()));
break;
}
emitter.onNext(true);
} catch (Exception e) {
e.printStackTrace();
emitter.onError(e);
} }
emitter.onComplete(); emitter.onComplete();
}).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<Boolean>() {
}).flatMap(response -> OkHttpUtils.setCookie(response, rc.getNameSpace()))
.flatMap((Function<StrResponse, ObservableSource<Boolean>>) this::debugSource);
}
observable.compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<Boolean>() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
disposable = d; disposable = d;
@ -214,10 +206,102 @@ public class SourceDebugActivity extends BaseActivity {
binding.rvSourceCode.setCode(debugEntity.getHtml()).apply(); binding.rvSourceCode.setCode(debugEntity.getHtml()).apply();
loadingDialog.dismiss(); loadingDialog.dismiss();
} }
}); });
} }
private Observable<Boolean> debugSource(StrResponse response) {
debugEntity.setHtml(response.body());
ListResult listResult = new ListResult();
switch (debugEntity.getDebugMode()) {
case DebugEntity.SEARCH:
default:
return rc.getBooksFromStrResponse(response)
.flatMap((Function<ConMVMap<SearchBookBean, Book>, ObservableSource<Boolean>>) books -> Observable.create(emitter -> {
List<DebugBook> debugBooks = book2DebugBook(books.values());
listResult.set信息(String.format("解析完毕,共%s本书籍", debugBooks.size()));
listResult.set结果(debugBooks);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.INFO:
return ((BookInfoCrawler) rc).getBookInfo(response, new Book())
.flatMap((Function<Book, ObservableSource<Boolean>>) book -> Observable.create(emitter -> {
debugEntity.setParseResult(GsonExtensionsKt.getGSON().toJson(book2DebugBook(book)));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.TOC:
return rc.getChaptersFromStrResponse(response)
.flatMap((Function<List<Chapter>, ObservableSource<Boolean>>) chapters -> Observable.create(emitter -> {
List<DebugChapter> debugChapters = chapter2DebugChapter(chapters);
listResult.set信息(String.format("解析完毕,共%s个章节", debugChapters.size()));
listResult.set结果(debugChapters);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.CONTENT:
return rc.getContentFormStrResponse(response)
.flatMap((Function<String, ObservableSource<Boolean>>) content -> Observable.create(emitter -> {
debugEntity.setParseResult(content);
emitter.onNext(true);
emitter.onComplete();
}));
}
}
private Observable<Boolean> debugThirdSource() {
debugEntity.setHtml("第三方书源不支持查看源码");
ListResult listResult = new ListResult();
Book book = new Book();
book.setChapterUrl(debugEntity.getUrl());
switch (debugEntity.getDebugMode()) {
case DebugEntity.SEARCH:
default:
return BookApi.search(debugEntity.getKey(), rc)
.flatMap((Function<ConMVMap<SearchBookBean, Book>, ObservableSource<Boolean>>) books -> Observable.create(emitter -> {
List<DebugBook> debugBooks = book2DebugBook(books.values());
listResult.set信息(String.format("解析完毕,共%s本书籍", debugBooks.size()));
listResult.set结果(debugBooks);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.INFO:
return BookApi.getBookInfo(book, (BookInfoCrawler) rc)
.flatMap((Function<Book, ObservableSource<Boolean>>) book1 -> Observable.create(emitter -> {
debugEntity.setParseResult(GsonExtensionsKt.getGSON().toJson(book2DebugBook(book1)));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.TOC:
return BookApi.getBookChapters(book, rc)
.flatMap((Function<List<Chapter>, ObservableSource<Boolean>>) chapters -> Observable.create(emitter -> {
List<DebugChapter> debugChapters = chapter2DebugChapter(chapters);
listResult.set信息(String.format("解析完毕,共%s个章节", debugChapters.size()));
listResult.set结果(debugChapters);
debugEntity.setParseResult(GsonExtensionsKt.getGSON()
.toJson(listResult));
emitter.onNext(true);
emitter.onComplete();
}));
case DebugEntity.CONTENT:
Chapter chapter = new Chapter();
book.setChapterUrl(rc.getNameSpace());
chapter.setUrl(debugEntity.getUrl());
return BookApi.getChapterContent(chapter, book, rc)
.flatMap((Function<String, ObservableSource<Boolean>>) content -> Observable.create(emitter -> {
debugEntity.setParseResult(content);
emitter.onNext(true);
emitter.onComplete();
}));
}
}
private List<DebugBook> book2DebugBook(List<Book> books) { private List<DebugBook> book2DebugBook(List<Book> books) {
List<DebugBook> debugBooks = new ArrayList<>(); List<DebugBook> debugBooks = new ArrayList<>();
for (Book book : books) { for (Book book : books) {

@ -141,17 +141,6 @@ public class SourceEditActivity extends BaseActivity {
@Override @Override
public void onTabReselected(TabLayout.Tab tab) { public void onTabReselected(TabLayout.Tab tab) {
}
});
binding.sSourceType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
invalidateOptionsMenu();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
} }
}); });
} }
@ -162,13 +151,6 @@ public class SourceEditActivity extends BaseActivity {
return true; return true;
} }
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem debug = menu.findItem(R.id.action_debug);
debug.setVisible(!APPCONST.THIRD_SOURCE.equals(getSource().getSourceType()));
return super.onPrepareOptionsMenu(menu);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_save) { if (item.getItemId() == R.id.action_save) {
@ -216,6 +198,7 @@ public class SourceEditActivity extends BaseActivity {
MyAlertDialog.createInputDia(this, String.valueOf(title), hint, MyAlertDialog.createInputDia(this, String.valueOf(title), hint,
"", true, 500, text -> { "", true, 500, text -> {
if (debugMode == DebugEntity.SEARCH) { if (debugMode == DebugEntity.SEARCH) {
debugEntity.setKey(text);
try { try {
MatcherCrawler sc = new MatcherCrawler(source); MatcherCrawler sc = new MatcherCrawler(source);
if (!sc.getSearchCharset().toLowerCase().equals("utf-8")) { if (!sc.getSearchCharset().toLowerCase().equals("utf-8")) {

@ -5,6 +5,8 @@ import org.jsoup.Connection;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -77,5 +79,11 @@ public interface JsExtensions {
.execute(); .execute();
} }
/**
* 时间格式化
*/
default String timeFormat(long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
return sdf.format(new Date(time));
}
} }

@ -123,7 +123,6 @@ public class BookApi {
/** /**
* 获取章节正文 * 获取章节正文
*/ */
public static Observable<String> getChapterContent(Chapter chapter, Book book, final ReadCrawler rc) { public static Observable<String> getChapterContent(Chapter chapter, Book book, final ReadCrawler rc) {
if (rc instanceof ThirdCrawler) { if (rc instanceof ThirdCrawler) {
return ThirdSourceApi.getChapterContentByTC(chapter, book, (ThirdCrawler) rc); return ThirdSourceApi.getChapterContentByTC(chapter, book, (ThirdCrawler) rc);

@ -40,7 +40,7 @@ public class ThirdSourceApi {
* @param rc * @param rc
* @return * @return
*/ */
public static Observable<ConMVMap<SearchBookBean, Book>> searchByTC(String key, final ThirdCrawler rc) { protected static Observable<ConMVMap<SearchBookBean, Book>> searchByTC(String key, final ThirdCrawler rc) {
try { try {
Map<String, String> headers = rc.getHeaders(); Map<String, String> headers = rc.getHeaders();
headers.putAll(getCookies(rc.getNameSpace())); headers.putAll(getCookies(rc.getNameSpace()));

@ -231,7 +231,6 @@ public class BiQuGeReadCrawler extends BaseReadCrawler implements BookInfoCrawle
Element p3 = ps.get(3); Element p3 = ps.get(3);
a = p3.getElementsByTag("a").get(0); a = p3.getElementsByTag("a").get(0);
book.setNewestChapterTitle(a.attr("title")); book.setNewestChapterTitle(a.attr("title"));
book.setNewestChapterUrl(book.getChapterUrl() + a.attr("href"));
//类型 //类型
String type = doc.select("meta[property=og:novel:category]").attr("content"); String type = doc.select("meta[property=og:novel:category]").attr("content");

@ -108,7 +108,6 @@ public class FYReadCrawler extends BaseReadCrawler {
book.setAuthor(div.getElementsByTag("a").get(2).text()); book.setAuthor(div.getElementsByTag("a").get(2).text());
book.setType(div.getElementsByTag("a").get(3).text()); book.setType(div.getElementsByTag("a").get(3).text());
book.setNewestChapterTitle(div.getElementsByTag("a").get(4).text()); book.setNewestChapterTitle(div.getElementsByTag("a").get(4).text());
book.setNewestChapterUrl(div.getElementsByTag("a").get(4).attr("href"));
Element img = div.getElementsByTag("img").get(0); Element img = div.getElementsByTag("img").get(0);
book.setImgUrl(img.attr("data-original")); book.setImgUrl(img.attr("data-original"));
Element chapterUrl = div.getElementsByTag("a").get(1); Element chapterUrl = div.getElementsByTag("a").get(1);

@ -143,7 +143,6 @@ public class TianLaiReadCrawler extends BaseReadCrawler {
book.setUpdateDate(infoStr.replace("更新时间:", "").replace(" ", "")); book.setUpdateDate(infoStr.replace("更新时间:", "").replace(" ", ""));
} else { } else {
Element newChapter = element1.child(1); Element newChapter = element1.child(1);
book.setNewestChapterUrl(newChapter.attr("href"));
book.setNewestChapterTitle(newChapter.text()); book.setNewestChapterTitle(newChapter.text());
} }
} }

@ -24,7 +24,7 @@
android:id="@+id/rv_type_list" android:id="@+id/rv_type_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="10"> android:layout_weight="12">
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
<RelativeLayout <RelativeLayout

@ -2,20 +2,20 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/colorBackground"
android:gravity="center"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="18dp" android:paddingTop="18dp"
android:paddingBottom="18dp" android:paddingRight="8dp"
android:gravity="center" android:paddingBottom="18dp">
android:background="@color/colorBackground">
<TextView <TextView
android:id="@+id/tv_type_name" android:id="@+id/tv_type_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLength="4"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:text="玄幻小说" android:textSize="13sp">
android:textSize="14sp">
</TextView> </TextView>

Loading…
Cancel
Save