mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-17 13:49:18 +01:00
Fix chapter recognition. Improve initial requests to fetch chapters from source
This commit is contained in:
parent
b986309b81
commit
384acb2322
@ -35,7 +35,6 @@ import eu.kanade.mangafeed.util.EventBusHook;
|
|||||||
import eu.kanade.mangafeed.util.ToastUtil;
|
import eu.kanade.mangafeed.util.ToastUtil;
|
||||||
import nucleus.factory.RequiresPresenter;
|
import nucleus.factory.RequiresPresenter;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
@RequiresPresenter(ChaptersPresenter.class)
|
@RequiresPresenter(ChaptersPresenter.class)
|
||||||
public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implements
|
public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implements
|
||||||
@ -84,7 +83,7 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
|
|||||||
setSortIcon();
|
setSortIcon();
|
||||||
|
|
||||||
// Init listeners
|
// Init listeners
|
||||||
swipeRefresh.setOnRefreshListener(this::onFetchChapters);
|
swipeRefresh.setOnRefreshListener(this::fetchChapters);
|
||||||
readCb.setOnCheckedChangeListener((arg, isChecked) ->
|
readCb.setOnCheckedChangeListener((arg, isChecked) ->
|
||||||
getPresenter().setReadFilter(isChecked));
|
getPresenter().setReadFilter(isChecked));
|
||||||
downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
|
downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
|
||||||
@ -127,31 +126,43 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_refresh:
|
case R.id.action_refresh:
|
||||||
onFetchChapters();
|
fetchChapters();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNextChapters(List<Chapter> chapters) {
|
public void onNextChapters(List<Chapter> chapters) {
|
||||||
if (chapters.isEmpty() && isCatalogueManga()) {
|
// If the list is empty, fetch chapters from source if the conditions are met
|
||||||
swipeRefresh.setRefreshing(true);
|
// We use presenter chapters instead because they are always unfiltered
|
||||||
getPresenter().fetchChaptersFromSource();
|
if (getPresenter().getChapters().isEmpty())
|
||||||
}
|
initialFetchChapters();
|
||||||
|
|
||||||
closeActionMode();
|
closeActionMode();
|
||||||
adapter.setItems(chapters);
|
adapter.setItems(chapters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFetchChapters() {
|
private void initialFetchChapters() {
|
||||||
|
// Only fetch if this view is from the catalog and it hasn't requested previously
|
||||||
|
if (isCatalogueManga() && !getPresenter().hasRequested()) {
|
||||||
|
fetchChapters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchChapters() {
|
||||||
swipeRefresh.setRefreshing(true);
|
swipeRefresh.setRefreshing(true);
|
||||||
getPresenter().fetchChaptersFromSource();
|
getPresenter().fetchChaptersFromSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFetchChaptersFinish() {
|
public void onFetchChaptersDone() {
|
||||||
swipeRefresh.setRefreshing(false);
|
swipeRefresh.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onFetchChaptersError() {
|
||||||
|
swipeRefresh.setRefreshing(false);
|
||||||
|
ToastUtil.showShort(getContext(), R.string.fetch_chapters_error);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isCatalogueManga() {
|
public boolean isCatalogueManga() {
|
||||||
return ((MangaActivity) getActivity()).isCatalogueManga();
|
return ((MangaActivity) getActivity()).isCatalogueManga();
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||||||
private boolean sortOrderAToZ = true;
|
private boolean sortOrderAToZ = true;
|
||||||
private boolean onlyUnread = true;
|
private boolean onlyUnread = true;
|
||||||
private boolean onlyDownloaded;
|
private boolean onlyDownloaded;
|
||||||
|
private boolean hasRequested;
|
||||||
|
|
||||||
private PublishSubject<List<Chapter>> chaptersSubject;
|
private PublishSubject<List<Chapter>> chaptersSubject;
|
||||||
|
|
||||||
@ -60,7 +61,8 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||||||
|
|
||||||
restartableLatestCache(FETCH_CHAPTERS,
|
restartableLatestCache(FETCH_CHAPTERS,
|
||||||
this::getOnlineChaptersObs,
|
this::getOnlineChaptersObs,
|
||||||
(view, result) -> view.onFetchChaptersFinish()
|
(view, result) -> view.onFetchChaptersDone(),
|
||||||
|
(view, error) -> view.onFetchChaptersError()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +80,8 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
|
||||||
EventBus.getDefault().removeStickyEvent(ChapterCountEvent.class);
|
EventBus.getDefault().removeStickyEvent(ChapterCountEvent.class);
|
||||||
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusHook
|
@EventBusHook
|
||||||
@ -116,7 +118,8 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||||||
.pullChaptersFromNetwork(manga.url)
|
.pullChaptersFromNetwork(manga.url)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters))
|
.flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters))
|
||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnNext(r -> hasRequested = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observable<List<Chapter>> getDbChaptersObs() {
|
private Observable<List<Chapter>> getDbChaptersObs() {
|
||||||
@ -248,4 +251,12 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||||||
return manga;
|
return manga;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Chapter> getChapters() {
|
||||||
|
return chapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasRequested() {
|
||||||
|
return hasRequested;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import eu.kanade.mangafeed.data.database.models.Manga;
|
|||||||
|
|
||||||
public class ChapterRecognition {
|
public class ChapterRecognition {
|
||||||
|
|
||||||
private static Pattern p1 = Pattern.compile("ch.?(\\d+[\\.,]?\\d*)");
|
private static Pattern p1 = Pattern.compile("Ch[^0-9]?\\s*(\\d+[\\.,]?\\d*)");
|
||||||
private static Pattern p2 = Pattern.compile("(\\d+[\\.,]?\\d*)");
|
private static Pattern p2 = Pattern.compile("(\\d+[\\.,]?\\d*)");
|
||||||
private static Pattern p3 = Pattern.compile("(\\d+[\\.,]?\\d*:)");
|
private static Pattern p3 = Pattern.compile("(\\d+[\\.,]?\\d*:)");
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ public class ChapterRecognition {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove spaces and convert to lower case
|
// Remove spaces and convert to lower case
|
||||||
String name = replaceIrrelevantCharacters(chapter.name);
|
String name = chapter.name;
|
||||||
Matcher matcher;
|
Matcher matcher;
|
||||||
|
|
||||||
// Safest option, the chapter has a token prepended
|
// Safest option, the chapter has a token prepended
|
||||||
@ -29,6 +29,8 @@ public class ChapterRecognition {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = replaceIrrelevantCharacters(name);
|
||||||
|
|
||||||
List<Float> occurences;
|
List<Float> occurences;
|
||||||
|
|
||||||
// If there's only one number, use it
|
// If there's only one number, use it
|
||||||
@ -71,7 +73,7 @@ public class ChapterRecognition {
|
|||||||
Matcher m = p2.matcher(text);
|
Matcher m = p2.matcher(text);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
try {
|
try {
|
||||||
Float value = Float.parseFloat(m.group());
|
Float value = Float.parseFloat(m.group(1));
|
||||||
if (!occurences.contains(value)) {
|
if (!occurences.contains(value)) {
|
||||||
occurences.add(value);
|
occurences.add(value);
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
<string name="chapter_queued">Queued</string>
|
<string name="chapter_queued">Queued</string>
|
||||||
<string name="chapter_downloading">Downloading</string>
|
<string name="chapter_downloading">Downloading</string>
|
||||||
<string name="chapter_error">Error</string>
|
<string name="chapter_error">Error</string>
|
||||||
|
<string name="fetch_chapters_error">Error while fetching chapters</string>
|
||||||
|
|
||||||
<!-- Reader activity -->
|
<!-- Reader activity -->
|
||||||
<string name="downloading">Downloading…</string>
|
<string name="downloading">Downloading…</string>
|
||||||
|
@ -105,4 +105,12 @@ public class ChapterRecognitionTest {
|
|||||||
assertThat(c.chapter_number, is(191f));
|
assertThat(c.chapter_number, is(191f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithKeywordChAtTheEndOfTheManga() {
|
||||||
|
// It should be 567, not 67 (ch is a keyword to get the chapter number)
|
||||||
|
Chapter c = createChapter("Bleach 567: Down With Snowwhite");
|
||||||
|
ChapterRecognition.parseChapterNumber(c, randomManga);
|
||||||
|
assertThat(c.chapter_number, is(567f));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user