Initial implementation of favorites syncing

General code cleanup
Fix some cases of duplicate galleries (not completely fixed)
This commit is contained in:
NerdNumber9
2018-01-31 22:39:55 -05:00
parent f18b32626a
commit d892f2f7f4
11 changed files with 588 additions and 389 deletions

View File

@@ -11,21 +11,26 @@ import eu.kanade.tachiyomi.source.model.*
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.LewdSource
import eu.kanade.tachiyomi.util.asJsoup
import exh.metadata.*
import exh.metadata.EX_DATE_FORMAT
import exh.metadata.ignore
import exh.metadata.models.ExGalleryMetadata
import exh.metadata.models.Tag
import exh.metadata.nullIfBlank
import exh.metadata.parseHumanReadableByteCount
import exh.ui.login.LoginController
import exh.util.UriFilter
import exh.util.UriGroup
import exh.util.urlImportFetchSearchManga
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.net.URLEncoder
import java.util.*
import exh.ui.login.LoginController
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.Request
import org.jsoup.nodes.Document
import exh.util.*
class EHentai(override val id: Long,
val exh: Boolean,
@@ -51,14 +56,14 @@ class EHentai(override val id: Long,
/**
* Gallery list entry
*/
data class ParsedManga(val fav: String?, val manga: Manga)
data class ParsedManga(val fav: Int, val manga: Manga)
fun extendedGenericMangaParse(doc: Document)
= with(doc) {
//Parse mangas
val parsedMangas = select(".gtr0,.gtr1").map {
ParsedManga(
fav = it.select(".itd .it3 > .i[id]").first()?.attr("title"),
fav = parseFavoritesStyle(it.select(".itd .it3 > .i[id]").first()?.attr("style")),
manga = Manga.create(id).apply {
//Get title
it.select(".itd .it5 a").first()?.apply {
@@ -85,6 +90,14 @@ class EHentai(override val id: Long,
Pair(parsedMangas, hasNextPage)
}
fun parseFavoritesStyle(style: String?): Int {
val offset = style?.substringAfterLast("background-position:0px ")
?.removeSuffix("px; cursor:pointer")
?.toIntOrNull() ?: return -1
return (offset + 2)/-19
}
/**
* Parse a list of galleries
*/
@@ -287,9 +300,7 @@ class EHentai(override val id: Long,
throw UnsupportedOperationException("Unused method was called somehow!")
}
//Too lazy to write return type
fun fetchFavorites() = {
//Used to get "s" cookie
fun fetchFavorites(): Pair<List<ParsedManga>, List<String>> {
val favoriteUrl = "$baseUrl/favorites.php"
val result = mutableListOf<ParsedManga>()
var page = 1
@@ -308,22 +319,23 @@ class EHentai(override val id: Long,
//Parse fav names
if (favNames == null)
favNames = doc.getElementsByClass("nosel").first().children().filter {
it.children().size >= 3
}.mapNotNull { it.child(2).text() }
favNames = doc.select(".fp:not(.fps)").mapNotNull {
it.child(2).text()
}
//Next page
page++
} while (parsed.second)
Pair(result as List<ParsedManga>, favNames!!)
}()
return Pair(result as List<ParsedManga>, favNames!!)
}
val cookiesHeader by lazy {
val cookies: MutableMap<String, String> = mutableMapOf()
if(prefs.enableExhentai().getOrDefault()) {
cookies.put(LoginController.MEMBER_ID_COOKIE, prefs.memberIdVal().get()!!)
cookies.put(LoginController.PASS_HASH_COOKIE, prefs.passHashVal().get()!!)
cookies.put(LoginController.IGNEOUS_COOKIE, prefs.igneousVal().get()!!)
cookies[LoginController.MEMBER_ID_COOKIE] = prefs.memberIdVal().get()!!
cookies[LoginController.PASS_HASH_COOKIE] = prefs.passHashVal().get()!!
cookies[LoginController.IGNEOUS_COOKIE] = prefs.igneousVal().get()!!
}
//Setup settings
@@ -458,20 +470,5 @@ class EHentai(override val id: Long,
companion object {
val QUERY_PREFIX = "?f_apply=Apply+Filter"
val TR_SUFFIX = "TR"
fun getCookies(cookies: String): Map<String, String>? {
val foundCookies = HashMap<String, String>()
for (cookie in cookies.split(";".toRegex()).dropLastWhile(String::isEmpty).toTypedArray()) {
val splitCookie = cookie.split("=".toRegex()).dropLastWhile(String::isEmpty).toTypedArray()
if (splitCookie.size < 2) {
return null
}
val trimmedKey = splitCookie[0].trim { it <= ' ' }
if (!foundCookies.containsKey(trimmedKey)) {
foundCookies.put(trimmedKey, splitCookie[1].trim { it <= ' ' })
}
}
return foundCookies
}
}
}

View File

@@ -12,6 +12,7 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.view.ActionMode
import android.support.v7.widget.SearchView
import android.view.*
import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.f2prateek.rx.preferences.Preference
@@ -36,7 +37,7 @@ import eu.kanade.tachiyomi.ui.migration.MigrationController
import eu.kanade.tachiyomi.util.inflate
import eu.kanade.tachiyomi.util.toast
import eu.kanade.tachiyomi.widget.DrawerSwipeCloseListener
import exh.FavoritesSyncHelper
import exh.favorites.FavoritesSyncStatus
import exh.metadata.loadAllMetadata
import exh.metadata.models.SearchableGalleryMetadata
import io.realm.Realm
@@ -133,8 +134,12 @@ class LibraryController(
var realm: Realm? = null
//Cached metadata
var meta: Map<KClass<out SearchableGalleryMetadata>, RealmResults<out SearchableGalleryMetadata>>? = null
//Sync dialog
private var favSyncDialog: MaterialDialog? = null
//Old sync status
private var oldSyncStatus: FavoritesSyncStatus? = null
//Favorites
val favorites by lazy { FavoritesSyncHelper(activity!!) }
private var favoritesSyncSubscription: Subscription? = null
// <-- EH
init {
@@ -406,7 +411,7 @@ class LibraryController(
router.pushController(MigrationController().withFadeTransaction())
}
R.id.action_download_favorites -> {
favorites.guiSyncFavorites { }
presenter.favoritesSync.runSync()
}
else -> return super.onOptionsItemSelected(item)
}
@@ -531,6 +536,100 @@ class LibraryController(
}
}
override fun onAttach(view: View) {
super.onAttach(view)
// --> EXH
cleanupSyncState()
favoritesSyncSubscription =
presenter.favoritesSync.status
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
updateSyncStatus(it)
}
// <-- EXH
}
override fun onDetach(view: View) {
super.onDetach(view)
//EXH
cleanupSyncState()
}
// --> EXH
private fun cleanupSyncState() {
favoritesSyncSubscription?.unsubscribe()
favoritesSyncSubscription = null
//Close sync status
favSyncDialog?.dismiss()
favSyncDialog = null
oldSyncStatus = null
}
private fun buildDialog() = activity?.let {
MaterialDialog.Builder(it)
}
private fun showSyncProgressDialog() {
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title("Favorites syncing")
?.cancelable(false)
?.progress(true, 0)
?.show()
}
private fun updateSyncStatus(status: FavoritesSyncStatus) {
when(status) {
is FavoritesSyncStatus.Idle -> {
favSyncDialog?.dismiss()
favSyncDialog = null
}
is FavoritesSyncStatus.Error -> {
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title("Favorites sync error")
?.content("An error occurred during the sync process: ${status.message}")
?.cancelable(false)
?.positiveText("Ok")
?.onPositive { _, _ ->
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
}
?.show()
}
is FavoritesSyncStatus.Processing,
is FavoritesSyncStatus.Initializing -> {
if(favSyncDialog == null || (oldSyncStatus != null
&& oldSyncStatus !is FavoritesSyncStatus.Initializing
&& oldSyncStatus !is FavoritesSyncStatus.Processing))
showSyncProgressDialog()
favSyncDialog?.setContent(status.message)
}
is FavoritesSyncStatus.Complete -> {
favSyncDialog?.dismiss()
if(status.errors.isNotEmpty()) {
favSyncDialog = buildDialog()
?.title("Favorites sync complete with errors")
?.content("Some errors occurred during the sync process:\n\n"
+ status.errors.joinToString("\n"))
?.cancelable(false)
?.positiveText("Ok")
?.onPositive { _, _ ->
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
}
?.show()
} else {
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
}
}
}
oldSyncStatus = status
}
// <-- EXH
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE_OPEN) {
if (data == null || resultCode != Activity.RESULT_OK) return

View File

@@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.combineLatest
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import exh.favorites.FavoritesSyncHelper
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
@@ -76,6 +77,10 @@ class LibraryPresenter(
*/
private var librarySubscription: Subscription? = null
// --> EXH
val favoritesSync = FavoritesSyncHelper(context)
// <-- EXH
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
subscribeLibrary()