Add EH code.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
package exh;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
|
||||
import eu.kanade.tachiyomi.data.database.models.Category;
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga;
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory;
|
||||
//import eu.kanade.tachiyomi.data.source.online.english.EHentai;
|
||||
|
||||
public class FavoritesSyncManager {
|
||||
/*
|
||||
Context context;
|
||||
DatabaseHelper db;
|
||||
|
||||
public FavoritesSyncManager(Context context, DatabaseHelper db) {
|
||||
this.context = context;
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public void guiSyncFavorites(final Runnable onComplete) {
|
||||
if(!DialogLogin.isLoggedIn(context, false)) {
|
||||
new AlertDialog.Builder(context).setTitle("Error")
|
||||
.setMessage("You are not logged in! Please log in and try again!")
|
||||
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}).show();
|
||||
return;
|
||||
}
|
||||
final ProgressDialog dialog = ProgressDialog.show(context, "Downloading Favorites", "Please wait...", true, false);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Handler mainLooper = new Handler(Looper.getMainLooper());
|
||||
try {
|
||||
syncFavorites();
|
||||
} catch (Exception e) {
|
||||
mainLooper.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle("Error")
|
||||
.setMessage("There was an error downloading your favorites, please try again later!")
|
||||
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
});
|
||||
e.printStackTrace();
|
||||
}
|
||||
dialog.dismiss();
|
||||
mainLooper.post(onComplete);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void syncFavorites() throws IOException {
|
||||
EHentai.FavoritesResponse favResponse = EHentai.fetchFavorites(context);
|
||||
Map<String, List<Manga>> favorites = favResponse.favs;
|
||||
List<Category> ourCategories = new ArrayList<>(db.getCategories().executeAsBlocking());
|
||||
List<Manga> ourMangas = new ArrayList<>(db.getMangas().executeAsBlocking());
|
||||
//Add required categories (categories do not sync upwards)
|
||||
List<Category> categoriesToInsert = new ArrayList<>();
|
||||
for (String theirCategory : favorites.keySet()) {
|
||||
boolean haveCategory = false;
|
||||
for (Category category : ourCategories) {
|
||||
if (category.getName().endsWith(theirCategory)) {
|
||||
haveCategory = true;
|
||||
}
|
||||
}
|
||||
if (!haveCategory) {
|
||||
Category category = Category.Companion.create(theirCategory);
|
||||
ourCategories.add(category);
|
||||
categoriesToInsert.add(category);
|
||||
}
|
||||
}
|
||||
if (!categoriesToInsert.isEmpty()) {
|
||||
for(Map.Entry<Category, PutResult> result : db.insertCategories(categoriesToInsert).executeAsBlocking().results().entrySet()) {
|
||||
if(result.getValue().wasInserted()) {
|
||||
result.getKey().setId(result.getValue().insertedId().intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
//Build category map
|
||||
Map<String, Category> categoryMap = new HashMap<>();
|
||||
for (Category category : ourCategories) {
|
||||
categoryMap.put(category.getName(), category);
|
||||
}
|
||||
//Insert new mangas
|
||||
List<Manga> mangaToInsert = new ArrayList<>();
|
||||
Map<Manga, Category> mangaToSetCategories = new HashMap<>();
|
||||
for (Map.Entry<String, List<Manga>> entry : favorites.entrySet()) {
|
||||
Category category = categoryMap.get(entry.getKey());
|
||||
for (Manga manga : entry.getValue()) {
|
||||
boolean alreadyHaveManga = false;
|
||||
for (Manga ourManga : ourMangas) {
|
||||
if (ourManga.getUrl().equals(manga.getUrl())) {
|
||||
alreadyHaveManga = true;
|
||||
manga = ourManga;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!alreadyHaveManga) {
|
||||
ourMangas.add(manga);
|
||||
mangaToInsert.add(manga);
|
||||
}
|
||||
mangaToSetCategories.put(manga, category);
|
||||
manga.setFavorite(true);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<Manga, PutResult> results : db.insertMangas(mangaToInsert).executeAsBlocking().results().entrySet()) {
|
||||
if(results.getValue().wasInserted()) {
|
||||
results.getKey().setId(results.getValue().insertedId());
|
||||
}
|
||||
}
|
||||
for(Map.Entry<Manga, Category> entry : mangaToSetCategories.entrySet()) {
|
||||
db.setMangaCategories(Collections.singletonList(MangaCategory.Companion.create(entry.getKey(), entry.getValue())),
|
||||
Collections.singletonList(entry.getKey()));
|
||||
}
|
||||
//Determines what
|
||||
/*Map<Integer, List<Manga>> toUpload = new HashMap<>();
|
||||
for (Manga manga : ourMangas) {
|
||||
if(manga.getFavorite()) {
|
||||
boolean remoteHasManga = false;
|
||||
for (List<Manga> remoteMangas : favorites.values()) {
|
||||
for (Manga remoteManga : remoteMangas) {
|
||||
if (remoteManga.getUrl().equals(manga.getUrl())) {
|
||||
remoteHasManga = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!remoteHasManga) {
|
||||
List<Category> mangaCategories = db.getCategoriesForManga(manga).executeAsBlocking();
|
||||
for (Category category : mangaCategories) {
|
||||
int categoryIndex = favResponse.favCategories.indexOf(category.getName());
|
||||
if (categoryIndex >= 0) {
|
||||
List<Manga> uploadMangas = toUpload.get(categoryIndex);
|
||||
if (uploadMangas == null) {
|
||||
uploadMangas = new ArrayList<>();
|
||||
toUpload.put(categoryIndex, uploadMangas);
|
||||
}
|
||||
uploadMangas.add(manga);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
/********** NON-FUNCTIONAL, modifygids[] CANNOT ADD NEW FAVORITES! (or as of my testing it can't, maybe I'll do more testing)**/
|
||||
/*PreferencesHelper helper = new PreferencesHelper(context);
|
||||
for(Map.Entry<Integer, List<Manga>> entry : toUpload.entrySet()) {
|
||||
FormBody.Builder formBody = new FormBody.Builder()
|
||||
.add("ddact", "fav" + entry.getKey());
|
||||
for(Manga manga : entry.getValue()) {
|
||||
List<String> splitUrl = new ArrayList<>(Arrays.asList(manga.getUrl().split("/")));
|
||||
splitUrl.removeAll(Collections.singleton(""));
|
||||
if(splitUrl.size() < 2) {
|
||||
continue;
|
||||
}
|
||||
formBody.add("modifygids[]", splitUrl.get(1).trim());
|
||||
}
|
||||
formBody.add("apply", "Apply");
|
||||
Request request = RequestsKt.POST(EHentai.buildFavoritesBase(context, helper.getPrefs()).favoritesBase,
|
||||
EHentai.getHeadersBuilder(helper).build(),
|
||||
formBody.build(),
|
||||
RequestsKt.getDEFAULT_CACHE_CONTROL());
|
||||
Response response = NetworkManager.getInstance().getClient().newCall(request).execute();
|
||||
Util.d("EHentai", response.body().string());
|
||||
}*/
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package exh
|
||||
|
||||
operator fun StringBuilder.plusAssign(other: String) { append(other) }
|
||||
@@ -0,0 +1,22 @@
|
||||
package exh.metadata
|
||||
|
||||
import exh.metadata.models.ExGalleryMetadata
|
||||
import io.paperdb.Paper
|
||||
|
||||
class MetadataHelper {
|
||||
|
||||
fun writeGallery(galleryMetadata: ExGalleryMetadata)
|
||||
= exGalleryBook().write(galleryMetadata.galleryUniqueIdentifier(), galleryMetadata)
|
||||
|
||||
fun fetchMetadata(url: String, exh: Boolean) = ExGalleryMetadata().apply {
|
||||
this.url = url
|
||||
this.exh = exh
|
||||
return exGalleryBook().read<ExGalleryMetadata>(galleryUniqueIdentifier())
|
||||
}
|
||||
|
||||
fun getAllGalleries() = exGalleryBook().allKeys.map {
|
||||
exGalleryBook().read<ExGalleryMetadata>(it)
|
||||
}
|
||||
|
||||
fun exGalleryBook() = Paper.book("gallery-ex")!!
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package exh.metadata
|
||||
|
||||
/**
|
||||
* Metadata utils
|
||||
*/
|
||||
fun humanReadableByteCount(bytes: Long, si: Boolean): String {
|
||||
val unit = if (si) 1000 else 1024
|
||||
if (bytes < unit) return bytes.toString() + " B"
|
||||
val exp = (Math.log(bytes.toDouble()) / Math.log(unit.toDouble())).toInt()
|
||||
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i"
|
||||
return String.format("%.1f %sB", bytes / Math.pow(unit.toDouble(), exp.toDouble()), pre)
|
||||
}
|
||||
|
||||
private val KB_FACTOR: Long = 1000
|
||||
private val KIB_FACTOR: Long = 1024
|
||||
private val MB_FACTOR = 1000 * KB_FACTOR
|
||||
private val MIB_FACTOR = 1024 * KIB_FACTOR
|
||||
private val GB_FACTOR = 1000 * MB_FACTOR
|
||||
private val GIB_FACTOR = 1024 * MIB_FACTOR
|
||||
|
||||
fun parseHumanReadableByteCount(arg0: String): Double? {
|
||||
val spaceNdx = arg0.indexOf(" ")
|
||||
val ret = java.lang.Double.parseDouble(arg0.substring(0, spaceNdx))
|
||||
when (arg0.substring(spaceNdx + 1)) {
|
||||
"GB" -> return ret * GB_FACTOR
|
||||
"GiB" -> return ret * GIB_FACTOR
|
||||
"MB" -> return ret * MB_FACTOR
|
||||
"MiB" -> return ret * MIB_FACTOR
|
||||
"KB" -> return ret * KB_FACTOR
|
||||
"KiB" -> return ret * KIB_FACTOR
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun String?.nullIfBlank(): String? = if(isNullOrBlank())
|
||||
null
|
||||
else
|
||||
this
|
||||
|
||||
fun <T> ignore(expr: () -> T): T? {
|
||||
return try { expr() } catch (t: Throwable) { null }
|
||||
}
|
||||
|
||||
fun <K,V> Set<Map.Entry<K,V>>.forEach(action: (K, V) -> Unit) {
|
||||
forEach { action(it.key, it.value) }
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package exh.metadata
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.util.UrlUtil
|
||||
import exh.metadata.models.ExGalleryMetadata
|
||||
import exh.metadata.models.Tag
|
||||
import exh.plusAssign
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Copies gallery metadata to a manga object
|
||||
*/
|
||||
|
||||
private const val ARTIST_NAMESPACE = "artist"
|
||||
private const val AUTHOR_NAMESPACE = "author"
|
||||
|
||||
private val ONGOING_SUFFIX = arrayOf(
|
||||
"[ongoing]",
|
||||
"(ongoing)",
|
||||
"{ongoing}"
|
||||
)
|
||||
|
||||
val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
|
||||
|
||||
fun ExGalleryMetadata.copyTo(manga: Manga) {
|
||||
exh?.let {
|
||||
manga.source = if(it)
|
||||
2
|
||||
else
|
||||
1
|
||||
}
|
||||
url?.let { manga.url = it }
|
||||
thumbnailUrl?.let { manga.thumbnail_url = it }
|
||||
title?.let { manga.title = it }
|
||||
|
||||
//Set artist (if we can find one)
|
||||
tags[ARTIST_NAMESPACE]?.let {
|
||||
if(it.isNotEmpty()) manga.artist = it.joinToString(transform = Tag::name)
|
||||
}
|
||||
//Set author (if we can find one)
|
||||
tags[AUTHOR_NAMESPACE]?.let {
|
||||
if(it.isNotEmpty()) manga.author = it.joinToString(transform = Tag::name)
|
||||
}
|
||||
//Set genre
|
||||
genre?.let { manga.genre = it }
|
||||
|
||||
//Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes
|
||||
//We default to completed
|
||||
manga.status = Manga.COMPLETED
|
||||
title?.let { t ->
|
||||
ONGOING_SUFFIX.find {
|
||||
t.endsWith(it, ignoreCase = true)
|
||||
}?.let {
|
||||
manga.status = Manga.ONGOING
|
||||
}
|
||||
}
|
||||
|
||||
//Build a nice looking description out of what we know
|
||||
val titleDesc = StringBuilder()
|
||||
title?.let { titleDesc += "Title: $it\n" }
|
||||
altTitle?.let { titleDesc += "Japanese Title: $it\n" }
|
||||
|
||||
val detailsDesc = StringBuilder()
|
||||
uploader?.let { detailsDesc += "Uploader: $it\n" }
|
||||
datePosted?.let { detailsDesc += "Posted: ${EX_DATE_FORMAT.format(Date(it))}\n" }
|
||||
visible?.let { detailsDesc += "Visible: $it\n" }
|
||||
language?.let {
|
||||
detailsDesc += "Language: $it"
|
||||
if(translated == true) detailsDesc += " TR"
|
||||
detailsDesc += "\n"
|
||||
}
|
||||
size?.let { detailsDesc += "File Size: ${humanReadableByteCount(it, true)}\n" }
|
||||
length?.let { detailsDesc += "Length: $it pages\n" }
|
||||
favorites?.let { detailsDesc += "Favorited: $it times\n" }
|
||||
averageRating?.let {
|
||||
detailsDesc += "Rating: $it"
|
||||
ratingCount?.let { detailsDesc += " ($it)" }
|
||||
detailsDesc += "\n"
|
||||
}
|
||||
|
||||
val tagsDesc = StringBuilder("Tags:\n")
|
||||
//BiConsumer only available in Java 8, don't bother calling forEach directly on 'tags'
|
||||
tags.entries.forEach { namespace, tags ->
|
||||
if(tags.isNotEmpty()) {
|
||||
val joinedTags = tags.joinToString(separator = " ", transform = { "<${it.name}>" })
|
||||
tagsDesc += "▪ $namespace: $joinedTags\n"
|
||||
}
|
||||
}
|
||||
|
||||
manga.description = listOf(titleDesc, detailsDesc, tagsDesc)
|
||||
.filter { it.isNotBlank() }
|
||||
.joinToString(separator = "\n")
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package exh.metadata.models
|
||||
|
||||
import android.net.Uri
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Gallery metadata storage model
|
||||
*/
|
||||
|
||||
class ExGalleryMetadata {
|
||||
var url: String? = null
|
||||
|
||||
var exh: Boolean? = null
|
||||
|
||||
var title: String? = null
|
||||
var altTitle: String? = null
|
||||
|
||||
var thumbnailUrl: String? = null
|
||||
|
||||
var genre: String? = null
|
||||
|
||||
var uploader: String? = null
|
||||
var datePosted: Long? = null
|
||||
var parent: String? = null
|
||||
var visible: String? = null
|
||||
var language: String? = null
|
||||
var translated: Boolean? = null
|
||||
var size: Long? = null
|
||||
var length: Int? = null
|
||||
var favorites: Int? = null
|
||||
var ratingCount: Int? = null
|
||||
var averageRating: Double? = null
|
||||
|
||||
//Being specific about which classes are used in generics to make deserialization easier
|
||||
var tags: HashMap<String, ArrayList<Tag>> = HashMap()
|
||||
|
||||
private fun splitGalleryUrl()
|
||||
= url?.let {
|
||||
Uri.parse(it).pathSegments.filterNot(String::isNullOrBlank)
|
||||
}
|
||||
|
||||
fun galleryId() = splitGalleryUrl()?.let { it[it.size - 2] }
|
||||
|
||||
fun galleryToken() =
|
||||
splitGalleryUrl()?.last()
|
||||
|
||||
fun galleryUniqueIdentifier() = exh?.let { exh ->
|
||||
url?.let {
|
||||
"${if(exh) "EXH" else "EX"}-${galleryId()}-${galleryToken()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package exh.metadata.models
|
||||
|
||||
/**
|
||||
* Simple tag model
|
||||
*/
|
||||
|
||||
data class Tag(var name: String, var light: Boolean)
|
||||
@@ -0,0 +1,182 @@
|
||||
package exh.ui.login
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||
import kotlinx.android.synthetic.main.eh_activity_login.*
|
||||
import kotlinx.android.synthetic.main.toolbar.*
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.net.HttpCookie
|
||||
|
||||
/**
|
||||
* LoginActivity
|
||||
*/
|
||||
|
||||
class LoginActivity : BaseActivity() {
|
||||
|
||||
val preferenceManager: PreferencesHelper by injectLazy()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setAppTheme()
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.eh_activity_login)
|
||||
|
||||
setup()
|
||||
|
||||
setupToolbar(toolbar, backNavigation = false)
|
||||
}
|
||||
|
||||
fun setup() {
|
||||
btn_cancel.setOnClickListener { onBackPressed() }
|
||||
btn_recheck.setOnClickListener { webview.loadUrl("http://exhentai.org/") }
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
CookieManager.getInstance().removeAllCookies {
|
||||
runOnUiThread {
|
||||
startWebview()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CookieManager.getInstance().removeAllCookie()
|
||||
startWebview()
|
||||
}
|
||||
}
|
||||
|
||||
fun startWebview() {
|
||||
webview.settings.javaScriptEnabled = true
|
||||
webview.settings.domStorageEnabled = true
|
||||
|
||||
webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
|
||||
|
||||
webview.setWebViewClient(object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
super.onPageFinished(view, url)
|
||||
Timber.d(url)
|
||||
val parsedUrl = Uri.parse(url)
|
||||
if(parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
|
||||
//Hide distracting content
|
||||
view.loadUrl(HIDE_JS)
|
||||
|
||||
//Check login result
|
||||
if(parsedUrl.getQueryParameter("code")?.toInt() != 0) {
|
||||
if(checkLoginCookies(url)) view.loadUrl("http://exhentai.org/")
|
||||
}
|
||||
} else if(parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
|
||||
//At ExHentai, check that everything worked out...
|
||||
if(applyExHentaiCookies(url)) {
|
||||
preferenceManager.enableExhentai().set(true)
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we are logged in
|
||||
*/
|
||||
fun checkLoginCookies(url: String): Boolean {
|
||||
getCookies(url)?.let { parsed ->
|
||||
return parsed.filter {
|
||||
(it.name.equals(MEMBER_ID_COOKIE, ignoreCase = true)
|
||||
|| it.name.equals(PASS_HASH_COOKIE, ignoreCase = true))
|
||||
&& it.value.isNotBlank()
|
||||
}.count() >= 2
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse cookies at ExHentai
|
||||
*/
|
||||
fun applyExHentaiCookies(url: String): Boolean {
|
||||
getCookies(url)?.let { parsed ->
|
||||
|
||||
var memberId: String? = null
|
||||
var passHash: String? = null
|
||||
var igneous: String? = null
|
||||
|
||||
parsed.forEach {
|
||||
when (it.name.toLowerCase()) {
|
||||
MEMBER_ID_COOKIE -> memberId = it.value
|
||||
PASS_HASH_COOKIE -> passHash = it.value
|
||||
IGNEOUS_COOKIE -> igneous = it.value
|
||||
}
|
||||
}
|
||||
|
||||
//Missing a cookie
|
||||
if (memberId == null || passHash == null || igneous == null) return false
|
||||
|
||||
//Update prefs
|
||||
preferenceManager.memberIdVal().set(memberId)
|
||||
preferenceManager.passHashVal().set(passHash)
|
||||
preferenceManager.igneousVal().set(igneous)
|
||||
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getCookies(url: String): List<HttpCookie>?
|
||||
= CookieManager.getInstance().getCookie(url)?.let {
|
||||
it.split("; ").flatMap {
|
||||
HttpCookie.parse(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> onBackPressed()
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MEMBER_ID_COOKIE = "ipb_member_id"
|
||||
const val PASS_HASH_COOKIE = "ipb_pass_hash"
|
||||
const val IGNEOUS_COOKIE = "igneous"
|
||||
|
||||
const val HIDE_JS = """
|
||||
javascript:(function () {
|
||||
document.getElementsByTagName('body')[0].style.visibility = 'hidden';
|
||||
document.getElementsByName('submit')[0].style.visibility = 'visible';
|
||||
document.querySelector('td[width="60%"][valign="top"]').style.visibility = 'visible';
|
||||
|
||||
function hide(e) {if(e !== null && e !== undefined) e.style.display = 'none';}
|
||||
|
||||
hide(document.querySelector(".errorwrap"));
|
||||
hide(document.querySelector('td[width="40%"][valign="top"]'));
|
||||
var child = document.querySelector(".page").querySelector('div');
|
||||
child.style.padding = null;
|
||||
var ft = child.querySelectorAll('table');
|
||||
var fd = child.parentNode.querySelectorAll('div > div');
|
||||
var fh = document.querySelector('#border').querySelectorAll('td > table');
|
||||
hide(ft[0]);
|
||||
hide(ft[1]);
|
||||
hide(fd[1]);
|
||||
hide(fd[2]);
|
||||
hide(child.querySelector('br'));
|
||||
var error = document.querySelector(".page > div > .borderwrap");
|
||||
if(error !== null) error.style.visibility = 'visible';
|
||||
hide(fh[0]);
|
||||
hide(fh[1]);
|
||||
hide(document.querySelector("#gfooter"));
|
||||
hide(document.querySelector(".copyright"));
|
||||
document.querySelectorAll("td").forEach(function(e) {
|
||||
e.style.color = "white";
|
||||
});
|
||||
var pc = document.querySelector(".postcolor");
|
||||
if(pc !== null) pc.style.color = "#26353F";
|
||||
})()
|
||||
"""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user