Merge pull request #6 from tom5079/development

Version 2.5
This commit is contained in:
tom5079
2019-06-07 12:05:06 +09:00
committed by GitHub
18 changed files with 416 additions and 62 deletions

View File

@@ -7,7 +7,12 @@ import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.getReader
import xyz.quaver.hiyobi.user_agent
import java.io.File
import java.net.URL
import javax.net.ssl.HttpsURLConnection
/**
* Instrumented test, which will execute on an Android device.
@@ -35,6 +40,17 @@ class ExampleInstrumentedTest {
@Test
fun test_doSearch() {
val reader = getReader(1426382)
val data: ByteArray
with(URL(reader[0].url).openConnection() as HttpsURLConnection) {
setRequestProperty("User-Agent", user_agent)
setRequestProperty("Cookie", cookie)
data = inputStream.readBytes()
}
Log.d("Pupil", data.size.toString())
}
}

View File

@@ -3,6 +3,7 @@
package="xyz.quaver.pupil">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
@@ -14,16 +15,6 @@
android:theme="@style/AppTheme"
android:name=".Pupil">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="xyz.quaver.pupil.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
<activity android:name=".ReaderActivity"
android:parentActivityName=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>

View File

@@ -1,12 +1,14 @@
package xyz.quaver.pupil
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.preference.PreferenceManager
import android.text.*
import android.text.style.AlignmentSpan
import android.util.Log
import android.view.*
import android.widget.EditText
import android.widget.ImageView
@@ -15,16 +17,20 @@ import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.GravityCompat
import com.arlib.floatingsearchview.FloatingSearchView
import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
import com.arlib.floatingsearchview.util.view.SearchInputView
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main_content.*
import kotlinx.android.synthetic.main.dialog_galleryblock.view.*
import kotlinx.coroutines.*
import kotlinx.io.IOException
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.JsonObject
@@ -35,9 +41,12 @@ import xyz.quaver.pupil.adapters.GalleryBlockAdapter
import xyz.quaver.pupil.types.TagSuggestion
import xyz.quaver.pupil.util.*
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.net.URL
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
@@ -68,6 +77,8 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkPermissions()
val preference = PreferenceManager.getDefaultSharedPreferences(this)
if (Locale.getDefault().language == "ko") {
@@ -238,6 +249,11 @@ class MainActivity : AppCompatActivity() {
}
}
private fun checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 13489)
}
private fun initView() {
var prevP1 = 0
main_appbar_layout.addOnOffsetChangedListener(
@@ -280,12 +296,7 @@ class MainActivity : AppCompatActivity() {
loadBlocks()
}
R.id.main_drawer_help -> {
AlertDialog.Builder(this@MainActivity).apply {
title = getString(R.string.help_dialog_title)
setMessage(R.string.help_dialog_message)
setPositiveButton(android.R.string.ok) { _, _ -> }
}.show()
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
}
R.id.main_drawer_github -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github))))
@@ -359,10 +370,9 @@ class MainActivity : AppCompatActivity() {
isEnabled = !(adapter as GalleryBlockAdapter).completeFlag.get(galleryBlock.id, false)
setOnClickListener {
val downloader = GalleryDownloader.get(galleryBlock.id)
if (downloader == null) {
if (downloader == null)
GalleryDownloader(context, galleryBlock, true).start()
downloads.add(galleryBlock.id)
} else {
else {
downloader.cancel()
downloader.clearNotification()
}
@@ -377,11 +387,91 @@ class MainActivity : AppCompatActivity() {
this?.cancelAndJoin()
this?.clearNotification()
}
val cache = File(cacheDir, "imageCache/${galleryBlock.id}/images/")
val cache = File(cacheDir, "imageCache/${galleryBlock.id}")
val data = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}")
cache.deleteRecursively()
data.deleteRecursively()
downloads.remove(galleryBlock.id)
if (mode == Mode.DOWNLOAD) {
runOnUiThread {
cancelFetch()
clearGalleries()
fetchGalleries(query)
loadBlocks()
}
}
(adapter as GalleryBlockAdapter).completeFlag.put(galleryBlock.id, false)
}
dialog.dismiss()
}
with(view.main_dialog_export) {
val images = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}/images").let {
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
}
}
isEnabled = images.exists()
setOnClickListener {
CoroutineScope(Dispatchers.Default).launch {
val preference = PreferenceManager.getDefaultSharedPreferences(context)
val zip = preference.getBoolean("export_zip", false)
if (zip) {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
return@launch
}
}
FileOutputStream(target).use { targetStream ->
ZipOutputStream(targetStream).use {zipStream ->
images.listFiles().forEach {
zipStream.putNextEntry(ZipEntry(it.name))
FileInputStream(it).use { fileStream ->
fileStream.copyTo(zipStream)
}
}
}
}
} else {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
try {
target.canonicalPath
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
try {
target.canonicalPath
} catch (e: IOException) {
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
return@launch
}
}
images.copyRecursively(target, true)
}
Snackbar.make(main_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
}
dialog.dismiss()
(adapter as GalleryBlockAdapter).completeFlag.put(galleryBlock.id, false)
}
}

View File

@@ -2,6 +2,7 @@ package xyz.quaver.pupil
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Environment
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
@@ -26,6 +27,11 @@ import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.pupil.adapters.ReaderAdapter
import xyz.quaver.pupil.util.GalleryDownloader
import xyz.quaver.pupil.util.ItemClickSupport
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
class ReaderActivity : AppCompatActivity() {
@@ -163,6 +169,7 @@ class ReaderActivity : AppCompatActivity() {
onProgressHandler = {
CoroutineScope(Dispatchers.Main).launch {
reader_progressbar.progress = it
menu?.findItem(R.id.reader_menu_use_hiyobi)?.isVisible = true
}
}
onDownloadedHandler = {
@@ -274,6 +281,14 @@ class ReaderActivity : AppCompatActivity() {
if (!downloader.download)
downloader.clearNotification()
}
reader_fab_export.setOnClickListener {
downloader.export( {
Snackbar.make(reader_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
}, {
Snackbar.make(reader_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
})
}
}
private fun fullscreen(isFullscreen: Boolean) {

View File

@@ -12,6 +12,7 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import kotlinx.android.synthetic.main.dialog_default_query.view.*
@@ -95,6 +96,33 @@ class SettingsActivity : AppCompatActivity() {
true
}
}
with(findPreference<Preference>("delete_downloads")) {
this ?: return@with
val dir = File(ContextCompat.getDataDir(context), "images")
summary = getCacheSize(dir)
setOnPreferenceClickListener {
AlertDialog.Builder(context).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_downloads_alert_message)
setPositiveButton(android.R.string.yes) { _, _ ->
if (dir.exists())
dir.deleteRecursively()
val downloads = (activity!!.application as Pupil).downloads
downloads.clear()
summary = getCacheSize(dir)
}
setNegativeButton(android.R.string.no) { _, _ -> }
}.show()
true
}
}
with(findPreference<Preference>("clear_history")) {
this ?: return@with

View File

@@ -68,16 +68,30 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
}
//Check cache
val readerCache = File(context.cacheDir, "imageCache/${gallery.id}/reader.json")
val imageCache = File(context.cacheDir, "imageCache/${gallery.id}/images")
val readerCache = {
File(ContextCompat.getDataDir(context), "images/${gallery.id}/reader.json").let {
when {
it.exists() -> it
else -> File(context.cacheDir, "imageCache/${gallery.id}/reader.json")
}
}
}
val imageCache = {
File(ContextCompat.getDataDir(context), "images/${gallery.id}/images").let {
when {
it.exists() -> it
else -> File(context.cacheDir, "imageCache/${gallery.id}/images")
}
}
}
if (readerCache.exists()) {
if (readerCache.invoke().exists()) {
val reader = Json(JsonConfiguration.Stable)
.parse(ReaderItem.serializer().list, readerCache.readText())
.parse(ReaderItem.serializer().list, readerCache.invoke().readText())
with(galleryblock_progressbar) {
max = reader.size
progress = imageCache.list()?.size ?: 0
progress = imageCache.invoke().list()?.size ?: 0
visibility = View.VISIBLE
}
@@ -89,9 +103,9 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
val refresh = Timer(false).schedule(0, 1000) {
post {
with(view.galleryblock_progressbar) {
progress = imageCache.list()?.size ?: 0
progress = imageCache.invoke().list()?.size ?: 0
if (!readerCache.exists()) {
if (!readerCache.invoke().exists()) {
visibility = View.GONE
max = 0
progress = 0
@@ -100,7 +114,7 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
} else {
if (visibility == View.GONE) {
val reader = Json(JsonConfiguration.Stable)
.parse(ReaderItem.serializer().list, readerCache.readText())
.parse(ReaderItem.serializer().list, readerCache.invoke().readText())
max = reader.size
visibility = View.VISIBLE
}

View File

@@ -4,10 +4,13 @@ import android.app.PendingIntent
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.os.Environment
import android.util.Log
import android.util.SparseArray
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.TaskStackBuilder
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager
import kotlinx.coroutines.*
import kotlinx.io.IOException
@@ -15,12 +18,18 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.list
import xyz.quaver.hitomi.*
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.user_agent
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
import xyz.quaver.pupil.ReaderActivity
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.net.URL
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList
import kotlin.concurrent.schedule
@@ -31,14 +40,27 @@ class GalleryDownloader(
_notify: Boolean = false
) : ContextWrapper(base) {
private val downloads = (applicationContext as Pupil).downloads
var useHiyobi = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("use_hiyobi", false)
var download: Boolean = false
set(value) {
if (value) {
field = true
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
val data = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}")
val cache = File(cacheDir, "imageCache/${galleryBlock.id}")
if (cache.exists() && !data.exists()) {
cache.copyRecursively(data, true)
cache.deleteRecursively()
}
if (!reader.isActive && downloadJob?.isActive != true)
field = false
downloads.add(galleryBlock.id)
} else {
field = false
}
@@ -70,11 +92,14 @@ class GalleryDownloader(
download = _notify
val json = Json(JsonConfiguration.Stable)
val serializer = ReaderItem.serializer().list
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
val useHiyobi = preference.getBoolean("use_hiyobi", false)
//Check cache
val cache = File(cacheDir, "imageCache/${galleryBlock.id}/reader.json")
val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/reader.json").let {
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/reader.json")
}
}
if (cache.exists()) {
val cached = json.parse(serializer, cache.readText())
@@ -90,7 +115,10 @@ class GalleryDownloader(
useHiyobi -> {
xyz.quaver.hiyobi.getReader(galleryBlock.id).let {
when {
it.isEmpty() -> getReader(galleryBlock.id)
it.isEmpty() -> {
useHiyobi = false
getReader(galleryBlock.id)
}
else -> it
}
}
@@ -148,12 +176,21 @@ class GalleryDownloader(
val name = "$index".padStart(4, '0')
val ext = url.split('.').last()
val cache = File(cacheDir, "/imageCache/${galleryBlock.id}/images/$name.$ext")
val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/images/$name.$ext").let {
when {
it.exists() -> it
else -> File(cacheDir, "/imageCache/${galleryBlock.id}/images/$name.$ext")
}
}
if (!cache.exists())
try {
with(URL(url).openConnection() as HttpsURLConnection) {
setRequestProperty("Referer", getReferer(galleryBlock.id))
if (useHiyobi) {
setRequestProperty("User-Agent", user_agent)
setRequestProperty("Cookie", cookie)
} else
setRequestProperty("Referer", getReferer(galleryBlock.id))
if (!cache.parentFile.exists())
cache.parentFile.mkdirs()
@@ -189,8 +226,35 @@ class GalleryDownloader(
.setContentText(getString(R.string.reader_notification_complete))
.setProgress(0, 0, false)
if (download)
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
if (download) {
File(cacheDir, "imageCache/${galleryBlock.id}").let {
if (it.exists()) {
it.copyRecursively(
File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}"),
true
)
it.deleteRecursively()
}
}
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
val autoExport = preference.getBoolean("auto_export", false)
if (autoExport) {
export({
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
}, {
notificationBuilder
.setContentTitle(galleryBlock.title)
.setContentText(getString(R.string.main_export_error))
.setProgress(0, 0, false)
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
})
} else {
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
}
}
download = false
}
@@ -207,6 +271,8 @@ class GalleryDownloader(
suspend fun cancelAndJoin() {
downloadJob?.cancelAndJoin()
remove(galleryBlock.id)
}
fun invokeOnReaderLoaded() {
@@ -243,4 +309,69 @@ class GalleryDownloader(
notificationManager = NotificationManagerCompat.from(this)
}
fun export(onSuccess: (() -> Unit)? = null, onError: (() -> Unit)? = null) {
val images = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}/images").let {
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
}
}
if (!images.exists())
return
CoroutineScope(Dispatchers.Default).launch {
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
val zip = preference.getBoolean("export_zip", false)
if (zip) {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
onError?.invoke()
return@launch
}
}
FileOutputStream(target).use { targetStream ->
ZipOutputStream(targetStream).use { zipStream ->
images.listFiles().forEach {
zipStream.putNextEntry(ZipEntry(it.name))
FileInputStream(it).use { fileStream ->
fileStream.copyTo(zipStream)
}
}
}
}
} else {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
try {
target.canonicalPath
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
try {
target.canonicalPath
} catch (e: IOException) {
onError?.invoke()
return@launch
}
}
images.copyRecursively(target, true)
}
onSuccess?.invoke()
}
}
}

View File

@@ -0,0 +1,8 @@
<!-- drawable/export.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#fff" android:pathData="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
</vector>

View File

@@ -51,6 +51,14 @@
app:fab_label="@string/reader_fab_download"
app:fab_size="mini"/>
<com.github.clans.fab.FloatingActionButton
android:id="@+id/reader_fab_export"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_export"
app:fab_label="@string/main_dialog_export"
app:fab_size="mini"/>
<com.github.clans.fab.FloatingActionButton
android:id="@+id/reader_fab_fullscreen"
android:layout_width="wrap_content"

View File

@@ -20,4 +20,12 @@
android:text="@string/main_dialog_delete"
app:layout_constraintTop_toBottomOf="@id/main_dialog_download"/>
<Button
android:id="@+id/main_dialog_export"
style="?borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/main_dialog_export"
app:layout_constraintTop_toBottomOf="@id/main_dialog_delete"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -2,6 +2,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/reader_menu_use_hiyobi"
android:title=""
android:icon="@drawable/ic_hiyobi"
app:showAsAction="ifRoom"
android:visible="false"/>
<item android:id="@+id/reader_menu_page_indicator"
android:title="@string/page_indicator_placeholder"
app:showAsAction="always|withText"/>

View File

@@ -9,8 +9,8 @@
<string name="search_hint_with_page">ギャラリー検索</string>
<string name="settings_cache_title">キャッシュ</string>
<string name="settings_clear_image_cache">イメージキャッシュクリア</string>
<string name="settings_clear_cache_alert_message">キャッシュをクリアするとイメージのロード速度に影響を与えます。実行しますか?</string>
<string name="settings_clear_cache_summary">キャッシュサイズ: %1$d%2$s</string>
<string name="settings_clear_cache_alert_message">キャッシュをクリアするとイメージのロード速度に影響を与えます。\n実行しますか?</string>
<string name="settings_clear_cache_summary">サイズ: %1$d%2$s</string>
<string name="settings_default_query">デフォルトキーワード</string>
<string name="settings_galleries_per_page">一回にロードするギャラリー数</string>
<string name="settings_search_title">検索設定</string>
@@ -19,7 +19,6 @@
<string name="update_title">新しいアップデートがあります</string>
<string name="warning">注意</string>
<string name="settings_miscellaneous_title">その他</string>
<string name="settings_use_hiyobi_summary">ロード速度を向上させるためhiyobi.meからイメージロード</string>
<string name="settings_use_hiyobi_title">hiyobi.meからロード</string>
<string name="settings_clear_history">履歴を削除</string>
<string name="settings_clear_history_alert_message">履歴を削除しますか?</string>
@@ -41,8 +40,6 @@
<string name="main_drawer_group_contact_help">ヘルプ</string>
<string name="main_drawer_group_contact_github">Github</string>
<string name="main_drawer_group_contact_email">メールを送る</string>
<string name="help_dialog_title">準備中</string>
<string name="help_dialog_message">準備中です。</string>
<string name="reader_fab_fullscreen">フルスクリーン</string>
<string name="channel_download">ダウンロード</string>
<string name="channel_download_description">ダウンロードの進行を通知</string>
@@ -59,4 +56,15 @@
<string name="main_move">%1$dページへ移動</string>
<string name="https_block_alert_title">(Korean only)</string>
<string name="https_block_alert">(Korean only)</string>
<string name="main_dialog_export">ギャラリーエクスポート</string>
<string name="main_export_complete">エクスポート完了</string>
<string name="main_export_open_folder">フォルダを開く</string>
<string name="main_export_error">エクスポートエラーが発生しました</string>
<string name="settings_export_zip_title">zipエクスポート</string>
<string name="settings_export_zip_summary">イメージフォルダの代わりzipファイルでエクスポート</string>
<string name="settings_auto_export_title">自動エクスポート</string>
<string name="settings_auto_export_summary">ダウンロード完了後自動的にエクスポート</string>
<string name="settings_clear_downloads">ダウンロード削除</string>
<string name="settings_clear_downloads_alert_message">ダウンロードしたギャラリーを全て削除します。\n実行しますか</string>
<string name="settings_use_hiyobi_summary">ロード速度を向上させるため可能であればhiyobi.meからイメージロード</string>
</resources>

View File

@@ -7,8 +7,8 @@
<string name="search_hint_with_page">갤러리 검색</string>
<string name="settings_default_query">기본 검색어</string>
<string name="settings_clear_image_cache">이미지 캐시 정리하기</string>
<string name="settings_clear_cache_alert_message">캐시를 정리하면 이미지 로딩속도가 느려질 수 있습니다. 계속하시겠습니까?</string>
<string name="settings_clear_cache_summary">현재 캐시 사용량: %1$d%2$s</string>
<string name="settings_clear_cache_alert_message">캐시를 정리하면 이미지 로딩속도가 느려질 수 있습니다.\n계속하시겠습니까?</string>
<string name="settings_clear_cache_summary">사용량: %1$d%2$s</string>
<string name="settings_galleries_per_page">한 번에 로드할 갤러리 수</string>
<string name="settings_search_title">검색 설정</string>
<string name="settings_title">설정</string>
@@ -19,7 +19,6 @@
<string name="main_search">검색</string>
<string name="settings_cache_title">캐시</string>
<string name="settings_miscellaneous_title">기타</string>
<string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string>
<string name="settings_use_hiyobi_title">hiyobi.me 사용</string>
<string name="settings_clear_history">기록 삭제</string>
<string name="settings_clear_history_alert_message">기록을 삭제하시겠습니까?</string>
@@ -41,8 +40,6 @@
<string name="main_drawer_group_contact_help">도움말</string>
<string name="main_drawer_group_contact_homepage">홈페이지</string>
<string name="main_drawer_group_contact_title">문의</string>
<string name="help_dialog_title">준비 중</string>
<string name="help_dialog_message">준비중입니다.</string>
<string name="reader_fab_fullscreen">전체 화면</string>
<string name="channel_download">다운로드</string>
<string name="channel_download_description">다운로드 상태 알림</string>
@@ -59,4 +56,15 @@
<string name="main_move">%1$d 페이지로 이동</string>
<string name="https_block_alert_title">접속 불가 현상 안내</string>
<string name="https_block_alert">최근 https 차단으로 접속이 안 되는 경우가 발생하고 있습니다\n이 경우 플레이스토어에서 SNIper앱을 이용하시면 정상이용이 가능합니다.</string>
<string name="main_dialog_export">갤러리 내보내기</string>
<string name="main_export_complete">내보내기 완료</string>
<string name="main_export_open_folder">폴더 열기</string>
<string name="main_export_error">내보내기 오류가 발생했습니다</string>
<string name="settings_export_zip_title">zip 파일로 내보내기</string>
<string name="settings_export_zip_summary">이미지 폴더 대신 zip 파일로 내보내기</string>
<string name="settings_auto_export_title">자동 내보내기</string>
<string name="settings_auto_export_summary">다운로드가 끝난 후 자동 내보내기</string>
<string name="settings_clear_downloads">다운로드 삭제</string>
<string name="settings_clear_downloads_alert_message">다운로드 된 만화를 모두 삭제합니다.\n계속하시겠습니까?</string>
<string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string>
</resources>

View File

@@ -5,6 +5,7 @@
<string name="release_name" translatable="false">Pupil-v(\\d+\\.)+\\d+\\.apk</string>
<string name="home_page" translatable="false">https://tom5079.github.io/Pupil</string>
<string name="help" translatable="false">https://tom5079.github.io/Pupil/2019/06/02/manual-kr.html</string>
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string>
<string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string>
@@ -46,9 +47,11 @@
<string name="main_move">Move to page %1$d</string>
<string name="main_dialog_delete">Delete this gallery</string>
<string name="main_dialog_export">Export this gallery</string>
<string name="help_dialog_title">WIP</string>
<string name="help_dialog_message">While in progress!</string>
<string name="main_export_complete">Export completed</string>
<string name="main_export_open_folder">Open Folder</string>
<string name="main_export_error">Error occurred during export</string>
<string name="update_title">Update available</string>
<string name="update_download_started">Download started</string>
@@ -76,14 +79,20 @@
<string name="settings_default_query">Default query</string>
<string name="settings_cache_title">Cache</string>
<string name="settings_clear_image_cache">Clear image cache</string>
<string name="settings_clear_cache_summary">Currently using %1$d%2$s of cache</string>
<string name="settings_clear_cache_alert_message">Deleting cache can affect image loading speed. Do you want to continue?</string>
<string name="settings_clear_cache_summary">Currently using %1$d%2$s</string>
<string name="settings_clear_cache_alert_message">Deleting cache can affect image loading speed.\nDo you want to continue?</string>
<string name="settings_clear_downloads">Clear downloads</string>
<string name="settings_clear_downloads_alert_message">Delete all downloaded galleries.\nDo you want to continue?</string>
<string name="settings_clear_history">Clear history</string>
<string name="settings_clear_history_alert_message">Do you want to clear histories?</string>
<string name="settings_clear_history_summary">%1$d histories saved</string>
<string name="settings_miscellaneous_title">Miscellaneous</string>
<string name="settings_use_hiyobi_title">Use hiyobi.me</string>
<string name="settings_use_hiyobi_summary">Load images from hiyobi.me to improve loading speed (if available)</string>
<string name="settings_export_zip_title">Export zip</string>
<string name="settings_export_zip_summary">Export to zip instead of image folder</string>
<string name="settings_auto_export_title">Auto Export</string>
<string name="settings_auto_export_summary">Automatically exports galleries when download is finished</string>
<string name="settings_security_mode_title">Enable security mode</string>
<string name="settings_security_mode_summary">Enable security mode to make the screen invisible on recent app window</string>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="Download" path="Download"/>
</paths>

View File

@@ -28,6 +28,10 @@
app:title="@string/settings_clear_image_cache"
app:key="delete_image_cache"/>
<Preference
app:title="@string/settings_clear_downloads"
app:key="delete_downloads"/>
<Preference
app:title="@string/settings_clear_history"
app:key="clear_history"/>
@@ -42,6 +46,16 @@
app:title="@string/settings_use_hiyobi_title"
app:summary="@string/settings_use_hiyobi_summary"/>
<SwitchPreference
app:key="export_zip"
app:title="@string/settings_export_zip_title"
app:summary="@string/settings_export_zip_summary"/>
<SwitchPreference
app:key="auto_export"
app:title="@string/settings_auto_export_title"
app:summary="@string/settings_auto_export_summary"/>
<SwitchPreference
app:key="security_mode"
app:title="@string/settings_security_mode_title"

View File

@@ -13,6 +13,12 @@ const val hiyobi = "xn--9w3b15m8vo.asia"
const val user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
var cookie: String = ""
get() {
if (field.isEmpty())
field = renewCookie()
return field
}
fun renewCookie() : String {
val url = "https://$hiyobi/"
@@ -32,9 +38,6 @@ fun renewCookie() : String {
fun getReader(galleryId: Int) : Reader {
val url = "https://$hiyobi/data/json/${galleryId}_list.json"
if (cookie.isEmpty())
cookie = renewCookie()
try {
val json = Json(JsonConfiguration.Stable).parseJson(
with(URL(url).openConnection() as HttpsURLConnection) {

View File

@@ -14,8 +14,7 @@ class UnitTest {
fun test_nozomi() {
val nozomi = fetchNozomi(start = 0, count = 5)
for (n in nozomi)
println(n)
nozomi.first
}
@Test
@@ -62,6 +61,8 @@ class UnitTest {
@Test
fun test_hiyobi() {
print(xyz.quaver.hiyobi.getReader(1415416).size)
xyz.quaver.hiyobi.getReader(1415416).forEach {
println(it.url)
}
}
}