Rewrite sources. Implement Batoto and Kissmanga

This commit is contained in:
len
2016-03-22 19:00:05 +01:00
parent bc3d5dc863
commit dd5692bb2d
36 changed files with 1516 additions and 2571 deletions

View File

@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.source.EN
import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.data.source.base.OnlineSource
import eu.kanade.tachiyomi.data.source.base.Source
import eu.kanade.tachiyomi.data.source.model.MangasPage
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@@ -52,7 +53,7 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
/**
* Active source.
*/
lateinit var source: Source
lateinit var source: OnlineSource
private set
/**
@@ -163,7 +164,7 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @param source the new active source.
*/
fun setActiveSource(source: Source) {
fun setActiveSource(source: OnlineSource) {
prefs.lastUsedCatalogueSource().set(source.id)
this.source = source
restartPager()
@@ -222,9 +223,9 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
}
val observable = if (query.isEmpty())
source.pullPopularMangasFromNetwork(nextMangasPage)
source.fetchPopularManga(nextMangasPage)
else
source.searchMangasFromNetwork(nextMangasPage, query)
source.fetchSearchManga(nextMangasPage, query)
return observable.subscribeOn(Schedulers.io())
.doOnNext { lastMangasPage = it }
@@ -268,7 +269,7 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
* @return an observable of the manga to initialize
*/
private fun getMangaDetailsObservable(manga: Manga): Observable<Manga> {
return source.pullMangaFromNetwork(manga.url)
return source.fetchMangaDetails(manga)
.flatMap { networkManga ->
manga.copyFrom(networkManga)
db.insertManga(manga).executeAsBlocking()
@@ -282,13 +283,13 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @return a source.
*/
fun getLastUsedSource(): Source {
fun getLastUsedSource(): OnlineSource {
val id = prefs.lastUsedCatalogueSource().get() ?: -1
val source = sourceManager.get(id)
if (!isValidSource(source)) {
return findFirstValidSource()
}
return source!!
return source as OnlineSource
}
/**
@@ -298,10 +299,10 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
* @return true if the source is valid, false otherwise.
*/
fun isValidSource(source: Source?): Boolean {
if (source == null) return false
if (source == null || source !is OnlineSource) return false
return with(source) {
if (!isLoginRequired || isLogged) {
if (!isLoginRequired() || isLogged()) {
true
} else {
prefs.sourceUsername(this) != "" && prefs.sourcePassword(this) != ""
@@ -314,14 +315,14 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @return the index of the first valid source.
*/
fun findFirstValidSource(): Source {
return sources.find { isValidSource(it) }!!
fun findFirstValidSource(): OnlineSource {
return sources.first { isValidSource(it) }
}
/**
* Returns a list of enabled sources ordered by language and name.
*/
private fun getEnabledSources(): List<Source> {
private fun getEnabledSources(): List<OnlineSource> {
val languages = prefs.enabledLanguages().getOrDefault()
// Ensure at least one language
@@ -329,7 +330,7 @@ class CataloguePresenter : BasePresenter<CatalogueFragment>() {
languages.add(EN.code)
}
return sourceManager.getSources()
return sourceManager.getOnlineSources()
.filter { it.lang.code in languages }
.sortedBy { "(${it.lang.code}) ${it.name}" }
}

View File

@@ -96,7 +96,7 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
}
fun getOnlineChaptersObs(): Observable<Pair<Int, Int>> {
return source.pullChaptersFromNetwork(manga.url)
return source.fetchChapterList(manga)
.subscribeOn(Schedulers.io())
.map { syncChaptersWithSource(db, it, manga, source) }
.observeOn(AndroidSchedulers.mainThread())

View File

@@ -8,6 +8,7 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.base.OnlineSource
import eu.kanade.tachiyomi.data.source.base.Source
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
import eu.kanade.tachiyomi.util.getResourceColor
@@ -96,7 +97,7 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() {
// If manga source is known update source TextView.
if (source != null) {
manga_source.text = source.visibleName
manga_source.text = source.toString()
}
// Update genres TextView.
@@ -140,8 +141,9 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() {
* Open the manga in browser.
*/
fun openInBrowser() {
val source = presenter.source as? OnlineSource ?: return
try {
val url = Uri.parse(presenter.source.baseUrl + presenter.manga.url)
val url = Uri.parse(source.baseUrl + presenter.manga.url)
val intent = CustomTabsIntent.Builder()
.setToolbarColor(context.theme.getResourceColor(R.attr.colorPrimary))
.build()

View File

@@ -99,7 +99,7 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() {
* @return manga information.
*/
private fun fetchMangaObs(): Observable<Manga> {
return source.pullMangaFromNetwork(manga.url)
return source.fetchMangaDetails(manga)
.flatMap { networkManga ->
manga.copyFrom(networkManga)
db.insertManga(manga).executeAsBlocking()

View File

@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager
import eu.kanade.tachiyomi.data.mangasync.UpdateMangaSyncService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.data.source.base.OnlineSource
import eu.kanade.tachiyomi.data.source.base.Source
import eu.kanade.tachiyomi.data.source.model.Page
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@@ -126,9 +127,16 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
observable = Observable.from(ch.pages)
.flatMap { downloadManager.getDownloadedImage(it, chapterDir) }
} else {
observable = source.getAllImageUrlsFromPageList(ch.pages)
.flatMap({ source.getCachedImage(it) }, 2)
.doOnCompleted { source.savePageList(ch.url, ch.pages) }
observable = source.let { source ->
if (source is OnlineSource) {
source.fetchAllImageUrlsFromPageList(ch.pages)
.flatMap({ source.getCachedImage(it) }, 2)
.doOnCompleted { source.savePageList(ch, ch.pages) }
} else {
Observable.from(ch.pages)
.flatMap { source.fetchImage(it) }
}
}
}
observable.doOnCompleted {
if (!isSeamlessMode && chapter === ch) {
@@ -139,13 +147,7 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
// Listen por retry events
add(retryPageSubject.observeOn(Schedulers.io())
.flatMap { page ->
if (page.imageUrl == null)
source.getImageUrlFromPage(page)
else
Observable.just<Page>(page)
}
.flatMap { source.getCachedImage(it) }
.flatMap { source.fetchImage(it) }
.subscribe())
}
@@ -156,7 +158,7 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
Observable.just(downloadManager.getSavedPageList(source, manga, chapter)!!)
else
// Fetch the page list from cache or fallback to network
source.getCachedPageListOrPullFromNetwork(chapter.url)
source.fetchPageList(chapter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -200,26 +202,15 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
// Preload the first pages of the next chapter. Only for non seamless mode
private fun getPreloadNextChapterObservable(): Observable<Page> {
return source.getCachedPageListOrPullFromNetwork(nextChapter!!.url)
val nextChapter = nextChapter ?: return Observable.error(Exception("No next chapter"))
return source.fetchPageList(nextChapter)
.flatMap { pages ->
nextChapter!!.pages = pages
nextChapter.pages = pages
val pagesToPreload = Math.min(pages.size, 5)
Observable.from(pages).take(pagesToPreload)
}
// Preload up to 5 images
.concatMap { page ->
if (page.imageUrl == null)
source.getImageUrlFromPage(page)
else
Observable.just<Page>(page)
}
// Download the first image
.concatMap { page ->
if (page.pageNumber == 0)
source.getCachedImage(page)
else
Observable.just<Page>(page)
}
.concatMap { source.fetchImage(it) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnCompleted { stopPreloadingNextChapter() }
@@ -324,7 +315,7 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
// Cache current page list progress for online chapters to allow a faster reopen
if (!chapter.isDownloaded) {
source.savePageList(chapter.url, pages)
source.let { if (it is OnlineSource) it.savePageList(chapter, pages) }
}
// Save current progress of the chapter. Mark as read if the chapter is finished
@@ -382,7 +373,7 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
}
fun updateMangaSyncLastChapterRead() {
for (mangaSync in mangaSyncList!!) {
for (mangaSync in mangaSyncList ?: emptyList()) {
val service = syncManager.getService(mangaSync.sync_id)
if (service.isLogged && mangaSync.update) {
UpdateMangaSyncService.start(context, mangaSync)
@@ -417,16 +408,21 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
}
private fun preloadNextChapter() {
if (hasNextChapter() && !isChapterDownloaded(nextChapter!!)) {
start(PRELOAD_NEXT_CHAPTER)
nextChapter?.let {
if (!isChapterDownloaded(it)) {
start(PRELOAD_NEXT_CHAPTER)
}
}
}
private fun stopPreloadingNextChapter() {
if (!isUnsubscribed(PRELOAD_NEXT_CHAPTER)) {
stop(PRELOAD_NEXT_CHAPTER)
if (nextChapter!!.pages != null)
source.savePageList(nextChapter!!.url, nextChapter!!.pages)
nextChapter?.let { chapter ->
if (chapter.pages != null) {
source.let { if (it is OnlineSource) it.savePageList(chapter, chapter.pages) }
}
}
}
}

View File

@@ -42,11 +42,11 @@ class SettingsSourcesFragment : SettingsNestedFragment() {
.subscribe { languages ->
sourcesPref.removeAll()
val enabledSources = settingsActivity.sourceManager.getSources()
val enabledSources = settingsActivity.sourceManager.getOnlineSources()
.filter { it.lang.code in languages }
for (source in enabledSources) {
if (source.isLoginRequired) {
if (source.isLoginRequired()) {
val pref = createSource(source)
sourcesPref.addPreference(pref)
}
@@ -65,7 +65,7 @@ class SettingsSourcesFragment : SettingsNestedFragment() {
fun createSource(source: Source): Preference {
return LoginPreference(preferenceManager.context).apply {
key = preferences.keys.sourceUsername(source.id)
title = source.visibleName
title = source.toString()
setOnPreferenceClickListener {
val fragment = SourceLoginDialog.newInstance(source)